Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0aa2e2b298 | ||
|
|
1f5ad49591 | ||
|
|
3e45c7895c | ||
|
|
29301f440e | ||
|
|
2f86c0d9d2 | ||
|
|
e7dbd5a5cc | ||
|
|
62c00bb7f5 | ||
|
|
12f0d2a867 | ||
|
|
5af66b60e1 | ||
|
|
028a4fe5b2 | ||
|
|
fa6e711c2f | ||
|
|
c620c7bf39 | ||
|
|
f3066594fe | ||
|
|
4db1e28677 | ||
|
|
d6cbc52790 | ||
|
|
0943065498 | ||
|
|
42cc3f309f | ||
|
|
6d7dc24775 | ||
|
|
8faa17ad33 | ||
|
|
3d5232b308 | ||
|
|
c2bab5b369 | ||
|
|
eee1dcef13 | ||
|
|
8254543da7 | ||
|
|
2028efabc3 | ||
|
|
011c033478 | ||
|
|
477e9f85be | ||
|
|
0d5ae63013 | ||
|
|
aa60a7b975 | ||
|
|
c071569f3c | ||
|
|
1d717ffe99 | ||
|
|
c53fff058b | ||
|
|
c836bd48e0 | ||
|
|
ec675a5662 | ||
|
|
02e72493ef | ||
|
|
dd2ad410b8 | ||
|
|
92fb183c22 | ||
|
|
46eca09d69 | ||
|
|
f7bc2b6d06 | ||
|
|
c87cb4bacd | ||
|
|
b6ea6530b7 | ||
|
|
af4e69afc9 | ||
|
|
a292936d55 | ||
|
|
a000687a42 | ||
|
|
03aaa89a61 | ||
|
|
be71d957e1 | ||
|
|
651970899d | ||
|
|
ae67b00c4d | ||
|
|
51848b6cce | ||
|
|
8e0b3a5df3 | ||
|
|
692c43a3cc | ||
|
|
29430df66d | ||
|
|
9954a75cdd | ||
|
|
6ee7964fa6 | ||
|
|
db6608571a | ||
|
|
76d5051833 | ||
|
|
9cdcbb1988 | ||
|
|
33882942e4 | ||
|
|
6c2c690504 | ||
|
|
c78f232e4a | ||
|
|
5f39046a52 | ||
|
|
fff2be49fc | ||
|
|
95a2b46ae1 | ||
|
|
754324d253 | ||
|
|
b350b89376 | ||
|
|
4445f752f3 | ||
|
|
9e92947b2c | ||
|
|
92d44b12bd | ||
|
|
36c673c660 | ||
|
|
db509cb72f | ||
|
|
c0af2af7e7 | ||
|
|
35b2b5263c | ||
|
|
fa3df44535 | ||
|
|
08dd7d6951 | ||
|
|
d7316918a3 | ||
|
|
044fc3af69 | ||
|
|
d1eb20e7b3 | ||
|
|
c27edb2475 | ||
|
|
58d4030133 | ||
|
|
e8b1063647 | ||
|
|
3caa703ced | ||
|
|
f7e016a98c | ||
|
|
156e9b8e54 | ||
|
|
7aa00a961a | ||
|
|
4678efff72 | ||
|
|
f3b4e7f752 | ||
|
|
e39fa44cdb | ||
|
|
3fb4d1e4c1 | ||
|
|
06b8636817 | ||
|
|
4b653ee367 | ||
|
|
d2cdd46466 | ||
|
|
2d46fb885d | ||
|
|
b3e0c4a5d5 | ||
|
|
ab6609282d | ||
|
|
6ff21692f1 | ||
|
|
f64cc4c655 | ||
|
|
e31af96ef9 | ||
|
|
a431b34c43 | ||
|
|
562bb8a878 | ||
|
|
719dbf02d4 | ||
|
|
e2327fcf94 | ||
|
|
5a0c8f4a8b | ||
|
|
031a380c25 | ||
|
|
23c4e584d4 | ||
|
|
452febd73e | ||
|
|
645741aa23 | ||
|
|
97b141b653 | ||
|
|
67ac778d4c | ||
|
|
e45ed19dc7 | ||
|
|
f79c2346a5 | ||
|
|
e964c60830 | ||
|
|
f8ffb4abbd | ||
|
|
37931f08b5 | ||
|
|
9b75e37e1f | ||
|
|
232f1d008d | ||
|
|
3947bd65f2 | ||
|
|
1d39299a7d | ||
|
|
da1389b0b4 | ||
|
|
818c7dac3d | ||
|
|
15b05304cc | ||
|
|
e33c7f6be4 | ||
|
|
d23bf7b927 | ||
|
|
de1ebe6319 | ||
|
|
3e9e0802f6 | ||
|
|
b8f9263d18 | ||
|
|
946cd381a0 | ||
|
|
0a49d09878 | ||
|
|
f936277a4d | ||
|
|
ac16c5663b | ||
|
|
83058b01d3 | ||
|
|
3c8619db5d | ||
|
|
14226ef69c | ||
|
|
910691ad4b | ||
|
|
115d29b6f8 | ||
|
|
05ef7c83a8 | ||
|
|
2311fb9a6d | ||
|
|
c1b8ec8da1 | ||
|
|
a1efd1d024 | ||
|
|
088b6eac35 | ||
|
|
ea1068c465 | ||
|
|
978545af94 | ||
|
|
86c10e687b | ||
|
|
24ab9f9fdf | ||
|
|
5d69bbc4ca | ||
|
|
3c3b7ff61c | ||
|
|
5a6e266c8d | ||
|
|
6f724e34f5 | ||
|
|
7cec421419 | ||
|
|
967f541659 | ||
|
|
6e78d903e0 | ||
|
|
03a243fd20 | ||
|
|
0b8d3744bb | ||
|
|
a0bb3b31a3 | ||
|
|
1f79402a0a | ||
|
|
f7db4058a8 | ||
|
|
4d9854695a | ||
|
|
e90133ebd0 | ||
|
|
d4818b5a71 | ||
|
|
68a15c5c7c | ||
|
|
42db55fabd | ||
|
|
e6c1dfc51e | ||
|
|
4f3146dc7b | ||
|
|
4372edb7c4 | ||
|
|
d105388d82 | ||
|
|
fd812f25a5 | ||
|
|
9f5904eaf2 | ||
|
|
d246b19750 | ||
|
|
128a3ac4d9 | ||
|
|
abd908949a | ||
|
|
ab083a3baf | ||
|
|
45ee3aa0a3 | ||
|
|
d587016cc3 | ||
|
|
8edee4e755 | ||
|
|
8aeaa6681a | ||
|
|
8a0a68248c | ||
|
|
251ba407be | ||
|
|
bd28d688aa | ||
|
|
6ab679a725 | ||
|
|
6b7d636b0d | ||
|
|
f72749fbd6 | ||
|
|
9a032a57d0 | ||
|
|
244ff0d846 | ||
|
|
c65726fb12 | ||
|
|
8ef7f07195 | ||
|
|
2af2fc31a1 | ||
|
|
9bf0edb5df | ||
|
|
53f4baa9ac | ||
|
|
63cc9c4b36 | ||
|
|
8b60ef1156 | ||
|
|
751a80afb7 | ||
|
|
f2b2852b76 | ||
|
|
f36d8224a6 | ||
|
|
c5c2a80af9 | ||
|
|
b9dfd2a795 | ||
|
|
b381fe6c27 | ||
|
|
003dcface0 | ||
|
|
0e05f1a8b7 | ||
|
|
5a340804fe | ||
|
|
65f6c35c88 | ||
|
|
cfee75b6e9 | ||
|
|
0463af26b3 | ||
|
|
ced3c2d778 | ||
|
|
7e4e6932a0 | ||
|
|
13940c97e7 | ||
|
|
91d28cbbdd | ||
|
|
adc2d2b513 | ||
|
|
c80116e90d | ||
|
|
f667c39ade | ||
|
|
ce0ddb2e1f | ||
|
|
3a716c08f8 | ||
|
|
d69f46f7ee | ||
|
|
3cda75986b | ||
|
|
ffea2de826 | ||
|
|
ac6ccc3257 | ||
|
|
29ed8f3116 | ||
|
|
3f2dd34ee5 | ||
|
|
df7c8bf508 | ||
|
|
1e2fdc3e1b | ||
|
|
901f3fe63b | ||
|
|
a767d2199d | ||
|
|
ceb4432b49 | ||
|
|
b80c48886a | ||
|
|
55121d501b | ||
|
|
2c0c8b59a2 | ||
|
|
788419d64c | ||
|
|
735a38d134 | ||
|
|
8d80903cf2 | ||
|
|
432c98f5f7 | ||
|
|
f7495155af | ||
|
|
c2ee9a9a5e | ||
|
|
71bbd85ba4 | ||
|
|
3776a7bee1 | ||
|
|
fb51a0f892 | ||
|
|
2d74d9fa92 | ||
|
|
2014f47046 | ||
|
|
79c2edca2d | ||
|
|
175f1a9acd | ||
|
|
18e943a65b | ||
|
|
20f36eaa9a | ||
|
|
6cbff694ab | ||
|
|
54e106bb14 | ||
|
|
3d1992440b | ||
|
|
1cbaea0e3d | ||
|
|
400bdb5103 | ||
|
|
dd560fb78c | ||
|
|
e71cbfbde2 | ||
|
|
eb6c103396 | ||
|
|
45c585e5c2 | ||
|
|
0ab92c77bd | ||
|
|
2d1fd1b3a5 | ||
|
|
d4d831b9ac | ||
|
|
c713a3fb25 | ||
|
|
ff60125183 | ||
|
|
94d28a2593 | ||
|
|
43f8b50ef7 | ||
|
|
7c098753cf | ||
|
|
b46d283dc4 | ||
|
|
f9639eb695 | ||
|
|
9fc0006316 | ||
|
|
a51672cc82 | ||
|
|
32decc31db | ||
|
|
14d9aac98b | ||
|
|
327962bc01 | ||
|
|
4197bbe73c | ||
|
|
e3ef20eec3 | ||
|
|
8ddb80fca2 | ||
|
|
b8eb72f823 | ||
|
|
9003177bb7 | ||
|
|
591142ba84 | ||
|
|
7b4f7f75b0 | ||
|
|
31b2cb35f7 | ||
|
|
20eb2a9fb0 | ||
|
|
37d9bff77f | ||
|
|
f3f0bf3524 | ||
|
|
b9ca57a921 | ||
|
|
04546e39a5 | ||
|
|
e6cf98f743 | ||
|
|
a528a503d3 | ||
|
|
8345788e59 | ||
|
|
21c2b8f74a | ||
|
|
69c004093d | ||
|
|
5bec411bdc | ||
|
|
34339fbcd9 | ||
|
|
b49dc87a86 | ||
|
|
535d6c9dc5 | ||
|
|
221fad6c3e | ||
|
|
aeb3873f3c | ||
|
|
4f6c83cb3a | ||
|
|
2ba5cffe44 | ||
|
|
1e85a054ac | ||
|
|
ca60e50128 | ||
|
|
70c13a7588 | ||
|
|
6653bab492 | ||
|
|
741c235f08 | ||
|
|
70bc3557b4 | ||
|
|
7509e5c99b | ||
|
|
5a2c401e05 | ||
|
|
75427973f0 | ||
|
|
63d5c442a3 | ||
|
|
45f74386b8 | ||
|
|
6093530175 | ||
|
|
6bd064f289 | ||
|
|
31d57b0c37 | ||
|
|
22a185b52e | ||
|
|
0067bd0d16 | ||
|
|
6521202e68 | ||
|
|
67e87c7367 | ||
|
|
a4eeb91290 | ||
|
|
c0b1322c77 | ||
|
|
3c18282510 | ||
|
|
55674e31ea | ||
|
|
39a69b6850 | ||
|
|
2b8a5d6176 | ||
|
|
eb692e672e | ||
|
|
381a6a999b | ||
|
|
e276a830d3 | ||
|
|
e4ee9284b4 | ||
|
|
9e441f69b8 | ||
|
|
0d2b13dd75 | ||
|
|
2df07344c8 | ||
|
|
38ad5a8e2c | ||
|
|
bd15d2f331 | ||
|
|
80ec35fd0a | ||
|
|
fb8d834036 | ||
|
|
4191153d0b | ||
|
|
ace66b2b2f | ||
|
|
c8afcde4e5 | ||
|
|
8b9a0edeba | ||
|
|
923770d95a | ||
|
|
011b8d250a | ||
|
|
0f8aa1e644 | ||
|
|
9179a31a93 | ||
|
|
c9d32b4163 | ||
|
|
57c691c2e2 | ||
|
|
8a75c9078e | ||
|
|
fbcf84e63f | ||
|
|
ea5ab5e921 | ||
|
|
3a8773baec | ||
|
|
ab4dd1ac6d | ||
|
|
6f38b2aa0d | ||
|
|
929ec28436 | ||
|
|
04a19543a5 | ||
|
|
5d505f5271 | ||
|
|
60ff3ca0a1 | ||
|
|
e4f5d9b32f | ||
|
|
6b42ef3cb1 | ||
|
|
345b9d9297 | ||
|
|
4bad3c2823 | ||
|
|
38033d9dcb | ||
|
|
5c961d4f16 | ||
|
|
c21cdc2916 | ||
|
|
1a797b10c3 | ||
|
|
3bfa427134 | ||
|
|
9a8c4bd431 | ||
|
|
dc72b55361 | ||
|
|
ee4ef882dd | ||
|
|
23c2f4bb8c | ||
|
|
bd01955f39 | ||
|
|
3f1e1e57d8 | ||
|
|
ee343c7533 | ||
|
|
961071e3fa | ||
|
|
0219341ee8 | ||
|
|
5df3c7838d | ||
|
|
bf63147ca3 | ||
|
|
b7d7b99a82 | ||
|
|
5a0129018a | ||
|
|
e48a437c88 | ||
|
|
187c32d231 | ||
|
|
c680e31817 | ||
|
|
cc177eeb2b | ||
|
|
918db24c63 | ||
|
|
7e005f4559 | ||
|
|
5d49c1346a | ||
|
|
f6147850b9 | ||
|
|
731e50da32 | ||
|
|
5078c3e9cf | ||
|
|
de0a09899a | ||
|
|
4041ef8746 | ||
|
|
3b35219beb | ||
|
|
ca289e081e | ||
|
|
5cd00d71c7 | ||
|
|
ea924fbb26 | ||
|
|
da23a89910 | ||
|
|
e4b47090ba | ||
|
|
386ded05fd | ||
|
|
e3b6cbcee9 | ||
|
|
fd7651e895 | ||
|
|
8ca2f53828 | ||
|
|
fc385935ef | ||
|
|
ed1c5714a3 | ||
|
|
dfe03458d0 | ||
|
|
c55cd03db1 | ||
|
|
6a2b347b21 | ||
|
|
b96abb5fd4 | ||
|
|
4974a47c94 | ||
|
|
7e229652f1 | ||
|
|
81f2959417 | ||
|
|
9d46c688ed | ||
|
|
60a8ddd306 | ||
|
|
4817a87499 | ||
|
|
91ce1c3f6c | ||
|
|
0c9cba4e71 | ||
|
|
c833de2e0a | ||
|
|
6824e42c69 | ||
|
|
67a41534bd | ||
|
|
3d0d522f76 | ||
|
|
accd29804c | ||
|
|
0c62609e76 | ||
|
|
6148654604 | ||
|
|
40c1957484 | ||
|
|
6f754d9810 | ||
|
|
9a4c9e4306 | ||
|
|
c52b40657a | ||
|
|
db2c88f2e5 | ||
|
|
b9095b2176 | ||
|
|
ec9fac6629 | ||
|
|
b2dac594dc | ||
|
|
28029030b6 | ||
|
|
4b1fbf1eff | ||
|
|
24fbecb2e6 | ||
|
|
4a142b5c02 | ||
|
|
dfba974572 | ||
|
|
c1fd31fa23 | ||
|
|
fd3e10f793 | ||
|
|
6a7358920b | ||
|
|
c0aa180e83 | ||
|
|
82cf7df7e9 | ||
|
|
4c58c602ff | ||
|
|
14e4b71d20 | ||
|
|
6483ea233c | ||
|
|
895ed4f6ff | ||
|
|
5ff7e66981 | ||
|
|
a2ff814796 | ||
|
|
c1e42a2f3e | ||
|
|
9e1c07b195 | ||
|
|
c71c732fc0 | ||
|
|
b3e0ec60df | ||
|
|
513cc2cac7 | ||
|
|
b0feeb3d31 | ||
|
|
9c7b3475d8 | ||
|
|
99e4a4fb4f | ||
|
|
7b7b46a61e | ||
|
|
ed4a264108 | ||
|
|
ae5d56471f | ||
|
|
bafb23ae44 | ||
|
|
c481d55976 | ||
|
|
7aa7d61984 | ||
|
|
fc545ed995 | ||
|
|
f85ab24993 | ||
|
|
4e1766485f | ||
|
|
8e5471d0fe | ||
|
|
a09878dcb4 | ||
|
|
b3f2ba035e | ||
|
|
10a620017d | ||
|
|
c10b06e29b | ||
|
|
411a634242 | ||
|
|
4ab421f183 | ||
|
|
8e3e15080b | ||
|
|
fd625c96d6 | ||
|
|
4f721fc1e2 | ||
|
|
373210e610 | ||
|
|
0ddb17862c | ||
|
|
aae415c1ee | ||
|
|
c79b2456f5 | ||
|
|
5104d323bb | ||
|
|
80c4be6e5f | ||
|
|
970859311d | ||
|
|
449581e7c4 | ||
|
|
02a8fc7f72 | ||
|
|
7bbeee8234 | ||
|
|
00532fe7ac | ||
|
|
073a934b2b | ||
|
|
ea7631de9e | ||
|
|
81e15c91f4 | ||
|
|
b8afbb66a7 | ||
|
|
9e9eba695f | ||
|
|
c6e3cad944 | ||
|
|
3af0e3249a | ||
|
|
510a836b90 | ||
|
|
25f415045a | ||
|
|
0af9c18ef2 |
@@ -24,6 +24,7 @@
|
|||||||
@import "CPAlert.j"
|
@import "CPAlert.j"
|
||||||
@import "CPAnimation.j"
|
@import "CPAnimation.j"
|
||||||
@import "CPApplication.j"
|
@import "CPApplication.j"
|
||||||
|
@import "CPArrayController.j"
|
||||||
@import "CPBezierPath.j"
|
@import "CPBezierPath.j"
|
||||||
@import "CPBox.j"
|
@import "CPBox.j"
|
||||||
@import "CPBrowser.j"
|
@import "CPBrowser.j"
|
||||||
@@ -31,6 +32,7 @@
|
|||||||
@import "CPButtonBar.j"
|
@import "CPButtonBar.j"
|
||||||
@import "CPCheckBox.j"
|
@import "CPCheckBox.j"
|
||||||
@import "CPCib.j"
|
@import "CPCib.j"
|
||||||
|
@import "CPCibBindingConnector.j"
|
||||||
@import "CPCibConnector.j"
|
@import "CPCibConnector.j"
|
||||||
@import "CPCibControlConnector.j"
|
@import "CPCibControlConnector.j"
|
||||||
@import "CPCibLoading.j"
|
@import "CPCibLoading.j"
|
||||||
@@ -74,15 +76,17 @@
|
|||||||
@import "CPSegmentedControl.j"
|
@import "CPSegmentedControl.j"
|
||||||
@import "CPShadow.j"
|
@import "CPShadow.j"
|
||||||
@import "CPSlider.j"
|
@import "CPSlider.j"
|
||||||
|
@import "CPSound.j"
|
||||||
@import "CPSplitView.j"
|
@import "CPSplitView.j"
|
||||||
|
@import "CPStepper.j"
|
||||||
@import "CPTableColumn.j"
|
@import "CPTableColumn.j"
|
||||||
@import "CPTableView.j"
|
@import "CPTableView.j"
|
||||||
@import "CPTabView.j"
|
@import "CPTabView.j"
|
||||||
@import "CPText.j"
|
@import "CPText.j"
|
||||||
@import "CPTextField.j"
|
@import "CPTextField.j"
|
||||||
|
@import "CPTokenField.j"
|
||||||
@import "CPToolbar.j"
|
@import "CPToolbar.j"
|
||||||
@import "CPToolbarItem.j"
|
@import "CPToolbarItem.j"
|
||||||
@import "CPTokenField.j"
|
|
||||||
@import "CPTreeNode.j"
|
@import "CPTreeNode.j"
|
||||||
@import "CPView.j"
|
@import "CPView.j"
|
||||||
@import "CPViewAnimation.j"
|
@import "CPViewAnimation.j"
|
||||||
@@ -90,4 +94,4 @@
|
|||||||
@import "CPWebView.j"
|
@import "CPWebView.j"
|
||||||
@import "CPWindow.j"
|
@import "CPWindow.j"
|
||||||
@import "CPWindowController.j"
|
@import "CPWindowController.j"
|
||||||
@import "CPArrayController.j"
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
*
|
*
|
||||||
* 11/10/2008 Ross Boucher
|
* 11/10/2008 Ross Boucher
|
||||||
* - Make it conform to style guidelines, general cleanup and ehancements
|
* - Make it conform to style guidelines, general cleanup and ehancements
|
||||||
|
* 11/10/2010 Antoine Mercadal
|
||||||
|
* - Enhancements, better compliance with Cocoa API
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@@ -75,22 +77,587 @@ CPCriticalAlertStyle = 2;
|
|||||||
*/
|
*/
|
||||||
@implementation CPAlert : CPView
|
@implementation CPAlert : CPView
|
||||||
{
|
{
|
||||||
CPPanel _alertPanel;
|
BOOL _showHelp @accessors(property=showsHelp);
|
||||||
|
BOOL _showSuppressionButton @accessors(property=showsSuppressionButton);
|
||||||
|
|
||||||
CPTextField _messageLabel;
|
CPAlertStyle _alertStyle @accessors(property=alertStyle);
|
||||||
CPTextField _informativeLabel;
|
CPString _title @accessors(property=title);
|
||||||
CPImageView _alertImageView;
|
CPView _accessoryView @accessors(property=accessoryView);
|
||||||
|
CPImage _icon @accessors(property=icon);
|
||||||
|
|
||||||
CPAlertStyle _alertStyle;
|
CPArray _buttons @accessors(property=buttons,readonly);
|
||||||
CPString _windowTitle;
|
CPCheckBox _suppressionButton @accessors(property=suppressionButton,readonly);
|
||||||
int _windowStyle;
|
|
||||||
CPArray _buttons;
|
|
||||||
|
|
||||||
id _delegate;
|
id _delegate @accessors(property=delegate);
|
||||||
SEL _didEndSelector;
|
|
||||||
id _modalDelegate;
|
id _modalDelegate;
|
||||||
|
SEL _didEndSelector;
|
||||||
|
|
||||||
|
CPWindow _window @accessors(property=window,readonly);
|
||||||
|
int _defaultWindowStyle;
|
||||||
|
|
||||||
|
CPImageView _alertImageView;
|
||||||
|
CPTextField _informativeLabel;
|
||||||
|
CPTextField _messageLabel;
|
||||||
|
CPButton _alertHelpButton;
|
||||||
|
|
||||||
|
BOOL _needsLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark Creating Alerts
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns a CPAlert object with the provided info
|
||||||
|
|
||||||
|
@param aMessage the main body text of the alert
|
||||||
|
@param defaultButton the title of the default button
|
||||||
|
@param alternateButton if not nil, the title of a second button
|
||||||
|
@param otherButton if not nil, the title of the third button
|
||||||
|
@param informativeText if not nil the informative text of the alert
|
||||||
|
@return fully initialized CPAlert
|
||||||
|
*/
|
||||||
|
+ (CPAlert)alertWithMessageText:(CPString)aMessage defaultButton:(CPString)defaultButtonTitle alternateButton:(CPString)alternateButtonTitle otherButton:(CPString)otherButtonTitle informativeTextWithFormat:(CPString)informativeText
|
||||||
|
{
|
||||||
|
var alert = [[CPAlert alloc] init];
|
||||||
|
|
||||||
|
[alert setMessageText:aMessage];
|
||||||
|
[alert addButtonWithTitle:defaultButtonTitle];
|
||||||
|
|
||||||
|
if (alternateButtonTitle)
|
||||||
|
[alert addButtonWithTitle:alternateButtonTitle];
|
||||||
|
|
||||||
|
if (otherButtonTitle)
|
||||||
|
[alert addButtonWithTitle:otherButtonTitle];
|
||||||
|
|
||||||
|
if (informativeText)
|
||||||
|
[alert setInformativeText:informativeText];
|
||||||
|
|
||||||
|
return alert;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Return an CPAlert with type error
|
||||||
|
|
||||||
|
@param anErrorMessage the message of the alert
|
||||||
|
@return fully initialized CPAlert
|
||||||
|
*/
|
||||||
|
+ (CPAlert)alertWithError:(CPString)anErrorMessage
|
||||||
|
{
|
||||||
|
var alert = [[CPAlert alloc] init];
|
||||||
|
|
||||||
|
[alert setMessageText:anErrorMessage];
|
||||||
|
[alert setAlertStyle:CPCriticalAlertStyle];
|
||||||
|
|
||||||
|
return alert;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Initializes a \c CPAlert panel with the default alert style \c CPWarningAlertStyle.
|
||||||
|
*/
|
||||||
|
- (id)init
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
|
||||||
|
if (self)
|
||||||
|
{
|
||||||
|
_buttons = [];
|
||||||
|
_alertStyle = CPWarningAlertStyle;
|
||||||
|
_showHelp = NO;
|
||||||
|
_needsLayout = YES;
|
||||||
|
_defaultWindowStyle = CPTitledWindowMask;
|
||||||
|
|
||||||
|
_messageLabel = [CPTextField labelWithTitle:@"Alert"];
|
||||||
|
_alertImageView = [[CPImageView alloc] init];
|
||||||
|
_informativeLabel = [[CPTextField alloc] init];
|
||||||
|
_suppressionButton = [CPCheckBox checkBoxWithTitle:@"Do not show this message again"];
|
||||||
|
|
||||||
|
_alertHelpButton = [[CPButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 16.0, 16.0)];
|
||||||
|
[_alertHelpButton setTarget:self];
|
||||||
|
[_alertHelpButton setAction:@selector(_showHelp:)];
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark Accessors
|
||||||
|
|
||||||
|
/*!
|
||||||
|
set the theme to use
|
||||||
|
|
||||||
|
@param the theme to use
|
||||||
|
*/
|
||||||
|
- (void)setTheme:(CPTheme)aTheme
|
||||||
|
{
|
||||||
|
if (aTheme === [self theme])
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (aTheme === [CPTheme defaultHudTheme])
|
||||||
|
_defaultWindowStyle = CPTitledWindowMask | CPHUDBackgroundWindowMask;
|
||||||
|
else
|
||||||
|
_defaultWindowStyle = CPTitledWindowMask;
|
||||||
|
|
||||||
|
_window = nil; // will be regenerated at next layout
|
||||||
|
_needsLayout = YES;
|
||||||
|
[super setTheme:aTheme];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! @deprecated
|
||||||
|
*/
|
||||||
|
- (void)setWindowStyle:(int)aStyle
|
||||||
|
{
|
||||||
|
CPLog.warn("DEPRECATED: setWindowStyle: is deprecated. use setTheme: instead");
|
||||||
|
[self setTheme:(aStyle === CPHUDBackgroundWindowMask) ? [CPTheme defaultHudTheme] : [CPTheme defaultTheme]];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! @deprecated
|
||||||
|
*/
|
||||||
|
- (int)windowStyle
|
||||||
|
{
|
||||||
|
CPLog.warn("DEPRECATED: windowStyle: is deprecated. use theme instead");
|
||||||
|
return _defaultWindowStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
set the text of the alert's message
|
||||||
|
|
||||||
|
@param aText CPString containing the text
|
||||||
|
*/
|
||||||
|
- (void)setMessageText:(CPString)aText
|
||||||
|
{
|
||||||
|
[_messageLabel setStringValue:aText];
|
||||||
|
_needsLayout = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
return the content of the message text
|
||||||
|
@return CPString containing the message text
|
||||||
|
*/
|
||||||
|
- (CPString)messageText
|
||||||
|
{
|
||||||
|
return [_messageLabel stringValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
set the text of the alert's informative text
|
||||||
|
|
||||||
|
@param aText CPString containing the informative text
|
||||||
|
*/
|
||||||
|
- (void)setInformativeText:(CPString)aText
|
||||||
|
{
|
||||||
|
[_informativeLabel setStringValue:aText];
|
||||||
|
_needsLayout = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
return the content of the message text
|
||||||
|
|
||||||
|
@return CPString containing the message text
|
||||||
|
*/
|
||||||
|
- (CPString)informativeText
|
||||||
|
{
|
||||||
|
return [_informativeLabel stringValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the title of the alert window.
|
||||||
|
This API is not present in Cocoa.
|
||||||
|
@param aTitle CPString containing the window title
|
||||||
|
*/
|
||||||
|
- (void)setTitle:(CPString)aTitle
|
||||||
|
{
|
||||||
|
_title = aTitle;
|
||||||
|
[_window setTitle:aTitle];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
set the accessory view
|
||||||
|
|
||||||
|
@param aView the accessory view
|
||||||
|
*/
|
||||||
|
- (void)setAccessoryView:(CPView)aView
|
||||||
|
{
|
||||||
|
_accessoryView = aView;
|
||||||
|
_needsLayout = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
set if alert shows the suppression button
|
||||||
|
|
||||||
|
@param shouldShowSuppressionButton YES or NO
|
||||||
|
*/
|
||||||
|
- (void)setShowsSuppressionButton:(BOOL)shouldShowSuppressionButton
|
||||||
|
{
|
||||||
|
_showSuppressionButton = shouldShowSuppressionButton;
|
||||||
|
_needsLayout = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark Accessing Buttons
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Adds a button with a given title to the receiver.
|
||||||
|
Buttons will be added starting from the right hand side of the \c CPAlert panel.
|
||||||
|
The first button will have the index 0, the second button 1 and so on.
|
||||||
|
|
||||||
|
The first button will automatically be given a key equivalent of Return,
|
||||||
|
and any button titled "Cancel" will be given a key equivalent of Escape.
|
||||||
|
|
||||||
|
You really shouldn't need more than 3 buttons.
|
||||||
|
|
||||||
|
@param title the title of the button
|
||||||
|
*/
|
||||||
|
- (void)addButtonWithTitle:(CPString)aTitle
|
||||||
|
{
|
||||||
|
var bounds = [[_window contentView] bounds],
|
||||||
|
count = [_buttons count],
|
||||||
|
|
||||||
|
button = [[CPButton alloc] initWithFrame:CGRectMakeZero()];
|
||||||
|
|
||||||
|
[button setTitle:aTitle];
|
||||||
|
[button setTag:count];
|
||||||
|
[button setTarget:self];
|
||||||
|
[button setAction:@selector(_takeReturnCodeFrom:)];
|
||||||
|
|
||||||
|
[[_window contentView] addSubview:button];
|
||||||
|
|
||||||
|
if (count == 0)
|
||||||
|
[button setKeyEquivalent:CPCarriageReturnCharacter];
|
||||||
|
else if ([aTitle lowercaseString] === @"cancel")
|
||||||
|
[button setKeyEquivalent:CPEscapeFunctionKey];
|
||||||
|
|
||||||
|
[_buttons insertObject:button atIndex:0];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark Layout
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
|
- (void)_layoutMessageView
|
||||||
|
{
|
||||||
|
var inset = [self currentValueForThemeAttribute:@"content-inset"],
|
||||||
|
sizeWithFontCorrection = 6.0,
|
||||||
|
messageLabelWidth,
|
||||||
|
messageLabelTextSize;
|
||||||
|
|
||||||
|
[_messageLabel setTextColor:[self currentValueForThemeAttribute:@"message-text-color"]];
|
||||||
|
[_messageLabel setFont:[self currentValueForThemeAttribute:@"message-text-font"]];
|
||||||
|
[_messageLabel setTextShadowColor:[self currentValueForThemeAttribute:@"message-text-shadow-color"]];
|
||||||
|
[_messageLabel setTextShadowOffset:[self currentValueForThemeAttribute:@"message-text-shadow-offset"]];
|
||||||
|
[_messageLabel setAlignment:[self currentValueForThemeAttribute:@"message-text-alignment"]];
|
||||||
|
[_messageLabel setLineBreakMode:CPLineBreakByWordWrapping];
|
||||||
|
|
||||||
|
messageLabelWidth = CGRectGetWidth([[_window contentView] frame]) - inset.left - inset.right;
|
||||||
|
messageLabelTextSize = [[_messageLabel stringValue] sizeWithFont:[_messageLabel font] inWidth:messageLabelWidth];
|
||||||
|
|
||||||
|
[_messageLabel setFrame:CGRectMake(inset.left, inset.top, messageLabelTextSize.width, messageLabelTextSize.height + sizeWithFontCorrection)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
|
- (void)_layoutInformativeView
|
||||||
|
{
|
||||||
|
var inset = [self currentValueForThemeAttribute:@"content-inset"],
|
||||||
|
defaultElementsMargin = [self currentValueForThemeAttribute:@"default-elements-margin"],
|
||||||
|
sizeWithFontCorrection = 6.0,
|
||||||
|
informativeLabelWidth,
|
||||||
|
informativeLabelOriginY,
|
||||||
|
informativeLabelTextSize;
|
||||||
|
|
||||||
|
[_informativeLabel setTextColor:[self currentValueForThemeAttribute:@"informative-text-color"]];
|
||||||
|
[_informativeLabel setFont:[self currentValueForThemeAttribute:@"informative-text-font"]];
|
||||||
|
[_informativeLabel setTextShadowColor:[self currentValueForThemeAttribute:@"informative-text-shadow-color"]];
|
||||||
|
[_informativeLabel setTextShadowOffset:[self currentValueForThemeAttribute:@"informative-text-shadow-offset"]];
|
||||||
|
[_informativeLabel setAlignment:[self currentValueForThemeAttribute:@"informative-text-alignment"]];
|
||||||
|
[_informativeLabel setLineBreakMode:CPLineBreakByWordWrapping];
|
||||||
|
|
||||||
|
informativeLabelWidth = CGRectGetWidth([[_window contentView] frame]) - inset.left - inset.right,
|
||||||
|
informativeLabelOriginY = [_messageLabel frameOrigin].y + [_messageLabel frameSize].height + defaultElementsMargin,
|
||||||
|
informativeLabelTextSize = [[_informativeLabel stringValue] sizeWithFont:[_informativeLabel font] inWidth:informativeLabelWidth];
|
||||||
|
|
||||||
|
[_informativeLabel setFrame:CGRectMake(inset.left, informativeLabelOriginY, informativeLabelTextSize.width, informativeLabelTextSize.height + sizeWithFontCorrection)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
|
- (void)_layoutAccessoryView
|
||||||
|
{
|
||||||
|
if (!_accessoryView)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var inset = [self currentValueForThemeAttribute:@"content-inset"],
|
||||||
|
defaultElementsMargin = [self currentValueForThemeAttribute:@"default-elements-margin"],
|
||||||
|
accessoryViewWidth = CGRectGetWidth([[_window contentView] frame]) - inset.left - inset.right,
|
||||||
|
accessoryViewOriginY = CGRectGetMaxY([_informativeLabel frame]) + defaultElementsMargin;
|
||||||
|
|
||||||
|
[_accessoryView setFrameOrigin:CGPointMake(inset.left, accessoryViewOriginY)];
|
||||||
|
[[_window contentView] addSubview:_accessoryView];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
|
- (void)_layoutSuppressionButton
|
||||||
|
{
|
||||||
|
if (!_showSuppressionButton)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var inset = [self currentValueForThemeAttribute:@"content-inset"],
|
||||||
|
suppressionViewXOffset = [self currentValueForThemeAttribute:@"suppression-button-x-offset"],
|
||||||
|
suppressionViewYOffset = [self currentValueForThemeAttribute:@"suppression-button-y-offset"],
|
||||||
|
defaultElementsMargin = [self currentValueForThemeAttribute:@"default-elements-margin"],
|
||||||
|
suppressionButtonViewOriginY = CGRectGetMaxY([(_accessoryView || _informativeLabel) frame]) + defaultElementsMargin + suppressionViewYOffset;
|
||||||
|
|
||||||
|
[_suppressionButton setTextColor:[self currentValueForThemeAttribute:@"suppression-button-text-color"]];
|
||||||
|
[_suppressionButton setFont:[self currentValueForThemeAttribute:@"suppression-button-text-font"]];
|
||||||
|
[_suppressionButton setTextShadowColor:[self currentValueForThemeAttribute:@"suppression-button-text-shadow-color"]];
|
||||||
|
[_suppressionButton setTextShadowOffset:[self currentValueForThemeAttribute:@"suppression-button-text-shadow-offset"]];
|
||||||
|
[_suppressionButton sizeToFit];
|
||||||
|
|
||||||
|
[_suppressionButton setFrameOrigin:CGPointMake(inset.left + suppressionViewXOffset, suppressionButtonViewOriginY)];
|
||||||
|
[[_window contentView] addSubview:_suppressionButton];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
|
- (CGSize)_layoutButtonsFromView:(CPView)lastView
|
||||||
|
{
|
||||||
|
var inset = [self currentValueForThemeAttribute:@"content-inset"],
|
||||||
|
minimumSize = [self currentValueForThemeAttribute:@"size"],
|
||||||
|
buttonOffset = [self currentValueForThemeAttribute:@"button-offset"],
|
||||||
|
helpLeftOffset = [self currentValueForThemeAttribute:@"help-image-left-offset"],
|
||||||
|
aRepresentativeButton = [_buttons objectAtIndex:0],
|
||||||
|
defaultElementsMargin = [self currentValueForThemeAttribute:@"default-elements-margin"],
|
||||||
|
panelSize = [[_window contentView] frame].size,
|
||||||
|
buttonsOriginY,
|
||||||
|
offsetX;
|
||||||
|
|
||||||
|
[aRepresentativeButton setTheme:[self theme]];
|
||||||
|
[aRepresentativeButton sizeToFit];
|
||||||
|
|
||||||
|
panelSize.height = CGRectGetMaxY([lastView frame]) + defaultElementsMargin + [aRepresentativeButton frameSize].height;
|
||||||
|
if (panelSize.height < minimumSize.height)
|
||||||
|
panelSize.height = minimumSize.height;
|
||||||
|
|
||||||
|
buttonsOriginY = panelSize.height - [aRepresentativeButton frameSize].height + buttonOffset;
|
||||||
|
offsetX = panelSize.width - inset.right;
|
||||||
|
|
||||||
|
for (var i = [_buttons count] - 1; i >= 0 ; i--)
|
||||||
|
{
|
||||||
|
var button = _buttons[i];
|
||||||
|
[button setTheme:[self theme]];
|
||||||
|
[button sizeToFit];
|
||||||
|
|
||||||
|
var buttonFrame = [button frame],
|
||||||
|
width = MAX(80.0, CGRectGetWidth(buttonFrame)),
|
||||||
|
height = CGRectGetHeight(buttonFrame);
|
||||||
|
|
||||||
|
offsetX -= width;
|
||||||
|
[button setFrame:CGRectMake(offsetX, buttonsOriginY, width, height)];
|
||||||
|
offsetX -= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_showHelp)
|
||||||
|
{
|
||||||
|
var helpImage = [self currentValueForThemeAttribute:@"help-image"],
|
||||||
|
helpImagePressed = [self currentValueForThemeAttribute:@"help-image-pressed"],
|
||||||
|
helpImageSize = helpImage ? [helpImage size] : CGSizeMakeZero(),
|
||||||
|
helpFrame = CGRectMake(helpLeftOffset, buttonsOriginY, helpImageSize.width, helpImageSize.height);
|
||||||
|
|
||||||
|
[_alertHelpButton setImage:helpImage];
|
||||||
|
[_alertHelpButton setAlternateImage:helpImagePressed];
|
||||||
|
[_alertHelpButton setBordered:NO];
|
||||||
|
[_alertHelpButton setFrame:helpFrame];
|
||||||
|
}
|
||||||
|
|
||||||
|
panelSize.height += [aRepresentativeButton frameSize].height + inset.bottom + buttonOffset;
|
||||||
|
return panelSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
|
- (void)layout
|
||||||
|
{
|
||||||
|
if (!_needsLayout)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!_window)
|
||||||
|
[self _createWindowWithStyle:nil];
|
||||||
|
|
||||||
|
var iconOffset = [self currentValueForThemeAttribute:@"image-offset"],
|
||||||
|
theImage = _icon,
|
||||||
|
finalSize;
|
||||||
|
|
||||||
|
if (!theImage)
|
||||||
|
switch (_alertStyle)
|
||||||
|
{
|
||||||
|
case CPWarningAlertStyle:
|
||||||
|
theImage = [self currentValueForThemeAttribute:@"warning-image"];
|
||||||
|
break;
|
||||||
|
case CPInformationalAlertStyle:
|
||||||
|
theImage = [self currentValueForThemeAttribute:@"information-image"];
|
||||||
|
break;
|
||||||
|
case CPCriticalAlertStyle:
|
||||||
|
theImage = [self currentValueForThemeAttribute:@"error-image"];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[_alertImageView setImage:theImage];
|
||||||
|
|
||||||
|
var imageSize = theImage ? [theImage size] : CGSizeMakeZero();
|
||||||
|
[_alertImageView setFrame:CGRectMake(iconOffset.x, iconOffset.y, imageSize.width, imageSize.height)];
|
||||||
|
|
||||||
|
[self _layoutMessageView];
|
||||||
|
[self _layoutInformativeView];
|
||||||
|
[self _layoutAccessoryView];
|
||||||
|
[self _layoutSuppressionButton];
|
||||||
|
|
||||||
|
var lastView = _informativeLabel;
|
||||||
|
if (_showSuppressionButton)
|
||||||
|
lastView = _suppressionButton;
|
||||||
|
else if (_accessoryView)
|
||||||
|
lastView = _accessoryView
|
||||||
|
|
||||||
|
finalSize = [self _layoutButtonsFromView:lastView];
|
||||||
|
if ([_window styleMask] & CPDocModalWindowMask)
|
||||||
|
finalSize.height -= 26; // adjust the absence of title bar
|
||||||
|
|
||||||
|
[_window setFrameSize:finalSize];
|
||||||
|
[_window center];
|
||||||
|
|
||||||
|
_needsLayout = NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark Displaying Alerts
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Displays the \c CPAlert panel as a modal dialog. The user will not be
|
||||||
|
able to interact with any other controls until s/he has dismissed the alert
|
||||||
|
by clicking on one of the buttons.
|
||||||
|
*/
|
||||||
|
- (void)runModal
|
||||||
|
{
|
||||||
|
if (!([_window styleMask] & _defaultWindowStyle))
|
||||||
|
{
|
||||||
|
_needsLayout = YES;
|
||||||
|
[self _createWindowWithStyle:_defaultWindowStyle];
|
||||||
|
}
|
||||||
|
|
||||||
|
[self layout];
|
||||||
|
[CPApp runModalForWindow:_window];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Runs the receiver modally as an alert sheet attached to a specified window.
|
||||||
|
|
||||||
|
@param window The parent window for the sheet.
|
||||||
|
@param modalDelegate The delegate for the modal-dialog session.
|
||||||
|
@param alertDidEndSelector Message the alert sends to modalDelegate after the sheet is dismissed.
|
||||||
|
@param contextInfo Contextual data passed to modalDelegate in didEndSelector message.
|
||||||
|
*/
|
||||||
|
- (void)beginSheetModalForWindow:(CPWindow)aWindow modalDelegate:(id)modalDelegate didEndSelector:(SEL)alertDidEndSelector contextInfo:(id)contextInfo
|
||||||
|
{
|
||||||
|
if (!([_window styleMask] & CPDocModalWindowMask))
|
||||||
|
{
|
||||||
|
_needsLayout = YES;
|
||||||
|
[self _createWindowWithStyle:CPDocModalWindowMask];
|
||||||
|
}
|
||||||
|
|
||||||
|
[self layout];
|
||||||
|
|
||||||
|
_modalDelegate = modalDelegate;
|
||||||
|
_didEndSelector = alertDidEndSelector;
|
||||||
|
|
||||||
|
[CPApp beginSheet:_window modalForWindow:aWindow modalDelegate:self didEndSelector:@selector(_alertDidEnd:returnCode:contextInfo:) contextInfo:contextInfo];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Runs the receiver modally as an alert sheet attached to a specified window.
|
||||||
|
|
||||||
|
@param window The parent window for the sheet.
|
||||||
|
*/
|
||||||
|
- (void)beginSheetModalForWindow:(CPWindow)aWindow
|
||||||
|
{
|
||||||
|
[self beginSheetModalForWindow:aWindow modalDelegate:nil didEndSelector:nil contextInfo:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark Private
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
|
- (void)_createWindowWithStyle:(int)forceStyle
|
||||||
|
{
|
||||||
|
var frame = CGRectMakeZero();
|
||||||
|
frame.size = [self currentValueForThemeAttribute:@"size"];
|
||||||
|
|
||||||
|
_window = [[CPWindow alloc] initWithContentRect:frame styleMask:forceStyle || _defaultWindowStyle];
|
||||||
|
|
||||||
|
if (_title)
|
||||||
|
[_window setTitle:_title];
|
||||||
|
|
||||||
|
var contentView = [_window contentView],
|
||||||
|
count = [_buttons count];
|
||||||
|
|
||||||
|
if (count)
|
||||||
|
while (count--)
|
||||||
|
[contentView addSubview:_buttons[count]];
|
||||||
|
else
|
||||||
|
[self addButtonWithTitle:@"OK"];
|
||||||
|
|
||||||
|
[contentView addSubview:_messageLabel];
|
||||||
|
[contentView addSubview:_alertImageView];
|
||||||
|
[contentView addSubview:_informativeLabel];
|
||||||
|
|
||||||
|
if (_showHelp)
|
||||||
|
[contentView addSubview:_alertHelpButton];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
|
- (@action)_showHelp:(id)aSender
|
||||||
|
{
|
||||||
|
if ([_delegate respondsToSelector:@selector(alertShowHelp:)])
|
||||||
|
[_delegate alertShowHelp:self];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
|
- (@action)_takeReturnCodeFrom:(id)aSender
|
||||||
|
{
|
||||||
|
if ([_window isSheet])
|
||||||
|
[CPApp endSheet:_window returnCode:[aSender tag]];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[CPApp abortModal];
|
||||||
|
[_window close];
|
||||||
|
|
||||||
|
[self _alertDidEnd:_window returnCode:[aSender tag] contextInfo:nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
|
- (void)_alertDidEnd:(CPWindow)aWindow returnCode:(int)returnCode contextInfo:(id)contextInfo
|
||||||
|
{
|
||||||
|
if ([_delegate respondsToSelector:@selector(alertDidEnd:returnCode:)])
|
||||||
|
[_delegate alertDidEnd:self returnCode:returnCode];
|
||||||
|
|
||||||
|
if (_didEndSelector)
|
||||||
|
objj_msgSend(_modalDelegate, _didEndSelector, self, returnCode, contextInfo);
|
||||||
|
|
||||||
|
_modalDelegate = nil;
|
||||||
|
_didEndSelector = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark Theme Attributes
|
||||||
|
|
||||||
+ (CPString)defaultThemeClass
|
+ (CPString)defaultThemeClass
|
||||||
{
|
{
|
||||||
return @"alert";
|
return @"alert";
|
||||||
@@ -104,7 +671,17 @@ CPCriticalAlertStyle = 2;
|
|||||||
CGPointMake(15, 12),
|
CGPointMake(15, 12),
|
||||||
[CPNull null],
|
[CPNull null],
|
||||||
[CPNull null],
|
[CPNull null],
|
||||||
[CPNull null]
|
[CPNull null],
|
||||||
|
[CPNull null],
|
||||||
|
[CPNull null],
|
||||||
|
[CPNull null],
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
3.0,
|
||||||
|
[CPColor blackColor],
|
||||||
|
[CPFont systemFontOfSize:12.0],
|
||||||
|
[CPNull null],
|
||||||
|
0.0
|
||||||
]
|
]
|
||||||
forKeys:[@"size", @"content-inset", @"informative-offset", @"button-offset",
|
forKeys:[@"size", @"content-inset", @"informative-offset", @"button-offset",
|
||||||
@"message-text-alignment", @"message-text-color", @"message-text-font", @"message-text-shadow-color", @"message-text-shadow-offset",
|
@"message-text-alignment", @"message-text-color", @"message-text-font", @"message-text-shadow-color", @"message-text-shadow-offset",
|
||||||
@@ -112,359 +689,18 @@ CPCriticalAlertStyle = 2;
|
|||||||
@"image-offset",
|
@"image-offset",
|
||||||
@"information-image",
|
@"information-image",
|
||||||
@"warning-image",
|
@"warning-image",
|
||||||
@"error-image"
|
@"error-image",
|
||||||
|
@"help-image",
|
||||||
|
@"help-image-left-offset",
|
||||||
|
@"help-image-pressed",
|
||||||
|
@"suppression-button-y-offset",
|
||||||
|
@"suppression-button-x-offset",
|
||||||
|
@"default-elements-margin",
|
||||||
|
@"suppression-button-text-color",
|
||||||
|
@"suppression-button-text-font",
|
||||||
|
@"suppression-button-text-shadow-color",
|
||||||
|
@"suppression-button-text-shadow-offset"
|
||||||
]];
|
]];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
Initializes a \c CPAlert panel with the default alert style \c CPWarningAlertStyle.
|
|
||||||
*/
|
|
||||||
- (id)init
|
|
||||||
{
|
|
||||||
if (self = [super init])
|
|
||||||
{
|
|
||||||
_buttons = [CPArray array];
|
|
||||||
_alertStyle = CPWarningAlertStyle;
|
|
||||||
_alertPanel = nil;
|
|
||||||
_windowStyle = nil;
|
|
||||||
_didEndSelector = nil;
|
|
||||||
|
|
||||||
_messageLabel = [CPTextField labelWithTitle:@"Alert"];
|
|
||||||
_alertImageView = [[CPImageView alloc] initWithFrame:CGRectMakeZero()];
|
|
||||||
_informativeLabel = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Sets the window appearance. If CPHUDBackgroundWindowMask is set, the default HUD theme
|
|
||||||
will be activated.
|
|
||||||
|
|
||||||
@param styleMask - Either CPHUDBackgroundWindowMask or nil for standard.
|
|
||||||
*/
|
|
||||||
- (void)setWindowStyle:(int)styleMask
|
|
||||||
{
|
|
||||||
_windowStyle = styleMask;
|
|
||||||
|
|
||||||
[self setTheme:(_windowStyle & CPHUDBackgroundWindowMask) ? [CPTheme defaultHudTheme] : [CPTheme defaultTheme]];
|
|
||||||
|
|
||||||
// We'll need to recreate the panel to get the new window style.
|
|
||||||
_alertPanel = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_createPanel
|
|
||||||
{
|
|
||||||
var frame = CGRectMakeZero();
|
|
||||||
frame.size = [self currentValueForThemeAttribute:@"size"];
|
|
||||||
_alertPanel = [[CPPanel alloc] initWithContentRect:frame styleMask:_windowStyle ? _windowStyle | CPTitledWindowMask : CPTitledWindowMask];
|
|
||||||
|
|
||||||
var contentView = [_alertPanel contentView],
|
|
||||||
count = [_buttons count];
|
|
||||||
|
|
||||||
if (count)
|
|
||||||
{
|
|
||||||
while (count--)
|
|
||||||
[contentView addSubview:_buttons[count]];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
[self addButtonWithTitle:@"OK"];
|
|
||||||
|
|
||||||
[contentView addSubview:_messageLabel];
|
|
||||||
[contentView addSubview:_alertImageView];
|
|
||||||
[contentView addSubview:_informativeLabel];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Sets the window's title. If this is not defined, a default title based on your warning level will be used.
|
|
||||||
@param aTitle the title to use in place of the default. Set to nil to use default.
|
|
||||||
*/
|
|
||||||
- (void)setTitle:(CPString)aTitle
|
|
||||||
{
|
|
||||||
_windowTitle = aTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Gets the window's title.
|
|
||||||
*/
|
|
||||||
- (CPString)title
|
|
||||||
{
|
|
||||||
return _windowTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Gets the window's style.
|
|
||||||
*/
|
|
||||||
- (int)windowStyle
|
|
||||||
{
|
|
||||||
return _windowStyle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Sets the receiver’s delegate.
|
|
||||||
@param delegate - Delegate for the alert. nil removes the delegate.
|
|
||||||
*/
|
|
||||||
- (void)setDelegate:(id)delegate
|
|
||||||
{
|
|
||||||
_delegate = delegate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Gets the receiver's delegate.
|
|
||||||
*/
|
|
||||||
- (void)delegate
|
|
||||||
{
|
|
||||||
return _delegate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Sets the alert style of the receiver.
|
|
||||||
@param style - Alert style for the alert.
|
|
||||||
*/
|
|
||||||
- (void)setAlertStyle:(CPAlertStyle)style
|
|
||||||
{
|
|
||||||
_alertStyle = style;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Gets the alert style.
|
|
||||||
*/
|
|
||||||
- (CPAlertStyle)alertStyle
|
|
||||||
{
|
|
||||||
return _alertStyle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Sets the receiver’s message text, or title, to a given text.
|
|
||||||
@param messageText - Message text for the alert.
|
|
||||||
*/
|
|
||||||
- (void)setMessageText:(CPString)messageText
|
|
||||||
{
|
|
||||||
[_messageLabel setStringValue:messageText];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns the receiver's message text body.
|
|
||||||
*/
|
|
||||||
- (CPString)messageText
|
|
||||||
{
|
|
||||||
return [_messageLabel stringValue];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Sets the receiver's informative text, shown below the message text.
|
|
||||||
@param informativeText - The informative text.
|
|
||||||
*/
|
|
||||||
- (void)setInformativeText:(CPString)informativeText
|
|
||||||
{
|
|
||||||
[_informativeLabel setStringValue:informativeText];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns the receiver's informative text.
|
|
||||||
*/
|
|
||||||
- (CPString)informativeText
|
|
||||||
{
|
|
||||||
return [_informativeLabel stringValue];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Adds a button with a given title to the receiver.
|
|
||||||
Buttons will be added starting from the right hand side of the \c CPAlert panel.
|
|
||||||
The first button will have the index 0, the second button 1 and so on.
|
|
||||||
|
|
||||||
The first button will automatically be given a key equivalent of Return,
|
|
||||||
and any button titled "Cancel" will be given a key equivalent of Escape.
|
|
||||||
|
|
||||||
You really shouldn't need more than 3 buttons.
|
|
||||||
*/
|
|
||||||
- (void)addButtonWithTitle:(CPString)title
|
|
||||||
{
|
|
||||||
var bounds = [[_alertPanel contentView] bounds],
|
|
||||||
button = [[CPButton alloc] initWithFrame:CGRectMakeZero()],
|
|
||||||
_buttonCount = [_buttons count];
|
|
||||||
|
|
||||||
[button setTitle:title];
|
|
||||||
[button setTarget:self];
|
|
||||||
[button setTag:_buttonCount];
|
|
||||||
[button setAction:@selector(_dismissAlert:)];
|
|
||||||
|
|
||||||
[[_alertPanel contentView] addSubview:button];
|
|
||||||
|
|
||||||
if (_buttonCount == 0)
|
|
||||||
[button setKeyEquivalent:CPCarriageReturnCharacter];
|
|
||||||
else if ([title lowercaseString] === "cancel")
|
|
||||||
[button setKeyEquivalent:CPEscapeFunctionKey];
|
|
||||||
else
|
|
||||||
[button setKeyEquivalent:nil];
|
|
||||||
|
|
||||||
[_buttons insertObject:button atIndex:0];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)layoutPanel
|
|
||||||
{
|
|
||||||
if (!_alertPanel)
|
|
||||||
[self _createPanel];
|
|
||||||
|
|
||||||
var inset = [self currentValueForThemeAttribute:@"content-inset"],
|
|
||||||
iconOffset = [self currentValueForThemeAttribute:@"image-offset"],
|
|
||||||
theTitle,
|
|
||||||
theImage;
|
|
||||||
|
|
||||||
switch (_alertStyle)
|
|
||||||
{
|
|
||||||
case CPWarningAlertStyle: theImage = [self currentValueForThemeAttribute:@"warning-image"];
|
|
||||||
theTitle = @"Warning";
|
|
||||||
break;
|
|
||||||
case CPInformationalAlertStyle: theImage = [self currentValueForThemeAttribute:@"information-image"];
|
|
||||||
theTitle = @"Information";
|
|
||||||
break;
|
|
||||||
case CPCriticalAlertStyle: theImage = [self currentValueForThemeAttribute:@"error-image"];
|
|
||||||
theTitle = @"Error";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
[_alertImageView setImage:theImage];
|
|
||||||
|
|
||||||
var imageSize = theImage ? [theImage size] : CGSizeMakeZero();
|
|
||||||
[_alertImageView setFrame:CGRectMake(iconOffset.x, iconOffset.y, imageSize.width, imageSize.height)];
|
|
||||||
|
|
||||||
[_alertPanel setTitle:_windowTitle ? _windowTitle : theTitle];
|
|
||||||
[_alertPanel setFloatingPanel:YES];
|
|
||||||
[_alertPanel center];
|
|
||||||
|
|
||||||
[_messageLabel setTextColor:[self currentValueForThemeAttribute:@"message-text-color"]];
|
|
||||||
[_messageLabel setFont:[self currentValueForThemeAttribute:@"message-text-font"]];
|
|
||||||
[_messageLabel setTextShadowColor:[self currentValueForThemeAttribute:@"message-text-shadow-color"]];
|
|
||||||
[_messageLabel setTextShadowOffset:[self currentValueForThemeAttribute:@"message-text-shadow-offset"]];
|
|
||||||
[_messageLabel setAlignment:[self currentValueForThemeAttribute:@"message-text-alignment"]];
|
|
||||||
[_messageLabel setLineBreakMode:CPLineBreakByWordWrapping];
|
|
||||||
|
|
||||||
[_informativeLabel setTextColor:[self currentValueForThemeAttribute:@"informative-text-color"]];
|
|
||||||
[_informativeLabel setFont:[self currentValueForThemeAttribute:@"informative-text-font"]];
|
|
||||||
[_informativeLabel setTextShadowColor:[self currentValueForThemeAttribute:@"informative-text-shadow-color"]];
|
|
||||||
[_informativeLabel setTextShadowOffset:[self currentValueForThemeAttribute:@"informative-text-shadow-offset"]];
|
|
||||||
[_informativeLabel setLineBreakMode:CPLineBreakByWordWrapping];
|
|
||||||
|
|
||||||
// FIXME sizeWithFontCorrection shouldn't be needed.
|
|
||||||
var bounds = [[_alertPanel contentView] bounds],
|
|
||||||
offsetX = CGRectGetWidth(bounds) - inset.right,
|
|
||||||
informativeOffset = [self currentValueForThemeAttribute:@"informative-offset"],
|
|
||||||
buttonOffset = [self currentValueForThemeAttribute:@"button-offset"],
|
|
||||||
|
|
||||||
textWidth = offsetX - inset.left,
|
|
||||||
messageSize = [([_messageLabel stringValue] || " ") sizeWithFont:[_messageLabel font] inWidth:textWidth],
|
|
||||||
informationString = [_informativeLabel stringValue],
|
|
||||||
informativeSize = [(informationString || " ") sizeWithFont:[_informativeLabel font] inWidth:textWidth],
|
|
||||||
sizeWithFontCorrection = 6.0;
|
|
||||||
|
|
||||||
[_messageLabel setFrame:CGRectMake(inset.left, inset.top, textWidth, messageSize.height + sizeWithFontCorrection)];
|
|
||||||
[_informativeLabel setFrame:CGRectMake(inset.left, CGRectGetMaxY([_messageLabel frame]) + informativeOffset, textWidth, informativeSize.height + sizeWithFontCorrection)];
|
|
||||||
// Don't let an empty informative label partially cover the buttons.
|
|
||||||
[_informativeLabel setHidden:!informationString];
|
|
||||||
|
|
||||||
var aRepresentativeButton = _buttons[0],
|
|
||||||
buttonY = MAX(CGRectGetMaxY([_alertImageView frame]), CGRectGetMaxY(informationString ? [_informativeLabel frame] : [_messageLabel frame])) + buttonOffset; // the lower of the bottom of the text and the bottom of the icon.
|
|
||||||
|
|
||||||
[aRepresentativeButton setTheme:[self theme]];
|
|
||||||
[aRepresentativeButton sizeToFit];
|
|
||||||
|
|
||||||
// Make the window just tall enough to fit everything. Bit of a hack really.
|
|
||||||
var minimumSize = [self currentValueForThemeAttribute:@"size"],
|
|
||||||
desiredHeight = MAX(minimumSize.height, buttonY + CGRectGetHeight([aRepresentativeButton bounds]) + inset.bottom),
|
|
||||||
deltaY = desiredHeight - CGRectGetHeight(bounds),
|
|
||||||
frameSize = CGSizeMakeCopy([_alertPanel frame].size);
|
|
||||||
|
|
||||||
frameSize.height += deltaY;
|
|
||||||
[_alertPanel setFrameSize:frameSize];
|
|
||||||
|
|
||||||
var count = [_buttons count];
|
|
||||||
|
|
||||||
while (count--)
|
|
||||||
{
|
|
||||||
var button = _buttons[count];
|
|
||||||
[button setTheme:[self theme]];
|
|
||||||
[button sizeToFit];
|
|
||||||
|
|
||||||
var buttonBounds = [button bounds],
|
|
||||||
width = MAX(80.0, CGRectGetWidth(buttonBounds)),
|
|
||||||
height = CGRectGetHeight(buttonBounds);
|
|
||||||
|
|
||||||
offsetX -= width;
|
|
||||||
[button setFrame:CGRectMake(offsetX, buttonY, width, height)];
|
|
||||||
offsetX -= 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Displays the \c CPAlert panel as a modal dialog. The user will not be
|
|
||||||
able to interact with any other controls until s/he has dismissed the alert
|
|
||||||
by clicking on one of the buttons.
|
|
||||||
*/
|
|
||||||
- (void)runModal
|
|
||||||
{
|
|
||||||
[self layoutPanel];
|
|
||||||
[CPApp runModalForWindow:_alertPanel];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Runs the receiver modally as an alert sheet attached to a specified window.
|
|
||||||
|
|
||||||
@param window The parent window for the sheet.
|
|
||||||
@param modalDelegate The delegate for the modal-dialog session.
|
|
||||||
@param alertDidEndSelector Message the alert sends to modalDelegate after the sheet is dismissed.
|
|
||||||
@param contextInfo Contextual data passed to modalDelegate in didEndSelector message.
|
|
||||||
*/
|
|
||||||
- (void)beginSheetModalForWindow:(CPWindow)window modalDelegate:(id)modalDelegate didEndSelector:(SEL)alertDidEndSelector contextInfo:(void)contextInfo
|
|
||||||
{
|
|
||||||
if (!(_windowStyle & CPDocModalWindowMask))
|
|
||||||
[self setWindowStyle:CPDocModalWindowMask];
|
|
||||||
[self layoutPanel];
|
|
||||||
|
|
||||||
_didEndSelector = alertDidEndSelector;
|
|
||||||
_modalDelegate = modalDelegate;
|
|
||||||
|
|
||||||
[CPApp beginSheet:_alertPanel modalForWindow:window modalDelegate:self didEndSelector:@selector(_alertDidEnd:returnCode:contextInfo:) contextInfo:contextInfo];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Runs the receiver modally as an alert sheet attached to a specified window.
|
|
||||||
|
|
||||||
@param window The parent window for the sheet.
|
|
||||||
*/
|
|
||||||
- (void)beginSheetModalForWindow:(CPWindow)window
|
|
||||||
{
|
|
||||||
if (!(_windowStyle & CPDocModalWindowMask))
|
|
||||||
[self setWindowStyle:CPDocModalWindowMask];
|
|
||||||
[self layoutPanel];
|
|
||||||
|
|
||||||
[CPApp beginSheet:_alertPanel modalForWindow:window modalDelegate:self didEndSelector:@selector(_alertDidEnd:returnCode:contextInfo:) contextInfo:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_alertDidEnd:(CPWindow)aSheet returnCode:(CPInteger)returnCode contextInfo:(id)contextInfo
|
|
||||||
{
|
|
||||||
if ([_delegate respondsToSelector:@selector(alertDidEnd:returnCode:)])
|
|
||||||
[_delegate alertDidEnd:self returnCode:returnCode];
|
|
||||||
|
|
||||||
if (_didEndSelector)
|
|
||||||
objj_msgSend(_modalDelegate, _didEndSelector, self, returnCode, contextInfo);
|
|
||||||
|
|
||||||
_didEndSelector = nil;
|
|
||||||
_modalDelegate = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* @ignore */
|
|
||||||
- (void)_dismissAlert:(CPButton)button
|
|
||||||
{
|
|
||||||
if ([_alertPanel isSheet])
|
|
||||||
[CPApp endSheet:_alertPanel returnCode:[button tag]];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
[CPApp abortModal];
|
|
||||||
[_alertPanel close];
|
|
||||||
|
|
||||||
[self _alertDidEnd:nil returnCode:[button tag] contextInfo:nil];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -312,7 +312,7 @@ ACTUAL_FRAME_RATE = 0;
|
|||||||
[_timingFunction getControlPointAtIndex:1 values:c1];
|
[_timingFunction getControlPointAtIndex:1 values:c1];
|
||||||
[_timingFunction getControlPointAtIndex:2 values:c2];
|
[_timingFunction getControlPointAtIndex:2 values:c2];
|
||||||
|
|
||||||
return CubicBezierAtTime(t,c1[0],c1[1],c2[0],c2[1],_duration);
|
return CubicBezierAtTime(t, c1[0], c1[1], c2[0], c2[1], _duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -320,28 +320,104 @@ ACTUAL_FRAME_RATE = 0;
|
|||||||
// currently used function to determine time
|
// currently used function to determine time
|
||||||
// 1:1 conversion to js from webkit source files
|
// 1:1 conversion to js from webkit source files
|
||||||
// UnitBezier.h, WebCore_animation_AnimationBase.cpp
|
// UnitBezier.h, WebCore_animation_AnimationBase.cpp
|
||||||
var CubicBezierAtTime = function CubicBezierAtTime(t,p1x,p1y,p2x,p2y,duration)
|
var CubicBezierAtTime = function CubicBezierAtTime(t, p1x, p1y, p2x, p2y, duration)
|
||||||
{
|
{
|
||||||
var ax=0,bx=0,cx=0,ay=0,by=0,cy=0;
|
var ax = 0,
|
||||||
|
bx = 0,
|
||||||
|
cx = 0,
|
||||||
|
ay = 0,
|
||||||
|
by = 0,
|
||||||
|
cy = 0;
|
||||||
// `ax t^3 + bx t^2 + cx t' expanded using Horner's rule.
|
// `ax t^3 + bx t^2 + cx t' expanded using Horner's rule.
|
||||||
function sampleCurveX(t) {return ((ax*t+bx)*t+cx)*t;};
|
function sampleCurveX(t)
|
||||||
function sampleCurveY(t) {return ((ay*t+by)*t+cy)*t;};
|
{
|
||||||
function sampleCurveDerivativeX(t) {return (3.0*ax*t+2.0*bx)*t+cx;};
|
return ((ax * t + bx) * t + cx) * t;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sampleCurveY(t)
|
||||||
|
{
|
||||||
|
return ((ay * t + by) * t + cy) * t;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sampleCurveDerivativeX(t)
|
||||||
|
{
|
||||||
|
return (3.0 * ax * t + 2.0 * bx) * t + cx;
|
||||||
|
}
|
||||||
|
|
||||||
// The epsilon value to pass given that the animation is going to run over |duration| seconds. The longer the animation, the more precision is needed in the timing function result to avoid ugly discontinuities.
|
// The epsilon value to pass given that the animation is going to run over |duration| seconds. The longer the animation, the more precision is needed in the timing function result to avoid ugly discontinuities.
|
||||||
function solveEpsilon(duration) {return 1.0/(200.0*duration);};
|
function solveEpsilon(duration)
|
||||||
function solve(x,epsilon) {return sampleCurveY(solveCurveX(x,epsilon));};
|
{
|
||||||
|
return 1.0 / (200.0 * duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
function solve(x, epsilon)
|
||||||
|
{
|
||||||
|
return sampleCurveY(solveCurveX(x, epsilon));
|
||||||
|
}
|
||||||
|
|
||||||
// Given an x value, find a parametric value it came from.
|
// Given an x value, find a parametric value it came from.
|
||||||
function solveCurveX(x,epsilon) {var t0,t1,t2,x2,d2,i;
|
function solveCurveX(x, epsilon)
|
||||||
function fabs(n) {if(n>=0) {return n;}else {return 0-n;}};
|
{
|
||||||
|
var t0,
|
||||||
|
t1,
|
||||||
|
t2 = x,
|
||||||
|
x2,
|
||||||
|
d2,
|
||||||
|
i = 0;
|
||||||
|
|
||||||
// First try a few iterations of Newton's method -- normally very fast.
|
// First try a few iterations of Newton's method -- normally very fast.
|
||||||
for(t2=x, i=0; i<8; i++) {x2=sampleCurveX(t2)-x; if(fabs(x2)<epsilon) {return t2;} d2=sampleCurveDerivativeX(t2); if(fabs(d2)<1e-6) {break;} t2=t2-x2/d2;}
|
for (; i < 8; i++)
|
||||||
|
{
|
||||||
|
x2 = sampleCurveX(t2) - x;
|
||||||
|
|
||||||
|
if (ABS(x2) < epsilon)
|
||||||
|
return t2;
|
||||||
|
|
||||||
|
d2 = sampleCurveDerivativeX(t2);
|
||||||
|
|
||||||
|
if (ABS(d2) < 1e-6)
|
||||||
|
break;
|
||||||
|
|
||||||
|
t2 = t2 - x2 / d2;
|
||||||
|
}
|
||||||
|
|
||||||
// Fall back to the bisection method for reliability.
|
// Fall back to the bisection method for reliability.
|
||||||
t0=0.0; t1=1.0; t2=x; if(t2<t0) {return t0;} if(t2>t1) {return t1;}
|
t0 = 0.0;
|
||||||
while(t0<t1) {x2=sampleCurveX(t2); if(fabs(x2-x)<epsilon) {return t2;} if(x>x2) {t0=t2;}else {t1=t2;} t2=(t1-t0)*.5+t0;}
|
t1 = 1.0;
|
||||||
|
t2 = x;
|
||||||
|
|
||||||
|
if (t2 < t0)
|
||||||
|
return t0;
|
||||||
|
|
||||||
|
if (t2 > t1)
|
||||||
|
return t1;
|
||||||
|
|
||||||
|
while (t0 < t1)
|
||||||
|
{
|
||||||
|
x2 = sampleCurveX(t2);
|
||||||
|
|
||||||
|
if (ABS(x2 - x) < epsilon)
|
||||||
|
return t2;
|
||||||
|
|
||||||
|
if (x > x2)
|
||||||
|
t0 = t2;
|
||||||
|
|
||||||
|
else
|
||||||
|
t1 = t2;
|
||||||
|
|
||||||
|
t2 = (t1 - t0) * 0.5 + t0;
|
||||||
|
}
|
||||||
|
|
||||||
return t2; // Failure.
|
return t2; // Failure.
|
||||||
};
|
};
|
||||||
// Calculate the polynomial coefficients, implicit first and last control points are (0,0) and (1,1).
|
// Calculate the polynomial coefficients, implicit first and last control points are (0,0) and (1,1).
|
||||||
cx=3.0*p1x; bx=3.0*(p2x-p1x)-cx; ax=1.0-cx-bx; cy=3.0*p1y; by=3.0*(p2y-p1y)-cy; ay=1.0-cy-by;
|
cx = 3.0 * p1x;
|
||||||
|
bx = 3.0 * (p2x - p1x) - cx;
|
||||||
|
ax = 1.0 - cx - bx;
|
||||||
|
cy = 3.0 * p1y;
|
||||||
|
by = 3.0 * (p2y - p1y) - cy;
|
||||||
|
ay = 1.0 - cy - by;
|
||||||
|
|
||||||
// Convert from input time to parametric value in curve, then from that to output time.
|
// Convert from input time to parametric value in curve, then from that to output time.
|
||||||
return solve(t, solveEpsilon(duration));
|
return solve(t, solveEpsilon(duration));
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -908,7 +908,7 @@ CPRunContinuesResponse = -1002;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([args class] != CPArray)
|
if (![args isKindOfClass:CPArray])
|
||||||
args = [CPArray arrayWithObject:args];
|
args = [CPArray arrayWithObject:args];
|
||||||
|
|
||||||
_args = args;
|
_args = args;
|
||||||
|
|||||||
@@ -108,6 +108,7 @@
|
|||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
|
_sortDescriptors = [CPArray array];
|
||||||
_selectionIndexes = [CPIndexSet indexSet];
|
_selectionIndexes = [CPIndexSet indexSet];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +206,7 @@
|
|||||||
|
|
||||||
- (void)_setContentSet:(id)aSet
|
- (void)_setContentSet:(id)aSet
|
||||||
{
|
{
|
||||||
[self setContent:aSet];
|
[self setContent:[aSet allObjects]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)contentArray
|
- (id)contentArray
|
||||||
@@ -215,7 +216,7 @@
|
|||||||
|
|
||||||
- (id)contentSet
|
- (id)contentSet
|
||||||
{
|
{
|
||||||
return [self content];
|
return [CPSet setWithArray:[self content]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CPArray)arrangeObjects:(CPArray)objects
|
- (CPArray)arrangeObjects:(CPArray)objects
|
||||||
@@ -393,7 +394,8 @@
|
|||||||
|
|
||||||
// Push back the new selection to the model for selectionIndexes if we have one.
|
// Push back the new selection to the model for selectionIndexes if we have one.
|
||||||
// There won't be an infinite loop because of the equality check above.
|
// There won't be an infinite loop because of the equality check above.
|
||||||
[[CPKeyValueBinding getBinding:@"selectionIndexes" forObject:self] reverseSetValueFor:@"selectionIndexes"];
|
var binderClass = [[self class] _binderClassForBinding:@"selectionIndexes"];
|
||||||
|
[[binderClass getBinding:@"selectionIndexes" forObject:self] reverseSetValueFor:@"selectionIndexes"];
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
@@ -534,9 +536,6 @@
|
|||||||
|
|
||||||
- (void)removeObject:(id)object
|
- (void)removeObject:(id)object
|
||||||
{
|
{
|
||||||
if (![self canRemove])
|
|
||||||
return;
|
|
||||||
|
|
||||||
[self willChangeValueForKey:@"content"];
|
[self willChangeValueForKey:@"content"];
|
||||||
[_contentObject removeObject:object];
|
[_contentObject removeObject:object];
|
||||||
|
|
||||||
@@ -598,9 +597,6 @@
|
|||||||
|
|
||||||
- (void)removeObjects:(CPArray)objects
|
- (void)removeObjects:(CPArray)objects
|
||||||
{
|
{
|
||||||
if (![self canRemove])
|
|
||||||
return;
|
|
||||||
|
|
||||||
[self _removeObjects:objects];
|
[self _removeObjects:objects];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -642,30 +638,49 @@
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
var CPArrayControllerAvoidsEmptySelection = @"CPArrayControllerAvoidsEmptySelection",
|
||||||
|
CPArrayControllerClearsFilterPredicateOnInsertion = @"CPArrayControllerClearsFilterPredicateOnInsertion",
|
||||||
|
CPArrayControllerFilterRestrictsInsertion = @"CPArrayControllerFilterRestrictsInsertion",
|
||||||
|
CPArrayControllerPreservesSelection = @"CPArrayControllerPreservesSelection",
|
||||||
|
CPArrayControllerSelectsInsertedObjects = @"CPArrayControllerSelectsInsertedObjects",
|
||||||
|
CPArrayControllerAlwaysUsesMultipleValuesMarker = @"CPArrayControllerAlwaysUsesMultipleValuesMarker";
|
||||||
|
|
||||||
@implementation CPArrayController (CPCoding)
|
@implementation CPArrayController (CPCoding)
|
||||||
|
|
||||||
- (id)initWithCoder:(CPCoder)aCoder
|
- (id)initWithCoder:(CPCoder)aCoder
|
||||||
{
|
{
|
||||||
self = [super initWithCoder:coder];
|
self = [super initWithCoder:aCoder];
|
||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
_avoidsEmptySelection = [coder decodeBoolForKey:@"CPArrayControllerAvoidsEmptySelection"];
|
_avoidsEmptySelection = [aCoder decodeBoolForKey:CPArrayControllerAvoidsEmptySelection];
|
||||||
_clearsFilterPredicateOnInsertion = [coder decodeBoolForKey:@"CPClearsFilterPredicateOnInsertion"];
|
_clearsFilterPredicateOnInsertion = [aCoder decodeBoolForKey:CPArrayControllerClearsFilterPredicateOnInsertion];
|
||||||
_filterRestrictsInsertion = [coder decodeBoolForKey:@"CPArrayControllerFilterRestrictsInsertion"];
|
_filterRestrictsInsertion = [aCoder decodeBoolForKey:CPArrayControllerFilterRestrictsInsertion];
|
||||||
_preservesSelection = [coder decodeBoolForKey:@"CPArrayControllerPreservesSelection"];
|
_preservesSelection = [aCoder decodeBoolForKey:CPArrayControllerPreservesSelection];
|
||||||
_selectsInsertedObjects = [coder decodeBoolForKey:@"CPArrayControllerSelectsInsertedObjects"];
|
_selectsInsertedObjects = [aCoder decodeBoolForKey:CPArrayControllerSelectsInsertedObjects];
|
||||||
_alwaysUsesMultipleValuesMarker = [coder decodeBoolForKey:@"CPArrayControllerAlwaysUsesMultipleValuesMarker"];
|
_alwaysUsesMultipleValuesMarker = [aCoder decodeBoolForKey:CPArrayControllerAlwaysUsesMultipleValuesMarker];
|
||||||
|
|
||||||
if ([self automaticallyPreparesContent])
|
if (![self content] && [self automaticallyPreparesContent])
|
||||||
[self prepareContent];
|
[self prepareContent];
|
||||||
else
|
else if (![self content])
|
||||||
[self _setContentArray:[]];
|
[self _setContentArray:[]];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)encodeWithCoder:(CPCoder)aCoder
|
||||||
|
{
|
||||||
|
[super encodeWithCoder:aCoder];
|
||||||
|
|
||||||
|
[aCoder encodeBool:_avoidsEmptySelection forKey:CPArrayControllerAvoidsEmptySelection];
|
||||||
|
[aCoder encodeBool:_clearsFilterPredicateOnInsertion forKey:CPArrayControllerClearsFilterPredicateOnInsertion];
|
||||||
|
[aCoder encodeBool:_filterRestrictsInsertion forKey:CPArrayControllerFilterRestrictsInsertion];
|
||||||
|
[aCoder encodeBool:_preservesSelection forKey:CPArrayControllerPreservesSelection];
|
||||||
|
[aCoder encodeBool:_selectsInsertedObjects forKey:CPArrayControllerSelectsInsertedObjects];
|
||||||
|
[aCoder encodeBool:_alwaysUsesMultipleValuesMarker forKey:CPArrayControllerAlwaysUsesMultipleValuesMarker];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)awakeFromCib
|
- (void)awakeFromCib
|
||||||
{
|
{
|
||||||
[self _selectionWillChange];
|
[self _selectionWillChange];
|
||||||
|
|||||||
@@ -184,7 +184,6 @@ var DefaultLineWidth = 1.0;
|
|||||||
CGContextBeginPath(ctx);
|
CGContextBeginPath(ctx);
|
||||||
CGContextAddPath(ctx, _path);
|
CGContextAddPath(ctx, _path);
|
||||||
CGContextSetLineWidth(ctx, [self lineWidth]);
|
CGContextSetLineWidth(ctx, [self lineWidth]);
|
||||||
CGContextClosePath(ctx);
|
|
||||||
CGContextStrokePath(ctx);
|
CGContextStrokePath(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,6 +280,7 @@ var DefaultLineWidth = 1.0;
|
|||||||
{
|
{
|
||||||
CGPathAddPath(_path, nil, other._path);
|
CGPathAddPath(_path, nil, other._path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Remove all path elements; clears path.
|
Remove all path elements; clears path.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
// CPBoxType
|
// CPBoxType
|
||||||
CPBoxPrimary = 0;
|
CPBoxPrimary = 0;
|
||||||
CPBoxSecondary = 1;
|
CPBoxSecondary = 1;
|
||||||
CPBoxSeperator = 2;
|
CPBoxSeparator = 2;
|
||||||
CPBoxOldStyle = 3;
|
CPBoxOldStyle = 3;
|
||||||
CPBoxCustom = 4;
|
CPBoxCustom = 4;
|
||||||
|
|
||||||
@@ -234,7 +234,7 @@ CPGrooveBorder = 3;
|
|||||||
|
|
||||||
switch (_boxType)
|
switch (_boxType)
|
||||||
{
|
{
|
||||||
case CPBoxSeperator:
|
case CPBoxSeparator:
|
||||||
// NSBox does not include a horitontal flag for the seperator type. We have to determine
|
// NSBox does not include a horitontal flag for the seperator type. We have to determine
|
||||||
// the type of seperator to draw by the width and height of the frame.
|
// the type of seperator to draw by the width and height of the frame.
|
||||||
if (CGRectGetWidth(bounds) === 5.0)
|
if (CGRectGetWidth(bounds) === 5.0)
|
||||||
@@ -265,8 +265,8 @@ CPGrooveBorder = 3;
|
|||||||
CGContextSetStrokeColor(context, [self borderColor]);
|
CGContextSetStrokeColor(context, [self borderColor]);
|
||||||
CGContextSetLineWidth(context, 1.0);
|
CGContextSetLineWidth(context, 1.0);
|
||||||
|
|
||||||
CGContextMoveToPoint(context, CGRectGetMinX(aRect), CGRectGetMinY(aRect));
|
CGContextMoveToPoint(context, CGRectGetMinX(aRect), CGRectGetMinY(aRect) + 0.5);
|
||||||
CGContextAddLineToPoint(context, CGRectGetWidth(aRect), CGRectGetMinY(aRect));
|
CGContextAddLineToPoint(context, CGRectGetWidth(aRect), CGRectGetMinY(aRect) + 0.5);
|
||||||
CGContextStrokePath(context);
|
CGContextStrokePath(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,8 +277,8 @@ CPGrooveBorder = 3;
|
|||||||
CGContextSetStrokeColor(context, [self borderColor]);
|
CGContextSetStrokeColor(context, [self borderColor]);
|
||||||
CGContextSetLineWidth(context, 1.0);
|
CGContextSetLineWidth(context, 1.0);
|
||||||
|
|
||||||
CGContextMoveToPoint(context, CGRectGetMinX(aRect), CGRectGetMinY(aRect));
|
CGContextMoveToPoint(context, CGRectGetMinX(aRect) + 0.5, CGRectGetMinY(aRect));
|
||||||
CGContextAddLineToPoint(context, CGRectGetMinX(aRect), CGRectGetHeight(aRect));
|
CGContextAddLineToPoint(context, CGRectGetMinX(aRect) + 0.5, CGRectGetHeight(aRect));
|
||||||
CGContextStrokePath(context);
|
CGContextStrokePath(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,13 @@ CPPushInCellMask = CPPushInButtonMask;
|
|||||||
CPChangeGrayCellMask = CPGrayButtonMask;
|
CPChangeGrayCellMask = CPGrayButtonMask;
|
||||||
CPChangeBackgroundCellMask = CPBackgroundButtonMask;
|
CPChangeBackgroundCellMask = CPBackgroundButtonMask;
|
||||||
|
|
||||||
CPButtonStateMixed = CPThemeState("mixed");
|
CPButtonStateMixed = CPThemeState("mixed");
|
||||||
|
CPButtonStateBezelStyleRounded = CPThemeState("rounded");
|
||||||
|
|
||||||
|
// add all future correspondance between bezel styles and theme state here.
|
||||||
|
var CPButtonBezelStyleStateMap = [CPDictionary dictionaryWithObjects:[CPButtonStateBezelStyleRounded, nil]
|
||||||
|
forKeys:[CPRoundedBezelStyle, CPRoundRectBezelStyle]];
|
||||||
|
|
||||||
|
|
||||||
CPButtonDefaultHeight = 24.0;
|
CPButtonDefaultHeight = 24.0;
|
||||||
CPButtonImageOffset = 3.0;
|
CPButtonImageOffset = 3.0;
|
||||||
@@ -129,6 +135,11 @@ CPButtonImageOffset = 3.0;
|
|||||||
forKeys:[@"image", @"image-offset", @"bezel-inset", @"content-inset", @"bezel-color"]];
|
forKeys:[@"image", @"image-offset", @"bezel-inset", @"content-inset", @"bezel-color"]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Initializes and returns a newly allocated CPButton object with a specified frame rectangle.
|
||||||
|
@param aFrame The frame rectangle for the created button object.
|
||||||
|
@return An initialized CPView object or nil if the object couldn't be created.
|
||||||
|
*/
|
||||||
- (id)initWithFrame:(CGRect)aFrame
|
- (id)initWithFrame:(CGRect)aFrame
|
||||||
{
|
{
|
||||||
self = [super initWithFrame:aFrame];
|
self = [super initWithFrame:aFrame];
|
||||||
@@ -146,7 +157,7 @@ CPButtonImageOffset = 3.0;
|
|||||||
_keyEquivalent = @"";
|
_keyEquivalent = @"";
|
||||||
_keyEquivalentModifierMask = 0;
|
_keyEquivalentModifierMask = 0;
|
||||||
|
|
||||||
// [self setBezelStyle:CPRoundRectBezelStyle];
|
[self setBezelStyle:CPRoundRectBezelStyle];
|
||||||
[self setBordered:YES];
|
[self setBordered:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +166,8 @@ CPButtonImageOffset = 3.0;
|
|||||||
|
|
||||||
// Setting the state
|
// Setting the state
|
||||||
/*!
|
/*!
|
||||||
Returns \c YES if the button has a 'mixed' state in addition to on and off.
|
Returns a Boolean value indicating whether the button allows a mixed state.
|
||||||
|
@return \c YES if the button has a 'mixed' state in addition to on and off.
|
||||||
*/
|
*/
|
||||||
- (BOOL)allowsMixedState
|
- (BOOL)allowsMixedState
|
||||||
{
|
{
|
||||||
@@ -179,6 +191,10 @@ CPButtonImageOffset = 3.0;
|
|||||||
[self setState:CPOnState];
|
[self setState:CPOnState];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the value of the button using an Objective-J object.
|
||||||
|
@param anObjectValue The value of the button interpreted as an Objective-J object.
|
||||||
|
*/
|
||||||
- (void)setObjectValue:(id)anObjectValue
|
- (void)setObjectValue:(id)anObjectValue
|
||||||
{
|
{
|
||||||
if (!anObjectValue || anObjectValue === @"" || ([anObjectValue intValue] === 0))
|
if (!anObjectValue || anObjectValue === @"" || ([anObjectValue intValue] === 0))
|
||||||
@@ -187,7 +203,7 @@ CPButtonImageOffset = 3.0;
|
|||||||
else if (![anObjectValue isKindOfClass:[CPNumber class]])
|
else if (![anObjectValue isKindOfClass:[CPNumber class]])
|
||||||
anObjectValue = CPOnState;
|
anObjectValue = CPOnState;
|
||||||
|
|
||||||
else if (anObjectValue > CPOnState)
|
else if (anObjectValue >= CPOnState)
|
||||||
anObjectValue = CPOnState
|
anObjectValue = CPOnState
|
||||||
|
|
||||||
else if (anObjectValue < CPOffState)
|
else if (anObjectValue < CPOffState)
|
||||||
@@ -213,6 +229,13 @@ CPButtonImageOffset = 3.0;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the button's next state.
|
||||||
|
@return The button's state. A button can have two or three states.
|
||||||
|
If it has two, this value is either \c CPOffState (the normal or unpressed state)
|
||||||
|
or \c CPOnState (the alternate or pressed state).
|
||||||
|
If it has three, this value can be \c CPOnState (the feature is in effect everywhere), \c CPOffState (the feature is in effect nowhere), or \c CPMixedState (the feature is in effect somewhere).
|
||||||
|
*/
|
||||||
- (CPInteger)nextState
|
- (CPInteger)nextState
|
||||||
{
|
{
|
||||||
if ([self allowsMixedState])
|
if ([self allowsMixedState])
|
||||||
@@ -225,8 +248,16 @@ CPButtonImageOffset = 3.0;
|
|||||||
return 1 - [self state];
|
return 1 - [self state];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the button's next state to \c aState.
|
||||||
|
@param aState Possible states are any of the CPButton globals:
|
||||||
|
\c CPOffState, \c CPOnState, \c CPMixedState
|
||||||
|
*/
|
||||||
- (void)setNextState
|
- (void)setNextState
|
||||||
{
|
{
|
||||||
|
if ([self infoForBinding:CPValueBinding])
|
||||||
|
[self setAllowsMixedState:NO];
|
||||||
|
|
||||||
[self setState:[self nextState]];
|
[self setState:[self nextState]];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,6 +279,11 @@ CPButtonImageOffset = 3.0;
|
|||||||
return [self intValue];
|
return [self intValue];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the title displayed by the button when in its normal state.
|
||||||
|
@param aTitle The string to set as the button's title. This title is always shown on buttons
|
||||||
|
that don’t use their alternate contents when highlighting or displaying their alternate state.
|
||||||
|
*/
|
||||||
- (void)setTitle:(CPString)aTitle
|
- (void)setTitle:(CPString)aTitle
|
||||||
{
|
{
|
||||||
if (_title === aTitle)
|
if (_title === aTitle)
|
||||||
@@ -259,6 +295,11 @@ CPButtonImageOffset = 3.0;
|
|||||||
[self setNeedsDisplay:YES];
|
[self setNeedsDisplay:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the title displayed on the button when it’s in its normal state.
|
||||||
|
@return The title displayed on the receiver when it’s in its normal state
|
||||||
|
or the empty string if the button doesn’t display a title.
|
||||||
|
*/
|
||||||
- (CPString)title
|
- (CPString)title
|
||||||
{
|
{
|
||||||
return _title;
|
return _title;
|
||||||
@@ -493,6 +534,9 @@ CPButtonImageOffset = 3.0;
|
|||||||
size.height = MIN(size.height, maxSize.height);
|
size.height = MIN(size.height, maxSize.height);
|
||||||
|
|
||||||
[self setFrameSize:size];
|
[self setFrameSize:size];
|
||||||
|
|
||||||
|
if (contentView)
|
||||||
|
[self layoutSubviews];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aName
|
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aName
|
||||||
@@ -643,10 +687,24 @@ CPButtonImageOffset = 3.0;
|
|||||||
|
|
||||||
- (void)setBezelStyle:(unsigned)aBezelStyle
|
- (void)setBezelStyle:(unsigned)aBezelStyle
|
||||||
{
|
{
|
||||||
|
if (aBezelStyle === _bezelStyle)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var currentState = [CPButtonBezelStyleStateMap objectForKey:_bezelStyle],
|
||||||
|
newState = [CPButtonBezelStyleStateMap objectForKey:aBezelStyle];
|
||||||
|
|
||||||
|
if (currentState)
|
||||||
|
[self unsetThemeState:currentState];
|
||||||
|
|
||||||
|
if (newState)
|
||||||
|
[self setThemeState:newState];
|
||||||
|
|
||||||
|
_bezelStyle = aBezelStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (unsigned)bezelStyle
|
- (unsigned)bezelStyle
|
||||||
{
|
{
|
||||||
|
return _bezelStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -44,6 +44,14 @@ CPCheckBoxImageOffset = 4.0;
|
|||||||
return @"check-box";
|
return @"check-box";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (Class)_binderClassForBinding:(CPString)theBinding
|
||||||
|
{
|
||||||
|
if (theBinding === CPValueBinding)
|
||||||
|
return [_CPCheckBoxValueBinder class];
|
||||||
|
|
||||||
|
return [super _binderClassForBinding:theBinding];
|
||||||
|
}
|
||||||
|
|
||||||
- (id)initWithFrame:(CGRect)aFrame
|
- (id)initWithFrame:(CGRect)aFrame
|
||||||
{
|
{
|
||||||
self = [super initWithFrame:aFrame];
|
self = [super initWithFrame:aFrame];
|
||||||
@@ -87,3 +95,53 @@ CPCheckBoxImageOffset = 4.0;
|
|||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@implementation _CPCheckBoxValueBinder : CPBinder
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setValueFor:(CPString)theBinding
|
||||||
|
{
|
||||||
|
var destination = [_info objectForKey:CPObservedObjectKey],
|
||||||
|
keyPath = [_info objectForKey:CPObservedKeyPathKey],
|
||||||
|
options = [_info objectForKey:CPOptionsKey],
|
||||||
|
newValue = [destination valueForKeyPath:keyPath],
|
||||||
|
isPlaceholder = CPIsControllerMarker(newValue);
|
||||||
|
|
||||||
|
if (isPlaceholder)
|
||||||
|
{
|
||||||
|
switch (newValue)
|
||||||
|
{
|
||||||
|
case CPMultipleValuesMarker:
|
||||||
|
newValue = CPMixedState;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CPNoSelectionMarker:
|
||||||
|
newValue = CPOffState;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CPNotApplicableMarker:
|
||||||
|
if ([options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
|
||||||
|
[CPException raise:CPGenericException reason:@"can't transform non applicable key on: "+_source+" value: "+newValue];
|
||||||
|
|
||||||
|
newValue = CPOffState;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newValue === CPMixedState)
|
||||||
|
{
|
||||||
|
[_source setAllowsMixedState:YES];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Cocoa will always set allowsMixedState to NO
|
||||||
|
// This behavior will be fine for Cappuccino as well if we (like Cocoa)
|
||||||
|
// default the CPConditionallySetsEnabledBindingOption to YES
|
||||||
|
[_source setAllowsMixedState:NO];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[_source setState:newValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|||||||
@@ -203,8 +203,8 @@
|
|||||||
*/
|
*/
|
||||||
- (void)setContent:(CPArray)anArray
|
- (void)setContent:(CPArray)anArray
|
||||||
{
|
{
|
||||||
if (_content == anArray)
|
// reset the _selectionIndexes
|
||||||
return;
|
[self setSelectionIndexes:[CPIndexSet indexSet]];
|
||||||
|
|
||||||
_content = anArray;
|
_content = anArray;
|
||||||
|
|
||||||
@@ -312,7 +312,8 @@
|
|||||||
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound)
|
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound)
|
||||||
[_items[index] setSelected:YES];
|
[_items[index] setSelected:YES];
|
||||||
|
|
||||||
[[CPKeyValueBinding getBinding:@"selectionIndexes" forObject:self] reverseSetValueFor:@"selectionIndexes"];
|
var binderClass = [[self class] _binderClassForBinding:@"selectionIndexes"];
|
||||||
|
[[binderClass getBinding:@"selectionIndexes" forObject:self] reverseSetValueFor:@"selectionIndexes"];
|
||||||
|
|
||||||
if ([_delegate respondsToSelector:@selector(collectionViewDidChangeSelection:)])
|
if ([_delegate respondsToSelector:@selector(collectionViewDidChangeSelection:)])
|
||||||
[_delegate collectionViewDidChangeSelection:self];
|
[_delegate collectionViewDidChangeSelection:self];
|
||||||
|
|||||||
@@ -534,7 +534,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
|
|||||||
{
|
{
|
||||||
var point = [self convertPoint:[anEvent locationInWindow] fromView:nil];
|
var point = [self convertPoint:[anEvent locationInWindow] fromView:nil];
|
||||||
|
|
||||||
if(point.x > [self bounds].size.width - 1 || point.x < 1)
|
if (point.x > [self bounds].size.width - 1 || point.x < 1)
|
||||||
return NO;
|
return NO;
|
||||||
|
|
||||||
[[CPPasteboard pasteboardWithName:CPDragPboard] declareTypes:[CPArray arrayWithObject:CPColorDragType] owner:self];
|
[[CPPasteboard pasteboardWithName:CPDragPboard] declareTypes:[CPArray arrayWithObject:CPColorDragType] owner:self];
|
||||||
|
|||||||
@@ -141,18 +141,20 @@ var CPControlBlackColor = [CPColor blackColor];
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_reverseSetBinding
|
+ (Class)_binderClassForBinding:(CPString)theBinding
|
||||||
{
|
{
|
||||||
var theBinding = [CPKeyValueBinding getBinding:CPValueBinding forObject:self];
|
if (theBinding === CPValueBinding)
|
||||||
[theBinding reverseSetValueFor:@"objectValue"];
|
return [_CPValueBinder class];
|
||||||
|
|
||||||
|
return [super _binderClassForBinding:theBinding];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_replacementKeyPathForBinding:(CPString)aBinding
|
- (void)_reverseSetBinding
|
||||||
{
|
{
|
||||||
if (aBinding === @"value")
|
var binderClass = [[self class] _binderClassForBinding:CPValueBinding],
|
||||||
return @"objectValue";
|
theBinding = [binderClass getBinding:CPValueBinding forObject:self];
|
||||||
|
|
||||||
return [super _replacementKeyPathForBinding:aBinding];
|
[theBinding reverseSetValueFor:@"objectValue"];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithFrame:(CGRect)aFrame
|
- (id)initWithFrame:(CGRect)aFrame
|
||||||
@@ -286,9 +288,14 @@ var CPControlBlackColor = [CPColor blackColor];
|
|||||||
[self stopTracking:_previousTrackingLocation at:currentLocation mouseIsUp:YES];
|
[self stopTracking:_previousTrackingLocation at:currentLocation mouseIsUp:YES];
|
||||||
|
|
||||||
_trackingMouseDownFlags = 0;
|
_trackingMouseDownFlags = 0;
|
||||||
|
|
||||||
|
if (isWithinFrame)
|
||||||
|
[self setThemeState:CPThemeStateHovered];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
[self unsetThemeState:CPThemeStateHovered];
|
||||||
|
|
||||||
if (type === CPLeftMouseDown)
|
if (type === CPLeftMouseDown)
|
||||||
{
|
{
|
||||||
_trackingMouseDownFlags = [anEvent modifierFlags];
|
_trackingMouseDownFlags = [anEvent modifierFlags];
|
||||||
@@ -384,6 +391,25 @@ var CPControlBlackColor = [CPColor blackColor];
|
|||||||
[self trackMouse:anEvent];
|
[self trackMouse:anEvent];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)mouseEntered:(CPEvent)anEvent
|
||||||
|
{
|
||||||
|
if (![self isEnabled])
|
||||||
|
return;
|
||||||
|
|
||||||
|
[self setThemeState:CPThemeStateHovered];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mouseExited:(CPEvent)anEvent
|
||||||
|
{
|
||||||
|
var currentLocation = [self convertPoint:[anEvent locationInWindow] fromView:nil],
|
||||||
|
isWithinFrame = [self tracksMouseOutsideOfFrame] || CGRectContainsPoint([self bounds], currentLocation);
|
||||||
|
|
||||||
|
// Make sure we're not still in the frame because Cappuccino will sent mouseExited events
|
||||||
|
// for all of the (ephemeral) subviews of a view as well.
|
||||||
|
if (!isWithinFrame)
|
||||||
|
[self unsetThemeState:CPThemeStateHovered];
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the receiver's object value
|
Returns the receiver's object value
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -390,13 +390,14 @@ var CPSharedDocumentController = nil;
|
|||||||
|
|
||||||
- (void)noteNewRecentDocument:(CPDocument)aDocument
|
- (void)noteNewRecentDocument:(CPDocument)aDocument
|
||||||
{
|
{
|
||||||
[self noteNewRecentDocumentURL:[[aDocument fileURL] absoluteString]];
|
[self noteNewRecentDocumentURL:[aDocument fileURL]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)noteNewRecentDocumentURL:(CPString)aURL
|
- (void)noteNewRecentDocumentURL:(CPURL)aURL
|
||||||
{
|
{
|
||||||
|
var urlAsString = [aURL isKindOfClass:CPString] ? aURL : [aURL absoluteString];
|
||||||
if (typeof window["cpNoteNewRecentDocumentPath"] === 'function')
|
if (typeof window["cpNoteNewRecentDocumentPath"] === 'function')
|
||||||
window.cpNoteNewRecentDocumentPath(aURL);
|
window.cpNoteNewRecentDocumentPath(urlAsString);
|
||||||
|
|
||||||
[self _updateRecentDocumentsMenu];
|
[self _updateRecentDocumentsMenu];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -220,14 +220,14 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
|
|||||||
[_draggingUpdateTimer invalidate];
|
[_draggingUpdateTimer invalidate];
|
||||||
_draggingUpdateTimer = nil;
|
_draggingUpdateTimer = nil;
|
||||||
|
|
||||||
var dragOperation = CPDragOperationCopy;
|
var dragOperation = CPDragOperationCopy,
|
||||||
// We have to convert base to bridge since the drag event comes from the source window, not the drag window.
|
// We have to convert base to bridge since the drag event comes from the source window, not the drag window.
|
||||||
var draggingDestination = [aPlatformWindow _dragHitTest:aLocation pasteboard:[CPDragServerDraggingInfo draggingPasteboard]];
|
draggingDestination = [aPlatformWindow _dragHitTest:aLocation pasteboard:[CPDragServerDraggingInfo draggingPasteboard]];
|
||||||
|
|
||||||
if (draggingDestination)
|
if (draggingDestination)
|
||||||
_draggingLocation = [DRAGGING_WINDOW(draggingDestination) convertPlatformWindowToBase:aLocation];
|
_draggingLocation = [DRAGGING_WINDOW(draggingDestination) convertPlatformWindowToBase:aLocation];
|
||||||
|
|
||||||
if(draggingDestination !== _draggingDestination)
|
if (draggingDestination !== _draggingDestination)
|
||||||
{
|
{
|
||||||
if ([_draggingDestination respondsToSelector:@selector(draggingExited:)])
|
if ([_draggingDestination respondsToSelector:@selector(draggingExited:)])
|
||||||
[_draggingDestination draggingExited:CPDragServerDraggingInfo];
|
[_draggingDestination draggingExited:CPDragServerDraggingInfo];
|
||||||
@@ -456,8 +456,8 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
|
|||||||
}
|
}
|
||||||
else if (type === CPKeyDown)
|
else if (type === CPKeyDown)
|
||||||
{
|
{
|
||||||
var keyCode = [anEvent keyCode];
|
var characters = [anEvent characters];
|
||||||
if (keyCode === CPEscapeKeyCode)
|
if (characters === CPEscapeFunctionKey)
|
||||||
{
|
{
|
||||||
_dragOperation = CPDragOperationNone;
|
_dragOperation = CPDragOperationNone;
|
||||||
[self draggingEndedInPlatformWindow:platformWindow globalLocation:CGPointMakeZero() operation:_dragOperation];
|
[self draggingEndedInPlatformWindow:platformWindow globalLocation:CGPointMakeZero() operation:_dragOperation];
|
||||||
|
|||||||
@@ -158,6 +158,7 @@ CPFindFunctionKey = "\uF745";
|
|||||||
CPHelpFunctionKey = "\uF746";
|
CPHelpFunctionKey = "\uF746";
|
||||||
CPModeSwitchFunctionKey = "\uF747";
|
CPModeSwitchFunctionKey = "\uF747";
|
||||||
CPEscapeFunctionKey = "\u001B";
|
CPEscapeFunctionKey = "\u001B";
|
||||||
|
CPSpaceFunctionKey = "\u0020";
|
||||||
|
|
||||||
|
|
||||||
CPDOMEventDoubleClick = "dblclick",
|
CPDOMEventDoubleClick = "dblclick",
|
||||||
@@ -527,7 +528,8 @@ var _CPEventPeriodicEventPeriod = 0,
|
|||||||
if (_CPEventUpperCaseRegex.test(aKeyEquivalent))
|
if (_CPEventUpperCaseRegex.test(aKeyEquivalent))
|
||||||
aKeyEquivalentModifierMask |= CPShiftKeyMask;
|
aKeyEquivalentModifierMask |= CPShiftKeyMask;
|
||||||
|
|
||||||
if (CPBrowserIsOperatingSystem(CPWindowsOperatingSystem) && (aKeyEquivalentModifierMask & CPCommandKeyMask))
|
// Windows and Linux don't have command keys, so just switch it to ctrl.
|
||||||
|
if (!CPBrowserIsOperatingSystem(CPMacOperatingSystem) && (aKeyEquivalentModifierMask & CPCommandKeyMask))
|
||||||
{
|
{
|
||||||
aKeyEquivalentModifierMask |= CPControlKeyMask;
|
aKeyEquivalentModifierMask |= CPControlKeyMask;
|
||||||
aKeyEquivalentModifierMask &= ~CPCommandKeyMask;
|
aKeyEquivalentModifierMask &= ~CPCommandKeyMask;
|
||||||
@@ -556,9 +558,9 @@ var _CPEventPeriodicEventPeriod = 0,
|
|||||||
if (_modifierFlags & (CPCommandKeyMask | CPControlKeyMask))
|
if (_modifierFlags & (CPCommandKeyMask | CPControlKeyMask))
|
||||||
return YES;
|
return YES;
|
||||||
|
|
||||||
for(var i=0; i<characterCount; i++)
|
for (var i = 0; i < characterCount; i++)
|
||||||
{
|
{
|
||||||
switch(_characters.charAt(i))
|
switch (_characters.charAt(i))
|
||||||
{
|
{
|
||||||
case CPBackspaceCharacter:
|
case CPBackspaceCharacter:
|
||||||
case CPDeleteCharacter:
|
case CPDeleteCharacter:
|
||||||
@@ -566,6 +568,7 @@ var _CPEventPeriodicEventPeriod = 0,
|
|||||||
case CPTabCharacter:
|
case CPTabCharacter:
|
||||||
case CPCarriageReturnCharacter:
|
case CPCarriageReturnCharacter:
|
||||||
case CPNewlineCharacter:
|
case CPNewlineCharacter:
|
||||||
|
case CPSpaceFunctionKey:
|
||||||
case CPEscapeFunctionKey:
|
case CPEscapeFunctionKey:
|
||||||
case CPPageUpFunctionKey:
|
case CPPageUpFunctionKey:
|
||||||
case CPPageDownFunctionKey:
|
case CPPageDownFunctionKey:
|
||||||
@@ -573,10 +576,12 @@ var _CPEventPeriodicEventPeriod = 0,
|
|||||||
case CPUpArrowFunctionKey:
|
case CPUpArrowFunctionKey:
|
||||||
case CPRightArrowFunctionKey:
|
case CPRightArrowFunctionKey:
|
||||||
case CPDownArrowFunctionKey:
|
case CPDownArrowFunctionKey:
|
||||||
|
case CPEndFunctionKey:
|
||||||
|
case CPHomeFunctionKey:
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// FIXME: More cases? Space?
|
// FIXME: More cases?
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
@import <Foundation/CPObject.j>
|
@import <Foundation/CPObject.j>
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
@class CPFlashMovie
|
@class CPFlashMovie
|
||||||
|
|
||||||
@@ -52,10 +52,10 @@
|
|||||||
- (id)initWithFile:(CPString)aFilename
|
- (id)initWithFile:(CPString)aFilename
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
_filename = aFilename;
|
_filename = aFilename;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,10 +32,10 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
|
|||||||
@implementation CPFlashView : CPView
|
@implementation CPFlashView : CPView
|
||||||
{
|
{
|
||||||
CPFlashMovie _flashMovie;
|
CPFlashMovie _flashMovie;
|
||||||
|
|
||||||
CPDictionary _params;
|
CPDictionary _params;
|
||||||
CPDictionary _paramElements;
|
CPDictionary _paramElements;
|
||||||
#if PLATFORM(DOM)
|
#if PLATFORM(DOM)
|
||||||
DOMElement _DOMParamElement;
|
DOMElement _DOMParamElement;
|
||||||
DOMElement _DOMObjectElement;
|
DOMElement _DOMObjectElement;
|
||||||
DOMElement _DOMInnerObjectElement;
|
DOMElement _DOMInnerObjectElement;
|
||||||
@@ -45,7 +45,7 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
|
|||||||
- (id)initWithFrame:(CGRect)aFrame
|
- (id)initWithFrame:(CGRect)aFrame
|
||||||
{
|
{
|
||||||
self = [super initWithFrame:aFrame];
|
self = [super initWithFrame:aFrame];
|
||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
#if PLATFORM(DOM)
|
#if PLATFORM(DOM)
|
||||||
@@ -58,24 +58,24 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
|
|||||||
_DOMObjectElement.style.left = @"0px";
|
_DOMObjectElement.style.left = @"0px";
|
||||||
_DOMObjectElement.type = @"application/x-shockwave-flash";
|
_DOMObjectElement.type = @"application/x-shockwave-flash";
|
||||||
_DOMObjectElement.setAttribute(@"classid", IEFlashCLSID);
|
_DOMObjectElement.setAttribute(@"classid", IEFlashCLSID);
|
||||||
|
|
||||||
_DOMParamElement = document.createElement(@"param");
|
_DOMParamElement = document.createElement(@"param");
|
||||||
_DOMParamElement.name = @"movie";
|
_DOMParamElement.name = @"movie";
|
||||||
|
|
||||||
_DOMInnerObjectElement = document.createElement(@"object");
|
_DOMInnerObjectElement = document.createElement(@"object");
|
||||||
_DOMInnerObjectElement.width = @"100%";
|
_DOMInnerObjectElement.width = @"100%";
|
||||||
_DOMInnerObjectElement.height = @"100%";
|
_DOMInnerObjectElement.height = @"100%";
|
||||||
|
|
||||||
_DOMObjectElement.appendChild(_DOMParamElement);
|
_DOMObjectElement.appendChild(_DOMParamElement);
|
||||||
_DOMObjectElement.appendChild(_DOMInnerObjectElement);
|
_DOMObjectElement.appendChild(_DOMInnerObjectElement);
|
||||||
|
|
||||||
_DOMElement.appendChild(_DOMObjectElement);
|
_DOMElement.appendChild(_DOMObjectElement);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
[self _rebuildIEObjects];
|
[self _rebuildIEObjects];
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
|
|||||||
{
|
{
|
||||||
if (_flashMovie == aFlashMovie)
|
if (_flashMovie == aFlashMovie)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_flashMovie = aFlashMovie;
|
_flashMovie = aFlashMovie;
|
||||||
#if PLATFORM(DOM)
|
#if PLATFORM(DOM)
|
||||||
if (!CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
|
if (!CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
|
||||||
@@ -105,14 +105,14 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
|
|||||||
{
|
{
|
||||||
var varString = @"",
|
var varString = @"",
|
||||||
enumerator = [aDictionary keyEnumerator];
|
enumerator = [aDictionary keyEnumerator];
|
||||||
|
|
||||||
var key;
|
var key;
|
||||||
while (key = [enumerator nextObject])
|
while (key = [enumerator nextObject])
|
||||||
varString = [varString stringByAppendingFormat:@"&%@=%@", key, [aDictionary objectForKey:key]];
|
varString = [varString stringByAppendingFormat:@"&%@=%@", key, [aDictionary objectForKey:key]];
|
||||||
|
|
||||||
if (!_params)
|
if (!_params)
|
||||||
_params = [CPDictionary dictionary];
|
_params = [CPDictionary dictionary];
|
||||||
|
|
||||||
[_params setObject:varString forKey:@"flashvars"];
|
[_params setObject:varString forKey:@"flashvars"];
|
||||||
[self setParameters:_params];
|
[self setParameters:_params];
|
||||||
}
|
}
|
||||||
@@ -129,7 +129,7 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
|
|||||||
{
|
{
|
||||||
var elements = [_paramElements allValues],
|
var elements = [_paramElements allValues],
|
||||||
count = [elements count];
|
count = [elements count];
|
||||||
|
|
||||||
for (var i = 0; i < count; i++)
|
for (var i = 0; i < count; i++)
|
||||||
_DOMObjectElement.removeChild([elements objectAtIndex:i]);
|
_DOMObjectElement.removeChild([elements objectAtIndex:i]);
|
||||||
}
|
}
|
||||||
@@ -139,18 +139,18 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
|
|||||||
if (!CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
|
if (!CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
|
||||||
{
|
{
|
||||||
_paramElements = [CPDictionary dictionary];
|
_paramElements = [CPDictionary dictionary];
|
||||||
|
|
||||||
var enumerator = [_params keyEnumerator],
|
var enumerator = [_params keyEnumerator],
|
||||||
key;
|
key;
|
||||||
|
|
||||||
while (key = [enumerator nextObject] && _DOMObjectElement)
|
while (key = [enumerator nextObject] && _DOMObjectElement)
|
||||||
{
|
{
|
||||||
var param = document.createElement(@"param");
|
var param = document.createElement(@"param");
|
||||||
param.name = key;
|
param.name = key;
|
||||||
param.value = [_params objectForKey:key];
|
param.value = [_params objectForKey:key];
|
||||||
|
|
||||||
_DOMObjectElement.appendChild(param);
|
_DOMObjectElement.appendChild(param);
|
||||||
|
|
||||||
[_paramElements setObject:param forKey:key];
|
[_paramElements setObject:param forKey:key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -170,17 +170,17 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
|
|||||||
_DOMElement.innerHTML = @"";
|
_DOMElement.innerHTML = @"";
|
||||||
if (![_flashMovie filename])
|
if (![_flashMovie filename])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var paramString = [CPString stringWithFormat:@"<param name='movie' value='%@' />", [_flashMovie filename]],
|
var paramString = [CPString stringWithFormat:@"<param name='movie' value='%@' />", [_flashMovie filename]],
|
||||||
paramEnumerator = [_params keyEnumerator],
|
paramEnumerator = [_params keyEnumerator],
|
||||||
key;
|
key;
|
||||||
|
|
||||||
while (key = [paramEnumerator nextObject])
|
while (key = [paramEnumerator nextObject])
|
||||||
paramString = [paramString stringByAppendingFormat:@"<param name='%@' value='%@' />", key, [_params objectForKey:key]];
|
paramString = [paramString stringByAppendingFormat:@"<param name='%@' value='%@' />", key, [_params objectForKey:key]];
|
||||||
|
|
||||||
_DOMObjectElement = document.createElement(@"object");
|
_DOMObjectElement = document.createElement(@"object");
|
||||||
_DOMElement.appendChild(_DOMObjectElement);
|
_DOMElement.appendChild(_DOMObjectElement);
|
||||||
|
|
||||||
_DOMObjectElement.outerHTML = [CPString stringWithFormat:@"<object classid=%@ width=%@ height=%@>%@</object>", IEFlashCLSID, CGRectGetWidth([self bounds]), CGRectGetHeight([self bounds]), paramString];
|
_DOMObjectElement.outerHTML = [CPString stringWithFormat:@"<object classid=%@ width=%@ height=%@>%@</object>", IEFlashCLSID, CGRectGetWidth([self bounds]), CGRectGetHeight([self bounds]), paramString];
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ var CPSharedFontManager = nil,
|
|||||||
{
|
{
|
||||||
if (!CPSharedFontManager)
|
if (!CPSharedFontManager)
|
||||||
CPSharedFontManager = [[CPFontManagerFactory alloc] init];
|
CPSharedFontManager = [[CPFontManagerFactory alloc] init];
|
||||||
|
|
||||||
return CPSharedFontManager;
|
return CPSharedFontManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ var CPSharedFontManager = nil,
|
|||||||
- (CPArray)availableFonts
|
- (CPArray)availableFonts
|
||||||
{
|
{
|
||||||
if (!_availableFonts)
|
if (!_availableFonts)
|
||||||
{
|
{
|
||||||
_CPFontDetectSpan = document.createElement("span");
|
_CPFontDetectSpan = document.createElement("span");
|
||||||
_CPFontDetectSpan.fontSize = "24px";
|
_CPFontDetectSpan.fontSize = "24px";
|
||||||
_CPFontDetectSpan.appendChild(document.createTextNode("mmmmmmmmmml"));
|
_CPFontDetectSpan.appendChild(document.createTextNode("mmmmmmmmmml"));
|
||||||
@@ -74,13 +74,14 @@ var CPSharedFontManager = nil,
|
|||||||
div.style.top = "-1000px";
|
div.style.top = "-1000px";
|
||||||
div.appendChild(_CPFontDetectSpan);
|
div.appendChild(_CPFontDetectSpan);
|
||||||
document.getElementsByTagName("body")[0].appendChild(div);
|
document.getElementsByTagName("body")[0].appendChild(div);
|
||||||
|
|
||||||
_CPFontDetectReferenceFonts = _CPFontDetectPickTwoDifferentFonts(["monospace", "serif", "sans-serif", "cursive"]);
|
_CPFontDetectReferenceFonts = _CPFontDetectPickTwoDifferentFonts(["monospace", "serif", "sans-serif", "cursive"]);
|
||||||
|
|
||||||
_availableFonts = [];
|
_availableFonts = [];
|
||||||
for (var i = 0; i < _CPFontDetectAllFonts.length; i++) {
|
for (var i = 0; i < _CPFontDetectAllFonts.length; i++)
|
||||||
|
{
|
||||||
var available = _CPFontDetectFontAvailable(_CPFontDetectAllFonts[i]);
|
var available = _CPFontDetectFontAvailable(_CPFontDetectAllFonts[i]);
|
||||||
if (available)
|
if (available)
|
||||||
_availableFonts.push(_CPFontDetectAllFonts[i]);
|
_availableFonts.push(_CPFontDetectAllFonts[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,8 +102,8 @@ var CPSharedFontManager = nil,
|
|||||||
var _CPFontDetectSpan,
|
var _CPFontDetectSpan,
|
||||||
_CPFontDetectReferenceFonts,
|
_CPFontDetectReferenceFonts,
|
||||||
_CPFontDetectAllFonts = [
|
_CPFontDetectAllFonts = [
|
||||||
/* "04b_21","A Charming Font","Abadi MT Condensed","Abadi MT Condensed Extra Bold","Abadi MT Condensed Light","Academy Engraved LET","Agency FB","Alba","Alba Matter","Alba Super","Algerian",*/
|
/* "04b_21","A Charming Font","Abadi MT Condensed","Abadi MT Condensed Extra Bold","Abadi MT Condensed Light","Academy Engraved LET","Agency FB","Alba","Alba Matter","Alba Super","Algerian",*/
|
||||||
"American Typewriter",
|
"American Typewriter",
|
||||||
/* "Andale Mono","Andale Mono IPA","Andy", */
|
/* "Andale Mono","Andale Mono IPA","Andy", */
|
||||||
"Apple Chancery","Arial","Arial Black","Arial Narrow","Arial Rounded MT Bold","Arial Unicode MS",
|
"Apple Chancery","Arial","Arial Black","Arial Narrow","Arial Rounded MT Bold","Arial Unicode MS",
|
||||||
/* "Avant Garde","Avantgarde","Baby Kruffy","Base 02","Baskerville","Baskerville Old Face","Bauhaus 93","Beesknees ITC","Bell MT","Berlin Sans FB","Berlin Sans FB Demi","Bernard MT Condensed","Bickley Script",*/
|
/* "Avant Garde","Avantgarde","Baby Kruffy","Base 02","Baskerville","Baskerville Old Face","Bauhaus 93","Beesknees ITC","Bell MT","Berlin Sans FB","Berlin Sans FB Demi","Bernard MT Condensed","Bickley Script",*/
|
||||||
@@ -122,8 +123,8 @@ var _CPFontDetectSpan,
|
|||||||
/* "GlooGun","Gloucester MT Extra Condensed","Goudy Old Style","Goudy Stout","Haettenschweiler","Harlow Solid Italic","Harrington",*/
|
/* "GlooGun","Gloucester MT Extra Condensed","Goudy Old Style","Goudy Stout","Haettenschweiler","Harlow Solid Italic","Harrington",*/
|
||||||
"Helvetica","Helvetica Narrow","Helvetica Neue","Herculanum","High Tower Text","Highlight LET","Hoefler Text","Impact","Imprint MT Shadow",
|
"Helvetica","Helvetica Narrow","Helvetica Neue","Herculanum","High Tower Text","Highlight LET","Hoefler Text","Impact","Imprint MT Shadow",
|
||||||
/* "Informal Roman","Jenkins v2.0","John Handy LET","Jokerman","Jokerman LET","Jokewood","Juice ITC","Kabel Ult BT","Kartika","Kino MT","Kristen ITC","Kunstler Script","La Bamba LET", */
|
/* "Informal Roman","Jenkins v2.0","John Handy LET","Jokerman","Jokerman LET","Jokewood","Juice ITC","Kabel Ult BT","Kartika","Kino MT","Kristen ITC","Kunstler Script","La Bamba LET", */
|
||||||
"Lucida","Lucida Bright","Lucida Calligraphy","Lucida Console","Lucida Fax","Lucida Grande","Lucida Handwriting","Lucida Sans","Lucida Sans Typewriter","Lucida Sans Unicode",
|
"Lucida","Lucida Bright","Lucida Calligraphy","Lucida Console","Lucida Fax","Lucida Grande","Lucida Handwriting","Lucida Sans","Lucida Sans Typewriter","Lucida Sans Unicode",
|
||||||
/* "Luxi Mono","Luxi Sans","Luxi Serif","MARKETPRO","MS Reference Sans Serif","MS Reference Serif","Magneto","Maiandra GD", */
|
/* "Luxi Mono","Luxi Sans","Luxi Serif","MARKETPRO","MS Reference Sans Serif","MS Reference Serif","Magneto","Maiandra GD", */
|
||||||
"Marker Felt",
|
"Marker Felt",
|
||||||
/* "Matisse ITC","Matura MT Script Capitals","Mead Bold","Mekanik LET","Mercurius Script MT Bold", */
|
/* "Matisse ITC","Matura MT Script Capitals","Mead Bold","Mekanik LET","Mercurius Script MT Bold", */
|
||||||
"Microsoft Sans Serif","Milano LET","Minion Web","MisterEarl BT","Mistral","Monaco","Monotype Corsiva","Monotype.com","New Century Schoolbook","New York","News Gothic MT",
|
"Microsoft Sans Serif","Milano LET","Minion Web","MisterEarl BT","Mistral","Monaco","Monotype Corsiva","Monotype.com","New Century Schoolbook","New York","News Gothic MT",
|
||||||
@@ -136,39 +137,44 @@ var _CPFontDetectSpan,
|
|||||||
"Zapfino"];
|
"Zapfino"];
|
||||||
|
|
||||||
// Compare against the reference fonts. Return true if it produces a different size than at least one of them.
|
// Compare against the reference fonts. Return true if it produces a different size than at least one of them.
|
||||||
var _CPFontDetectFontAvailable = function(font) {
|
var _CPFontDetectFontAvailable = function(font)
|
||||||
for (var i = 0; i < _CPFontDetectReferenceFonts.length; i++)
|
{
|
||||||
if (_CPFontDetectCompareFonts(_CPFontDetectReferenceFonts[i], font))
|
for (var i = 0; i < _CPFontDetectReferenceFonts.length; i++)
|
||||||
return true;
|
if (_CPFontDetectCompareFonts(_CPFontDetectReferenceFonts[i], font))
|
||||||
return false;
|
return true;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var _CPFontDetectCache = {};
|
var _CPFontDetectCache = {};
|
||||||
|
|
||||||
// Compares two given fonts. Returns true if they produce different sizes (i.e. fontA didn't fallback to fontB)
|
// Compares two given fonts. Returns true if they produce different sizes (i.e. fontA didn't fallback to fontB)
|
||||||
var _CPFontDetectCompareFonts = function(fontA, fontB) {
|
var _CPFontDetectCompareFonts = function(fontA, fontB)
|
||||||
|
{
|
||||||
var a;
|
var a;
|
||||||
if (_CPFontDetectCache[fontA]) {
|
if (_CPFontDetectCache[fontA])
|
||||||
a = _CPFontDetectCache[fontA];
|
a = _CPFontDetectCache[fontA];
|
||||||
} else {
|
|
||||||
_CPFontDetectSpan.style.fontFamily = '"' + fontA + '"';
|
else
|
||||||
|
{
|
||||||
|
_CPFontDetectSpan.style.fontFamily = '"' + fontA + '"';
|
||||||
_CPFontDetectCache[fontA] = a = { w: _CPFontDetectSpan.offsetWidth, h: _CPFontDetectSpan.offsetHeight };
|
_CPFontDetectCache[fontA] = a = { w: _CPFontDetectSpan.offsetWidth, h: _CPFontDetectSpan.offsetHeight };
|
||||||
}
|
}
|
||||||
|
|
||||||
_CPFontDetectSpan.style.fontFamily= '"' + fontB + '", "' + fontA + '"';
|
_CPFontDetectSpan.style.fontFamily = '"' + fontB + '", "' + fontA + '"';
|
||||||
var bWidth = _CPFontDetectSpan.offsetWidth;
|
var bWidth = _CPFontDetectSpan.offsetWidth,
|
||||||
var bHeight = _CPFontDetectSpan.offsetHeight;
|
bHeight = _CPFontDetectSpan.offsetHeight;
|
||||||
|
|
||||||
return (a.w != bWidth || a.h != bHeight);
|
return (a.w != bWidth || a.h != bHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test the candidate fonts pairwise until we find two that are different. Otherwise return the first.
|
// Test the candidate fonts pairwise until we find two that are different. Otherwise return the first.
|
||||||
var _CPFontDetectPickTwoDifferentFonts = function(candidates) {
|
var _CPFontDetectPickTwoDifferentFonts = function(candidates)
|
||||||
for (var i = 0; i < candidates.length; i++)
|
{
|
||||||
for (var j = 0; j < i; j++)
|
for (var i = 0; i < candidates.length; i++)
|
||||||
if (_CPFontDetectCompareFonts(candidates[i], candidates[j]))
|
for (var j = 0; j < i; j++)
|
||||||
return [candidates[i], candidates[j]];
|
if (_CPFontDetectCompareFonts(candidates[i], candidates[j]))
|
||||||
return [candidates[0]];
|
return [candidates[i], candidates[j]];
|
||||||
|
return [candidates[0]];
|
||||||
}
|
}
|
||||||
|
|
||||||
[CPFontManager setFontManagerFactory:[CPFontManager class]];
|
[CPFontManager setFontManagerFactory:[CPFontManager class]];
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ function CPPointMake(x, y)
|
|||||||
function CPRectInset(aRect, dX, dY)
|
function CPRectInset(aRect, dX, dY)
|
||||||
{
|
{
|
||||||
return CPRectMake( aRect.origin.x + dX, aRect.origin.y + dY,
|
return CPRectMake( aRect.origin.x + dX, aRect.origin.y + dY,
|
||||||
aRect.size.width - 2 * dX, aRect.size.height - 2*dY);
|
aRect.size.width - 2 * dX, aRect.size.height - 2 * dY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
@@ -71,10 +71,10 @@ var CPGraphicsContextCurrent = nil;
|
|||||||
- (id)initWithGraphicsPort:(CPContext)aGraphicsPort
|
- (id)initWithGraphicsPort:(CPContext)aGraphicsPort
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
_graphicsPort = aGraphicsPort;
|
_graphicsPort = aGraphicsPort;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ function CPAppKitImage(aFilename, aSize)
|
|||||||
return CPImageInBundle(aFilename, aSize, [CPBundle bundleForClass:[CPView class]]);
|
return CPImageInBundle(aFilename, aSize, [CPBundle bundleForClass:[CPView class]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
@class CPImage
|
@class CPImage
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ function CPAppKitImage(aFilename, aSize)
|
|||||||
all image types supported by the browser.
|
all image types supported by the browser.
|
||||||
|
|
||||||
@par Delegate Methods
|
@par Delegate Methods
|
||||||
|
|
||||||
@delegate -(void)imageDidLoad:(CPImage)image;
|
@delegate -(void)imageDidLoad:(CPImage)image;
|
||||||
Called when the specified image has finished loading.
|
Called when the specified image has finished loading.
|
||||||
@param image the image that loaded
|
@param image the image that loaded
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ CPImageAlignRight = 8;
|
|||||||
|
|
||||||
var CPImageViewShadowBackgroundColor = nil,
|
var CPImageViewShadowBackgroundColor = nil,
|
||||||
CPImageViewEmptyPlaceholderImage = nil;
|
CPImageViewEmptyPlaceholderImage = nil;
|
||||||
|
|
||||||
var LEFT_SHADOW_INSET = 3.0,
|
var LEFT_SHADOW_INSET = 3.0,
|
||||||
RIGHT_SHADOW_INSET = 3.0,
|
RIGHT_SHADOW_INSET = 3.0,
|
||||||
TOP_SHADOW_INSET = 3.0,
|
TOP_SHADOW_INSET = 3.0,
|
||||||
@@ -51,7 +51,7 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
VERTICAL_SHADOW_INSET = TOP_SHADOW_INSET + BOTTOM_SHADOW_INSET,
|
VERTICAL_SHADOW_INSET = TOP_SHADOW_INSET + BOTTOM_SHADOW_INSET,
|
||||||
HORIZONTAL_SHADOW_INSET = LEFT_SHADOW_INSET + RIGHT_SHADOW_INSET;
|
HORIZONTAL_SHADOW_INSET = LEFT_SHADOW_INSET + RIGHT_SHADOW_INSET;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
@class CPImageView
|
@class CPImageView
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
@implementation CPImageView : CPControl
|
@implementation CPImageView : CPControl
|
||||||
{
|
{
|
||||||
DOMElement _DOMImageElement;
|
DOMElement _DOMImageElement;
|
||||||
|
|
||||||
BOOL _hasShadow;
|
BOOL _hasShadow;
|
||||||
CPView _shadowView;
|
CPView _shadowView;
|
||||||
|
|
||||||
@@ -73,14 +73,14 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
+ (void)initialize
|
+ (void)initialize
|
||||||
{
|
{
|
||||||
var bundle = [CPBundle bundleForClass:[CPView class]];
|
var bundle = [CPBundle bundleForClass:[CPView class]];
|
||||||
|
|
||||||
CPImageViewEmptyPlaceholderImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"empty.png"]];
|
CPImageViewEmptyPlaceholderImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"empty.png"]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithFrame:(CGRect)aFrame
|
- (id)initWithFrame:(CGRect)aFrame
|
||||||
{
|
{
|
||||||
self = [super initWithFrame:aFrame];
|
self = [super initWithFrame:aFrame];
|
||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
#if PLATFORM(DOM)
|
#if PLATFORM(DOM)
|
||||||
@@ -96,11 +96,11 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPDOMDisplayServerAppendChild(_DOMElement, _DOMImageElement);
|
CPDOMDisplayServerAppendChild(_DOMElement, _DOMImageElement);
|
||||||
|
|
||||||
_DOMImageElement.style.visibility = "hidden";
|
_DOMImageElement.style.visibility = "hidden";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,29 +121,29 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
- (void)setObjectValue:(CPImage)anImage
|
- (void)setObjectValue:(CPImage)anImage
|
||||||
{
|
{
|
||||||
var oldImage = [self objectValue];
|
var oldImage = [self objectValue];
|
||||||
|
|
||||||
if (oldImage === anImage)
|
if (oldImage === anImage)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
[super setObjectValue:anImage];
|
[super setObjectValue:anImage];
|
||||||
|
|
||||||
var defaultCenter = [CPNotificationCenter defaultCenter];
|
var defaultCenter = [CPNotificationCenter defaultCenter];
|
||||||
|
|
||||||
if (oldImage)
|
if (oldImage)
|
||||||
[defaultCenter removeObserver:self name:CPImageDidLoadNotification object:oldImage];
|
[defaultCenter removeObserver:self name:CPImageDidLoadNotification object:oldImage];
|
||||||
|
|
||||||
var newImage = [self objectValue];
|
var newImage = [self objectValue];
|
||||||
|
|
||||||
#if PLATFORM(DOM)
|
#if PLATFORM(DOM)
|
||||||
_DOMImageElement.src = newImage ? [newImage filename] : [CPImageViewEmptyPlaceholderImage filename];
|
_DOMImageElement.src = newImage ? [newImage filename] : [CPImageViewEmptyPlaceholderImage filename];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
var size = [newImage size];
|
var size = [newImage size];
|
||||||
|
|
||||||
if (size && size.width === -1 && size.height === -1)
|
if (size && size.width === -1 && size.height === -1)
|
||||||
{
|
{
|
||||||
[defaultCenter addObserver:self selector:@selector(imageDidLoad:) name:CPImageDidLoadNotification object:newImage];
|
[defaultCenter addObserver:self selector:@selector(imageDidLoad:) name:CPImageDidLoadNotification object:newImage];
|
||||||
|
|
||||||
#if PLATFORM(DOM)
|
#if PLATFORM(DOM)
|
||||||
_DOMImageElement.width = 0;
|
_DOMImageElement.width = 0;
|
||||||
_DOMImageElement.height = 0;
|
_DOMImageElement.height = 0;
|
||||||
@@ -162,7 +162,7 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
- (void)imageDidLoad:(CPNotification)aNotification
|
- (void)imageDidLoad:(CPNotification)aNotification
|
||||||
{
|
{
|
||||||
[self hideOrDisplayContents];
|
[self hideOrDisplayContents];
|
||||||
|
|
||||||
[self setNeedsLayout];
|
[self setNeedsLayout];
|
||||||
[self setNeedsDisplay:YES];
|
[self setNeedsDisplay:YES];
|
||||||
}
|
}
|
||||||
@@ -184,25 +184,25 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
{
|
{
|
||||||
if (_hasShadow == shouldHaveShadow)
|
if (_hasShadow == shouldHaveShadow)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_hasShadow = shouldHaveShadow;
|
_hasShadow = shouldHaveShadow;
|
||||||
|
|
||||||
if (_hasShadow)
|
if (_hasShadow)
|
||||||
{
|
{
|
||||||
_shadowView = [[CPShadowView alloc] initWithFrame:[self bounds]];
|
_shadowView = [[CPShadowView alloc] initWithFrame:[self bounds]];
|
||||||
|
|
||||||
[self addSubview:_shadowView];
|
[self addSubview:_shadowView];
|
||||||
|
|
||||||
[self setNeedsLayout];
|
[self setNeedsLayout];
|
||||||
[self setNeedsDisplay:YES];
|
[self setNeedsDisplay:YES];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
[_shadowView removeFromSuperview];
|
[_shadowView removeFromSuperview];
|
||||||
|
|
||||||
_shadowView = nil;
|
_shadowView = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
[self hideOrDisplayContents];
|
[self hideOrDisplayContents];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,12 +215,12 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
{
|
{
|
||||||
if (_imageAlignment == anImageAlignment)
|
if (_imageAlignment == anImageAlignment)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_imageAlignment = anImageAlignment;
|
_imageAlignment = anImageAlignment;
|
||||||
|
|
||||||
if (![self image])
|
if (![self image])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
[self setNeedsLayout];
|
[self setNeedsLayout];
|
||||||
[self setNeedsDisplay:YES];
|
[self setNeedsDisplay:YES];
|
||||||
}
|
}
|
||||||
@@ -238,14 +238,14 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
- (void)setImageScaling:(CPImageScaling)anImageScaling
|
- (void)setImageScaling:(CPImageScaling)anImageScaling
|
||||||
{
|
{
|
||||||
[super setImageScaling:anImageScaling];
|
[super setImageScaling:anImageScaling];
|
||||||
|
|
||||||
#if PLATFORM(DOM)
|
#if PLATFORM(DOM)
|
||||||
if ([self currentValueForThemeAttribute:@"image-scaling"] === CPScaleToFit)
|
if ([self currentValueForThemeAttribute:@"image-scaling"] === CPScaleToFit)
|
||||||
{
|
{
|
||||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageElement, NULL, 0.0, 0.0);
|
CPDOMDisplayServerSetStyleLeftTop(_DOMImageElement, NULL, 0.0, 0.0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
[self setNeedsLayout];
|
[self setNeedsLayout];
|
||||||
[self setNeedsDisplay:YES];
|
[self setNeedsDisplay:YES];
|
||||||
}
|
}
|
||||||
@@ -314,7 +314,7 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var size = [image size];
|
var size = [image size];
|
||||||
|
|
||||||
if (size.width == -1 && size.height == -1)
|
if (size.width == -1 && size.height == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -331,7 +331,7 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
{
|
{
|
||||||
var imageRatio = size.width / size.height,
|
var imageRatio = size.width / size.height,
|
||||||
viewRatio = width / height;
|
viewRatio = width / height;
|
||||||
|
|
||||||
if (viewRatio > imageRatio)
|
if (viewRatio > imageRatio)
|
||||||
width = height * imageRatio;
|
width = height * imageRatio;
|
||||||
else
|
else
|
||||||
@@ -348,7 +348,7 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
width = size.width;
|
width = size.width;
|
||||||
height = size.height;
|
height = size.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imageScaling == CPScaleNone)
|
if (imageScaling == CPScaleNone)
|
||||||
{
|
{
|
||||||
#if PLATFORM(DOM)
|
#if PLATFORM(DOM)
|
||||||
@@ -357,8 +357,9 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
var x, y;
|
var x,
|
||||||
|
y;
|
||||||
|
|
||||||
switch (_imageAlignment)
|
switch (_imageAlignment)
|
||||||
{
|
{
|
||||||
case CPImageAlignLeft:
|
case CPImageAlignLeft:
|
||||||
@@ -366,7 +367,7 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
case CPImageAlignBottomLeft:
|
case CPImageAlignBottomLeft:
|
||||||
x = 0.0;
|
x = 0.0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CPImageAlignRight:
|
case CPImageAlignRight:
|
||||||
case CPImageAlignTopRight:
|
case CPImageAlignTopRight:
|
||||||
case CPImageAlignBottomRight:
|
case CPImageAlignBottomRight:
|
||||||
@@ -377,7 +378,7 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
x = (boundsWidth - width) / 2.0;
|
x = (boundsWidth - width) / 2.0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (_imageAlignment)
|
switch (_imageAlignment)
|
||||||
{
|
{
|
||||||
case CPImageAlignTop:
|
case CPImageAlignTop:
|
||||||
@@ -385,7 +386,7 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
case CPImageAlignTopRight:
|
case CPImageAlignTopRight:
|
||||||
y = 0.0;
|
y = 0.0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CPImageAlignBottom:
|
case CPImageAlignBottom:
|
||||||
case CPImageAlignBottomLeft:
|
case CPImageAlignBottomLeft:
|
||||||
case CPImageAlignBottomRight:
|
case CPImageAlignBottomRight:
|
||||||
@@ -395,7 +396,7 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
default:
|
default:
|
||||||
y = (boundsHeight - height) / 2.0;
|
y = (boundsHeight - height) / 2.0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PLATFORM(DOM)
|
#if PLATFORM(DOM)
|
||||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageElement, NULL, x, y);
|
CPDOMDisplayServerSetStyleLeftTop(_DOMImageElement, NULL, x, y);
|
||||||
@@ -403,7 +404,7 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
}
|
}
|
||||||
|
|
||||||
_imageRect = _CGRectMake(x, y, width, height);
|
_imageRect = _CGRectMake(x, y, width, height);
|
||||||
|
|
||||||
if (_hasShadow)
|
if (_hasShadow)
|
||||||
[_shadowView setFrame:_CGRectMake(x - LEFT_SHADOW_INSET, y - TOP_SHADOW_INSET, width + insetWidth, height + insetHeight)];
|
[_shadowView setFrame:_CGRectMake(x - LEFT_SHADOW_INSET, y - TOP_SHADOW_INSET, width + insetWidth, height + insetHeight)];
|
||||||
}
|
}
|
||||||
@@ -450,7 +451,7 @@ var LEFT_SHADOW_INSET = 3.0,
|
|||||||
[self setImage:images[0]];
|
[self setImage:images[0]];
|
||||||
[self sendAction:[self action] to:[self target]];
|
[self sendAction:[self action] to:[self target]];
|
||||||
}
|
}
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,7 +486,7 @@ var CPImageViewImageKey = @"CPImageViewImageKey",
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
self = [super initWithCoder:aCoder];
|
self = [super initWithCoder:aCoder];
|
||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
#if PLATFORM(DOM)
|
#if PLATFORM(DOM)
|
||||||
@@ -494,14 +495,14 @@ var CPImageViewImageKey = @"CPImageViewImageKey",
|
|||||||
|
|
||||||
[self setHasShadow:[aCoder decodeBoolForKey:CPImageViewHasShadowKey]];
|
[self setHasShadow:[aCoder decodeBoolForKey:CPImageViewHasShadowKey]];
|
||||||
[self setImageAlignment:[aCoder decodeIntForKey:CPImageViewImageAlignmentKey]];
|
[self setImageAlignment:[aCoder decodeIntForKey:CPImageViewImageAlignmentKey]];
|
||||||
|
|
||||||
if ([aCoder decodeBoolForKey:CPImageViewIsEditableKey] || NO)
|
if ([aCoder decodeBoolForKey:CPImageViewIsEditableKey] || NO)
|
||||||
[self setEditable:YES];
|
[self setEditable:YES];
|
||||||
|
|
||||||
[self setNeedsLayout];
|
[self setNeedsLayout];
|
||||||
[self setNeedsDisplay:YES];
|
[self setNeedsDisplay:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -512,21 +513,21 @@ var CPImageViewImageKey = @"CPImageViewImageKey",
|
|||||||
*/
|
*/
|
||||||
- (void)encodeWithCoder:(CPCoder)aCoder
|
- (void)encodeWithCoder:(CPCoder)aCoder
|
||||||
{
|
{
|
||||||
// We do this in order to avoid encoding the _shadowView, which
|
// We do this in order to avoid encoding the _shadowView, which
|
||||||
// should just automatically be created programmatically as needed.
|
// should just automatically be created programmatically as needed.
|
||||||
if (_shadowView)
|
if (_shadowView)
|
||||||
{
|
{
|
||||||
var actualSubviews = _subviews;
|
var actualSubviews = _subviews;
|
||||||
|
|
||||||
_subviews = [_subviews copy];
|
_subviews = [_subviews copy];
|
||||||
[_subviews removeObjectIdenticalTo:_shadowView];
|
[_subviews removeObjectIdenticalTo:_shadowView];
|
||||||
}
|
}
|
||||||
|
|
||||||
[super encodeWithCoder:aCoder];
|
[super encodeWithCoder:aCoder];
|
||||||
|
|
||||||
if (_shadowView)
|
if (_shadowView)
|
||||||
_subviews = actualSubviews;
|
_subviews = actualSubviews;
|
||||||
|
|
||||||
[aCoder encodeBool:_hasShadow forKey:CPImageViewHasShadowKey];
|
[aCoder encodeBool:_hasShadow forKey:CPImageViewHasShadowKey];
|
||||||
[aCoder encodeInt:_imageAlignment forKey:CPImageViewImageAlignmentKey];
|
[aCoder encodeInt:_imageAlignment forKey:CPImageViewImageAlignmentKey];
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ var exposedBindingsMap = [CPDictionary new],
|
|||||||
var CPBindingOperationAnd = 0,
|
var CPBindingOperationAnd = 0,
|
||||||
CPBindingOperationOr = 1;
|
CPBindingOperationOr = 1;
|
||||||
|
|
||||||
@implementation CPKeyValueBinding : CPObject
|
@implementation CPBinder : CPObject
|
||||||
{
|
{
|
||||||
CPDictionary _info;
|
CPDictionary _info;
|
||||||
id _source;
|
id _source;
|
||||||
@@ -43,12 +43,12 @@ var CPBindingOperationAnd = 0,
|
|||||||
|
|
||||||
+ (void)exposeBinding:(CPString)aBinding forClass:(Class)aClass
|
+ (void)exposeBinding:(CPString)aBinding forClass:(Class)aClass
|
||||||
{
|
{
|
||||||
var bindings = [exposedBindingsMap objectForKey:[aClass hash]];
|
var bindings = [exposedBindingsMap objectForKey:[aClass UID]];
|
||||||
|
|
||||||
if (!bindings)
|
if (!bindings)
|
||||||
{
|
{
|
||||||
bindings = [];
|
bindings = [];
|
||||||
[exposedBindingsMap setObject:bindings forKey:[aClass hash]];
|
[exposedBindingsMap setObject:bindings forKey:[aClass UID]];
|
||||||
}
|
}
|
||||||
|
|
||||||
bindings.push(aBinding);
|
bindings.push(aBinding);
|
||||||
@@ -56,12 +56,12 @@ var CPBindingOperationAnd = 0,
|
|||||||
|
|
||||||
+ (CPArray)exposedBindingsForClass:(Class)aClass
|
+ (CPArray)exposedBindingsForClass:(Class)aClass
|
||||||
{
|
{
|
||||||
return [[exposedBindingsMap objectForKey:[aClass hash]] copy];
|
return [[exposedBindingsMap objectForKey:[aClass UID]] copy];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CPKeyValueBinding)getBinding:(CPString)aBinding forObject:(id)anObject
|
+ (CPBinder)getBinding:(CPString)aBinding forObject:(id)anObject
|
||||||
{
|
{
|
||||||
return [[bindingsMap objectForKey:[anObject hash]] objectForKey:aBinding];
|
return [[bindingsMap objectForKey:[anObject UID]] objectForKey:aBinding];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CPDictionary)infoForBinding:(CPString)aBinding forObject:(id)anObject
|
+ (CPDictionary)infoForBinding:(CPString)aBinding forObject:(id)anObject
|
||||||
@@ -76,12 +76,12 @@ var CPBindingOperationAnd = 0,
|
|||||||
|
|
||||||
+ (CPDictionary)allBindingsForObject:(id)anObject
|
+ (CPDictionary)allBindingsForObject:(id)anObject
|
||||||
{
|
{
|
||||||
return [bindingsMap objectForKey:[anObject hash]];
|
return [bindingsMap objectForKey:[anObject UID]];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)unbind:(CPString)aBinding forObject:(id)anObject
|
+ (void)unbind:(CPString)aBinding forObject:(id)anObject
|
||||||
{
|
{
|
||||||
var bindings = [bindingsMap objectForKey:[anObject hash]];
|
var bindings = [bindingsMap objectForKey:[anObject UID]];
|
||||||
|
|
||||||
if (!bindings)
|
if (!bindings)
|
||||||
return;
|
return;
|
||||||
@@ -101,7 +101,7 @@ var CPBindingOperationAnd = 0,
|
|||||||
|
|
||||||
+ (void)unbindAllForObject:(id)anObject
|
+ (void)unbindAllForObject:(id)anObject
|
||||||
{
|
{
|
||||||
var bindings = [bindingsMap objectForKey:[anObject hash]];
|
var bindings = [bindingsMap objectForKey:[anObject UID]];
|
||||||
if (!bindings)
|
if (!bindings)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ var CPBindingOperationAnd = 0,
|
|||||||
while (count--)
|
while (count--)
|
||||||
[anObject unbind:[bindings objectForKey:allKeys[count]]];
|
[anObject unbind:[bindings objectForKey:allKeys[count]]];
|
||||||
|
|
||||||
[bindingsMap removeObjectForKey:[anObject hash]];
|
[bindingsMap removeObjectForKey:[anObject UID]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithBinding:(CPString)aBinding name:(CPString)aName to:(id)aDestination keyPath:(CPString)aKeyPath options:(CPDictionary)options from:(id)aSource
|
- (id)initWithBinding:(CPString)aBinding name:(CPString)aName to:(id)aDestination keyPath:(CPString)aKeyPath options:(CPDictionary)options from:(id)aSource
|
||||||
@@ -128,11 +128,11 @@ var CPBindingOperationAnd = 0,
|
|||||||
|
|
||||||
[aDestination addObserver:self forKeyPath:aKeyPath options:CPKeyValueObservingOptionNew context:aBinding];
|
[aDestination addObserver:self forKeyPath:aKeyPath options:CPKeyValueObservingOptionNew context:aBinding];
|
||||||
|
|
||||||
var bindings = [bindingsMap objectForKey:[_source hash]];
|
var bindings = [bindingsMap objectForKey:[_source UID]];
|
||||||
if (!bindings)
|
if (!bindings)
|
||||||
{
|
{
|
||||||
bindings = [CPDictionary new];
|
bindings = [CPDictionary new];
|
||||||
[bindingsMap setObject:bindings forKey:[_source hash]];
|
[bindingsMap setObject:bindings forKey:[_source UID]];
|
||||||
}
|
}
|
||||||
|
|
||||||
[bindings setObject:self forKey:aName];
|
[bindings setObject:self forKey:aName];
|
||||||
@@ -147,39 +147,10 @@ var CPBindingOperationAnd = 0,
|
|||||||
var destination = [_info objectForKey:CPObservedObjectKey],
|
var destination = [_info objectForKey:CPObservedObjectKey],
|
||||||
keyPath = [_info objectForKey:CPObservedKeyPathKey],
|
keyPath = [_info objectForKey:CPObservedKeyPathKey],
|
||||||
options = [_info objectForKey:CPOptionsKey],
|
options = [_info objectForKey:CPOptionsKey],
|
||||||
newValue = [destination valueForKeyPath:keyPath],
|
newValue = [destination valueForKeyPath:keyPath];
|
||||||
isPlaceholder = CPIsControllerMarker(newValue);
|
|
||||||
|
|
||||||
if (isPlaceholder)
|
|
||||||
{
|
|
||||||
switch (newValue)
|
|
||||||
{
|
|
||||||
case CPMultipleValuesMarker:
|
|
||||||
newValue = [options objectForKey:CPMultipleValuesPlaceholderBindingOption] || @"Multiple Values";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CPNoSelectionMarker:
|
|
||||||
newValue = [options objectForKey:CPNoSelectionPlaceholderBindingOption] || @"No Selection";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CPNotApplicableMarker:
|
|
||||||
if ([options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
|
|
||||||
[CPException raise:CPGenericException reason:@"can't transform non applicable key on: "+_source+" value: "+newValue];
|
|
||||||
|
|
||||||
newValue = [options objectForKey:CPNotApplicablePlaceholderBindingOption] || @"Not Applicable";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Only transform the value if the current value is not a placeholder
|
|
||||||
newValue = [self transformValue:newValue withOptions:options];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
newValue = [self transformValue:newValue withOptions:options];
|
||||||
[_source setValue:newValue forKey:aBinding];
|
[_source setValue:newValue forKey:aBinding];
|
||||||
|
|
||||||
if ([_source respondsToSelector:@selector(_setCurrentValueIsPlaceholder:)])
|
|
||||||
[_source _setCurrentValueIsPlaceholder:isPlaceholder];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)reverseSetValueFor:(CPString)aBinding
|
- (void)reverseSetValueFor:(CPString)aBinding
|
||||||
@@ -231,7 +202,7 @@ var CPBindingOperationAnd = 0,
|
|||||||
aValue = [valueTransformer transformedValue:aValue];
|
aValue = [valueTransformer transformedValue:aValue];
|
||||||
|
|
||||||
|
|
||||||
if (aValue === undefined || aValue === nil)
|
if (aValue === undefined || aValue === nil || aValue === [CPNull null])
|
||||||
aValue = [options objectForKey:CPNullPlaceholderBindingOption] || nil;
|
aValue = [options objectForKey:CPNullPlaceholderBindingOption] || nil;
|
||||||
|
|
||||||
return aValue;
|
return aValue;
|
||||||
@@ -259,7 +230,13 @@ var CPBindingOperationAnd = 0,
|
|||||||
|
|
||||||
+ (void)exposeBinding:(CPString)aBinding
|
+ (void)exposeBinding:(CPString)aBinding
|
||||||
{
|
{
|
||||||
[CPKeyValueBinding exposeBinding:aBinding forClass:[self class]];
|
[CPBinder exposeBinding:aBinding forClass:[self class]];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
+ (Class)_binderClassForBinding:(CPString)theBinding
|
||||||
|
{
|
||||||
|
return [CPBinder class];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CPArray)exposedBindings
|
- (CPArray)exposedBindings
|
||||||
@@ -269,7 +246,7 @@ var CPBindingOperationAnd = 0,
|
|||||||
|
|
||||||
while (theClass)
|
while (theClass)
|
||||||
{
|
{
|
||||||
var temp = [CPKeyValueBinding exposedBindingsForClass:theClass];
|
var temp = [CPBinder exposedBindingsForClass:theClass];
|
||||||
|
|
||||||
if (temp)
|
if (temp)
|
||||||
[exposedBindings addObjectsFromArray:temp];
|
[exposedBindings addObjectsFromArray:temp];
|
||||||
@@ -293,18 +270,21 @@ var CPBindingOperationAnd = 0,
|
|||||||
//if (![[self exposedBindings] containsObject:aBinding])
|
//if (![[self exposedBindings] containsObject:aBinding])
|
||||||
// CPLog.warn("No binding exposed on "+self+" for "+aBinding);
|
// CPLog.warn("No binding exposed on "+self+" for "+aBinding);
|
||||||
|
|
||||||
|
var binderClass = [[self class] _binderClassForBinding:aBinding];
|
||||||
|
|
||||||
[self unbind:aBinding];
|
[self unbind:aBinding];
|
||||||
[[CPKeyValueBinding alloc] initWithBinding:[self _replacementKeyPathForBinding:aBinding] name:aBinding to:anObject keyPath:aKeyPath options:options from:self];
|
[[binderClass alloc] initWithBinding:[self _replacementKeyPathForBinding:aBinding] name:aBinding to:anObject keyPath:aKeyPath options:options from:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CPDictionary)infoForBinding:(CPString)aBinding
|
- (CPDictionary)infoForBinding:(CPString)aBinding
|
||||||
{
|
{
|
||||||
return [CPKeyValueBinding infoForBinding:aBinding forObject:self];
|
return [CPBinder infoForBinding:aBinding forObject:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)unbind:(CPString)aBinding
|
- (void)unbind:(CPString)aBinding
|
||||||
{
|
{
|
||||||
[CPKeyValueBinding unbind:aBinding forObject:self];
|
var binderClass = [[self class] _binderClassForBinding:aBinding];
|
||||||
|
[binderClass unbind:aBinding forObject:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)_replacementKeyPathForBinding:(CPString)binding
|
- (id)_replacementKeyPathForBinding:(CPString)binding
|
||||||
@@ -314,13 +294,35 @@ var CPBindingOperationAnd = 0,
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation _CPKeyValueOrBinding : CPKeyValueBinding
|
/*!
|
||||||
|
@ignore
|
||||||
|
Provides stub implementations that simply call super for the "objectValue" binding
|
||||||
|
This class should not be necessary but assures backwards compliance with our old way of doing bindings
|
||||||
|
Every class with a value binding should implement a subclass to handle it's specific value binding logic
|
||||||
|
*/
|
||||||
|
@implementation _CPValueBinder : CPBinder
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setValueFor:(CPString)theBinding
|
||||||
|
{
|
||||||
|
[super setValueFor:@"objectValue"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)reverseSetValueFor:(CPString)theBinding
|
||||||
|
{
|
||||||
|
[super reverseSetValueFor:@"objectValue"];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation _CPKeyValueOrBinding : CPBinder
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setValueFor:(CPString)aBinding
|
- (void)setValueFor:(CPString)aBinding
|
||||||
{
|
{
|
||||||
var bindings = [bindingsMap valueForKey:[_source hash]];
|
var bindings = [bindingsMap valueForKey:[_source UID]];
|
||||||
|
|
||||||
if (!bindings)
|
if (!bindings)
|
||||||
return;
|
return;
|
||||||
@@ -335,13 +337,13 @@ var CPBindingOperationAnd = 0,
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation _CPKeyValueAndBinding : CPKeyValueBinding
|
@implementation _CPKeyValueAndBinding : CPBinder
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setValueFor:(CPString)aBinding
|
- (void)setValueFor:(CPString)aBinding
|
||||||
{
|
{
|
||||||
var bindings = [bindingsMap objectForKey:[_source hash]];
|
var bindings = [bindingsMap objectForKey:[_source UID]];
|
||||||
|
|
||||||
if (!bindings)
|
if (!bindings)
|
||||||
return;
|
return;
|
||||||
@@ -441,30 +443,30 @@ CPToolTipBinding = @"CPToolTipBinding";
|
|||||||
CPValueBinding = @"value";
|
CPValueBinding = @"value";
|
||||||
|
|
||||||
//Binding options constants
|
//Binding options constants
|
||||||
CPAllowsEditingMultipleValuesSelectionBindingOption = @"CPAllowsEditingMultipleValuesSelectionBindingOption";
|
CPAllowsEditingMultipleValuesSelectionBindingOption = @"CPAllowsEditingMultipleValuesSelection";
|
||||||
CPAllowsNullArgumentBindingOption = @"CPAllowsNullArgumentBindingOption";
|
CPAllowsNullArgumentBindingOption = @"CPAllowsNullArgument";
|
||||||
CPConditionallySetsEditableBindingOption = @"CPConditionallySetsEditableBindingOption";
|
CPConditionallySetsEditableBindingOption = @"CPConditionallySetsEditable";
|
||||||
CPConditionallySetsEnabledBindingOption = @"CPConditionallySetsEnabledBindingOption";
|
CPConditionallySetsEnabledBindingOption = @"CPConditionallySetsEnabled";
|
||||||
CPConditionallySetsHiddenBindingOption = @"CPConditionallySetsHiddenBindingOption";
|
CPConditionallySetsHiddenBindingOption = @"CPConditionallySetsHidden";
|
||||||
CPContinuouslyUpdatesValueBindingOption = @"CPContinuouslyUpdatesValueBindingOption";
|
CPContinuouslyUpdatesValueBindingOption = @"CPContinuouslyUpdatesValue";
|
||||||
CPCreatesSortDescriptorBindingOption = @"CPCreatesSortDescriptorBindingOption";
|
CPCreatesSortDescriptorBindingOption = @"CPCreatesSortDescriptor";
|
||||||
CPDeletesObjectsOnRemoveBindingsOption = @"CPDeletesObjectsOnRemoveBindingsOption";
|
CPDeletesObjectsOnRemoveBindingsOption = @"CPDeletesObjectsOnRemove";
|
||||||
CPDisplayNameBindingOption = @"CPDisplayNameBindingOption";
|
CPDisplayNameBindingOption = @"CPDisplayName";
|
||||||
CPDisplayPatternBindingOption = @"CPDisplayPatternBindingOption";
|
CPDisplayPatternBindingOption = @"CPDisplayPattern";
|
||||||
CPHandlesContentAsCompoundValueBindingOption = @"CPHandlesContentAsCompoundValueBindingOption";
|
CPHandlesContentAsCompoundValueBindingOption = @"CPHandlesContentAsCompoundValue";
|
||||||
CPInsertsNullPlaceholderBindingOption = @"CPInsertsNullPlaceholderBindingOption";
|
CPInsertsNullPlaceholderBindingOption = @"CPInsertsNullPlaceholder";
|
||||||
CPInvokesSeparatelyWithArrayObjectsBindingOption = @"CPInvokesSeparatelyWithArrayObjectsBindingOption";
|
CPInvokesSeparatelyWithArrayObjectsBindingOption = @"CPInvokesSeparatelyWithArrayObjects";
|
||||||
CPMultipleValuesPlaceholderBindingOption = @"CPMultipleValuesPlaceholderBindingOption";
|
CPMultipleValuesPlaceholderBindingOption = @"CPMultipleValuesPlaceholder";
|
||||||
CPNoSelectionPlaceholderBindingOption = @"CPNoSelectionPlaceholderBindingOption";
|
CPNoSelectionPlaceholderBindingOption = @"CPNoSelectionPlaceholder";
|
||||||
CPNotApplicablePlaceholderBindingOption = @"CPNotApplicablePlaceholderBindingOption";
|
CPNotApplicablePlaceholderBindingOption = @"CPNotApplicablePlaceholder";
|
||||||
CPNullPlaceholderBindingOption = @"CPNullPlaceholderBindingOption";
|
CPNullPlaceholderBindingOption = @"CPNullPlaceholder";
|
||||||
CPPredicateFormatBindingOption = @"CPPredicateFormatBindingOption";
|
CPPredicateFormatBindingOption = @"CPPredicateFormat";
|
||||||
CPRaisesForNotApplicableKeysBindingOption = @"CPRaisesForNotApplicableKeysBindingOption";
|
CPRaisesForNotApplicableKeysBindingOption = @"CPRaisesForNotApplicableKeys";
|
||||||
CPSelectorNameBindingOption = @"CPSelectorNameBindingOption";
|
CPSelectorNameBindingOption = @"CPSelectorName";
|
||||||
CPSelectsAllWhenSettingContentBindingOption = @"CPSelectsAllWhenSettingContentBindingOption";
|
CPSelectsAllWhenSettingContentBindingOption = @"CPSelectsAllWhenSettingContent";
|
||||||
CPValidatesImmediatelyBindingOption = @"CPValidatesImmediatelyBindingOption";
|
CPValidatesImmediatelyBindingOption = @"CPValidatesImmediately";
|
||||||
CPValueTransformerNameBindingOption = @"CPValueTransformerNameBindingOption";
|
CPValueTransformerNameBindingOption = @"CPValueTransformerName";
|
||||||
CPValueTransformerBindingOption = @"CPValueTransformerBindingOption";
|
CPValueTransformerBindingOption = @"CPValueTransformer";
|
||||||
|
|
||||||
CPIsControllerMarker = function(/*id*/anObject)
|
CPIsControllerMarker = function(/*id*/anObject)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -692,7 +692,7 @@ var _CPMenuBarVisible = NO,
|
|||||||
var delegate = [self delegate];
|
var delegate = [self delegate];
|
||||||
|
|
||||||
if ([delegate respondsToSelector:@selector(menuWillOpen:)])
|
if ([delegate respondsToSelector:@selector(menuWillOpen:)])
|
||||||
[delegate menuWillOpen:aMenu];
|
[delegate menuWillOpen:self];
|
||||||
|
|
||||||
// Convert location to global coordinates if not already in them.
|
// Convert location to global coordinates if not already in them.
|
||||||
if (aView)
|
if (aView)
|
||||||
|
|||||||
@@ -459,7 +459,7 @@ CPOffState
|
|||||||
|
|
||||||
if (supermenu)
|
if (supermenu)
|
||||||
[CPException raise:CPInvalidArgumentException
|
[CPException raise:CPInvalidArgumentException
|
||||||
reason: @"Can't add submenu \"" + [aMenu title] + "\" to item \"" + [self title] + "\", because it is already submenu of \"" + [[aMenu supermenu] title] + "\""];
|
reason: @"Can't add submenu \"" + [aMenu title] + "\" to item \"" + [self title] + "\", because it is already submenu of \"" + [[aMenu supermenu] title] + "\""];
|
||||||
|
|
||||||
_submenu = aMenu;
|
_submenu = aMenu;
|
||||||
|
|
||||||
@@ -592,7 +592,7 @@ CPControlKeyMask
|
|||||||
return @"";
|
return @"";
|
||||||
|
|
||||||
var string = _keyEquivalent.toUpperCase(),
|
var string = _keyEquivalent.toUpperCase(),
|
||||||
needsShift = _keyEquivalentModifierMask & CPShiftKeyMask ||
|
needsShift = _keyEquivalentModifierMask & CPShiftKeyMask ||
|
||||||
(string === _keyEquivalent && _keyEquivalent.toLowerCase() !== _keyEquivalent.toUpperCase());
|
(string === _keyEquivalent && _keyEquivalent.toLowerCase() !== _keyEquivalent.toUpperCase());
|
||||||
|
|
||||||
if (CPBrowserIsOperatingSystem(CPMacOperatingSystem))
|
if (CPBrowserIsOperatingSystem(CPMacOperatingSystem))
|
||||||
@@ -791,12 +791,12 @@ CPControlKeyMask
|
|||||||
- (id)copy
|
- (id)copy
|
||||||
{
|
{
|
||||||
var item = [[CPMenuItem alloc] init];
|
var item = [[CPMenuItem alloc] init];
|
||||||
|
|
||||||
// No point in going through accessors and doing lots of unnecessary state checking/updating
|
// No point in going through accessors and doing lots of unnecessary state checking/updating
|
||||||
item._isSeparator = _isSeparator;
|
item._isSeparator = _isSeparator;
|
||||||
|
|
||||||
[item setTitle:_title];
|
[item setTitle:_title];
|
||||||
[item setFont:_font];
|
[item setFont:_font];
|
||||||
[item setTarget:_target];
|
[item setTarget:_target];
|
||||||
[item setAction:_action];
|
[item setAction:_action];
|
||||||
[item setEnabled:_isEnabled];
|
[item setEnabled:_isEnabled];
|
||||||
@@ -815,7 +815,7 @@ CPControlKeyMask
|
|||||||
[item setIndentationLevel:_indentationLevel];
|
[item setIndentationLevel:_indentationLevel];
|
||||||
[item setToolTip:_toolTip];
|
[item setToolTip:_toolTip];
|
||||||
[item setRepresentedObject:_representedObject];
|
[item setRepresentedObject:_representedObject];
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
id _selection;
|
id _selection;
|
||||||
|
|
||||||
Class _objectClass;
|
Class _objectClass;
|
||||||
|
CPString _objectClassName;
|
||||||
|
|
||||||
BOOL _isEditable;
|
BOOL _isEditable;
|
||||||
BOOL _automaticallyPreparesContent;
|
BOOL _automaticallyPreparesContent;
|
||||||
@@ -122,16 +123,22 @@
|
|||||||
return _objectClass;
|
return _objectClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)newObject
|
- (id)_defaultNewObject
|
||||||
{
|
{
|
||||||
return [[[self objectClass] alloc] init];
|
return [[[self objectClass] alloc] init];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (id)newObject
|
||||||
|
{
|
||||||
|
return [self _defaultNewObject];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)addObject:(id)anObject
|
- (void)addObject:(id)anObject
|
||||||
{
|
{
|
||||||
[self setContent:anObject];
|
[self setContent:anObject];
|
||||||
|
|
||||||
[[CPKeyValueBinding getBinding:@"contentObject" forObject:self] reverseSetValueFor:@"contentObject"];
|
var binderClass = [[self class] _binderClassForBinding:@"contentObject"];
|
||||||
|
[[binderClass getBinding:@"contentObject" forObject:self] reverseSetValueFor:@"contentObject"];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)removeObject:(id)anObject
|
- (void)removeObject:(id)anObject
|
||||||
@@ -139,7 +146,8 @@
|
|||||||
if ([self content] === anObject)
|
if ([self content] === anObject)
|
||||||
[self setContent:nil];
|
[self setContent:nil];
|
||||||
|
|
||||||
[[CPKeyValueBinding getBinding:@"contentObject" forObject:self] reverseSetValueFor:@"contentObject"];
|
var binderClass = [[self class] _binderClassForBinding:@"contentObject"];
|
||||||
|
[[binderClass getBinding:@"contentObject" forObject:self] reverseSetValueFor:@"contentObject"];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)add:(id)aSender
|
- (void)add:(id)aSender
|
||||||
@@ -176,7 +184,7 @@
|
|||||||
|
|
||||||
- (CPArray)selectedObjects
|
- (CPArray)selectedObjects
|
||||||
{
|
{
|
||||||
return [[_CPObservableArray alloc] initWithObjects:[_contentObject] count:1];
|
return [[_CPObservableArray alloc] initWithArray:[_contentObject]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)selection
|
- (id)selection
|
||||||
@@ -218,7 +226,8 @@
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
var CPObjectControllerObjectClassNameKey = @"CPObjectControllerObjectClassNameKey",
|
var CPObjectControllerContentKey = @"CPObjectControllerContentKey",
|
||||||
|
CPObjectControllerObjectClassNameKey = @"CPObjectControllerObjectClassNameKey",
|
||||||
CPObjectControllerIsEditableKey = @"CPObjectControllerIsEditableKey",
|
CPObjectControllerIsEditableKey = @"CPObjectControllerIsEditableKey",
|
||||||
CPObjectControllerAutomaticallyPreparesContentKey = @"CPObjectControllerAutomaticallyPreparesContentKey";
|
CPObjectControllerAutomaticallyPreparesContentKey = @"CPObjectControllerAutomaticallyPreparesContentKey";
|
||||||
|
|
||||||
@@ -233,11 +242,10 @@ var CPObjectControllerObjectClassNameKey = @"CPObjectControllerOb
|
|||||||
var objectClassName = [aCoder decodeObjectForKey:CPObjectControllerObjectClassNameKey],
|
var objectClassName = [aCoder decodeObjectForKey:CPObjectControllerObjectClassNameKey],
|
||||||
objectClass = CPClassFromString(objectClassName);
|
objectClass = CPClassFromString(objectClassName);
|
||||||
|
|
||||||
// FIXME: Error if objectClass === nil
|
[self setObjectClass:objectClass || [CPMutableDictionary class]];
|
||||||
|
|
||||||
[self setObjectClass:objectClass];
|
|
||||||
[self setEditable:[aCoder decodeBoolForKey:CPObjectControllerIsEditableKey]];
|
[self setEditable:[aCoder decodeBoolForKey:CPObjectControllerIsEditableKey]];
|
||||||
[self setAutomaticallyPreparesContent:[aCoder decodeBoolForKey:CPObjectControllerAutomaticallyPreparesContentKey] || NO];
|
[self setAutomaticallyPreparesContent:[aCoder decodeBoolForKey:CPObjectControllerAutomaticallyPreparesContentKey] || NO];
|
||||||
|
[self setContent:[aCoder decodeObjectForKey:CPObjectControllerContentKey]];
|
||||||
|
|
||||||
_observedKeys = [[CPCountedSet alloc] init];
|
_observedKeys = [[CPCountedSet alloc] init];
|
||||||
}
|
}
|
||||||
@@ -247,11 +255,15 @@ var CPObjectControllerObjectClassNameKey = @"CPObjectControllerOb
|
|||||||
|
|
||||||
- (void)encodeWithCoder:(CPCoder)aCoder
|
- (void)encodeWithCoder:(CPCoder)aCoder
|
||||||
{
|
{
|
||||||
[aCoder encodeObject:CPStringFromClass(objectClass) forKey:CPObjectControllerObjectClassNameKey];
|
[aCoder encodeObject:[self content] forKey:CPObjectControllerContentKey];
|
||||||
[aCoder encodeObject:[self isEditable] forKey:CPObjectControllerIsEditableKey];
|
|
||||||
|
|
||||||
if (![self automaticallyPreparesContent])
|
if (_objectClass)
|
||||||
[aCoder encodeBOOL:YES forKey:CPObjectControllerAutomaticallyPreparesContentKey];
|
[aCoder encodeObject:CPStringFromClass(_objectClass) forKey:CPObjectControllerObjectClassNameKey];
|
||||||
|
else if (_objectClassName)
|
||||||
|
[aCoder encodeObject:_objectClassName forKey:CPObjectControllerObjectClassNameKey];
|
||||||
|
|
||||||
|
[aCoder encodeBool:[self isEditable] forKey:CPObjectControllerIsEditableKey];
|
||||||
|
[aCoder encodeBool:[self automaticallyPreparesContent] forKey:CPObjectControllerAutomaticallyPreparesContentKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -270,7 +282,7 @@ var CPObjectControllerObjectClassNameKey = @"CPObjectControllerOb
|
|||||||
|
|
||||||
- (id)initWithKeyPath:(id)aKeyPath observer:(id)anObserver object:(id)anObject
|
- (id)initWithKeyPath:(id)aKeyPath observer:(id)anObserver object:(id)anObject
|
||||||
{
|
{
|
||||||
if (self=[super init])
|
if (self = [super init])
|
||||||
{
|
{
|
||||||
_keyPath = aKeyPath;
|
_keyPath = aKeyPath;
|
||||||
_observer = anObserver;
|
_observer = anObserver;
|
||||||
@@ -319,9 +331,9 @@ var CPObjectControllerObjectClassNameKey = @"CPObjectControllerOb
|
|||||||
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObject change:(CPDictionary)change context:(id)context
|
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObject change:(CPDictionary)change context:(id)context
|
||||||
{
|
{
|
||||||
if (_notifyObject)
|
if (_notifyObject)
|
||||||
[_object observeValueForKeyPath:_keyPath ofObject:_object change:change context:context];
|
[_object observeValueForKeyPath:aKeyPath ofObject:_object change:change context:context];
|
||||||
|
|
||||||
[_observer observeValueForKeyPath:_keyPath ofObject:_object change:change context:context];
|
[_observer observeValueForKeyPath:aKeyPath ofObject:_object change:change context:context];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CPString)description
|
- (CPString)description
|
||||||
@@ -331,7 +343,8 @@ var CPObjectControllerObjectClassNameKey = @"CPObjectControllerOb
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation _CPObservableArray : CPMutableArray
|
// FIXME: This should subclass CPMutableArray not _CPJavaScriptArray
|
||||||
|
@implementation _CPObservableArray : _CPJavaScriptArray
|
||||||
{
|
{
|
||||||
CPArray _observationProxies;
|
CPArray _observationProxies;
|
||||||
}
|
}
|
||||||
@@ -357,25 +370,15 @@ var CPObjectControllerObjectClassNameKey = @"CPObjectControllerOb
|
|||||||
|
|
||||||
- (id)initWithArray:(CPArray)anArray
|
- (id)initWithArray:(CPArray)anArray
|
||||||
{
|
{
|
||||||
if (self = [super initWithArray:anArray])
|
self = [super initWithArray:anArray];
|
||||||
{
|
|
||||||
_observationProxies = [];
|
self.isa = [_CPObservableArray class];
|
||||||
}
|
self._observationProxies = [];
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithObjects:(CPArray)objects count:(unsigned)count
|
- (void)addObserver:(id)anObserver forKeyPath:(CPString)aKeyPath options:(CPKeyValueObservingOptions)options context:(id)context
|
||||||
{
|
|
||||||
if (self = [super initWithObjects:objects count:count])
|
|
||||||
{
|
|
||||||
_observationProxies = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
-(void)addObserver:(id)anObserver forKeyPath:(CPString)aKeyPath options:(CPKeyValueObservingOptions)options context:(id)context
|
|
||||||
{
|
{
|
||||||
if (aKeyPath.indexOf("@") === 0)
|
if (aKeyPath.indexOf("@") === 0)
|
||||||
{
|
{
|
||||||
@@ -387,7 +390,7 @@ var CPObjectControllerObjectClassNameKey = @"CPObjectControllerOb
|
|||||||
[_observationProxies addObject:proxy];
|
[_observationProxies addObject:proxy];
|
||||||
|
|
||||||
var dotIndex = aKeyPath.indexOf("."),
|
var dotIndex = aKeyPath.indexOf("."),
|
||||||
remaining = aKeyPath.substring(dotIndex+1),
|
remaining = aKeyPath.substring(dotIndex + 1),
|
||||||
indexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [self count])];
|
indexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [self count])];
|
||||||
|
|
||||||
[self addObserver:proxy toObjectsAtIndexes:indexes forKeyPath:remaining options:options context:context];
|
[self addObserver:proxy toObjectsAtIndexes:indexes forKeyPath:remaining options:options context:context];
|
||||||
@@ -409,7 +412,7 @@ var CPObjectControllerObjectClassNameKey = @"CPObjectControllerOb
|
|||||||
proxy = [_observationProxies objectAtIndex:index];
|
proxy = [_observationProxies objectAtIndex:index];
|
||||||
|
|
||||||
var dotIndex = aKeyPath.indexOf("."),
|
var dotIndex = aKeyPath.indexOf("."),
|
||||||
remaining = aKeyPath.substring(dotIndex+1),
|
remaining = aKeyPath.substring(dotIndex + 1),
|
||||||
indexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [self count])];
|
indexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [self count])];
|
||||||
|
|
||||||
[self removeObserver:proxy fromObjectsAtIndexes:indexes forKeyPath:remaining];
|
[self removeObserver:proxy fromObjectsAtIndexes:indexes forKeyPath:remaining];
|
||||||
@@ -423,7 +426,7 @@ var CPObjectControllerObjectClassNameKey = @"CPObjectControllerOb
|
|||||||
|
|
||||||
- (void)insertObject:(id)anObject atIndex:(unsigned)anIndex
|
- (void)insertObject:(id)anObject atIndex:(unsigned)anIndex
|
||||||
{
|
{
|
||||||
for (var i=0, count=[_observationProxies count]; i<count; i++)
|
for (var i = 0, count = [_observationProxies count]; i < count; i++)
|
||||||
{
|
{
|
||||||
var proxy = [_observationProxies objectAtIndex:i],
|
var proxy = [_observationProxies objectAtIndex:i],
|
||||||
keyPath = [proxy keyPath],
|
keyPath = [proxy keyPath],
|
||||||
@@ -443,7 +446,7 @@ var CPObjectControllerObjectClassNameKey = @"CPObjectControllerOb
|
|||||||
|
|
||||||
- (void)removeObjectAtIndex:(unsigned)anIndex
|
- (void)removeObjectAtIndex:(unsigned)anIndex
|
||||||
{
|
{
|
||||||
for (var i=0, count=[_observationProxies count]; i<count; i++)
|
for (var i = 0, count = [_observationProxies count]; i < count; i++)
|
||||||
{
|
{
|
||||||
var proxy = [_observationProxies objectAtIndex:i],
|
var proxy = [_observationProxies objectAtIndex:i],
|
||||||
keyPath = [proxy keyPath],
|
keyPath = [proxy keyPath],
|
||||||
@@ -480,7 +483,7 @@ var CPObjectControllerObjectClassNameKey = @"CPObjectControllerOb
|
|||||||
{
|
{
|
||||||
var currentObject = [self objectAtIndex:anIndex];
|
var currentObject = [self objectAtIndex:anIndex];
|
||||||
|
|
||||||
for (var i=0, count=[_observationProxies count]; i<count; i++)
|
for (var i = 0, count = [_observationProxies count]; i < count; i++)
|
||||||
{
|
{
|
||||||
var proxy = [_observationProxies objectAtIndex:i],
|
var proxy = [_observationProxies objectAtIndex:i],
|
||||||
keyPath = [proxy keyPath],
|
keyPath = [proxy keyPath],
|
||||||
@@ -503,11 +506,13 @@ var CPObjectControllerObjectClassNameKey = @"CPObjectControllerOb
|
|||||||
|
|
||||||
@implementation CPControllerSelectionProxy : CPObject
|
@implementation CPControllerSelectionProxy : CPObject
|
||||||
{
|
{
|
||||||
id _controller;
|
id _controller;
|
||||||
id _keys;
|
id _keys;
|
||||||
|
|
||||||
CPDictionary _cachedValues;
|
CPDictionary _cachedValues;
|
||||||
CPArray _observationProxies;
|
CPArray _observationProxies;
|
||||||
|
|
||||||
|
Object _observedObjectsByKeyPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithController:(id)aController
|
- (id)initWithController:(id)aController
|
||||||
@@ -517,46 +522,65 @@ var CPObjectControllerObjectClassNameKey = @"CPObjectControllerOb
|
|||||||
_cachedValues = [CPDictionary dictionary];
|
_cachedValues = [CPDictionary dictionary];
|
||||||
_observationProxies = [CPArray array];
|
_observationProxies = [CPArray array];
|
||||||
_controller = aController;
|
_controller = aController;
|
||||||
|
_observedObjectsByKeyPath = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)valueForKey:(CPString)aKey
|
- (id)_controllerMarkerForValues:(CPArray)theValues
|
||||||
{
|
{
|
||||||
var value = [_cachedValues objectForKey:aKey];
|
var count = [theValues count];
|
||||||
|
|
||||||
if (value !== undefined && value !== nil)
|
|
||||||
return value;
|
|
||||||
|
|
||||||
var allValues = [[_controller selectedObjects] valueForKeyPath:aKey],
|
|
||||||
count = [allValues count];
|
|
||||||
|
|
||||||
if (!count)
|
if (!count)
|
||||||
value = CPNoSelectionMarker;
|
value = CPNoSelectionMarker;
|
||||||
else if (count === 1)
|
else if (count === 1)
|
||||||
value = [allValues objectAtIndex:0];
|
value = [theValues objectAtIndex:0];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ([_controller alwaysUsesMultipleValuesMarker])
|
if ([_controller alwaysUsesMultipleValuesMarker])
|
||||||
value = CPMultipleValuesMarker;
|
value = CPMultipleValuesMarker;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
value = [allValues objectAtIndex:0];
|
value = [theValues objectAtIndex:0];
|
||||||
|
|
||||||
for (var i=0, count=[allValues count]; i<count && value!=CPMultipleValuesMarker; i++)
|
for (var i = 0, count= [theValues count]; i < count && value != CPMultipleValuesMarker; i++)
|
||||||
{
|
{
|
||||||
if (![value isEqual:[allValues objectAtIndex:i]])
|
if (![value isEqual:[theValues objectAtIndex:i]])
|
||||||
value = CPMultipleValuesMarker;
|
value = CPMultipleValuesMarker;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[_cachedValues setValue:value forKey:aKey];
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id)valueForKeyPath:(CPString)theKeyPath
|
||||||
|
{
|
||||||
|
var values = [[_controller selectedObjects] valueForKeyPath:theKeyPath];
|
||||||
|
value = [self _controllerMarkerForValues:values];
|
||||||
|
|
||||||
|
[_cachedValues setObject:value forKey:theKeyPath];
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (id)valueForKey:(CPString)theKeyPath
|
||||||
|
{
|
||||||
|
return [self valueForKeyPath:theKeyPath];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setValue:(id)theValue forKeyPath:(CPString)theKeyPath
|
||||||
|
{
|
||||||
|
[[_controller selectedObjects] setValue:theValue forKeyPath:theKeyPath];
|
||||||
|
[_cachedValues removeObjectForKey:theKeyPath];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setValue:(id)theValue forKey:(CPString)theKeyPath
|
||||||
|
{
|
||||||
|
[self setValue:theKeyPath forKeyPath:theKeyPath];
|
||||||
|
}
|
||||||
|
|
||||||
- (unsigned)count
|
- (unsigned)count
|
||||||
{
|
{
|
||||||
return [_cachedValues count];
|
return [_cachedValues count];
|
||||||
@@ -567,32 +591,27 @@ var CPObjectControllerObjectClassNameKey = @"CPObjectControllerOb
|
|||||||
return [_cachedValues keyEnumerator];
|
return [_cachedValues keyEnumerator];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setValue:(id)aValue forKey:(CPString)aKey
|
- (void)controllerWillChange
|
||||||
{
|
|
||||||
[[_controller selectedObjects] setValue:aValue forKey:aKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
-(void)controllerWillChange
|
|
||||||
{
|
{
|
||||||
_keys = [_cachedValues allKeys];
|
_keys = [_cachedValues allKeys];
|
||||||
|
|
||||||
if (!_keys)
|
if (!_keys)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (var i=0, count=_keys.length; i<count; i++)
|
for (var i = 0, count = _keys.length; i < count; i++)
|
||||||
[self willChangeValueForKey:_keys[i]];
|
[self willChangeValueForKey:_keys[i]];
|
||||||
|
|
||||||
[_cachedValues removeAllObjects];
|
[_cachedValues removeAllObjects];
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)controllerDidChange
|
- (void)controllerDidChange
|
||||||
{
|
{
|
||||||
[_cachedValues removeAllObjects];
|
[_cachedValues removeAllObjects];
|
||||||
|
|
||||||
if (!_keys)
|
if (!_keys)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (var i=0, count=_keys.length; i<count; i++)
|
for (var i = 0, count = _keys.length; i < count; i++)
|
||||||
[self didChangeValueForKey:_keys[i]];
|
[self didChangeValueForKey:_keys[i]];
|
||||||
|
|
||||||
_keys = nil;
|
_keys = nil;
|
||||||
@@ -610,7 +629,11 @@ var CPObjectControllerObjectClassNameKey = @"CPObjectControllerOb
|
|||||||
[proxy setNotifyObject:YES];
|
[proxy setNotifyObject:YES];
|
||||||
[_observationProxies addObject:proxy];
|
[_observationProxies addObject:proxy];
|
||||||
|
|
||||||
[[_controller selectedObjects] addObserver:proxy forKeyPath:aKeyPath options:options context:context];
|
// We keep are reference to the observed objects
|
||||||
|
// because the removeObserver: will be called after the selection changes
|
||||||
|
var observedObjects = [_controller selectedObjects];
|
||||||
|
_observedObjectsByKeyPath[aKeyPath] = observedObjects;
|
||||||
|
[observedObjects addObserver:proxy forKeyPath:aKeyPath options:options context:context];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)removeObserver:(id)anObject forKeyPath:(CPString)aKeyPath
|
- (void)removeObserver:(id)anObject forKeyPath:(CPString)aKeyPath
|
||||||
@@ -618,8 +641,12 @@ var CPObjectControllerObjectClassNameKey = @"CPObjectControllerOb
|
|||||||
var proxy = [[_CPObservationProxy alloc] initWithKeyPath:aKeyPath observer:anObject object:self],
|
var proxy = [[_CPObservationProxy alloc] initWithKeyPath:aKeyPath observer:anObject object:self],
|
||||||
index = [_observationProxies indexOfObject:proxy];
|
index = [_observationProxies indexOfObject:proxy];
|
||||||
|
|
||||||
[[_controller selectedObjects] removeObserver:[_observationProxies objectAtIndex:index] forKeyPath:aKeyPath];
|
var observedObjects = _observedObjectsByKeyPath[aKeyPath];
|
||||||
|
[observedObjects removeObserver:[_observationProxies objectAtIndex:index] forKeyPath:aKeyPath];
|
||||||
|
|
||||||
[_observationProxies removeObjectAtIndex:index];
|
[_observationProxies removeObjectAtIndex:index];
|
||||||
|
|
||||||
|
_observedObjects = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -75,6 +75,16 @@ var CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_
|
|||||||
|
|
||||||
CPOutlineViewDropOnItemIndex = -1;
|
CPOutlineViewDropOnItemIndex = -1;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ingroup appkit
|
||||||
|
@class CPOutlineView
|
||||||
|
|
||||||
|
CPOutlineView is a subclass of CPTableView that inherates the row and column format to display hierarchial data.
|
||||||
|
The outlineview adds the ability to expand and collapse items. This is useful for browsing a tree like structure such as directories or a filesystem.
|
||||||
|
|
||||||
|
Like the tableview, an outlineview uses a data source to supply its data. For this reason you must implement a couple data source methods (documented in setDataSource:)
|
||||||
|
|
||||||
|
*/
|
||||||
@implementation CPOutlineView : CPTableView
|
@implementation CPOutlineView : CPTableView
|
||||||
{
|
{
|
||||||
id _outlineViewDataSource;
|
id _outlineViewDataSource;
|
||||||
@@ -139,7 +149,54 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
/*!
|
||||||
|
In addition to standard delegation, the outline view also supports data source delegation. This method sets the data source object.
|
||||||
|
Just like the TableView you have CPTableColumns but instead of rows you deal with items.
|
||||||
|
|
||||||
|
You must implement these data source methods:
|
||||||
|
|
||||||
|
- (id)outlineView:(CPOutlineView)outlineView child:(CPInteger)index ofItem:(id)item;
|
||||||
|
Returns the child item at an index of a given item. if item is nil you should return the appropriate root item.
|
||||||
|
|
||||||
|
- (BOOL)outlineView:(CPOutlineView)outlineView isItemExpandable:(id)item;
|
||||||
|
Returns YES if the item is expandable, otherwise NO.
|
||||||
|
|
||||||
|
- (int)outlineView:(CPOutlineView)outlineView numberOfChildrenOfItem:(id)item;
|
||||||
|
Returns the number of child items of a given item. If item is nil you should return the number of top level (root) items.
|
||||||
|
|
||||||
|
- (id)outlineView:(CPOutlineView)outlineView objectValueForTableColumn:(CPTableColumn)tableColumn byItem:(id)item;
|
||||||
|
Returns the object value of the item in a given column.
|
||||||
|
|
||||||
|
|
||||||
|
The following methods are optional:
|
||||||
|
|
||||||
|
Editing:
|
||||||
|
- (void)outlineView:(CPOutlineView)outlineView setObjectValue:(id)object forTableColumn:(CPTableColumn)tableColumn byItem:(id)item;
|
||||||
|
Sets the data object value for an item in a given column. This needs to be implemented if you want inline editing support.
|
||||||
|
|
||||||
|
|
||||||
|
Sorting:
|
||||||
|
- (void)outlineView:(CPOutlineView)outlineView sortDescriptorsDidChange:(CPArray)oldDescriptors;
|
||||||
|
The outlineview will call this method if you click the tableheader. You should sort the datasource based off of the new sort descriptors and reload the data
|
||||||
|
|
||||||
|
Drag and Drop:
|
||||||
|
In order for the outlineview to recieve drops dont forget to first register the tableview for drag types like you do with every other view
|
||||||
|
|
||||||
|
- (BOOL)outlineView:(CPOutlineView)outlineView acceptDrop:(id < CPDraggingInfo >)info item:(id)item childIndex:(CPInteger)index;
|
||||||
|
Return YES if the operation was successful otherwise return NO.
|
||||||
|
The data source should incorporate the data from the dragging pasteboard in this method implementation.
|
||||||
|
To get this data use the draggingPasteboard method on the CPDraggingInfo object.
|
||||||
|
|
||||||
|
- (CPDragOperation)outlineView:(CPOutlineView)outlineView validateDrop:(id < CPDraggingInfo >)info proposedItem:(id)item proposedChildIndex:(CPInteger)index;
|
||||||
|
Return the drag operation (move, copy, etc) that should be performaned if a registered drag type is over the tableview
|
||||||
|
The data source can retarget a drop if you want by calling -(void)setDropItem:(id)anItem dropChildIndex:(int)anIndex;
|
||||||
|
|
||||||
|
- (BOOL)outlineView:(CPOutlineView)outlineView writeItems:(CPArray)items toPasteboard:(CPPasteboard)pboard;
|
||||||
|
Returns YES if the drop operation is allowed otherwise NO.
|
||||||
|
This method is invoked by the outlineview after a drag should begin, but before it is started. If you dont want the drag to being return NO.
|
||||||
|
If you want the drag to begin you should return YES and place the drag data on the pboard.
|
||||||
|
|
||||||
|
*/
|
||||||
- (void)setDataSource:(id)aDataSource
|
- (void)setDataSource:(id)aDataSource
|
||||||
{
|
{
|
||||||
if (_outlineViewDataSource === aDataSource)
|
if (_outlineViewDataSource === aDataSource)
|
||||||
@@ -193,11 +250,22 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
[self reloadData];
|
[self reloadData];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the datasource object.
|
||||||
|
@return id - The data source object
|
||||||
|
*/
|
||||||
- (id)dataSource
|
- (id)dataSource
|
||||||
{
|
{
|
||||||
return _outlineViewDataSource;
|
return _outlineViewDataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Used to query whether an item is expandable or not.
|
||||||
|
|
||||||
|
@param anItem - the item you are interested in.
|
||||||
|
|
||||||
|
@return BOOL - YES if the item is expandable, otherwise NO.
|
||||||
|
*/
|
||||||
- (BOOL)isExpandable:(id)anItem
|
- (BOOL)isExpandable:(id)anItem
|
||||||
{
|
{
|
||||||
if (!anItem)
|
if (!anItem)
|
||||||
@@ -211,7 +279,14 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
return itemInfo.isExpandable;
|
return itemInfo.isExpandable;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)isItemExpanded:(id)anItem
|
/*!
|
||||||
|
Used to find if an item is already expanded.
|
||||||
|
|
||||||
|
@param anItem - the item you are interest in.
|
||||||
|
|
||||||
|
@return BOOL - Yes if the item is already expanded, otherwise NO.
|
||||||
|
*/
|
||||||
|
- (BOOL)isItemExpanded:(id)anItem
|
||||||
{
|
{
|
||||||
if (!anItem)
|
if (!anItem)
|
||||||
return YES;
|
return YES;
|
||||||
@@ -224,11 +299,22 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
return itemInfo.isExpanded;
|
return itemInfo.isExpanded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Expends a given item.
|
||||||
|
|
||||||
|
@param anItem - the item to expand.
|
||||||
|
*/
|
||||||
- (void)expandItem:(id)anItem
|
- (void)expandItem:(id)anItem
|
||||||
{
|
{
|
||||||
[self expandItem:anItem expandChildren:NO];
|
[self expandItem:anItem expandChildren:NO];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Expands a given item, and optionally all the children of that item.
|
||||||
|
|
||||||
|
@param anItem - the item you want to expand.
|
||||||
|
@param shouldExpandChildren - Pass YES if you want to expand all the children of anItem, otherwise NO.
|
||||||
|
*/
|
||||||
- (void)expandItem:(id)anItem expandChildren:(BOOL)shouldExpandChildren
|
- (void)expandItem:(id)anItem expandChildren:(BOOL)shouldExpandChildren
|
||||||
{
|
{
|
||||||
var itemInfo = null;
|
var itemInfo = null;
|
||||||
@@ -245,6 +331,22 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
if (!itemInfo.isExpanded)
|
if (!itemInfo.isExpanded)
|
||||||
{
|
{
|
||||||
[self _noteItemWillExpand:anItem];
|
[self _noteItemWillExpand:anItem];
|
||||||
|
|
||||||
|
// Shift selection indexes below so that the same items remain selected.
|
||||||
|
var newRowCount = [_outlineViewDataSource outlineView:self numberOfChildrenOfItem:anItem];
|
||||||
|
if (newRowCount)
|
||||||
|
{
|
||||||
|
var selection = [self selectedRowIndexes],
|
||||||
|
expandIndex = [self rowForItem:anItem] + 1;
|
||||||
|
|
||||||
|
if ([selection intersectsIndexesInRange:CPMakeRange(expandIndex, _itemsForRows.length)])
|
||||||
|
{
|
||||||
|
[self _noteSelectionIsChanging];
|
||||||
|
[selection shiftIndexesStartingAtIndex:expandIndex by:newRowCount];
|
||||||
|
[self _setSelectedRowIndexes:selection];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
itemInfo.isExpanded = YES;
|
itemInfo.isExpanded = YES;
|
||||||
[self _noteItemDidExpand:anItem];
|
[self _noteItemDidExpand:anItem];
|
||||||
[self reloadItem:anItem reloadChildren:YES];
|
[self reloadItem:anItem reloadChildren:YES];
|
||||||
@@ -260,6 +362,11 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Collapse a given item.
|
||||||
|
|
||||||
|
@param anItem - The item you want to collapse.
|
||||||
|
*/
|
||||||
- (void)collapseItem:(id)anItem
|
- (void)collapseItem:(id)anItem
|
||||||
{
|
{
|
||||||
if (!anItem)
|
if (!anItem)
|
||||||
@@ -274,17 +381,68 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
[self _noteItemWillCollapse:anItem];
|
[self _noteItemWillCollapse:anItem];
|
||||||
|
// Update selections:
|
||||||
|
// * Deselect items inside the collapsed item.
|
||||||
|
// * Shift row selections below the collapsed item so that the same logical items remain selected.
|
||||||
|
var collapseTopIndex = [self rowForItem:anItem],
|
||||||
|
topLevel = [self levelForRow:collapseTopIndex],
|
||||||
|
collapseEndIndex = collapseTopIndex;
|
||||||
|
|
||||||
|
while (collapseEndIndex + 1 < _itemsForRows.length && [self levelForRow:collapseEndIndex + 1] > topLevel)
|
||||||
|
collapseEndIndex++;
|
||||||
|
|
||||||
|
var collapseRange = CPMakeRange(collapseTopIndex + 1, collapseEndIndex - collapseTopIndex);
|
||||||
|
if (collapseRange.length)
|
||||||
|
{
|
||||||
|
var selection = [self selectedRowIndexes],
|
||||||
|
didChange = NO;
|
||||||
|
|
||||||
|
if ([selection intersectsIndexesInRange:collapseRange])
|
||||||
|
{
|
||||||
|
[selection removeIndexesInRange:collapseRange];
|
||||||
|
[self _noteSelectionIsChanging];
|
||||||
|
didChange = YES;
|
||||||
|
// Will call _noteSelectionDidChange
|
||||||
|
[self _setSelectedRowIndexes:selection];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shift any selected rows below upwards.
|
||||||
|
if ([selection intersectsIndexesInRange:CPMakeRange(collapseEndIndex + 1, _itemsForRows.length)])
|
||||||
|
{
|
||||||
|
// Notify if that wasn't already done above.
|
||||||
|
if (!didChange)
|
||||||
|
[self _noteSelectionIsChanging];
|
||||||
|
didChange = YES;
|
||||||
|
|
||||||
|
[selection shiftIndexesStartingAtIndex:collapseEndIndex + 1 by:-collapseRange.length];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (didChange)
|
||||||
|
[self _setSelectedRowIndexes:selection];
|
||||||
|
}
|
||||||
itemInfo.isExpanded = NO;
|
itemInfo.isExpanded = NO;
|
||||||
|
|
||||||
[self _noteItemDidCollapse:anItem];
|
[self _noteItemDidCollapse:anItem];
|
||||||
|
|
||||||
[self reloadItem:anItem reloadChildren:YES];
|
[self reloadItem:anItem reloadChildren:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Reloads the data for an item.
|
||||||
|
|
||||||
|
@param anItem - The item you want to reload.
|
||||||
|
*/
|
||||||
- (void)reloadItem:(id)anItem
|
- (void)reloadItem:(id)anItem
|
||||||
{
|
{
|
||||||
[self reloadItem:anItem reloadChildren:NO];
|
[self reloadItem:anItem reloadChildren:NO];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Reloads the data for a given item and optionally the children.
|
||||||
|
|
||||||
|
@param anItem - The item you want to reload.
|
||||||
|
@param shouldReloadChildren - Pass YES if you want to reload all the children, otherwise NO.
|
||||||
|
*/
|
||||||
- (void)reloadItem:(id)anItem reloadChildren:(BOOL)shouldReloadChildren
|
- (void)reloadItem:(id)anItem reloadChildren:(BOOL)shouldReloadChildren
|
||||||
{
|
{
|
||||||
if (!!shouldReloadChildren || !anItem)
|
if (!!shouldReloadChildren || !anItem)
|
||||||
@@ -295,11 +453,23 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
[super reloadData];
|
[super reloadData];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the item at a given row index. If no item exists nil is returned.
|
||||||
|
|
||||||
|
@param aRow - The rown index you want to find the item at.
|
||||||
|
@return id - The item at a given index.
|
||||||
|
*/
|
||||||
- (id)itemAtRow:(CPInteger)aRow
|
- (id)itemAtRow:(CPInteger)aRow
|
||||||
{
|
{
|
||||||
return _itemsForRows[aRow] || nil;
|
return _itemsForRows[aRow] || nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the row of a given item
|
||||||
|
|
||||||
|
@param anItem - The item you want to find the row of.
|
||||||
|
@return int - The row index of a given item.
|
||||||
|
*/
|
||||||
- (CPInteger)rowForItem:(id)anItem
|
- (CPInteger)rowForItem:(id)anItem
|
||||||
{
|
{
|
||||||
if (!anItem)
|
if (!anItem)
|
||||||
@@ -313,6 +483,11 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
return itemInfo.row;
|
return itemInfo.row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the table column you want to display the disclosure button in.
|
||||||
|
|
||||||
|
@param aTableColumn - The CPTableColumn you want to use for hierarchical data.
|
||||||
|
*/
|
||||||
- (void)setOutlineTableColumn:(CPTableColumn)aTableColumn
|
- (void)setOutlineTableColumn:(CPTableColumn)aTableColumn
|
||||||
{
|
{
|
||||||
if (_outlineTableColumn === aTableColumn)
|
if (_outlineTableColumn === aTableColumn)
|
||||||
@@ -324,11 +499,22 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
[self reloadData];
|
[self reloadData];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the table column used to display hierarchical data.
|
||||||
|
|
||||||
|
@return CPTableColumn - The table column that displays the disclosure button.
|
||||||
|
*/
|
||||||
- (CPTableColumn)outlineTableColumn
|
- (CPTableColumn)outlineTableColumn
|
||||||
{
|
{
|
||||||
return _outlineTableColumn;
|
return _outlineTableColumn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the indentation level of a given item. If the item is nil (the top level root item) CPNotFound is returned. Indentation levels are zero based, thus items that are not indented return 0.
|
||||||
|
|
||||||
|
@param anItem - The item you want the indentation level for.
|
||||||
|
@return int - the indentation level of anItem.
|
||||||
|
*/
|
||||||
- (CPInteger)levelForItem:(id)anItem
|
- (CPInteger)levelForItem:(id)anItem
|
||||||
{
|
{
|
||||||
if (!anItem)
|
if (!anItem)
|
||||||
@@ -342,11 +528,22 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
return itemInfo.level;
|
return itemInfo.level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the indentation level for a given row. If the row is invalid CPNotFound is returned. Rows that are nto indented return 0.
|
||||||
|
|
||||||
|
@param aRow - the row of the reciever
|
||||||
|
@return int - the indentation level of aRow.
|
||||||
|
*/
|
||||||
- (CPInteger)levelForRow:(CPInteger)aRow
|
- (CPInteger)levelForRow:(CPInteger)aRow
|
||||||
{
|
{
|
||||||
return [self levelForItem:[self itemAtRow:aRow]];
|
return [self levelForItem:[self itemAtRow:aRow]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the number of pixels to indent an item at each indentation level.
|
||||||
|
|
||||||
|
@param anIndentationWidth - the width of each indentation level.
|
||||||
|
*/
|
||||||
- (void)setIndentationPerLevel:(float)anIndentationWidth
|
- (void)setIndentationPerLevel:(float)anIndentationWidth
|
||||||
{
|
{
|
||||||
if (_indentationPerLevel === anIndentationWidth)
|
if (_indentationPerLevel === anIndentationWidth)
|
||||||
@@ -358,11 +555,21 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
[self reloadData];
|
[self reloadData];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the width of an indentation level.
|
||||||
|
|
||||||
|
@return float - the width of the indentation per level.
|
||||||
|
*/
|
||||||
- (float)indentationPerLevel
|
- (float)indentationPerLevel
|
||||||
{
|
{
|
||||||
return _indentationPerLevel;
|
return _indentationPerLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the layout behaviour of disclosure button. If you pass NO the disclosure button will always align itself to the left of the outline column.
|
||||||
|
|
||||||
|
@param indentationMarkerShouldFollowDataView - Pass YES if the disclosure control should be indented along with the dataview, otherwise NO.
|
||||||
|
*/
|
||||||
- (void)setIndentationMarkerFollowsDataView:(BOOL)indentationMarkerShouldFollowDataView
|
- (void)setIndentationMarkerFollowsDataView:(BOOL)indentationMarkerShouldFollowDataView
|
||||||
{
|
{
|
||||||
if (_indentationMarkerFollowsDataView === indentationMarkerShouldFollowDataView)
|
if (_indentationMarkerFollowsDataView === indentationMarkerShouldFollowDataView)
|
||||||
@@ -374,11 +581,22 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
[self reloadData];
|
[self reloadData];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the layout behaviour of the disclosure buttons.
|
||||||
|
|
||||||
|
@return BOOL - YES if the disclosure control indents itself with the dataview, otherwise NO if the control is always aligned to the left of the outline column
|
||||||
|
*/
|
||||||
- (BOOL)indentationMarkerFollowsDataView
|
- (BOOL)indentationMarkerFollowsDataView
|
||||||
{
|
{
|
||||||
return _indentationMarkerFollowsDataView;
|
return _indentationMarkerFollowsDataView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the parent item for a given item. If the item is a top level root object nil is returned.
|
||||||
|
|
||||||
|
@param anItem - The item of the reciver.
|
||||||
|
@return id - The parent item of anItem. If no parent exists (the item is a root item) nil is returned.
|
||||||
|
*/
|
||||||
- (id)parentForItem:(id)anItem
|
- (id)parentForItem:(id)anItem
|
||||||
{
|
{
|
||||||
if (!anItem)
|
if (!anItem)
|
||||||
@@ -398,9 +616,15 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGRect)frameOfOutlineDataViewAtColumn:(CPInteger)aColumn row:(CPInteger)aRow
|
/*!
|
||||||
|
@ignore
|
||||||
|
|
||||||
|
Returns the frame of the dataview at the row given for the outline column
|
||||||
|
*/
|
||||||
|
- (CGRect)_frameOfOutlineDataViewAtRow:(CPInteger)aRow
|
||||||
{
|
{
|
||||||
var frame = [super frameOfDataViewAtColumn:aColumn row:aRow],
|
var columnIndex = [[self tableColumns] indexOfObject:_outlineTableColumn],
|
||||||
|
frame = [super frameOfDataViewAtColumn:columnIndex row:aRow],
|
||||||
indentationWidth = ([self levelForRow:aRow] + 1) * [self indentationPerLevel];
|
indentationWidth = ([self levelForRow:aRow] + 1) * [self indentationPerLevel];
|
||||||
|
|
||||||
frame.origin.x += indentationWidth;
|
frame.origin.x += indentationWidth;
|
||||||
@@ -409,6 +633,29 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the frame of the disclosure button for the outline column.
|
||||||
|
If the item is not expandable a CGZeroRect is returned.
|
||||||
|
Subclasses can return a CGZeroRect to prevent the disclosure control from being displayed.
|
||||||
|
|
||||||
|
@param aRow - The row of the reciever
|
||||||
|
@return CGRect - The rect of the disclosure button at aRow.
|
||||||
|
*/
|
||||||
|
- (CGRect)frameOfOutlineDisclosureControlAtRow:(CPInteger)aRow
|
||||||
|
{
|
||||||
|
if (![self isExpandable:[self itemAtRow:aRow]])
|
||||||
|
return _CGRectMakeZero();
|
||||||
|
|
||||||
|
var dataViewFrame = [self _frameOfOutlineDataViewAtRow:aRow],
|
||||||
|
frame = _CGRectMake(_CGRectGetMinX(dataViewFrame) - 10, _CGRectGetMinY(dataViewFrame), 10, _CGRectGetHeight(dataViewFrame));
|
||||||
|
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
Select or deselect rows, this is overridden because we need to change the color or the outline control
|
||||||
|
*/
|
||||||
- (void)_performSelection:(BOOL)select forRow:(CPInteger)rowIndex context:(id)context
|
- (void)_performSelection:(BOOL)select forRow:(CPInteger)rowIndex context:(id)context
|
||||||
{
|
{
|
||||||
[super _performSelection:select forRow:rowIndex context:context];
|
[super _performSelection:select forRow:rowIndex context:context];
|
||||||
@@ -419,6 +666,68 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
[control performSelector:CPSelectorFromString(selector) withObject:CPThemeStateSelected];
|
[control performSelector:CPSelectorFromString(selector) withObject:CPThemeStateSelected];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the delegate for the outlineview.
|
||||||
|
|
||||||
|
The following methods can be implemented:
|
||||||
|
|
||||||
|
User Interaction Notifications:
|
||||||
|
- (void)outlineViewColumnDidMove:(CPNotification)notification;
|
||||||
|
Called when the user moves a column in the outlineview.
|
||||||
|
|
||||||
|
- (void)outlineViewColumnDidResize:(CPNotification)notification;
|
||||||
|
Called when the user resizes a column in the outlineview.
|
||||||
|
|
||||||
|
- (void)outlineViewItemDidCollapse:(CPNotification)notification;
|
||||||
|
Called when the user collapses an item in teh outlineview.
|
||||||
|
|
||||||
|
- (void)outlineViewItemDidExpand:(CPNotification)notification;
|
||||||
|
Called when the user expands an item in the outlineview.
|
||||||
|
|
||||||
|
- (void)outlineViewItemWillCollapse:(CPNotification)notification;
|
||||||
|
Called when the user collapses an item in the outlineview, but before the item is actually collapsed.
|
||||||
|
|
||||||
|
- (void)outlineViewItemWillExpand:(CPNotification)notification;
|
||||||
|
Called when the used expands an item, but before the item is actually expanded.
|
||||||
|
|
||||||
|
- (void)outlineViewSelectionDidChange:(CPNotification)notification;
|
||||||
|
Called when the user changes the selection of the outlineview.
|
||||||
|
|
||||||
|
- (void)outlineViewSelectionIsChanging:(CPNotification)notification
|
||||||
|
Called when the user changes the selection of the outlineview, but before the change is made.
|
||||||
|
|
||||||
|
Expanding and collapsing items:
|
||||||
|
- (BOOL)outlineView:(CPOutlineView)outlineView shouldExpandItem:(id)item;
|
||||||
|
Return YES if the item should be given permission to expand, otherwise NO.
|
||||||
|
|
||||||
|
- (BOOL)outlineView:(CPOutlineView)outlineView shouldCollapseItem:(id)item;
|
||||||
|
Return YES if the item should be given permission to collapse, otherwise NO.
|
||||||
|
|
||||||
|
Selection:
|
||||||
|
- (BOOL)outlineView:(CPOutlineView)outlineView shouldSelectTableColumn:(CPTableColumn)tableColumn;
|
||||||
|
Return YES to allow the selection of tableColumn, otherwise NO.
|
||||||
|
|
||||||
|
- (BOOL)outlineView:(CPOutlineView)outlineView shouldSelectItem:(id)item;
|
||||||
|
Return YES to allow the selection of an item, otherwise NO.
|
||||||
|
|
||||||
|
- (BOOL)selectionShouldChangeInOutlineView:(CPOutlineView)outlineView;
|
||||||
|
Return YES to allow the selection of the outlineview to be changed, otherwise NO.
|
||||||
|
|
||||||
|
Displaying DataViews:
|
||||||
|
- (void)outlineView:(CPOutlineView)outlineView willDisplayView:(id)dataView forTableColumn:(CPTableColumn)tableColumn item:(id)item;
|
||||||
|
Called when a dataView is about to be displayed. This gives you the ability to alter the dataView if needed.
|
||||||
|
|
||||||
|
Editing:
|
||||||
|
- (BOOL)outlineView:(CPOutlineView)outlineView shouldEditTableColumn:(CPTableColumn)tableColumn item:(id)item;
|
||||||
|
Return YES to allow for editing of a dataview at given item and tableColumn, otherwise NO to prevent the edit.
|
||||||
|
|
||||||
|
Group Items:
|
||||||
|
- (BOOL)outlineView:(CPOutlineView)outlineView isGroupItem:(id)item;
|
||||||
|
Implement this to indicate whether a given item should be rendered using the group item style.
|
||||||
|
Return YES if the item is a group item, otherwise NO.
|
||||||
|
|
||||||
|
@param aDelegate - the delegate object you wish to set for the reciever.
|
||||||
|
*/
|
||||||
- (void)setDelegate:(id)aDelegate
|
- (void)setDelegate:(id)aDelegate
|
||||||
{
|
{
|
||||||
if (_outlineViewDelegate === aDelegate)
|
if (_outlineViewDelegate === aDelegate)
|
||||||
@@ -513,10 +822,10 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
],
|
],
|
||||||
delegateCount = [delegateMethods count];
|
delegateCount = [delegateMethods count];
|
||||||
|
|
||||||
for (var i=0; i < delegateCount; i += 2)
|
for (var i = 0; i < delegateCount; i += 2)
|
||||||
{
|
{
|
||||||
var bitMask = delegateMethods[i],
|
var bitMask = delegateMethods[i],
|
||||||
selector = delegateMethods[i+1];
|
selector = delegateMethods[i + 1];
|
||||||
|
|
||||||
if ([_outlineViewDelegate respondsToSelector:selector])
|
if ([_outlineViewDelegate respondsToSelector:selector])
|
||||||
_implementedOutlineViewDelegateMethods |= bitMask;
|
_implementedOutlineViewDelegateMethods |= bitMask;
|
||||||
@@ -581,11 +890,20 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the delegate object for the outlineview.
|
||||||
|
*/
|
||||||
- (id)delegate
|
- (id)delegate
|
||||||
{
|
{
|
||||||
return _outlineViewDelegate;
|
return _outlineViewDelegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the prototype of the disclosure control. This is used if you want to set a special type of button, instead of the default triangle.
|
||||||
|
The control must implement CPCoding.
|
||||||
|
|
||||||
|
@param aControl - the control to be used to expand and collapse items.
|
||||||
|
*/
|
||||||
- (void)setDisclosureControlPrototype:(CPControl)aControl
|
- (void)setDisclosureControlPrototype:(CPControl)aControl
|
||||||
{
|
{
|
||||||
_disclosureControlPrototype = aControl;
|
_disclosureControlPrototype = aControl;
|
||||||
@@ -596,21 +914,97 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
[self reloadData];
|
[self reloadData];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Reloads all the data of the outlineview.
|
||||||
|
*/
|
||||||
- (void)reloadData
|
- (void)reloadData
|
||||||
{
|
{
|
||||||
[self reloadItem:nil reloadChildren:YES];
|
[self reloadItem:nil reloadChildren:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
We overide this because we need a special behaviour for the outline column
|
||||||
|
*/
|
||||||
- (CGRect)frameOfDataViewAtColumn:(CPInteger)aColumn row:(CPInteger)aRow
|
- (CGRect)frameOfDataViewAtColumn:(CPInteger)aColumn row:(CPInteger)aRow
|
||||||
{
|
{
|
||||||
var tableColumn = [self tableColumns][aColumn];
|
var tableColumn = [self tableColumns][aColumn];
|
||||||
|
|
||||||
if (tableColumn === _outlineTableColumn)
|
if (tableColumn === _outlineTableColumn)
|
||||||
return [self frameOfOutlineDataViewAtColumn:aColumn row:aRow];
|
return [self _frameOfOutlineDataViewAtRow:aRow];
|
||||||
|
|
||||||
return [super frameOfDataViewAtColumn:aColumn row:aRow];
|
return [super frameOfDataViewAtColumn:aColumn row:aRow];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
we need to offset the dataview and add the dislosure triangle
|
||||||
|
*/
|
||||||
|
- (CPView)_dragViewForColumn:(int)theColumnIndex event:(CPEvent)theDragEvent offset:(CPPointPointer)theDragViewOffset
|
||||||
|
{
|
||||||
|
var dragView = [[_CPColumnDragView alloc] initWithLineColor:[self gridColor]],
|
||||||
|
tableColumn = [[self tableColumns] objectAtIndex:theColumnIndex],
|
||||||
|
bounds = _CGRectMake(0.0, 0.0, [tableColumn width], _CGRectGetHeight([self exposedRect]) + 23.0),
|
||||||
|
columnRect = [self rectOfColumn:theColumnIndex],
|
||||||
|
headerView = [tableColumn headerView],
|
||||||
|
row = [_exposedRows firstIndex];
|
||||||
|
|
||||||
|
while (row !== CPNotFound)
|
||||||
|
{
|
||||||
|
var dataView = [self _newDataViewForRow:row tableColumn:tableColumn],
|
||||||
|
dataViewFrame = [self frameOfDataViewAtColumn:theColumnIndex row:row];
|
||||||
|
|
||||||
|
// Only one column is ever dragged so we just place the view at
|
||||||
|
dataViewFrame.origin.x = 0.0;
|
||||||
|
|
||||||
|
// Offset by table header height - scroll position
|
||||||
|
dataViewFrame.origin.y = ( _CGRectGetMinY(dataViewFrame) - _CGRectGetMinY([self exposedRect]) ) + 23.0;
|
||||||
|
[dataView setFrame:dataViewFrame];
|
||||||
|
|
||||||
|
[dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]];
|
||||||
|
|
||||||
|
|
||||||
|
if (tableColumn === _outlineTableColumn)
|
||||||
|
{
|
||||||
|
// first inset the dragview
|
||||||
|
var indentationWidth = ([self levelForRow:row] + 1) * [self indentationPerLevel];
|
||||||
|
|
||||||
|
dataViewFrame.origin.x += indentationWidth;
|
||||||
|
dataViewFrame.size.width -= indentationWidth;
|
||||||
|
|
||||||
|
[dataView setFrame:dataViewFrame];
|
||||||
|
}
|
||||||
|
|
||||||
|
[dragView addSubview:dataView];
|
||||||
|
|
||||||
|
row = [_exposedRows indexGreaterThanIndex:row];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the column header view
|
||||||
|
var headerFrame = [headerView frame];
|
||||||
|
headerFrame.origin = _CGPointMakeZero();
|
||||||
|
|
||||||
|
var columnHeaderView = [[_CPTableColumnHeaderView alloc] initWithFrame:headerFrame];
|
||||||
|
[columnHeaderView setStringValue:[headerView stringValue]];
|
||||||
|
[columnHeaderView setThemeState:[headerView themeState]];
|
||||||
|
[dragView addSubview:columnHeaderView];
|
||||||
|
|
||||||
|
[dragView setBackgroundColor:[CPColor whiteColor]];
|
||||||
|
[dragView setAlphaValue:0.7];
|
||||||
|
[dragView setFrame:bounds];
|
||||||
|
|
||||||
|
return dragView;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Retargets the drop item for the outlineview.
|
||||||
|
To specify a drop on theItem, you specify item as theItem and index as CPOutlineViewDropOnItemIndex.
|
||||||
|
To specify a drop between child 1 and 2 of theItem, you specify item as theItem and index as 2.
|
||||||
|
To specify a drop on an item that can't be expanded theItem, you specify item as someOutlineItem and index as CPOutlineViewDropOnItemIndex.
|
||||||
|
|
||||||
|
@param theItem - The item you want to retarget the drop on.
|
||||||
|
@param theIndex - The index of the child item you want to retarget the drop between. Pass CPOutlineViewDropOnItemIndex if you want to drop on theItem.
|
||||||
|
*/
|
||||||
- (void)setDropItem:(id)theItem dropChildIndex:(int)theIndex
|
- (void)setDropItem:(id)theItem dropChildIndex:(int)theIndex
|
||||||
{
|
{
|
||||||
if (_dropItem !== theItem && theIndex < 0 && [self isExpandable:theItem] && ![self isItemExpanded:theItem])
|
if (_dropItem !== theItem && theIndex < 0 && [self isExpandable:theItem] && ![self isItemExpanded:theItem])
|
||||||
@@ -657,6 +1051,9 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
- (void)_draggingEnded
|
- (void)_draggingEnded
|
||||||
{
|
{
|
||||||
[super _draggingEnded];
|
[super _draggingEnded];
|
||||||
@@ -665,13 +1062,16 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
_dragHoverTimer = nil;
|
_dragHoverTimer = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
- (id)_parentItemForUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex atMouseOffset:(CPPoint)theOffset
|
- (id)_parentItemForUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex atMouseOffset:(CPPoint)theOffset
|
||||||
{
|
{
|
||||||
if (_shouldRetargetItem)
|
if (_shouldRetargetItem)
|
||||||
return _retargetedItem;
|
return _retargetedItem;
|
||||||
|
|
||||||
var lowerLevel = [self levelForRow:theLowerRowIndex]
|
var lowerLevel = [self levelForRow:theLowerRowIndex],
|
||||||
upperItem = [self itemAtRow:theUpperRowIndex];
|
upperItem = [self itemAtRow:theUpperRowIndex],
|
||||||
upperLevel = [self levelForItem:upperItem];
|
upperLevel = [self levelForItem:upperItem];
|
||||||
|
|
||||||
// If the row above us has a higher level the item can be added to multiple parent items
|
// If the row above us has a higher level the item can be added to multiple parent items
|
||||||
@@ -692,6 +1092,9 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
return [self parentForItem:[self itemAtRow:theLowerRowIndex]];
|
return [self parentForItem:[self itemAtRow:theLowerRowIndex]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
- (CPRect)_rectForDropHighlightViewBetweenUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex offset:(CPPoint)theOffset
|
- (CPRect)_rectForDropHighlightViewBetweenUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex offset:(CPPoint)theOffset
|
||||||
{
|
{
|
||||||
// Call super and the update x to reflect the current indentation level
|
// Call super and the update x to reflect the current indentation level
|
||||||
@@ -705,13 +1108,59 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
We need to move the disclosure control too
|
||||||
|
*/
|
||||||
|
- (void)_layoutDataViewsInRows:(CPIndexSet)rows columns:(CPIndexSet)columns
|
||||||
|
{
|
||||||
|
var rowArray = [],
|
||||||
|
columnArray = [];
|
||||||
|
|
||||||
|
[rows getIndexes:rowArray maxCount:-1 inIndexRange:nil];
|
||||||
|
[columns getIndexes:columnArray maxCount:-1 inIndexRange:nil];
|
||||||
|
|
||||||
|
var columnIndex = 0,
|
||||||
|
columnsCount = columnArray.length;
|
||||||
|
|
||||||
|
for (; columnIndex < columnsCount; ++columnIndex)
|
||||||
|
{
|
||||||
|
var column = columnArray[columnIndex],
|
||||||
|
tableColumn = _tableColumns[column],
|
||||||
|
tableColumnUID = [tableColumn UID],
|
||||||
|
dataViewsForTableColumn = _dataViewsForTableColumns[tableColumnUID],
|
||||||
|
rowIndex = 0,
|
||||||
|
rowsCount = rowArray.length;
|
||||||
|
|
||||||
|
for (; rowIndex < rowsCount; ++rowIndex)
|
||||||
|
{
|
||||||
|
var row = rowArray[rowIndex],
|
||||||
|
dataView = dataViewsForTableColumn[row],
|
||||||
|
dataViewFrame = [self frameOfDataViewAtColumn:column row:row];
|
||||||
|
|
||||||
|
[dataView setFrame:dataViewFrame];
|
||||||
|
|
||||||
|
if (tableColumn === _outlineTableColumn)
|
||||||
|
{
|
||||||
|
var control = _disclosureControlsForRows[row],
|
||||||
|
frame = [self frameOfOutlineDisclosureControlAtRow:row];
|
||||||
|
|
||||||
|
[control setFrame:frame];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
- (void)_loadDataViewsInRows:(CPIndexSet)rows columns:(CPIndexSet)columns
|
- (void)_loadDataViewsInRows:(CPIndexSet)rows columns:(CPIndexSet)columns
|
||||||
{
|
{
|
||||||
[super _loadDataViewsInRows:rows columns:columns];
|
[super _loadDataViewsInRows:rows columns:columns];
|
||||||
|
|
||||||
var outlineColumn = [[self tableColumns] indexOfObjectIdenticalTo:[self outlineTableColumn]];
|
var outlineColumn = [[self tableColumns] indexOfObjectIdenticalTo:[self outlineTableColumn]];
|
||||||
|
|
||||||
if (![columns containsIndex:outlineColumn])
|
if (![columns containsIndex:outlineColumn] || [self outlineTableColumn] === _draggedColumn)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var rowArray = [];
|
var rowArray = [];
|
||||||
@@ -730,27 +1179,22 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
if (!isExpandable)
|
if (!isExpandable)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var control = [self _dequeueDisclosureControl],
|
var control = [self _dequeueDisclosureControl];
|
||||||
frame = [control frame],
|
|
||||||
dataViewFrame = [self frameOfDataViewAtColumn:outlineColumn row:row];
|
|
||||||
|
|
||||||
frame.origin.x = _indentationMarkerFollowsDataView ? _CGRectGetMinX(dataViewFrame) - _CGRectGetWidth(frame) : 0.0;
|
|
||||||
frame.origin.y = _CGRectGetMinY(dataViewFrame);
|
|
||||||
frame.size.height = _CGRectGetHeight(dataViewFrame);
|
|
||||||
// FIXME: center instead?
|
|
||||||
//frame.origin.y = _CGRectGetMidY(dataViewFrame) - _CGRectGetHeight(frame) / 2.0;
|
|
||||||
|
|
||||||
_disclosureControlsForRows[row] = control;
|
_disclosureControlsForRows[row] = control;
|
||||||
|
|
||||||
[control setState:[self isItemExpanded:item] ? CPOnState : CPOffState];
|
[control setState:[self isItemExpanded:item] ? CPOnState : CPOffState];
|
||||||
var selector = [self isRowSelected:row] ? @"setThemeState:" : @"unsetThemeState:";
|
var selector = [self isRowSelected:row] ? @"setThemeState:" : @"unsetThemeState:";
|
||||||
[control performSelector:CPSelectorFromString(selector) withObject:CPThemeStateSelected];
|
[control performSelector:CPSelectorFromString(selector) withObject:CPThemeStateSelected];
|
||||||
[control setFrame:frame];
|
[control setFrame:[self frameOfOutlineDisclosureControlAtRow:row]];
|
||||||
|
|
||||||
[self addSubview:control];
|
[self addSubview:control];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
- (void)_unloadDataViewsInRows:(CPIndexSet)rows columns:(CPIndexSet)columns
|
- (void)_unloadDataViewsInRows:(CPIndexSet)rows columns:(CPIndexSet)columns
|
||||||
{
|
{
|
||||||
[super _unloadDataViewsInRows:rows columns:columns];
|
[super _unloadDataViewsInRows:rows columns:columns];
|
||||||
@@ -783,6 +1227,9 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
- (void)_toggleFromDisclosureControl:(CPControl)aControl
|
- (void)_toggleFromDisclosureControl:(CPControl)aControl
|
||||||
{
|
{
|
||||||
var controlFrame = [aControl frame],
|
var controlFrame = [aControl frame],
|
||||||
@@ -795,11 +1242,17 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
[self expandItem:item];
|
[self expandItem:item];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
- (void)_enqueueDisclosureControl:(CPControl)aControl
|
- (void)_enqueueDisclosureControl:(CPControl)aControl
|
||||||
{
|
{
|
||||||
_disclosureControlQueue.push(aControl);
|
_disclosureControlQueue.push(aControl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
- (CPControl)_dequeueDisclosureControl
|
- (CPControl)_dequeueDisclosureControl
|
||||||
{
|
{
|
||||||
if (_disclosureControlQueue.length)
|
if (_disclosureControlQueue.length)
|
||||||
@@ -819,6 +1272,9 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
return disclosureControl;
|
return disclosureControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
- (void)_noteSelectionIsChanging
|
- (void)_noteSelectionIsChanging
|
||||||
{
|
{
|
||||||
[[CPNotificationCenter defaultCenter]
|
[[CPNotificationCenter defaultCenter]
|
||||||
@@ -827,6 +1283,9 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
userInfo:nil];
|
userInfo:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
- (void)_noteSelectionDidChange
|
- (void)_noteSelectionDidChange
|
||||||
{
|
{
|
||||||
[[CPNotificationCenter defaultCenter]
|
[[CPNotificationCenter defaultCenter]
|
||||||
@@ -835,6 +1294,9 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
userInfo:nil];
|
userInfo:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
- (void)_noteItemWillExpand:(id)item
|
- (void)_noteItemWillExpand:(id)item
|
||||||
{
|
{
|
||||||
[[CPNotificationCenter defaultCenter]
|
[[CPNotificationCenter defaultCenter]
|
||||||
@@ -843,6 +1305,9 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
|
userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
- (void)_noteItemDidExpand:(id)item
|
- (void)_noteItemDidExpand:(id)item
|
||||||
{
|
{
|
||||||
[[CPNotificationCenter defaultCenter]
|
[[CPNotificationCenter defaultCenter]
|
||||||
@@ -851,6 +1316,9 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
|
userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
- (void)_noteItemWillCollapse:(id)item
|
- (void)_noteItemWillCollapse:(id)item
|
||||||
{
|
{
|
||||||
[[CPNotificationCenter defaultCenter]
|
[[CPNotificationCenter defaultCenter]
|
||||||
@@ -859,6 +1327,9 @@ CPOutlineViewDropOnItemIndex = -1;
|
|||||||
userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
|
userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
- (void)_noteItemDidCollapse:(id)item
|
- (void)_noteItemDidCollapse:(id)item
|
||||||
{
|
{
|
||||||
[[CPNotificationCenter defaultCenter]
|
[[CPNotificationCenter defaultCenter]
|
||||||
@@ -875,7 +1346,7 @@ var _reloadItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anItem)
|
|||||||
if (!anItem)
|
if (!anItem)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
with(anOutlineView)
|
with (anOutlineView)
|
||||||
{
|
{
|
||||||
// Get the existing info if it exists.
|
// Get the existing info if it exists.
|
||||||
var itemInfosForItems = _itemInfosForItems,
|
var itemInfosForItems = _itemInfosForItems,
|
||||||
@@ -911,7 +1382,7 @@ var _reloadItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anItem)
|
|||||||
// FIX ME: We're using with() here because Safari fails if we use anOutlineView._itemInfosForItems or whatever...
|
// FIX ME: We're using with() here because Safari fails if we use anOutlineView._itemInfosForItems or whatever...
|
||||||
var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anItem, /*BOOL*/ isIntermediate)
|
var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anItem, /*BOOL*/ isIntermediate)
|
||||||
{
|
{
|
||||||
with(anOutlineView)
|
with (anOutlineView)
|
||||||
{
|
{
|
||||||
var itemInfosForItems = _itemInfosForItems,
|
var itemInfosForItems = _itemInfosForItems,
|
||||||
dataSource = _outlineViewDataSource;
|
dataSource = _outlineViewDataSource;
|
||||||
@@ -1119,8 +1590,8 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
|
|||||||
if (!(_outlineView._implementedOutlineViewDataSourceMethods & CPOutlineViewDataSource_outlineView_acceptDrop_item_childIndex_))
|
if (!(_outlineView._implementedOutlineViewDataSourceMethods & CPOutlineViewDataSource_outlineView_acceptDrop_item_childIndex_))
|
||||||
return NO;
|
return NO;
|
||||||
|
|
||||||
var location = [_outlineView convertPoint:[theInfo draggingLocation] fromView:nil],
|
var location = [_outlineView convertPoint:[theInfo draggingLocation] fromView:nil],
|
||||||
parentItem = [self _parentItemForDropOperation:theOperation row:theRow offset:location];
|
parentItem = [self _parentItemForDropOperation:theOperation row:theRow offset:location],
|
||||||
childIndex = [self _childIndexForDropOperation:theOperation row:theRow offset:location];
|
childIndex = [self _childIndexForDropOperation:theOperation row:theRow offset:location];
|
||||||
|
|
||||||
_outlineView._retargetedItem = nil;
|
_outlineView._retargetedItem = nil;
|
||||||
@@ -1180,13 +1651,13 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
|
|||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (float)tableView:(CPTableView)theTableView heightOfRow:(int)theRow
|
/*- (float)tableView:(CPTableView)theTableView heightOfRow:(int)theRow
|
||||||
{
|
{
|
||||||
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_heightOfRowByItem_))
|
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_heightOfRowByItem_))
|
||||||
return [_outlineView._outlineViewDelegate outlineView:_outlineView heightOfRowByItem:[_outlineView itemAtRow:theRow]];
|
return [_outlineView._outlineViewDelegate outlineView:_outlineView heightOfRowByItem:[_outlineView itemAtRow:theRow]];
|
||||||
|
|
||||||
return [theTableView rowHeight];
|
return [theTableView rowHeight];
|
||||||
}
|
}*/
|
||||||
|
|
||||||
- (void)tableView:(CPTableView)aTableView willDisplayView:(id)aView forTableColumn:(CPTableColumn)aTableColumn row:(int)aRowIndex
|
- (void)tableView:(CPTableView)aTableView willDisplayView:(id)aView forTableColumn:(CPTableColumn)aTableColumn row:(int)aRowIndex
|
||||||
{
|
{
|
||||||
@@ -1261,12 +1732,16 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
|
|||||||
|
|
||||||
CGContextBeginPath(context);
|
CGContextBeginPath(context);
|
||||||
CGContextMoveToPoint(context, 0.0, 0.0);
|
CGContextMoveToPoint(context, 0.0, 0.0);
|
||||||
if(_angle === 0.0) {
|
|
||||||
|
if (_angle === 0.0)
|
||||||
|
{
|
||||||
CGContextAddLineToPoint(context, 4.5, 8.0);
|
CGContextAddLineToPoint(context, 4.5, 8.0);
|
||||||
CGContextAddLineToPoint(context, 9.0, 0.0);
|
CGContextAddLineToPoint(context, 9.0, 0.0);
|
||||||
} else {
|
|
||||||
CGContextAddLineToPoint(context, 4.5, 8.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
CGContextAddLineToPoint(context, 4.5, 8.0);
|
||||||
|
|
||||||
CGContextSetStrokeColor(context, [CPColor colorWithCalibratedWhite:1.0 alpha: 0.8]);
|
CGContextSetStrokeColor(context, [CPColor colorWithCalibratedWhite:1.0 alpha: 0.8]);
|
||||||
CGContextStrokePath(context);
|
CGContextStrokePath(context);
|
||||||
}
|
}
|
||||||
@@ -1304,6 +1779,7 @@ var CPOutlineViewIndentationPerLevelKey = @"CPOutlineViewIndentationPerLevelKey"
|
|||||||
_outlineViewDelegate = [aCoder decodeObjectForKey:CPOutlineViewDelegateKey];
|
_outlineViewDelegate = [aCoder decodeObjectForKey:CPOutlineViewDelegateKey];
|
||||||
|
|
||||||
[super setDataSource:[[_CPOutlineViewTableViewDataSource alloc] initWithOutlineView:self]];
|
[super setDataSource:[[_CPOutlineViewTableViewDataSource alloc] initWithOutlineView:self]];
|
||||||
|
[super setDelegate:[[_CPOutlineViewTableViewDelegate alloc] initWithOutlineView:self]];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ CPCancelButton = 0;
|
|||||||
@global
|
@global
|
||||||
@class CPWindow
|
@class CPWindow
|
||||||
*/
|
*/
|
||||||
CPDocModalWindowMask = 1 << 6;
|
CPDocModalWindowMask = 1 << 6;
|
||||||
|
|
||||||
@implementation CPPanel : CPWindow
|
@implementation CPPanel : CPWindow
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -50,18 +50,18 @@ CPImagePboardType = @"CPImagePboardType";
|
|||||||
var CPPasteboards = nil,
|
var CPPasteboards = nil,
|
||||||
supportsNativePasteboard = NO;
|
supportsNativePasteboard = NO;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
@class CPPasteboard
|
@class CPPasteboard
|
||||||
|
|
||||||
CPPasteBoard is the object responsible for cut/copy/paste and drag&drop operations.
|
CPPasteBoard is the object responsible for cut/copy/paste and drag&drop operations.
|
||||||
*/
|
*/
|
||||||
@implementation CPPasteboard : CPObject
|
@implementation CPPasteboard : CPObject
|
||||||
{
|
{
|
||||||
CPArray _types;
|
CPArray _types;
|
||||||
CPDictionary _owners;
|
CPDictionary _owners;
|
||||||
CPDictionary _provided;
|
CPDictionary _provided;
|
||||||
|
|
||||||
unsigned _changeCount;
|
unsigned _changeCount;
|
||||||
CPString _stateUID;
|
CPString _stateUID;
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ var CPPasteboards = nil,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
[self setVersion:1.0];
|
[self setVersion:1.0];
|
||||||
|
|
||||||
CPPasteboards = [CPDictionary dictionary];
|
CPPasteboards = [CPDictionary dictionary];
|
||||||
|
|
||||||
if (typeof window.cpPasteboardWithName !== "undefined")
|
if (typeof window.cpPasteboardWithName !== "undefined")
|
||||||
@@ -103,10 +103,10 @@ var CPPasteboards = nil,
|
|||||||
|
|
||||||
if (pasteboard)
|
if (pasteboard)
|
||||||
return pasteboard;
|
return pasteboard;
|
||||||
|
|
||||||
pasteboard = [[CPPasteboard alloc] _initWithName:aName];
|
pasteboard = [[CPPasteboard alloc] _initWithName:aName];
|
||||||
[CPPasteboards setObject:pasteboard forKey:aName];
|
[CPPasteboards setObject:pasteboard forKey:aName];
|
||||||
|
|
||||||
return pasteboard;
|
return pasteboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,15 +114,15 @@ var CPPasteboards = nil,
|
|||||||
- (id)_initWithName:(CPString)aName
|
- (id)_initWithName:(CPString)aName
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
_name = aName;
|
_name = aName;
|
||||||
_types = [];
|
_types = [];
|
||||||
|
|
||||||
_owners = [CPDictionary dictionary];
|
_owners = [CPDictionary dictionary];
|
||||||
_provided = [CPDictionary dictionary];
|
_provided = [CPDictionary dictionary];
|
||||||
|
|
||||||
_changeCount = 0;
|
_changeCount = 0;
|
||||||
|
|
||||||
if (supportsNativePasteboard)
|
if (supportsNativePasteboard)
|
||||||
@@ -131,7 +131,7 @@ var CPPasteboards = nil,
|
|||||||
[self _synchronizePasteboard];
|
[self _synchronizePasteboard];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,17 +145,17 @@ var CPPasteboards = nil,
|
|||||||
{
|
{
|
||||||
var i = 0,
|
var i = 0,
|
||||||
count = types.length;
|
count = types.length;
|
||||||
|
|
||||||
for (; i < count; ++i)
|
for (; i < count; ++i)
|
||||||
{
|
{
|
||||||
var type = types[i];
|
var type = types[i];
|
||||||
|
|
||||||
if(![_owners objectForKey:type])
|
if (![_owners objectForKey:type])
|
||||||
{
|
{
|
||||||
[_types addObject:type];
|
[_types addObject:type];
|
||||||
[_provided removeObjectForKey:type];
|
[_provided removeObjectForKey:type];
|
||||||
}
|
}
|
||||||
|
|
||||||
[_owners setObject:anOwner forKey:type];
|
[_owners setObject:anOwner forKey:type];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ var CPPasteboards = nil,
|
|||||||
_provided = [CPDictionary dictionary];
|
_provided = [CPDictionary dictionary];
|
||||||
|
|
||||||
var count = _types.length;
|
var count = _types.length;
|
||||||
|
|
||||||
while (count--)
|
while (count--)
|
||||||
[_owners setObject:anOwner forKey:_types[count]];
|
[_owners setObject:anOwner forKey:_types[count]];
|
||||||
|
|
||||||
@@ -283,18 +283,18 @@ var CPPasteboards = nil,
|
|||||||
- (CPData)dataForType:(CPString)aType
|
- (CPData)dataForType:(CPString)aType
|
||||||
{
|
{
|
||||||
var data = [_provided objectForKey:aType];
|
var data = [_provided objectForKey:aType];
|
||||||
|
|
||||||
if (data)
|
if (data)
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
var owner = [_owners objectForKey:aType];
|
var owner = [_owners objectForKey:aType];
|
||||||
|
|
||||||
if (owner)
|
if (owner)
|
||||||
{
|
{
|
||||||
[owner pasteboard:self provideDataForType:aType];
|
[owner pasteboard:self provideDataForType:aType];
|
||||||
return [_provided objectForKey:aType];
|
return [_provided objectForKey:aType];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aType === CPStringPboardType)
|
if (aType === CPStringPboardType)
|
||||||
return [self dataForType:UTF8PboardType];
|
return [self dataForType:UTF8PboardType];
|
||||||
|
|
||||||
@@ -339,10 +339,10 @@ var CPPasteboards = nil,
|
|||||||
- (id)propertyListForType:(CPString)aType
|
- (id)propertyListForType:(CPString)aType
|
||||||
{
|
{
|
||||||
var data = [self dataForType:aType];
|
var data = [self dataForType:aType];
|
||||||
|
|
||||||
if (data)
|
if (data)
|
||||||
return [CPPropertyListSerialization propertyListFromData:data format:CPPropertyList280NorthFormat_v1_0];
|
return [CPPropertyListSerialization propertyListFromData:data format:CPPropertyList280NorthFormat_v1_0];
|
||||||
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,9 +360,9 @@ var CPPasteboards = nil,
|
|||||||
- (CPString)_generateStateUID
|
- (CPString)_generateStateUID
|
||||||
{
|
{
|
||||||
var bits = 32;
|
var bits = 32;
|
||||||
|
|
||||||
_stateUID = @"";
|
_stateUID = @"";
|
||||||
|
|
||||||
while (bits--)
|
while (bits--)
|
||||||
_stateUID += FLOOR(RAND() * 16.0).toString(16).toUpperCase();
|
_stateUID += FLOOR(RAND() * 16.0).toString(16).toUpperCase();
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,11 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
|
|||||||
return "popup-button";
|
return "popup-button";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (CPSet)keyPathsForValuesAffectingSelectedTag
|
||||||
|
{
|
||||||
|
return [CPSet setWithObject:@"selectedIndex"];
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Initializes the pop-up button to the specified size.
|
Initializes the pop-up button to the specified size.
|
||||||
@param aFrame the size for the button
|
@param aFrame the size for the button
|
||||||
@@ -233,6 +238,22 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
|
|||||||
return _selectedIndex;
|
return _selectedIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
|
- (int)selectedTag
|
||||||
|
{
|
||||||
|
return [[self selectedItem] tag];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
|
- (void)_setSelectedTag:(int)aTag
|
||||||
|
{
|
||||||
|
[self selectItemWithTag:aTag];
|
||||||
|
}
|
||||||
|
|
||||||
// Setting the Current Selection
|
// Setting the Current Selection
|
||||||
/*!
|
/*!
|
||||||
Selects the specified menu item.
|
Selects the specified menu item.
|
||||||
@@ -252,6 +273,8 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
|
|||||||
if (_selectedIndex == anIndex)
|
if (_selectedIndex == anIndex)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
[self willChangeValueForKey:@"selectedIndex"];
|
||||||
|
|
||||||
if (_selectedIndex >= 0 && ![self pullsDown])
|
if (_selectedIndex >= 0 && ![self pullsDown])
|
||||||
[[self selectedItem] setState:CPOffState];
|
[[self selectedItem] setState:CPOffState];
|
||||||
|
|
||||||
@@ -261,6 +284,8 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
|
|||||||
[[self selectedItem] setState:CPOnState];
|
[[self selectedItem] setState:CPOnState];
|
||||||
|
|
||||||
[self synchronizeTitleAndSelectedItem];
|
[self synchronizeTitleAndSelectedItem];
|
||||||
|
|
||||||
|
[self didChangeValueForKey:@"selectedIndex"];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
|
|||||||
CPProgressIndicatorStyleIdentifiers = nil,
|
CPProgressIndicatorStyleIdentifiers = nil,
|
||||||
CPProgressIndicatorStyleSizes = nil;
|
CPProgressIndicatorStyleSizes = nil;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
@class CPProgressIndicator
|
@class CPProgressIndicator
|
||||||
|
|
||||||
@@ -59,19 +59,19 @@ var CPProgressIndicatorSpinningStyleColors = nil,
|
|||||||
{
|
{
|
||||||
double _minValue;
|
double _minValue;
|
||||||
double _maxValue;
|
double _maxValue;
|
||||||
|
|
||||||
double _doubleValue;
|
double _doubleValue;
|
||||||
|
|
||||||
CPControlSize _controlSize;
|
CPControlSize _controlSize;
|
||||||
|
|
||||||
BOOL _isIndeterminate;
|
BOOL _isIndeterminate;
|
||||||
CPProgressIndicatorStyle _style;
|
CPProgressIndicatorStyle _style;
|
||||||
|
|
||||||
BOOL _isAnimating;
|
BOOL _isAnimating;
|
||||||
|
|
||||||
BOOL _isDisplayedWhenStoppedSet;
|
BOOL _isDisplayedWhenStoppedSet;
|
||||||
BOOL _isDisplayedWhenStopped;
|
BOOL _isDisplayedWhenStopped;
|
||||||
|
|
||||||
CPView _barView;
|
CPView _barView;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,11 +82,11 @@ var CPProgressIndicatorSpinningStyleColors = nil,
|
|||||||
{
|
{
|
||||||
if (self != [CPProgressIndicator class])
|
if (self != [CPProgressIndicator class])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var bundle = [CPBundle bundleForClass:self];
|
var bundle = [CPBundle bundleForClass:self];
|
||||||
|
|
||||||
CPProgressIndicatorSpinningStyleColors = [];
|
CPProgressIndicatorSpinningStyleColors = [];
|
||||||
|
|
||||||
CPProgressIndicatorSpinningStyleColors[CPMiniControlSize] = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:
|
CPProgressIndicatorSpinningStyleColors[CPMiniControlSize] = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:
|
||||||
[bundle pathForResource:@"CPProgressIndicator/CPProgressIndicatorSpinningStyleRegular.gif"] size:CGSizeMake(64.0, 64.0)]];
|
[bundle pathForResource:@"CPProgressIndicator/CPProgressIndicatorSpinningStyleRegular.gif"] size:CGSizeMake(64.0, 64.0)]];
|
||||||
CPProgressIndicatorSpinningStyleColors[CPSmallControlSize] = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:
|
CPProgressIndicatorSpinningStyleColors[CPSmallControlSize] = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:
|
||||||
@@ -95,10 +95,10 @@ var CPProgressIndicatorSpinningStyleColors = nil,
|
|||||||
[bundle pathForResource:@"CPProgressIndicator/CPProgressIndicatorSpinningStyleRegular.gif"] size:CGSizeMake(64.0, 64.0)]];
|
[bundle pathForResource:@"CPProgressIndicator/CPProgressIndicatorSpinningStyleRegular.gif"] size:CGSizeMake(64.0, 64.0)]];
|
||||||
|
|
||||||
CPProgressIndicatorBezelBorderViewPool = [];
|
CPProgressIndicatorBezelBorderViewPool = [];
|
||||||
|
|
||||||
var start = CPProgressIndicatorBarStyle,
|
var start = CPProgressIndicatorBarStyle,
|
||||||
end = CPProgressIndicatorHUDBarStyle;
|
end = CPProgressIndicatorHUDBarStyle;
|
||||||
|
|
||||||
for (; start <= end; ++start)
|
for (; start <= end; ++start)
|
||||||
{
|
{
|
||||||
CPProgressIndicatorBezelBorderViewPool[start] = [];
|
CPProgressIndicatorBezelBorderViewPool[start] = [];
|
||||||
@@ -106,14 +106,14 @@ var CPProgressIndicatorSpinningStyleColors = nil,
|
|||||||
CPProgressIndicatorBezelBorderViewPool[start][CPSmallControlSize] = [];
|
CPProgressIndicatorBezelBorderViewPool[start][CPSmallControlSize] = [];
|
||||||
CPProgressIndicatorBezelBorderViewPool[start][CPRegularControlSize] = [];
|
CPProgressIndicatorBezelBorderViewPool[start][CPRegularControlSize] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
CPProgressIndicatorClassName = [self className];
|
CPProgressIndicatorClassName = [self className];
|
||||||
CPProgressIndicatorStyleIdentifiers = [];
|
CPProgressIndicatorStyleIdentifiers = [];
|
||||||
|
|
||||||
CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle] = @"Bar";
|
CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle] = @"Bar";
|
||||||
CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorSpinningStyle] = @"Spinny";
|
CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorSpinningStyle] = @"Spinny";
|
||||||
CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorHUDBarStyle] = @"HUDBar";
|
CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorHUDBarStyle] = @"HUDBar";
|
||||||
|
|
||||||
var regularIdentifier = _CPControlIdentifierForControlSize(CPRegularControlSize),
|
var regularIdentifier = _CPControlIdentifierForControlSize(CPRegularControlSize),
|
||||||
smallIdentifier = _CPControlIdentifierForControlSize(CPSmallControlSize),
|
smallIdentifier = _CPControlIdentifierForControlSize(CPSmallControlSize),
|
||||||
miniIdentifier = _CPControlIdentifierForControlSize(CPMiniControlSize);
|
miniIdentifier = _CPControlIdentifierForControlSize(CPMiniControlSize);
|
||||||
@@ -128,7 +128,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
|
|||||||
CPProgressIndicatorClassName + @"Bar" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorHUDBarStyle]
|
CPProgressIndicatorClassName + @"Bar" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorHUDBarStyle]
|
||||||
];
|
];
|
||||||
|
|
||||||
for (var i = 0, count = prefixes.length; i<count; i++)
|
for (var i = 0, count = prefixes.length; i < count; i++)
|
||||||
{
|
{
|
||||||
var prefix = prefixes[i];
|
var prefix = prefixes[i];
|
||||||
CPProgressIndicatorStyleSizes[prefix + regularIdentifier] = [_CGSizeMake(3.0, 16.0), _CGSizeMake(1.0, 16.0), _CGSizeMake(3.0, 16.0)];
|
CPProgressIndicatorStyleSizes[prefix + regularIdentifier] = [_CGSizeMake(3.0, 16.0), _CGSizeMake(1.0, 16.0), _CGSizeMake(3.0, 16.0)];
|
||||||
@@ -140,23 +140,23 @@ var CPProgressIndicatorSpinningStyleColors = nil,
|
|||||||
- (id)initWithFrame:(CGRect)aFrame
|
- (id)initWithFrame:(CGRect)aFrame
|
||||||
{
|
{
|
||||||
self = [super initWithFrame:aFrame];
|
self = [super initWithFrame:aFrame];
|
||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
_minValue = 0.0;
|
_minValue = 0.0;
|
||||||
_maxValue = 100.0;
|
_maxValue = 100.0;
|
||||||
|
|
||||||
_doubleValue = 0.0;
|
_doubleValue = 0.0;
|
||||||
|
|
||||||
_style = CPProgressIndicatorBarStyle;
|
_style = CPProgressIndicatorBarStyle;
|
||||||
_isDisplayedWhenStoppedSet = NO;
|
_isDisplayedWhenStoppedSet = NO;
|
||||||
|
|
||||||
_controlSize = CPRegularControlSize;
|
_controlSize = CPRegularControlSize;
|
||||||
|
|
||||||
[self updateBackgroundColor];
|
[self updateBackgroundColor];
|
||||||
[self drawBar];
|
[self drawBar];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +174,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
|
|||||||
- (void)startAnimation:(id)aSender
|
- (void)startAnimation:(id)aSender
|
||||||
{
|
{
|
||||||
_isAnimating = YES;
|
_isAnimating = YES;
|
||||||
|
|
||||||
[self _hideOrDisplay];
|
[self _hideOrDisplay];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +213,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
|
|||||||
- (void)setDoubleValue:(double)aValue
|
- (void)setDoubleValue:(double)aValue
|
||||||
{
|
{
|
||||||
_doubleValue = MIN(MAX(aValue, _minValue), _maxValue);
|
_doubleValue = MIN(MAX(aValue, _minValue), _maxValue);
|
||||||
|
|
||||||
[self drawBar];
|
[self drawBar];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,7 +268,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
|
|||||||
{
|
{
|
||||||
if (_controlSize == aControlSize)
|
if (_controlSize == aControlSize)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_controlSize = aControlSize;
|
_controlSize = aControlSize;
|
||||||
|
|
||||||
[self updateBackgroundColor];
|
[self updateBackgroundColor];
|
||||||
@@ -320,7 +320,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
|
|||||||
{
|
{
|
||||||
if (_isIndeterminate == isIndeterminate)
|
if (_isIndeterminate == isIndeterminate)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_isIndeterminate = isIndeterminate;
|
_isIndeterminate = isIndeterminate;
|
||||||
|
|
||||||
[self updateBackgroundColor];
|
[self updateBackgroundColor];
|
||||||
@@ -342,9 +342,9 @@ var CPProgressIndicatorSpinningStyleColors = nil,
|
|||||||
{
|
{
|
||||||
if (_style == aStyle)
|
if (_style == aStyle)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_style = aStyle;
|
_style = aStyle;
|
||||||
|
|
||||||
[self updateBackgroundColor];
|
[self updateBackgroundColor];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,8 +357,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
|
|||||||
[self setFrameSize:[[CPProgressIndicatorSpinningStyleColors[_controlSize] patternImage] size]];
|
[self setFrameSize:[[CPProgressIndicatorSpinningStyleColors[_controlSize] patternImage] size]];
|
||||||
else
|
else
|
||||||
[self setFrameSize:CGSizeMake(CGRectGetWidth([self frame]), CPProgressIndicatorStyleSizes[
|
[self setFrameSize:CGSizeMake(CGRectGetWidth([self frame]), CPProgressIndicatorStyleSizes[
|
||||||
CPProgressIndicatorClassName + @"BezelBorder" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle] +
|
CPProgressIndicatorClassName + @"BezelBorder" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle] + _CPControlIdentifierForControlSize(_controlSize)][0].height)];
|
||||||
_CPControlIdentifierForControlSize(_controlSize)][0].height)];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -370,11 +369,11 @@ var CPProgressIndicatorSpinningStyleColors = nil,
|
|||||||
{
|
{
|
||||||
if (_isDisplayedWhenStoppedSet && _isDisplayedWhenStopped == isDisplayedWhenStopped)
|
if (_isDisplayedWhenStoppedSet && _isDisplayedWhenStopped == isDisplayedWhenStopped)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_isDisplayedWhenStoppedSet = YES;
|
_isDisplayedWhenStoppedSet = YES;
|
||||||
|
|
||||||
_isDisplayedWhenStopped = isDisplayedWhenStopped;
|
_isDisplayedWhenStopped = isDisplayedWhenStopped;
|
||||||
|
|
||||||
[self _hideOrDisplay];
|
[self _hideOrDisplay];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -385,10 +384,10 @@ var CPProgressIndicatorSpinningStyleColors = nil,
|
|||||||
{
|
{
|
||||||
if (_isDisplayedWhenStoppedSet)
|
if (_isDisplayedWhenStoppedSet)
|
||||||
return _isDisplayedWhenStopped;
|
return _isDisplayedWhenStopped;
|
||||||
|
|
||||||
if (_style == CPProgressIndicatorBarStyle || _style == CPProgressIndicatorHUDBarStyle)
|
if (_style == CPProgressIndicatorBarStyle || _style == CPProgressIndicatorHUDBarStyle)
|
||||||
return YES;
|
return YES;
|
||||||
|
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,7 +400,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
|
|||||||
- (void)setFrameSize:(CGSize)aSize
|
- (void)setFrameSize:(CGSize)aSize
|
||||||
{
|
{
|
||||||
[super setFrameSize:aSize];
|
[super setFrameSize:aSize];
|
||||||
|
|
||||||
[self drawBar];
|
[self drawBar];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,13 +409,13 @@ var CPProgressIndicatorSpinningStyleColors = nil,
|
|||||||
{
|
{
|
||||||
if (_style == CPProgressIndicatorSpinningStyle)
|
if (_style == CPProgressIndicatorSpinningStyle)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!_barView)
|
if (!_barView)
|
||||||
{
|
{
|
||||||
_barView = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, 0.0, 16.0)];
|
_barView = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, 0.0, 16.0)];
|
||||||
[self addSubview:_barView];
|
[self addSubview:_barView];
|
||||||
}
|
}
|
||||||
|
|
||||||
[_barView setBackgroundColor:_CPControlThreePartImagePattern(
|
[_barView setBackgroundColor:_CPControlThreePartImagePattern(
|
||||||
NO,
|
NO,
|
||||||
CPProgressIndicatorStyleSizes,
|
CPProgressIndicatorStyleSizes,
|
||||||
@@ -442,9 +441,9 @@ var CPProgressIndicatorSpinningStyleColors = nil,
|
|||||||
if (_style == CPProgressIndicatorSpinningStyle)
|
if (_style == CPProgressIndicatorSpinningStyle)
|
||||||
{
|
{
|
||||||
[_barView removeFromSuperview];
|
[_barView removeFromSuperview];
|
||||||
|
|
||||||
_barView = nil;
|
_barView = nil;
|
||||||
|
|
||||||
[self setBackgroundColor:CPProgressIndicatorSpinningStyleColors[_controlSize]];
|
[self setBackgroundColor:CPProgressIndicatorSpinningStyleColors[_controlSize]];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -456,7 +455,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
|
|||||||
@"BezelBorder",
|
@"BezelBorder",
|
||||||
CPProgressIndicatorStyleIdentifiers[_style],
|
CPProgressIndicatorStyleIdentifiers[_style],
|
||||||
_CPControlIdentifierForControlSize(_controlSize))];
|
_CPControlIdentifierForControlSize(_controlSize))];
|
||||||
|
|
||||||
[self drawBar];
|
[self drawBar];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -354,6 +354,11 @@
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
Sets the type of border to be drawn around the view.
|
Sets the type of border to be drawn around the view.
|
||||||
|
Valid types are:
|
||||||
|
CPNoBorder
|
||||||
|
CPLineBorder
|
||||||
|
CPBezelBorder
|
||||||
|
CPGrooveBorder
|
||||||
*/
|
*/
|
||||||
- (void)setBorderType:(CPBorderType)borderType
|
- (void)setBorderType:(CPBorderType)borderType
|
||||||
{
|
{
|
||||||
@@ -974,6 +979,22 @@
|
|||||||
[self moveByOffset:CGSizeMake(0.0, _CGRectGetHeight(contentBounds) - _verticalPageScroll)];
|
[self moveByOffset:CGSizeMake(0.0, _CGRectGetHeight(contentBounds) - _verticalPageScroll)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)scrollToBeginningOfDocument:(id)sender
|
||||||
|
{
|
||||||
|
[_contentView scrollToPoint:_CGPointMakeZero()];
|
||||||
|
[_headerClipView scrollToPoint:_CGPointMakeZero()];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)scrollToEndOfDocument:(id)sender
|
||||||
|
{
|
||||||
|
var contentBounds = [_contentView bounds],
|
||||||
|
documentFrame = [[self documentView] frame],
|
||||||
|
scrollPoint = _CGPointMake(0.0, _CGRectGetHeight(documentFrame) - _CGRectGetHeight(contentBounds));
|
||||||
|
|
||||||
|
[_contentView scrollToPoint:scrollPoint];
|
||||||
|
[_headerClipView scrollToPoint:_CGPointMakeZero()];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)moveLeft:(id)sender
|
- (void)moveLeft:(id)sender
|
||||||
{
|
{
|
||||||
[self moveByOffset:CGSizeMake(-_horizontalLineScroll, 0.0)];
|
[self moveByOffset:CGSizeMake(-_horizontalLineScroll, 0.0)];
|
||||||
@@ -1003,7 +1024,7 @@
|
|||||||
contentBounds.origin.y += aSize.height;
|
contentBounds.origin.y += aSize.height;
|
||||||
|
|
||||||
[_contentView scrollToPoint:contentBounds.origin];
|
[_contentView scrollToPoint:contentBounds.origin];
|
||||||
[_headerClipView scrollToPoint:CGPointMake(contentBounds.origin, 0)];
|
[_headerClipView scrollToPoint:CGPointMake(contentBounds.origin.x, 0)];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -23,12 +23,10 @@
|
|||||||
@import "CPButton.j"
|
@import "CPButton.j"
|
||||||
@import "CPTextField.j"
|
@import "CPTextField.j"
|
||||||
|
|
||||||
|
|
||||||
CPSearchFieldRecentsTitleMenuItemTag = 1000;
|
CPSearchFieldRecentsTitleMenuItemTag = 1000;
|
||||||
CPSearchFieldRecentsMenuItemTag = 1001;
|
CPSearchFieldRecentsMenuItemTag = 1001;
|
||||||
CPSearchFieldClearRecentsMenuItemTag = 1002;
|
CPSearchFieldClearRecentsMenuItemTag = 1002;
|
||||||
CPSearchFieldNoRecentsMenuItemTag = 1003;
|
CPSearchFieldNoRecentsMenuItemTag = 1003;
|
||||||
CPSearchFieldSeparatorMenuItemTag = 1004;
|
|
||||||
|
|
||||||
var CPSearchFieldSearchImage = nil,
|
var CPSearchFieldSearchImage = nil,
|
||||||
CPSearchFieldFindImage = nil,
|
CPSearchFieldFindImage = nil,
|
||||||
@@ -39,15 +37,16 @@ var SEARCH_BUTTON_DEFAULT_WIDTH = 25.0,
|
|||||||
CANCEL_BUTTON_DEFAULT_WIDTH = 22.0,
|
CANCEL_BUTTON_DEFAULT_WIDTH = 22.0,
|
||||||
BUTTON_DEFAULT_HEIGHT = 22.0;
|
BUTTON_DEFAULT_HEIGHT = 22.0;
|
||||||
|
|
||||||
|
var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotification";
|
||||||
|
|
||||||
var RECENT_SEARCH_PREFIX = @" ";
|
var RECENT_SEARCH_PREFIX = @" ";
|
||||||
|
|
||||||
|
/*!
|
||||||
/*!
|
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
@class CPSearchField
|
@class CPSearchField
|
||||||
The CPSearchField class defines the programmatic interface for text fields that are optimized for text-based searches. A CPSearchField object directly inherits from the CPTextField class. The search field implemented by these classes presents a standard user interface for searches, including a search button, a cancel button, and a pop-up icon menu for listing recent search strings and custom search categories.
|
The CPSearchField class defines the programmatic interface for text fields that are optimized for text-based searches. A CPSearchField object directly inherits from the CPTextField class. The search field implemented by these classes presents a standard user interface for searches, including a search button, a cancel button, and a pop-up icon menu for listing recent search strings and custom search categories.
|
||||||
|
|
||||||
When the user types and then pauses, the text field's action message is sent to its target. You can query the text field's string value for the current text to search for. Do not rely on the sender of the action to be an CPMenu object because the menu may change. If you need to change the menu, modify the search menu template and call the setSearchMenuTemplate: method to update.
|
When the user types and then pauses, the text field's action message is sent to its target. You can query the text field's string value for the current text to search for. Do not rely on the sender of the action to be an CPMenu object because the menu may change. If you need to change the menu, modify the search menu template and call the setSearchMenuTemplate: method to update.
|
||||||
*/
|
*/
|
||||||
@implementation CPSearchField : CPTextField
|
@implementation CPSearchField : CPTextField
|
||||||
{
|
{
|
||||||
@@ -58,7 +57,7 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
|
|
||||||
CPString _recentsAutosaveName;
|
CPString _recentsAutosaveName;
|
||||||
CPArray _recentSearches;
|
CPArray _recentSearches;
|
||||||
|
|
||||||
int _maximumRecents;
|
int _maximumRecents;
|
||||||
BOOL _sendsWholeSearchString;
|
BOOL _sendsWholeSearchString;
|
||||||
BOOL _sendsSearchStringImmediately;
|
BOOL _sendsSearchStringImmediately;
|
||||||
@@ -96,9 +95,9 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
#if PLATFORM(DOM)
|
#if PLATFORM(DOM)
|
||||||
_cancelButton._DOMElement.style.cursor = "default";
|
_cancelButton._DOMElement.style.cursor = "default";
|
||||||
_searchButton._DOMElement.style.cursor = "default";
|
_searchButton._DOMElement.style.cursor = "default";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,17 +111,17 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
[self setEditable:YES];
|
[self setEditable:YES];
|
||||||
[self setDelegate:self];
|
[self setDelegate:self];
|
||||||
[self setContinuous:YES];
|
[self setContinuous:YES];
|
||||||
|
|
||||||
var bounds = [self bounds],
|
var bounds = [self bounds],
|
||||||
cancelButton = [[CPButton alloc] initWithFrame:[self cancelButtonRectForBounds:bounds]],
|
cancelButton = [[CPButton alloc] initWithFrame:[self cancelButtonRectForBounds:bounds]],
|
||||||
searchButton = [[CPButton alloc] initWithFrame:[self searchButtonRectForBounds:bounds]];
|
searchButton = [[CPButton alloc] initWithFrame:[self searchButtonRectForBounds:bounds]];
|
||||||
|
|
||||||
[self setCancelButton:cancelButton];
|
[self setCancelButton:cancelButton];
|
||||||
[self resetCancelButton];
|
[self resetCancelButton];
|
||||||
|
|
||||||
[self setSearchButton:searchButton];
|
[self setSearchButton:searchButton];
|
||||||
[self resetSearchButton];
|
[self resetSearchButton];
|
||||||
|
|
||||||
_canResignFirstResponder = YES;
|
_canResignFirstResponder = YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,12 +131,12 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
@param button The search button.
|
@param button The search button.
|
||||||
*/
|
*/
|
||||||
- (void)setSearchButton:(CPButton)button
|
- (void)setSearchButton:(CPButton)button
|
||||||
{
|
{
|
||||||
if (button != _searchButton)
|
if (button != _searchButton)
|
||||||
{
|
{
|
||||||
[_searchButton removeFromSuperview];
|
[_searchButton removeFromSuperview];
|
||||||
_searchButton = button;
|
_searchButton = button;
|
||||||
|
|
||||||
[_searchButton setFrame:[self searchButtonRectForBounds:[self bounds]]];
|
[_searchButton setFrame:[self searchButtonRectForBounds:[self bounds]]];
|
||||||
[_searchButton setAutoresizingMask:CPViewMaxXMargin];
|
[_searchButton setAutoresizingMask:CPViewMaxXMargin];
|
||||||
[self addSubview:_searchButton];
|
[self addSubview:_searchButton];
|
||||||
@@ -161,7 +160,7 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
{
|
{
|
||||||
var button = [self searchButton],
|
var button = [self searchButton],
|
||||||
searchButtonImage = (_searchMenuTemplate === nil) ? CPSearchFieldSearchImage : CPSearchFieldFindImage;
|
searchButtonImage = (_searchMenuTemplate === nil) ? CPSearchFieldSearchImage : CPSearchFieldFindImage;
|
||||||
|
|
||||||
[button setBordered:NO];
|
[button setBordered:NO];
|
||||||
[button setImageScaling:CPScaleToFit];
|
[button setImageScaling:CPScaleToFit];
|
||||||
[button setImage:searchButtonImage];
|
[button setImage:searchButtonImage];
|
||||||
@@ -178,11 +177,11 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
{
|
{
|
||||||
[_cancelButton removeFromSuperview];
|
[_cancelButton removeFromSuperview];
|
||||||
_cancelButton = button;
|
_cancelButton = button;
|
||||||
|
|
||||||
[_cancelButton setFrame:[self cancelButtonRectForBounds:[self bounds]]];
|
[_cancelButton setFrame:[self cancelButtonRectForBounds:[self bounds]]];
|
||||||
[_cancelButton setAutoresizingMask:CPViewMinXMargin];
|
[_cancelButton setAutoresizingMask:CPViewMinXMargin];
|
||||||
[_cancelButton setTarget:self];
|
[_cancelButton setTarget:self];
|
||||||
[_cancelButton setAction:@selector(_searchFieldCancel:)];
|
[_cancelButton setAction:@selector(_searchFieldCancel:)];
|
||||||
[self _updateCancelButtonVisibility];
|
[self _updateCancelButtonVisibility];
|
||||||
[self addSubview:_cancelButton];
|
[self addSubview:_cancelButton];
|
||||||
}
|
}
|
||||||
@@ -222,22 +221,22 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
*/
|
*/
|
||||||
- (CGRect)searchTextRectForBounds:(CGRect)rect
|
- (CGRect)searchTextRectForBounds:(CGRect)rect
|
||||||
{
|
{
|
||||||
var leftOffset = 0,
|
var leftOffset = 0,
|
||||||
width = _CGRectGetWidth(rect),
|
width = _CGRectGetWidth(rect),
|
||||||
bounds = [self bounds];
|
bounds = [self bounds];
|
||||||
|
|
||||||
if (_searchButton)
|
if (_searchButton)
|
||||||
{
|
{
|
||||||
var searchBounds = [self searchButtonRectForBounds:bounds];
|
var searchBounds = [self searchButtonRectForBounds:bounds];
|
||||||
leftOffset = _CGRectGetMaxX(searchBounds) + 2;
|
leftOffset = _CGRectGetMaxX(searchBounds) + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_cancelButton)
|
if (_cancelButton)
|
||||||
{
|
{
|
||||||
var cancelRect = [self cancelButtonRectForBounds:bounds];
|
var cancelRect = [self cancelButtonRectForBounds:bounds];
|
||||||
width = _CGRectGetMinX(cancelRect) - leftOffset;
|
width = _CGRectGetMinX(cancelRect) - leftOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _CGRectMake(leftOffset, _CGRectGetMinY(rect), width, _CGRectGetHeight(rect));
|
return _CGRectMake(leftOffset, _CGRectGetMinY(rect), width, _CGRectGetHeight(rect));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,7 +256,7 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
Subclasses can override this method to return a new bounding rectangle for the cancel button. You might use this method to provide a custom layout for the search field control.
|
Subclasses can override this method to return a new bounding rectangle for the cancel button. You might use this method to provide a custom layout for the search field control.
|
||||||
*/
|
*/
|
||||||
- (CGRect)cancelButtonRectForBounds:(CGRect)rect
|
- (CGRect)cancelButtonRectForBounds:(CGRect)rect
|
||||||
{
|
{
|
||||||
return _CGRectMake(_CGRectGetWidth(rect) - CANCEL_BUTTON_DEFAULT_WIDTH - 5, (_CGRectGetHeight(rect) - CANCEL_BUTTON_DEFAULT_WIDTH) / 2, BUTTON_DEFAULT_HEIGHT, BUTTON_DEFAULT_HEIGHT);
|
return _CGRectMake(_CGRectGetWidth(rect) - CANCEL_BUTTON_DEFAULT_WIDTH - 5, (_CGRectGetHeight(rect) - CANCEL_BUTTON_DEFAULT_WIDTH) / 2, BUTTON_DEFAULT_HEIGHT, BUTTON_DEFAULT_HEIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,7 +278,7 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
- (void)setSearchMenuTemplate:(CPMenu)aMenu
|
- (void)setSearchMenuTemplate:(CPMenu)aMenu
|
||||||
{
|
{
|
||||||
_searchMenuTemplate = aMenu;
|
_searchMenuTemplate = aMenu;
|
||||||
|
|
||||||
[self resetSearchButton];
|
[self resetSearchButton];
|
||||||
[self _loadRecentSearchList];
|
[self _loadRecentSearchList];
|
||||||
[self _updateSearchMenu];
|
[self _updateSearchMenu];
|
||||||
@@ -291,8 +290,8 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
@return \c YES if the action message is sent all at once when the user clicks the search button or presses return; otherwise, NO if the search string is sent after each keystroke. The default value is NO.
|
@return \c YES if the action message is sent all at once when the user clicks the search button or presses return; otherwise, NO if the search string is sent after each keystroke. The default value is NO.
|
||||||
*/
|
*/
|
||||||
- (BOOL)sendsWholeSearchString
|
- (BOOL)sendsWholeSearchString
|
||||||
{
|
{
|
||||||
return _sendsWholeSearchString;
|
return _sendsWholeSearchString;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -309,8 +308,8 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
@return \c YES if the text field sends its action immediately upon notification of any changes to the search field; otherwise, NO.
|
@return \c YES if the text field sends its action immediately upon notification of any changes to the search field; otherwise, NO.
|
||||||
*/
|
*/
|
||||||
- (BOOL)sendsSearchStringImmediately
|
- (BOOL)sendsSearchStringImmediately
|
||||||
{
|
{
|
||||||
return _sendsSearchStringImmediately;
|
return _sendsSearchStringImmediately;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -328,7 +327,7 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
@return The maximum number of search strings that can appear in the menu. This value is between 0 and 254.
|
@return The maximum number of search strings that can appear in the menu. This value is between 0 and 254.
|
||||||
*/
|
*/
|
||||||
- (int)maximumRecents
|
- (int)maximumRecents
|
||||||
{
|
{
|
||||||
return _maximumRecents;
|
return _maximumRecents;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,13 +341,13 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
max = 254;
|
max = 254;
|
||||||
else if (max < 0)
|
else if (max < 0)
|
||||||
max = 10;
|
max = 10;
|
||||||
|
|
||||||
_maximumRecents = max;
|
_maximumRecents = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the list of recent search strings for the control.
|
Returns the list of recent search strings for the control.
|
||||||
@return An array of \c CPString objects, each of which contains a search string either displayed in the search menu or from a recent autosave archive. If there have been no recent searches and no prior searches saved under an autosave name, this array may be empty.
|
@return An array of \c CPString objects, each of which contains a search string either displayed in the search menu or from a recent autosave archive. If there have been no recent searches and no prior searches saved under an autosave name, this array may be empty.
|
||||||
*/
|
*/
|
||||||
- (CPArray)recentSearches
|
- (CPArray)recentSearches
|
||||||
{
|
{
|
||||||
@@ -364,8 +363,8 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
{
|
{
|
||||||
var max = MIN([self maximumRecents], [searches count]),
|
var max = MIN([self maximumRecents], [searches count]),
|
||||||
searches = [searches subarrayWithRange:CPMakeRange(0, max)];
|
searches = [searches subarrayWithRange:CPMakeRange(0, max)];
|
||||||
|
|
||||||
_recentSearches = searches;
|
_recentSearches = searches;
|
||||||
[self _autosaveRecentSearchList];
|
[self _autosaveRecentSearchList];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,7 +374,7 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
*/
|
*/
|
||||||
- (CPString)recentsAutosaveName
|
- (CPString)recentsAutosaveName
|
||||||
{
|
{
|
||||||
return _recentsAutosaveName;
|
return _recentsAutosaveName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -386,9 +385,9 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
{
|
{
|
||||||
if (_recentsAutosaveName != nil)
|
if (_recentsAutosaveName != nil)
|
||||||
[self _deregisterForAutosaveNotification];
|
[self _deregisterForAutosaveNotification];
|
||||||
|
|
||||||
_recentsAutosaveName = name;
|
_recentsAutosaveName = name;
|
||||||
|
|
||||||
if (_recentsAutosaveName != nil)
|
if (_recentsAutosaveName != nil)
|
||||||
[self _registerForAutosaveNotification];
|
[self _registerForAutosaveNotification];
|
||||||
}
|
}
|
||||||
@@ -397,13 +396,13 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
|
|
||||||
- (CGRect)contentRectForBounds:(CGRect)bounds
|
- (CGRect)contentRectForBounds:(CGRect)bounds
|
||||||
{
|
{
|
||||||
var superbounds = [super contentRectForBounds:bounds];
|
var superbounds = [super contentRectForBounds:bounds];
|
||||||
return [self searchTextRectForBounds:superbounds];
|
return [self searchTextRectForBounds:superbounds];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (double)_keyboardDelayForPartialSearchString:(CPString)string
|
+ (double)_keyboardDelayForPartialSearchString:(CPString)string
|
||||||
{
|
{
|
||||||
return (6 - MIN([string length],4))/10;
|
return (6 - MIN([string length], 4)) / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CPMenu)menu
|
- (CPMenu)menu
|
||||||
@@ -431,15 +430,15 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
{
|
{
|
||||||
[_partialStringTimer invalidate];
|
[_partialStringTimer invalidate];
|
||||||
var timeInterval = [CPSearchField _keyboardDelayForPartialSearchString:[self stringValue]];
|
var timeInterval = [CPSearchField _keyboardDelayForPartialSearchString:[self stringValue]];
|
||||||
|
|
||||||
_partialStringTimer = [CPTimer scheduledTimerWithTimeInterval:timeInterval
|
_partialStringTimer = [CPTimer scheduledTimerWithTimeInterval:timeInterval
|
||||||
target:self
|
target:self
|
||||||
selector:@selector(_sendPartialString)
|
selector:@selector(_sendPartialString)
|
||||||
userInfo:nil
|
userInfo:nil
|
||||||
repeats:NO];
|
repeats:NO];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[self _updateCancelButtonVisibility];
|
[self _updateCancelButtonVisibility];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,7 +461,7 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
{
|
{
|
||||||
if (string === nil || string === @"" || [_recentSearches containsObject:string])
|
if (string === nil || string === @"" || [_recentSearches containsObject:string])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var searches = [CPMutableArray arrayWithArray:_recentSearches];
|
var searches = [CPMutableArray arrayWithArray:_recentSearches];
|
||||||
[searches addObject:string];
|
[searches addObject:string];
|
||||||
[self setRecentSearches:searches];
|
[self setRecentSearches:searches];
|
||||||
@@ -471,7 +470,7 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
|
|
||||||
- (CPView)hitTest:(CGPoint)aPoint
|
- (CPView)hitTest:(CGPoint)aPoint
|
||||||
{
|
{
|
||||||
// Make sure a hit anywhere within the search field returns the search field itself
|
// Make sure a hit anywhere within the search field returns the search field itself
|
||||||
if (_CGRectContainsPoint([self frame], aPoint))
|
if (_CGRectContainsPoint([self frame], aPoint))
|
||||||
return self;
|
return self;
|
||||||
else
|
else
|
||||||
@@ -493,8 +492,8 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
if (_searchMenuTemplate == nil)
|
if (_searchMenuTemplate == nil)
|
||||||
[self _sendAction:self];
|
[self _sendAction:self];
|
||||||
else
|
else
|
||||||
[self _showMenu];
|
[self _showMenu];
|
||||||
}
|
}
|
||||||
else if (_CGRectContainsPoint([self cancelButtonRectForBounds:[self bounds]], point))
|
else if (_CGRectContainsPoint([self cancelButtonRectForBounds:[self bounds]], point))
|
||||||
[_cancelButton mouseDown:anEvent];
|
[_cancelButton mouseDown:anEvent];
|
||||||
else
|
else
|
||||||
@@ -504,69 +503,69 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
/*!
|
/*!
|
||||||
Provides the common case items for a recent searches menu. If there are not recent searches,
|
Provides the common case items for a recent searches menu. If there are not recent searches,
|
||||||
displays a single disabled item:
|
displays a single disabled item:
|
||||||
|
|
||||||
No Recent Searches
|
No Recent Searches
|
||||||
|
|
||||||
If there are 1 more recent searches, it displays:
|
If there are 1 more recent searches, it displays:
|
||||||
|
|
||||||
Recent Searches
|
Recent Searches
|
||||||
recent search 1
|
recent search 1
|
||||||
recent search 2
|
recent search 2
|
||||||
etc.
|
etc.
|
||||||
---------------------
|
---------------------
|
||||||
Clear Recent Searches
|
Clear Recent Searches
|
||||||
|
|
||||||
If you wish to add items before or after the template, you can. If you put items
|
If you wish to add items before or after the template, you can. If you put items
|
||||||
before, a separator will automatically be placed before the default template item.
|
before, a separator will automatically be placed before the default template item.
|
||||||
If you add items after the default template, it is your responsibility to add a separator.
|
If you add items after the default template, it is your responsibility to add a separator.
|
||||||
|
|
||||||
To add a custom item:
|
To add a custom item:
|
||||||
|
|
||||||
item = [[CPMenuItem alloc] initWithTitle:@"google"
|
item = [[CPMenuItem alloc] initWithTitle:@"google"
|
||||||
action:@selector(google:)
|
action:@selector(google:)
|
||||||
keyEquivalent:@""];
|
keyEquivalent:@""];
|
||||||
[item setTag:700];
|
[item setTag:700];
|
||||||
[item setTarget:self];
|
[item setTarget:self];
|
||||||
[template addItem:item];
|
[template addItem:item];
|
||||||
|
|
||||||
Be sure that your custom items do not use tags in the range 1000-1004 inclusive.
|
Be sure that your custom items do not use tags in the range 1000-1003 inclusive.
|
||||||
If you wish to maintain state in custom menu items that you add, you will need to maintain
|
If you wish to maintain state in custom menu items that you add, you will need to maintain
|
||||||
the item state yourself, then in the action method of the custom items, modify the items
|
the item state yourself, then in the action method of the custom items, modify the items
|
||||||
in the search menu template and send [searchField setSearchMenuTemplate:template] to update the menu.
|
in the search menu template and send [searchField setSearchMenuTemplate:template] to update the menu.
|
||||||
*/
|
*/
|
||||||
- (CPMenu)defaultSearchMenuTemplate
|
- (CPMenu)defaultSearchMenuTemplate
|
||||||
{
|
{
|
||||||
var template = [[CPMenu alloc] init],
|
var template = [[CPMenu alloc] init],
|
||||||
item;
|
item;
|
||||||
|
|
||||||
item = [[CPMenuItem alloc] initWithTitle:@"Recent Searches"
|
item = [[CPMenuItem alloc] initWithTitle:@"Recent Searches"
|
||||||
action:nil
|
action:nil
|
||||||
keyEquivalent:@""];
|
keyEquivalent:@""];
|
||||||
[item setTag:CPSearchFieldRecentsTitleMenuItemTag];
|
[item setTag:CPSearchFieldRecentsTitleMenuItemTag];
|
||||||
[item setEnabled:NO];
|
[item setEnabled:NO];
|
||||||
[template addItem:item];
|
[template addItem:item];
|
||||||
|
|
||||||
item = [[CPMenuItem alloc] initWithTitle:@"Recent search item"
|
item = [[CPMenuItem alloc] initWithTitle:@"Recent search item"
|
||||||
action:@selector(_searchFieldSearch:)
|
action:@selector(_searchFieldSearch:)
|
||||||
keyEquivalent:@""];
|
keyEquivalent:@""];
|
||||||
[item setTag:CPSearchFieldRecentsMenuItemTag];
|
[item setTag:CPSearchFieldRecentsMenuItemTag];
|
||||||
[item setTarget:self];
|
[item setTarget:self];
|
||||||
[template addItem:item];
|
[template addItem:item];
|
||||||
|
|
||||||
item = [[CPMenuItem alloc] initWithTitle:@"Clear Recent Searches"
|
item = [[CPMenuItem alloc] initWithTitle:@"Clear Recent Searches"
|
||||||
action:@selector(_searchFieldClearRecents:)
|
action:@selector(_searchFieldClearRecents:)
|
||||||
keyEquivalent:@""];
|
keyEquivalent:@""];
|
||||||
[item setTag:CPSearchFieldClearRecentsMenuItemTag];
|
[item setTag:CPSearchFieldClearRecentsMenuItemTag];
|
||||||
[item setTarget:self];
|
[item setTarget:self];
|
||||||
[template addItem:item];
|
[template addItem:item];
|
||||||
|
|
||||||
item = [[CPMenuItem alloc] initWithTitle:@"No Recent Searches"
|
item = [[CPMenuItem alloc] initWithTitle:@"No Recent Searches"
|
||||||
action:nil
|
action:nil
|
||||||
keyEquivalent:@""];
|
keyEquivalent:@""];
|
||||||
[item setTag:CPSearchFieldNoRecentsMenuItemTag];
|
[item setTag:CPSearchFieldNoRecentsMenuItemTag];
|
||||||
[item setEnabled:NO];
|
[item setEnabled:NO];
|
||||||
[template addItem:item];
|
[template addItem:item];
|
||||||
|
|
||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -574,72 +573,66 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
{
|
{
|
||||||
if (_searchMenuTemplate === nil)
|
if (_searchMenuTemplate === nil)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var menu = [[CPMenu alloc] init],
|
var menu = [[CPMenu alloc] init],
|
||||||
countOfRecents = [_recentSearches count],
|
countOfRecents = [_recentSearches count],
|
||||||
numberOfItems = [_searchMenuTemplate numberOfItems];
|
numberOfItems = [_searchMenuTemplate numberOfItems];
|
||||||
|
|
||||||
for (var i = 0; i < numberOfItems; i++)
|
for (var i = 0; i < numberOfItems; i++)
|
||||||
{
|
{
|
||||||
var item = [[_searchMenuTemplate itemAtIndex:i] copy];
|
var item = [[_searchMenuTemplate itemAtIndex:i] copy];
|
||||||
|
|
||||||
switch ([item tag])
|
switch ([item tag])
|
||||||
{
|
{
|
||||||
case CPSearchFieldRecentsTitleMenuItemTag:
|
case CPSearchFieldRecentsTitleMenuItemTag:
|
||||||
if (countOfRecents === 0)
|
if (countOfRecents === 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ([menu numberOfItems] > 0)
|
if ([menu numberOfItems] > 0)
|
||||||
[self _addSeparatorToMenu:menu];
|
[self _addSeparatorToMenu:menu];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CPSearchFieldRecentsMenuItemTag:
|
case CPSearchFieldRecentsMenuItemTag:
|
||||||
{
|
{
|
||||||
var itemAction = @selector(_searchFieldSearch:);
|
var itemAction = @selector(_searchFieldSearch:);
|
||||||
|
|
||||||
for (var recentIndex = 0; recentIndex < countOfRecents; ++recentIndex)
|
for (var recentIndex = 0; recentIndex < countOfRecents; ++recentIndex)
|
||||||
{
|
{
|
||||||
// RECENT_SEARCH_PREFIX is a hack until CPMenuItem -setIndentationLevel works
|
// RECENT_SEARCH_PREFIX is a hack until CPMenuItem -setIndentationLevel works
|
||||||
var recentItem = [[CPMenuItem alloc] initWithTitle:RECENT_SEARCH_PREFIX + [_recentSearches objectAtIndex:recentIndex]
|
var recentItem = [[CPMenuItem alloc] initWithTitle:RECENT_SEARCH_PREFIX + [_recentSearches objectAtIndex:recentIndex]
|
||||||
action:itemAction
|
action:itemAction
|
||||||
keyEquivalent:[item keyEquivalent]];
|
keyEquivalent:[item keyEquivalent]];
|
||||||
[item setTarget:self];
|
[item setTarget:self];
|
||||||
[menu addItem:recentItem];
|
[menu addItem:recentItem];
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CPSearchFieldClearRecentsMenuItemTag:
|
case CPSearchFieldClearRecentsMenuItemTag:
|
||||||
if (countOfRecents === 0)
|
if (countOfRecents === 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ([menu numberOfItems] > 0)
|
if ([menu numberOfItems] > 0)
|
||||||
[self _addSeparatorToMenu:menu];
|
[self _addSeparatorToMenu:menu];
|
||||||
|
|
||||||
[item setAction:@selector(_searchFieldClearRecents:)];
|
[item setAction:@selector(_searchFieldClearRecents:)];
|
||||||
[item setTarget:self];
|
[item setTarget:self];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CPSearchFieldNoRecentsMenuItemTag:
|
case CPSearchFieldNoRecentsMenuItemTag:
|
||||||
if (countOfRecents !== 0)
|
if (countOfRecents !== 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ([menu numberOfItems] > 0)
|
if ([menu numberOfItems] > 0)
|
||||||
[self _addSeparatorToMenu:menu];
|
[self _addSeparatorToMenu:menu];
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case CPSearchFieldSeparatorMenuItemTag:
|
|
||||||
item = [CPMenuItem separatorItem];
|
|
||||||
[item setEnabled:NO];
|
|
||||||
[menu addItem:item];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
[item setEnabled:([item isEnabled] && [item action] != nil && [item target] != nil)];
|
[item setEnabled:([item isEnabled] && [item action] != nil && [item target] != nil)];
|
||||||
[menu addItem:item];
|
[menu addItem:item];
|
||||||
}
|
}
|
||||||
|
|
||||||
[menu setDelegate:self];
|
[menu setDelegate:self];
|
||||||
|
|
||||||
_searchMenu = menu;
|
_searchMenu = menu;
|
||||||
@@ -660,7 +653,7 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
- (void)menuDidClose:(CPMenu)menu
|
- (void)menuDidClose:(CPMenu)menu
|
||||||
{
|
{
|
||||||
_canResignFirstResponder = YES;
|
_canResignFirstResponder = YES;
|
||||||
|
|
||||||
[self becomeFirstResponder];
|
[self becomeFirstResponder];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -668,12 +661,12 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
{
|
{
|
||||||
if (_searchMenu === nil || [_searchMenu numberOfItems] === 0 || ![self isEnabled])
|
if (_searchMenu === nil || [_searchMenu numberOfItems] === 0 || ![self isEnabled])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var aFrame = [[self superview] convertRect:[self frame] toView:nil],
|
var aFrame = [[self superview] convertRect:[self frame] toView:nil],
|
||||||
location = CPMakePoint(aFrame.origin.x + 10, aFrame.origin.y + aFrame.size.height - 4);
|
location = CPMakePoint(aFrame.origin.x + 10, aFrame.origin.y + aFrame.size.height - 4);
|
||||||
|
|
||||||
var anEvent = [CPEvent mouseEventWithType:CPRightMouseDown location:location modifierFlags:0 timestamp:[[CPApp currentEvent] timestamp] windowNumber:[[self window] windowNumber] context:nil eventNumber:1 clickCount:1 pressure:0];
|
var anEvent = [CPEvent mouseEventWithType:CPRightMouseDown location:location modifierFlags:0 timestamp:[[CPApp currentEvent] timestamp] windowNumber:[[self window] windowNumber] context:nil eventNumber:1 clickCount:1 pressure:0];
|
||||||
|
|
||||||
[self selectAll:nil];
|
[self selectAll:nil];
|
||||||
[CPMenu popUpContextMenu:_searchMenu withEvent:anEvent forView:self];
|
[CPMenu popUpContextMenu:_searchMenu withEvent:anEvent forView:self];
|
||||||
}
|
}
|
||||||
@@ -685,7 +678,7 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)_searchFieldCancel:(id)sender
|
- (void)_searchFieldCancel:(id)sender
|
||||||
{
|
{
|
||||||
[self setObjectValue:@""];
|
[self setObjectValue:@""];
|
||||||
[self _sendPartialString];
|
[self _sendPartialString];
|
||||||
[self _updateCancelButtonVisibility];
|
[self _updateCancelButtonVisibility];
|
||||||
@@ -694,14 +687,14 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
- (void)_searchFieldSearch:(id)sender
|
- (void)_searchFieldSearch:(id)sender
|
||||||
{
|
{
|
||||||
var searchString = [[sender title] substringFromIndex:[RECENT_SEARCH_PREFIX length]];
|
var searchString = [[sender title] substringFromIndex:[RECENT_SEARCH_PREFIX length]];
|
||||||
|
|
||||||
if ([sender tag] != CPSearchFieldRecentsMenuItemTag)
|
if ([sender tag] != CPSearchFieldRecentsMenuItemTag)
|
||||||
[self _addStringToRecentSearches:searchString];
|
[self _addStringToRecentSearches:searchString];
|
||||||
|
|
||||||
[self setObjectValue:searchString];
|
[self setObjectValue:searchString];
|
||||||
[self _sendPartialString];
|
[self _sendPartialString];
|
||||||
[self selectAll:nil];
|
[self selectAll:nil];
|
||||||
|
|
||||||
[self _updateCancelButtonVisibility];
|
[self _updateCancelButtonVisibility];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -715,54 +708,36 @@ var RECENT_SEARCH_PREFIX = @" ";
|
|||||||
|
|
||||||
- (void)_registerForAutosaveNotification
|
- (void)_registerForAutosaveNotification
|
||||||
{
|
{
|
||||||
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_updateAutosavedRecents:) name:@"CPAutosavedRecentsChangedNotification" object:nil];
|
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_updateAutosavedRecents:) name:CPAutosavedRecentsChangedNotification object:_recentsAutosaveName];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_deregisterForAutosaveNotification
|
- (void)_deregisterForAutosaveNotification
|
||||||
{
|
{
|
||||||
[[CPNotificationCenter defaultCenter] removeObserver:self name:@"CPAutosavedRecentsChangedNotification" object:nil];
|
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPAutosavedRecentsChangedNotification object:_recentsAutosaveName];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_autosaveRecentSearchList
|
- (void)_autosaveRecentSearchList
|
||||||
{
|
{
|
||||||
if (_recentsAutosaveName != nil)
|
if (_recentsAutosaveName != nil)
|
||||||
[[CPNotificationCenter defaultCenter] postNotificationName:@"CPAutosavedRecentsChangedNotification" object:_recentsAutosaveName];
|
[[CPNotificationCenter defaultCenter] postNotificationName:CPAutosavedRecentsChangedNotification object:_recentsAutosaveName];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_updateAutosavedRecents:(id)notification
|
- (void)_updateAutosavedRecents:(id)notification
|
||||||
{
|
{
|
||||||
var list = [self recentSearches],
|
var name = [notification object];
|
||||||
name = [notification object],
|
[[CPUserDefaults standardUserDefaults] setObject:_recentSearches forKey:name];
|
||||||
bundle_name = [[[CPBundle mainBundle] infoDictionary] objectForKey:"CPBundleName"],
|
|
||||||
cookie_name = [bundle_name lowercaseString] + "." + [notification object],
|
|
||||||
|
|
||||||
cookie = [[CPCookie alloc] initWithName:cookie_name],
|
|
||||||
cookie_value = [list componentsJoinedByString:@","];
|
|
||||||
|
|
||||||
[cookie setValue:cookie_value
|
|
||||||
expires:[[CPDate alloc] initWithTimeIntervalSinceNow:3600*24*365]
|
|
||||||
domain:(window.location.href.hostname)];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_loadRecentSearchList
|
- (void)_loadRecentSearchList
|
||||||
{
|
{
|
||||||
var list,
|
var name = [self recentsAutosaveName];
|
||||||
name = [self recentsAutosaveName];
|
|
||||||
|
|
||||||
if (name === nil)
|
if (name === nil)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var bundle_name = [[[CPBundle mainBundle] infoDictionary] objectForKey:"CPBundleName"],
|
var list = [[CPUserDefaults standardUserDefaults] objectForKey:name];
|
||||||
cookie_name = [bundle_name lowercaseString] + "." + name,
|
|
||||||
|
|
||||||
cookie = [[CPCookie alloc] initWithName:cookie_name];
|
if (list !== nil)
|
||||||
|
|
||||||
if (cookie != nil)
|
|
||||||
{
|
|
||||||
var cookie_value = [cookie value];
|
|
||||||
list = (cookie_value != @"") ? [cookie_value componentsSeparatedByString:@","] : [CPArray array];
|
|
||||||
_recentSearches = list;
|
_recentSearches = list;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -780,7 +755,7 @@ var CPRecentsAutosaveNameKey = @"CPRecentsAutosaveNameKey",
|
|||||||
[_searchButton removeFromSuperview];
|
[_searchButton removeFromSuperview];
|
||||||
[_cancelButton removeFromSuperview];
|
[_cancelButton removeFromSuperview];
|
||||||
|
|
||||||
[super encodeWithCoder:coder];
|
[super encodeWithCoder:coder];
|
||||||
|
|
||||||
if (_searchButton)
|
if (_searchButton)
|
||||||
[self addSubview:_searchButton];
|
[self addSubview:_searchButton];
|
||||||
@@ -793,7 +768,7 @@ var CPRecentsAutosaveNameKey = @"CPRecentsAutosaveNameKey",
|
|||||||
|
|
||||||
if (_recentsAutosaveName)
|
if (_recentsAutosaveName)
|
||||||
[coder encodeObject:_recentsAutosaveName forKey:CPRecentsAutosaveNameKey];
|
[coder encodeObject:_recentsAutosaveName forKey:CPRecentsAutosaveNameKey];
|
||||||
|
|
||||||
if (_searchMenuTemplate)
|
if (_searchMenuTemplate)
|
||||||
[coder encodeObject:_searchMenuTemplate forKey:CPSearchMenuTemplateKey];
|
[coder encodeObject:_searchMenuTemplate forKey:CPSearchMenuTemplateKey];
|
||||||
}
|
}
|
||||||
@@ -802,16 +777,16 @@ var CPRecentsAutosaveNameKey = @"CPRecentsAutosaveNameKey",
|
|||||||
{
|
{
|
||||||
if (self = [super initWithCoder:coder])
|
if (self = [super initWithCoder:coder])
|
||||||
{
|
{
|
||||||
_recentsAutosaveName = [coder decodeObjectForKey:CPRecentsAutosaveNameKey];
|
[self setRecentsAutosaveName:[coder decodeObjectForKey:CPRecentsAutosaveNameKey]];
|
||||||
_sendsWholeSearchString = [coder decodeBoolForKey:CPSendsWholeSearchStringKey];
|
_sendsWholeSearchString = [coder decodeBoolForKey:CPSendsWholeSearchStringKey];
|
||||||
_sendsSearchStringImmediately = [coder decodeBoolForKey:CPSendsSearchStringImmediatelyKey];
|
_sendsSearchStringImmediately = [coder decodeBoolForKey:CPSendsSearchStringImmediatelyKey];
|
||||||
_maximumRecents = [coder decodeIntForKey:CPMaximumRecentsKey];
|
_maximumRecents = [coder decodeIntForKey:CPMaximumRecentsKey];
|
||||||
|
|
||||||
var template = [coder decodeObjectForKey:CPSearchMenuTemplateKey];
|
var template = [coder decodeObjectForKey:CPSearchMenuTemplateKey];
|
||||||
|
|
||||||
if (template)
|
if (template)
|
||||||
[self setSearchMenuTemplate:template];
|
[self setSearchMenuTemplate:template];
|
||||||
|
|
||||||
[self _init];
|
[self _init];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -94,7 +94,9 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
if (_segments.length == aCount)
|
if (_segments.length == aCount)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var height = CGRectGetHeight([self bounds]);
|
var height = CGRectGetHeight([self bounds]),
|
||||||
|
dividersBefore = MAX(0, _segments.length - 1),
|
||||||
|
dividersAfter = MAX(0, aCount - 1);
|
||||||
|
|
||||||
if (_segments.length < aCount)
|
if (_segments.length < aCount)
|
||||||
{
|
{
|
||||||
@@ -113,6 +115,14 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
if (_selectedSegment >= _segments.length)
|
if (_selectedSegment >= _segments.length)
|
||||||
_selectedSegment = -1;
|
_selectedSegment = -1;
|
||||||
|
|
||||||
|
// Make space for/remove space used by dividers.
|
||||||
|
var thickness = [self currentValueForThemeAttribute:@"divider-thickness"],
|
||||||
|
delta = thickness * (dividersAfter - dividersBefore),
|
||||||
|
frame = [self frame];
|
||||||
|
|
||||||
|
if (delta)
|
||||||
|
[self setFrameSize:CGSizeMake(frame.size.width + delta, frame.size.height)];
|
||||||
|
|
||||||
[self tileWithChangedSegment:0];
|
[self tileWithChangedSegment:0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -607,7 +617,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
|||||||
segmentWidth = [segment width],
|
segmentWidth = [segment width],
|
||||||
themeState = _themeStates[aSegment] | (_themeState & CPThemeStateDisabled),
|
themeState = _themeStates[aSegment] | (_themeState & CPThemeStateDisabled),
|
||||||
contentInset = [self valueForThemeAttribute:@"content-inset" inState:themeState],
|
contentInset = [self valueForThemeAttribute:@"content-inset" inState:themeState],
|
||||||
font = [self valueForThemeAttribute:@"font" inState:themeState];
|
font = [self font];
|
||||||
|
|
||||||
if (!segmentWidth)
|
if (!segmentWidth)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,8 +23,8 @@
|
|||||||
@import <Foundation/CPObject.j>
|
@import <Foundation/CPObject.j>
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@deprecated
|
@deprecated
|
||||||
@class CPShadow
|
@class CPShadow
|
||||||
|
|
||||||
Instances of this class contain the attributes of a drop shadow used in Cappuccino.
|
Instances of this class contain the attributes of a drop shadow used in Cappuccino.
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
CPSize _offset;
|
CPSize _offset;
|
||||||
float _blurRadius;
|
float _blurRadius;
|
||||||
CPColor _color;
|
CPColor _color;
|
||||||
|
|
||||||
CPString _cssString;
|
CPString _cssString;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,16 +54,16 @@
|
|||||||
- (id)_initWithOffset:(CPSize)anOffset blurRadius:(float)aBlurRadius color:(CPColor)aColor
|
- (id)_initWithOffset:(CPSize)anOffset blurRadius:(float)aBlurRadius color:(CPColor)aColor
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
_offset = anOffset;
|
_offset = anOffset;
|
||||||
_blurRadius = aBlurRadius;
|
_blurRadius = aBlurRadius;
|
||||||
_color = aColor;
|
_color = aColor;
|
||||||
|
|
||||||
_cssString = [_color cssString] + " " + Math.round(anOffset.width) + @"px " + Math.round(anOffset.height) + @"px " + Math.round(_blurRadius) + @"px";
|
_cssString = [_color cssString] + " " + Math.round(anOffset.width) + @"px " + Math.round(anOffset.height) + @"px " + Math.round(_blurRadius) + @"px";
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,16 +28,16 @@
|
|||||||
@ignore
|
@ignore
|
||||||
*/
|
*/
|
||||||
@implementation CPSliderColorPicker : CPColorPicker
|
@implementation CPSliderColorPicker : CPColorPicker
|
||||||
{
|
{
|
||||||
CPView _contentView;
|
CPView _contentView;
|
||||||
|
|
||||||
CPSlider _redSlider;
|
CPSlider _redSlider;
|
||||||
CPSlider _greenSlider;
|
CPSlider _greenSlider;
|
||||||
CPSlider _blueSlider;
|
CPSlider _blueSlider;
|
||||||
CPSlider _hueSlider;
|
CPSlider _hueSlider;
|
||||||
CPSlider _saturationSlider;
|
CPSlider _saturationSlider;
|
||||||
CPSlider _brightnessSlider;
|
CPSlider _brightnessSlider;
|
||||||
|
|
||||||
CPTextField _rgbLabel;
|
CPTextField _rgbLabel;
|
||||||
CPTextField _hsbLabel;
|
CPTextField _hsbLabel;
|
||||||
CPTextField _redLabel;
|
CPTextField _redLabel;
|
||||||
@@ -58,27 +58,27 @@
|
|||||||
CPTextField _brightnessValue;
|
CPTextField _brightnessValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithPickerMask:(int)mask colorPanel:(CPColorPanel)owningColorPanel
|
- (id)initWithPickerMask:(int)mask colorPanel:(CPColorPanel)owningColorPanel
|
||||||
{
|
{
|
||||||
return [super initWithPickerMask:mask colorPanel: owningColorPanel];
|
return [super initWithPickerMask:mask colorPanel: owningColorPanel];
|
||||||
}
|
}
|
||||||
|
|
||||||
-(id)initView
|
- (id)initView
|
||||||
{
|
{
|
||||||
aFrame = CPRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
|
aFrame = CGRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
|
||||||
|
|
||||||
_contentView = [[CPView alloc] initWithFrame:aFrame];
|
_contentView = [[CPView alloc] initWithFrame:aFrame];
|
||||||
[_contentView setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable];
|
[_contentView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
||||||
|
|
||||||
_rgbLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 10, 100, 20)];
|
_rgbLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 10, 100, 20)];
|
||||||
[_rgbLabel setStringValue: "Red, Green, Blue"];
|
[_rgbLabel setStringValue: "Red, Green, Blue"];
|
||||||
[_rgbLabel setTextColor:[CPColor blackColor]];
|
[_rgbLabel setTextColor:[CPColor blackColor]];
|
||||||
|
|
||||||
_redLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 35, 15, 20)];
|
_redLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 35, 15, 20)];
|
||||||
[_redLabel setStringValue: "R"];
|
[_redLabel setStringValue: "R"];
|
||||||
[_redLabel setTextColor:[CPColor blackColor]];
|
[_redLabel setTextColor:[CPColor blackColor]];
|
||||||
|
|
||||||
_redSlider = [[CPSlider alloc] initWithFrame: CPRectMake(15, 35, aFrame.size.width - 70, 20)];
|
_redSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 35, aFrame.size.width - 70, 20)];
|
||||||
[_redSlider setMaxValue: 1.0];
|
[_redSlider setMaxValue: 1.0];
|
||||||
[_redSlider setMinValue: 0.0];
|
[_redSlider setMinValue: 0.0];
|
||||||
[_redSlider setTarget: self];
|
[_redSlider setTarget: self];
|
||||||
@@ -93,11 +93,11 @@
|
|||||||
[_redValue setDelegate: self];
|
[_redValue setDelegate: self];
|
||||||
[_contentView addSubview: _redValue];
|
[_contentView addSubview: _redValue];
|
||||||
|
|
||||||
_greenLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 58, 15, 20)];
|
_greenLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 58, 15, 20)];
|
||||||
[_greenLabel setStringValue: "G"];
|
[_greenLabel setStringValue: "G"];
|
||||||
[_greenLabel setTextColor:[CPColor blackColor]];
|
[_greenLabel setTextColor:[CPColor blackColor]];
|
||||||
|
|
||||||
_greenSlider = [[CPSlider alloc] initWithFrame: CPRectMake(15, 58, aFrame.size.width - 70, 20)];
|
_greenSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 58, aFrame.size.width - 70, 20)];
|
||||||
[_greenSlider setMaxValue: 1.0];
|
[_greenSlider setMaxValue: 1.0];
|
||||||
[_greenSlider setMinValue: 0.0];
|
[_greenSlider setMinValue: 0.0];
|
||||||
[_greenSlider setTarget: self];
|
[_greenSlider setTarget: self];
|
||||||
@@ -112,11 +112,11 @@
|
|||||||
[_greenValue setDelegate: self];
|
[_greenValue setDelegate: self];
|
||||||
[_contentView addSubview: _greenValue];
|
[_contentView addSubview: _greenValue];
|
||||||
|
|
||||||
_blueLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 81, 15, 20)];
|
_blueLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 81, 15, 20)];
|
||||||
[_blueLabel setStringValue: "B"];
|
[_blueLabel setStringValue: "B"];
|
||||||
[_blueLabel setTextColor:[CPColor blackColor]];
|
[_blueLabel setTextColor:[CPColor blackColor]];
|
||||||
|
|
||||||
_blueSlider = [[CPSlider alloc] initWithFrame: CPRectMake(15, 81, aFrame.size.width - 70, 20)];
|
_blueSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 81, aFrame.size.width - 70, 20)];
|
||||||
[_blueSlider setMaxValue: 1.0];
|
[_blueSlider setMaxValue: 1.0];
|
||||||
[_blueSlider setMinValue: 0.0];
|
[_blueSlider setMinValue: 0.0];
|
||||||
[_blueSlider setTarget: self];
|
[_blueSlider setTarget: self];
|
||||||
@@ -131,15 +131,15 @@
|
|||||||
[_blueValue setDelegate: self];
|
[_blueValue setDelegate: self];
|
||||||
[_contentView addSubview: _blueValue];
|
[_contentView addSubview: _blueValue];
|
||||||
|
|
||||||
_hsbLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 120, 190, 20)];
|
_hsbLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 120, 190, 20)];
|
||||||
[_hsbLabel setStringValue: "Hue, Saturation, Brightness"];
|
[_hsbLabel setStringValue: "Hue, Saturation, Brightness"];
|
||||||
[_hsbLabel setTextColor:[CPColor blackColor]];
|
[_hsbLabel setTextColor:[CPColor blackColor]];
|
||||||
|
|
||||||
_hueLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 145, 15, 20)];
|
_hueLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 145, 15, 20)];
|
||||||
[_hueLabel setStringValue: "H"];
|
[_hueLabel setStringValue: "H"];
|
||||||
[_hueLabel setTextColor:[CPColor blackColor]];
|
[_hueLabel setTextColor:[CPColor blackColor]];
|
||||||
|
|
||||||
_hueSlider = [[CPSlider alloc] initWithFrame: CPRectMake(15, 145, aFrame.size.width - 70, 20)];
|
_hueSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 145, aFrame.size.width - 70, 20)];
|
||||||
[_hueSlider setMaxValue: 359.0];
|
[_hueSlider setMaxValue: 359.0];
|
||||||
[_hueSlider setMinValue: 0.0];
|
[_hueSlider setMinValue: 0.0];
|
||||||
[_hueSlider setTarget: self];
|
[_hueSlider setTarget: self];
|
||||||
@@ -154,11 +154,11 @@
|
|||||||
[_hueValue setDelegate: self];
|
[_hueValue setDelegate: self];
|
||||||
[_contentView addSubview: _hueValue];
|
[_contentView addSubview: _hueValue];
|
||||||
|
|
||||||
_saturationLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 168, 15, 20)];
|
_saturationLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 168, 15, 20)];
|
||||||
[_saturationLabel setStringValue: "S"];
|
[_saturationLabel setStringValue: "S"];
|
||||||
[_saturationLabel setTextColor:[CPColor blackColor]];
|
[_saturationLabel setTextColor:[CPColor blackColor]];
|
||||||
|
|
||||||
_saturationSlider = [[CPSlider alloc] initWithFrame: CPRectMake(15, 168, aFrame.size.width - 70, 20)];
|
_saturationSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 168, aFrame.size.width - 70, 20)];
|
||||||
[_saturationSlider setMaxValue: 100.0];
|
[_saturationSlider setMaxValue: 100.0];
|
||||||
[_saturationSlider setMinValue: 0.0];
|
[_saturationSlider setMinValue: 0.0];
|
||||||
[_saturationSlider setTarget: self];
|
[_saturationSlider setTarget: self];
|
||||||
@@ -173,11 +173,11 @@
|
|||||||
[_saturationValue setDelegate: self];
|
[_saturationValue setDelegate: self];
|
||||||
[_contentView addSubview: _saturationValue];
|
[_contentView addSubview: _saturationValue];
|
||||||
|
|
||||||
_brightnessLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 191, 15, 20)];
|
_brightnessLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 191, 15, 20)];
|
||||||
[_brightnessLabel setStringValue: "B"];
|
[_brightnessLabel setStringValue: "B"];
|
||||||
[_brightnessLabel setTextColor:[CPColor blackColor]];
|
[_brightnessLabel setTextColor:[CPColor blackColor]];
|
||||||
|
|
||||||
_brightnessSlider = [[CPSlider alloc] initWithFrame: CPRectMake(15, 191, aFrame.size.width - 70, 20)];
|
_brightnessSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 191, aFrame.size.width - 70, 20)];
|
||||||
[_brightnessSlider setMaxValue: 100.0];
|
[_brightnessSlider setMaxValue: 100.0];
|
||||||
[_brightnessSlider setMinValue: 0.0];
|
[_brightnessSlider setMinValue: 0.0];
|
||||||
[_brightnessSlider setTarget: self];
|
[_brightnessSlider setTarget: self];
|
||||||
@@ -192,7 +192,7 @@
|
|||||||
[_brightnessValue setDelegate: self];
|
[_brightnessValue setDelegate: self];
|
||||||
[_contentView addSubview: _brightnessValue];
|
[_contentView addSubview: _brightnessValue];
|
||||||
|
|
||||||
_hexLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 230, 30, 20)];
|
_hexLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 230, 30, 20)];
|
||||||
[_hexLabel setStringValue: "Hex"];
|
[_hexLabel setStringValue: "Hex"];
|
||||||
[_hexLabel setTextColor:[CPColor blackColor]];
|
[_hexLabel setTextColor:[CPColor blackColor]];
|
||||||
|
|
||||||
@@ -210,7 +210,7 @@
|
|||||||
[_contentView addSubview: _redSlider];
|
[_contentView addSubview: _redSlider];
|
||||||
[_contentView addSubview: _greenSlider];
|
[_contentView addSubview: _greenSlider];
|
||||||
[_contentView addSubview: _blueSlider];
|
[_contentView addSubview: _blueSlider];
|
||||||
|
|
||||||
[_contentView addSubview: _hsbLabel];
|
[_contentView addSubview: _hsbLabel];
|
||||||
[_contentView addSubview: _hueLabel];
|
[_contentView addSubview: _hueLabel];
|
||||||
[_contentView addSubview: _saturationLabel];
|
[_contentView addSubview: _saturationLabel];
|
||||||
@@ -218,24 +218,24 @@
|
|||||||
[_contentView addSubview: _hueSlider];
|
[_contentView addSubview: _hueSlider];
|
||||||
[_contentView addSubview: _saturationSlider];
|
[_contentView addSubview: _saturationSlider];
|
||||||
[_contentView addSubview: _brightnessSlider];
|
[_contentView addSubview: _brightnessSlider];
|
||||||
|
|
||||||
[_contentView addSubview: _hexLabel];
|
[_contentView addSubview: _hexLabel];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CPView)provideNewView:(BOOL)initialRequest
|
- (CPView)provideNewView:(BOOL)initialRequest
|
||||||
{
|
{
|
||||||
if (initialRequest)
|
if (initialRequest)
|
||||||
[self initView];
|
[self initView];
|
||||||
|
|
||||||
return _contentView;
|
return _contentView;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (int)currentMode
|
- (int)currentMode
|
||||||
{
|
{
|
||||||
return CPSliderColorPickerMode;
|
return CPSliderColorPickerMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)supportsMode:(int)mode
|
- (BOOL)supportsMode:(int)mode
|
||||||
{
|
{
|
||||||
return (mode == CPSliderColorPickerMode) ? YES : NO;
|
return (mode == CPSliderColorPickerMode) ? YES : NO;
|
||||||
}
|
}
|
||||||
@@ -246,7 +246,7 @@
|
|||||||
colorPanel = [self colorPanel],
|
colorPanel = [self colorPanel],
|
||||||
alpha = [colorPanel opacity];
|
alpha = [colorPanel opacity];
|
||||||
|
|
||||||
switch(sender)
|
switch (sender)
|
||||||
{
|
{
|
||||||
case _hueSlider:
|
case _hueSlider:
|
||||||
case _saturationSlider:
|
case _saturationSlider:
|
||||||
@@ -254,21 +254,21 @@
|
|||||||
saturation: [_saturationSlider floatValue]
|
saturation: [_saturationSlider floatValue]
|
||||||
brightness: [_brightnessSlider floatValue]
|
brightness: [_brightnessSlider floatValue]
|
||||||
alpha: alpha];
|
alpha: alpha];
|
||||||
|
|
||||||
[self updateRGBSliders: newColor];
|
[self updateRGBSliders: newColor];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case _redSlider:
|
case _redSlider:
|
||||||
case _greenSlider:
|
case _greenSlider:
|
||||||
case _blueSlider: newColor = [CPColor colorWithCalibratedRed: [_redSlider floatValue]
|
case _blueSlider: newColor = [CPColor colorWithCalibratedRed: [_redSlider floatValue]
|
||||||
green: [_greenSlider floatValue]
|
green: [_greenSlider floatValue]
|
||||||
blue: [_blueSlider floatValue]
|
blue: [_blueSlider floatValue]
|
||||||
alpha: alpha];
|
alpha: alpha];
|
||||||
|
|
||||||
[self updateHSBSliders: newColor];
|
[self updateHSBSliders: newColor];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
[self updateLabels];
|
[self updateLabels];
|
||||||
[self updateHex: newColor];
|
[self updateHex: newColor];
|
||||||
[colorPanel setColor: newColor];
|
[colorPanel setColor: newColor];
|
||||||
@@ -285,7 +285,7 @@
|
|||||||
-(void)updateHSBSliders:(CPColor)aColor
|
-(void)updateHSBSliders:(CPColor)aColor
|
||||||
{
|
{
|
||||||
var hsb = [aColor hsbComponents];
|
var hsb = [aColor hsbComponents];
|
||||||
|
|
||||||
[_hueSlider setFloatValue:hsb[0]];
|
[_hueSlider setFloatValue:hsb[0]];
|
||||||
[_saturationSlider setFloatValue:hsb[1]];
|
[_saturationSlider setFloatValue:hsb[1]];
|
||||||
[_brightnessSlider setFloatValue:hsb[2]];
|
[_brightnessSlider setFloatValue:hsb[2]];
|
||||||
@@ -310,7 +310,7 @@
|
|||||||
[_hueValue setStringValue: ROUND([_hueSlider floatValue])];
|
[_hueValue setStringValue: ROUND([_hueSlider floatValue])];
|
||||||
[_saturationValue setStringValue: ROUND([_saturationSlider floatValue])];
|
[_saturationValue setStringValue: ROUND([_saturationSlider floatValue])];
|
||||||
[_brightnessValue setStringValue: ROUND([_brightnessSlider floatValue])];
|
[_brightnessValue setStringValue: ROUND([_brightnessSlider floatValue])];
|
||||||
|
|
||||||
[_redValue setStringValue: ROUND([_redSlider floatValue] * 255)];
|
[_redValue setStringValue: ROUND([_redSlider floatValue] * 255)];
|
||||||
[_greenValue setStringValue: ROUND([_greenSlider floatValue] * 255)];
|
[_greenValue setStringValue: ROUND([_greenSlider floatValue] * 255)];
|
||||||
[_blueValue setStringValue: ROUND([_blueSlider floatValue] * 255)];
|
[_blueValue setStringValue: ROUND([_blueSlider floatValue] * 255)];
|
||||||
@@ -330,14 +330,21 @@
|
|||||||
{
|
{
|
||||||
var field = [aNotification object],
|
var field = [aNotification object],
|
||||||
value = [[field stringValue] stringByTrimmingWhitespace];
|
value = [[field stringValue] stringByTrimmingWhitespace];
|
||||||
if (field === _hexValue) {
|
|
||||||
|
if (field === _hexValue)
|
||||||
|
{
|
||||||
var newColor = [CPColor colorWithHexString: value];
|
var newColor = [CPColor colorWithHexString: value];
|
||||||
if (newColor) {
|
|
||||||
|
if (newColor)
|
||||||
|
{
|
||||||
[self setColor: newColor];
|
[self setColor: newColor];
|
||||||
[[self colorPanel] setColor: newColor];
|
[[self colorPanel] setColor: newColor];
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
switch(field) {
|
else
|
||||||
|
{
|
||||||
|
switch (field)
|
||||||
|
{
|
||||||
case _redValue: [_redSlider setFloatValue:MAX(MIN(ROUND(value), 255) / 255.0, 0)];
|
case _redValue: [_redSlider setFloatValue:MAX(MIN(ROUND(value), 255) / 255.0, 0)];
|
||||||
[self sliderChanged: _redSlider];
|
[self sliderChanged: _redSlider];
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -0,0 +1,268 @@
|
|||||||
|
/*
|
||||||
|
* CPSound.j
|
||||||
|
* AppKit
|
||||||
|
*
|
||||||
|
* Created by Antoine Mercadal
|
||||||
|
* Copyright 2010, Antoine Mercadal
|
||||||
|
*
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
@import <Foundation/CPObject.j>
|
||||||
|
|
||||||
|
CPSoundLoadStateEmpty = 0;
|
||||||
|
CPSoundLoadStateLoading = 1;
|
||||||
|
CPSoundLoadStateCanBePlayed = 2;
|
||||||
|
|
||||||
|
CPSoundPlayBackStatePlay = 0;
|
||||||
|
CPSoundPlayBackStateStop = 1;
|
||||||
|
CPSoundPlayBackStatePause = 2;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
CPSound provides a way to load and play sounds. In the browser it relies on the
|
||||||
|
HTML5 audio tag being available.
|
||||||
|
|
||||||
|
CPSound delegate:
|
||||||
|
- sound:didFinishPlaying: called when sound has finished to played
|
||||||
|
|
||||||
|
*/
|
||||||
|
@implementation CPSound : CPObject
|
||||||
|
{
|
||||||
|
CPString _name @accessors(property=name);
|
||||||
|
id _delegate @accessors(property=delegate);
|
||||||
|
|
||||||
|
HTMLAudioElement _audioTag;
|
||||||
|
int _loadStatus;
|
||||||
|
int _playBackStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark Initialization
|
||||||
|
|
||||||
|
- (id)init
|
||||||
|
{
|
||||||
|
if (self = [super init])
|
||||||
|
{
|
||||||
|
_loadStatus = CPSoundLoadStateEmpty;
|
||||||
|
_loops = NO;
|
||||||
|
_audioTag = document.createElement("audio");
|
||||||
|
_audioTag.preload = YES;
|
||||||
|
_audioTag.addEventListener("canplay", function()
|
||||||
|
{
|
||||||
|
[self _soundDidload];
|
||||||
|
});
|
||||||
|
_audioTag.addEventListener("ended", function()
|
||||||
|
{
|
||||||
|
[self _soundDidEnd];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Initialize with the sound contents of the URL represented by aFile.
|
||||||
|
|
||||||
|
@param aFile CPString the path of the sound
|
||||||
|
@param byRef ignored (Cocoa compatibibility)
|
||||||
|
*/
|
||||||
|
- (id)initWithContentsOfFile:(CPString)aFile byReference:(BOOL)byRef
|
||||||
|
{
|
||||||
|
if (self = [self init])
|
||||||
|
{
|
||||||
|
_loadStatus = CPSoundLoadStateLoading;
|
||||||
|
_audioTag.src = aFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Initialize with the sound contents of the file located at aURL.
|
||||||
|
|
||||||
|
@param aURL CPURL containing the URL of the sound
|
||||||
|
@param byRef ignored (Cocoa compatibibility)
|
||||||
|
*/
|
||||||
|
- (id)initWithContentsOfURL:(CPURL)aURL byReference:(BOOL)byRef
|
||||||
|
{
|
||||||
|
return [self initWithContentsOfFile:[aURL absoluteString] byReference:NO];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Initialize with the sound contents of someData.
|
||||||
|
|
||||||
|
@param someData CPData containing the sound
|
||||||
|
@param byRef ignored (Cocoa compatibibility)
|
||||||
|
*/
|
||||||
|
- (id)initWithData:(CPData)someData
|
||||||
|
{
|
||||||
|
if (self = [self init])
|
||||||
|
{
|
||||||
|
_loadStatus = CPSoundLoadStateLoading;
|
||||||
|
_audioTag.src = [someData rawString];
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark Events listener
|
||||||
|
|
||||||
|
/*! @ignore
|
||||||
|
*/
|
||||||
|
- (void)_soundDidload
|
||||||
|
{
|
||||||
|
_loadStatus = CPSoundLoadStateCanBePlayed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! @ignore
|
||||||
|
*/
|
||||||
|
- (void)_soundDidEnd
|
||||||
|
{
|
||||||
|
if (![self loops])
|
||||||
|
[self stop];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark Media controls
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Play the sound.
|
||||||
|
*/
|
||||||
|
- (void)play
|
||||||
|
{
|
||||||
|
if ((_loadStatus !== CPSoundLoadStateCanBePlayed)
|
||||||
|
|| (_playBackStatus === CPSoundPlayBackStatePlay))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_audioTag.play();
|
||||||
|
_playBackStatus = CPSoundPlayBackStatePlay;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Stop the sound.
|
||||||
|
*/
|
||||||
|
- (void)stop
|
||||||
|
{
|
||||||
|
if ((_loadStatus !== CPSoundLoadStateCanBePlayed)
|
||||||
|
|| (_playBackStatus === CPSoundPlayBackStateStop))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_audioTag.pause();
|
||||||
|
_audioTag.currentTime = 0.0;
|
||||||
|
_playBackStatus = CPSoundPlayBackStateStop;
|
||||||
|
|
||||||
|
if (_delegate && [_delegate respondsToSelector:@selector(sound:didFinishPlaying:)])
|
||||||
|
[_delegate sound:self didFinishPlaying:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Pause the sound.
|
||||||
|
*/
|
||||||
|
- (void)pause
|
||||||
|
{
|
||||||
|
if ((_loadStatus !== CPSoundLoadStateCanBePlayed)
|
||||||
|
|| (_playBackStatus === CPSoundPlayBackStatePause))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_audioTag.pause();
|
||||||
|
_playBackStatus = CPSoundPlayBackStatePause;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Resume playback of a paused sound.
|
||||||
|
*/
|
||||||
|
- (void)resume
|
||||||
|
{
|
||||||
|
if ((_loadStatus !== CPSoundLoadStateCanBePlayed)
|
||||||
|
|| (_playBackStatus !== CPSoundPlayBackStatePause))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_audioTag.play();
|
||||||
|
_playBackStatus = CPSoundPlayBackStatePlay;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Return YES if the sound is in loop mode.
|
||||||
|
|
||||||
|
@return BOOL YES if in loop mode, NO otherwise
|
||||||
|
*/
|
||||||
|
- (BOOL)loops
|
||||||
|
{
|
||||||
|
return _audioTag.loop;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Specifies whether the sound should repeat.
|
||||||
|
|
||||||
|
@param BOOL YES for loop mode, NO otherwise
|
||||||
|
*/
|
||||||
|
- (void)setLoops:(BOOL)shouldLoop
|
||||||
|
{
|
||||||
|
_audioTag.loop = shouldLoop;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the volume of the receiver.
|
||||||
|
|
||||||
|
@return double from 0.0 to 1.0
|
||||||
|
*/
|
||||||
|
- (double)volume
|
||||||
|
{
|
||||||
|
return _audioTag.volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Set the volume the sound should be played at.
|
||||||
|
|
||||||
|
@param double a volume value between 0.0 and 1.0
|
||||||
|
*/
|
||||||
|
- (void)setVolume:(double)aVolume
|
||||||
|
{
|
||||||
|
if (aVolume > 1.0)
|
||||||
|
aVolume = 1.0;
|
||||||
|
else if (aVolume < 0.0)
|
||||||
|
aVolume = 0.0;
|
||||||
|
|
||||||
|
_audioTag.volume = aVolume;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark Accessors
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the duration in seconds of the sound.
|
||||||
|
|
||||||
|
@return double the duration
|
||||||
|
*/
|
||||||
|
- (double)duration
|
||||||
|
{
|
||||||
|
return _audioTag.duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns if the sound is playing or not.
|
||||||
|
|
||||||
|
@return BOOL YES if the sound is playing, NO otherwise
|
||||||
|
*/
|
||||||
|
- (BOOL)isPlaying
|
||||||
|
{
|
||||||
|
return (_playBackStatus === CPSoundPlayBackStatePlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -621,17 +621,20 @@ var CPSplitViewHorizontalImage = nil,
|
|||||||
viewFrame = CGRectMakeCopy(bounds),
|
viewFrame = CGRectMakeCopy(bounds),
|
||||||
isSizable = isVertical ? [view autoresizingMask] & CPViewWidthSizable : [view autoresizingMask] & CPViewHeightSizable;
|
isSizable = isVertical ? [view autoresizingMask] & CPViewWidthSizable : [view autoresizingMask] & CPViewHeightSizable;
|
||||||
|
|
||||||
if (index + 1 == count)
|
if (index + 1 === count)
|
||||||
viewFrame.size[_sizeComponent] = bounds.size[_sizeComponent] - viewFrame.origin[_originComponent];
|
viewFrame.size[_sizeComponent] = bounds.size[_sizeComponent] - viewFrame.origin[_originComponent];
|
||||||
else if (totalSizableSpace && isSizable && lastSizableIndex === index)
|
|
||||||
viewFrame.size[_sizeComponent] = MAX(0, ROUND([view frame].size[_sizeComponent] + remainingFlexibleSpace))
|
else if (totalSizableSpace && isSizable && lastSizableIndex === index)
|
||||||
else if (isSizable || !totalSizableSpace)
|
viewFrame.size[_sizeComponent] = MAX(0, ROUND([view frame].size[_sizeComponent] + remainingFlexibleSpace))
|
||||||
{
|
|
||||||
viewFrame.size[_sizeComponent] = MAX(0, ROUND(ratio * [view frame].size[_sizeComponent]));
|
else if (isSizable || !totalSizableSpace)
|
||||||
remainingFlexibleSpace -= (viewFrame.size[_sizeComponent] - [view frame].size[_sizeComponent]);
|
{
|
||||||
}
|
viewFrame.size[_sizeComponent] = MAX(0, ROUND(ratio * [view frame].size[_sizeComponent]));
|
||||||
else if (totalSizableSpace && !isSizable)
|
remainingFlexibleSpace -= (viewFrame.size[_sizeComponent] - [view frame].size[_sizeComponent]);
|
||||||
viewFrame.size[_sizeComponent] = [view frame].size[_sizeComponent];
|
}
|
||||||
|
|
||||||
|
else if (totalSizableSpace && !isSizable)
|
||||||
|
viewFrame.size[_sizeComponent] = [view frame].size[_sizeComponent];
|
||||||
|
|
||||||
bounds.origin[_originComponent] += viewFrame.size[_sizeComponent] + dividerThickness;
|
bounds.origin[_originComponent] += viewFrame.size[_sizeComponent] + dividerThickness;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,344 @@
|
|||||||
|
/*
|
||||||
|
* CPStepper.j
|
||||||
|
* AppKit
|
||||||
|
*
|
||||||
|
* Created by Antoine Mercadal
|
||||||
|
* Copyright 2009, Antoine Mercadal
|
||||||
|
*
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
@import <AppKit/CPControl.j>
|
||||||
|
@import <AppKit/CPButton.j>
|
||||||
|
@import <AppKit/CPTextField.j>
|
||||||
|
|
||||||
|
|
||||||
|
var CPStepperButtonsSize = CPSizeMake(19, 13);
|
||||||
|
|
||||||
|
/*! CPStepper is an implementation of Cocoa NSStepper.
|
||||||
|
|
||||||
|
This control display a two part button that can be used to increase or decrease a value with a given interval.
|
||||||
|
*/
|
||||||
|
@implementation CPStepper: CPControl
|
||||||
|
{
|
||||||
|
BOOL _valueWraps @accessors(property=valueWraps);
|
||||||
|
int _increment @accessors(property=increment);
|
||||||
|
int _maxValue @accessors(property=maxValue);
|
||||||
|
int _minValue @accessors(property=minValue);
|
||||||
|
|
||||||
|
_CPContinuousButton _buttonDown;
|
||||||
|
_CPContinuousButton _buttonUp;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark Initialization
|
||||||
|
|
||||||
|
/*! Initializes a CPStepper with given values
|
||||||
|
@param aValue the initial value of the CPStepper
|
||||||
|
@param minValue the minimal acceptable value of the stepper
|
||||||
|
@param maxValue the maximal acceptable value of the stepper
|
||||||
|
@return Initialized CPStepper
|
||||||
|
*/
|
||||||
|
+ (CPStepper)stepperWithInitialValue:(float)aValue minValue:(float)aMinValue maxValue:(float)aMaxValue
|
||||||
|
{
|
||||||
|
var stepper = [[CPStepper alloc] initWithFrame:CPRectMake(0, 0, 19, 25)];
|
||||||
|
[stepper setDoubleValue:aValue];
|
||||||
|
[stepper setMinValue:aMinValue];
|
||||||
|
[stepper setMaxValue:aMaxValue];
|
||||||
|
|
||||||
|
return stepper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Initializes a CPStepper with default values:
|
||||||
|
- minValue = 0.0
|
||||||
|
- maxValue = 59.0
|
||||||
|
- value = 0.0
|
||||||
|
@return Initialized CPStepper
|
||||||
|
*/
|
||||||
|
+ (CPStepper)stepper
|
||||||
|
{
|
||||||
|
return [CPStepper stepperWithInitialValue:0.0 minValue:0.0 maxValue:59.0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Initializes the CPStepper
|
||||||
|
@param aFrame the frame of the control
|
||||||
|
@return initialized CPStepper
|
||||||
|
*/
|
||||||
|
- (id)initWithFrame:(CGRect)aFrame
|
||||||
|
{
|
||||||
|
if (self = [super initWithFrame:aFrame])
|
||||||
|
{
|
||||||
|
_maxValue = 59.0;
|
||||||
|
_minValue = 0.0;
|
||||||
|
_increment = 1.0;
|
||||||
|
_valueWraps = YES;
|
||||||
|
|
||||||
|
[self setDoubleValue:0.0];
|
||||||
|
|
||||||
|
_buttonUp = [[_CPContinuousButton alloc] initWithFrame:CPRectMake(aFrame.size.width - CPStepperButtonsSize.width, 0, CPStepperButtonsSize.width, CPStepperButtonsSize.height)];
|
||||||
|
[_buttonUp setContinuous:YES];
|
||||||
|
[_buttonUp setTarget:self];
|
||||||
|
[_buttonUp setAction:@selector(_buttonDidClick:)];
|
||||||
|
[_buttonUp setAutoresizingMask:CPViewNotSizable];
|
||||||
|
[self addSubview:_buttonUp];
|
||||||
|
|
||||||
|
_buttonDown = [[_CPContinuousButton alloc] initWithFrame:CPRectMake(aFrame.size.width - CPStepperButtonsSize.width, CPStepperButtonsSize.height, CPStepperButtonsSize.width, CPStepperButtonsSize.height - 1)];
|
||||||
|
[_buttonDown setContinuous:YES];
|
||||||
|
[_buttonDown setTarget:self];
|
||||||
|
[_buttonDown setAction:@selector(_buttonDidClick:)];
|
||||||
|
[_buttonDown setAutoresizingMask:CPViewNotSizable];
|
||||||
|
[self addSubview:_buttonDown];
|
||||||
|
|
||||||
|
[self setNeedsLayout];
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark Superclass overrides
|
||||||
|
|
||||||
|
/*! set if the CPStepper is enabled or not
|
||||||
|
@param shouldEnabled BOOL that define if stepper is enabled or not.
|
||||||
|
*/
|
||||||
|
- (void)setEnabled:(BOOL)shouldEnabled
|
||||||
|
{
|
||||||
|
[super setEnabled:shouldEnabled];
|
||||||
|
|
||||||
|
[_buttonUp setEnabled:shouldEnabled];
|
||||||
|
[_buttonDown setEnabled:shouldEnabled];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! set the frame of the CPStepper and check if width is not smaller than theme min-size
|
||||||
|
@param aFrame the frame
|
||||||
|
*/
|
||||||
|
- (void)setFrame:(CGRect)aFrame
|
||||||
|
{
|
||||||
|
if (aFrame.size.width >= CGRectGetWidth(aFrame))
|
||||||
|
[super setFrame:aFrame];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! @ignore
|
||||||
|
*/
|
||||||
|
- (void)layoutSubviews
|
||||||
|
{
|
||||||
|
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
|
||||||
|
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered | CPThemeStateDisabled] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateDisabled];
|
||||||
|
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered | CPThemeStateHighlighted] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateHighlighted];
|
||||||
|
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:CPThemeStateBordered] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
|
||||||
|
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:CPThemeStateBordered | CPThemeStateDisabled] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateDisabled];
|
||||||
|
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:CPThemeStateBordered | CPThemeStateHighlighted] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateHighlighted];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! set if CPStepper should autorepeat
|
||||||
|
@param shouldAutoRepeat if YES, the first mouse down does one increment (decrement) and, after each delay of 0.5 seconds
|
||||||
|
*/
|
||||||
|
- (void)setAutorepeat:(BOOL)shouldAutoRepeat
|
||||||
|
{
|
||||||
|
[_buttonUp setContinuous:shouldAutoRepeat];
|
||||||
|
[_buttonDown setContinuous:shouldAutoRepeat];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! set the current value of the stepper
|
||||||
|
@param aValue a float contaning the value
|
||||||
|
*/
|
||||||
|
- (void)setDoubleValue:(float)aValue
|
||||||
|
{
|
||||||
|
if (aValue > _maxValue)
|
||||||
|
[super setDoubleValue:_valueWraps ? _minValue : _maxValue];
|
||||||
|
else if (aValue < _minValue)
|
||||||
|
[super setDoubleValue:_valueWraps ? _maxValue : _minValue];
|
||||||
|
else
|
||||||
|
[super setDoubleValue:aValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark Actions
|
||||||
|
|
||||||
|
/*! @ignore
|
||||||
|
*/
|
||||||
|
- (IBAction)_buttonDidClick:(id)aSender
|
||||||
|
{
|
||||||
|
if (![self isEnabled])
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (aSender == _buttonUp)
|
||||||
|
[self setDoubleValue:([self doubleValue] + _increment)];
|
||||||
|
else
|
||||||
|
[self setDoubleValue:([self doubleValue] - _increment)];
|
||||||
|
|
||||||
|
if (_target && _action && [_target respondsToSelector:_action])
|
||||||
|
[self sendAction:_action to:_target];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! @perform a programatic click on up button
|
||||||
|
@param aSender sender of the action
|
||||||
|
*/
|
||||||
|
- (IBAction)performClickUp:(id)aSender
|
||||||
|
{
|
||||||
|
[_buttonUp performClick:aSender];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! @perform a programatic click on down button
|
||||||
|
@param aSender sender of the action
|
||||||
|
*/
|
||||||
|
- (IBAction)performClickDown:(id)aSender
|
||||||
|
{
|
||||||
|
[_buttonDown performClick:aSender];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark Theming
|
||||||
|
|
||||||
|
+ (CPString)defaultThemeClass
|
||||||
|
{
|
||||||
|
return @"stepper";
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (id)themeAttributes
|
||||||
|
{
|
||||||
|
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null]]
|
||||||
|
forKeys:[@"bezel-color-up-button", @"bezel-color-down-button"]];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@implementation CPStepper (CPCodingCompliance)
|
||||||
|
|
||||||
|
- (id)initWithCoder:(CPCoder)aCoder
|
||||||
|
{
|
||||||
|
if (self = [super initWithCoder:aCoder])
|
||||||
|
{
|
||||||
|
_maxValue = [aCoder decodeObjectForKey:@"_maxValue"];
|
||||||
|
_minValue = [aCoder decodeObjectForKey:@"_minValue"];
|
||||||
|
_increment = [aCoder decodeObjectForKey:@"_increment"];
|
||||||
|
_buttonUp = [aCoder decodeObjectForKey:@"_buttonUp"];
|
||||||
|
_buttonDown = [aCoder decodeObjectForKey:@"_buttonDown"];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)encodeWithCoder:(CPCoder)aCoder
|
||||||
|
{
|
||||||
|
[super encodeWithCoder:aCoder];
|
||||||
|
|
||||||
|
[aCoder encodeObject:_maxValue forKey:@"_maxValue"];
|
||||||
|
[aCoder encodeObject:_minValue forKey:@"_minValue"];
|
||||||
|
[aCoder encodeObject:_increment forKey:@"_increment"];
|
||||||
|
[aCoder encodeObject:_buttonUp forKey:@"_buttonUp"];
|
||||||
|
[aCoder encodeObject:_buttonDown forKey:@"_buttonDown"];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
/*! This is a subclass of CPButton that allows to send continuous action.
|
||||||
|
This may should be include in CPButton..
|
||||||
|
*/
|
||||||
|
@implementation _CPContinuousButton : CPButton
|
||||||
|
{
|
||||||
|
CPTimer _continuousDelayTimer;
|
||||||
|
CPTimer _continuousTimer;
|
||||||
|
float _periodicDelay;
|
||||||
|
float _periodicInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)initWithFrame:(CGRect)aFrame
|
||||||
|
{
|
||||||
|
if (self = [super initWithFrame:aFrame])
|
||||||
|
{
|
||||||
|
_periodicInterval = 0.05;
|
||||||
|
_periodicDelay = 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setPeriodicDelay:(float)aDelay interval:(float)anInterval
|
||||||
|
{
|
||||||
|
_periodicDelay = aDelay;
|
||||||
|
_periodicInterval = anInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mouseDown:(CPEvent)anEvent
|
||||||
|
{
|
||||||
|
if ([self isContinuous])
|
||||||
|
{
|
||||||
|
_continuousDelayTimer = [CPTimer scheduledTimerWithTimeInterval:_periodicDelay callback: function()
|
||||||
|
{
|
||||||
|
if (!_continuousTimer)
|
||||||
|
_continuousTimer = [CPTimer scheduledTimerWithTimeInterval:_periodicInterval target:self selector:@selector(onContinousEvent:) userInfo:anEvent repeats:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
repeats:NO];
|
||||||
|
}
|
||||||
|
|
||||||
|
[super mouseDown:anEvent];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)onContinousEvent:(CPTimer)aTimer
|
||||||
|
{
|
||||||
|
if (_target && _action && [_target respondsToSelector:_action])
|
||||||
|
[_target performSelector:_action withObject:self];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)stopTracking:(CGPoint)lastPoint at:(CGPoint)aPoint mouseIsUp:(BOOL)mouseIsUp
|
||||||
|
{
|
||||||
|
[self invalidateTimers];
|
||||||
|
[super stopTracking:lastPoint at:aPoint mouseIsUp:mouseIsUp];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)invalidateTimers
|
||||||
|
{
|
||||||
|
if (_continuousTimer)
|
||||||
|
{
|
||||||
|
[_continuousTimer invalidate];
|
||||||
|
_continuousTimer = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_continuousDelayTimer)
|
||||||
|
{
|
||||||
|
[_continuousDelayTimer invalidate];
|
||||||
|
_continuousDelayTimer = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@implementation _CPContinuousButton (CPCodingCompliance)
|
||||||
|
|
||||||
|
- (id)initWithCoder:(CPCoder)aCoder
|
||||||
|
{
|
||||||
|
if (self = [super initWithCoder:aCoder])
|
||||||
|
{
|
||||||
|
_periodicDelay = [aCoder decodeObjectForKey:@"_periodicDelay"];
|
||||||
|
_periodicInterval = [aCoder decodeObjectForKey:@"_periodicInterval"];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)encodeWithCoder:(CPCoder)aCoder
|
||||||
|
{
|
||||||
|
[super encodeWithCoder:aCoder];
|
||||||
|
|
||||||
|
[self invalidateTimers];
|
||||||
|
[aCoder encodeObject:_periodicDelay forKey:@"_periodicDelay"];
|
||||||
|
[aCoder encodeObject:_periodicInterval forKey:@"_periodicInterval"];
|
||||||
|
}
|
||||||
|
@end
|
||||||
@@ -3,83 +3,66 @@
|
|||||||
@import "CPTabViewItem.j"
|
@import "CPTabViewItem.j"
|
||||||
@import "CPView.j"
|
@import "CPView.j"
|
||||||
|
|
||||||
/*
|
|
||||||
Places tabs on top with a bezeled border.
|
|
||||||
@global
|
|
||||||
@group CPTabViewType
|
|
||||||
*/
|
|
||||||
CPTopTabsBezelBorder = 0;
|
CPTopTabsBezelBorder = 0;
|
||||||
//CPLeftTabsBezelBorder = 1;
|
//CPLeftTabsBezelBorder = 1;
|
||||||
CPBottomTabsBezelBorder = 2;
|
CPBottomTabsBezelBorder = 2;
|
||||||
//CPRightTabsBezelBorder = 3;
|
//CPRightTabsBezelBorder = 3;
|
||||||
/*
|
CPNoTabsBezelBorder = 4; //Displays no tabs and has a bezeled border.
|
||||||
Displays no tabs and has a bezeled border.
|
CPNoTabsLineBorder = 5; //Has no tabs and displays a line border.
|
||||||
@global
|
CPNoTabsNoBorder = 6; //Displays no tabs and no border.
|
||||||
@group CPTabViewType
|
|
||||||
*/
|
|
||||||
CPNoTabsBezelBorder = 4;
|
|
||||||
/*
|
|
||||||
Has no tabs and displays a line border.
|
|
||||||
@global
|
|
||||||
@group CPTabViewType
|
|
||||||
*/
|
|
||||||
CPNoTabsLineBorder = 5;
|
|
||||||
/*
|
|
||||||
Displays no tabs and no border.
|
|
||||||
@global
|
|
||||||
@group CPTabViewType
|
|
||||||
*/
|
|
||||||
CPNoTabsNoBorder = 6;
|
|
||||||
|
|
||||||
var CPTabViewDidSelectTabViewItemSelector = 1,
|
var CPTabViewDidSelectTabViewItemSelector = 1,
|
||||||
CPTabViewShouldSelectTabViewItemSelector = 2,
|
CPTabViewShouldSelectTabViewItemSelector = 2,
|
||||||
CPTabViewWillSelectTabViewItemSelector = 4,
|
CPTabViewWillSelectTabViewItemSelector = 4,
|
||||||
CPTabViewDidChangeNumberOfTabViewItemsSelector = 8;
|
CPTabViewDidChangeNumberOfTabViewItemsSelector = 8;
|
||||||
|
|
||||||
var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|
||||||
|
|
||||||
@implementation CPTabView : CPView
|
@implementation CPTabView : CPView
|
||||||
{
|
{
|
||||||
CPArray items;
|
CPArray _items;
|
||||||
|
|
||||||
CPSegmentedControl tabs;
|
CPSegmentedControl _tabs;
|
||||||
CPBox box;
|
CPBox _box;
|
||||||
|
|
||||||
CPNumber selectedIndex;
|
CPNumber _selectedIndex;
|
||||||
|
|
||||||
CPTabViewType type;
|
CPTabViewType _type;
|
||||||
|
|
||||||
id delegate;
|
id _delegate;
|
||||||
unsigned delegateSelectors;
|
unsigned _delegateSelectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithFrame:(CGRect)aFrame
|
- (id)initWithFrame:(CGRect)aFrame
|
||||||
{
|
{
|
||||||
self = [super initWithFrame:aFrame];
|
if (self = [super initWithFrame:aFrame])
|
||||||
if (self)
|
|
||||||
{
|
{
|
||||||
items = [CPArray array];
|
_items = [CPArray array];
|
||||||
|
_selectedIndex = CPNotFound;
|
||||||
tabs = [[CPSegmentedControl alloc] initWithFrame:CGRectMake(0, 0, 0, HEIGHT_OF_SEGMENTED_CONTROL)];
|
|
||||||
[tabs setHitTests:NO];
|
|
||||||
|
|
||||||
box = [[CPBox alloc] initWithFrame:CGRectMake(0, HEIGHT_OF_SEGMENTED_CONTROL / 2, CGRectGetWidth(aFrame),
|
|
||||||
CGRectGetHeight(aFrame) - HEIGHT_OF_SEGMENTED_CONTROL)];
|
|
||||||
|
|
||||||
selectedIndex = CPNotFound;
|
|
||||||
|
|
||||||
|
[self _init];
|
||||||
[self setTabViewType:CPTopTabsBezelBorder];
|
[self setTabViewType:CPTopTabsBezelBorder];
|
||||||
[self setBackgroundColor:[CPColor colorWithCalibratedWhite:0.95 alpha:1.0]];
|
|
||||||
|
|
||||||
[self addSubview:box];
|
|
||||||
[self addSubview:tabs];
|
|
||||||
|
|
||||||
[box setAutoresizingMask:CPViewWidthSizable];
|
|
||||||
[tabs setAutoresizingMask:CPViewMinXMargin | CPViewMaxXMargin];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)_init
|
||||||
|
{
|
||||||
|
_tabs = [[CPSegmentedControl alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
|
||||||
|
[_tabs setHitTests:NO];
|
||||||
|
|
||||||
|
var height = [_tabs valueForThemeAttribute:@"default-height"];
|
||||||
|
[_tabs setFrameSize:CGSizeMake(0, height)];
|
||||||
|
|
||||||
|
_box = [[CPBox alloc] initWithFrame:[self bounds]];
|
||||||
|
[self setBackgroundColor:[CPColor colorWithCalibratedWhite:0.95 alpha:1.0]];
|
||||||
|
|
||||||
|
[_box setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
||||||
|
[_tabs setAutoresizingMask:CPViewMinXMargin | CPViewMaxXMargin];
|
||||||
|
|
||||||
|
[self addSubview:_box];
|
||||||
|
[self addSubview:_tabs];
|
||||||
|
}
|
||||||
|
|
||||||
// Adding and Removing Tabs
|
// Adding and Removing Tabs
|
||||||
/*!
|
/*!
|
||||||
Adds a CPTabViewItem to the tab view.
|
Adds a CPTabViewItem to the tab view.
|
||||||
@@ -87,7 +70,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (void)addTabViewItem:(CPTabViewItem)aTabViewItem
|
- (void)addTabViewItem:(CPTabViewItem)aTabViewItem
|
||||||
{
|
{
|
||||||
[self insertTabViewItem:aTabViewItem atIndex:[items count]];
|
[self insertTabViewItem:aTabViewItem atIndex:[_items count]];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -98,13 +81,15 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (void)insertTabViewItem:(CPTabViewItem)aTabViewItem atIndex:(unsigned)anIndex
|
- (void)insertTabViewItem:(CPTabViewItem)aTabViewItem atIndex:(unsigned)anIndex
|
||||||
{
|
{
|
||||||
[items insertObject:aTabViewItem atIndex:anIndex];
|
[_items insertObject:aTabViewItem atIndex:anIndex];
|
||||||
|
|
||||||
[self _updateItems];
|
[self _updateItems];
|
||||||
[self _repositionTabs];
|
[self _repositionTabs];
|
||||||
|
|
||||||
|
[aTabViewItem _setTabView:self];
|
||||||
|
|
||||||
if (delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector)
|
if (_delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector)
|
||||||
[delegate tabViewDidChangeNumberOfTabViewItems:self];
|
[_delegate tabViewDidChangeNumberOfTabViewItems:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -113,19 +98,23 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (void)removeTabViewItem:(CPTabViewItem)aTabViewItem
|
- (void)removeTabViewItem:(CPTabViewItem)aTabViewItem
|
||||||
{
|
{
|
||||||
for (var i = 0; i < [items count]; i++)
|
var count = [_items count];
|
||||||
|
for (var i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if ([items objectAtIndex:i] === aTabViewItem)
|
if ([_items objectAtIndex:i] === aTabViewItem)
|
||||||
{
|
{
|
||||||
[items removeObjectAtIndex:i];
|
[_items removeObjectAtIndex:i];
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[self _updateItems];
|
[self _updateItems];
|
||||||
[self _repositionTabs];
|
[self _repositionTabs];
|
||||||
|
|
||||||
|
[aTabViewItem _setTabView:nil];
|
||||||
|
|
||||||
if (delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector)
|
if (_delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector)
|
||||||
[delegate tabViewDidChangeNumberOfTabViewItems:self];
|
[_delegate tabViewDidChangeNumberOfTabViewItems:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accessing Tabs
|
// Accessing Tabs
|
||||||
@@ -135,7 +124,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (int)indexOfTabViewItem:(CPTabViewItem)aTabViewItem
|
- (int)indexOfTabViewItem:(CPTabViewItem)aTabViewItem
|
||||||
{
|
{
|
||||||
return [items indexOfObjectIdenticalTo:aTabViewItem];
|
return [_items indexOfObjectIdenticalTo:aTabViewItem];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -144,8 +133,8 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (int)indexOfTabViewItemWithIdentifier:(CPString)anIdentifier
|
- (int)indexOfTabViewItemWithIdentifier:(CPString)anIdentifier
|
||||||
{
|
{
|
||||||
for (var index = [items count]; index >= 0; index--)
|
for (var index = [_items count]; index >= 0; index--)
|
||||||
if ([[items[index] identifier] isEqual:anIdentifier])
|
if ([[_items[index] identifier] isEqual:anIdentifier])
|
||||||
return index;
|
return index;
|
||||||
|
|
||||||
return CPNotFound;
|
return CPNotFound;
|
||||||
@@ -156,7 +145,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (unsigned)numberOfTabViewItems
|
- (unsigned)numberOfTabViewItems
|
||||||
{
|
{
|
||||||
return [items count];
|
return [_items count];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -164,7 +153,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (CPTabViewItem)tabViewItemAtIndex:(unsigned)anIndex
|
- (CPTabViewItem)tabViewItemAtIndex:(unsigned)anIndex
|
||||||
{
|
{
|
||||||
return [items objectAtIndex:anIndex];
|
return [_items objectAtIndex:anIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -172,7 +161,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (CPArray)tabViewItems
|
- (CPArray)tabViewItems
|
||||||
{
|
{
|
||||||
return [items copy]; // Copy?
|
return [_items copy]; // Copy?
|
||||||
}
|
}
|
||||||
|
|
||||||
// Selecting a Tab
|
// Selecting a Tab
|
||||||
@@ -182,7 +171,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (void)selectFirstTabViewItem:(id)aSender
|
- (void)selectFirstTabViewItem:(id)aSender
|
||||||
{
|
{
|
||||||
if ([items count] === 0)
|
if ([_items count] === 0)
|
||||||
return; // throw?
|
return; // throw?
|
||||||
|
|
||||||
[self selectTabViewItemAtIndex:0];
|
[self selectTabViewItemAtIndex:0];
|
||||||
@@ -194,10 +183,10 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (void)selectLastTabViewItem:(id)aSender
|
- (void)selectLastTabViewItem:(id)aSender
|
||||||
{
|
{
|
||||||
if ([items count] === 0)
|
if ([_items count] === 0)
|
||||||
return; // throw?
|
return; // throw?
|
||||||
|
|
||||||
[self selectTabViewItemAtIndex:[items count] - 1];
|
[self selectTabViewItemAtIndex:[_items count] - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -206,12 +195,12 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (void)selectNextTabViewItem:(id)aSender
|
- (void)selectNextTabViewItem:(id)aSender
|
||||||
{
|
{
|
||||||
if (selectedIndex === CPNotFound)
|
if (_selectedIndex === CPNotFound)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var nextIndex = selectedIndex + 1;
|
var nextIndex = _selectedIndex + 1;
|
||||||
|
|
||||||
if (nextIndex === [items count])
|
if (nextIndex === [_items count])
|
||||||
// does nothing. According to spec at (http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Reference/ApplicationKit/Classes/NSTabView_Class/Reference/Reference.html#//apple_ref/occ/instm/NSTabView/selectNextTabViewItem:)
|
// does nothing. According to spec at (http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Reference/ApplicationKit/Classes/NSTabView_Class/Reference/Reference.html#//apple_ref/occ/instm/NSTabView/selectNextTabViewItem:)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -224,10 +213,10 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (void)selectPreviousTabViewItem:(id)aSender
|
- (void)selectPreviousTabViewItem:(id)aSender
|
||||||
{
|
{
|
||||||
if (selectedIndex === CPNotFound)
|
if (_selectedIndex === CPNotFound)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var previousIndex = selectedIndex - 1;
|
var previousIndex = _selectedIndex - 1;
|
||||||
|
|
||||||
if (previousIndex < 0)
|
if (previousIndex < 0)
|
||||||
return; // does nothing. See above.
|
return; // does nothing. See above.
|
||||||
@@ -250,24 +239,24 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (void)selectTabViewItemAtIndex:(unsigned)anIndex
|
- (void)selectTabViewItemAtIndex:(unsigned)anIndex
|
||||||
{
|
{
|
||||||
var aTabViewItem = [items objectAtIndex:anIndex];
|
var aTabViewItem = [_items objectAtIndex:anIndex];
|
||||||
|
|
||||||
if (anIndex === selectedIndex)
|
if (anIndex === _selectedIndex)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var aTabViewItem = [self tabViewItemAtIndex:anIndex];
|
var aTabViewItem = [self tabViewItemAtIndex:anIndex];
|
||||||
|
|
||||||
if ((delegateSelectors & CPTabViewShouldSelectTabViewItemSelector) && ![delegate tabView:self shouldSelectTabViewItem:aTabViewItem])
|
if ((_delegateSelectors & CPTabViewShouldSelectTabViewItemSelector) && ![_delegate tabView:self shouldSelectTabViewItem:aTabViewItem])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (delegateSelectors & CPTabViewWillSelectTabViewItemSelector)
|
if (_delegateSelectors & CPTabViewWillSelectTabViewItemSelector)
|
||||||
[delegate tabView:self willSelectTabViewItem:aTabViewItem];
|
[_delegate tabView:self willSelectTabViewItem:aTabViewItem];
|
||||||
|
|
||||||
[tabs selectSegmentWithTag:anIndex];
|
[_tabs selectSegmentWithTag:anIndex];
|
||||||
[self _setSelectedIndex:anIndex];
|
[self _setSelectedIndex:anIndex];
|
||||||
|
|
||||||
if (delegateSelectors & CPTabViewDidSelectTabViewItemSelector)
|
if (_delegateSelectors & CPTabViewDidSelectTabViewItemSelector)
|
||||||
[delegate tabView:self didSelectTabViewItem:aTabViewItem];
|
[_delegate tabView:self didSelectTabViewItem:aTabViewItem];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -275,7 +264,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (CPTabViewItem)selectedTabViewItem
|
- (CPTabViewItem)selectedTabViewItem
|
||||||
{
|
{
|
||||||
return [items objectAtIndex:selectedIndex];
|
return [_items objectAtIndex:_selectedIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -285,31 +274,40 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (void)setTabViewType:(CPTabViewType)aTabViewType
|
- (void)setTabViewType:(CPTabViewType)aTabViewType
|
||||||
{
|
{
|
||||||
if (type === aTabViewType)
|
if (_type === aTabViewType)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((type === CPTopTabsBezelBorder || type === CPBottomTabsBezelBorder)
|
_type = aTabViewType;
|
||||||
&& (aTabViewType !== CPTopTabsBezelBorder && aTabViewType !== CPBottomTabsBezelBorder))
|
|
||||||
[tabs removeFromSuperview];
|
|
||||||
|
|
||||||
if ((type === CPNoTabsBezelBorder || type === CPNoTabsLineBorder || type === CPNoTabsNoBorder)
|
if (_type !== CPTopTabsBezelBorder && _type !== CPBottomTabsBezelBorder)
|
||||||
&& (aTabViewType !== CPNoTabsBezelBorder && aTabViewType !== CPNoTabsBezelBorder && aTabViewType !== CPNoTabsNoBorder))
|
{
|
||||||
[self addSubview:tabs];
|
[_box setFrame:[self bounds]];
|
||||||
|
[_tabs removeFromSuperview];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var aFrame = [self frame],
|
||||||
|
segmentedHeight = CGRectGetHeight([_tabs frame]),
|
||||||
|
origin = _type === CPTopTabsBezelBorder ? segmentedHeight / 2 : 0;
|
||||||
|
|
||||||
type = aTabViewType;
|
[_box setFrame:CGRectMake(0, origin, CGRectGetWidth(aFrame),
|
||||||
|
CGRectGetHeight(aFrame) - segmentedHeight / 2)];
|
||||||
|
|
||||||
switch (type)
|
[self addSubview:_tabs];
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (_type)
|
||||||
{
|
{
|
||||||
case CPTopTabsBezelBorder:
|
case CPTopTabsBezelBorder:
|
||||||
case CPBottomTabsBezelBorder:
|
case CPBottomTabsBezelBorder:
|
||||||
case CPNoTabsBezelBorder:
|
case CPNoTabsBezelBorder:
|
||||||
[box setBorderType:CPBezelBorder];
|
[_box setBorderType:CPBezelBorder];
|
||||||
break;
|
break;
|
||||||
case CPNoTabsLineBorder:
|
case CPNoTabsLineBorder:
|
||||||
[box setBorderType:CPLineBorder];
|
[_box setBorderType:CPLineBorder];
|
||||||
break;
|
break;
|
||||||
case CPNoTabsNoBorder:
|
case CPNoTabsNoBorder:
|
||||||
[box setBorderType:CPNoBorder];
|
[_box setBorderType:CPNoBorder];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -319,7 +317,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (CPTabViewType)tabViewType
|
- (CPTabViewType)tabViewType
|
||||||
{
|
{
|
||||||
return type;
|
return _type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -327,7 +325,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (id)delegate
|
- (id)delegate
|
||||||
{
|
{
|
||||||
return delegate;
|
return _delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -336,71 +334,77 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24;
|
|||||||
*/
|
*/
|
||||||
- (void)setDelegate:(id)aDelegate
|
- (void)setDelegate:(id)aDelegate
|
||||||
{
|
{
|
||||||
if (delegate == aDelegate)
|
if (_delegate == aDelegate)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
delegate = aDelegate;
|
_delegate = aDelegate;
|
||||||
|
|
||||||
delegateSelectors = 0;
|
_delegateSelectors = 0;
|
||||||
|
|
||||||
if ([delegate respondsToSelector:@selector(tabView:shouldSelectTabViewItem:)])
|
if ([_delegate respondsToSelector:@selector(tabView:shouldSelectTabViewItem:)])
|
||||||
delegateSelectors |= CPTabViewShouldSelectTabViewItemSelector;
|
_delegateSelectors |= CPTabViewShouldSelectTabViewItemSelector;
|
||||||
|
|
||||||
if ([delegate respondsToSelector:@selector(tabView:willSelectTabViewItem:)])
|
if ([_delegate respondsToSelector:@selector(tabView:willSelectTabViewItem:)])
|
||||||
delegateSelectors |= CPTabViewWillSelectTabViewItemSelector;
|
_delegateSelectors |= CPTabViewWillSelectTabViewItemSelector;
|
||||||
|
|
||||||
if ([delegate respondsToSelector:@selector(tabView:didSelectTabViewItem:)])
|
if ([_delegate respondsToSelector:@selector(tabView:didSelectTabViewItem:)])
|
||||||
delegateSelectors |= CPTabViewDidSelectTabViewItemSelector;
|
_delegateSelectors |= CPTabViewDidSelectTabViewItemSelector;
|
||||||
|
|
||||||
if ([delegate respondsToSelector:@selector(tabViewDidChangeNumberOfTabViewItems:)])
|
if ([_delegate respondsToSelector:@selector(tabViewDidChangeNumberOfTabViewItems:)])
|
||||||
delegateSelectors |= CPTabViewDidChangeNumberOfTabViewItemsSelector;
|
_delegateSelectors |= CPTabViewDidChangeNumberOfTabViewItemsSelector;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setBackgroundColor:(CPColor)aColor
|
- (void)setBackgroundColor:(CPColor)aColor
|
||||||
{
|
{
|
||||||
[box setBackgroundColor:aColor];
|
[_box setBackgroundColor:aColor];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CPColor)backgroundColor
|
||||||
|
{
|
||||||
|
return [_box backgroundColor];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)mouseDown:(CPEvent)anEvent
|
- (void)mouseDown:(CPEvent)anEvent
|
||||||
{
|
{
|
||||||
var segmentIndex = [tabs testSegment:[tabs convertPoint:[anEvent locationInWindow] fromView:nil]];
|
var segmentIndex = [_tabs testSegment:[_tabs convertPoint:[anEvent locationInWindow] fromView:nil]];
|
||||||
|
|
||||||
if (segmentIndex != CPNotFound)
|
if (segmentIndex != CPNotFound)
|
||||||
{
|
{
|
||||||
[self selectTabViewItemAtIndex:segmentIndex];
|
[self selectTabViewItemAtIndex:segmentIndex];
|
||||||
[tabs trackSegment:anEvent];
|
[_tabs trackSegment:anEvent];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_repositionTabs
|
- (void)_repositionTabs
|
||||||
{
|
{
|
||||||
var horizontalCenterOfSelf = CGRectGetWidth([self bounds]) / 2,
|
var horizontalCenterOfSelf = CGRectGetWidth([self bounds]) / 2,
|
||||||
verticalCenterOfTabs = CGRectGetHeight([tabs bounds]) / 2;
|
verticalCenterOfTabs = CGRectGetHeight([_tabs bounds]) / 2;
|
||||||
|
|
||||||
if (type === CPBottomTabsBezelBorder)
|
if (_type === CPBottomTabsBezelBorder)
|
||||||
[tabs setCenter:CGPointMake(horizontalCenterOfSelf, CGRectGetHeight([self bounds]) - verticalCenterOfTabs)];
|
[_tabs setCenter:CGPointMake(horizontalCenterOfSelf, CGRectGetHeight([self bounds]) - verticalCenterOfTabs)];
|
||||||
else
|
else
|
||||||
[tabs setCenter:CGPointMake(horizontalCenterOfSelf, verticalCenterOfTabs)];
|
[_tabs setCenter:CGPointMake(horizontalCenterOfSelf, verticalCenterOfTabs)];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_setSelectedIndex:(CPNumber)index
|
- (void)_setSelectedIndex:(CPNumber)index
|
||||||
{
|
{
|
||||||
selectedIndex = index;
|
_selectedIndex = index;
|
||||||
|
|
||||||
[box setContentView:[[items objectAtIndex:selectedIndex] view]];
|
[_box setContentView:[[_items objectAtIndex:_selectedIndex] view]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_updateItems
|
- (void)_updateItems
|
||||||
{
|
{
|
||||||
[tabs setSegmentCount:[items count]];
|
var count = [_items count];
|
||||||
|
[_tabs setSegmentCount:count];
|
||||||
|
|
||||||
for (var i = 0; i < [items count]; i++)
|
for (var i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
[tabs setLabel:[[items objectAtIndex:i] label] forSegment:i];
|
[_tabs setLabel:[[_items objectAtIndex:i] label] forSegment:i];
|
||||||
[tabs setTag:i forSegment:i];
|
[_tabs setTag:i forSegment:i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedIndex === CPNotFound)
|
if (_selectedIndex === CPNotFound)
|
||||||
{
|
{
|
||||||
[self selectFirstTabViewItem:self];
|
[self selectFirstTabViewItem:self];
|
||||||
}
|
}
|
||||||
@@ -419,18 +423,20 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
|
|||||||
{
|
{
|
||||||
if (self = [super initWithCoder:aCoder])
|
if (self = [super initWithCoder:aCoder])
|
||||||
{
|
{
|
||||||
type = [aCoder decodeIntForKey:CPTabViewTypeKey];
|
[self _init];
|
||||||
items = [];
|
|
||||||
|
|
||||||
var encodedItems = [aCoder decodeObjectForKey:CPTabViewItemsKey];
|
_items = [aCoder decodeObjectForKey:CPTabViewItemsKey];
|
||||||
for (var i = 0; encodedItems && i < encodedItems.length; i++)
|
|
||||||
[self insertTabViewItem:encodedItems[i] atIndex:i];
|
[self _updateItems];
|
||||||
|
[self _repositionTabs];
|
||||||
|
|
||||||
var selected = [aCoder decodeObjectForKey:CPTabViewSelectedItemKey];
|
var selected = [aCoder decodeObjectForKey:CPTabViewSelectedItemKey];
|
||||||
if (selected)
|
if (selected)
|
||||||
[self selectTabViewItem:selected];
|
[self selectTabViewItem:selected];
|
||||||
|
|
||||||
[self setDelegate:[aCoder decodeObjectForKey:CPTabViewDelegateKey]];
|
[self setDelegate:[aCoder decodeObjectForKey:CPTabViewDelegateKey]];
|
||||||
|
|
||||||
|
[self setTabViewType:[aCoder decodeIntForKey:CPTabViewTypeKey]];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
@@ -440,12 +446,12 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
|
|||||||
{
|
{
|
||||||
[super encodeWithCoder:aCoder];
|
[super encodeWithCoder:aCoder];
|
||||||
|
|
||||||
[aCoder encodeObject:items forKey:CPTabViewItemsKey];;
|
[aCoder encodeObject:_items forKey:CPTabViewItemsKey];
|
||||||
[aCoder encodeObject:[self selectedTabViewItem] forKey:CPTabViewSelectedItemKey];
|
[aCoder encodeObject:[self selectedTabViewItem] forKey:CPTabViewSelectedItemKey];
|
||||||
|
|
||||||
[aCoder encodeInt:type forKey:CPTabViewTypeKey];
|
[aCoder encodeInt:_type forKey:CPTabViewTypeKey];
|
||||||
|
|
||||||
[aCoder encodeConditionalObject:delegate forKey:CPTabViewDelegateKey];
|
[aCoder encodeConditionalObject:_delegate forKey:CPTabViewDelegateKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ CPBackgroundTab = 1;
|
|||||||
*/
|
*/
|
||||||
CPPressedTab = 2;
|
CPPressedTab = 2;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
@class CPTabViewItem
|
@class CPTabViewItem
|
||||||
|
|
||||||
@@ -55,10 +55,10 @@ CPPressedTab = 2;
|
|||||||
{
|
{
|
||||||
id _identifier;
|
id _identifier;
|
||||||
CPString _label;
|
CPString _label;
|
||||||
|
|
||||||
CPView _view;
|
CPView _view;
|
||||||
CPView _auxiliaryView;
|
CPView _auxiliaryView;
|
||||||
|
|
||||||
CPTabView _tabView;
|
CPTabView _tabView;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,10 +74,10 @@ CPPressedTab = 2;
|
|||||||
- (id)initWithIdentifier:(id)anIdentifier
|
- (id)initWithIdentifier:(id)anIdentifier
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
_identifier = anIdentifier;
|
_identifier = anIdentifier;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,16 +191,16 @@ var CPTabViewItemIdentifierKey = "CPTabViewItemIdentifierKey",
|
|||||||
- (id)initWithCoder:(CPCoder)aCoder
|
- (id)initWithCoder:(CPCoder)aCoder
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
_identifier = [aCoder decodeObjectForKey:CPTabViewItemIdentifierKey];
|
_identifier = [aCoder decodeObjectForKey:CPTabViewItemIdentifierKey];
|
||||||
_label = [aCoder decodeObjectForKey:CPTabViewItemLabelKey];
|
_label = [aCoder decodeObjectForKey:CPTabViewItemLabelKey];
|
||||||
|
|
||||||
_view = [aCoder decodeObjectForKey:CPTabViewItemViewKey];
|
_view = [aCoder decodeObjectForKey:CPTabViewItemViewKey];
|
||||||
_auxiliaryView = [aCoder decodeObjectForKey:CPTabViewItemAuxViewKey];
|
_auxiliaryView = [aCoder decodeObjectForKey:CPTabViewItemAuxViewKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,7 +208,7 @@ var CPTabViewItemIdentifierKey = "CPTabViewItemIdentifierKey",
|
|||||||
{
|
{
|
||||||
[aCoder encodeObject:_identifier forKey:CPTabViewItemIdentifierKey];
|
[aCoder encodeObject:_identifier forKey:CPTabViewItemIdentifierKey];
|
||||||
[aCoder encodeObject:_label forKey:CPTabViewItemLabelKey];
|
[aCoder encodeObject:_label forKey:CPTabViewItemLabelKey];
|
||||||
|
|
||||||
[aCoder encodeObject:_view forKey:CPTabViewItemViewKey];
|
[aCoder encodeObject:_view forKey:CPTabViewItemViewKey];
|
||||||
[aCoder encodeObject:_auxiliaryView forKey:CPTabViewItemAuxViewKey];
|
[aCoder encodeObject:_auxiliaryView forKey:CPTabViewItemAuxViewKey];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,14 @@ CPTableColumnNoResizing = 0;
|
|||||||
CPTableColumnAutoresizingMask = 1 << 0;
|
CPTableColumnAutoresizingMask = 1 << 0;
|
||||||
CPTableColumnUserResizingMask = 1 << 1;
|
CPTableColumnUserResizingMask = 1 << 1;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@class CPTableColumn
|
||||||
|
|
||||||
|
A CPTableColumn contains a dataview to display for its column of the CPTableView.
|
||||||
|
A CPTableColumn determines its own size constrains and resizing behaviour.
|
||||||
|
|
||||||
|
The default dataview is a CPTextField but you can set it to any view you'd like. See -setDataView:
|
||||||
|
*/
|
||||||
@implementation CPTableColumn : CPObject
|
@implementation CPTableColumn : CPObject
|
||||||
{
|
{
|
||||||
CPTableView _tableView;
|
CPTableView _tableView;
|
||||||
@@ -54,11 +62,23 @@ CPTableColumnUserResizingMask = 1 << 1;
|
|||||||
BOOL _disableResizingPosting @accessors(property=disableResizingPosting);
|
BOOL _disableResizingPosting @accessors(property=disableResizingPosting);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (Class)_binderClassForBinding:(CPString)theBinding
|
||||||
|
{
|
||||||
|
return [CPBinder class];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
- (id)init
|
- (id)init
|
||||||
{
|
{
|
||||||
return [self initWithIdentifier:@""];
|
return [self initWithIdentifier:@""];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Initializes a newly created CPTableColumn with a given identifier.
|
||||||
|
|
||||||
|
*/
|
||||||
- (id)initWithIdentifier:(id)anIdentifier
|
- (id)initWithIdentifier:(id)anIdentifier
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
@@ -84,17 +104,50 @@ CPTableColumnUserResizingMask = 1 << 1;
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Set the columns's parent tableview
|
||||||
|
*/
|
||||||
- (void)setTableView:(CPTableView)aTableView
|
- (void)setTableView:(CPTableView)aTableView
|
||||||
{
|
{
|
||||||
_tableView = aTableView;
|
_tableView = aTableView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Return the column's parent tableview
|
||||||
|
*/
|
||||||
- (CPTableView)tableView
|
- (CPTableView)tableView
|
||||||
{
|
{
|
||||||
return _tableView;
|
return _tableView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
this method tries to resize a column called via the tableview via autoresizing
|
||||||
|
it returns the delta from the actual resize and the proposed resize
|
||||||
|
|
||||||
|
for example if the column should have been resized 50px but the maxWidth was hit only
|
||||||
|
after 25px then the return value would be 25px;
|
||||||
|
|
||||||
|
if no edge has been hit zero will be returned
|
||||||
|
*/
|
||||||
|
- (int)_tryToResizeToWidth:(int)width
|
||||||
|
{
|
||||||
|
var min = [self minWidth],
|
||||||
|
max = [self maxWidth],
|
||||||
|
newWidth = MIN(MAX(width, min), max);
|
||||||
|
|
||||||
|
[self setWidth:newWidth];
|
||||||
|
|
||||||
|
return newWidth - width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Set the width of the column
|
||||||
|
Default value is: 100
|
||||||
|
|
||||||
|
If the value is greater than the maxWidth the maxWidth will be reset with the supplied width here
|
||||||
|
If the value is less than the minWidth the minWidth will be reset with the supplied width.
|
||||||
|
*/
|
||||||
- (void)setWidth:(float)aWidth
|
- (void)setWidth:(float)aWidth
|
||||||
{
|
{
|
||||||
aWidth = +aWidth;
|
aWidth = +aWidth;
|
||||||
@@ -135,11 +188,18 @@ CPTableColumnUserResizingMask = 1 << 1;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the column's width
|
||||||
|
*/
|
||||||
- (float)width
|
- (float)width
|
||||||
{
|
{
|
||||||
return _width;
|
return _width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the minimum width of the column.
|
||||||
|
Default value is 10.
|
||||||
|
*/
|
||||||
- (void)setMinWidth:(float)aMinWidth
|
- (void)setMinWidth:(float)aMinWidth
|
||||||
{
|
{
|
||||||
aMinWidth = +aMinWidth;
|
aMinWidth = +aMinWidth;
|
||||||
@@ -156,11 +216,18 @@ CPTableColumnUserResizingMask = 1 << 1;
|
|||||||
[self setWidth:newWidth];
|
[self setWidth:newWidth];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the minimum width of the column.
|
||||||
|
*/
|
||||||
- (float)minWidth
|
- (float)minWidth
|
||||||
{
|
{
|
||||||
return _minWidth;
|
return _minWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the maximum width of the table column.
|
||||||
|
Default value is: 1000000
|
||||||
|
*/
|
||||||
- (void)setMaxWidth:(float)aMaxWidth
|
- (void)setMaxWidth:(float)aMaxWidth
|
||||||
{
|
{
|
||||||
aMaxWidth = +aMaxWidth;
|
aMaxWidth = +aMaxWidth;
|
||||||
@@ -177,21 +244,40 @@ CPTableColumnUserResizingMask = 1 << 1;
|
|||||||
[self setWidth:newWidth];
|
[self setWidth:newWidth];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the maximum width of the column
|
||||||
|
*/
|
||||||
- (float)maxWidth
|
- (float)maxWidth
|
||||||
{
|
{
|
||||||
return _maxWidth;
|
return _maxWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Set the resizing mask of the column.
|
||||||
|
By default the column can be resized automatically with the tableview and manaully by the user
|
||||||
|
|
||||||
|
Possible masking values are:
|
||||||
|
CPTableColumnNoResizing
|
||||||
|
CPTableColumnAutoresizingMask
|
||||||
|
CPTableColumnUserResizingMask
|
||||||
|
*/
|
||||||
- (void)setResizingMask:(unsigned)aResizingMask
|
- (void)setResizingMask:(unsigned)aResizingMask
|
||||||
{
|
{
|
||||||
_resizingMask = aResizingMask;
|
_resizingMask = aResizingMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the resizing mask of the column
|
||||||
|
*/
|
||||||
- (unsigned)resizingMask
|
- (unsigned)resizingMask
|
||||||
{
|
{
|
||||||
return _resizingMask;
|
return _resizingMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sizes the column to fix the column header text.
|
||||||
|
*/
|
||||||
- (void)sizeToFit
|
- (void)sizeToFit
|
||||||
{
|
{
|
||||||
var width = _CGRectGetWidth([_headerView frame]);
|
var width = _CGRectGetWidth([_headerView frame]);
|
||||||
@@ -205,7 +291,11 @@ CPTableColumnUserResizingMask = 1 << 1;
|
|||||||
[self setWidth:width];
|
[self setWidth:width];
|
||||||
}
|
}
|
||||||
|
|
||||||
//Setting Component Cells
|
|
||||||
|
/*!
|
||||||
|
Sets the header view for the column.
|
||||||
|
The headerview handles the display of sort indicators, text, etc
|
||||||
|
*/
|
||||||
- (void)setHeaderView:(CPView)aView
|
- (void)setHeaderView:(CPView)aView
|
||||||
{
|
{
|
||||||
if (!aView)
|
if (!aView)
|
||||||
@@ -219,13 +309,16 @@ CPTableColumnUserResizingMask = 1 << 1;
|
|||||||
[tableHeaderView setNeedsDisplay:YES];
|
[tableHeaderView setNeedsDisplay:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the headerview for the column
|
||||||
|
*/
|
||||||
- (CPView)headerView
|
- (CPView)headerView
|
||||||
{
|
{
|
||||||
return _headerView;
|
return _headerView;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
This method set's the "prototype" view which will be used to create all table cells in this column.
|
This method sets the "prototype" view which will be used to create all table cells in this column.
|
||||||
|
|
||||||
It creates a snapshot of aView, using keyed archiving, which is then copied over and over for each
|
It creates a snapshot of aView, using keyed archiving, which is then copied over and over for each
|
||||||
individual cell that is shown. As a result, changes made after calling this method won't be reflected.
|
individual cell that is shown. As a result, changes made after calling this method won't be reflected.
|
||||||
@@ -239,6 +332,8 @@ CPTableColumnUserResizingMask = 1 << 1;
|
|||||||
|
|
||||||
[someView setSomething:x];
|
[someView setSomething:x];
|
||||||
[tableColumn setDataView:someView];
|
[tableColumn setDataView:someView];
|
||||||
|
|
||||||
|
REMEMBER: you should implement CPKeyedArchiving otherwise you might see unexpected results
|
||||||
*/
|
*/
|
||||||
- (void)setDataView:(CPView)aView
|
- (void)setDataView:(CPView)aView
|
||||||
{
|
{
|
||||||
@@ -269,6 +364,9 @@ CPTableColumnUserResizingMask = 1 << 1;
|
|||||||
return [self dataView];
|
return [self dataView];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
- (id)_newDataViewForRow:(int)aRowIndex
|
- (id)_newDataViewForRow:(int)aRowIndex
|
||||||
{
|
{
|
||||||
var dataView = [self dataViewForRow:aRowIndex],
|
var dataView = [self dataViewForRow:aRowIndex],
|
||||||
@@ -329,19 +427,26 @@ CPTableColumnUserResizingMask = 1 << 1;
|
|||||||
return _isEditable;
|
return _isEditable;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Sorting
|
/*!
|
||||||
|
Sets the sort descriptor prototype for the column.
|
||||||
|
*/
|
||||||
- (void)setSortDescriptorPrototype:(CPSortDescriptor)aSortDescriptor
|
- (void)setSortDescriptorPrototype:(CPSortDescriptor)aSortDescriptor
|
||||||
{
|
{
|
||||||
_sortDescriptorPrototype = aSortDescriptor;
|
_sortDescriptorPrototype = aSortDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the sort descriptor prototype for the column.
|
||||||
|
*/
|
||||||
- (CPSortDescriptor)sortDescriptorPrototype
|
- (CPSortDescriptor)sortDescriptorPrototype
|
||||||
{
|
{
|
||||||
return _sortDescriptorPrototype;
|
return _sortDescriptorPrototype;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Setting Column Visibility
|
/*!
|
||||||
|
If NO the tablecolumn will no longer be visisble in the tableview
|
||||||
|
If YES the tablecolumn will be visible in the tableview.
|
||||||
|
*/
|
||||||
- (void)setHidden:(BOOL)shouldBeHidden
|
- (void)setHidden:(BOOL)shouldBeHidden
|
||||||
{
|
{
|
||||||
shouldBeHidden = !!shouldBeHidden
|
shouldBeHidden = !!shouldBeHidden
|
||||||
@@ -354,6 +459,9 @@ CPTableColumnUserResizingMask = 1 << 1;
|
|||||||
[[self tableView] _tableColumnVisibilityDidChange:self];
|
[[self tableView] _tableColumnVisibilityDidChange:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the visibility status of the column.
|
||||||
|
*/
|
||||||
- (BOOL)isHidden
|
- (BOOL)isHidden
|
||||||
{
|
{
|
||||||
return _isHidden;
|
return _isHidden;
|
||||||
@@ -370,13 +478,21 @@ CPTableColumnUserResizingMask = 1 << 1;
|
|||||||
_headerToolTip = aToolTip;
|
_headerToolTip = aToolTip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the tooltip for the column header
|
||||||
|
*/
|
||||||
- (CPString)headerToolTip
|
- (CPString)headerToolTip
|
||||||
{
|
{
|
||||||
return _headerToolTip;
|
return _headerToolTip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
- (void)_postDidResizeNotificationWithOldWidth:(float)oldWidth
|
- (void)_postDidResizeNotificationWithOldWidth:(float)oldWidth
|
||||||
{
|
{
|
||||||
|
[[self tableView] _didResizeTableColumn:self];
|
||||||
|
|
||||||
[[CPNotificationCenter defaultCenter]
|
[[CPNotificationCenter defaultCenter]
|
||||||
postNotificationName:CPTableViewColumnDidResizeNotification
|
postNotificationName:CPTableViewColumnDidResizeNotification
|
||||||
object:[self tableView]
|
object:[self tableView]
|
||||||
@@ -386,7 +502,6 @@ CPTableColumnUserResizingMask = 1 << 1;
|
|||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation CPTableColumn (Bindings)
|
@implementation CPTableColumn (Bindings)
|
||||||
|
|
||||||
- (void)bind:(CPString)aBinding toObject:(id)anObject withKeyPath:(CPString)aKeyPath options:(CPDictionary)options
|
- (void)bind:(CPString)aBinding toObject:(id)anObject withKeyPath:(CPString)aKeyPath options:(CPDictionary)options
|
||||||
{
|
{
|
||||||
[super bind:aBinding toObject:anObject withKeyPath:aKeyPath options:options];
|
[super bind:aBinding toObject:anObject withKeyPath:aKeyPath options:options];
|
||||||
@@ -397,7 +512,7 @@ CPTableColumnUserResizingMask = 1 << 1;
|
|||||||
|
|
||||||
- (void)prepareDataView:(CPView)aDataView forRow:(unsigned)aRow
|
- (void)prepareDataView:(CPView)aDataView forRow:(unsigned)aRow
|
||||||
{
|
{
|
||||||
var bindingsDictionary = [CPKeyValueBinding allBindingsForObject:self],
|
var bindingsDictionary = [CPBinder allBindingsForObject:self],
|
||||||
keys = [bindingsDictionary allKeys];
|
keys = [bindingsDictionary allKeys];
|
||||||
|
|
||||||
for (var i = 0, count = [keys count]; i < count; i++)
|
for (var i = 0, count = [keys count]; i < count; i++)
|
||||||
@@ -437,9 +552,7 @@ CPTableColumnUserResizingMask = 1 << 1;
|
|||||||
}
|
}
|
||||||
|
|
||||||
value = [binding transformValue:value withOptions:[bindingInfo objectForKey:CPOptionsKey]];
|
value = [binding transformValue:value withOptions:[bindingInfo objectForKey:CPOptionsKey]];
|
||||||
|
[aDataView setValue:value forKey:@"objectValue"];
|
||||||
// console.log(bindingName+" : "+keyPath+" : "+aRow+" : "+[[destination valueForKeyPath:keyPath] objectAtIndex:aRow]);
|
|
||||||
[aDataView setValue:value forKey:bindingPath];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -520,25 +633,25 @@ var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
|
|||||||
- (void)setHeaderCell:(CPView)aView
|
- (void)setHeaderCell:(CPView)aView
|
||||||
{
|
{
|
||||||
[CPException raise:CPUnsupportedMethodException
|
[CPException raise:CPUnsupportedMethodException
|
||||||
reason:@"setHeaderCell: is not supported. -setHeaderCell:aView instead."];
|
reason:@"setHeaderCell: is not supported. Use -setHeaderView:aView instead."];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CPView)headerCell
|
- (CPView)headerCell
|
||||||
{
|
{
|
||||||
[CPException raise:CPUnsupportedMethodException
|
[CPException raise:CPUnsupportedMethodException
|
||||||
reason:@"headCell is not supported. -headerView instead."];
|
reason:@"headCell is not supported. Use -headerView instead."];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setDataCell:(CPView)aView
|
- (void)setDataCell:(CPView)aView
|
||||||
{
|
{
|
||||||
[CPException raise:CPUnsupportedMethodException
|
[CPException raise:CPUnsupportedMethodException
|
||||||
reason:@"setDataCell: is not supported. Use -setHeaderCell:aView instead."];
|
reason:@"setDataCell: is not supported. Use -setDataView:aView instead."];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CPView)dataCell
|
- (CPView)dataCell
|
||||||
{
|
{
|
||||||
[CPException raise:CPUnsupportedMethodException
|
[CPException raise:CPUnsupportedMethodException
|
||||||
reason:@"dataCell is not supported. Use -dataCell instead."];
|
reason:@"dataCell is not supported. Use -dataView instead."];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)dataCellForRow:(int)row
|
- (id)dataCellForRow:(int)row
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
{
|
{
|
||||||
_textField = [[_CPImageAndTextView alloc] initWithFrame:_CGRectMakeZero()];
|
_textField = [[_CPImageAndTextView alloc] initWithFrame:_CGRectMakeZero()];
|
||||||
|
|
||||||
[_textField setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable];
|
[_textField setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
||||||
|
|
||||||
[_textField setLineBreakMode:CPLineBreakByTruncatingTail];
|
[_textField setLineBreakMode:CPLineBreakByTruncatingTail];
|
||||||
[_textField setAlignment:CPLeftTextAlignment];
|
[_textField setAlignment:CPLeftTextAlignment];
|
||||||
@@ -102,20 +102,20 @@
|
|||||||
|
|
||||||
- (void)setFont:(CPFont)aFont
|
- (void)setFont:(CPFont)aFont
|
||||||
{
|
{
|
||||||
[_textField setFont:aFont];
|
[self setValue:aFont forThemeAttribute:"text-font"];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_setIndicatorImage:(CPImage)anImage
|
- (void)_setIndicatorImage:(CPImage)anImage
|
||||||
{
|
{
|
||||||
if (anImage)
|
if (anImage)
|
||||||
{
|
{
|
||||||
[_textField setImage:anImage];
|
[_textField setImage:anImage];
|
||||||
[_textField setImagePosition:CPImageRight];
|
[_textField setImagePosition:CPImageRight];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
[_textField setImagePosition:CPNoImage];
|
[_textField setImagePosition:CPNoImage];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -634,7 +634,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
|||||||
columnMaxX;
|
columnMaxX;
|
||||||
|
|
||||||
CGContextBeginPath(context);
|
CGContextBeginPath(context);
|
||||||
for(; columnArrayIndex < columnArrayCount; columnArrayIndex++)
|
for (; columnArrayIndex < columnArrayCount; columnArrayIndex++)
|
||||||
{
|
{
|
||||||
// grab each column rect and add vertical lines
|
// grab each column rect and add vertical lines
|
||||||
var columnIndex = columnsArray[columnArrayIndex],
|
var columnIndex = columnsArray[columnArrayIndex],
|
||||||
@@ -669,7 +669,15 @@ var CPTableHeaderViewTableViewKey = @"CPTableHeaderViewTableViewKey",
|
|||||||
{
|
{
|
||||||
[self _init];
|
[self _init];
|
||||||
_tableView = [aCoder decodeObjectForKey:CPTableHeaderViewTableViewKey];
|
_tableView = [aCoder decodeObjectForKey:CPTableHeaderViewTableViewKey];
|
||||||
_drawsColumnLines = [aCoder decodeBoolForKey:CPTableHeaderViewDrawsColumnLines];
|
|
||||||
|
// FIX ME: Take this out before 1.0
|
||||||
|
if ([aCoder containsValueForKey:CPTableHeaderViewDrawsColumnLines])
|
||||||
|
_drawsColumnLines = [aCoder decodeBoolForKey:CPTableHeaderViewDrawsColumnLines];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_drawsColumnLines = YES;
|
||||||
|
CPLog.warn("The tableview header being decoded is using an old cib. Please run Nib2Cib.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
|||||||
@@ -84,7 +84,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
CPColor _textFieldBackgroundColor;
|
CPColor _textFieldBackgroundColor;
|
||||||
|
|
||||||
id _placeholderString;
|
id _placeholderString;
|
||||||
id _originalPlaceholderString;
|
|
||||||
BOOL _currentValueIsPlaceholder;
|
BOOL _currentValueIsPlaceholder;
|
||||||
|
|
||||||
id _delegate;
|
id _delegate;
|
||||||
@@ -160,6 +159,14 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
return "textfield";
|
return "textfield";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (Class)_binderClassForBinding:(CPString)theBinding
|
||||||
|
{
|
||||||
|
if (theBinding === CPValueBinding)
|
||||||
|
return [_CPTextFieldValueBinder class];
|
||||||
|
|
||||||
|
return [super _binderClassForBinding:theBinding];
|
||||||
|
}
|
||||||
|
|
||||||
+ (id)themeAttributes
|
+ (id)themeAttributes
|
||||||
{
|
{
|
||||||
return [CPDictionary dictionaryWithObjects:[_CGInsetMakeZero(), _CGInsetMake(2.0, 2.0, 2.0, 2.0), [CPNull null]]
|
return [CPDictionary dictionaryWithObjects:[_CGInsetMakeZero(), _CGInsetMake(2.0, 2.0, 2.0, 2.0), [CPNull null]]
|
||||||
@@ -672,8 +679,14 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
|
|
||||||
- (void)keyDown:(CPEvent)anEvent
|
- (void)keyDown:(CPEvent)anEvent
|
||||||
{
|
{
|
||||||
if ([anEvent keyCode] === CPReturnKeyCode)
|
var characters = [anEvent characters];
|
||||||
|
// Treat \r and \n the same. See issue #710.
|
||||||
|
if (characters === CPNewlineCharacter || characters === CPCarriageReturnCharacter)
|
||||||
{
|
{
|
||||||
|
// selectText: has a side effect - it can change first responder of the window
|
||||||
|
// we have to prevent such behaviour inside this method because target should be able to change first responder after receiving action.
|
||||||
|
[self selectText:nil];
|
||||||
|
|
||||||
if (_isEditing)
|
if (_isEditing)
|
||||||
{
|
{
|
||||||
_isEditing = NO;
|
_isEditing = NO;
|
||||||
@@ -681,7 +694,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
}
|
}
|
||||||
|
|
||||||
[self sendAction:[self action] to:[self target]];
|
[self sendAction:[self action] to:[self target]];
|
||||||
[self selectText:nil];
|
|
||||||
|
|
||||||
[[[self window] platformWindow] _propagateCurrentDOMEvent:NO];
|
[[[self window] platformWindow] _propagateCurrentDOMEvent:NO];
|
||||||
}
|
}
|
||||||
@@ -728,6 +740,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
@ignore
|
@ignore
|
||||||
|
Sets the internal string value without updating the value in the input element
|
||||||
*/
|
*/
|
||||||
- (void)_setStringValue:(id)aValue
|
- (void)_setStringValue:(id)aValue
|
||||||
{
|
{
|
||||||
@@ -787,34 +800,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
return _placeholderString;
|
return _placeholderString;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_setCurrentValueIsPlaceholder:(BOOL)isPlaceholder
|
|
||||||
{
|
|
||||||
// The initial _currentValueIsPlaceholder is null so convert it to NO for comparison purposes.
|
|
||||||
if (!!_currentValueIsPlaceholder === isPlaceholder)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (isPlaceholder)
|
|
||||||
{
|
|
||||||
// Save the original placeholder value so we can restore it later
|
|
||||||
// Only do this if the placeholder is not already overridden because the bindings logic might call this method
|
|
||||||
// several times and we don't want the bindings placeholder to ever become the original placeholder
|
|
||||||
if (!_currentValueIsPlaceholder)
|
|
||||||
_originalPlaceholderString = [self placeholderString];
|
|
||||||
|
|
||||||
// Set the current string value as the current placeholder and clear the string value
|
|
||||||
[self setPlaceholderString:[self stringValue]];
|
|
||||||
[self setStringValue:@""];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Restore the original placeholder, the actual textfield value is already correct
|
|
||||||
// because it was set using setValue:forKey:
|
|
||||||
[self setPlaceholderString:_originalPlaceholderString];
|
|
||||||
}
|
|
||||||
|
|
||||||
_currentValueIsPlaceholder = isPlaceholder;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
For non-bezeled text fields (typically a label), sizeToFit has two behaviors, depending
|
For non-bezeled text fields (typically a label), sizeToFit has two behaviors, depending
|
||||||
on the line break mode of the receiver.
|
on the line break mode of the receiver.
|
||||||
@@ -885,21 +870,28 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Select all the text in the CPTextField.
|
Make the receiver the first responder and select all the text in the field.
|
||||||
*/
|
*/
|
||||||
- (void)selectText:(id)sender
|
- (void)selectText:(id)sender
|
||||||
{
|
{
|
||||||
#if PLATFORM(DOM)
|
// FIXME Should this really make the text field the first responder?
|
||||||
var element = [self _inputElement];
|
|
||||||
|
|
||||||
if (([self isEditable] || [self isSelectable]))
|
if (([self isEditable] || [self isSelectable]))
|
||||||
{
|
{
|
||||||
|
#if PLATFORM(DOM)
|
||||||
|
var element = [self _inputElement];
|
||||||
|
|
||||||
if ([[self window] firstResponder] === self)
|
if ([[self window] firstResponder] === self)
|
||||||
window.setTimeout(function() { element.select(); }, 0);
|
window.setTimeout(function() { element.select(); }, 0);
|
||||||
else if ([self window] !== nil && [[self window] makeFirstResponder:self])
|
else if ([self window] !== nil && [[self window] makeFirstResponder:self])
|
||||||
window.setTimeout(function() {[self selectText:sender];}, 0);
|
window.setTimeout(function() {[self selectText:sender];}, 0);
|
||||||
}
|
#else
|
||||||
|
// Even if we can't actually select the text we need to preserve the first
|
||||||
|
// responder side effect.
|
||||||
|
if ([self window] !== nil && [[self window] firstResponder] !== self)
|
||||||
|
[[self window] makeFirstResponder:self];
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)copy:(id)sender
|
- (void)copy:(id)sender
|
||||||
@@ -981,7 +973,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
|||||||
// fall through to the return
|
// fall through to the return
|
||||||
}
|
}
|
||||||
|
|
||||||
return CGMakeRange(0, 0);
|
return CPMakeRange(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setSelectedRange:(CPRange)aRange
|
- (void)setSelectedRange:(CPRange)aRange
|
||||||
@@ -1262,18 +1254,6 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
|
|||||||
[self setAlignment:[aCoder decodeIntForKey:CPTextFieldAlignmentKey]];
|
[self setAlignment:[aCoder decodeIntForKey:CPTextFieldAlignmentKey]];
|
||||||
|
|
||||||
[self setPlaceholderString:[aCoder decodeObjectForKey:CPTextFieldPlaceholderStringKey]];
|
[self setPlaceholderString:[aCoder decodeObjectForKey:CPTextFieldPlaceholderStringKey]];
|
||||||
|
|
||||||
// Make sure the frame is big enough
|
|
||||||
var minSize = [self _minimumFrameSize];
|
|
||||||
minSize.width = MAX(CGRectGetWidth([self frame]), minSize.width);
|
|
||||||
minSize.height = MAX(CGRectGetHeight([self frame]), minSize.height);
|
|
||||||
|
|
||||||
// Only size multiline bezeled textfields if it's to small to fit the content
|
|
||||||
if ([self isBezeled])
|
|
||||||
if ([self lineBreakMode] === CPLineBreakByCharWrapping || [self lineBreakMode] == CPLineBreakByWordWrapping)
|
|
||||||
minSize.height = MAX(CGRectGetHeight([self frame]), minSize.height);
|
|
||||||
|
|
||||||
[self setFrameSize:minSize];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
@@ -1302,3 +1282,48 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@implementation _CPTextFieldValueBinder : CPBinder
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setValueFor:(CPString)theBinding
|
||||||
|
{
|
||||||
|
var destination = [_info objectForKey:CPObservedObjectKey],
|
||||||
|
keyPath = [_info objectForKey:CPObservedKeyPathKey],
|
||||||
|
options = [_info objectForKey:CPOptionsKey],
|
||||||
|
newValue = [destination valueForKeyPath:keyPath],
|
||||||
|
isPlaceholder = CPIsControllerMarker(newValue);
|
||||||
|
|
||||||
|
if (isPlaceholder)
|
||||||
|
{
|
||||||
|
switch (newValue)
|
||||||
|
{
|
||||||
|
case CPMultipleValuesMarker:
|
||||||
|
newValue = [options objectForKey:CPMultipleValuesPlaceholderBindingOption] || @"Multiple Values";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CPNoSelectionMarker:
|
||||||
|
newValue = [options objectForKey:CPNoSelectionPlaceholderBindingOption] || @"No Selection";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CPNotApplicableMarker:
|
||||||
|
if ([options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
|
||||||
|
[CPException raise:CPGenericException
|
||||||
|
reason:@"can't transform non applicable key on: "+_source+" value: "+newValue];
|
||||||
|
|
||||||
|
newValue = [options objectForKey:CPNotApplicablePlaceholderBindingOption] || @"Not Applicable";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[_source setPlaceholderString:newValue];
|
||||||
|
[_source setObjectValue:nil];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newValue = [self transformValue:newValue withOptions:options];
|
||||||
|
[_source setObjectValue:newValue];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|||||||
@@ -405,6 +405,7 @@ function CPThemeStateName(aState)
|
|||||||
CPThemeStateNames[0] = "normal";
|
CPThemeStateNames[0] = "normal";
|
||||||
CPThemeStateNormal = CPThemeStates["normal"] = 0;
|
CPThemeStateNormal = CPThemeStates["normal"] = 0;
|
||||||
CPThemeStateDisabled = CPThemeState("disabled");
|
CPThemeStateDisabled = CPThemeState("disabled");
|
||||||
|
CPThemeStateHovered = CPThemeState("hovered");
|
||||||
CPThemeStateHighlighted = CPThemeState("highlighted");
|
CPThemeStateHighlighted = CPThemeState("highlighted");
|
||||||
CPThemeStateSelected = CPThemeState("selected");
|
CPThemeStateSelected = CPThemeState("selected");
|
||||||
CPThemeStateTableDataView = CPThemeState("tableDataView");
|
CPThemeStateTableDataView = CPThemeState("tableDataView");
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
@import "CPButton.j"
|
@import "CPButton.j"
|
||||||
@import "CPScrollView.j"
|
@import "CPScrollView.j"
|
||||||
@import "CPTextField.j"
|
@import "CPTextField.j"
|
||||||
|
@import "CPTableView.j"
|
||||||
@import "CPWindow.j"
|
@import "CPWindow.j"
|
||||||
@import "_CPMenuWindow.j"
|
@import "_CPMenuWindow.j"
|
||||||
|
|
||||||
@@ -79,6 +80,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
|
|||||||
CPEvent _mouseDownEvent;
|
CPEvent _mouseDownEvent;
|
||||||
|
|
||||||
BOOL _preventResign;
|
BOOL _preventResign;
|
||||||
|
BOOL _shouldNotifyTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CPCharacterSet)defaultTokenizingCharacterSet
|
+ (CPCharacterSet)defaultTokenizingCharacterSet
|
||||||
@@ -208,10 +210,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
|
|||||||
[self _inputElement].value = @"";
|
[self _inputElement].value = @"";
|
||||||
[self setNeedsLayout];
|
[self setNeedsLayout];
|
||||||
|
|
||||||
var theBinding = [CPKeyValueBinding getBinding:CPValueBinding forObject:self];
|
[self _controlTextDidChange];
|
||||||
|
|
||||||
if (theBinding)
|
|
||||||
[theBinding reverseSetValueFor:@"objectValue"];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_autocomplete
|
- (void)_autocomplete
|
||||||
@@ -265,12 +264,15 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
|
|||||||
|
|
||||||
- (void)_controlTextDidChange
|
- (void)_controlTextDidChange
|
||||||
{
|
{
|
||||||
var theBinding = [CPKeyValueBinding getBinding:CPValueBinding forObject:self];
|
var binderClass = [[self class] _binderClassForBinding:CPValueBinding],
|
||||||
|
theBinding = [binderClass getBinding:CPValueBinding forObject:self];
|
||||||
|
|
||||||
if (theBinding)
|
if (theBinding)
|
||||||
[theBinding reverseSetValueFor:@"objectValue"];
|
[theBinding reverseSetValueFor:@"objectValue"];
|
||||||
|
|
||||||
[self textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:self userInfo:nil]];
|
[self textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:self userInfo:nil]];
|
||||||
|
|
||||||
|
_shouldNotifyTarget = YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_removeSelectedTokens:(id)sender
|
- (void)_removeSelectedTokens:(id)sender
|
||||||
@@ -401,7 +403,14 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
|
|||||||
|
|
||||||
[self setNeedsLayout];
|
[self setNeedsLayout];
|
||||||
|
|
||||||
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidBeginEditingNotification object:self userInfo:nil]];
|
if (_shouldNotifyTarget)
|
||||||
|
{
|
||||||
|
_shouldNotifyTarget = NO;
|
||||||
|
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]];
|
||||||
|
|
||||||
|
if ([self sendsActionOnEndEditing])
|
||||||
|
[self sendAction:[self action] to:[self target]];
|
||||||
|
}
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
@@ -465,7 +474,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
|
|||||||
if ([token isKindOfClass:[CPString class]])
|
if ([token isKindOfClass:[CPString class]])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
[objectValue addObject:[token stringValue]];
|
[objectValue addObject:[token representedObject]];
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PLATFORM(DOM)
|
#if PLATFORM(DOM)
|
||||||
@@ -501,13 +510,14 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
|
|||||||
for (var i = 0, count = [aValue count]; i < count; i++)
|
for (var i = 0, count = [aValue count]; i < count; i++)
|
||||||
{
|
{
|
||||||
// Do we have this token among the old ones?
|
// Do we have this token among the old ones?
|
||||||
var tokenValue = aValue[i],
|
var tokenObject = aValue[i],
|
||||||
|
tokenValue = [self tokenField:self displayStringForRepresentedObject:tokenObject],
|
||||||
newToken = nil;
|
newToken = nil;
|
||||||
|
|
||||||
for (var j = 0, oldCount = [oldTokens count]; j < oldCount; j++)
|
for (var j = 0, oldCount = [oldTokens count]; j < oldCount; j++)
|
||||||
{
|
{
|
||||||
var oldToken = oldTokens[j];
|
var oldToken = oldTokens[j];
|
||||||
if ([oldToken stringValue] == tokenValue)
|
if ([oldToken representedObject] == tokenObject)
|
||||||
{
|
{
|
||||||
// Yep. Reuse it.
|
// Yep. Reuse it.
|
||||||
[oldTokens removeObjectAtIndex:j];
|
[oldTokens removeObjectAtIndex:j];
|
||||||
@@ -520,6 +530,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
|
|||||||
{
|
{
|
||||||
newToken = [[_CPTokenFieldToken alloc] init];
|
newToken = [[_CPTokenFieldToken alloc] init];
|
||||||
[newToken setTokenField:self];
|
[newToken setTokenField:self];
|
||||||
|
[newToken setRepresentedObject:tokenObject];
|
||||||
[newToken setStringValue:tokenValue];
|
[newToken setStringValue:tokenValue];
|
||||||
[contentView addSubview:newToken];
|
[contentView addSubview:newToken];
|
||||||
}
|
}
|
||||||
@@ -552,6 +563,12 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
|
|||||||
[self setNeedsDisplay:YES];
|
[self setNeedsDisplay:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)sendAction:(SEL)anAction to:(id)anObject
|
||||||
|
{
|
||||||
|
_shouldNotifyTarget = NO;
|
||||||
|
[super sendAction:anAction to:anObject];
|
||||||
|
}
|
||||||
|
|
||||||
// Incredible hack to disable supers implementation
|
// Incredible hack to disable supers implementation
|
||||||
// so it cannot change our object value and break the tokenfield
|
// so it cannot change our object value and break the tokenfield
|
||||||
- (void)_setStringValue:(id)aValue
|
- (void)_setStringValue:(id)aValue
|
||||||
@@ -1074,7 +1091,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
|
|||||||
|
|
||||||
- (void)tableView:(CPTableView)tableView objectValueForTableColumn:(CPTableColumn)tableColumn row:(int)row
|
- (void)tableView:(CPTableView)tableView objectValueForTableColumn:(CPTableColumn)tableColumn row:(int)row
|
||||||
{
|
{
|
||||||
return [_cachedCompletions objectAtIndex:row];
|
return [self tokenField:self displayStringForRepresentedObject:[_cachedCompletions objectAtIndex:row]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)tableViewSelectionDidChange:(CPNotification)notification
|
- (void)tableViewSelectionDidChange:(CPNotification)notification
|
||||||
@@ -1111,6 +1128,23 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
|
|||||||
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// // Alows the delegate to provide a string to be displayed as a proxy for the given represented object.
|
||||||
|
// // If you return nil or do not implement this method, then representedObject is displayed as the string.
|
||||||
|
- (CPString)tokenField:(CPTokenField)tokenField displayStringForRepresentedObject:(id)representedObject
|
||||||
|
{
|
||||||
|
if ([[self delegate] respondsToSelector:@selector(tokenField:displayStringForRepresentedObject:)])
|
||||||
|
{
|
||||||
|
var stringForRepresentedObject = [[self delegate] tokenField:tokenField displayStringForRepresentedObject:representedObject];
|
||||||
|
if (stringForRepresentedObject !== nil)
|
||||||
|
{
|
||||||
|
return stringForRepresentedObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return representedObject;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// // return an array of represented objects you want to add.
|
// // return an array of represented objects you want to add.
|
||||||
// // If you want to reject the add, return an empty array.
|
// // If you want to reject the add, return an empty array.
|
||||||
@@ -1119,7 +1153,6 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
|
|||||||
//
|
//
|
||||||
// // If you return nil or don't implement these delegate methods, we will assume
|
// // If you return nil or don't implement these delegate methods, we will assume
|
||||||
// // editing string = display string = represented object
|
// // editing string = display string = represented object
|
||||||
// - (NSString *)tokenField:(NSTokenField *)tokenField displayStringForRepresentedObject:(id)representedObject;
|
|
||||||
// - (NSString *)tokenField:(NSTokenField *)tokenField editingStringForRepresentedObject:(id)representedObject;
|
// - (NSString *)tokenField:(NSTokenField *)tokenField editingStringForRepresentedObject:(id)representedObject;
|
||||||
// - (id)tokenField:(NSTokenField *)tokenField representedObjectForEditingString: (NSString *)editingString;
|
// - (id)tokenField:(NSTokenField *)tokenField representedObjectForEditingString: (NSString *)editingString;
|
||||||
//
|
//
|
||||||
@@ -1143,6 +1176,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
|
|||||||
{
|
{
|
||||||
_CPTokenFieldTokenCloseButton _deleteButton;
|
_CPTokenFieldTokenCloseButton _deleteButton;
|
||||||
CPTokenField _tokenField;
|
CPTokenField _tokenField;
|
||||||
|
id _representedObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CPString)defaultThemeClass
|
+ (CPString)defaultThemeClass
|
||||||
@@ -1175,6 +1209,16 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
|
|||||||
_tokenField = tokenField;
|
_tokenField = tokenField;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (id)representedObject
|
||||||
|
{
|
||||||
|
return _representedObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setRepresentedObject:(id)representedObject
|
||||||
|
{
|
||||||
|
_representedObject = representedObject;
|
||||||
|
}
|
||||||
|
|
||||||
- (CGSize)_minimumFrameSize
|
- (CGSize)_minimumFrameSize
|
||||||
{
|
{
|
||||||
var size = CGSizeMakeZero(),
|
var size = CGSizeMakeZero(),
|
||||||
|
|||||||
@@ -667,7 +667,7 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
|
|||||||
|
|
||||||
// Determine all the items that have flexible width.
|
// Determine all the items that have flexible width.
|
||||||
// Also determine the height of the toolbar.
|
// Also determine the height of the toolbar.
|
||||||
var count = _visibleItems.length
|
var count = _visibleItems.length,
|
||||||
flexibleItemIndexes = [CPIndexSet indexSet];
|
flexibleItemIndexes = [CPIndexSet indexSet];
|
||||||
|
|
||||||
while (count--)
|
while (count--)
|
||||||
@@ -799,10 +799,11 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
|
|||||||
|
|
||||||
hasNonSeparatorItem = YES;
|
hasNonSeparatorItem = YES;
|
||||||
|
|
||||||
var menuItem = [[CPMenuItem alloc] initWithTitle:[item label] action:[item action] keyEquivalent:nil];
|
var menuItem = [[CPMenuItem alloc] initWithTitle:[item label] action:@selector(didSelectMenuItem:) keyEquivalent:nil];
|
||||||
|
|
||||||
|
[menuItem setRepresentedObject:item];
|
||||||
[menuItem setImage:[item image]];
|
[menuItem setImage:[item image]];
|
||||||
[menuItem setTarget:[item target]];
|
[menuItem setTarget:self];
|
||||||
[menuItem setEnabled:[item isEnabled]];
|
[menuItem setEnabled:[item isEnabled]];
|
||||||
|
|
||||||
[_additionalItemsButton addItem:menuItem];
|
[_additionalItemsButton addItem:menuItem];
|
||||||
@@ -812,6 +813,18 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
|
|||||||
[_additionalItemsButton removeFromSuperview];
|
[_additionalItemsButton removeFromSuperview];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Used privately.
|
||||||
|
@ignore
|
||||||
|
*/
|
||||||
|
|
||||||
|
- (void)didSelectMenuItem:(id)aSender
|
||||||
|
{
|
||||||
|
var toolbarItem = [aSender representedObject];
|
||||||
|
|
||||||
|
[CPApp sendAction:[toolbarItem action] to:[toolbarItem target] from:toolbarItem];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)reloadToolbarItems
|
- (void)reloadToolbarItems
|
||||||
{
|
{
|
||||||
// Get rid of all our current subviews.
|
// Get rid of all our current subviews.
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ CPToolbarShowFontsItemIdentifier = @"CPToolbarShowFontsItem";
|
|||||||
CPToolbarCustomizeToolbarItemIdentifier = @"CPToolbarCustomizeToolbarItem";
|
CPToolbarCustomizeToolbarItemIdentifier = @"CPToolbarCustomizeToolbarItem";
|
||||||
CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
|
CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
@class CPToolbarItem
|
@class CPToolbarItem
|
||||||
|
|
||||||
@@ -49,9 +49,9 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
|
|||||||
@implementation CPToolbarItem : CPObject
|
@implementation CPToolbarItem : CPObject
|
||||||
{
|
{
|
||||||
CPString _itemIdentifier;
|
CPString _itemIdentifier;
|
||||||
|
|
||||||
CPToolbar _toolbar;
|
CPToolbar _toolbar;
|
||||||
|
|
||||||
CPString _label;
|
CPString _label;
|
||||||
CPString _paletteLabel;
|
CPString _paletteLabel;
|
||||||
CPString _toolTip;
|
CPString _toolTip;
|
||||||
@@ -61,12 +61,12 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
|
|||||||
BOOL _isEnabled;
|
BOOL _isEnabled;
|
||||||
CPImage _image;
|
CPImage _image;
|
||||||
CPImage _alternateImage;
|
CPImage _alternateImage;
|
||||||
|
|
||||||
CPView _view;
|
CPView _view;
|
||||||
|
|
||||||
CGSize _minSize;
|
CGSize _minSize;
|
||||||
CGSize _maxSize;
|
CGSize _maxSize;
|
||||||
|
|
||||||
int _visibilityPriority;
|
int _visibilityPriority;
|
||||||
|
|
||||||
BOOL _autovalidates;
|
BOOL _autovalidates;
|
||||||
@@ -86,21 +86,21 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
|
|||||||
- (id)initWithItemIdentifier:(CPString)anItemIdentifier
|
- (id)initWithItemIdentifier:(CPString)anItemIdentifier
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
_itemIdentifier = anItemIdentifier;
|
_itemIdentifier = anItemIdentifier;
|
||||||
|
|
||||||
_tag = 0;
|
_tag = 0;
|
||||||
_isEnabled = YES;
|
_isEnabled = YES;
|
||||||
|
|
||||||
_minSize = CGSizeMakeZero();
|
_minSize = CGSizeMakeZero();
|
||||||
_maxSize = CGSizeMakeZero();
|
_maxSize = CGSizeMakeZero();
|
||||||
|
|
||||||
_visibilityPriority = CPToolbarItemVisibilityPriorityStandard;
|
_visibilityPriority = CPToolbarItemVisibilityPriorityStandard;
|
||||||
_autovalidates = YES;
|
_autovalidates = YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +170,7 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
|
|||||||
{
|
{
|
||||||
if ([_view respondsToSelector:@selector(toolTip)])
|
if ([_view respondsToSelector:@selector(toolTip)])
|
||||||
return [_view toolTip];
|
return [_view toolTip];
|
||||||
|
|
||||||
return _toolTip;
|
return _toolTip;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,7 +182,7 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
|
|||||||
{
|
{
|
||||||
if ([_view respondsToSelector:@selector(setToolTip:)])
|
if ([_view respondsToSelector:@selector(setToolTip:)])
|
||||||
[_view setToolTip:aToolTip];
|
[_view setToolTip:aToolTip];
|
||||||
|
|
||||||
_toolTip = aToolTip;
|
_toolTip = aToolTip;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,7 +193,7 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
|
|||||||
{
|
{
|
||||||
if ([_view respondsToSelector:@selector(tag)])
|
if ([_view respondsToSelector:@selector(tag)])
|
||||||
return [_view tag];
|
return [_view tag];
|
||||||
|
|
||||||
return _tag;
|
return _tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +205,7 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
|
|||||||
{
|
{
|
||||||
if ([_view respondsToSelector:@selector(setTag:)])
|
if ([_view respondsToSelector:@selector(setTag:)])
|
||||||
[_view setTag:aTag];
|
[_view setTag:aTag];
|
||||||
|
|
||||||
_tag = aTag;
|
_tag = aTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,12 +216,12 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
|
|||||||
{
|
{
|
||||||
if (_view)
|
if (_view)
|
||||||
return [_view respondsToSelector:@selector(target)] ? [_view target] : nil;
|
return [_view respondsToSelector:@selector(target)] ? [_view target] : nil;
|
||||||
|
|
||||||
return _target;
|
return _target;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Sets the target of the action that is triggered when the user clicks this item. \c nil will cause
|
Sets the target of the action that is triggered when the user clicks this item. \c nil will cause
|
||||||
the action to be passed on to the first responder.
|
the action to be passed on to the first responder.
|
||||||
@param aTarget the new target
|
@param aTarget the new target
|
||||||
*/
|
*/
|
||||||
@@ -229,7 +229,7 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
|
|||||||
{
|
{
|
||||||
if (!_view)
|
if (!_view)
|
||||||
_target = aTarget;
|
_target = aTarget;
|
||||||
|
|
||||||
else if ([_view respondsToSelector:@selector(setTarget:)])
|
else if ([_view respondsToSelector:@selector(setTarget:)])
|
||||||
[_view setTarget:aTarget];
|
[_view setTarget:aTarget];
|
||||||
}
|
}
|
||||||
@@ -241,7 +241,7 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
|
|||||||
{
|
{
|
||||||
if (_view)
|
if (_view)
|
||||||
return [_view respondsToSelector:@selector(action)] ? [_view action] : nil;
|
return [_view respondsToSelector:@selector(action)] ? [_view action] : nil;
|
||||||
|
|
||||||
return _action;
|
return _action;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,7 +265,7 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
|
|||||||
{
|
{
|
||||||
if ([_view respondsToSelector:@selector(isEnabled)])
|
if ([_view respondsToSelector:@selector(isEnabled)])
|
||||||
return [_view isEnabled];
|
return [_view isEnabled];
|
||||||
|
|
||||||
return _isEnabled;
|
return _isEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,7 +277,7 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
|
|||||||
{
|
{
|
||||||
if ([_view respondsToSelector:@selector(setEnabled:)])
|
if ([_view respondsToSelector:@selector(setEnabled:)])
|
||||||
[_view setEnabled:shouldBeEnabled];
|
[_view setEnabled:shouldBeEnabled];
|
||||||
|
|
||||||
_isEnabled = shouldBeEnabled;
|
_isEnabled = shouldBeEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,7 +288,7 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
|
|||||||
{
|
{
|
||||||
if ([_view respondsToSelector:@selector(image)])
|
if ([_view respondsToSelector:@selector(image)])
|
||||||
return [_view image];
|
return [_view image];
|
||||||
|
|
||||||
return _image;
|
return _image;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,11 +302,11 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
|
|||||||
[_view setImage:anImage];
|
[_view setImage:anImage];
|
||||||
|
|
||||||
_image = anImage;
|
_image = anImage;
|
||||||
|
|
||||||
if (!_image)
|
if (!_image)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_minSize.width === 0 && _minSize.height === 0 &&
|
if (_minSize.width === 0 && _minSize.height === 0 &&
|
||||||
_maxSize.width === 0 && _maxSize.height === 0)
|
_maxSize.width === 0 && _maxSize.height === 0)
|
||||||
{
|
{
|
||||||
var imageSize = [_image size];
|
var imageSize = [_image size];
|
||||||
@@ -327,7 +327,7 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
|
|||||||
{
|
{
|
||||||
if ([_view respondsToSelector:@selector(setAlternateImage:)])
|
if ([_view respondsToSelector:@selector(setAlternateImage:)])
|
||||||
[_view setAlternateImage:anImage];
|
[_view setAlternateImage:anImage];
|
||||||
|
|
||||||
_alternateImage = anImage;
|
_alternateImage = anImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,7 +338,7 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
|
|||||||
{
|
{
|
||||||
if ([_view respondsToSelector:@selector(alternateIamge)])
|
if ([_view respondsToSelector:@selector(alternateIamge)])
|
||||||
return [_view alternateImage];
|
return [_view alternateImage];
|
||||||
|
|
||||||
return _alternateImage;
|
return _alternateImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,7 +358,7 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
|
|||||||
{
|
{
|
||||||
if (_view == aView)
|
if (_view == aView)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_view = aView;
|
_view = aView;
|
||||||
|
|
||||||
if (_view)
|
if (_view)
|
||||||
@@ -366,7 +366,7 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
|
|||||||
// Tags get forwarded.
|
// Tags get forwarded.
|
||||||
if (_tag !== 0 && [_view respondsToSelector:@selector(setTag:)])
|
if (_tag !== 0 && [_view respondsToSelector:@selector(setTag:)])
|
||||||
[_view setTag:_tag];
|
[_view setTag:_tag];
|
||||||
|
|
||||||
_target = nil;
|
_target = nil;
|
||||||
_action = nil;
|
_action = nil;
|
||||||
}
|
}
|
||||||
@@ -386,11 +386,11 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
|
|||||||
*/
|
*/
|
||||||
- (void)setMinSize:(CGSize)aMinSize
|
- (void)setMinSize:(CGSize)aMinSize
|
||||||
{
|
{
|
||||||
if(!aMinSize.height || !aMinSize.width)
|
if (!aMinSize.height || !aMinSize.width)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_minSize = CGSizeMakeCopy(aMinSize);
|
_minSize = CGSizeMakeCopy(aMinSize);
|
||||||
|
|
||||||
// Try to provide some sanity: Make maxSize >= minSize
|
// Try to provide some sanity: Make maxSize >= minSize
|
||||||
_maxSize = CGSizeMake(MAX(_minSize.width, _maxSize.width), MAX(_minSize.height, _maxSize.height));
|
_maxSize = CGSizeMake(MAX(_minSize.width, _maxSize.width), MAX(_minSize.height, _maxSize.height));
|
||||||
}
|
}
|
||||||
@@ -409,11 +409,11 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
|
|||||||
*/
|
*/
|
||||||
- (void)setMaxSize:(CGSize)aMaxSize
|
- (void)setMaxSize:(CGSize)aMaxSize
|
||||||
{
|
{
|
||||||
if(!aMaxSize.height || !aMaxSize.width)
|
if (!aMaxSize.height || !aMaxSize.width)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_maxSize = CGSizeMakeCopy(aMaxSize);
|
_maxSize = CGSizeMakeCopy(aMaxSize);
|
||||||
|
|
||||||
// Try to provide some sanity: Make minSize <= maxSize
|
// Try to provide some sanity: Make minSize <= maxSize
|
||||||
_minSize = CGSizeMake(MIN(_minSize.width, _maxSize.width), MIN(_minSize.height, _maxSize.height));
|
_minSize = CGSizeMake(MIN(_minSize.width, _maxSize.width), MIN(_minSize.height, _maxSize.height));
|
||||||
}
|
}
|
||||||
@@ -623,7 +623,7 @@ var CPToolbarItemItemIdentifierKey = @"CPToolbarItemItemIdentifierKey",
|
|||||||
case CPToolbarCustomizeToolbarItemIdentifier: return nil;
|
case CPToolbarCustomizeToolbarItemIdentifier: return nil;
|
||||||
case CPToolbarPrintItemIdentifier: return nil;
|
case CPToolbarPrintItemIdentifier: return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
|
|
||||||
@import <Foundation/CPObject.j>
|
@import <Foundation/CPObject.j>
|
||||||
|
@import <Foundation/CPIndexPath.j>
|
||||||
|
|
||||||
|
|
||||||
@implementation CPTreeNode : CPObject
|
@implementation CPTreeNode : CPObject
|
||||||
{
|
{
|
||||||
id _representedObject @accessors(readonly, property=representedObject);
|
id _representedObject @accessors(readonly, property=representedObject);
|
||||||
|
|
||||||
CPTreeNode _parentNode @accessors(readonly, property=parentNode);
|
CPTreeNode _parentNode @accessors(readonly, property=parentNode);
|
||||||
CPMutableArray _childNodes;
|
CPMutableArray _childNodes;
|
||||||
}
|
}
|
||||||
@@ -87,6 +88,18 @@
|
|||||||
[_childNodes[count] sortWithSortDescriptors:sortDescriptors recursively:YES];
|
[_childNodes[count] sortWithSortDescriptors:sortDescriptors recursively:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (CPTreeNode)descendantNodeAtIndexPath:(CPIndexPath)indexPath
|
||||||
|
{
|
||||||
|
var index = 0,
|
||||||
|
count = [indexPath length],
|
||||||
|
node = self;
|
||||||
|
|
||||||
|
for (; index < count; ++index)
|
||||||
|
node = [node objectInChildNodesAtIndex:[indexPath indexAtPosition:index]];
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
var CPTreeNodeRepresentedObjectKey = @"CPTreeNodeRepresentedObjectKey",
|
var CPTreeNodeRepresentedObjectKey = @"CPTreeNodeRepresentedObjectKey",
|
||||||
|
|||||||
@@ -1566,6 +1566,16 @@ var CPViewFlags = { },
|
|||||||
return CGPointApplyAffineTransform(aPoint, _CPViewGetTransform(aView, self));
|
return CGPointApplyAffineTransform(aPoint, _CPViewGetTransform(aView, self));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Converts the point from the base coordinate system to the receiver’s coordinate system.
|
||||||
|
@param aPoint A point specifying a location in the base coordinate system
|
||||||
|
@return The point converted to the receiver’s base coordinate system
|
||||||
|
*/
|
||||||
|
- (CGPoint)convertPointFromBase:(CGPoint)aPoint
|
||||||
|
{
|
||||||
|
return CGPointApplyAffineTransform(aPoint, _CPViewGetTransform(nil, self));
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Converts \c aPoint from the receiver's coordinate space to the coordinate space of \c aView.
|
Converts \c aPoint from the receiver's coordinate space to the coordinate space of \c aView.
|
||||||
@param aPoint the point to convert
|
@param aPoint the point to convert
|
||||||
@@ -1577,6 +1587,16 @@ var CPViewFlags = { },
|
|||||||
return CGPointApplyAffineTransform(aPoint, _CPViewGetTransform(self, aView));
|
return CGPointApplyAffineTransform(aPoint, _CPViewGetTransform(self, aView));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Converts the point from the receiver’s coordinate system to the base coordinate system.
|
||||||
|
@param aPoint A point specifying a location in the coordinate system of the receiver
|
||||||
|
@return The point converted to the base coordinate system
|
||||||
|
*/
|
||||||
|
- (CGPoint)convertPointToBase:(CGPoint)aPoint
|
||||||
|
{
|
||||||
|
return CGPointApplyAffineTransform(aPoint, _CPViewGetTransform(self, nil));
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Convert's \c aSize from \c aView's coordinate space to the receiver's coordinate space.
|
Convert's \c aSize from \c aView's coordinate space to the receiver's coordinate space.
|
||||||
@param aSize the size to convert
|
@param aSize the size to convert
|
||||||
@@ -1610,6 +1630,16 @@ var CPViewFlags = { },
|
|||||||
return CGRectApplyAffineTransform(aRect, _CPViewGetTransform(aView, self));
|
return CGRectApplyAffineTransform(aRect, _CPViewGetTransform(aView, self));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Converts the rectangle from the base coordinate system to the receiver’s coordinate system.
|
||||||
|
@param aRect A rectangle specifying a location in the base coordinate system
|
||||||
|
@return The rectangle converted to the receiver’s base coordinate system
|
||||||
|
*/
|
||||||
|
- (CGRect)convertRectFromBase:(CGRect)aRect
|
||||||
|
{
|
||||||
|
return CGRectApplyAffineTransform(aRect, _CPViewGetTransform(nil, self));
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Converts \c aRect from the receiver's coordinate space to \c aView's coordinate space.
|
Converts \c aRect from the receiver's coordinate space to \c aView's coordinate space.
|
||||||
@param aRect the rectangle to convert
|
@param aRect the rectangle to convert
|
||||||
@@ -1621,6 +1651,16 @@ var CPViewFlags = { },
|
|||||||
return CGRectApplyAffineTransform(aRect, _CPViewGetTransform(self, aView));
|
return CGRectApplyAffineTransform(aRect, _CPViewGetTransform(self, aView));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Converts the rectangle from the receiver’s coordinate system to the base coordinate system.
|
||||||
|
@param aRect A rectangle specifying a location in the coordinate system of the receiver
|
||||||
|
@return The rectangle converted to the base coordinate system
|
||||||
|
*/
|
||||||
|
- (CGRect)convertRectToBase:(CGRect)aRect
|
||||||
|
{
|
||||||
|
return CGRectApplyAffineTransform(aRect, _CPViewGetTransform(self, nil));
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Sets whether the receiver posts a CPViewFrameDidChangeNotification notification
|
Sets whether the receiver posts a CPViewFrameDidChangeNotification notification
|
||||||
to the default notification center when its frame is changed. The default is \c NO.
|
to the default notification center when its frame is changed. The default is \c NO.
|
||||||
@@ -2105,11 +2145,18 @@ setBoundsOrigin:
|
|||||||
|
|
||||||
- (CPView)nextValidKeyView
|
- (CPView)nextValidKeyView
|
||||||
{
|
{
|
||||||
var result = [self nextKeyView];
|
var result = [self nextKeyView],
|
||||||
|
firstResult = result;
|
||||||
|
|
||||||
while (result && ![result canBecomeKeyView])
|
while (result && ![result canBecomeKeyView])
|
||||||
|
{
|
||||||
result = [result nextKeyView];
|
result = [result nextKeyView];
|
||||||
|
|
||||||
|
// Cycled.
|
||||||
|
if (result === firstResult)
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2213,6 +2260,10 @@ setBoundsOrigin:
|
|||||||
|
|
||||||
- (BOOL)hasThemeState:(CPThemeState)aState
|
- (BOOL)hasThemeState:(CPThemeState)aState
|
||||||
{
|
{
|
||||||
|
// Because CPThemeStateNormal is defined as 0 we need to check for it explicitly here
|
||||||
|
if (aState === CPThemeStateNormal && _themeState === CPThemeStateNormal)
|
||||||
|
return YES;
|
||||||
|
|
||||||
return !!(_themeState & ((typeof aState === "string") ? CPThemeState(aState) : aState));
|
return !!(_themeState & ((typeof aState === "string") ? CPThemeState(aState) : aState));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2469,7 +2520,7 @@ setBoundsOrigin:
|
|||||||
|
|
||||||
var frame = [self rectForEphemeralSubviewNamed:aViewName];
|
var frame = [self rectForEphemeralSubviewNamed:aViewName];
|
||||||
|
|
||||||
if (frame && !_CGRectIsEmpty(frame))
|
if (frame)
|
||||||
{
|
{
|
||||||
if (!_ephemeralSubviewsForNames[aViewName])
|
if (!_ephemeralSubviewsForNames[aViewName])
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,13 +23,13 @@
|
|||||||
@import "CPAnimation.j"
|
@import "CPAnimation.j"
|
||||||
|
|
||||||
|
|
||||||
CPViewAnimationTargetKey = @"CPViewAnimationTarget";
|
CPViewAnimationTargetKey = @"CPViewAnimationTargetKey";
|
||||||
CPViewAnimationStartFrameKey = @"CPViewAnimationStartFrame";
|
CPViewAnimationStartFrameKey = @"CPViewAnimationStartFrameKey";
|
||||||
CPViewAnimationEndFrameKey = @"CPViewAnimationEndFrame";
|
CPViewAnimationEndFrameKey = @"CPViewAnimationEndFrameKey";
|
||||||
CPViewAnimationEffectKey = @"CPViewAnimationEffect";
|
CPViewAnimationEffectKey = @"CPViewAnimationEffectKey";
|
||||||
|
|
||||||
CPViewAnimationFadeInEffect = @"CPViewAnimationFadeIn";
|
CPViewAnimationFadeInEffect = @"CPViewAnimationFadeInEffect";
|
||||||
CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut";
|
CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOutEffect";
|
||||||
|
|
||||||
@implementation CPViewAnimation : CPAnimation
|
@implementation CPViewAnimation : CPAnimation
|
||||||
{
|
{
|
||||||
@@ -61,7 +61,7 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut";
|
|||||||
if (effect === CPViewAnimationFadeInEffect)
|
if (effect === CPViewAnimationFadeInEffect)
|
||||||
{
|
{
|
||||||
[view setAlphaValue:0.0];
|
[view setAlphaValue:0.0];
|
||||||
[view setHidden:NO];
|
[self _targetView:view setHidden:NO];
|
||||||
}
|
}
|
||||||
else if (effect === CPViewAnimationFadeOutEffect)
|
else if (effect === CPViewAnimationFadeOutEffect)
|
||||||
[view setAlphaValue:1.0];
|
[view setAlphaValue:1.0];
|
||||||
@@ -104,7 +104,7 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut";
|
|||||||
[view setAlphaValue:1.0 + ( 0.0 - 1.0 ) * progress];
|
[view setAlphaValue:1.0 + ( 0.0 - 1.0 ) * progress];
|
||||||
|
|
||||||
if (progress === 1.0)
|
if (progress === 1.0)
|
||||||
[view setHidden:_CGRectIsNull(endFrame) || [view alphaValue] === 0.0];
|
[self _targetView:view setHidden:_CGRectIsNull(endFrame) || [view alphaValue] === 0.0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,12 +125,25 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut";
|
|||||||
else if (effect === CPViewAnimationFadeOutEffect)
|
else if (effect === CPViewAnimationFadeOutEffect)
|
||||||
[view setAlphaValue:0.0];
|
[view setAlphaValue:0.0];
|
||||||
|
|
||||||
[view setHidden:_CGRectIsNull(endFrame) || [view alphaValue] === 0.0];
|
[self _targetView:view setHidden:_CGRectIsNull(endFrame) || [view alphaValue] === 0.0];
|
||||||
}
|
}
|
||||||
|
|
||||||
[super stopAnimation];
|
[super stopAnimation];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)_targetView:(id)theView setHidden:(BOOL)isHidden
|
||||||
|
{
|
||||||
|
if ([theView isKindOfClass:[CPWindow class]])
|
||||||
|
{
|
||||||
|
if (isHidden)
|
||||||
|
[theView orderOut:self];
|
||||||
|
else
|
||||||
|
[theView orderFront:self];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
[theView setHidden:isHidden];
|
||||||
|
}
|
||||||
|
|
||||||
- (id)_targetView:(CPDictionary)dictionary
|
- (id)_targetView:(CPDictionary)dictionary
|
||||||
{
|
{
|
||||||
var targetView = [dictionary valueForKey:CPViewAnimationTargetKey];
|
var targetView = [dictionary valueForKey:CPViewAnimationTargetKey];
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ CPWebViewScrollNative = 2;
|
|||||||
_ignoreLoadEnd = YES;
|
_ignoreLoadEnd = YES;
|
||||||
|
|
||||||
_iframe = document.createElement("iframe");
|
_iframe = document.createElement("iframe");
|
||||||
_iframe.name = "iframe_" + Math.floor(Math.random()*10000);
|
_iframe.name = "iframe_" + FLOOR(RAND() * 10000);
|
||||||
_iframe.style.width = "100%";
|
_iframe.style.width = "100%";
|
||||||
_iframe.style.height = "100%";
|
_iframe.style.height = "100%";
|
||||||
_iframe.style.borderWidth = "0px";
|
_iframe.style.borderWidth = "0px";
|
||||||
@@ -116,47 +116,46 @@ CPWebViewScrollNative = 2;
|
|||||||
[self setDrawsBackground:YES];
|
[self setDrawsBackground:YES];
|
||||||
|
|
||||||
_loadCallback = function() {
|
_loadCallback = function() {
|
||||||
// HACK: this block handles the case where we don't know about loads initiated by the user clicking a link
|
// HACK: this block handles the case where we don't know about loads initiated by the user clicking a link
|
||||||
if (!_ignoreLoadStart)
|
if (!_ignoreLoadStart)
|
||||||
{
|
{
|
||||||
// post the start load notification
|
// post the start load notification
|
||||||
[self _startedLoading];
|
[self _startedLoading];
|
||||||
|
|
||||||
if (_mainFrameURL)
|
if (_mainFrameURL)
|
||||||
[_backwardStack addObject:_mainFrameURL];
|
[_backwardStack addObject:_mainFrameURL];
|
||||||
|
|
||||||
// FIXME: this doesn't actually get the right URL for different domains. Not possible due to browser security restrictions.
|
// FIXME: this doesn't actually get the right URL for different domains. Not possible due to browser security restrictions.
|
||||||
_mainFrameURL = _iframe.src;
|
_mainFrameURL = _iframe.src;
|
||||||
_mainFrameURL = _iframe.src;
|
_mainFrameURL = _iframe.src;
|
||||||
|
|
||||||
// clear the forward
|
// clear the forward
|
||||||
[_forwardStack removeAllObjects];
|
[_forwardStack removeAllObjects];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
_ignoreLoadStart = NO;
|
_ignoreLoadStart = NO;
|
||||||
|
|
||||||
if (!_ignoreLoadEnd)
|
if (!_ignoreLoadEnd)
|
||||||
{
|
{
|
||||||
[self _finishedLoading];
|
[self _finishedLoading];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
_ignoreLoadEnd = NO;
|
_ignoreLoadEnd = NO;
|
||||||
|
|
||||||
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
|
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_iframe.addEventListener)
|
|
||||||
_iframe.addEventListener("load", _loadCallback, false);
|
|
||||||
else if (_iframe.attachEvent)
|
|
||||||
_iframe.attachEvent("onload", _loadCallback);
|
|
||||||
|
|
||||||
|
if (_iframe.addEventListener)
|
||||||
|
_iframe.addEventListener("load", _loadCallback, false);
|
||||||
|
else if (_iframe.attachEvent)
|
||||||
|
_iframe.attachEvent("onload", _loadCallback);
|
||||||
|
|
||||||
_frameView = [[CPView alloc] initWithFrame:[self bounds]];
|
_frameView = [[CPView alloc] initWithFrame:[self bounds]];
|
||||||
[_frameView setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable];
|
[_frameView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
||||||
|
|
||||||
_scrollView = [[CPScrollView alloc] initWithFrame:[self bounds]];
|
_scrollView = [[CPScrollView alloc] initWithFrame:[self bounds]];
|
||||||
[_scrollView setAutohidesScrollers:YES];
|
[_scrollView setAutohidesScrollers:YES];
|
||||||
[_scrollView setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable];
|
[_scrollView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
||||||
[_scrollView setDocumentView:_frameView];
|
[_scrollView setDocumentView:_frameView];
|
||||||
|
|
||||||
_frameView._DOMElement.appendChild(_iframe);
|
_frameView._DOMElement.appendChild(_iframe);
|
||||||
|
|||||||
@@ -197,6 +197,21 @@ var CPWindowSaveImage = nil,
|
|||||||
|
|
||||||
var CPWindowResizeTime = 0.2;
|
var CPWindowResizeTime = 0.2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Keys for which action messages will be sent by default when unhandled, e.g. complete:.
|
||||||
|
*/
|
||||||
|
var CPWindowActionMessageKeys = [
|
||||||
|
CPLeftArrowFunctionKey,
|
||||||
|
CPRightArrowFunctionKey,
|
||||||
|
CPUpArrowFunctionKey,
|
||||||
|
CPDownArrowFunctionKey,
|
||||||
|
CPPageUpFunctionKey,
|
||||||
|
CPPageDownFunctionKey,
|
||||||
|
CPHomeFunctionKey,
|
||||||
|
CPEndFunctionKey,
|
||||||
|
CPEscapeFunctionKey
|
||||||
|
];
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
@class CPWindow
|
@class CPWindow
|
||||||
@@ -388,6 +403,7 @@ CPTexturedBackgroundWindowMask
|
|||||||
_registeredDraggedTypes = [CPSet set];
|
_registeredDraggedTypes = [CPSet set];
|
||||||
_registeredDraggedTypesArray = [];
|
_registeredDraggedTypesArray = [];
|
||||||
_isSheet = NO;
|
_isSheet = NO;
|
||||||
|
_acceptsMouseMovedEvents = YES;
|
||||||
|
|
||||||
// Set up our window number.
|
// Set up our window number.
|
||||||
_windowNumber = [CPApp._windows count];
|
_windowNumber = [CPApp._windows count];
|
||||||
@@ -937,7 +953,7 @@ CPTexturedBackgroundWindowMask
|
|||||||
/*!
|
/*!
|
||||||
Sets the window's minimum size. If the provided
|
Sets the window's minimum size. If the provided
|
||||||
size is the same as the current minimum size, the method simply returns.
|
size is the same as the current minimum size, the method simply returns.
|
||||||
@aSize the new minimum size for the window
|
@param aSize the new minimum size for the window
|
||||||
*/
|
*/
|
||||||
- (void)setMinSize:(CGSize)aSize
|
- (void)setMinSize:(CGSize)aSize
|
||||||
{
|
{
|
||||||
@@ -1223,10 +1239,10 @@ CPTexturedBackgroundWindowMask
|
|||||||
if (_firstResponder === aResponder)
|
if (_firstResponder === aResponder)
|
||||||
return YES;
|
return YES;
|
||||||
|
|
||||||
if(![_firstResponder resignFirstResponder])
|
if (![_firstResponder resignFirstResponder])
|
||||||
return NO;
|
return NO;
|
||||||
|
|
||||||
if(!aResponder || ![aResponder acceptsFirstResponder] || ![aResponder becomeFirstResponder])
|
if (!aResponder || ![aResponder acceptsFirstResponder] || ![aResponder becomeFirstResponder])
|
||||||
{
|
{
|
||||||
_firstResponder = self;
|
_firstResponder = self;
|
||||||
|
|
||||||
@@ -2155,7 +2171,7 @@ CPTexturedBackgroundWindowMask
|
|||||||
aSheet._isSheet = YES;
|
aSheet._isSheet = YES;
|
||||||
aSheet._parentView = self;
|
aSheet._parentView = self;
|
||||||
|
|
||||||
var originx = frame.origin.x + FLOOR((frame.size.width - sheetFrame.size.width)/2),
|
var originx = frame.origin.x + FLOOR((frame.size.width - sheetFrame.size.width) / 2),
|
||||||
originy = frame.origin.y + [[self contentView] frame].origin.y,
|
originy = frame.origin.y + [[self contentView] frame].origin.y,
|
||||||
startFrame = CGRectMake(originx, originy, sheetFrame.size.width, 0),
|
startFrame = CGRectMake(originx, originy, sheetFrame.size.width, 0),
|
||||||
endFrame = CGRectMake(originx, originy, sheetFrame.size.width, sheetFrame.size.height);
|
endFrame = CGRectMake(originx, originy, sheetFrame.size.width, sheetFrame.size.height);
|
||||||
@@ -2314,7 +2330,7 @@ CPTexturedBackgroundWindowMask
|
|||||||
|
|
||||||
// Apple's documentation is inconsistent with their behavior here. According to the docs
|
// Apple's documentation is inconsistent with their behavior here. According to the docs
|
||||||
// an event going of the responder chain is passed to the input system as a last resort.
|
// an event going of the responder chain is passed to the input system as a last resort.
|
||||||
// However, the only methods I could get Cocoa to call automatically are
|
// However, the only methods I could get Cocoa to call automatically are
|
||||||
// moveUp: moveDown: moveLeft: moveRight: pageUp: pageDown: and complete:
|
// moveUp: moveDown: moveLeft: moveRight: pageUp: pageDown: and complete:
|
||||||
[self _processKeyboardUIKey:anEvent];
|
[self _processKeyboardUIKey:anEvent];
|
||||||
}
|
}
|
||||||
@@ -2323,59 +2339,15 @@ CPTexturedBackgroundWindowMask
|
|||||||
@ignore
|
@ignore
|
||||||
Interprets the key event for action messages and sends the action message down the responder chain
|
Interprets the key event for action messages and sends the action message down the responder chain
|
||||||
Cocoa only sends moveDown:, moveUp:, moveLeft:, moveRight:, pageUp:, pageDown: and complete: messages.
|
Cocoa only sends moveDown:, moveUp:, moveLeft:, moveRight:, pageUp:, pageDown: and complete: messages.
|
||||||
We deviate from this by sending (the default) scrollPageUp: scrollPageDown: for pageUp and pageDown keys.
|
We deviate from this by sending (the default) scrollPageUp:, scrollPageDown:, scrollToBeginningOfDocument: and scrollToEndOfDocument: for pageUp, pageDown, home and end keys.
|
||||||
@param anEvent the event to handle.
|
@param anEvent the event to handle.
|
||||||
@return YES if the key event was handled, NO if no responder handled the key event
|
@return YES if the key event was handled, NO if no responder handled the key event
|
||||||
*/
|
*/
|
||||||
- (BOOL)_processKeyboardUIKey:(CPEvent)anEvent
|
- (BOOL)_processKeyboardUIKey:(CPEvent)anEvent
|
||||||
{
|
{
|
||||||
var character = [anEvent charactersIgnoringModifiers],
|
var character = [anEvent charactersIgnoringModifiers];
|
||||||
uiKeys = [CPLeftArrowFunctionKey, CPRightArrowFunctionKey, CPUpArrowFunctionKey, CPDownArrowFunctionKey, CPPageUpFunctionKey, CPPageDownFunctionKey, CPEscapeFunctionKey];
|
|
||||||
|
|
||||||
if (![uiKeys containsObject:character])
|
if (![CPWindowActionMessageKeys containsObject:character])
|
||||||
return NO;
|
|
||||||
|
|
||||||
var selectors = [CPKeyBinding selectorsForKey:character modifierFlags:0];
|
|
||||||
|
|
||||||
if ([selectors count] <= 0)
|
|
||||||
return NO;
|
|
||||||
|
|
||||||
if (character !== CPEscapeFunctionKey)
|
|
||||||
{
|
|
||||||
var selector = [selectors objectAtIndex:0];
|
|
||||||
return [[self firstResponder] tryToPerform:selector with:self];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Cocoa sends complete: for the escape key (in stead of the default cancelOperation:)
|
|
||||||
// This is also the only action that is not sent directly to the first responder, but through doCommandBySelector.
|
|
||||||
// The difference is that doCommandBySelector: will also send the action to the window and application delegates.
|
|
||||||
[[self firstResponder] doCommandBySelector:@selector(complete:)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
@ignore
|
|
||||||
Interprets the key event for action messages and sends the action message down the responder chain
|
|
||||||
Cocoa only sends moveDown:, moveUp:, moveLeft:, moveRight:, pageUp:, pageDown: and complete: messages.
|
|
||||||
We deviate from this by sending (the default) scrollPageUp: scrollPageDown: for pageUp and pageDown keys.
|
|
||||||
@param anEvent the event to handle.
|
|
||||||
@return YES if the key event was handled, NO if no responder handled the key event
|
|
||||||
*/
|
|
||||||
- (BOOL)_processKeyboardUIKey:(CPEvent)anEvent
|
|
||||||
{
|
|
||||||
var character = [anEvent charactersIgnoringModifiers],
|
|
||||||
uiKeys = [
|
|
||||||
CPLeftArrowFunctionKey,
|
|
||||||
CPRightArrowFunctionKey,
|
|
||||||
CPUpArrowFunctionKey,
|
|
||||||
CPDownArrowFunctionKey,
|
|
||||||
CPPageUpFunctionKey,
|
|
||||||
CPPageDownFunctionKey,
|
|
||||||
CPEscapeFunctionKey
|
|
||||||
];
|
|
||||||
|
|
||||||
if (![uiKeys containsObject:character])
|
|
||||||
return NO;
|
return NO;
|
||||||
|
|
||||||
var selectors = [CPKeyBinding selectorsForKey:character modifierFlags:0];
|
var selectors = [CPKeyBinding selectorsForKey:character modifierFlags:0];
|
||||||
@@ -2405,45 +2377,31 @@ CPTexturedBackgroundWindowMask
|
|||||||
|
|
||||||
- (BOOL)_hasKeyViewLoop
|
- (BOOL)_hasKeyViewLoop
|
||||||
{
|
{
|
||||||
var subviews = [];
|
var views = allViews(self),
|
||||||
|
index = [views count];
|
||||||
|
|
||||||
[self _appendSubviewsOf:_contentView toArray:subviews];
|
while (index--)
|
||||||
|
if ([views[index] nextKeyView])
|
||||||
for (var i = 0, count = [subviews count]; i<count; i++)
|
|
||||||
{
|
|
||||||
if (subviews[i]._nextKeyView)
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
|
||||||
|
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)recalculateKeyViewLoop
|
- (void)recalculateKeyViewLoop
|
||||||
{
|
{
|
||||||
var subviews = [];
|
var views = allViews(self);
|
||||||
|
|
||||||
[self _appendSubviewsOf:_contentView toArray:subviews];
|
[views sortUsingFunction:keyViewComparator context:nil];
|
||||||
|
|
||||||
var keyViewOrder = [subviews sortedArrayUsingFunction:keyViewComparator context:_contentView],
|
var index = 0,
|
||||||
count = [keyViewOrder count];
|
count = [views count];
|
||||||
|
|
||||||
for (var i=0; i<count; i++)
|
for (; index < count; ++index)
|
||||||
[keyViewOrder[i] setNextKeyView:keyViewOrder[(i+1)%count]];
|
[views[index] setNextKeyView:views[(index + 1) % count]];
|
||||||
|
|
||||||
_keyViewLoopIsDirty = NO;
|
_keyViewLoopIsDirty = NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_appendSubviewsOf:(CPView)aView toArray:(CPArray)anArray
|
|
||||||
{
|
|
||||||
var subviews = [aView subviews],
|
|
||||||
count = [subviews count];
|
|
||||||
|
|
||||||
while (count--)
|
|
||||||
[self _appendSubviewsOf:subviews[count] toArray:anArray];
|
|
||||||
|
|
||||||
[anArray addObject:aView];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setAutorecalculatesKeyViewLoop:(BOOL)shouldRecalculate
|
- (void)setAutorecalculatesKeyViewLoop:(BOOL)shouldRecalculate
|
||||||
{
|
{
|
||||||
if (_autorecalculatesKeyViewLoop === shouldRecalculate)
|
if (_autorecalculatesKeyViewLoop === shouldRecalculate)
|
||||||
@@ -2541,19 +2499,46 @@ CPTexturedBackgroundWindowMask
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
var keyViewComparator = function(a, b, context)
|
var allViews = function(aWindow)
|
||||||
{
|
{
|
||||||
var viewBounds = [a convertRect:[a bounds] toView:nil],
|
var views = [[aWindow contentView] subviews],
|
||||||
otherBounds = [b convertRect:[b bounds] toView:nil];
|
index = 0;
|
||||||
|
|
||||||
if (CGRectGetMinY(viewBounds) < CGRectGetMinY(otherBounds))
|
for (; index < views.length; ++index)
|
||||||
return -1;
|
views = views.concat([views[index] subviews]);
|
||||||
else if (CGRectGetMinY(viewBounds) == CGRectGetMinY(otherBounds) && CGRectGetMinX(viewBounds) < CGRectGetMinX(otherBounds))
|
|
||||||
return -1;
|
return views;
|
||||||
else if (CGRectGetMinX(viewBounds) == CGRectGetMinX(otherBounds) && CGRectGetMinX(viewBounds) == CGRectGetMinX(otherBounds))
|
}
|
||||||
return 0;
|
|
||||||
else
|
var keyViewComparator = function(lhs, rhs, context)
|
||||||
return 1;
|
{
|
||||||
|
var lhsBounds = [lhs convertRect:[lhs bounds] toView:nil],
|
||||||
|
rhsBounds = [rhs convertRect:[rhs bounds] toView:nil],
|
||||||
|
lhsY = _CGRectGetMinY(lhsBounds),
|
||||||
|
rhsY = _CGRectGetMinY(rhsBounds),
|
||||||
|
lhsX = _CGRectGetMinX(lhsBounds),
|
||||||
|
rhsX = _CGRectGetMinX(rhsBounds),
|
||||||
|
intersectsVertically = MIN(_CGRectGetMaxY(lhsBounds), _CGRectGetMaxY(rhsBounds)) - MAX(lhsY, rhsY);
|
||||||
|
|
||||||
|
// If two views are "on the same line" (intersect vertically), then rely on the x comparison.
|
||||||
|
if (intersectsVertically > 0)
|
||||||
|
{
|
||||||
|
if (lhsX < rhsX)
|
||||||
|
return CPOrderedAscending;
|
||||||
|
|
||||||
|
if (lhsX === rhsX)
|
||||||
|
return CPOrderedSame;
|
||||||
|
|
||||||
|
return CPOrderedDescending;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lhsY < rhsY)
|
||||||
|
return CPOrderedAscending;
|
||||||
|
|
||||||
|
if (lhsY === rhsY)
|
||||||
|
return CPOrderedSame;
|
||||||
|
|
||||||
|
return CPOrderedDescending;
|
||||||
}
|
}
|
||||||
|
|
||||||
@implementation CPWindow (MenuBar)
|
@implementation CPWindow (MenuBar)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ var _CPStandardWindowViewBodyBackgroundColor = nil;
|
|||||||
@implementation _CPDocModalWindowView : _CPWindowView
|
@implementation _CPDocModalWindowView : _CPWindowView
|
||||||
{
|
{
|
||||||
CPView _bodyView;
|
CPView _bodyView;
|
||||||
|
CPView _shadowView;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CPColor)bodyBackgroundColor
|
+ (CPColor)bodyBackgroundColor
|
||||||
@@ -25,13 +26,19 @@ var _CPStandardWindowViewBodyBackgroundColor = nil;
|
|||||||
var theClass = [self class],
|
var theClass = [self class],
|
||||||
bounds = [self bounds];
|
bounds = [self bounds];
|
||||||
|
|
||||||
_bodyView = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(bounds), CGRectGetHeight(bounds))];
|
_bodyView = [[CPView alloc] initWithFrame:_CGRectMake(0.0, 0.0, _CGRectGetWidth(bounds), _CGRectGetHeight(bounds))];
|
||||||
|
|
||||||
[_bodyView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
[_bodyView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
||||||
[_bodyView setBackgroundColor:[theClass bodyBackgroundColor]];
|
[_bodyView setBackgroundColor:[theClass bodyBackgroundColor]];
|
||||||
[_bodyView setHitTests:NO];
|
[_bodyView setHitTests:NO];
|
||||||
|
|
||||||
[self addSubview:_bodyView];
|
[self addSubview:_bodyView];
|
||||||
|
|
||||||
|
var bundle = [CPBundle bundleForClass:[CPWindow class]];
|
||||||
|
_shadowView = [[CPView alloc] initWithFrame:CGRectMake(0, 0, _CGRectGetWidth(bounds), 8)];
|
||||||
|
[_shadowView setAutoresizingMask:CPViewWidthSizable];
|
||||||
|
[_shadowView setBackgroundColor:[CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/CPWindowAttachedSheetShadow.png"] size:CGSizeMake(9,8)]]];
|
||||||
|
[self addSubview:_shadowView];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
|||||||
@@ -19,9 +19,11 @@
|
|||||||
* License along with this library; if not, write to the Free Software
|
* License along with this library; if not, write to the Free Software
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@import "CPTextField.j"
|
||||||
|
|
||||||
var _CPHUDWindowViewBackgroundColor = nil,
|
var _CPHUDWindowViewBackgroundColor = nil,
|
||||||
|
|
||||||
CPHUDCloseButtonImage = nil;
|
CPHUDCloseButtonImage = nil;
|
||||||
|
|
||||||
var HUD_TITLEBAR_HEIGHT = 26.0;
|
var HUD_TITLEBAR_HEIGHT = 26.0;
|
||||||
@@ -29,7 +31,7 @@ var HUD_TITLEBAR_HEIGHT = 26.0;
|
|||||||
@implementation _CPHUDWindowView : _CPWindowView
|
@implementation _CPHUDWindowView : _CPWindowView
|
||||||
{
|
{
|
||||||
CPView _toolbarView;
|
CPView _toolbarView;
|
||||||
|
|
||||||
CPTextField _titleField;
|
CPTextField _titleField;
|
||||||
CPButton _closeButton;
|
CPButton _closeButton;
|
||||||
}
|
}
|
||||||
@@ -38,19 +40,19 @@ var HUD_TITLEBAR_HEIGHT = 26.0;
|
|||||||
{
|
{
|
||||||
if (self != [_CPHUDWindowView class])
|
if (self != [_CPHUDWindowView class])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var bundle = [CPBundle bundleForClass:self];
|
var bundle = [CPBundle bundleForClass:self];
|
||||||
|
|
||||||
_CPHUDWindowViewBackgroundColor = [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:
|
_CPHUDWindowViewBackgroundColor = [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:
|
||||||
[
|
[
|
||||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground0.png"] size:CPSizeMake(7.0, 37.0)],
|
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground0.png"] size:CPSizeMake(7.0, 37.0)],
|
||||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground1.png"] size:CPSizeMake(1.0, 37.0)],
|
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground1.png"] size:CPSizeMake(1.0, 37.0)],
|
||||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground2.png"] size:CPSizeMake(7.0, 37.0)],
|
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground2.png"] size:CPSizeMake(7.0, 37.0)],
|
||||||
|
|
||||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground3.png"] size:CPSizeMake(7.0, 1.0)],
|
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground3.png"] size:CPSizeMake(7.0, 1.0)],
|
||||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground4.png"] size:CPSizeMake(2.0, 2.0)],
|
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground4.png"] size:CPSizeMake(2.0, 2.0)],
|
||||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground5.png"] size:CPSizeMake(7.0, 1.0)],
|
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground5.png"] size:CPSizeMake(7.0, 1.0)],
|
||||||
|
|
||||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground6.png"] size:CPSizeMake(7.0, 3.0)],
|
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground6.png"] size:CPSizeMake(7.0, 3.0)],
|
||||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground7.png"] size:CPSizeMake(1.0, 3.0)],
|
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground7.png"] size:CPSizeMake(1.0, 3.0)],
|
||||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground8.png"] size:CPSizeMake(7.0, 3.0)]
|
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground8.png"] size:CPSizeMake(7.0, 3.0)]
|
||||||
@@ -64,7 +66,7 @@ var HUD_TITLEBAR_HEIGHT = 26.0;
|
|||||||
{
|
{
|
||||||
var contentRect = CGRectMakeCopy(aFrameRect),
|
var contentRect = CGRectMakeCopy(aFrameRect),
|
||||||
titleBarHeight = HUD_TITLEBAR_HEIGHT;
|
titleBarHeight = HUD_TITLEBAR_HEIGHT;
|
||||||
|
|
||||||
contentRect.origin.y += titleBarHeight;
|
contentRect.origin.y += titleBarHeight;
|
||||||
contentRect.size.height -= titleBarHeight;
|
contentRect.size.height -= titleBarHeight;
|
||||||
|
|
||||||
@@ -75,92 +77,92 @@ var HUD_TITLEBAR_HEIGHT = 26.0;
|
|||||||
{
|
{
|
||||||
var frameRect = CGRectMakeCopy(aContentRect),
|
var frameRect = CGRectMakeCopy(aContentRect),
|
||||||
titleBarHeight = HUD_TITLEBAR_HEIGHT;
|
titleBarHeight = HUD_TITLEBAR_HEIGHT;
|
||||||
|
|
||||||
frameRect.origin.y -= titleBarHeight;
|
frameRect.origin.y -= titleBarHeight;
|
||||||
frameRect.size.height += titleBarHeight;
|
frameRect.size.height += titleBarHeight;
|
||||||
|
|
||||||
return frameRect;
|
return frameRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
|
- (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
|
||||||
{
|
{
|
||||||
var contentRect = [[self class] contentRectForFrameRect:aFrameRect];
|
var contentRect = [[self class] contentRectForFrameRect:aFrameRect];
|
||||||
|
|
||||||
if ([[[self window] toolbar] isVisible])
|
if ([[[self window] toolbar] isVisible])
|
||||||
{
|
{
|
||||||
toolbarHeight = CGRectGetHeight([[self toolbarView] frame]);
|
toolbarHeight = CGRectGetHeight([[self toolbarView] frame]);
|
||||||
|
|
||||||
contentRect.origin.y += toolbarHeight;
|
contentRect.origin.y += toolbarHeight;
|
||||||
contentRect.size.height -= toolbarHeight;
|
contentRect.size.height -= toolbarHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
return contentRect;
|
return contentRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGRect)frameRectForContentRect:(CGRect)aContentRect
|
- (CGRect)frameRectForContentRect:(CGRect)aContentRect
|
||||||
{
|
{
|
||||||
var frameRect = [[self class] frameRectForContentRect:aContentRect];
|
var frameRect = [[self class] frameRectForContentRect:aContentRect];
|
||||||
|
|
||||||
if ([[[self window] toolbar] isVisible])
|
if ([[[self window] toolbar] isVisible])
|
||||||
{
|
{
|
||||||
toolbarHeight = CGRectGetHeight([[self toolbarView] frame]);
|
toolbarHeight = CGRectGetHeight([[self toolbarView] frame]);
|
||||||
|
|
||||||
frameRect.origin.y -= toolbarHeight;
|
frameRect.origin.y -= toolbarHeight;
|
||||||
frameRect.size.height += toolbarHeight;
|
frameRect.size.height += toolbarHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
return frameRect;
|
return frameRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithFrame:(CPRect)aFrame styleMask:(unsigned)aStyleMask
|
- (id)initWithFrame:(CPRect)aFrame styleMask:(unsigned)aStyleMask
|
||||||
{
|
{
|
||||||
self = [super initWithFrame:aFrame styleMask:aStyleMask];
|
self = [super initWithFrame:aFrame styleMask:aStyleMask];
|
||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
var bounds = [self bounds];
|
var bounds = [self bounds];
|
||||||
|
|
||||||
[self setBackgroundColor:_CPHUDWindowViewBackgroundColor];
|
[self setBackgroundColor:_CPHUDWindowViewBackgroundColor];
|
||||||
|
|
||||||
_titleField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
|
_titleField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
|
||||||
|
|
||||||
[_titleField setHitTests:NO];
|
[_titleField setHitTests:NO];
|
||||||
[_titleField setFont:[CPFont systemFontOfSize:11.0]];
|
[_titleField setFont:[CPFont systemFontOfSize:11.0]];
|
||||||
[_titleField setTextColor:[CPColor whiteColor]];
|
[_titleField setTextColor:[CPColor whiteColor]];
|
||||||
[_titleField setTextShadowColor:[CPColor blackColor]];
|
[_titleField setTextShadowColor:[CPColor blackColor]];
|
||||||
[_titleField setTextShadowOffset:CGSizeMake(0.0, 1.0)];
|
[_titleField setTextShadowOffset:CGSizeMake(0.0, 1.0)];
|
||||||
[_titleField setAutoresizingMask:CPViewWidthSizable];
|
[_titleField setAutoresizingMask:CPViewWidthSizable];
|
||||||
|
|
||||||
// FIXME: Make this to CPLineBreakByTruncatingMiddle once it's implemented.
|
// FIXME: Make this to CPLineBreakByTruncatingMiddle once it's implemented.
|
||||||
[_titleField setLineBreakMode:CPLineBreakByTruncatingTail];
|
[_titleField setLineBreakMode:CPLineBreakByTruncatingTail];
|
||||||
[_titleField setAlignment:CPCenterTextAlignment];
|
[_titleField setAlignment:CPCenterTextAlignment];
|
||||||
|
|
||||||
[_titleField setStringValue:@"Untitled"];
|
[_titleField setStringValue:@"Untitled"];
|
||||||
[_titleField sizeToFit];
|
[_titleField sizeToFit];
|
||||||
[_titleField setAutoresizingMask:CPViewWidthSizable];
|
[_titleField setAutoresizingMask:CPViewWidthSizable];
|
||||||
[_titleField setStringValue:@""];
|
[_titleField setStringValue:@""];
|
||||||
|
|
||||||
[_titleField setFrame:CGRectMake(20.0, 3.0, CGRectGetWidth([self bounds]) - 40.0, CGRectGetHeight([_titleField frame]))];
|
[_titleField setFrame:CGRectMake(20.0, 3.0, CGRectGetWidth([self bounds]) - 40.0, CGRectGetHeight([_titleField frame]))];
|
||||||
|
|
||||||
[self addSubview:_titleField];
|
[self addSubview:_titleField];
|
||||||
|
|
||||||
if (_styleMask & CPClosableWindowMask)
|
if (_styleMask & CPClosableWindowMask)
|
||||||
{
|
{
|
||||||
var closeSize = [_CPHUDWindowViewCloseImage size];
|
var closeSize = [_CPHUDWindowViewCloseImage size];
|
||||||
|
|
||||||
_closeButton = [[CPButton alloc] initWithFrame:CGRectMake(8.0, 5.0, closeSize.width, closeSize.height)];
|
_closeButton = [[CPButton alloc] initWithFrame:CGRectMake(8.0, 5.0, closeSize.width, closeSize.height)];
|
||||||
|
|
||||||
[_closeButton setBordered:NO];
|
[_closeButton setBordered:NO];
|
||||||
|
|
||||||
[_closeButton setImage:_CPHUDWindowViewCloseImage];
|
[_closeButton setImage:_CPHUDWindowViewCloseImage];
|
||||||
[_closeButton setAlternateImage:_CPHUDWindowViewCloseActiveImage];
|
[_closeButton setAlternateImage:_CPHUDWindowViewCloseActiveImage];
|
||||||
|
|
||||||
[self addSubview:_closeButton];
|
[self addSubview:_closeButton];
|
||||||
}
|
}
|
||||||
|
|
||||||
[self setResizeIndicatorOffset:CGSizeMake(5.0, 5.0)];
|
[self setResizeIndicatorOffset:CGSizeMake(5.0, 5.0)];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@import "CPTextField.j"
|
||||||
@import "_CPWindowView.j"
|
@import "_CPWindowView.j"
|
||||||
|
|
||||||
|
|
||||||
@@ -40,7 +41,7 @@ var _CPTexturedWindowHeadGradientColor = nil,
|
|||||||
if (!_CPTexturedWindowHeadGradientColor)
|
if (!_CPTexturedWindowHeadGradientColor)
|
||||||
{
|
{
|
||||||
var bundle = [CPBundle bundleForClass:[_CPWindowView class]];
|
var bundle = [CPBundle bundleForClass:[_CPWindowView class]];
|
||||||
|
|
||||||
_CPTexturedWindowHeadGradientColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
|
_CPTexturedWindowHeadGradientColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
|
||||||
[
|
[
|
||||||
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/Standard/CPWindowStandardTop0.png"] size:CGSizeMake(6.0, 41.0)],
|
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/Standard/CPWindowStandardTop0.png"] size:CGSizeMake(6.0, 41.0)],
|
||||||
@@ -50,7 +51,7 @@ var _CPTexturedWindowHeadGradientColor = nil,
|
|||||||
isVertical:NO
|
isVertical:NO
|
||||||
]];
|
]];
|
||||||
}
|
}
|
||||||
|
|
||||||
return _CPTexturedWindowHeadGradientColor;
|
return _CPTexturedWindowHeadGradientColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,37 +59,37 @@ var _CPTexturedWindowHeadGradientColor = nil,
|
|||||||
{
|
{
|
||||||
if (!_CPTexturedWindowHeadSolidColor)
|
if (!_CPTexturedWindowHeadSolidColor)
|
||||||
_CPTexturedWindowHeadSolidColor = [CPColor colorWithCalibratedRed:195.0 / 255.0 green:195.0 / 255.0 blue:195.0 / 255.0 alpha:1.0];
|
_CPTexturedWindowHeadSolidColor = [CPColor colorWithCalibratedRed:195.0 / 255.0 green:195.0 / 255.0 blue:195.0 / 255.0 alpha:1.0];
|
||||||
|
|
||||||
return _CPTexturedWindowHeadSolidColor;
|
return _CPTexturedWindowHeadSolidColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithFrame:(CGRect)aFrame
|
- (id)initWithFrame:(CGRect)aFrame
|
||||||
{
|
{
|
||||||
self = [super initWithFrame:aFrame];
|
self = [super initWithFrame:aFrame];
|
||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
var theClass = [self class],
|
var theClass = [self class],
|
||||||
bounds = [self bounds];
|
bounds = [self bounds];
|
||||||
|
|
||||||
_gradientView = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(bounds), GRADIENT_HEIGHT)];
|
_gradientView = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(bounds), GRADIENT_HEIGHT)];
|
||||||
[_gradientView setBackgroundColor:[theClass gradientColor]];
|
[_gradientView setBackgroundColor:[theClass gradientColor]];
|
||||||
|
|
||||||
[self addSubview:_gradientView];
|
[self addSubview:_gradientView];
|
||||||
|
|
||||||
_solidView = [[CPView alloc] initWithFrame:CGRectMake(0.0, GRADIENT_HEIGHT, CGRectGetWidth(bounds), CGRectGetHeight(bounds) - GRADIENT_HEIGHT)];
|
_solidView = [[CPView alloc] initWithFrame:CGRectMake(0.0, GRADIENT_HEIGHT, CGRectGetWidth(bounds), CGRectGetHeight(bounds) - GRADIENT_HEIGHT)];
|
||||||
[_solidView setBackgroundColor:[theClass solidColor]];
|
[_solidView setBackgroundColor:[theClass solidColor]];
|
||||||
|
|
||||||
[self addSubview:_solidView];
|
[self addSubview:_solidView];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)resizeSubviewsWithOldSize:(CGSize)aSize
|
- (void)resizeSubviewsWithOldSize:(CGSize)aSize
|
||||||
{
|
{
|
||||||
var bounds = [self bounds];
|
var bounds = [self bounds];
|
||||||
|
|
||||||
[_gradientView setFrameSize:CGSizeMake(CGRectGetWidth(bounds), GRADIENT_HEIGHT)];
|
[_gradientView setFrameSize:CGSizeMake(CGRectGetWidth(bounds), GRADIENT_HEIGHT)];
|
||||||
[_solidView setFrameSize:CGSizeMake(CGRectGetWidth(bounds), CGRectGetHeight(bounds) - GRADIENT_HEIGHT)];
|
[_solidView setFrameSize:CGSizeMake(CGRectGetWidth(bounds), CGRectGetHeight(bounds) - GRADIENT_HEIGHT)];
|
||||||
}
|
}
|
||||||
@@ -114,7 +115,7 @@ var STANDARD_GRADIENT_HEIGHT = 41.0;
|
|||||||
CPView _dividerView;
|
CPView _dividerView;
|
||||||
CPView _bodyView;
|
CPView _bodyView;
|
||||||
CPView _toolbarView;
|
CPView _toolbarView;
|
||||||
|
|
||||||
CPTextField _titleField;
|
CPTextField _titleField;
|
||||||
CPButton _closeButton;
|
CPButton _closeButton;
|
||||||
CPButton _minimizeButton;
|
CPButton _minimizeButton;
|
||||||
@@ -126,15 +127,15 @@ var STANDARD_GRADIENT_HEIGHT = 41.0;
|
|||||||
{
|
{
|
||||||
if (!_CPStandardWindowViewBodyBackgroundColor)
|
if (!_CPStandardWindowViewBodyBackgroundColor)
|
||||||
_CPStandardWindowViewBodyBackgroundColor = [CPColor colorWithWhite:0.96 alpha:1.0];
|
_CPStandardWindowViewBodyBackgroundColor = [CPColor colorWithWhite:0.96 alpha:1.0];
|
||||||
|
|
||||||
return _CPStandardWindowViewBodyBackgroundColor;
|
return _CPStandardWindowViewBodyBackgroundColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (CPColor)dividerBackgroundColor
|
+ (CPColor)dividerBackgroundColor
|
||||||
{
|
{
|
||||||
if (!_CPStandardWindowViewDividerBackgroundColor)
|
if (!_CPStandardWindowViewDividerBackgroundColor)
|
||||||
_CPStandardWindowViewDividerBackgroundColor = [CPColor colorWithCalibratedRed:125.0 / 255.0 green:125.0 / 255.0 blue:125.0 / 255.0 alpha:1.0];
|
_CPStandardWindowViewDividerBackgroundColor = [CPColor colorWithCalibratedRed:125.0 / 255.0 green:125.0 / 255.0 blue:125.0 / 255.0 alpha:1.0];
|
||||||
|
|
||||||
return _CPStandardWindowViewDividerBackgroundColor;
|
return _CPStandardWindowViewDividerBackgroundColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +143,7 @@ var STANDARD_GRADIENT_HEIGHT = 41.0;
|
|||||||
{
|
{
|
||||||
if (!_CPStandardWindowViewTitleBackgroundColor)
|
if (!_CPStandardWindowViewTitleBackgroundColor)
|
||||||
_CPStandardWindowViewTitleBackgroundColor = [CPColor colorWithCalibratedRed:44.0 / 255.0 green:44.0 / 255.0 blue:44.0 / 255.0 alpha:1.0];
|
_CPStandardWindowViewTitleBackgroundColor = [CPColor colorWithCalibratedRed:44.0 / 255.0 green:44.0 / 255.0 blue:44.0 / 255.0 alpha:1.0];
|
||||||
|
|
||||||
return _CPStandardWindowViewTitleBackgroundColor;
|
return _CPStandardWindowViewTitleBackgroundColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,7 +151,7 @@ var STANDARD_GRADIENT_HEIGHT = 41.0;
|
|||||||
{
|
{
|
||||||
var contentRect = CGRectMakeCopy(aFrameRect),
|
var contentRect = CGRectMakeCopy(aFrameRect),
|
||||||
titleBarHeight = [self titleBarHeight] + 1.0;
|
titleBarHeight = [self titleBarHeight] + 1.0;
|
||||||
|
|
||||||
contentRect.origin.y += titleBarHeight;
|
contentRect.origin.y += titleBarHeight;
|
||||||
contentRect.size.height -= titleBarHeight;
|
contentRect.size.height -= titleBarHeight;
|
||||||
|
|
||||||
@@ -161,10 +162,10 @@ var STANDARD_GRADIENT_HEIGHT = 41.0;
|
|||||||
{
|
{
|
||||||
var frameRect = CGRectMakeCopy(aContentRect),
|
var frameRect = CGRectMakeCopy(aContentRect),
|
||||||
titleBarHeight = [self titleBarHeight] + 1.0;
|
titleBarHeight = [self titleBarHeight] + 1.0;
|
||||||
|
|
||||||
frameRect.origin.y -= titleBarHeight;
|
frameRect.origin.y -= titleBarHeight;
|
||||||
frameRect.size.height += titleBarHeight;
|
frameRect.size.height += titleBarHeight;
|
||||||
|
|
||||||
return frameRect;
|
return frameRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,15 +178,15 @@ var STANDARD_GRADIENT_HEIGHT = 41.0;
|
|||||||
{
|
{
|
||||||
var contentRect = [[self class] contentRectForFrameRect:aFrameRect],
|
var contentRect = [[self class] contentRectForFrameRect:aFrameRect],
|
||||||
theToolbar = [[self window] toolbar];
|
theToolbar = [[self window] toolbar];
|
||||||
|
|
||||||
if ([theToolbar isVisible])
|
if ([theToolbar isVisible])
|
||||||
{
|
{
|
||||||
toolbarHeight = CGRectGetHeight([[theToolbar _toolbarView] frame]);
|
toolbarHeight = CGRectGetHeight([[theToolbar _toolbarView] frame]);
|
||||||
|
|
||||||
contentRect.origin.y += toolbarHeight;
|
contentRect.origin.y += toolbarHeight;
|
||||||
contentRect.size.height -= toolbarHeight;
|
contentRect.size.height -= toolbarHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
return contentRect;
|
return contentRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,72 +194,72 @@ var STANDARD_GRADIENT_HEIGHT = 41.0;
|
|||||||
{
|
{
|
||||||
var frameRect = [[self class] frameRectForContentRect:aContentRect],
|
var frameRect = [[self class] frameRectForContentRect:aContentRect],
|
||||||
theToolbar = [[self window] toolbar];
|
theToolbar = [[self window] toolbar];
|
||||||
|
|
||||||
if ([theToolbar isVisible])
|
if ([theToolbar isVisible])
|
||||||
{
|
{
|
||||||
toolbarHeight = CGRectGetHeight([[theToolbar _toolbarView] frame]);
|
toolbarHeight = CGRectGetHeight([[theToolbar _toolbarView] frame]);
|
||||||
|
|
||||||
frameRect.origin.y -= toolbarHeight;
|
frameRect.origin.y -= toolbarHeight;
|
||||||
frameRect.size.height += toolbarHeight;
|
frameRect.size.height += toolbarHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
return frameRect;
|
return frameRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithFrame:(CPRect)aFrame styleMask:(unsigned)aStyleMask
|
- (id)initWithFrame:(CPRect)aFrame styleMask:(unsigned)aStyleMask
|
||||||
{
|
{
|
||||||
self = [super initWithFrame:aFrame styleMask:aStyleMask];
|
self = [super initWithFrame:aFrame styleMask:aStyleMask];
|
||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
var theClass = [self class],
|
var theClass = [self class],
|
||||||
bounds = [self bounds];
|
bounds = [self bounds];
|
||||||
|
|
||||||
_headView = [[_CPTexturedWindowHeadView alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(bounds), [[self class] titleBarHeight])];
|
_headView = [[_CPTexturedWindowHeadView alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(bounds), [[self class] titleBarHeight])];
|
||||||
|
|
||||||
[_headView setAutoresizingMask:CPViewWidthSizable];;
|
[_headView setAutoresizingMask:CPViewWidthSizable];;
|
||||||
[_headView setHitTests:NO];
|
[_headView setHitTests:NO];
|
||||||
|
|
||||||
[self addSubview:_headView];
|
[self addSubview:_headView];
|
||||||
|
|
||||||
_dividerView = [[CPView alloc] initWithFrame:CGRectMake(0.0, CGRectGetMaxY([_headView frame]), CGRectGetWidth(bounds), 1.0)];
|
_dividerView = [[CPView alloc] initWithFrame:CGRectMake(0.0, CGRectGetMaxY([_headView frame]), CGRectGetWidth(bounds), 1.0)];
|
||||||
|
|
||||||
[_dividerView setAutoresizingMask:CPViewWidthSizable];
|
[_dividerView setAutoresizingMask:CPViewWidthSizable];
|
||||||
[_dividerView setBackgroundColor:[theClass dividerBackgroundColor]];
|
[_dividerView setBackgroundColor:[theClass dividerBackgroundColor]];
|
||||||
[_dividerView setHitTests:NO];
|
[_dividerView setHitTests:NO];
|
||||||
|
|
||||||
[self addSubview:_dividerView];
|
[self addSubview:_dividerView];
|
||||||
|
|
||||||
var y = CGRectGetMaxY([_dividerView frame]);
|
var y = CGRectGetMaxY([_dividerView frame]);
|
||||||
|
|
||||||
_bodyView = [[CPView alloc] initWithFrame:CGRectMake(0.0, y, CGRectGetWidth(bounds), CGRectGetHeight(bounds) - y)];
|
_bodyView = [[CPView alloc] initWithFrame:CGRectMake(0.0, y, CGRectGetWidth(bounds), CGRectGetHeight(bounds) - y)];
|
||||||
|
|
||||||
[_bodyView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
[_bodyView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
||||||
[_bodyView setBackgroundColor:[theClass bodyBackgroundColor]];
|
[_bodyView setBackgroundColor:[theClass bodyBackgroundColor]];
|
||||||
[_bodyView setHitTests:NO];
|
[_bodyView setHitTests:NO];
|
||||||
|
|
||||||
[self addSubview:_bodyView];
|
[self addSubview:_bodyView];
|
||||||
|
|
||||||
[self setResizeIndicatorOffset:CGSizeMake(2.0, 2.0)];
|
[self setResizeIndicatorOffset:CGSizeMake(2.0, 2.0)];
|
||||||
|
|
||||||
_titleField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
|
_titleField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
|
||||||
|
|
||||||
[_titleField setFont:[CPFont boldSystemFontOfSize:12.0]];
|
[_titleField setFont:[CPFont boldSystemFontOfSize:12.0]];
|
||||||
[_titleField setAutoresizingMask:CPViewWidthSizable];
|
[_titleField setAutoresizingMask:CPViewWidthSizable];
|
||||||
|
|
||||||
// FIXME: Make this to CPLineBreakByTruncatingMiddle once it's implemented.
|
// FIXME: Make this to CPLineBreakByTruncatingMiddle once it's implemented.
|
||||||
[_titleField setLineBreakMode:CPLineBreakByTruncatingTail];
|
[_titleField setLineBreakMode:CPLineBreakByTruncatingTail];
|
||||||
[_titleField setAlignment:CPCenterTextAlignment];
|
[_titleField setAlignment:CPCenterTextAlignment];
|
||||||
[_titleField setTextShadowColor:[CPColor whiteColor]];
|
[_titleField setTextShadowColor:[CPColor whiteColor]];
|
||||||
[_titleField setTextShadowOffset:CGSizeMake(0.0, 1.0)];
|
[_titleField setTextShadowOffset:CGSizeMake(0.0, 1.0)];
|
||||||
|
|
||||||
[_titleField setStringValue:@"Untitled"];
|
[_titleField setStringValue:@"Untitled"];
|
||||||
[_titleField sizeToFit];
|
[_titleField sizeToFit];
|
||||||
[_titleField setAutoresizingMask:CPViewWidthSizable];
|
[_titleField setAutoresizingMask:CPViewWidthSizable];
|
||||||
[_titleField setStringValue:@""];
|
[_titleField setStringValue:@""];
|
||||||
|
|
||||||
[self addSubview:_titleField];
|
[self addSubview:_titleField];
|
||||||
|
|
||||||
if (_styleMask & CPClosableWindowMask)
|
if (_styleMask & CPClosableWindowMask)
|
||||||
{
|
{
|
||||||
if (!_CPStandardWindowViewCloseButtonImage)
|
if (!_CPStandardWindowViewCloseButtonImage)
|
||||||
|
|||||||
@@ -29,15 +29,14 @@ var _CPWindowViewResizeIndicatorImage = nil;
|
|||||||
@implementation _CPWindowView : CPView
|
@implementation _CPWindowView : CPView
|
||||||
{
|
{
|
||||||
unsigned _styleMask;
|
unsigned _styleMask;
|
||||||
|
|
||||||
CPImageView _resizeIndicator;
|
CPImageView _resizeIndicator;
|
||||||
CGSize _resizeIndicatorOffset;
|
CGSize _resizeIndicatorOffset;
|
||||||
|
|
||||||
CPView _toolbarView;
|
CPView _toolbarView;
|
||||||
CGSize _toolbarOffset;
|
CGSize _toolbarOffset;
|
||||||
// BOOL _isAnimatingToolbar;
|
// BOOL _isAnimatingToolbar;
|
||||||
|
|
||||||
|
|
||||||
CGRect _resizeFrame;
|
CGRect _resizeFrame;
|
||||||
CGPoint _mouseDraggedPoint;
|
CGPoint _mouseDraggedPoint;
|
||||||
|
|
||||||
@@ -48,7 +47,7 @@ var _CPWindowViewResizeIndicatorImage = nil;
|
|||||||
{
|
{
|
||||||
if (self != [_CPWindowView class])
|
if (self != [_CPWindowView class])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_CPWindowViewResizeIndicatorImage = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPWindow class]] pathForResource:@"_CPWindowView/_CPWindowViewResizeIndicator.png"] size:CGSizeMake(12.0, 12.0)];
|
_CPWindowViewResizeIndicatorImage = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPWindow class]] pathForResource:@"_CPWindowView/_CPWindowViewResizeIndicator.png"] size:CGSizeMake(12.0, 12.0)];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,14 +74,14 @@ var _CPWindowViewResizeIndicatorImage = nil;
|
|||||||
- (id)initWithFrame:(CPRect)aFrame styleMask:(unsigned)aStyleMask
|
- (id)initWithFrame:(CPRect)aFrame styleMask:(unsigned)aStyleMask
|
||||||
{
|
{
|
||||||
self = [super initWithFrame:aFrame];
|
self = [super initWithFrame:aFrame];
|
||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
_styleMask = aStyleMask;
|
_styleMask = aStyleMask;
|
||||||
_resizeIndicatorOffset = CGSizeMakeZero();
|
_resizeIndicatorOffset = CGSizeMakeZero();
|
||||||
_toolbarOffset = CGSizeMakeZero();
|
_toolbarOffset = CGSizeMakeZero();
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,14 +106,14 @@ var _CPWindowViewResizeIndicatorImage = nil;
|
|||||||
{
|
{
|
||||||
// FIXME: This should be better
|
// FIXME: This should be better
|
||||||
var frame = [_resizeIndicator frame];
|
var frame = [_resizeIndicator frame];
|
||||||
|
|
||||||
if (CGRectContainsPoint(frame, [self convertPoint:[anEvent locationInWindow] fromView:nil]))
|
if (CGRectContainsPoint(frame, [self convertPoint:[anEvent locationInWindow] fromView:nil]))
|
||||||
return [self trackResizeWithEvent:anEvent];
|
return [self trackResizeWithEvent:anEvent];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([theWindow isMovableByWindowBackground])
|
if ([theWindow isMovableByWindowBackground])
|
||||||
[self trackMoveWithEvent:anEvent];
|
[self trackMoveWithEvent:anEvent];
|
||||||
|
|
||||||
else
|
else
|
||||||
[super mouseDown:anEvent];
|
[super mouseDown:anEvent];
|
||||||
}
|
}
|
||||||
@@ -123,29 +122,29 @@ var _CPWindowViewResizeIndicatorImage = nil;
|
|||||||
{
|
{
|
||||||
var location = [anEvent locationInWindow],
|
var location = [anEvent locationInWindow],
|
||||||
type = [anEvent type];
|
type = [anEvent type];
|
||||||
|
|
||||||
if (type === CPLeftMouseUp)
|
if (type === CPLeftMouseUp)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var theWindow = [self window];
|
var theWindow = [self window];
|
||||||
|
|
||||||
if (type === CPLeftMouseDown)
|
if (type === CPLeftMouseDown)
|
||||||
{
|
{
|
||||||
var frame = [theWindow frame];
|
var frame = [theWindow frame];
|
||||||
|
|
||||||
_resizeFrame = CGRectMake(location.x, location.y, CGRectGetWidth(frame), CGRectGetHeight(frame));
|
_resizeFrame = CGRectMake(location.x, location.y, CGRectGetWidth(frame), CGRectGetHeight(frame));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (type === CPLeftMouseDragged)
|
else if (type === CPLeftMouseDragged)
|
||||||
{
|
{
|
||||||
var newSize = CGSizeMake(CGRectGetWidth(_resizeFrame) + location.x - CGRectGetMinX(_resizeFrame), CGRectGetHeight(_resizeFrame) + location.y - CGRectGetMinY(_resizeFrame));
|
var newSize = CGSizeMake(CGRectGetWidth(_resizeFrame) + location.x - CGRectGetMinX(_resizeFrame), CGRectGetHeight(_resizeFrame) + location.y - CGRectGetMinY(_resizeFrame));
|
||||||
|
|
||||||
if (theWindow._isSheet && theWindow._parentView && (theWindow._frame.size.width !== newSize.width))
|
if (theWindow._isSheet && theWindow._parentView && (theWindow._frame.size.width !== newSize.width))
|
||||||
[theWindow._parentView _setAttachedSheetFrameOrigin];
|
[theWindow._parentView _setAttachedSheetFrameOrigin];
|
||||||
|
|
||||||
[theWindow setFrameSize:newSize];
|
[theWindow setFrameSize:newSize];
|
||||||
}
|
}
|
||||||
|
|
||||||
[CPApp setTarget:self selector:@selector(trackResizeWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
|
[CPApp setTarget:self selector:@selector(trackResizeWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,10 +160,10 @@ var _CPWindowViewResizeIndicatorImage = nil;
|
|||||||
visibleFrame = [[CPPlatformWindow primaryPlatformWindow] visibleFrame];
|
visibleFrame = [[CPPlatformWindow primaryPlatformWindow] visibleFrame];
|
||||||
|
|
||||||
var minPointY = 0;
|
var minPointY = 0;
|
||||||
|
|
||||||
if([CPMenu menuBarVisible])
|
if([CPMenu menuBarVisible])
|
||||||
minPointY = [[CPApp mainMenu] menuBarHeight];
|
minPointY = [[CPApp mainMenu] menuBarHeight];
|
||||||
|
|
||||||
var restrictedPoint = CGPointMake(0, 0);
|
var restrictedPoint = CGPointMake(0, 0);
|
||||||
|
|
||||||
restrictedPoint.x = MIN(MAX(aPoint.x, -_frame.size.width + 4.0), CGRectGetMaxX(visibleFrame) - 4.0);
|
restrictedPoint.x = MIN(MAX(aPoint.x, -_frame.size.width + 4.0), CGRectGetMaxX(visibleFrame) - 4.0);
|
||||||
@@ -194,14 +193,14 @@ var _CPWindowViewResizeIndicatorImage = nil;
|
|||||||
var theWindow = [self window],
|
var theWindow = [self window],
|
||||||
frame = [theWindow frame],
|
frame = [theWindow frame],
|
||||||
location = [theWindow convertBaseToGlobal:[anEvent locationInWindow]],
|
location = [theWindow convertBaseToGlobal:[anEvent locationInWindow]],
|
||||||
origin = [self _pointWithinScreenFrame:CGPointMake(_CGRectGetMinX(frame) + (location.x - _mouseDraggedPoint.x),
|
origin = [self _pointWithinScreenFrame:CGPointMake(_CGRectGetMinX(frame) + (location.x - _mouseDraggedPoint.x),
|
||||||
_CGRectGetMinY(frame) + (location.y - _mouseDraggedPoint.y))];
|
_CGRectGetMinY(frame) + (location.y - _mouseDraggedPoint.y))];
|
||||||
|
|
||||||
[theWindow setFrameOrigin:origin];
|
[theWindow setFrameOrigin:origin];
|
||||||
|
|
||||||
_mouseDraggedPoint = [self _pointWithinScreenFrame:location];
|
_mouseDraggedPoint = [self _pointWithinScreenFrame:location];
|
||||||
}
|
}
|
||||||
|
|
||||||
[CPApp setTarget:self selector:@selector(trackMoveWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
|
[CPApp setTarget:self selector:@selector(trackMoveWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,9 +210,9 @@ var _CPWindowViewResizeIndicatorImage = nil;
|
|||||||
{
|
{
|
||||||
var size = [_CPWindowViewResizeIndicatorImage size],
|
var size = [_CPWindowViewResizeIndicatorImage size],
|
||||||
boundsSize = [self frame].size;
|
boundsSize = [self frame].size;
|
||||||
|
|
||||||
_resizeIndicator = [[CPImageView alloc] initWithFrame:CGRectMake(boundsSize.width - size.width - _resizeIndicatorOffset.width, boundsSize.height - size.height - _resizeIndicatorOffset.height, size.width, size.height)];
|
_resizeIndicator = [[CPImageView alloc] initWithFrame:CGRectMake(boundsSize.width - size.width - _resizeIndicatorOffset.width, boundsSize.height - size.height - _resizeIndicatorOffset.height, size.width, size.height)];
|
||||||
|
|
||||||
[_resizeIndicator setImage:_CPWindowViewResizeIndicatorImage];
|
[_resizeIndicator setImage:_CPWindowViewResizeIndicatorImage];
|
||||||
[_resizeIndicator setAutoresizingMask:CPViewMinXMargin | CPViewMinYMargin];
|
[_resizeIndicator setAutoresizingMask:CPViewMinXMargin | CPViewMinYMargin];
|
||||||
|
|
||||||
@@ -236,15 +235,15 @@ var _CPWindowViewResizeIndicatorImage = nil;
|
|||||||
{
|
{
|
||||||
if (CGSizeEqualToSize(_resizeIndicatorOffset, anOffset))
|
if (CGSizeEqualToSize(_resizeIndicatorOffset, anOffset))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_resizeIndicatorOffset = anOffset;
|
_resizeIndicatorOffset = anOffset;
|
||||||
|
|
||||||
if (!_resizeIndicator)
|
if (!_resizeIndicator)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var size = [_resizeIndicator frame].size,
|
var size = [_resizeIndicator frame].size,
|
||||||
boundsSize = [self frame].size;
|
boundsSize = [self frame].size;
|
||||||
|
|
||||||
[_resizeIndicator setFrameOrigin:CGPointMake(boundsSize.width - size.width - anOffset.width, boundsSize.height - size.height - anOffset.height)];
|
[_resizeIndicator setFrameOrigin:CGPointMake(boundsSize.width - size.width - anOffset.width, boundsSize.height - size.height - anOffset.height)];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,7 +279,7 @@ var _CPWindowViewResizeIndicatorImage = nil;
|
|||||||
{
|
{
|
||||||
if (!_toolbarView || [_toolbarView isHidden])
|
if (!_toolbarView || [_toolbarView isHidden])
|
||||||
return [self toolbarOffset].height;
|
return [self toolbarOffset].height;
|
||||||
|
|
||||||
return CGRectGetMaxY([_toolbarView frame]);
|
return CGRectGetMaxY([_toolbarView frame]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,20 +293,20 @@ var _CPWindowViewResizeIndicatorImage = nil;
|
|||||||
var theWindow = [self window],
|
var theWindow = [self window],
|
||||||
bounds = [self bounds],
|
bounds = [self bounds],
|
||||||
width = CGRectGetWidth(bounds);
|
width = CGRectGetWidth(bounds);
|
||||||
|
|
||||||
if ([[theWindow toolbar] isVisible])
|
if ([[theWindow toolbar] isVisible])
|
||||||
{
|
{
|
||||||
var toolbarView = [self toolbarView],
|
var toolbarView = [self toolbarView],
|
||||||
toolbarOffset = [self toolbarOffset];
|
toolbarOffset = [self toolbarOffset];
|
||||||
|
|
||||||
[toolbarView setFrame:CGRectMake(toolbarOffset.width, toolbarOffset.height, width, CGRectGetHeight([toolbarView frame]))];
|
[toolbarView setFrame:CGRectMake(toolbarOffset.width, toolbarOffset.height, width, CGRectGetHeight([toolbarView frame]))];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([self showsResizeIndicator])
|
if ([self showsResizeIndicator])
|
||||||
{
|
{
|
||||||
var size = [_resizeIndicator frame].size,
|
var size = [_resizeIndicator frame].size,
|
||||||
boundsSize = [self bounds].size;
|
boundsSize = [self bounds].size;
|
||||||
|
|
||||||
[_resizeIndicator setFrameOrigin:CGPointMake(boundsSize.width - size.width - _resizeIndicatorOffset.width, boundsSize.height - size.height - _resizeIndicatorOffset.height)];
|
[_resizeIndicator setFrameOrigin:CGPointMake(boundsSize.width - size.width - _resizeIndicatorOffset.width, boundsSize.height - size.height - _resizeIndicatorOffset.height)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -317,11 +316,11 @@ var _CPWindowViewResizeIndicatorImage = nil;
|
|||||||
var theWindow = [self window],
|
var theWindow = [self window],
|
||||||
toolbar = [theWindow toolbar],
|
toolbar = [theWindow toolbar],
|
||||||
toolbarView = [toolbar _toolbarView];
|
toolbarView = [toolbar _toolbarView];
|
||||||
|
|
||||||
if (_toolbarView !== toolbarView)
|
if (_toolbarView !== toolbarView)
|
||||||
{
|
{
|
||||||
[_toolbarView removeFromSuperview];
|
[_toolbarView removeFromSuperview];
|
||||||
|
|
||||||
if (toolbarView)
|
if (toolbarView)
|
||||||
{
|
{
|
||||||
[toolbarView removeFromSuperview];
|
[toolbarView removeFromSuperview];
|
||||||
@@ -329,7 +328,7 @@ var _CPWindowViewResizeIndicatorImage = nil;
|
|||||||
|
|
||||||
[self addSubview:toolbarView];
|
[self addSubview:toolbarView];
|
||||||
}
|
}
|
||||||
|
|
||||||
_toolbarView = toolbarView;
|
_toolbarView = toolbarView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
@import "CPDocument.j"
|
@import "CPDocument.j"
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ingroup appkit
|
@ingroup appkit
|
||||||
@class CPWindowController
|
@class CPWindowController
|
||||||
|
|
||||||
@@ -171,8 +171,8 @@
|
|||||||
|
|
||||||
if (_window === nil && [_cibOwner isKindOfClass:[CPDocument class]])
|
if (_window === nil && [_cibOwner isKindOfClass:[CPDocument class]])
|
||||||
[self setWindow:[_cibOwner valueForKey:@"window"]];
|
[self setWindow:[_cibOwner valueForKey:@"window"]];
|
||||||
|
|
||||||
if (!_window)
|
if (!_window)
|
||||||
{
|
{
|
||||||
var reason = [CPString stringWithFormat:@"Window for %@ could not be loaded from Cib or no window specified. \
|
var reason = [CPString stringWithFormat:@"Window for %@ could not be loaded from Cib or no window specified. \
|
||||||
Override loadWindow to load the window manually.", self];
|
Override loadWindow to load the window manually.", self];
|
||||||
@@ -232,7 +232,7 @@
|
|||||||
{
|
{
|
||||||
if (![self supportsMultipleDocuments])
|
if (![self supportsMultipleDocuments])
|
||||||
[self removeDocument:_document];
|
[self removeDocument:_document];
|
||||||
|
|
||||||
[defaultCenter removeObserver:self
|
[defaultCenter removeObserver:self
|
||||||
name:CPDocumentWillSaveNotification
|
name:CPDocumentWillSaveNotification
|
||||||
object:_document];
|
object:_document];
|
||||||
@@ -276,6 +276,10 @@
|
|||||||
[self setViewController:viewController];
|
[self setViewController:viewController];
|
||||||
|
|
||||||
[self synchronizeWindowTitleWithDocumentName];
|
[self synchronizeWindowTitleWithDocumentName];
|
||||||
|
|
||||||
|
// Change of document means toolbar items may no longer make sense.
|
||||||
|
// FIXME: DOCUMENT ARCHITECTURE Should we setToolbar: as well?
|
||||||
|
[[[self window] toolbar] validateVisibleItems];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setSupportsMultipleDocuments:(BOOL)shouldSupportMultipleDocuments
|
- (void)setSupportsMultipleDocuments:(BOOL)shouldSupportMultipleDocuments
|
||||||
@@ -381,7 +385,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Sets whether the document has unsaved changes. The window can use this as a hint to
|
Sets whether the document has unsaved changes. The window can use this as a hint to
|
||||||
@param isEdited \c YES means the document has unsaved changes.
|
@param isEdited \c YES means the document has unsaved changes.
|
||||||
*/
|
*/
|
||||||
- (void)setDocumentEdited:(BOOL)isEdited
|
- (void)setDocumentEdited:(BOOL)isEdited
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* CPCibBindingConnector.j
|
||||||
|
* AppKit
|
||||||
|
*
|
||||||
|
* Created by Ross Boucher.
|
||||||
|
* Copyright 2010, 280 North, Inc.
|
||||||
|
*
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
@import "CPCibConnector.j"
|
||||||
|
|
||||||
|
var CPCibBindingConnectorBindingKey = @"CPCibBindingConnectorBindingKey",
|
||||||
|
CPCibBindingConnectorKeyPathKey = @"CPCibBindingConnectorKeyPathKey",
|
||||||
|
CPCibBindingConnectorOptionsKey = @"CPCibBindingConnectorOptionsKey";
|
||||||
|
|
||||||
|
@implementation CPCibBindingConnector : CPCibConnector
|
||||||
|
{
|
||||||
|
id _binding;
|
||||||
|
id _keyPath;
|
||||||
|
id _options;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id)initWithCoder:(CPCoder)aCoder
|
||||||
|
{
|
||||||
|
if (self = [super initWithCoder:aCoder])
|
||||||
|
{
|
||||||
|
_binding = [aCoder decodeObjectForKey:CPCibBindingConnectorBindingKey];
|
||||||
|
_keyPath = [aCoder decodeObjectForKey:CPCibBindingConnectorKeyPathKey];
|
||||||
|
_options = [aCoder decodeObjectForKey:CPCibBindingConnectorOptionsKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)encodeWithCoder:(CPCoder)aCoder
|
||||||
|
{
|
||||||
|
[super encodeWithCoder:aCoder];
|
||||||
|
|
||||||
|
[aCoder encodeObject:_binding forKey:CPCibBindingConnectorBindingKey];
|
||||||
|
[aCoder encodeObject:_keyPath forKey:CPCibBindingConnectorKeyPathKey];
|
||||||
|
[aCoder encodeObject:_options forKey:CPCibBindingConnectorOptionsKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)establishConnection
|
||||||
|
{
|
||||||
|
[_source bind:_binding toObject:_destination withKeyPath:_keyPath options:_options];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -34,7 +34,7 @@ var _CPCibCustomObjectClassName = @"_CPCibCustomObjectClassName";
|
|||||||
|
|
||||||
if (self)
|
if (self)
|
||||||
_className = [aCoder decodeObjectForKey:_CPCibCustomObjectClassName];
|
_className = [aCoder decodeObjectForKey:_CPCibCustomObjectClassName];
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ var _CPCibCustomObjectClassName = @"_CPCibCustomObjectClassName";
|
|||||||
|
|
||||||
if (theClass === [CPApplication class])
|
if (theClass === [CPApplication class])
|
||||||
return [CPApplication sharedApplication];
|
return [CPApplication sharedApplication];
|
||||||
|
|
||||||
return [[theClass alloc] init];
|
return [[theClass alloc] init];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,36 +28,37 @@
|
|||||||
@import "CPCibConnector.j"
|
@import "CPCibConnector.j"
|
||||||
@import "CPCibControlConnector.j"
|
@import "CPCibControlConnector.j"
|
||||||
@import "CPCibOutletConnector.j"
|
@import "CPCibOutletConnector.j"
|
||||||
|
@import "CPCibBindingConnector.j"
|
||||||
|
|
||||||
|
|
||||||
@implementation _CPCibObjectData : CPObject
|
@implementation _CPCibObjectData : CPObject
|
||||||
{
|
{
|
||||||
CPArray _namesKeys;
|
CPArray _namesKeys;
|
||||||
CPArray _namesValues;
|
CPArray _namesValues;
|
||||||
|
|
||||||
CPArray _accessibilityConnectors;
|
CPArray _accessibilityConnectors;
|
||||||
CPArray _accessibilityOidsKeys;
|
CPArray _accessibilityOidsKeys;
|
||||||
CPArray _accessibilityOidsValues;
|
CPArray _accessibilityOidsValues;
|
||||||
|
|
||||||
CPArray _classesKeys;
|
CPArray _classesKeys;
|
||||||
CPArray _classesValues;
|
CPArray _classesValues;
|
||||||
|
|
||||||
CPArray _connections;
|
CPArray _connections;
|
||||||
|
|
||||||
id _fontManager;
|
id _fontManager;
|
||||||
|
|
||||||
CPString _framework;
|
CPString _framework;
|
||||||
|
|
||||||
int _nextOid;
|
int _nextOid;
|
||||||
|
|
||||||
CPArray _objectsKeys;
|
CPArray _objectsKeys;
|
||||||
CPArray _objectsValues;
|
CPArray _objectsValues;
|
||||||
|
|
||||||
CPArray _oidKeys;
|
CPArray _oidKeys;
|
||||||
CPArray _oidValues;
|
CPArray _oidValues;
|
||||||
|
|
||||||
_CPCibCustomObject _fileOwner;
|
_CPCibCustomObject _fileOwner;
|
||||||
|
|
||||||
CPSet _visibleWindows;
|
CPSet _visibleWindows;
|
||||||
|
|
||||||
JSObject _replacementObjects;
|
JSObject _replacementObjects;
|
||||||
@@ -113,28 +114,28 @@
|
|||||||
|
|
||||||
var _CPCibObjectDataNamesKeysKey = @"_CPCibObjectDataNamesKeysKey",
|
var _CPCibObjectDataNamesKeysKey = @"_CPCibObjectDataNamesKeysKey",
|
||||||
_CPCibObjectDataNamesValuesKey = @"_CPCibObjectDataNamesValuesKey",
|
_CPCibObjectDataNamesValuesKey = @"_CPCibObjectDataNamesValuesKey",
|
||||||
|
|
||||||
_CPCibObjectDataAccessibilityConnectorsKey = @"_CPCibObjectDataAccessibilityConnectors",
|
_CPCibObjectDataAccessibilityConnectorsKey = @"_CPCibObjectDataAccessibilityConnectors",
|
||||||
_CPCibObjectDataAccessibilityOidsKeysKey = @"_CPCibObjectDataAccessibilityOidsKeys",
|
_CPCibObjectDataAccessibilityOidsKeysKey = @"_CPCibObjectDataAccessibilityOidsKeys",
|
||||||
_CPCibObjectDataAccessibilityOidsValuesKey = @"_CPCibObjectDataAccessibilityOidsValues",
|
_CPCibObjectDataAccessibilityOidsValuesKey = @"_CPCibObjectDataAccessibilityOidsValues",
|
||||||
|
|
||||||
_CPCibObjectDataClassesKeysKey = @"_CPCibObjectDataClassesKeysKey",
|
_CPCibObjectDataClassesKeysKey = @"_CPCibObjectDataClassesKeysKey",
|
||||||
_CPCibObjectDataClassesValuesKey = @"_CPCibObjectDataClassesValuesKey",
|
_CPCibObjectDataClassesValuesKey = @"_CPCibObjectDataClassesValuesKey",
|
||||||
|
|
||||||
_CPCibObjectDataConnectionsKey = @"_CPCibObjectDataConnectionsKey",
|
_CPCibObjectDataConnectionsKey = @"_CPCibObjectDataConnectionsKey",
|
||||||
|
|
||||||
_CPCibObjectDataFontManagerKey = @"_CPCibObjectDataFontManagerKey",
|
_CPCibObjectDataFontManagerKey = @"_CPCibObjectDataFontManagerKey",
|
||||||
|
|
||||||
_CPCibObjectDataFrameworkKey = @"_CPCibObjectDataFrameworkKey",
|
_CPCibObjectDataFrameworkKey = @"_CPCibObjectDataFrameworkKey",
|
||||||
|
|
||||||
_CPCibObjectDataNextOidKey = @"_CPCibObjectDataNextOidKey",
|
_CPCibObjectDataNextOidKey = @"_CPCibObjectDataNextOidKey",
|
||||||
|
|
||||||
_CPCibObjectDataObjectsKeysKey = @"_CPCibObjectDataObjectsKeysKey",
|
_CPCibObjectDataObjectsKeysKey = @"_CPCibObjectDataObjectsKeysKey",
|
||||||
_CPCibObjectDataObjectsValuesKey = @"_CPCibObjectDataObjectsValuesKey",
|
_CPCibObjectDataObjectsValuesKey = @"_CPCibObjectDataObjectsValuesKey",
|
||||||
|
|
||||||
_CPCibObjectDataOidKeysKey = @"_CPCibObjectDataOidKeysKey",
|
_CPCibObjectDataOidKeysKey = @"_CPCibObjectDataOidKeysKey",
|
||||||
_CPCibObjectDataOidValuesKey = @"_CPCibObjectDataOidValuesKey",
|
_CPCibObjectDataOidValuesKey = @"_CPCibObjectDataOidValuesKey",
|
||||||
|
|
||||||
_CPCibObjectDataFileOwnerKey = @"_CPCibObjectDataFileOwnerKey",
|
_CPCibObjectDataFileOwnerKey = @"_CPCibObjectDataFileOwnerKey",
|
||||||
_CPCibObjectDataVisibleWindowsKey = @"_CPCibObjectDataVisibleWindowsKey";
|
_CPCibObjectDataVisibleWindowsKey = @"_CPCibObjectDataVisibleWindowsKey";
|
||||||
|
|
||||||
@@ -194,17 +195,17 @@ var _CPCibObjectDataNamesKeysKey = @"_CPCibObjectDataNamesKeysKey
|
|||||||
[aCoder encodeObject:_connections forKey:_CPCibObjectDataConnectionsKey];
|
[aCoder encodeObject:_connections forKey:_CPCibObjectDataConnectionsKey];
|
||||||
|
|
||||||
//id _fontManager;
|
//id _fontManager;
|
||||||
|
|
||||||
[aCoder encodeObject:_framework forKey:_CPCibObjectDataFrameworkKey];
|
[aCoder encodeObject:_framework forKey:_CPCibObjectDataFrameworkKey];
|
||||||
|
|
||||||
[aCoder encodeInt:_nextOid forKey:_CPCibObjectDataNextOidKey];
|
[aCoder encodeInt:_nextOid forKey:_CPCibObjectDataNextOidKey];
|
||||||
|
|
||||||
[aCoder encodeObject:_objectsKeys forKey:_CPCibObjectDataObjectsKeysKey];
|
[aCoder encodeObject:_objectsKeys forKey:_CPCibObjectDataObjectsKeysKey];
|
||||||
[aCoder encodeObject:_objectsValues forKey:_CPCibObjectDataObjectsValuesKey];
|
[aCoder encodeObject:_objectsValues forKey:_CPCibObjectDataObjectsValuesKey];
|
||||||
|
|
||||||
[aCoder encodeObject:_oidKeys forKey:_CPCibObjectDataOidKeysKey];
|
[aCoder encodeObject:_oidKeys forKey:_CPCibObjectDataOidKeysKey];
|
||||||
[aCoder encodeObject:_oidValues forKey:_CPCibObjectDataOidValuesKey];
|
[aCoder encodeObject:_oidValues forKey:_CPCibObjectDataOidValuesKey];
|
||||||
|
|
||||||
[aCoder encodeObject:_fileOwner forKey:_CPCibObjectDataFileOwnerKey];
|
[aCoder encodeObject:_fileOwner forKey:_CPCibObjectDataFileOwnerKey];
|
||||||
// CPCustomObject _fileOwner;
|
// CPCustomObject _fileOwner;
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ function CFHashCode(aCFObject)
|
|||||||
{
|
{
|
||||||
if (!aCFObject.hash)
|
if (!aCFObject.hash)
|
||||||
aCFObject.hash = ++CFTypeGlobalCount;
|
aCFObject.hash = ++CFTypeGlobalCount;
|
||||||
|
|
||||||
return aCFObject;
|
return aCFObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ function CGColorGetConstantColor(aColorName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
This function is for source compatability.
|
This function is for source compatability.
|
||||||
*/
|
*/
|
||||||
function CGColorRetain(aColor)
|
function CGColorRetain(aColor)
|
||||||
{
|
{
|
||||||
@@ -55,7 +55,7 @@ function CGColorRetain(aColor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
This function is for source compatability.
|
This function is for source compatability.
|
||||||
*/
|
*/
|
||||||
function CGColorRelease()
|
function CGColorRelease()
|
||||||
{
|
{
|
||||||
@@ -74,14 +74,14 @@ function CGColorCreate(aColorSpace, components)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
var components = components.slice();
|
var components = components.slice();
|
||||||
|
|
||||||
CGColorSpaceStandardizeComponents(aColorSpace, components);
|
CGColorSpaceStandardizeComponents(aColorSpace, components);
|
||||||
|
|
||||||
var UID = CFHashCode(aColorSpace) + components.join("");
|
var UID = CFHashCode(aColorSpace) + components.join("");
|
||||||
|
|
||||||
if (_CGColorMap[UID])
|
if (_CGColorMap[UID])
|
||||||
return _CGColorMap[UID];
|
return _CGColorMap[UID];
|
||||||
|
|
||||||
return _CGColorMap[UID] = { colorspace:aColorSpace, pattern:NULL, components:components };
|
return _CGColorMap[UID] = { colorspace:aColorSpace, pattern:NULL, components:components };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,9 +150,9 @@ function CGColorCreateGenericCMYK(cyan, magenta, yellow, black, alpha)
|
|||||||
function CGColorCreateCopyWithAlpha(aColor, anAlpha)
|
function CGColorCreateCopyWithAlpha(aColor, anAlpha)
|
||||||
{
|
{
|
||||||
var components = aColor.components;
|
var components = aColor.components;
|
||||||
|
|
||||||
if (!aColor || anAlpha == components[components.length - 1])
|
if (!aColor || anAlpha == components[components.length - 1])
|
||||||
return aColor;
|
return aColor;
|
||||||
|
|
||||||
if (aColor.pattern)
|
if (aColor.pattern)
|
||||||
var copy = CGColorCreateWithPattern(aColor.colorspace, aColor.pattern, components);
|
var copy = CGColorCreateWithPattern(aColor.colorspace, aColor.pattern, components);
|
||||||
@@ -160,7 +160,7 @@ function CGColorCreateCopyWithAlpha(aColor, anAlpha)
|
|||||||
var copy = CGColorCreate(aColor.colorspace, components);
|
var copy = CGColorCreate(aColor.colorspace, components);
|
||||||
|
|
||||||
copy.components[components.length - 1] = anAlpha;
|
copy.components[components.length - 1] = anAlpha;
|
||||||
|
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ function CGColorEqualToColor(lhs, rhs)
|
|||||||
{
|
{
|
||||||
if (lhs == rhs)
|
if (lhs == rhs)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!lhs || !rhs)
|
if (!lhs || !rhs)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -201,17 +201,17 @@ function CGColorEqualToColor(lhs, rhs)
|
|||||||
|
|
||||||
if (lhsComponentCount != rhsComponents.length)
|
if (lhsComponentCount != rhsComponents.length)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
while (lhsComponentCount--)
|
while (lhsComponentCount--)
|
||||||
if (lhsComponents[lhsComponentCount] != rhsComponents[lhsComponentCount])
|
if (lhsComponents[lhsComponentCount] != rhsComponents[lhsComponentCount])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (lhs.pattern != rhs.pattern)
|
if (lhs.pattern != rhs.pattern)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (CGColorSpaceEqualToColorSpace(lhs.colorspace, rhs.colorspace))
|
if (CGColorSpaceEqualToColorSpace(lhs.colorspace, rhs.colorspace))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,7 +224,7 @@ function CGColorEqualToColor(lhs, rhs)
|
|||||||
function CGColorGetAlpha(aColor)
|
function CGColorGetAlpha(aColor)
|
||||||
{
|
{
|
||||||
var components = aColor.components;
|
var components = aColor.components;
|
||||||
|
|
||||||
return components[components.length - 1];
|
return components[components.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,13 +273,13 @@ function CGColorGetPattern(aColor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* var components = aColor.components;
|
/* var components = aColor.components;
|
||||||
|
|
||||||
case : _CGCSSForColor[CFGetHash(aColor)] = "rgba(" + ROUND(components[0] * 255.0) + ',' + ROUND(components[0] * 255.0) + ',' ROUND(components[0] * 255.0) + ',' + ROUND(components[0] * 255.0);
|
case : _CGCSSForColor[CFGetHash(aColor)] = "rgba(" + ROUND(components[0] * 255.0) + ',' + ROUND(components[0] * 255.0) + ',' ROUND(components[0] * 255.0) + ',' + ROUND(components[0] * 255.0);
|
||||||
_cssString = (hasAlpha ? "rgba(" : "rgb(") +
|
_cssString = (hasAlpha ? "rgba(" : "rgb(") +
|
||||||
parseInt(_components[0] * 255.0) + ", " +
|
parseInt(_components[0] * 255.0) + ", " +
|
||||||
parseInt(_components[1] * 255.0) + ", " +
|
parseInt(_components[1] * 255.0) + ", " +
|
||||||
parseInt(_components[2] * 255.0) +
|
parseInt(_components[2] * 255.0) +
|
||||||
(hasAlpha ? (", " + _components[3]) : "") + ")";
|
(hasAlpha ? (", " + _components[3]) : "") + ")";
|
||||||
|
|
||||||
function CFStringFromColor()
|
function CFStringFromColor()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
|
|
||||||
kCGLineCapButt = 0;
|
kCGLineCapButt = 0;
|
||||||
kCGLineCapRound = 1;
|
kCGLineCapRound = 1;
|
||||||
kCGLineCapSquare = 2;
|
kCGLineCapSquare = 2;
|
||||||
|
|
||||||
kCGLineJoinMiter = 0;
|
kCGLineJoinMiter = 0;
|
||||||
@@ -114,8 +114,8 @@ if (!CPFeatureIsCompatible(CPHTMLCanvasFeature))
|
|||||||
*/
|
*/
|
||||||
function CGGStateCreate()
|
function CGGStateCreate()
|
||||||
{
|
{
|
||||||
return { alpha:1.0, strokeStyle:"#000", fillStyle:"#ccc", lineWidth:1.0, lineJoin:kCGLineJoinMiter, lineCap:kCGLineCapButt, miterLimit:10.0, globalAlpha:1.0,
|
return { alpha:1.0, strokeStyle:"#000", fillStyle:"#ccc", lineWidth:1.0, lineJoin:kCGLineJoinMiter, lineCap:kCGLineCapButt, miterLimit:10.0, globalAlpha:1.0,
|
||||||
blendMode:kCGBlendModeNormal,
|
blendMode:kCGBlendModeNormal,
|
||||||
shadowOffset:_CGSizeMakeZero(), shadowBlur:0.0, shadowColor:NULL, CTM:_CGAffineTransformMakeIdentity() };
|
shadowOffset:_CGSizeMakeZero(), shadowBlur:0.0, shadowColor:NULL, CTM:_CGAffineTransformMakeIdentity() };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,9 +126,9 @@ function CGGStateCreate()
|
|||||||
*/
|
*/
|
||||||
function CGGStateCreateCopy(aGState)
|
function CGGStateCreateCopy(aGState)
|
||||||
{
|
{
|
||||||
return { alpha:aGState.alpha, strokeStyle:aGState.strokeStyle, fillStyle:aGState.fillStyle, lineWidth:aGState.lineWidth,
|
return { alpha:aGState.alpha, strokeStyle:aGState.strokeStyle, fillStyle:aGState.fillStyle, lineWidth:aGState.lineWidth,
|
||||||
lineJoin:aGState.lineJoin, lineCap:aGState.lineCap, miterLimit:aGState.miterLimit, globalAlpha:aGState.globalAlpha,
|
lineJoin:aGState.lineJoin, lineCap:aGState.lineCap, miterLimit:aGState.miterLimit, globalAlpha:aGState.globalAlpha,
|
||||||
blendMode:aGState.blendMode,
|
blendMode:aGState.blendMode,
|
||||||
shadowOffset:aGState.shadowOffset, shadowBlur:aGState.shadowBlur, shadowColor:aGState.shadowColor, CTM:_CGAffineTransformMakeCopy(aGState.CTM) };
|
shadowOffset:aGState.shadowOffset, shadowBlur:aGState.shadowBlur, shadowColor:aGState.shadowColor, CTM:_CGAffineTransformMakeCopy(aGState.CTM) };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,10 +256,10 @@ function CGContextAddPath(aContext, aPath)
|
|||||||
{
|
{
|
||||||
if (!aContext || CGPathIsEmpty(aPath))
|
if (!aContext || CGPathIsEmpty(aPath))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!aContext.path)
|
if (!aContext.path)
|
||||||
aContext.path = CGPathCreateMutable();
|
aContext.path = CGPathCreateMutable();
|
||||||
|
|
||||||
CGPathAddPath(aContext.path, aContext.gState.CTM, aPath);
|
CGPathAddPath(aContext.path, aContext.gState.CTM, aPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,7 +332,7 @@ function CGContextMoveToPoint(aContext, x, y)
|
|||||||
{
|
{
|
||||||
if (!aContext.path)
|
if (!aContext.path)
|
||||||
aContext.path = CGPathCreateMutable();
|
aContext.path = CGPathCreateMutable();
|
||||||
|
|
||||||
CGPathMoveToPoint(aContext.path, aContext.gState.CTM, x, y);
|
CGPathMoveToPoint(aContext.path, aContext.gState.CTM, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,11 +358,11 @@ function CGContextFillRects(aContext, rects, count)
|
|||||||
{
|
{
|
||||||
if (arguments[2] === undefined)
|
if (arguments[2] === undefined)
|
||||||
var count = rects.length;
|
var count = rects.length;
|
||||||
|
|
||||||
CGContextBeginPath(aContext);
|
CGContextBeginPath(aContext);
|
||||||
CGContextAddRects(aContext, rects, count);
|
CGContextAddRects(aContext, rects, count);
|
||||||
CGContextClosePath(aContext);
|
CGContextClosePath(aContext);
|
||||||
|
|
||||||
CGContextDrawPath(aContext, kCGPathFill);
|
CGContextDrawPath(aContext, kCGPathFill);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -373,11 +373,11 @@ function CGContextFillRects(aContext, rects, count)
|
|||||||
@return void
|
@return void
|
||||||
*/
|
*/
|
||||||
function CGContextStrokeRect(aContext, aRect)
|
function CGContextStrokeRect(aContext, aRect)
|
||||||
{
|
{
|
||||||
CGContextBeginPath(aContext);
|
CGContextBeginPath(aContext);
|
||||||
CGContextAddRect(aContext, aRect);
|
CGContextAddRect(aContext, aRect);
|
||||||
CGContextClosePath(aContext);
|
CGContextClosePath(aContext);
|
||||||
|
|
||||||
CGContextDrawPath(aContext, kCGPathStroke);
|
CGContextDrawPath(aContext, kCGPathStroke);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,10 +391,10 @@ function CGContextStrokeRect(aContext, aRect)
|
|||||||
function CGContextStrokeRectWithWidth(aContext, aRect, aWidth)
|
function CGContextStrokeRectWithWidth(aContext, aRect, aWidth)
|
||||||
{
|
{
|
||||||
CGContextSaveGState(aContext);
|
CGContextSaveGState(aContext);
|
||||||
|
|
||||||
CGContextSetLineWidth(aContext, aWidth);
|
CGContextSetLineWidth(aContext, aWidth);
|
||||||
CGContextStrokeRect(aContext, aRect);
|
CGContextStrokeRect(aContext, aRect);
|
||||||
|
|
||||||
CGContextRestoreGState(aContext);
|
CGContextRestoreGState(aContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,7 +407,7 @@ function CGContextStrokeRectWithWidth(aContext, aRect, aWidth)
|
|||||||
function CGContextConcatCTM(aContext, aTransform)
|
function CGContextConcatCTM(aContext, aTransform)
|
||||||
{
|
{
|
||||||
var CTM = aContext.gState.CTM;
|
var CTM = aContext.gState.CTM;
|
||||||
|
|
||||||
_CGAffineTransformConcatTo(CTM, aTransform, CTM);
|
_CGAffineTransformConcatTo(CTM, aTransform, CTM);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,7 +431,7 @@ function CGContextGetCTM(aContext)
|
|||||||
function CGContextRotateCTM(aContext, anAngle)
|
function CGContextRotateCTM(aContext, anAngle)
|
||||||
{
|
{
|
||||||
var gState = aContext.gState;
|
var gState = aContext.gState;
|
||||||
|
|
||||||
gState.CTM = CGAffineTransformRotate(gState.CTM, anAngle);
|
gState.CTM = CGAffineTransformRotate(gState.CTM, anAngle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,7 +445,7 @@ function CGContextRotateCTM(aContext, anAngle)
|
|||||||
function CGContextScaleCTM(aContext, sx, sy)
|
function CGContextScaleCTM(aContext, sx, sy)
|
||||||
{
|
{
|
||||||
var gState = aContext.gState;
|
var gState = aContext.gState;
|
||||||
|
|
||||||
gState.CTM = _CGAffineTransformScale(gState.CTM, sx, sy);
|
gState.CTM = _CGAffineTransformScale(gState.CTM, sx, sy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -459,7 +459,7 @@ function CGContextScaleCTM(aContext, sx, sy)
|
|||||||
function CGContextTranslateCTM(aContext, tx, ty)
|
function CGContextTranslateCTM(aContext, tx, ty)
|
||||||
{
|
{
|
||||||
var gState = aContext.gState;
|
var gState = aContext.gState;
|
||||||
|
|
||||||
gState.CTM = _CGAffineTransformTranslate(gState.CTM, tx, ty);
|
gState.CTM = _CGAffineTransformTranslate(gState.CTM, tx, ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -474,7 +474,7 @@ function CGContextTranslateCTM(aContext, tx, ty)
|
|||||||
function CGContextSetShadow(aContext, aSize, aBlur)
|
function CGContextSetShadow(aContext, aSize, aBlur)
|
||||||
{
|
{
|
||||||
var gState = aContext.gState;
|
var gState = aContext.gState;
|
||||||
|
|
||||||
gState.shadowOffset = _CGSizeMakeCopy(aSize);
|
gState.shadowOffset = _CGSizeMakeCopy(aSize);
|
||||||
gState.shadowBlur = aBlur;
|
gState.shadowBlur = aBlur;
|
||||||
gState.shadowColor = [CPColor shadowColor];
|
gState.shadowColor = [CPColor shadowColor];
|
||||||
@@ -491,7 +491,7 @@ function CGContextSetShadow(aContext, aSize, aBlur)
|
|||||||
function CGContextSetShadowWithColor(aContext, aSize, aBlur, aColor)
|
function CGContextSetShadowWithColor(aContext, aSize, aBlur, aColor)
|
||||||
{
|
{
|
||||||
var gState = aContext.gState;
|
var gState = aContext.gState;
|
||||||
|
|
||||||
gState.shadowOffset = _CGSizeMakeCopy(aSize);
|
gState.shadowOffset = _CGSizeMakeCopy(aSize);
|
||||||
gState.shadowBlur = aBlur;
|
gState.shadowBlur = aBlur;
|
||||||
gState.shadowColor = aColor;
|
gState.shadowColor = aColor;
|
||||||
@@ -535,6 +535,7 @@ function CGContextEOFillPath(aContext)
|
|||||||
function CGContextFillPath(aContext)
|
function CGContextFillPath(aContext)
|
||||||
{
|
{
|
||||||
CGContextDrawPath(aContext, kCGPathFill);
|
CGContextDrawPath(aContext, kCGPathFill);
|
||||||
|
CGContextClosePath(aContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
var KAPPA = 4.0 * ((SQRT2 - 1.0) / 3.0);
|
var KAPPA = 4.0 * ((SQRT2 - 1.0) / 3.0);
|
||||||
@@ -588,6 +589,7 @@ function CGContextStrokeEllipseInRect(aContext, aRect)
|
|||||||
function CGContextStrokePath(aContext)
|
function CGContextStrokePath(aContext)
|
||||||
{
|
{
|
||||||
CGContextDrawPath(aContext, kCGPathStroke);
|
CGContextDrawPath(aContext, kCGPathStroke);
|
||||||
|
CGContextClosePath(aContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -603,10 +605,10 @@ function CGContextStrokePath(aContext)
|
|||||||
function CGContextStrokeLineSegments(aContext, points, count)
|
function CGContextStrokeLineSegments(aContext, points, count)
|
||||||
{
|
{
|
||||||
var i = 0;
|
var i = 0;
|
||||||
|
|
||||||
if (arguments["count"] == NULL)
|
if (arguments["count"] == NULL)
|
||||||
var count = points.length;
|
var count = points.length;
|
||||||
|
|
||||||
CGContextBeginPath(aContext);
|
CGContextBeginPath(aContext);
|
||||||
|
|
||||||
for (; i < count; i += 2)
|
for (; i < count; i += 2)
|
||||||
@@ -614,7 +616,7 @@ function CGContextStrokeLineSegments(aContext, points, count)
|
|||||||
CGContextMoveToPoint(aContext, points[i].x, points[i].y);
|
CGContextMoveToPoint(aContext, points[i].x, points[i].y);
|
||||||
CGContextAddLineToPoint(aContext, points[i + 1].x, points[i + 1].y);
|
CGContextAddLineToPoint(aContext, points[i + 1].x, points[i + 1].y);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGContextStrokePath(aContext);
|
CGContextStrokePath(aContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -679,12 +681,12 @@ function CGContextFillRoundedRectangleInRect(aContext, aRect, aRadius, ne, se, s
|
|||||||
function CGContextStrokeRoundedRectangleInRect(aContext, aRect, aRadius, ne, se, sw, nw)
|
function CGContextStrokeRoundedRectangleInRect(aContext, aRect, aRadius, ne, se, sw, nw)
|
||||||
{
|
{
|
||||||
CGContextBeginPath(aContext);
|
CGContextBeginPath(aContext);
|
||||||
CGContextAddPath(aContext, CGPathWithRoundedRectangleInRect(aRect, aRadius, aRadius, ne, se, sw, nw));
|
CGContextAddPath(aContext, CGPathWithRoundedRectangleInRect(aRect, aRadius, aRadius, ne, se, sw, nw));
|
||||||
CGContextClosePath(aContext);
|
CGContextClosePath(aContext);
|
||||||
CGContextStrokePath(aContext);
|
CGContextStrokePath(aContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@}
|
@}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -255,8 +255,6 @@ function CGContextDrawPath(aContext, aMode)
|
|||||||
|
|
||||||
vml.push("</cg_vml_:shape>");
|
vml.push("</cg_vml_:shape>");
|
||||||
|
|
||||||
aContext.path = NULL;
|
|
||||||
|
|
||||||
if (aContext.buffer != nil)
|
if (aContext.buffer != nil)
|
||||||
aContext.buffer += vml.join("");
|
aContext.buffer += vml.join("");
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -267,21 +267,21 @@ var KAPPA = 4.0 * ((SQRT2 - 1.0) / 3.0);
|
|||||||
function CGPathWithEllipseInRect(aRect)
|
function CGPathWithEllipseInRect(aRect)
|
||||||
{
|
{
|
||||||
var path = CGPathCreateMutable();
|
var path = CGPathCreateMutable();
|
||||||
|
|
||||||
if (_CGRectGetWidth(aRect) == _CGRectGetHeight(aRect))
|
if (_CGRectGetWidth(aRect) == _CGRectGetHeight(aRect))
|
||||||
CGPathAddArc(path, nil, _CGRectGetMidX(aRect), _CGRectGetMidY(aRect), _CGRectGetWidth(aRect) / 2.0, 0.0, 2 * PI, YES);
|
CGPathAddArc(path, nil, _CGRectGetMidX(aRect), _CGRectGetMidY(aRect), _CGRectGetWidth(aRect) / 2.0, 0.0, 2 * PI, YES);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var axis = _CGSizeMake(_CGRectGetWidth(aRect) / 2.0, _CGRectGetHeight(aRect) / 2.0),
|
var axis = _CGSizeMake(_CGRectGetWidth(aRect) / 2.0, _CGRectGetHeight(aRect) / 2.0),
|
||||||
center = _CGPointMake(_CGRectGetMinX(aRect) + axis.width, _CGRectGetMinY(aRect) + axis.height);
|
center = _CGPointMake(_CGRectGetMinX(aRect) + axis.width, _CGRectGetMinY(aRect) + axis.height);
|
||||||
|
|
||||||
CGPathMoveToPoint(path, nil, center.x, center.y - axis.height);
|
CGPathMoveToPoint(path, nil, center.x, center.y - axis.height);
|
||||||
|
|
||||||
CGPathAddCurveToPoint(path, nil, center.x + (KAPPA * axis.width), center.y - axis.height, center.x + axis.width, center.y - (KAPPA * axis.height), center.x + axis.width, center.y);
|
CGPathAddCurveToPoint(path, nil, center.x + (KAPPA * axis.width), center.y - axis.height, center.x + axis.width, center.y - (KAPPA * axis.height), center.x + axis.width, center.y);
|
||||||
CGPathAddCurveToPoint(path, nil, center.x + axis.width, center.y + (KAPPA * axis.height), center.x + (KAPPA * axis.width), center.y + axis.height, center.x, center.y + axis.height);
|
CGPathAddCurveToPoint(path, nil, center.x + axis.width, center.y + (KAPPA * axis.height), center.x + (KAPPA * axis.width), center.y + axis.height, center.x, center.y + axis.height);
|
||||||
CGPathAddCurveToPoint(path, nil, center.x - (KAPPA * axis.width), center.y + axis.height, center.x - axis.width, center.y + (KAPPA * axis.height), center.x - axis.width, center.y);
|
CGPathAddCurveToPoint(path, nil, center.x - (KAPPA * axis.width), center.y + axis.height, center.x - axis.width, center.y + (KAPPA * axis.height), center.x - axis.width, center.y);
|
||||||
CGPathAddCurveToPoint(path, nil, center.x - axis.width, center.y - (KAPPA * axis.height), center.x - (KAPPA * axis.width), center.y - axis.height, center.x, center.y - axis.height);
|
CGPathAddCurveToPoint(path, nil, center.x - axis.width, center.y - (KAPPA * axis.height), center.x - (KAPPA * axis.width), center.y - axis.height, center.x, center.y - axis.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGPathCloseSubpath(path);
|
CGPathCloseSubpath(path);
|
||||||
|
|
||||||
@@ -297,37 +297,38 @@ function CGPathWithRoundedRectangleInRect(aRect, xRadius, yRadius/*not currently
|
|||||||
yMax = _CGRectGetMaxY(aRect);
|
yMax = _CGRectGetMaxY(aRect);
|
||||||
|
|
||||||
CGPathMoveToPoint(path, nil, xMin + xRadius, yMin);
|
CGPathMoveToPoint(path, nil, xMin + xRadius, yMin);
|
||||||
|
|
||||||
if (ne)
|
if (ne)
|
||||||
{
|
{
|
||||||
CGPathAddLineToPoint(path, nil, xMax - xRadius, yMin);
|
CGPathAddLineToPoint(path, nil, xMax - xRadius, yMin);
|
||||||
CGPathAddCurveToPoint(path, nil, xMax - xRadius, yMin, xMax, yMin, xMax, yMin + xRadius);
|
CGPathAddCurveToPoint(path, nil, xMax - xRadius, yMin, xMax, yMin, xMax, yMin + xRadius);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
CGPathAddLineToPoint(path, nil, xMax, yMin);
|
CGPathAddLineToPoint(path, nil, xMax, yMin);
|
||||||
|
|
||||||
if (se)
|
if (se)
|
||||||
{
|
{
|
||||||
CGPathAddLineToPoint(path, nil, xMax, yMax - xRadius);
|
CGPathAddLineToPoint(path, nil, xMax, yMax - xRadius);
|
||||||
CGPathAddCurveToPoint(path, nil, xMax, yMax - xRadius, xMax, yMax, xMax - xRadius, yMax);
|
CGPathAddCurveToPoint(path, nil, xMax, yMax - xRadius, xMax, yMax, xMax - xRadius, yMax);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
CGPathAddLineToPoint(path, nil, xMax, yMax);
|
CGPathAddLineToPoint(path, nil, xMax, yMax);
|
||||||
|
|
||||||
if (sw)
|
if (sw)
|
||||||
{
|
{
|
||||||
CGPathAddLineToPoint(path, nil, xMin + xRadius, yMax);
|
CGPathAddLineToPoint(path, nil, xMin + xRadius, yMax);
|
||||||
CGPathAddCurveToPoint(path, nil, xMin + xRadius, yMax, xMin, yMax, xMin, yMax - xRadius);
|
CGPathAddCurveToPoint(path, nil, xMin + xRadius, yMax, xMin, yMax, xMin, yMax - xRadius);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
CGPathAddLineToPoint(path, nil, xMin, yMax);
|
CGPathAddLineToPoint(path, nil, xMin, yMax);
|
||||||
|
|
||||||
if (nw)
|
if (nw)
|
||||||
{
|
{
|
||||||
CGPathAddLineToPoint(path, nil, xMin, yMin + xRadius);
|
CGPathAddLineToPoint(path, nil, xMin, yMin + xRadius);
|
||||||
CGPathAddCurveToPoint(path, nil, xMin, yMin + xRadius, xMin, yMin, xMin + xRadius, yMin);
|
CGPathAddCurveToPoint(path, nil, xMin, yMin + xRadius, xMin, yMin, xMin + xRadius, yMin);
|
||||||
} else
|
}
|
||||||
CGPathAddLineToPoint(path, nil, xMin, yMin);
|
else
|
||||||
|
CGPathAddLineToPoint(path, nil, xMin, yMin);
|
||||||
|
|
||||||
CGPathCloseSubpath(path);
|
CGPathCloseSubpath(path);
|
||||||
|
|
||||||
|
|||||||
@@ -168,6 +168,8 @@ KeyCodesToUnicodeMap[CPKeyCodes.LEFT] = CPLeftArrowFunctionKey
|
|||||||
KeyCodesToUnicodeMap[CPKeyCodes.UP] = CPUpArrowFunctionKey;
|
KeyCodesToUnicodeMap[CPKeyCodes.UP] = CPUpArrowFunctionKey;
|
||||||
KeyCodesToUnicodeMap[CPKeyCodes.RIGHT] = CPRightArrowFunctionKey;
|
KeyCodesToUnicodeMap[CPKeyCodes.RIGHT] = CPRightArrowFunctionKey;
|
||||||
KeyCodesToUnicodeMap[CPKeyCodes.DOWN] = CPDownArrowFunctionKey;
|
KeyCodesToUnicodeMap[CPKeyCodes.DOWN] = CPDownArrowFunctionKey;
|
||||||
|
KeyCodesToUnicodeMap[CPKeyCodes.HOME] = CPHomeFunctionKey;
|
||||||
|
KeyCodesToUnicodeMap[CPKeyCodes.END] = CPEndFunctionKey;
|
||||||
KeyCodesToUnicodeMap[CPKeyCodes.SEMICOLON] = ";";
|
KeyCodesToUnicodeMap[CPKeyCodes.SEMICOLON] = ";";
|
||||||
KeyCodesToUnicodeMap[CPKeyCodes.DASH] = "-";
|
KeyCodesToUnicodeMap[CPKeyCodes.DASH] = "-";
|
||||||
KeyCodesToUnicodeMap[CPKeyCodes.EQUALS] = "=";
|
KeyCodesToUnicodeMap[CPKeyCodes.EQUALS] = "=";
|
||||||
|
|||||||
|
After Width: | Height: | Size: 183 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1023 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.4 KiB |