mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-08 04:44:55 +10:00
Compare commits
1367 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8e20f61946 | |||
| ad9a575dc6 | |||
| def979adf8 | |||
| bd172ec0fd | |||
| b8a2e3a727 | |||
| 7c7799ae37 | |||
| 7de1e7644d | |||
| cbbd6ad88f | |||
| 8f8c096dfb | |||
| 53019ac600 | |||
| 8c82bef903 | |||
| dd6dd7daf8 | |||
| 5f20c1cd6e | |||
| e7e9e889e1 | |||
| d460d0b1db | |||
| b44ea41a1e | |||
| 9199bd9655 | |||
| 67728e60d6 | |||
| 9006e9bbc5 | |||
| b657a4d53f | |||
| 0b1e282731 | |||
| 716dc40f53 | |||
| 05b15a7297 | |||
| aa6a413be1 | |||
| 23f58d7bac | |||
| 52aa79b8b4 | |||
| 4c7d282b69 | |||
| 6d272a6507 | |||
| 241cfd234b | |||
| bef7b2b831 | |||
| 3a625a7105 | |||
| fb37ab6eea | |||
| f2ef393fd7 | |||
| 8a88e72dee | |||
| d72f76d836 | |||
| d996847b6d | |||
| cd2f6fe417 | |||
| 6c62484b48 | |||
| 44dd21ad43 | |||
| 04f6b778bc | |||
| d58e251b97 | |||
| 8d9234d3f6 | |||
| a7d08d8cd4 | |||
| 10d76da592 | |||
| 35519da907 | |||
| bd73320738 | |||
| 6a15c7ec0d | |||
| 48ae7201a5 | |||
| 144c3628ae | |||
| 3f448c1537 | |||
| 9d0d458fac | |||
| 40851b4a62 | |||
| 88ded5eb0d | |||
| 1fd7643993 | |||
| dff96fd647 | |||
| 0ca4df3161 | |||
| e0aa7d99ee | |||
| 6ad5a5361c | |||
| 713bca84af | |||
| 3bc3f13bfb | |||
| 75ea0a4e6d | |||
| 0ddf096bd2 | |||
| ac6be61379 | |||
| 3874da705a | |||
| 8173f1a975 | |||
| cafb1a2915 | |||
| 37dc1c66a2 | |||
| 8b32fa0579 | |||
| c9d3f669a3 | |||
| 992d62e0d0 | |||
| 4d575b27a7 | |||
| 08701c1632 | |||
| c8a09d0d10 | |||
| 435043cb48 | |||
| caa4bbb0c8 | |||
| 159986dba1 | |||
| 7d853a6df6 | |||
| 7cf3fe436a | |||
| 25abcbfd27 | |||
| 3884f26a18 | |||
| 1c6dfb609c | |||
| 61ec91116c | |||
| 0e4d653c51 | |||
| 9968fb8283 | |||
| 7e04c18b14 | |||
| 8b414b8fda | |||
| b2afe2e2c5 | |||
| b1b3dd5564 | |||
| 7a4b77767d | |||
| 1417aaed0b | |||
| 243b13c37c | |||
| 4660467df5 | |||
| 73a12bc107 | |||
| ece6015a7f | |||
| 1cbdf505fe | |||
| f0c1970784 | |||
| 14944a3e38 | |||
| 48fe5f496b | |||
| 57a7932675 | |||
| e0d2964e12 | |||
| c3f9208ab7 | |||
| 3a5e6f553d | |||
| 24c8afd620 | |||
| 4710d1b484 | |||
| 2ce7677672 | |||
| 04a22436d2 | |||
| 0ef3bc4adb | |||
| 887be7338f | |||
| 72f61b978a | |||
| 4c38075dc7 | |||
| 8211976044 | |||
| 22e9bbaa20 | |||
| 0fcf7e1fd4 | |||
| 04302866e9 | |||
| 9bcc56f228 | |||
| d7903bc3bb | |||
| 8178c72fbe | |||
| ab53f7e85f | |||
| 7a186d0d49 | |||
| d5d0ec56cf | |||
| b45ee77472 | |||
| 796c825f02 | |||
| 063cfde769 | |||
| b89a851513 | |||
| b6f3020072 | |||
| f4f4ba7458 | |||
| f181109ac7 | |||
| c7d5fe3cf4 | |||
| e9414613a4 | |||
| 54da44e0d0 | |||
| 92f9c0c89a | |||
| 16d718ffc5 | |||
| 03df6158e2 | |||
| 895de4e7f2 | |||
| 655f5253f6 | |||
| 693315ec96 | |||
| 7f49727966 | |||
| 15110214ea | |||
| 3dc0f0d01b | |||
| 82d4b9ebfc | |||
| bc0fc4d3b9 | |||
| c5a095cad9 | |||
| be996d6494 | |||
| a9c4f2807f | |||
| 2ad35e0ac0 | |||
| 6dafbe1215 | |||
| 1ba5f1525b | |||
| 72a00087c3 | |||
| 0c53c8918a | |||
| 45b9532e66 | |||
| 0e5dad5412 | |||
| d0f6c78b5b | |||
| 58f73e7c24 | |||
| a7bdac4d52 | |||
| a9036e7b19 | |||
| b0ee56b0cc | |||
| 0957f3bc8f | |||
| d3d98b3058 | |||
| ec5e1ae233 | |||
| 0f2e581a02 | |||
| aaa24ad56a | |||
| 50588a759d | |||
| 19e9d1692a | |||
| be91987759 | |||
| 03ab0f1d95 | |||
| a4529c38a2 | |||
| de04bd7ec1 | |||
| e7fcebcf96 | |||
| cf791ac259 | |||
| efeed5d49a | |||
| 07f7382e56 | |||
| 0535df6880 | |||
| 8d54c8666a | |||
| 6e382a8375 | |||
| 76965ffa23 | |||
| b5087a4d77 | |||
| 6d1b513421 | |||
| 6918872b65 | |||
| f3e8509ff3 | |||
| d4bb4b94b9 | |||
| 70294769f1 | |||
| be138f34fc | |||
| 52b56374a9 | |||
| 904d1a6203 | |||
| bdfd130fb7 | |||
| 5cc652331e | |||
| dbc2ef4fbf | |||
| b435c51bde | |||
| c8e507a159 | |||
| e369266d49 | |||
| 6f3b737405 | |||
| dc3eeb3ff9 | |||
| c297459ff2 | |||
| 9d9de0bb4d | |||
| 69895fdc3f | |||
| a9f0c9b82c | |||
| bee06d489d | |||
| 0778def541 | |||
| 86acda3f46 | |||
| 5d6b77f259 | |||
| 20d957357f | |||
| f54e73d166 | |||
| c843f54248 | |||
| 36abdc1381 | |||
| 79e3ba9fdd | |||
| d75653c424 | |||
| e3d2ad82c9 | |||
| 4d88fb36cb | |||
| 717e20ead3 | |||
| 1323e9e7c8 | |||
| 4ee9bced0e | |||
| 573adc23ba | |||
| 544c5323d5 | |||
| 01a14d490d | |||
| 37b1d1dbd9 | |||
| 55c91faaf7 | |||
| 7c81b7f8d2 | |||
| 18c7b9207b | |||
| acda3b69f6 | |||
| cf315c5f79 | |||
| 93e0395ac5 | |||
| c30c8da267 | |||
| 6100309b3b | |||
| 24995d7c3f | |||
| 770eb87a74 | |||
| 1ecafb7811 | |||
| 8829165e36 | |||
| 7d597c5ca2 | |||
| f9759b8cc4 | |||
| 0d40e53e06 | |||
| 2447780585 | |||
| fa0d3699ce | |||
| 7878c1fc71 | |||
| 50d4c1dec1 | |||
| ebbc25a92d | |||
| da0ce8970d | |||
| 064b4d31ee | |||
| acd8f70cc5 | |||
| e8e370d3d3 | |||
| 3bf9e09a9f | |||
| d3cd8c5e86 | |||
| 25222cbb19 | |||
| 40e1935e3f | |||
| ad8c624efb | |||
| 741b9bc624 | |||
| 3b12788eff | |||
| d2adb49ccf | |||
| f422e0fdf9 | |||
| 0d8d456e98 | |||
| af4c22c856 | |||
| 9e3f1793fd | |||
| c6ae5af997 | |||
| a1c4747b6d | |||
| f2dc63e7e6 | |||
| f5498714b0 | |||
| 66e668a2b2 | |||
| 95f86f9056 | |||
| 8074f6e49c | |||
| 5b9e2ff387 | |||
| 1d542c5c96 | |||
| 969c7ebdc1 | |||
| 746d6c06e7 | |||
| 9fde2e7bb3 | |||
| ad29d2d077 | |||
| 43d58ae4a6 | |||
| 80f006f6b5 | |||
| a08c8a4484 | |||
| 8d385ef812 | |||
| bcc1a2cb3a | |||
| f568ba6fac | |||
| 9bf5b57663 | |||
| 29c2240920 | |||
| 22086e05a7 | |||
| 3842e65fb9 | |||
| b59afed4fd | |||
| df1e1334e0 | |||
| 3cb3f11c58 | |||
| 5605becb98 | |||
| c24187eeb6 | |||
| d50acb4911 | |||
| bf89b07cea | |||
| d513cb2667 | |||
| b646d90179 | |||
| 3dcc4a1638 | |||
| f5df5ba9eb | |||
| 7210ac1533 | |||
| a3acc07014 | |||
| bcbac424ed | |||
| dbfb768dc3 | |||
| e6c1313312 | |||
| 53bff5ef13 | |||
| d376ec9278 | |||
| 2cbaaa4a7d | |||
| 5539195778 | |||
| a576f140ad | |||
| c665397bda | |||
| 1ce7646fb5 | |||
| d0ae14d33e | |||
| 94963afb75 | |||
| 3d7d6f60fc | |||
| 0dcfe8a08a | |||
| a147345756 | |||
| a038de3d31 | |||
| 738dd800af | |||
| 30dc7ce36b | |||
| d245a6305f | |||
| feaa48fed5 | |||
| 437ec07d2d | |||
| 06cb3913ae | |||
| 878d048040 | |||
| ad8d719eeb | |||
| bf31204c45 | |||
| 8275226942 | |||
| e03e1516e0 | |||
| d2f9ef5ac2 | |||
| 22f0950fcf | |||
| 9617449de8 | |||
| c7a68d6542 | |||
| a7a2d24e16 | |||
| b22fa6291c | |||
| 666b940176 | |||
| 9872d2547d | |||
| b1902fd086 | |||
| 2649254a49 | |||
| 650a60bdb4 | |||
| bfc61f5513 | |||
| 2c81782f62 | |||
| 986d92ec53 | |||
| 9af055e4ca | |||
| 61202675b8 | |||
| 1aabe42573 | |||
| fa56fd79cf | |||
| bcb1b3c082 | |||
| 50fc7c1261 | |||
| 7b64a2c8d0 | |||
| aff0ec8ecf | |||
| d716a4c986 | |||
| 751f6493cd | |||
| 5835d18a21 | |||
| d095a664fc | |||
| f094480b64 | |||
| 67bbac196a | |||
| 3b3e05f4e9 | |||
| 5415c29ee0 | |||
| 536188dc92 | |||
| cccca4a203 | |||
| 889d76c3ee | |||
| 4f1fb85886 | |||
| 458b853830 | |||
| 1737df8047 | |||
| 75758e0250 | |||
| 4144956a09 | |||
| 607f963ba7 | |||
| a2b06c0a0d | |||
| 8e7c815d2b | |||
| e7b096f5c1 | |||
| db42e3ed9b | |||
| 8b90c9295b | |||
| 92cb86103b | |||
| 911d85cfd0 | |||
| 66359d3c01 | |||
| 373fde0d6f | |||
| b348513d0c | |||
| a3edd3bcf1 | |||
| 3fda739703 | |||
| 3988940446 | |||
| 3e5978beb7 | |||
| 26fa95670e | |||
| a4de01dfb0 | |||
| 278ec5cd84 | |||
| d3655e3f69 | |||
| 6b84228284 | |||
| e86f754768 | |||
| 6fce948506 | |||
| 2a063c84cd | |||
| 4f0f45315e | |||
| 695710f34f | |||
| 6c00be0b87 | |||
| 52750121e3 | |||
| 9dada76406 | |||
| cad1160ce7 | |||
| e52873fc50 | |||
| 7dd63ba2d8 | |||
| a1e43be273 | |||
| 3d1a7a5748 | |||
| f1b7d39ad4 | |||
| b6b50d376d | |||
| a03dd74c80 | |||
| e4bdb820d4 | |||
| f386d79a26 | |||
| b3ce9db691 | |||
| 011a06ec75 | |||
| a1072973d2 | |||
| 59620a6692 | |||
| 77ab989334 | |||
| d58542a2f9 | |||
| 9f71a77edc | |||
| 4450f249ea | |||
| caf9b3b5d5 | |||
| dfdb490e64 | |||
| 91dd539b3b | |||
| 257563974b | |||
| 0b3bc7a879 | |||
| 68dd3e08b4 | |||
| ff02e779e1 | |||
| 364cb30db0 | |||
| b96b694e87 | |||
| 49790e0015 | |||
| 9294c24684 | |||
| 93abda7966 | |||
| f39392f737 | |||
| 0b72abb8b4 | |||
| 7a5a6a469d | |||
| 9372858596 | |||
| 5638d560a4 | |||
| a680a5b802 | |||
| 0fa15650c3 | |||
| e128c4cae4 | |||
| d55d83c7c3 | |||
| eb3915495d | |||
| bb768c0b07 | |||
| 4f2e1db6d7 | |||
| d5b6a29fdd | |||
| bb0669439e | |||
| 98e009ecb9 | |||
| 12364e908a | |||
| f2caf0c9fc | |||
| 57a0425723 | |||
| b1b3d2ef9c | |||
| 632dff3e2c | |||
| d0ab585ba0 | |||
| 59cc4084fc | |||
| 00769efb56 | |||
| a17c478e0b | |||
| 0aaaea2bfa | |||
| 8c63184740 | |||
| cbe22df372 | |||
| 97027d1774 | |||
| 11fb16b674 | |||
| 82f37a5225 | |||
| f79fb73cb2 | |||
| 3ab85b4fb1 | |||
| 5164501228 | |||
| 94d713182e | |||
| 5f664dcc5d | |||
| b02fe56ba9 | |||
| 430779ba8d | |||
| 70ca45513e | |||
| d7ea8f3738 | |||
| 5591724a67 | |||
| 7628eefd6d | |||
| 972635b679 | |||
| 25d9ff302f | |||
| 951bb1247d | |||
| a5fe794b14 | |||
| aec5348b83 | |||
| a03806c776 | |||
| 113cb69ae4 | |||
| 5572645081 | |||
| 42589a5ed3 | |||
| 7fc87ca235 | |||
| e825814929 | |||
| aeca976c4e | |||
| ffe4d83e3d | |||
| f4aa60263c | |||
| e7c220c307 | |||
| 106cb55ff0 | |||
| adcbfbc679 | |||
| 71e32a9296 | |||
| 8e0974cfb2 | |||
| 07ba8f14f7 | |||
| 477839e111 | |||
| d291fcd373 | |||
| 308a0346a9 | |||
| 1c591bb9f5 | |||
| 73da32b306 | |||
| 3c26a0c8da | |||
| d4519ac5a9 | |||
| 437657a79c | |||
| bac4e5f01d | |||
| 5cf4f5a27a | |||
| 2dfd925462 | |||
| 1d770b475f | |||
| 3c7b77df3e | |||
| 48aef2cd7e | |||
| 749118ce02 | |||
| 436741d59b | |||
| 2549affc1f | |||
| e4a9155239 | |||
| 990620ab75 | |||
| f8a2ac9013 | |||
| 1031c4b61f | |||
| 49bc9cb8cc | |||
| ce3ec4a5af | |||
| bdf93b75e2 | |||
| 4ee7a13f71 | |||
| 5cb2e7dd2b | |||
| f408ce15b5 | |||
| 3223202869 | |||
| 25542d2384 | |||
| f834098363 | |||
| 7ef36bedfe | |||
| 6f62d2280a | |||
| 1e5c945804 | |||
| 606715398a | |||
| 2ffc40baea | |||
| dddeba1fae | |||
| f92a80e260 | |||
| 0d556b66e8 | |||
| fda3b22db8 | |||
| 5921b387c4 | |||
| c63b26b660 | |||
| c2b44905fc | |||
| 2d34b2cf8a | |||
| 2086ecf2ca | |||
| 96d2b9501a | |||
| 01458c52c1 | |||
| 80071a2ac2 | |||
| 83a56df6a9 | |||
| c92dc9176b | |||
| b7b9933d72 | |||
| 61f62b7186 | |||
| f8b88755e4 | |||
| 3c72fc5168 | |||
| 7df07c2bd1 | |||
| 7754922711 | |||
| ac606bb472 | |||
| 6c77dd5102 | |||
| 01e1ed3f6c | |||
| e8031a6cb4 | |||
| 3ef9586764 | |||
| f0219fce0b | |||
| f41a028236 | |||
| 297c8d58c1 | |||
| 098c0a9baf | |||
| bf025ee990 | |||
| cce1fe6c9c | |||
| 874c9dea83 | |||
| e78c6148c7 | |||
| a18a226020 | |||
| 6a630aa498 | |||
| 553a14c5d2 | |||
| 853033aa14 | |||
| 06da2c565d | |||
| 3ae44ca040 | |||
| edefb8f7e3 | |||
| 60c540be6a | |||
| a6cba04fa5 | |||
| b416d4c8d4 | |||
| af2f55905e | |||
| 83d8e8b325 | |||
| 73bc4b2776 | |||
| f299106430 | |||
| 9963b7b3d3 | |||
| d720f73887 | |||
| 8d188f0038 | |||
| 2889d51387 | |||
| 30c29ab452 | |||
| c390e68e50 | |||
| 2a9c433a18 | |||
| 1ffe70b66a | |||
| 64920a2c07 | |||
| a0611fa727 | |||
| b8e64334bb | |||
| af7e11d3c6 | |||
| 6a07e916ed | |||
| 4bd462589d | |||
| b1929e538b | |||
| c2007f62b1 | |||
| 6c3185c3ad | |||
| fe687a99df | |||
| e067440a49 | |||
| 4d075037c7 | |||
| 47eb02fc5d | |||
| 4b2ee03f09 | |||
| f4efe3b924 | |||
| f103f2970b | |||
| 56f637b5e2 | |||
| ae1aa7bde6 | |||
| 9676a21b76 | |||
| fd8640ba3d | |||
| ae7f2625ed | |||
| a665bfcf42 | |||
| dd06c5b7df | |||
| 6db4423bbf | |||
| 7559aea5aa | |||
| d15f4a0a90 | |||
| dcfebda6fd | |||
| e29bdf5f62 | |||
| 7b3326a5cd | |||
| 9e0caafee7 | |||
| 4cf840b32a | |||
| 3933c4c1b3 | |||
| 3222a1afa4 | |||
| 652bb4514d | |||
| 861fa87232 | |||
| fa63a11848 | |||
| ebe548aa3f | |||
| 8fd38c968a | |||
| c1b41121de | |||
| 30f9b2a643 | |||
| da3290b405 | |||
| 0e95d4883a | |||
| 571391f27c | |||
| 42305cd629 | |||
| d870acec6d | |||
| 4d5f70a81b | |||
| 52d71e2404 | |||
| 8cbdae162e | |||
| 99212d2b9c | |||
| bfc6721974 | |||
| d9ca1346f0 | |||
| 720acb75a8 | |||
| 416b8503de | |||
| 928470d48b | |||
| e3781bb094 | |||
| 9e315fb5ac | |||
| f3fc5eff29 | |||
| da7ddf845b | |||
| 6db50fd7c6 | |||
| bb88fe1e97 | |||
| 3577e4c595 | |||
| 16887f2a3a | |||
| 52c9f00f3c | |||
| aa70df6d9b | |||
| 015f5d2f02 | |||
| 8f43377a5c | |||
| 41a7b750da | |||
| 9f528b3218 | |||
| 8eb20b610d | |||
| c7d799f178 | |||
| 1409b344a8 | |||
| 1f08fd4562 | |||
| 4414ecf774 | |||
| d84ceaac8f | |||
| dc2172e98f | |||
| d62ce646ed | |||
| 276ad57521 | |||
| a385d467a4 | |||
| a301109047 | |||
| a4e448af31 | |||
| 09e96a03a3 | |||
| f88f9ef25c | |||
| 1768dbabfc | |||
| a37b1e49e3 | |||
| 21fa33c74a | |||
| 8abfabf1f4 | |||
| 6416f69305 | |||
| 7d46f49788 | |||
| 5809c721d7 | |||
| f11bb639b9 | |||
| fd079f44be | |||
| 55ab31f8e2 | |||
| 32eb3a366a | |||
| 0f0739c978 | |||
| 47072a3b3e | |||
| 382a304793 | |||
| 9838fc924c | |||
| 8364d05a94 | |||
| a500ccb165 | |||
| 8a6d98e496 | |||
| d27530d7e6 | |||
| 759df0ac8f | |||
| 88d4d021ff | |||
| 99743d12ea | |||
| 275009b315 | |||
| ec0d2a686c | |||
| e429f65ed2 | |||
| 7c87ab075d | |||
| 7e6f4e5727 | |||
| 804ac2a82a | |||
| 4718ba6592 | |||
| 77a6f4d3b4 | |||
| b27b89b900 | |||
| 4821d6f370 | |||
| 6d04ac8e3d | |||
| 88ec95d4fa | |||
| a6b7debfd7 | |||
| 257c7bc3bf | |||
| ba7b85a7a6 | |||
| 3b32182961 | |||
| 25c86ad4e9 | |||
| 5b0fc2f232 | |||
| c12623c523 | |||
| fd6039a2fe | |||
| edce9835d0 | |||
| 015677c567 | |||
| 4da2539324 | |||
| 12f58e60f9 | |||
| 8f0c0adcb4 | |||
| bff1b670d5 | |||
| e93a82f9fd | |||
| bc7df76c3e | |||
| 7477c606f4 | |||
| 85a37a2fd7 | |||
| 9106d3f63a | |||
| 339f4a44ef | |||
| 769dc8e543 | |||
| 5f8e5e5ed2 | |||
| 71f5bcd1f7 | |||
| bb3b37f23b | |||
| fcea5975a8 | |||
| 2294ac45a2 | |||
| 5598f22b2f | |||
| 812b7adb28 | |||
| 9fd5a8fe96 | |||
| 0b8952e354 | |||
| 5c47ff1ef0 | |||
| b85b93404b | |||
| b46f46aa99 | |||
| 48266d3b27 | |||
| eb6cc76f02 | |||
| a5d512ca37 | |||
| 1d038b5f8c | |||
| 9366f9c602 | |||
| 23b4fcae02 | |||
| 14a994e68f | |||
| 894ff1a2cb | |||
| 78dcd27e1d | |||
| 714db98afa | |||
| 2faa2c6d61 | |||
| 3c45336afe | |||
| a0601cc83d | |||
| 9925d58347 | |||
| 6c241b3180 | |||
| 838adc9a51 | |||
| 41d2b73cca | |||
| 8d3789a0b0 | |||
| 95f65dcdf1 | |||
| 3d0f9554b0 | |||
| 0c21e013b4 | |||
| f8e24b0937 | |||
| 37d5ce18fc | |||
| e9a2785344 | |||
| 4de3b6d97c | |||
| 92a2bb9809 | |||
| 440b953531 | |||
| 1bc11e09ab | |||
| f20b896184 | |||
| 49d93b42a4 | |||
| b279510e5c | |||
| a83cda9ecd | |||
| f63b422a8c | |||
| 7af919b303 | |||
| 1c1ec2fcf5 | |||
| 8ccdd84a6f | |||
| 54ff518438 | |||
| c893b37fdf | |||
| 81e259bb62 | |||
| d5aac6b265 | |||
| d544797047 | |||
| 8ed2c0c9a5 | |||
| 2d1cf515d6 | |||
| 2553ffbba7 | |||
| 04418f8101 | |||
| c548a35939 | |||
| 777f4aa3fd | |||
| c0c226c580 | |||
| 40d234d1c4 | |||
| bc0d759d39 | |||
| b3497cdca8 | |||
| cc0f698c8b | |||
| b0123db3e7 | |||
| c9a32cc390 | |||
| 46d9e1f82a | |||
| 9596d6ca8e | |||
| 65315ed559 | |||
| 57bce6b8e5 | |||
| 403d0ea433 | |||
| 595cfb3ed1 | |||
| 2c689c584d | |||
| 84eaa1bf29 | |||
| 20e01762b8 | |||
| 08aec6fa9b | |||
| f51d19b39a | |||
| 8bfb3ade55 | |||
| 3847813351 | |||
| 67761b1027 | |||
| 7cca8f86b2 | |||
| 39976ec3d6 | |||
| a155aef596 | |||
| b24bfafb39 | |||
| 31ce46f147 | |||
| ce43a5d2e6 | |||
| 0d007e5737 | |||
| c0dac1a1db | |||
| ec7244042d | |||
| 88275e95e2 | |||
| add8566d4f | |||
| c5495ad14f | |||
| 94f1c68c7b | |||
| 3e67515f69 | |||
| 2091b8a03d | |||
| 235acf538f | |||
| 45404aaabd | |||
| 2727276a09 | |||
| cb6aa83269 | |||
| 39daa9e61f | |||
| 8313a62324 | |||
| c1d718a0f9 | |||
| 6e5174750f | |||
| 1cfb30f35e | |||
| ddfc615a6a | |||
| f53ad8c206 | |||
| 20645fed13 | |||
| d3c2e20359 | |||
| 46f693addf | |||
| 008ee8564b | |||
| b234015a32 | |||
| bb69d8dd04 | |||
| b02eaf928d | |||
| 2c4ff547fe | |||
| ca78cd030b | |||
| 51a12d61e1 | |||
| 661e5e2403 | |||
| ae8d015a78 | |||
| 59096d69ed | |||
| 66e1227182 | |||
| 19bdf41655 | |||
| 0acca63ccd | |||
| 6d2e876381 | |||
| 13f13191c4 | |||
| 86500cb4a0 | |||
| f7e5421f18 | |||
| c7bc8360ba | |||
| d91527a91c | |||
| 9e760ba655 | |||
| 9a2585d23f | |||
| 83723dd416 | |||
| 7597143b1b | |||
| 0cb4377830 | |||
| fbf2569a7e | |||
| 290406609b | |||
| 417c389b0a | |||
| 1af44eadfc | |||
| 364010ae63 | |||
| 7fb78237fb | |||
| c120bc10ed | |||
| 9c81ad0eec | |||
| bb564248d9 | |||
| 3deb988a06 | |||
| ae3e698d9e | |||
| 2735d7e343 | |||
| f4cc0ca360 | |||
| 99b7dbb6f3 | |||
| e3ca5244fe | |||
| a0b78a5e3d | |||
| 81b299865c | |||
| 3027753225 | |||
| 13997ee757 | |||
| 8c09fe72e6 | |||
| 6e9169242a | |||
| 91389ef09b | |||
| 921b503057 | |||
| efceedc924 | |||
| cad26211b3 | |||
| 36259bc83b | |||
| 024ede48a8 | |||
| b44c3bad62 | |||
| 0741f4334b | |||
| 46f20a75ec | |||
| 34ea20eedd | |||
| 08a0e451e7 | |||
| 53eb70e693 | |||
| 1b8a72d24a | |||
| 04840bac7b | |||
| 0a97b53f60 | |||
| 4d3f2968c1 | |||
| d5f3457c43 | |||
| 0c76b93db0 | |||
| 197f9ca216 | |||
| c8af6dbbb2 | |||
| 0a444f5ee7 | |||
| f0172f9adc | |||
| 5c9754baf4 | |||
| ef5bde9091 | |||
| a4efb57452 | |||
| 58aa0ab5be | |||
| 32b2713732 | |||
| cb21392d1e | |||
| 149cdbca48 | |||
| 73e4d6fc93 | |||
| 08bc4f5170 | |||
| 813baee504 | |||
| 74e524e98c | |||
| a8f5155acd | |||
| dd06195035 | |||
| 19ea23895b | |||
| 61444db46d | |||
| 54e991891d | |||
| ba735dd350 | |||
| 6b1913fd5b | |||
| c6f6aa9186 | |||
| ef51c44e54 | |||
| 5dc911776c | |||
| 9757e81500 | |||
| 46f8506c39 | |||
| f1ccfa86c0 | |||
| 5b2a9c0e43 | |||
| 81a6cf282b | |||
| 984edc196b | |||
| e5fff0b538 | |||
| 26c3c488e0 | |||
| 62bb6aac05 | |||
| 1a1e8ae56f | |||
| 7a8e25ab39 | |||
| 7b47a747bf | |||
| c4b66f5995 | |||
| 97cc9ca6c8 | |||
| 252b9ef560 | |||
| 77d038cef9 | |||
| 6ce5d305f1 | |||
| 2d0eb136fe | |||
| 4c03d9f658 | |||
| c5c4d6c04e | |||
| c7f468a0bc | |||
| 41b670616c | |||
| f62de41a95 | |||
| e6bdedfaea | |||
| e2e33a1b13 | |||
| 2266dadcba | |||
| 149f05f20c | |||
| 539b3c68de | |||
| 185eb9d1d3 | |||
| 9525505865 | |||
| a91e8dd062 | |||
| 5ce3d6d4b3 | |||
| facf816458 | |||
| afadc5e171 | |||
| a91eb15837 | |||
| cd74e417a9 | |||
| 7ca6eb0e2f | |||
| 78600f1c24 | |||
| 7aa6f31e67 | |||
| e91dc72424 | |||
| f9e2c1f1fa | |||
| bc49daf1be | |||
| dc07d2732b | |||
| 2f76bb8446 | |||
| cc286f9c41 | |||
| 42ca1926e1 | |||
| 007a52f0b5 | |||
| 7caadec1ec | |||
| 0f3f2a350b | |||
| bfe044f3f6 | |||
| 4eda278bc0 | |||
| 3379987a74 | |||
| c6b2cba3aa | |||
| a6538947d0 | |||
| 54e97b9adc | |||
| 4ebd1deed4 | |||
| af2195798f | |||
| c7a04075f4 | |||
| ebf988eaba | |||
| 0cd9f97e70 | |||
| 40d9b296da | |||
| 3f8dee89bb | |||
| 82d265e457 | |||
| 6aa63d3a7b | |||
| fdc76c80cf | |||
| a574eac4e6 | |||
| beb6c4857d | |||
| 8e5b4b0ecc | |||
| a92c6de926 | |||
| e38f4121b9 | |||
| bd40ad7dda | |||
| 767df37286 | |||
| fc33be65ab | |||
| a4639d3f1a | |||
| 405f8367df | |||
| dbf3a1e64d | |||
| 82d5c4436e | |||
| e541026656 | |||
| 8be8c23213 | |||
| 54b0519f09 | |||
| 41a2f3ed78 | |||
| 8dd1b74f96 | |||
| b9613fa72d | |||
| 295504d7d9 | |||
| ea00c503ee | |||
| 162980da67 | |||
| f2cd0f2a56 | |||
| d38d2f9b1b | |||
| 22e59d991c | |||
| 1ffd9b50a8 | |||
| 1268f83f5e | |||
| ce0ac2460c | |||
| e9615d4d64 | |||
| 48a6857738 | |||
| b489adf7c7 | |||
| 1cfe2ee99a | |||
| 9888d5f4c8 | |||
| ac1c68c7c1 | |||
| 4a3304a20e | |||
| f8a9171e12 | |||
| 79abef597b | |||
| 5593804a6f | |||
| abb6fabf39 | |||
| 1566fc07b4 | |||
| b0e986b4f9 | |||
| fb0dc31b98 | |||
| 1188a2e3c6 | |||
| 56a97f28b9 | |||
| 1c36acf6db | |||
| f07fd9c5e6 | |||
| 27a24b45b3 | |||
| c567342aaa | |||
| d9b7dda449 | |||
| 99f2482b39 | |||
| aadc9e394d | |||
| 3fec176fc1 | |||
| 680397b44f | |||
| f94691bb0e | |||
| e1c30b93ec | |||
| ec2a85f8d8 | |||
| a6e4edcb61 | |||
| 8559843f2d | |||
| c58b27b5a2 | |||
| 95687438f9 | |||
| 14de8ea270 | |||
| ce64cb46e7 | |||
| 97babd38cc | |||
| d8b7e99044 | |||
| 2bf7de07f3 | |||
| fd75174d6d | |||
| 1cbb1b8200 | |||
| 6c61b5219f | |||
| 7575ae29d9 | |||
| 745901131e | |||
| 53b58ef35a | |||
| 2cc916c8c1 | |||
| 58a4ff987f | |||
| d506feac27 | |||
| 4aeaa25d1a | |||
| b9cf1b4aa8 | |||
| ec7f195a2e | |||
| 1b7f24bae4 | |||
| 3939d2c5a7 | |||
| 2ee81093a0 | |||
| ed6792800b | |||
| bc5fc23f38 | |||
| 36f8674417 | |||
| 153b374191 | |||
| f573930ddf | |||
| d6ac3c4018 | |||
| e9afbaecdb | |||
| c761677bed | |||
| f188f239b5 | |||
| 3c458b9f16 | |||
| 5a269afd2f | |||
| 43b232ad45 | |||
| e4b155b12f | |||
| cf7692fa9a | |||
| bff46cf6d5 | |||
| 58a615b548 | |||
| 870199398c | |||
| c946e34144 | |||
| 7ccad5bf08 | |||
| 6821718b8d | |||
| e6a56e8157 | |||
| 71afe72f37 | |||
| f9d22b3d6f | |||
| 53e6b4014c | |||
| c05b1a2131 | |||
| f6d6b9a370 | |||
| 6c2bb797ad | |||
| ddd634c825 | |||
| 1bcb630619 | |||
| a75c9830e5 | |||
| 0e04d168e7 | |||
| d1a7227f4c | |||
| a8665271b0 | |||
| f7c19c4483 | |||
| df1331811c | |||
| aa5b81d0e5 | |||
| 38aa6bf660 | |||
| c2be767df1 | |||
| 9ba7b66d05 | |||
| 48b8e10795 | |||
| 2d0fbf40a8 | |||
| ebe680fb8b | |||
| 0c806022f2 | |||
| 9b0eac7617 | |||
| d84f7dadf5 | |||
| c7d8e8e0f0 | |||
| 08882a5167 | |||
| b745ae8e15 | |||
| 2a72c8380c | |||
| cc008568a0 | |||
| c5b5465bab | |||
| 0a7e5c7dc7 | |||
| d62221b796 | |||
| 3e0a698d32 | |||
| c37b0f3071 | |||
| 0fcd523d6b | |||
| ccf6e7bb7e | |||
| d211ea6ffc | |||
| a5bd532e47 | |||
| ddfb64f1a4 | |||
| 5198c9e2b5 | |||
| b39f685a90 | |||
| b2501ccba1 | |||
| 3f4b0475bc | |||
| f43cd8d90a | |||
| 66bdd41b29 | |||
| c84fc3a200 | |||
| 1f44d63865 | |||
| c4b329744e | |||
| dda588b28f | |||
| 283232630c | |||
| cd5d5011c6 | |||
| 217c0b1b67 | |||
| 4f0018d655 | |||
| 5ac8379693 | |||
| 72d0ab0d94 | |||
| 3e05634713 | |||
| 87e0997377 | |||
| d1b29ec228 | |||
| aad6cef831 | |||
| 2bd78110a7 | |||
| 6458dfd39b | |||
| e342ed1c2c | |||
| f6ad118044 | |||
| 5dc090828c | |||
| f1611bbf0f | |||
| d65609b3d2 | |||
| b3d63e9f22 | |||
| dc8612a167 | |||
| 1fbd3c1dae | |||
| fba2ecc384 | |||
| 3048127024 | |||
| 017afda5a4 | |||
| 54bcd99d17 | |||
| 7ba7afe680 | |||
| d9cffc1a34 | |||
| 781a8389d0 | |||
| 32e273df6e | |||
| cbd58a1dd8 | |||
| beb574c38f | |||
| 8e05394203 | |||
| e2c0723a23 | |||
| 7973549819 | |||
| 8e6f7a07e5 | |||
| aadeac3f34 | |||
| 422545ffe2 | |||
| 649caea538 | |||
| e7260a24e4 | |||
| 08e1a371b7 | |||
| 105f38e97f | |||
| ff1d26b75b | |||
| 43bc49303c | |||
| 5c7143b1a0 | |||
| 900fea58a1 | |||
| 3f8582df78 | |||
| bbcc196e9f | |||
| 3423f00c15 | |||
| 42fe174a69 | |||
| c1c87a2454 | |||
| d35566cdf5 | |||
| c2aa863c2a | |||
| aa1a327ac1 | |||
| b7a1ef6664 | |||
| fc7fd2aed8 | |||
| 2c4aba1557 | |||
| 703ec78974 | |||
| fc36f9d632 | |||
| 44797477ba | |||
| a739e2c51b | |||
| 1160286bc7 | |||
| e4cf9d5fda | |||
| 58bf48d8ac | |||
| 57a9577016 | |||
| 7c26b7aa94 | |||
| 0555d4b86e | |||
| c59597d8f0 | |||
| 0286894338 | |||
| ec06e03641 | |||
| 5f466110ad | |||
| 579eaccf50 | |||
| a86ff5c6e4 | |||
| c64c9fb5b2 | |||
| c945dc89ad | |||
| a9f177b980 | |||
| b85bd09778 | |||
| 62cc726070 | |||
| 959c5be424 | |||
| 5daa7c7bc9 | |||
| 43262cea6a | |||
| af39da27aa | |||
| 06b56e57ad | |||
| 545df1b1fa | |||
| 8a3f017468 | |||
| 980055d4c0 | |||
| 53f09e6143 | |||
| 23d702eeb5 | |||
| 3a419c0959 | |||
| 97e44fba1e | |||
| ac93a97e85 | |||
| 34bc347140 | |||
| e8b1258f09 | |||
| caa92e973d | |||
| 95c8ee3bf6 | |||
| 0af2d068ea | |||
| f12402e024 | |||
| 6ec5c165f5 | |||
| 686754faa0 | |||
| 2f97b39f18 | |||
| 0e62f97ed7 | |||
| ea210d816d | |||
| c200a2ffbf | |||
| 10905a7f0a | |||
| fad005cccf | |||
| 7bb1a86f48 | |||
| a3f8910268 | |||
| 1bf2825f80 | |||
| ab64e8bb14 | |||
| c1ed488b7c | |||
| 00c9744c40 | |||
| f73e8197ce | |||
| d953c75b33 | |||
| 191e82caf3 | |||
| 8b0af57c35 | |||
| 7a5de6bad0 | |||
| 2a0da6e794 | |||
| 38b057888f | |||
| b14b7afd39 | |||
| fb6b1464a3 | |||
| 328cf0e9b7 | |||
| ebb6a57ee8 | |||
| 62893ffb7c | |||
| 0e1db4ddb1 | |||
| 699762707a | |||
| efc92dfc71 | |||
| 321995a704 | |||
| d1ff654fc6 | |||
| 842d056fd7 | |||
| 58a794e8a7 | |||
| 3fbec7fb13 | |||
| 81194fbcab | |||
| f79498bc22 | |||
| a32105e156 | |||
| 65a6e30986 | |||
| 2eeb05e7af | |||
| ef07d109cf | |||
| d27b049110 | |||
| ba9924cc99 | |||
| 5a57c58563 | |||
| 66e29aa275 | |||
| 9d465b3156 | |||
| 127ea2b84c | |||
| db1950621e | |||
| b134c8f2d9 | |||
| fc9988f682 | |||
| f259604274 | |||
| 32053fb2a8 | |||
| 97d7d51fae | |||
| 327a30215e | |||
| 9c0784d59f | |||
| f63b6e5c0d | |||
| 606d6a50be | |||
| 6abea34d56 | |||
| 744e6a2576 | |||
| dff7860002 | |||
| 0ac2c5bd9d | |||
| adfedf11ce | |||
| 8fc5fe4c18 | |||
| 02b2c036ba | |||
| 9ac8f9d966 | |||
| ad6e45da23 | |||
| 94c8512c11 | |||
| 3776955d7b | |||
| 5981f96916 | |||
| ad5bdbe22d | |||
| fc717870f1 | |||
| f9a32ebce3 | |||
| 271b38c51c | |||
| a74f00a5fd | |||
| 98087d8889 | |||
| 1849eec874 | |||
| 85cb01b0d5 | |||
| f6e5078028 | |||
| 22b06e2a3b | |||
| 5e00e3128b | |||
| 5de31dd7bb | |||
| 06e2342d36 | |||
| 287157016f | |||
| 5f020414a0 | |||
| 1eeed9174a | |||
| abb9c5ce6f | |||
| 6312e251f6 | |||
| 2131f9fe44 | |||
| 997afc0e84 | |||
| eff81b718d | |||
| 76cb664d5d | |||
| 5a998c9dc0 | |||
| dfc14c26f9 | |||
| fccd4b481a | |||
| 5d5aa05f08 | |||
| dc42dd8bd4 | |||
| c24d186476 | |||
| c68d91997f | |||
| f571992692 | |||
| 21815584ac | |||
| ad4716cd79 | |||
| e67c879472 | |||
| 6977d97332 | |||
| d1279ccc9a | |||
| 0da4375857 | |||
| 3e695a37f0 | |||
| 377d8c4ed5 | |||
| e48b94c91b | |||
| 8c85e7351c | |||
| d510483f31 | |||
| 54e9797566 | |||
| 5ffb223a0d | |||
| f65b43b578 | |||
| 727d46e8d3 | |||
| 04016ff879 | |||
| 2105391c89 | |||
| 71c0bacf9c | |||
| af5080b422 | |||
| 70edab78a4 | |||
| 47eaf46bb4 | |||
| 5ea18aa018 | |||
| ac4ec9c390 | |||
| 04a0d6bea9 | |||
| be334165ba | |||
| 13f7116552 | |||
| b529adefcb | |||
| 3afd1add40 | |||
| 6a232fee94 | |||
| a9df82cbab | |||
| a197bbc21a | |||
| 0610229157 | |||
| 5ec0616a1e | |||
| 81a0ff1d44 | |||
| 3c4b4adfb4 | |||
| 545e483397 | |||
| 309973e37f | |||
| 71534e065b | |||
| ff019542f8 | |||
| a7a99cc4ec | |||
| 5b5b75142f | |||
| d8b915f8a5 | |||
| 83e7c0b077 | |||
| 4738a23fc6 | |||
| 7c6bd1804b | |||
| f949fa5087 | |||
| 700a09ed86 | |||
| 1b3d6fb2fc | |||
| 3446505c27 | |||
| 34c2c736ad | |||
| c75711642a | |||
| eef4988177 | |||
| 05207700fe | |||
| 0c75ab2b5a | |||
| 8850616584 | |||
| e6b782ee64 | |||
| 3003ca4ed2 | |||
| d2b6584ef0 | |||
| 1ac18b3819 | |||
| 3d69e259be | |||
| 021bac8f83 | |||
| 2f98f0c75d | |||
| e7945df218 | |||
| 8694606441 | |||
| 468f482db9 |
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="test"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="lib" path="lib/log4j-1.2.15.jar"/>
|
||||
<classpathentry kind="lib" path="lib/xstream-1.3.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/junit-4.7.jar"/>
|
||||
<classpathentry kind="lib" path="lib/iText-2.1.7.jar"/>
|
||||
<classpathentry kind="lib" path="lib/cloning-1.5.jar"/>
|
||||
<classpathentry kind="lib" path="lib/objenesis-1.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/jettison-1.0.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/poi-3.5-FINAL-20090928.jar"/>
|
||||
<classpathentry kind="lib" path="library/main.jar"/>
|
||||
<classpathentry kind="lib" path="lib/bancika-gui-framework.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
@@ -1 +0,0 @@
|
||||
/bin/
|
||||
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>DIYLC</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
|
||||
<stringAttribute key="bad_container_name" value="\DIYLC\r"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/DIYLC/src/org/diylc/DIYLCStarter.java"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="1"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.debug.core.source_locator_id" value="org.eclipse.jdt.launching.sourceLocator.JavaSourceLookupDirector"/>
|
||||
<stringAttribute key="org.eclipse.debug.core.source_locator_memento" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <sourceLookupDirector> <sourceContainers duplicates="false"> <container memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;javaProject name=&quot;Library&quot;/&gt;&#13;&#10;" typeId="org.eclipse.jdt.launching.sourceContainer.javaProject"/> <container memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;javaProject name=&quot;DIYLC&quot;/&gt;&#13;&#10;" typeId="org.eclipse.jdt.launching.sourceContainer.javaProject"/> <container memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;default/&gt;&#13;&#10;" typeId="org.eclipse.debug.core.containerType.default"/> </sourceContainers> </sourceLookupDirector> "/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.diylc.DIYLCStarter"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="DIYLC"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms256m -Xmx512m"/>
|
||||
</launchConfiguration>
|
||||
@@ -1,78 +0,0 @@
|
||||
<project name="diylc" basedir="." default="jar">
|
||||
<property name="src.dir" value="src" />
|
||||
|
||||
<property name="lib.dir" value="${basedir}/lib" />
|
||||
<property name="build.dir" value="${basedir}/build" />
|
||||
<property name="jar.dir" value="${build.dir}/jar" />
|
||||
<property name="report.dir" value="${build.dir}/junitreport" />
|
||||
<property name="main.class" value="org.diylc.DIYLCStarter" />
|
||||
|
||||
<property name="classes.dir" value="${build.dir}/temp/${ant.project.name}/classes" />
|
||||
<property name="test.classes.dir" value="${build.dir}/temp/${ant.project.name}/test.classes" />
|
||||
|
||||
<target name="clean">
|
||||
<delete dir="${build.dir}" />
|
||||
</target>
|
||||
|
||||
<!--change src dir-->
|
||||
<target name="compile">
|
||||
<mkdir dir="${classes.dir}" />
|
||||
<echo>Compile with JDK ${java.runtime.version}</echo>
|
||||
<javac encoding="8859_1" srcdir="${src.dir}" destdir="${classes.dir}" classpathref="class.path" />
|
||||
</target>
|
||||
|
||||
<target name="resource.copy">
|
||||
<copy todir="${classes.dir}">
|
||||
<fileset dir="${src.dir}">
|
||||
<exclude name="**/*.java" />
|
||||
</fileset>
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="lib.copy">
|
||||
<copy todir="${jar.dir}/lib" overwrite="true">
|
||||
<fileset dir="${basedir}/lib">
|
||||
<exclude name="**/*dll" />
|
||||
</fileset>
|
||||
</copy>
|
||||
<copy todir="${jar.dir}/library" overwrite="true">
|
||||
<fileset dir="${basedir}/library">
|
||||
<exclude name="**/*dll" />
|
||||
</fileset>
|
||||
</copy>
|
||||
<copy todir="${jar.dir}" overwrite="true">
|
||||
<fileset dir="${basedir}/lib/" includes="**/*.dll" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<path id="class.path">
|
||||
<fileset dir="${basedir}">
|
||||
<include name="lib/**/*.jar" />
|
||||
<include name="library/**/*.jar" />
|
||||
</fileset>
|
||||
</path>
|
||||
|
||||
<manifestclasspath jarfile="${ant.project.name}.jar" property="manifest.class.path">
|
||||
<classpath refid="class.path" />
|
||||
</manifestclasspath>
|
||||
|
||||
<target name="jar" depends="clean, lib.copy, resource.copy, compile">
|
||||
<jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="${user.name}" />
|
||||
<attribute name="Main-Class" value="${main.class}" />
|
||||
<attribute name="Class-Path" value="${manifest.class.path}" />
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="javadoc">
|
||||
<javadoc access="public" author="true" classpathref="class.path" destdir="doc" nodeprecated="false" nodeprecatedlist="false" noindex="false" nonavbar="false" notree="false" source="1.6" splitindex="true" use="true" version="true">
|
||||
<fileset dir="${src.dir}">
|
||||
<exclude name="**\.svn\**" />
|
||||
<include name="**/*.java" />
|
||||
</fileset>
|
||||
</javadoc>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
@@ -1,86 +0,0 @@
|
||||
<map>
|
||||
<entry>
|
||||
<string>default.org.diylc.components.passive.TrimmerPotentiometer:Type</string>
|
||||
<org.diylc.components.passive.TrimmerPotentiometer_-TrimmerType>FLAT_LARGE</org.diylc.components.passive.TrimmerPotentiometer_-TrimmerType>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>lastPath</string>
|
||||
<string>C:\Documents and Settings\Branislav Stojkovic\My Documents\Downloads</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>abnormalExit</string>
|
||||
<boolean>false</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>stickyPoints</string>
|
||||
<boolean>true</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>theme</string>
|
||||
<org.diylc.core.Theme>
|
||||
<name>Light</name>
|
||||
<bgColor>
|
||||
<red>255</red>
|
||||
<green>255</green>
|
||||
<blue>255</blue>
|
||||
<alpha>255</alpha>
|
||||
</bgColor>
|
||||
<gridColor>
|
||||
<red>240</red>
|
||||
<green>240</green>
|
||||
<blue>240</blue>
|
||||
<alpha>240</alpha>
|
||||
</gridColor>
|
||||
<outlineColor>
|
||||
<red>0</red>
|
||||
<green>0</green>
|
||||
<blue>0</blue>
|
||||
<alpha>255</alpha>
|
||||
</outlineColor>
|
||||
</org.diylc.core.Theme>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>antiAliasing</string>
|
||||
<boolean>true</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>snapToGrid</string>
|
||||
<boolean>true</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>hiQualityRender</string>
|
||||
<boolean>false</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>outline</string>
|
||||
<boolean>true</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>exportGrid</string>
|
||||
<boolean>true</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>autoEdit</string>
|
||||
<boolean>false</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>wheelZoom</string>
|
||||
<boolean>false</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>default.org.diylc.components.misc.Label:Font Bold</string>
|
||||
<boolean>false</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>autoCreatePads</string>
|
||||
<boolean>true</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>continuousCreation</string>
|
||||
<boolean>true</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>showTemplatesAtStartup</string>
|
||||
<boolean>false</boolean>
|
||||
</entry>
|
||||
</map>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,76 +0,0 @@
|
||||
package org.diylc;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.log4j.PropertyConfigurator;
|
||||
import org.diylc.presenter.Presenter;
|
||||
import org.diylc.swing.gui.MainFrame;
|
||||
import org.diylc.swing.gui.TemplateDialog;
|
||||
|
||||
import com.diyfever.gui.miscutils.ConfigurationManager;
|
||||
import com.diyfever.gui.miscutils.PropertyInjector;
|
||||
|
||||
/**
|
||||
* Main class that runs DIYLC.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*
|
||||
* @see Presenter
|
||||
* @see MainFrame
|
||||
*/
|
||||
public class DIYLCStarter {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(Presenter.class);
|
||||
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
URL url = DIYLCStarter.class.getResource("log4j.properties");
|
||||
Properties properties = new Properties();
|
||||
try {
|
||||
properties.load(url.openStream());
|
||||
PropertyConfigurator.configure(properties);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Could not initialize log4j configuration", e);
|
||||
}
|
||||
|
||||
LOG.debug("Java version: " + System.getProperty("java.runtime.version") + " by " + System.getProperty("java.vm.vendor"));
|
||||
|
||||
LOG.info("Starting DIYLC with working directory " + System.getProperty("user.dir"));
|
||||
|
||||
try {
|
||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
} catch (Exception e) {
|
||||
LOG.error("Could not set Look&Feel", e);
|
||||
}
|
||||
|
||||
MainFrame mainFrame = new MainFrame();
|
||||
mainFrame.setLocationRelativeTo(null);
|
||||
mainFrame.setVisible(true);
|
||||
|
||||
boolean showTemplates = ConfigurationManager.getInstance().readBoolean(
|
||||
TemplateDialog.SHOW_TEMPLATES_KEY, true);
|
||||
if (showTemplates) {
|
||||
TemplateDialog templateDialog = new TemplateDialog(mainFrame, mainFrame.getPresenter());
|
||||
if (!templateDialog.getFiles().isEmpty()) {
|
||||
templateDialog.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
url = DIYLCStarter.class.getResource("/config.properties");
|
||||
properties = new Properties();
|
||||
try {
|
||||
LOG.info("Injecting default properties.");
|
||||
properties.load(new FileInputStream("config.properties"));
|
||||
PropertyInjector.injectProperties(properties);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Could not read config.properties file", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
-7
@@ -1,7 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
public class BadPositionException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
||||
-88
@@ -1,88 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
import org.diylc.core.CreationMethod;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
/**
|
||||
* Entity class used to describe a component type.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*
|
||||
* @see IDIYComponent
|
||||
*/
|
||||
public class ComponentType {
|
||||
|
||||
private String name;
|
||||
private String description;
|
||||
private CreationMethod creationMethod;
|
||||
private String category;
|
||||
private String namePrefix;
|
||||
private String author;
|
||||
private Icon icon;
|
||||
private Class<? extends IDIYComponent<?>> instanceClass;
|
||||
private double zOrder;
|
||||
private boolean stretchable;
|
||||
|
||||
public ComponentType(String name, String description, CreationMethod creationMethod,
|
||||
String category, String namePrefix, String author, Icon icon,
|
||||
Class<? extends IDIYComponent<?>> instanceClass, double zOrder, boolean stretchable) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.creationMethod = creationMethod;
|
||||
this.category = category;
|
||||
this.namePrefix = namePrefix;
|
||||
this.author = author;
|
||||
this.icon = icon;
|
||||
this.instanceClass = instanceClass;
|
||||
this.zOrder = zOrder;
|
||||
this.stretchable = stretchable;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public CreationMethod getCreationMethod() {
|
||||
return creationMethod;
|
||||
}
|
||||
|
||||
public String getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
public String getNamePrefix() {
|
||||
return namePrefix;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public Icon getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
public Class<? extends IDIYComponent<?>> getInstanceClass() {
|
||||
return instanceClass;
|
||||
}
|
||||
|
||||
public double getZOrder() {
|
||||
return zOrder;
|
||||
}
|
||||
|
||||
public boolean isStretchable() {
|
||||
return stretchable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
public enum Display {
|
||||
|
||||
NAME, VALUE;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().substring(0, 1) + name().substring(1).toLowerCase();
|
||||
}
|
||||
}
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
import java.awt.Graphics;
|
||||
|
||||
/**
|
||||
* Enumerates all options that can be used when drawing a project.
|
||||
*
|
||||
* @see IPlugInPort#draw(java.awt.Graphics2D, java.util.Set, IComponentFiler)
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public enum DrawOption {
|
||||
|
||||
/**
|
||||
* Selection rectangle will be drawn when needed and selected components may
|
||||
* be rendered differently.
|
||||
*/
|
||||
SELECTION,
|
||||
/**
|
||||
* Selected zoom level will be applied to scale the {@link Graphics} before
|
||||
* drawing.
|
||||
*/
|
||||
ZOOM,
|
||||
/**
|
||||
* Grid lines are drawn.
|
||||
*/
|
||||
GRID,
|
||||
/**
|
||||
* Control points are drawn.
|
||||
*/
|
||||
CONTROL_POINTS,
|
||||
/**
|
||||
* Anti-aliasing is used when drawing.
|
||||
*/
|
||||
ANTIALIASING,
|
||||
/**
|
||||
* Draw components in outline mode.
|
||||
*/
|
||||
OUTLINE_MODE;
|
||||
}
|
||||
-83
@@ -1,83 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.Point2D;
|
||||
|
||||
import org.diylc.core.Project;
|
||||
|
||||
/**
|
||||
* Enumerates all possible events between {@link IPlugInPort} and
|
||||
* {@link IPlugIn}. Some events overlap so be careful which ones you subscribe
|
||||
* for and how you process them.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public enum EventType {
|
||||
|
||||
/**
|
||||
* Called when zoom level changes. Typically only one parameter of type
|
||||
* {@link Double} is passed with new zoom level.
|
||||
*/
|
||||
ZOOM_CHANGED,
|
||||
/**
|
||||
* Called when a new project is loaded. New {@link Project} is the first
|
||||
* parameter. Boolean flag is the second parameter and it's true when new
|
||||
* project is loaded, false when the same project has been either reloaded
|
||||
* or loaded with undo/redo operations.
|
||||
*/
|
||||
PROJECT_LOADED,
|
||||
/**
|
||||
* Called when either current file name or modified flag are changed. The
|
||||
* first parameter is the current file name, the second one is a boolean
|
||||
* modified flag.
|
||||
*/
|
||||
FILE_STATUS_CHANGED,
|
||||
/**
|
||||
* Called when selection rectangle is changed. Object of type
|
||||
* {@link Rectangle} is the only parameter and it contains the new selection
|
||||
* rectangle.
|
||||
*/
|
||||
SELECTION_RECT_CHANGED,
|
||||
/**
|
||||
* Called when component selection is changed. New
|
||||
* {@link ComponentSelection} is attached as a parameter.
|
||||
*/
|
||||
SELECTION_CHANGED,
|
||||
/**
|
||||
* Called when selection size changes, together with a {@link Point2D}
|
||||
* object containing selection size (x = width, y = height). Size is
|
||||
* expressed in the default measure (cm for metric, inches for imperial).
|
||||
*/
|
||||
REPAINT,
|
||||
/**
|
||||
* Called when new component slot has been changed. The only parameter is
|
||||
* {@link ComponentType} and may be null.
|
||||
*/
|
||||
SLOT_CHANGED,
|
||||
/**
|
||||
* Called when the current project has been modified. Two instances of
|
||||
* {@link Project} are passed as parameters, one before and one after the
|
||||
* change. The third parameter is a string containing change description.
|
||||
*/
|
||||
PROJECT_MODIFIED,
|
||||
/**
|
||||
* Called when control points under the cursor are changed. A single
|
||||
* parameter is passed, an instance of
|
||||
* <code>Map<IDIYComponent<?>, Set<Integer>></code> containing all the
|
||||
* components and indices of their control points that are under the cursor.
|
||||
*/
|
||||
AVAILABLE_CTRL_POINTS_CHANGED,
|
||||
/**
|
||||
* Called when mouse cursor is moved. Point object is passed, containing the
|
||||
* current cursor location (not taking zoom into account).
|
||||
*/
|
||||
MOUSE_MOVED,
|
||||
/**
|
||||
* Called when a layer status is changed. The first parameter is a set of indices of locked layers. All layers not included are considered unlocked.
|
||||
*/
|
||||
LAYER_STATE_CHANGED,
|
||||
/**
|
||||
* Called to update the status message. New status message is passed as a first parameter.
|
||||
*/
|
||||
STATUS_MESSAGE_CHANGED;
|
||||
}
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
public enum GridType {
|
||||
|
||||
LINES, CROSSHAIR, DOT, NONE;
|
||||
}
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
public interface IComponentFiler {
|
||||
|
||||
boolean testComponent(IDIYComponent<?> component);
|
||||
}
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
import com.diyfever.gui.simplemq.IMessageListener;
|
||||
|
||||
/**
|
||||
* Interface for plug-ins.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public interface IPlugIn extends IMessageListener<EventType> {
|
||||
|
||||
/**
|
||||
* Method that connects the plug-in with {@link IPlugInPort}. Called by the
|
||||
* application when plug-in is installed.
|
||||
*
|
||||
* @param plugInPort
|
||||
*/
|
||||
void connect(IPlugInPort plugInPort);
|
||||
}
|
||||
-375
@@ -1,375 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.Theme;
|
||||
import org.diylc.swing.plugins.edit.ComponentTransferable;
|
||||
|
||||
import com.diyfever.gui.simplemq.IMessageListener;
|
||||
import com.diyfever.gui.simplemq.MessageDispatcher;
|
||||
import com.diyfever.gui.update.VersionNumber;
|
||||
|
||||
/**
|
||||
* Interface for communication between plug-ins and the application. Plug-ins
|
||||
* may acquire information or make changes through this interface. Application
|
||||
* events are dispatched to plug-ins through {@link MessageDispatcher}
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*
|
||||
* @see IPlugIn
|
||||
* @see MessageDispatcher
|
||||
* @see IMessageListener
|
||||
* @see EventType
|
||||
*/
|
||||
public interface IPlugInPort {
|
||||
|
||||
public static final String ANTI_ALIASING_KEY = "antiAliasing";
|
||||
public static final String HI_QUALITY_RENDER_KEY = "hiQualityRender";
|
||||
public static final String EXPORT_GRID_KEY = "exportGrid";
|
||||
public static final String STICKY_POINTS_KEY = "stickyPoints";
|
||||
public static final String METRIC_KEY = "metric";
|
||||
public static final String SNAP_TO_GRID_KEY = "snapToGrid";
|
||||
public static final String AUTO_PADS_KEY = "autoCreatePads";
|
||||
public static final String CONTINUOUS_CREATION_KEY = "continuousCreation";
|
||||
public static final String AUTO_EDIT_KEY = "autoEdit";
|
||||
public static final String ABNORMAL_EXIT_KEY = "abnormalExit";
|
||||
public static final String WHEEL_ZOOM_KEY = "wheelZoom";
|
||||
public static final String OUTLINE_KEY = "outline";
|
||||
public static final String THEME_KEY = "theme";
|
||||
public static final String RECENT_COMPONENTS_KEY = "recentComponents";
|
||||
|
||||
/**
|
||||
* Returns size of the canvas that takes project dimensions into account as
|
||||
* well as zoom level. Each dimension is calculated as the product of the
|
||||
* actual size and the number of pixels per unit. If <code>useZoom</code> is
|
||||
* set to true, the result is scaled by zoom factor.
|
||||
*
|
||||
* @param useZoom
|
||||
*
|
||||
* @return canvas dimensions
|
||||
*/
|
||||
Dimension getCanvasDimensions(boolean useZoom);
|
||||
|
||||
/**
|
||||
* Returns an instance of {@link Cursor} that should be used at the
|
||||
* specified location.
|
||||
*
|
||||
* Note: point coordinates are scaled for zoom factor.
|
||||
*
|
||||
* @param point
|
||||
* @return cursor
|
||||
*/
|
||||
Cursor getCursorAt(Point point);
|
||||
|
||||
/**
|
||||
* Returns an instance of currently loaded project.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Project getCurrentProject();
|
||||
|
||||
/**
|
||||
* Loads specified {@link Project}.
|
||||
*
|
||||
* @param project
|
||||
* @param freshStart
|
||||
*/
|
||||
void loadProject(Project project, boolean freshStart);
|
||||
|
||||
/**
|
||||
* Creates a new project.
|
||||
*/
|
||||
void createNewProject();
|
||||
|
||||
/**
|
||||
* Loads a project from the specified file.
|
||||
*
|
||||
* @param fileName
|
||||
*/
|
||||
void loadProjectFromFile(String fileName);
|
||||
|
||||
/**
|
||||
* Saves the current project into the specified file.
|
||||
*
|
||||
* @param fileName
|
||||
* @param isBackup
|
||||
*/
|
||||
void saveProjectToFile(String fileName, boolean isBackup);
|
||||
|
||||
/**
|
||||
* @return the current file name.
|
||||
*/
|
||||
String getCurrentFileName();
|
||||
|
||||
/**
|
||||
* @return true if the current project is modified.
|
||||
*/
|
||||
boolean isProjectModified();
|
||||
|
||||
/**
|
||||
* Shows a user dialog if there are changes to confirm that it's safe to
|
||||
* proceed.
|
||||
*
|
||||
* @return true, if file actions (new, open, close) can be taken
|
||||
*/
|
||||
boolean allowFileAction();
|
||||
|
||||
/**
|
||||
* Returns all available {@link ComponentType}s classified by category.
|
||||
* Result is a {@link Map} between category name to a {@link List} of all
|
||||
* {@link ComponentType}s that share that category name.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Map<String, List<ComponentType>> getComponentTypes();
|
||||
|
||||
/**
|
||||
* Draws project on the provided {@link Graphics2D}. If the provided filter
|
||||
* is not null, it will be used to filter the components that are shown.
|
||||
*
|
||||
* @param g2d
|
||||
* @param drawOptions
|
||||
* specific drawing options
|
||||
* @param filter
|
||||
*/
|
||||
void draw(Graphics2D g2d, Set<DrawOption> drawOptions, IComponentFiler filter);
|
||||
|
||||
Double[] getAvailableZoomLevels();
|
||||
|
||||
/**
|
||||
* Returns current zoom level where <code>zoomLevel = 1.0d</code> means
|
||||
* 100%.
|
||||
*
|
||||
* @return current zoom level
|
||||
*/
|
||||
double getZoomLevel();
|
||||
|
||||
/**
|
||||
* Changes current zoom level where <code>zoomLevel = 1.0d</code> means 100%
|
||||
*
|
||||
* @param zoomLevel
|
||||
* new zoom leve
|
||||
*/
|
||||
void setZoomLevel(double zoomLevel);
|
||||
|
||||
/**
|
||||
* Notifies the presenter that mouse is clicked.
|
||||
*
|
||||
* Note: point coordinates are display based, i.e. scaled for zoom factor.
|
||||
*
|
||||
* @param point
|
||||
* @param ctrlDown
|
||||
* @param shiftDown
|
||||
* @param altDown
|
||||
* @param clickCount
|
||||
*/
|
||||
void mouseClicked(Point point, boolean ctrlDown, boolean shiftDown, boolean altDown,
|
||||
int clickCount);
|
||||
|
||||
/**
|
||||
* Notifies the presenter that mouse is moved.
|
||||
*
|
||||
* Note: point coordinates are display based, i.e. scaled for zoom factor.
|
||||
*
|
||||
* @param point
|
||||
* @param ctrlDown
|
||||
* @param shiftDown
|
||||
* @param altDown
|
||||
*/
|
||||
void mouseMoved(Point point, boolean ctrlDown, boolean shiftDown, boolean altDown);
|
||||
|
||||
/**
|
||||
* Returns the current {@link ComponentTransferable}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<IDIYComponent<?>> getSelectedComponents();
|
||||
|
||||
/**
|
||||
* Updates the selection with the specified list of component. Also, updates
|
||||
* control point map with all components that are stuck to the newly
|
||||
* selected components.
|
||||
*
|
||||
* @param newSelection
|
||||
*/
|
||||
void updateSelection(List<IDIYComponent<?>> newSelection);
|
||||
|
||||
/**
|
||||
* Selects all components in the project.
|
||||
*/
|
||||
void selectAll();
|
||||
|
||||
/**
|
||||
* Notification that drag has been started from the specified point.
|
||||
*
|
||||
* Note: point coordinates are scaled for zoom factor.
|
||||
*
|
||||
* @param point
|
||||
* @param ctrlDown
|
||||
* @param shiftDown
|
||||
* @param altDown
|
||||
*/
|
||||
void dragStarted(Point point, boolean ctrlDown, boolean shiftDown, boolean altDown);
|
||||
|
||||
/**
|
||||
* Checks if it's possible to drop over the specified point.
|
||||
*
|
||||
* Note: point coordinates are scaled for zoom factor.
|
||||
*
|
||||
* @param point
|
||||
* @return
|
||||
*/
|
||||
boolean dragOver(Point point);
|
||||
|
||||
/**
|
||||
* Notification that drag has been ended in the specified point.
|
||||
*
|
||||
* Note: point coordinates are scaled for zoom factor.
|
||||
*
|
||||
* @param point
|
||||
*/
|
||||
void dragEnded(Point point);
|
||||
|
||||
/**
|
||||
* Returns current version number.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
VersionNumber getCurrentVersionNumber();
|
||||
|
||||
/**
|
||||
* Adds a list of components to the project.
|
||||
*
|
||||
* @param components
|
||||
*/
|
||||
void pasteComponents(List<IDIYComponent<?>> components);
|
||||
|
||||
/**
|
||||
* Deletes all the selected components from the project.
|
||||
*/
|
||||
void deleteSelectedComponents();
|
||||
|
||||
/**
|
||||
* Sets default value for the specified property name for currently selected
|
||||
* component types.
|
||||
*
|
||||
* @param propertyName
|
||||
* display name for property
|
||||
* @param value
|
||||
* new default value, must not be null
|
||||
*/
|
||||
void setSelectionDefaultPropertyValue(String propertyName, Object value);
|
||||
|
||||
/**
|
||||
* Sets default value for the specified property name for projects.
|
||||
*
|
||||
* @param propertyName
|
||||
* display name for property
|
||||
* @param value
|
||||
* new default value, must not be null
|
||||
*/
|
||||
void setProjectDefaultPropertyValue(String propertyName, Object value);
|
||||
|
||||
/**
|
||||
* @return a list of properties that are mutual for all the selected
|
||||
* components. Resulting list may be empty if selected components do
|
||||
* not have mutual properties or can be null if the selection is
|
||||
* empty.
|
||||
*/
|
||||
List<PropertyWrapper> getMutualSelectionProperties();
|
||||
|
||||
void editSelection();
|
||||
|
||||
/**
|
||||
* @return a list of editable properties of the current project.
|
||||
*/
|
||||
List<PropertyWrapper> getProjectProperties();
|
||||
|
||||
/**
|
||||
* Applies specified properties to the current project.
|
||||
*
|
||||
* @param properties
|
||||
*/
|
||||
void applyPropertiesToProject(List<PropertyWrapper> properties);
|
||||
|
||||
/**
|
||||
* Sets the new component slot. Specified component type will be used to
|
||||
* instantiate new component.
|
||||
*/
|
||||
void setNewComponentTypeSlot(ComponentType componentType);
|
||||
|
||||
/**
|
||||
* Changes default size notation, true for metric, false for imperial.
|
||||
*
|
||||
* @param isMetric
|
||||
*/
|
||||
void setMetric(boolean isMetric);
|
||||
|
||||
/**
|
||||
* Groups all selected components.
|
||||
*/
|
||||
void groupSelectedComponents();
|
||||
|
||||
/**
|
||||
* Ungroups all selected components.
|
||||
*/
|
||||
void ungroupSelectedComponents();
|
||||
|
||||
/**
|
||||
* Locks or unlocks the specified layer. All components within +- 0.5 range
|
||||
* will be affected by the change as well.
|
||||
*
|
||||
* @param layerZOrder
|
||||
* @param locked
|
||||
*/
|
||||
void setLayerLocked(int layerZOrder, boolean locked);
|
||||
|
||||
/**
|
||||
* @return selection size expressed in either inches or centimeters, based
|
||||
* on the user preference.
|
||||
*/
|
||||
Point2D calculateSelectionDimension();
|
||||
|
||||
/**
|
||||
* Sends each of the selected components one step back.
|
||||
*/
|
||||
void sendSelectionToBack();
|
||||
|
||||
/**
|
||||
* Brings each of the selected components one step to front.
|
||||
*/
|
||||
void bringSelectionToFront();
|
||||
|
||||
/**
|
||||
* Causes the display to refresh.
|
||||
*/
|
||||
void refresh();
|
||||
|
||||
/**
|
||||
* @return currently selected theme.
|
||||
*/
|
||||
Theme getSelectedTheme();
|
||||
|
||||
/**
|
||||
* Changes the current theme.
|
||||
*
|
||||
* @param theme
|
||||
*/
|
||||
void setSelectedTheme(Theme theme);
|
||||
|
||||
/**
|
||||
* Renumbers all the selected components.
|
||||
*
|
||||
* @param xAxisFirst
|
||||
*/
|
||||
void renumberSelectedComponents(boolean xAxisFirst);
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
/**
|
||||
* Abstract layer between the app and platform worker thread implementation.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public interface ITask<T> {
|
||||
|
||||
/**
|
||||
* Runs in background thread.
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
T doInBackground() throws Exception;
|
||||
|
||||
/**
|
||||
* Called if background thread fails.
|
||||
*
|
||||
* @param e
|
||||
*/
|
||||
void failed(Exception e);
|
||||
|
||||
/**
|
||||
* Called if background thread is executed correctly, the result is passed
|
||||
* as a parameter.
|
||||
*
|
||||
* @param result
|
||||
*/
|
||||
void complete(T result);
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
public enum LabelPosition {
|
||||
|
||||
ABOVE, BELOW;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().substring(0, 1) + name().substring(1).toLowerCase();
|
||||
}
|
||||
}
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Stroke;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Repository for object that may be reused, such as {@link Stroke} or
|
||||
* {@link AlphaComposite}.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class ObjectCache {
|
||||
|
||||
private static ObjectCache instance;
|
||||
|
||||
public static ObjectCache getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new ObjectCache();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private ObjectCache() {
|
||||
}
|
||||
|
||||
private Map<Integer, Stroke> basicStrokeMap = new HashMap<Integer, Stroke>();
|
||||
|
||||
public Stroke fetchBasicStroke(int width) {
|
||||
if (basicStrokeMap.containsKey(width)) {
|
||||
return basicStrokeMap.get(width);
|
||||
}
|
||||
Stroke stroke = new BasicStroke(width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
|
||||
basicStrokeMap.put(width, stroke);
|
||||
return stroke;
|
||||
}
|
||||
}
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
public enum Orientation {
|
||||
|
||||
DEFAULT, _90, _180, _270;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (this == DEFAULT) {
|
||||
return "Default";
|
||||
} else {
|
||||
return name().replace("_", "") + " degrees clockwise";
|
||||
}
|
||||
}
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
public enum OrientationHV {
|
||||
|
||||
VERTICAL, HORIZONTAL;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().substring(0, 1) + name().substring(1).toLowerCase();
|
||||
}
|
||||
}
|
||||
-156
@@ -1,156 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import org.diylc.core.IPropertyValidator;
|
||||
|
||||
/**
|
||||
* Entity class for editable properties extracted from component objects.
|
||||
* Represents a single editable property together with it's current value.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class PropertyWrapper implements Cloneable {
|
||||
|
||||
private String name;
|
||||
private Class<?> type;
|
||||
private Object value;
|
||||
private String setter;
|
||||
private String getter;
|
||||
private boolean defaultable;
|
||||
private IPropertyValidator validator;
|
||||
private boolean unique = true;
|
||||
private boolean changed = false;
|
||||
|
||||
public PropertyWrapper(String name, Class<?> type, String getter, String setter,
|
||||
boolean defaultable, IPropertyValidator validator) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.getter = getter;
|
||||
this.setter = setter;
|
||||
this.defaultable = defaultable;
|
||||
this.validator = validator;
|
||||
}
|
||||
|
||||
public void readFrom(Object object) throws IllegalArgumentException, IllegalAccessException,
|
||||
InvocationTargetException, SecurityException, NoSuchMethodException {
|
||||
this.value = object.getClass().getMethod(getter).invoke(object);
|
||||
}
|
||||
|
||||
// public void readUniqueFrom(IDIYComponent component)
|
||||
// throws IllegalArgumentException, IllegalAccessException,
|
||||
// InvocationTargetException {
|
||||
// Object newValue = getter.invoke(component);
|
||||
// if (!newValue.equals(value)) {
|
||||
// this.value = null;
|
||||
// }
|
||||
// }
|
||||
|
||||
public void writeTo(Object object) throws IllegalArgumentException, IllegalAccessException,
|
||||
InvocationTargetException, SecurityException, NoSuchMethodException {
|
||||
object.getClass().getMethod(setter, type).invoke(object, this.value);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public boolean isDefaultable() {
|
||||
return defaultable;
|
||||
}
|
||||
|
||||
public IPropertyValidator getValidator() {
|
||||
return validator;
|
||||
}
|
||||
|
||||
public boolean isUnique() {
|
||||
return unique;
|
||||
}
|
||||
|
||||
public void setUnique(boolean unique) {
|
||||
this.unique = unique;
|
||||
}
|
||||
|
||||
public boolean isChanged() {
|
||||
return changed;
|
||||
}
|
||||
|
||||
public void setChanged(boolean changed) {
|
||||
this.changed = changed;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public Object clone() throws CloneNotSupportedException {
|
||||
// // Try to invoke clone method on value if possible.
|
||||
// try {
|
||||
// Method cloneMethod = value.getClass().getMethod("clone");
|
||||
// return new Property(name, type, cloneMethod.invoke(value));
|
||||
// } catch (Exception e) {
|
||||
// }
|
||||
// return new Property(name, type, value);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (defaultable ? 1231 : 1237);
|
||||
result = prime * result + ((getter == null) ? 0 : getter.hashCode());
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + ((setter == null) ? 0 : setter.hashCode());
|
||||
result = prime * result + ((type == null) ? 0 : type.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
PropertyWrapper other = (PropertyWrapper) obj;
|
||||
if (defaultable != other.defaultable)
|
||||
return false;
|
||||
if (getter == null) {
|
||||
if (other.getter != null)
|
||||
return false;
|
||||
} else if (!getter.equals(other.getter))
|
||||
return false;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
if (setter == null) {
|
||||
if (other.setter != null)
|
||||
return false;
|
||||
} else if (!setter.equals(other.setter))
|
||||
return false;
|
||||
if (type == null) {
|
||||
if (other.type != null)
|
||||
return false;
|
||||
} else if (!type.equals(other.type))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + " = " + value;
|
||||
}
|
||||
}
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
public enum ResistorColorCode {
|
||||
|
||||
NONE, _4_BAND, _5_BAND;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (name().startsWith("_")) {
|
||||
return name().substring(1).replace("_", " ").toLowerCase();
|
||||
}
|
||||
return name().substring(0, 1).toUpperCase() + name().substring(1).toLowerCase();
|
||||
}
|
||||
}
|
||||
-73
@@ -1,73 +0,0 @@
|
||||
package org.diylc.components;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.Shape;
|
||||
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
|
||||
/**
|
||||
* Abstract implementation of {@link IDIYComponent} that contains component name
|
||||
* and toString.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract class AbstractComponent<T> implements IDIYComponent<T> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
protected String name = "";
|
||||
|
||||
public static Color SELECTION_COLOR = Color.red;
|
||||
public static Color LABEL_COLOR = Color.black;
|
||||
public static Color LABEL_COLOR_SELECTED = Color.red;
|
||||
public static Font LABEL_FONT = new Font("Tahoma", Font.PLAIN, 14);
|
||||
|
||||
@EditableProperty(defaultable = false)
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canControlPointOverlap(int index) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the closest odd number, i.e. x when x is odd, or x + 1 when x is
|
||||
* even.
|
||||
*
|
||||
* @param x
|
||||
* @return
|
||||
*/
|
||||
protected int getClosestOdd(double x) {
|
||||
return ((int) x / 2) * 2 + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clip
|
||||
* @return true if none of the control points lie in the clip rectangle.
|
||||
*/
|
||||
protected boolean checkPointsClipped(Shape clip) {
|
||||
for (int i = 0; i < getControlPointCount(); i++) {
|
||||
if (clip.contains(getControlPoint(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
-249
@@ -1,249 +0,0 @@
|
||||
package org.diylc.components;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.geom.CubicCurve2D;
|
||||
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.VisibilityPolicy;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
public abstract class AbstractCurvedComponent<T> extends AbstractTransparentComponent<T> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static Color GUIDELINE_COLOR = Color.blue;
|
||||
public static Size DEFAULT_SIZE = new Size(1d, SizeUnit.in);
|
||||
|
||||
protected Point[] controlPoints = new Point[] {
|
||||
new Point(0, 0),
|
||||
new Point((int) (DEFAULT_SIZE.convertToPixels() / 2), 0),
|
||||
new Point((int) (DEFAULT_SIZE.convertToPixels() / 2), (int) (DEFAULT_SIZE
|
||||
.convertToPixels())),
|
||||
new Point((int) DEFAULT_SIZE.convertToPixels(), (int) DEFAULT_SIZE.convertToPixels()) };
|
||||
|
||||
protected Color color = getDefaultColor();
|
||||
protected PointCount pointCount = PointCount.FOUR;
|
||||
|
||||
/**
|
||||
* Draws the specified curve onto graphics.
|
||||
*
|
||||
* @param curve
|
||||
* @param g2d
|
||||
* @param componentState
|
||||
* @param theme
|
||||
*/
|
||||
protected abstract void drawCurve(CubicCurve2D curve, Graphics2D g2d,
|
||||
ComponentState componentState);
|
||||
|
||||
/**
|
||||
* @return default color.
|
||||
*/
|
||||
protected abstract Color getDefaultColor();
|
||||
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
g2d.setColor(getDefaultColor().darker());
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(3));
|
||||
CubicCurve2D curve = new CubicCurve2D.Double(1, height - 1, width / 4, height / 3,
|
||||
3 * width / 4, 2 * height / 3, width - 1, 1);
|
||||
g2d.draw(curve);
|
||||
g2d.setColor(getDefaultColor());
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
g2d.draw(curve);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
|
||||
Project project, IDrawingObserver drawingObserver) {
|
||||
if (checkPointsClipped(g2d.getClip())) {
|
||||
return;
|
||||
}
|
||||
if (componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING) {
|
||||
// Do not track guidelines.
|
||||
drawingObserver.stopTracking();
|
||||
g2d.setStroke(Constants.DASHED_STROKE);
|
||||
g2d.setColor(GUIDELINE_COLOR);
|
||||
g2d.drawLine(controlPoints[0].x, controlPoints[0].y, controlPoints[1].x,
|
||||
controlPoints[1].y);
|
||||
g2d.drawLine(controlPoints[1].x, controlPoints[1].y, controlPoints[2].x,
|
||||
controlPoints[2].y);
|
||||
g2d.drawLine(controlPoints[2].x, controlPoints[2].y, controlPoints[3].x,
|
||||
controlPoints[3].y);
|
||||
drawingObserver.startTracking();
|
||||
}
|
||||
CubicCurve2D curve = new CubicCurve2D.Double(controlPoints[0].x, controlPoints[0].y,
|
||||
controlPoints[1].x, controlPoints[1].y, controlPoints[2].x, controlPoints[2].y,
|
||||
controlPoints[3].x, controlPoints[3].y);
|
||||
|
||||
Composite oldComposite = g2d.getComposite();
|
||||
if (alpha < MAX_ALPHA) {
|
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha
|
||||
/ MAX_ALPHA));
|
||||
}
|
||||
// g2d.setColor(color.darker());
|
||||
// g2d.setStroke(new BasicStroke(thickness));
|
||||
// g2d.draw(path);
|
||||
// g2d.setColor(color);
|
||||
// g2d.setStroke(new BasicStroke(thickness - 2));
|
||||
// g2d.draw(path);
|
||||
drawCurve(curve, g2d, componentState);
|
||||
g2d.setComposite(oldComposite);
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Point Count")
|
||||
public PointCount getPointCount() {
|
||||
if (pointCount == null) {
|
||||
pointCount = PointCount.FOUR;
|
||||
}
|
||||
return pointCount;
|
||||
}
|
||||
|
||||
public void setPointCount(PointCount pointCount) {
|
||||
this.pointCount = pointCount;
|
||||
// Reset control points.
|
||||
for (int i = 0; i < getControlPointCount(); i++) {
|
||||
setControlPoint(getControlPoint(i), i);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getControlPointCount() {
|
||||
switch (getPointCount()) {
|
||||
case TWO:
|
||||
return 2;
|
||||
case THREE:
|
||||
return 3;
|
||||
case FOUR:
|
||||
return 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isControlPointSticky(int index) {
|
||||
return index == 0 || index == getControlPointCount() - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
|
||||
return VisibilityPolicy.WHEN_SELECTED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canControlPointOverlap(int index) {
|
||||
// Only shape control points may overlap.
|
||||
switch (getPointCount()) {
|
||||
case TWO:
|
||||
return false;
|
||||
case THREE:
|
||||
return index == 1;
|
||||
case FOUR:
|
||||
return index == 1 || index == 2;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getControlPoint(int index) {
|
||||
if (index == 0) {
|
||||
return controlPoints[0];
|
||||
}
|
||||
switch (getPointCount()) {
|
||||
case TWO:
|
||||
switch (index) {
|
||||
case 1:
|
||||
return controlPoints[3];
|
||||
}
|
||||
case THREE:
|
||||
switch (index) {
|
||||
case 1:
|
||||
return controlPoints[1];
|
||||
case 2:
|
||||
return controlPoints[3];
|
||||
}
|
||||
case FOUR:
|
||||
switch (index) {
|
||||
case 1:
|
||||
return controlPoints[1];
|
||||
case 2:
|
||||
return controlPoints[2];
|
||||
case 3:
|
||||
return controlPoints[3];
|
||||
}
|
||||
}
|
||||
return controlPoints[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlPoint(Point point, int index) {
|
||||
if (index == 0) {
|
||||
controlPoints[0].setLocation(point);
|
||||
} else {
|
||||
switch (getPointCount()) {
|
||||
case TWO:
|
||||
switch (index) {
|
||||
case 1:
|
||||
Point center = new Point((point.x + controlPoints[0].x) / 2,
|
||||
(point.y + controlPoints[0].y) / 2);
|
||||
controlPoints[1].setLocation(center);
|
||||
controlPoints[2].setLocation(center);
|
||||
controlPoints[3].setLocation(point);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case THREE:
|
||||
switch (index) {
|
||||
case 1:
|
||||
controlPoints[1].setLocation(point);
|
||||
controlPoints[2].setLocation(point);
|
||||
break;
|
||||
case 2:
|
||||
controlPoints[3].setLocation(point);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FOUR:
|
||||
switch (index) {
|
||||
case 1:
|
||||
controlPoints[1].setLocation(point);
|
||||
break;
|
||||
case 2:
|
||||
controlPoints[2].setLocation(point);
|
||||
break;
|
||||
case 3:
|
||||
controlPoints[3].setLocation(point);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
enum PointCount {
|
||||
TWO, THREE, FOUR;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().substring(0, 1) + name().substring(1).toLowerCase();
|
||||
}
|
||||
}
|
||||
}
|
||||
-336
@@ -1,336 +0,0 @@
|
||||
package org.diylc.components;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
import org.diylc.common.Display;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.Theme;
|
||||
import org.diylc.core.VisibilityPolicy;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
import com.diyfever.gui.miscutils.ConfigurationManager;
|
||||
|
||||
/**
|
||||
* Base class for all leaded components such as resistors or capacitors. Has two
|
||||
* control points and draws leads between them. Also, it positions and draws the
|
||||
* shape of the component as specified by a child class.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComponent<T> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static Color LEAD_COLOR = Color.decode("#236B8E");
|
||||
public static Size LEAD_THICKNESS = new Size(0.6d, SizeUnit.mm);
|
||||
public static Size DEFAULT_SIZE = new Size(1d, SizeUnit.in);
|
||||
|
||||
protected Size length;
|
||||
protected Size width;
|
||||
protected Point[] points = new Point[] {
|
||||
new Point((int) (-DEFAULT_SIZE.convertToPixels() / 2), 0),
|
||||
new Point((int) (DEFAULT_SIZE.convertToPixels() / 2), 0) };
|
||||
protected Color bodyColor = Color.white;
|
||||
protected Color borderColor = Color.black;
|
||||
protected Color labelColor = LABEL_COLOR;
|
||||
protected Display display = Display.VALUE;
|
||||
|
||||
protected AbstractLeadedComponent() {
|
||||
super();
|
||||
try {
|
||||
this.length = getDefaultLength().clone();
|
||||
this.width = getDefaultWidth().clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
// This should never happen because Size supports cloning.
|
||||
} catch (NullPointerException e) {
|
||||
// This will happen if components do not have any shape.
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
|
||||
Project project, IDrawingObserver drawingObserver) {
|
||||
double distance = points[0].distance(points[1]);
|
||||
Shape shape = getBodyShape();
|
||||
// If there's no body, just draw the line connecting the ending points.
|
||||
if (shape == null) {
|
||||
drawLead(g2d, componentState);
|
||||
} else if (supportsStandingMode()
|
||||
&& length.convertToPixels() > points[0].distance(points[1])) {
|
||||
// When ending points are too close draw the component in standing
|
||||
// mode.
|
||||
int width = getClosestOdd(this.width.convertToPixels());
|
||||
Shape body = new Ellipse2D.Double(points[0].x - width / 2, points[0].y - width / 2,
|
||||
width, width);
|
||||
Composite oldComposite = g2d.getComposite();
|
||||
if (alpha < MAX_ALPHA) {
|
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha
|
||||
/ MAX_ALPHA));
|
||||
}
|
||||
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : bodyColor);
|
||||
g2d.fill(body);
|
||||
g2d.setComposite(oldComposite);
|
||||
Color finalBorderColor;
|
||||
if (outlineMode) {
|
||||
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
|
||||
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
||||
finalBorderColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : theme
|
||||
.getOutlineColor();
|
||||
} else {
|
||||
finalBorderColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR
|
||||
: borderColor;
|
||||
}
|
||||
|
||||
g2d.setColor(finalBorderColor);
|
||||
g2d.draw(body);
|
||||
if (!outlineMode) {
|
||||
drawLead(g2d, componentState);
|
||||
}
|
||||
} else {
|
||||
// Normal mode with component body in the center and two lead parts.
|
||||
Rectangle shapeRect = shape.getBounds();
|
||||
Double theta = Math.atan2(points[1].y - points[0].y, points[1].x - points[0].x);
|
||||
// Transform graphics to draw the body in the right place and at the
|
||||
// right angle.
|
||||
AffineTransform oldTransform = g2d.getTransform();
|
||||
g2d.translate((points[0].x + points[1].x - shapeRect.width) / 2, (points[0].y
|
||||
+ points[1].y - shapeRect.height) / 2);
|
||||
g2d.rotate(theta, shapeRect.width / 2, shapeRect.height / 2);
|
||||
// Draw body.
|
||||
Composite oldComposite = g2d.getComposite();
|
||||
if (alpha < MAX_ALPHA) {
|
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha
|
||||
/ MAX_ALPHA));
|
||||
}
|
||||
if (bodyColor != null) {
|
||||
if (bodyColor != null) {
|
||||
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : bodyColor);
|
||||
g2d.fill(shape);
|
||||
}
|
||||
}
|
||||
decorateComponentBody(g2d, outlineMode);
|
||||
g2d.setComposite(oldComposite);
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
Color finalBorderColor;
|
||||
if (outlineMode) {
|
||||
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
|
||||
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
||||
finalBorderColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : theme
|
||||
.getOutlineColor();
|
||||
} else {
|
||||
finalBorderColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR
|
||||
: borderColor;
|
||||
}
|
||||
g2d.setColor(finalBorderColor);
|
||||
g2d.draw(shape);
|
||||
// Draw label.
|
||||
g2d.setFont(LABEL_FONT);
|
||||
Color finalLabelColor;
|
||||
if (outlineMode) {
|
||||
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
|
||||
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
||||
finalLabelColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED : theme
|
||||
.getOutlineColor();
|
||||
} else {
|
||||
finalLabelColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
|
||||
: labelColor;
|
||||
}
|
||||
g2d.setColor(finalLabelColor);
|
||||
FontMetrics fontMetrics = g2d.getFontMetrics();
|
||||
String label = display == Display.NAME ? getName() : getValue().toString();
|
||||
// Adjust label angle if needed to make sure that it's readable.
|
||||
if ((theta >= Math.PI / 2 && theta <= Math.PI)
|
||||
|| (theta < -Math.PI / 2 && theta > -Math.PI)) {
|
||||
g2d.rotate(Math.PI, shapeRect.width / 2, shapeRect.height / 2);
|
||||
}
|
||||
Rectangle2D textRect = fontMetrics.getStringBounds(label, g2d);
|
||||
g2d.drawString(label, (int) (shapeRect.width - textRect.getWidth()) / 2,
|
||||
calculateLabelYCoordinate(shapeRect, textRect, fontMetrics));
|
||||
|
||||
// Go back to the original transformation to draw leads.
|
||||
if (!outlineMode) {
|
||||
g2d.setTransform(oldTransform);
|
||||
int leadThickness = getClosestOdd(getLeadThickness());
|
||||
double leadLength = (distance - shapeRect.width) / 2 - leadThickness / 2;
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness));
|
||||
Color leadColor = shouldShadeLeads() ? getLeadColor(componentState).darker()
|
||||
: getLeadColor(componentState);
|
||||
g2d.setColor(leadColor);
|
||||
int endX = (int) (points[0].x + Math.cos(theta) * leadLength);
|
||||
int endY = (int) Math.round(points[0].y + Math.sin(theta) * leadLength);
|
||||
g2d.drawLine(points[0].x, points[0].y, endX, endY);
|
||||
endX = (int) (points[1].x + Math.cos(theta - Math.PI) * leadLength);
|
||||
endY = (int) Math.round(points[1].y + Math.sin(theta - Math.PI) * leadLength);
|
||||
g2d.drawLine(points[1].x, points[1].y, endX, endY);
|
||||
if (shouldShadeLeads()) {
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness - 2));
|
||||
leadColor = getLeadColor(componentState);
|
||||
g2d.setColor(leadColor);
|
||||
g2d.drawLine(points[0].x, points[0].y, (int) (points[0].x + Math.cos(theta)
|
||||
* leadLength), (int) (points[0].y + Math.sin(theta) * leadLength));
|
||||
g2d.drawLine(points[1].x, points[1].y, (int) (points[1].x + Math.cos(theta
|
||||
- Math.PI)
|
||||
* leadLength), (int) (points[1].y + Math.sin(theta - Math.PI)
|
||||
* leadLength));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void drawLead(Graphics2D g2d, ComponentState componentState) {
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(getLeadThickness()));
|
||||
Color leadColor = shouldShadeLeads() ? getLeadColor(componentState).darker()
|
||||
: getLeadColor(componentState);
|
||||
g2d.setColor(leadColor);
|
||||
g2d.drawLine(points[0].x, points[0].y, points[1].x, points[1].y);
|
||||
if (shouldShadeLeads()) {
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(getLeadThickness() - 2));
|
||||
leadColor = getLeadColor(componentState);
|
||||
g2d.setColor(leadColor);
|
||||
g2d.drawLine(points[0].x, points[0].y, points[1].x, points[1].y);
|
||||
}
|
||||
}
|
||||
|
||||
protected void decorateComponentBody(Graphics2D g2d, boolean outlineMode) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
protected int calculateLabelYCoordinate(Rectangle2D shapeRect, Rectangle2D textRect,
|
||||
FontMetrics fontMetrics) {
|
||||
return (int) (shapeRect.getHeight() - textRect.getHeight()) / 2 + fontMetrics.getAscent();
|
||||
}
|
||||
|
||||
protected boolean shouldShadeLeads() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean supportsStandingMode() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return default component length.
|
||||
*/
|
||||
protected abstract Size getDefaultLength();
|
||||
|
||||
/**
|
||||
* Returns default component width.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected abstract Size getDefaultWidth();
|
||||
|
||||
/**
|
||||
* @return shape that represents component body. Shape should not be
|
||||
* transformed and should be referenced to (0, 0).
|
||||
*/
|
||||
protected abstract Shape getBodyShape();
|
||||
|
||||
/**
|
||||
* @return default lead thickness. Override this method to change it.
|
||||
*/
|
||||
protected int getLeadThickness() {
|
||||
return (int) LEAD_THICKNESS.convertToPixels();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return default lead color. Override this method to change it.
|
||||
*/
|
||||
protected Color getLeadColor(ComponentState componentState) {
|
||||
return componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : LEAD_COLOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getControlPointCount() {
|
||||
return points.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getControlPoint(int index) {
|
||||
return (Point) points[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isControlPointSticky(int index) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
|
||||
return VisibilityPolicy.ALWAYS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlPoint(Point point, int index) {
|
||||
points[index].setLocation(point);
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Color")
|
||||
public Color getBodyColor() {
|
||||
return bodyColor;
|
||||
}
|
||||
|
||||
public void setBodyColor(Color bodyColor) {
|
||||
this.bodyColor = bodyColor;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Border")
|
||||
public Color getBorderColor() {
|
||||
return borderColor;
|
||||
}
|
||||
|
||||
public void setBorderColor(Color borderColor) {
|
||||
this.borderColor = borderColor;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Length", defaultable = true)
|
||||
public Size getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public void setLength(Size length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Width", defaultable = true)
|
||||
public Size getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(Size width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Display getDisplay() {
|
||||
return display;
|
||||
}
|
||||
|
||||
public void setDisplay(Display display) {
|
||||
this.display = display;
|
||||
}
|
||||
}
|
||||
-72
@@ -1,72 +0,0 @@
|
||||
package org.diylc.components;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
import org.diylc.common.LabelPosition;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
|
||||
public abstract class AbstractSchematicLeadedSymbol<T> extends AbstractLeadedComponent<T> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static Color COLOR = Color.blue;
|
||||
public static Color LEAD_COLOR = Color.black;
|
||||
|
||||
protected LabelPosition labelPosition = LabelPosition.ABOVE;
|
||||
|
||||
public AbstractSchematicLeadedSymbol() {
|
||||
super();
|
||||
// We don't want to fill the body, so use null.
|
||||
this.bodyColor = null;
|
||||
this.borderColor = COLOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getBodyColor() {
|
||||
return super.getBodyColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldShadeLeads() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLeadThickness() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int calculateLabelYCoordinate(Rectangle2D shapeRect, Rectangle2D textRect,
|
||||
FontMetrics fontMetrics) {
|
||||
if (labelPosition == LabelPosition.ABOVE) {
|
||||
return -1;
|
||||
} else {
|
||||
return (int) (shapeRect.getHeight() + textRect.getHeight() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Label position")
|
||||
public LabelPosition getLabelPosition() {
|
||||
return labelPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
@EditableProperty(name = "Color")
|
||||
public Color getBorderColor() {
|
||||
return super.getBorderColor();
|
||||
}
|
||||
|
||||
public void setLabelPosition(LabelPosition labelPosition) {
|
||||
this.labelPosition = labelPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Color getLeadColor(ComponentState componentState) {
|
||||
return componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : LEAD_COLOR;
|
||||
}
|
||||
}
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
package org.diylc.components;
|
||||
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
|
||||
public abstract class AbstractTransparentComponent<T> extends AbstractComponent<T> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static byte MAX_ALPHA = 127;
|
||||
|
||||
protected byte alpha = MAX_ALPHA;
|
||||
|
||||
@EditableProperty
|
||||
public Byte getAlpha() {
|
||||
return alpha;
|
||||
}
|
||||
|
||||
public void setAlpha(Byte alpha) {
|
||||
this.alpha = alpha;
|
||||
}
|
||||
}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
package org.diylc.core;
|
||||
|
||||
/**
|
||||
* Validator that allows all values.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class AllowAllValidator implements IPropertyValidator {
|
||||
|
||||
@Override
|
||||
public void validate(Object value) throws ValidationException {
|
||||
}
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
package org.diylc.core;
|
||||
|
||||
/**
|
||||
* Enumerates all possible states that a component can be in.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public enum ComponentState {
|
||||
|
||||
NORMAL, SELECTED, LOCKED, DRAGGING
|
||||
}
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
package org.diylc.core;
|
||||
|
||||
public enum CreationMethod {
|
||||
|
||||
SINGLE_CLICK, POINT_BY_POINT;
|
||||
}
|
||||
-122
@@ -1,122 +0,0 @@
|
||||
package org.diylc.core;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
|
||||
/**
|
||||
* Interface for component instance. Implementation classes of this interface
|
||||
* will be instantiated by the application when component is added to the
|
||||
* canvas. <br>
|
||||
* <br>
|
||||
* <b>Implementing classes should meet the following: </b>
|
||||
* <ul>
|
||||
* <li>Must have an empty constructor.</li>
|
||||
* <li>Class should be annotated with {@link ComponentDescriptor}.</li>
|
||||
* <li>Getters for properties editable by users should be annotated with
|
||||
* {@link EditableProperty}.</li>
|
||||
* <li>Component configuration should be stored int <code>public static</code>
|
||||
* fields so they can be set through config file.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*
|
||||
* @param <T>
|
||||
* type of component values, e.g. Resistance for resistors or String
|
||||
* for transistors.
|
||||
*/
|
||||
public interface IDIYComponent<T> extends Serializable {
|
||||
|
||||
public static final int CHASSIS = 1;
|
||||
public static final int BOARD = 2;
|
||||
public static final int TRACE = 3;
|
||||
public static final int COMPONENT = 4;
|
||||
public static final int TEXT = 5;
|
||||
|
||||
/**
|
||||
* @return component instance name.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Updates component instance name.
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
void setName(String name);
|
||||
|
||||
/**
|
||||
* @return component value.
|
||||
*/
|
||||
T getValue();
|
||||
|
||||
/**
|
||||
* Updates component value.
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
void setValue(T value);
|
||||
|
||||
/**
|
||||
* @return number of control points for this component instance. May vary
|
||||
* between two instances of the same type, e.g. DIL IC with 8 and 16
|
||||
* pins will have 8 or 16 pins although they are of the same type.
|
||||
*/
|
||||
int getControlPointCount();
|
||||
|
||||
/**
|
||||
* @param index
|
||||
* @return control point at the specified index.
|
||||
*/
|
||||
Point getControlPoint(int index);
|
||||
|
||||
/**
|
||||
* Updates the control point at the specified index.
|
||||
*
|
||||
* @param point
|
||||
* @param index
|
||||
*/
|
||||
void setControlPoint(Point point, int index);
|
||||
|
||||
/**
|
||||
* @param index
|
||||
* @return true, if the specified control point may stick to control points
|
||||
* of other components.
|
||||
*/
|
||||
boolean isControlPointSticky(int index);
|
||||
|
||||
/**
|
||||
* @param index
|
||||
* @return true, if the specified control point may overlap with other
|
||||
* control points <b>of the same component</b>. The other control
|
||||
* point must be able to overlap too.
|
||||
*/
|
||||
boolean canControlPointOverlap(int index);
|
||||
|
||||
VisibilityPolicy getControlPointVisibilityPolicy(int index);
|
||||
|
||||
/**
|
||||
* Draws the component onto the {@link Graphics2D}.
|
||||
*
|
||||
* @param g2d
|
||||
* @param componentState
|
||||
* @param outlineMode
|
||||
* @param project
|
||||
* @param drawingObserver
|
||||
*/
|
||||
void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
|
||||
IDrawingObserver drawingObserver);
|
||||
|
||||
/**
|
||||
* Draws icon representation of the component. This should not depend on
|
||||
* component state, i.e. it should be treated as a static method.
|
||||
*
|
||||
* @param g2d
|
||||
* @param width
|
||||
* @param height
|
||||
*/
|
||||
void drawIcon(Graphics2D g2d, int width, int height);
|
||||
}
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
package org.diylc.core;
|
||||
|
||||
/**
|
||||
* Interface for tracking component drawing process. Components may use it to
|
||||
* stop or restart tracking. Anything drawn while tracking is stopped will not
|
||||
* be added to the mouse hot-spot area.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public interface IDrawingObserver {
|
||||
|
||||
void stopTracking();
|
||||
|
||||
void startTracking();
|
||||
}
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
package org.diylc.core;
|
||||
|
||||
/**
|
||||
* Interface for validating property value changes.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public interface IPropertyValidator {
|
||||
|
||||
/**
|
||||
* @param value
|
||||
* @throws ValidationException
|
||||
* if validation fails. Message will contain the reason.
|
||||
*/
|
||||
void validate(Object value) throws ValidationException;
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package org.diylc.core;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
|
||||
|
||||
/**
|
||||
* Base interface for the main GUI component.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public interface IView {
|
||||
|
||||
public static final int ERROR_MESSAGE = 0;
|
||||
public static final int INFORMATION_MESSAGE = 1;
|
||||
public static final int WARNING_MESSAGE = 2;
|
||||
public static final int QUESTION_MESSAGE = 3;
|
||||
public static final int PLAIN_MESSAGE = -1;
|
||||
public static final int DEFAULT_OPTION = -1;
|
||||
public static final int YES_NO_OPTION = 0;
|
||||
public static final int YES_NO_CANCEL_OPTION = 1;
|
||||
public static final int OK_CANCEL_OPTION = 2;
|
||||
public static final int YES_OPTION = 0;
|
||||
public static final int NO_OPTION = 1;
|
||||
public static final int CANCEL_OPTION = 2;
|
||||
public static final int OK_OPTION = 0;
|
||||
|
||||
public static final String CHECK_BOX_MENU_ITEM = "org.diylc.checkBoxMenuItem";
|
||||
public static final String RADIO_BUTTON_GROUP_KEY = "org.diylc.radioButtonGroup";
|
||||
|
||||
void showMessage(String message, String title, int messageType);
|
||||
|
||||
int showConfirmDialog(String message, String title, int optionType, int messageType);
|
||||
|
||||
boolean editProperties(List<PropertyWrapper> properties, Set<PropertyWrapper> defaultedProperties);
|
||||
}
|
||||
-225
@@ -1,225 +0,0 @@
|
||||
package org.diylc.core;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.annotations.PositiveMeasureValidator;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
|
||||
import com.diyfever.gui.update.VersionNumber;
|
||||
|
||||
/**
|
||||
* Entity class that defines a project. Contains project properties and a
|
||||
* collection of components.This class is serialized to file. Some filed getters
|
||||
* are tagged with {@link EditableProperty} to enable for user to edit them.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class Project implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static String DEFAULT_TITLE = "New Project";
|
||||
public static Size DEFAULT_WIDTH = new Size(29d, SizeUnit.cm);
|
||||
public static Size DEFAULT_HEIGHT = new Size(21d, SizeUnit.cm);
|
||||
public static Size DEFAULT_GRID_SPACING = new Size(0.1d, SizeUnit.in);
|
||||
|
||||
private VersionNumber fileVersion;
|
||||
|
||||
private String title;
|
||||
private String author;
|
||||
private String description;
|
||||
private Size width;
|
||||
private Size height;
|
||||
private Size gridSpacing;
|
||||
private List<IDIYComponent<?>> components;
|
||||
private Set<Set<IDIYComponent<?>>> groups;
|
||||
private Set<Integer> lockedLayers;
|
||||
|
||||
public Project() {
|
||||
components = new ArrayList<IDIYComponent<?>>();
|
||||
groups = new HashSet<Set<IDIYComponent<?>>>();
|
||||
lockedLayers = new HashSet<Integer>();
|
||||
title = DEFAULT_TITLE;
|
||||
author = System.getProperty("user.name");
|
||||
width = DEFAULT_WIDTH;
|
||||
height = DEFAULT_HEIGHT;
|
||||
gridSpacing = DEFAULT_GRID_SPACING;
|
||||
}
|
||||
|
||||
@EditableProperty(defaultable = false)
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public void setAuthor(String author) {
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
@EditableProperty(defaultable = false)
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Size getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(Size width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Size getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(Size height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Grid spacing", validatorClass = SpacingValidator.class)
|
||||
public Size getGridSpacing() {
|
||||
return gridSpacing;
|
||||
}
|
||||
|
||||
public void setGridSpacing(Size gridSpacing) {
|
||||
this.gridSpacing = gridSpacing;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of components sorted by z-order ascending.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<IDIYComponent<?>> getComponents() {
|
||||
return components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set of grouped components.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Set<Set<IDIYComponent<?>>> getGroups() {
|
||||
return groups;
|
||||
}
|
||||
|
||||
public Set<Integer> getLockedLayers() {
|
||||
return lockedLayers;
|
||||
}
|
||||
|
||||
public VersionNumber getFileVersion() {
|
||||
return fileVersion;
|
||||
}
|
||||
|
||||
public void setFileVersion(VersionNumber fileVersion) {
|
||||
this.fileVersion = fileVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((author == null) ? 0 : author.hashCode());
|
||||
result = prime * result + ((components == null) ? 0 : components.hashCode());
|
||||
result = prime * result + ((description == null) ? 0 : description.hashCode());
|
||||
result = prime * result + ((height == null) ? 0 : height.hashCode());
|
||||
result = prime * result + ((title == null) ? 0 : title.hashCode());
|
||||
result = prime * result + ((width == null) ? 0 : width.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Project other = (Project) obj;
|
||||
if (author == null) {
|
||||
if (other.author != null)
|
||||
return false;
|
||||
} else if (!author.equals(other.author))
|
||||
return false;
|
||||
if (components == null) {
|
||||
if (other.components != null)
|
||||
return false;
|
||||
} else if (!components.equals(other.components))
|
||||
return false;
|
||||
if (description == null) {
|
||||
if (other.description != null)
|
||||
return false;
|
||||
} else if (!description.equals(other.description))
|
||||
return false;
|
||||
if (height == null) {
|
||||
if (other.height != null)
|
||||
return false;
|
||||
} else if (!height.equals(other.height))
|
||||
return false;
|
||||
if (title == null) {
|
||||
if (other.title != null)
|
||||
return false;
|
||||
} else if (!title.equals(other.title))
|
||||
return false;
|
||||
if (width == null) {
|
||||
if (other.width != null)
|
||||
return false;
|
||||
} else if (!width.equals(other.width))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public static class SpacingValidator extends PositiveMeasureValidator {
|
||||
|
||||
@Override
|
||||
public void validate(Object value) throws ValidationException {
|
||||
super.validate(value);
|
||||
Size size = (Size) value;
|
||||
if (size.compareTo(new Size(1d, SizeUnit.mm)) < 0) {
|
||||
throw new ValidationException("must be greater than 1mm");
|
||||
}
|
||||
if (size.compareTo(new Size(1d, SizeUnit.in)) > 0) {
|
||||
throw new ValidationException("must be less than 1in");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public Project clone() throws CloneNotSupportedException {
|
||||
// List<IDIYComponent> clonedComponents = new
|
||||
// ArrayList<IDIYComponent>();
|
||||
// for (IDIYComponent component : components) {
|
||||
// clonedComponents.add(component.clone());
|
||||
// }
|
||||
// Project project = new Project(title, author, description,
|
||||
// width.clone(), height.clone(), clonedComponents);
|
||||
// return project;
|
||||
// }
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
package org.diylc.core;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.Serializable;
|
||||
|
||||
public class Theme implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String name;
|
||||
private Color bgColor;
|
||||
private Color gridColor;
|
||||
private Color outlineColor;
|
||||
|
||||
public Theme(String name, Color bgColor, Color gridColor, Color outlineColor) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.bgColor = bgColor;
|
||||
this.gridColor = gridColor;
|
||||
this.outlineColor = outlineColor;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Color getBgColor() {
|
||||
return bgColor;
|
||||
}
|
||||
|
||||
public Color getGridColor() {
|
||||
return gridColor;
|
||||
}
|
||||
|
||||
public Color getOutlineColor() {
|
||||
return outlineColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((bgColor == null) ? 0 : bgColor.hashCode());
|
||||
result = prime * result + ((gridColor == null) ? 0 : gridColor.hashCode());
|
||||
result = prime * result + ((outlineColor == null) ? 0 : outlineColor.hashCode());
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Theme other = (Theme) obj;
|
||||
if (bgColor == null) {
|
||||
if (other.bgColor != null)
|
||||
return false;
|
||||
} else if (!bgColor.equals(other.bgColor))
|
||||
return false;
|
||||
if (gridColor == null) {
|
||||
if (other.gridColor != null)
|
||||
return false;
|
||||
} else if (!gridColor.equals(other.gridColor))
|
||||
return false;
|
||||
if (outlineColor == null) {
|
||||
if (other.outlineColor != null)
|
||||
return false;
|
||||
} else if (!outlineColor.equals(other.outlineColor))
|
||||
return false;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
|
||||
package org.diylc.core;
|
||||
|
||||
public class ValidationException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ValidationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
package org.diylc.core;
|
||||
|
||||
/**
|
||||
* Enumerates control point visibility policies.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public enum VisibilityPolicy {
|
||||
|
||||
/**
|
||||
* Control point should be rendered all the time.
|
||||
*/
|
||||
ALWAYS,
|
||||
/**
|
||||
* Control point should be rendered only when the component is selected.
|
||||
*/
|
||||
WHEN_SELECTED,
|
||||
/**
|
||||
* Control point should not be rendered regardless of component selection.
|
||||
*/
|
||||
NEVER;
|
||||
}
|
||||
-62
@@ -1,62 +0,0 @@
|
||||
package org.diylc.core.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import org.diylc.core.CreationMethod;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
/**
|
||||
* Annotation for {@link IDIYComponent} implementation. Describes component
|
||||
* properties.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ComponentDescriptor {
|
||||
|
||||
/**
|
||||
* @return component type name.
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* @return component type description.
|
||||
*/
|
||||
String description();
|
||||
|
||||
/**
|
||||
* @return method that should be used to create a component. If
|
||||
* <code>CreationMethod.POINT_BY_POINT</code> is used, user will
|
||||
* have to select ending points before the component is created.
|
||||
*/
|
||||
CreationMethod creationMethod() default CreationMethod.SINGLE_CLICK;
|
||||
|
||||
/**
|
||||
* @return component category, e.g. "Passive", "Semiconductors", etc.
|
||||
*/
|
||||
String category();
|
||||
|
||||
/**
|
||||
* @return component author name.
|
||||
*/
|
||||
String author();
|
||||
|
||||
/**
|
||||
* @return prefix that will be used to generate component instance names,
|
||||
* e.g. "R" for resistors or "Q" for transistors.
|
||||
*/
|
||||
String instanceNamePrefix();
|
||||
|
||||
/**
|
||||
* @return Z-order of the component.
|
||||
*/
|
||||
double zOrder();
|
||||
|
||||
/**
|
||||
* @return when false, moving one control point will cause all the others to
|
||||
* move together with it.
|
||||
*/
|
||||
boolean stretchable() default true;
|
||||
|
||||
}
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
package org.diylc.core.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import org.diylc.core.AllowAllValidator;
|
||||
import org.diylc.core.IPropertyValidator;
|
||||
|
||||
/**
|
||||
* Used to annotate editable component property. Editable property XYZ must have
|
||||
* both getter and setter named <code>getXYZ</code> and <code>setXYZ</code>
|
||||
* respectively and this annotation must be placed on the getter method.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface EditableProperty {
|
||||
|
||||
/**
|
||||
* Returns property name. If left blank property name will be extracted from
|
||||
* the getter name, e.g. getter <code>getXYZ</code> will induce property
|
||||
* name <code>XYZ</code>. <br>
|
||||
* Default value is blank.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String name() default "";
|
||||
|
||||
/**
|
||||
* If true, application may set default value for this property. <br>
|
||||
* Default value is true.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean defaultable() default true;
|
||||
|
||||
/**
|
||||
* Class of validator to use to
|
||||
* @return
|
||||
*/
|
||||
Class<? extends IPropertyValidator> validatorClass() default AllowAllValidator.class;
|
||||
}
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
package org.diylc.core.annotations;
|
||||
|
||||
import org.diylc.core.IPropertyValidator;
|
||||
import org.diylc.core.ValidationException;
|
||||
import org.diylc.core.measures.AbstractMeasure;
|
||||
|
||||
public class PositiveMeasureValidator implements IPropertyValidator {
|
||||
|
||||
@Override
|
||||
public void validate(Object value) throws ValidationException {
|
||||
if (value instanceof AbstractMeasure) {
|
||||
AbstractMeasure measure = (AbstractMeasure) value;
|
||||
if (measure.getValue() < 0) {
|
||||
throw new ValidationException("must be greater than zero.");
|
||||
}
|
||||
} else {
|
||||
throw new ValidationException("wrong data type, measure expected.");
|
||||
}
|
||||
}
|
||||
}
|
||||
-81
@@ -1,81 +0,0 @@
|
||||
package org.diylc.core.measures;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.Format;
|
||||
|
||||
public class AbstractMeasure<T extends Enum<? extends Unit>> implements Serializable, Cloneable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
protected static final Format format = new DecimalFormat("0.####");
|
||||
|
||||
protected Double value;
|
||||
protected T unit;
|
||||
|
||||
public AbstractMeasure() {
|
||||
}
|
||||
|
||||
public AbstractMeasure(Double value, T unit) {
|
||||
super();
|
||||
this.value = value;
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
public Double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Double value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public T getUnit() {
|
||||
return unit;
|
||||
}
|
||||
|
||||
public void setUnit(T multiplier) {
|
||||
this.unit = multiplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() throws CloneNotSupportedException {
|
||||
return super.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((unit == null) ? 0 : unit.hashCode());
|
||||
result = prime * result + ((value == null) ? 0 : value.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
AbstractMeasure<?> other = (AbstractMeasure<?>) obj;
|
||||
if (unit == null) {
|
||||
if (other.unit != null)
|
||||
return false;
|
||||
} else if (!unit.equals(other.unit))
|
||||
return false;
|
||||
if (value == null) {
|
||||
if (other.value != null)
|
||||
return false;
|
||||
} else if (!value.equals(other.value))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return format.format(value) + " " + unit;
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
package org.diylc.core.measures;
|
||||
|
||||
public class Capacitance extends AbstractMeasure<CapacitanceUnit> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public Capacitance() {
|
||||
super();
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public Capacitance(Double value, CapacitanceUnit unit) {
|
||||
super(value, unit);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public Capacitance clone() throws CloneNotSupportedException {
|
||||
return new Capacitance(value, unit);
|
||||
}
|
||||
|
||||
public static Capacitance parseCapacitance(String value) {
|
||||
for (CapacitanceUnit unit : CapacitanceUnit.values()) {
|
||||
if (value.toLowerCase().endsWith(unit.toString().toLowerCase())) {
|
||||
value = value.substring(0, value.length() - unit.toString().length() - 1).trim();
|
||||
return new Capacitance(Double.parseDouble(value), unit);
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Could not parse capacitance: " + value);
|
||||
}
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
package org.diylc.core.measures;
|
||||
|
||||
public enum CapacitanceUnit implements Unit {
|
||||
|
||||
pF(1, "pF"), nF(1e3, "nF"), uF(1e6, "uF"), mF(1e9, "mF"), F(1e12, "F");
|
||||
|
||||
double factor;
|
||||
String display;
|
||||
|
||||
private CapacitanceUnit(double factor, String display) {
|
||||
this.factor = factor;
|
||||
this.display = display;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getFactor() {
|
||||
return factor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return display;
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
package org.diylc.core.measures;
|
||||
|
||||
public class Inductance extends AbstractMeasure<InductanceUnit> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public Inductance() {
|
||||
super();
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public Inductance(Double value, InductanceUnit unit) {
|
||||
super(value, unit);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public Inductance clone() throws CloneNotSupportedException {
|
||||
return new Inductance(value, unit);
|
||||
}
|
||||
|
||||
public static Inductance parseCapacitance(String value) {
|
||||
for (InductanceUnit unit : InductanceUnit.values()) {
|
||||
if (value.toLowerCase().endsWith(unit.toString().toLowerCase())) {
|
||||
value = value.substring(0, value.length() - unit.toString().length() - 1).trim();
|
||||
return new Inductance(Double.parseDouble(value), unit);
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Could not parse inductance: " + value);
|
||||
}
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
package org.diylc.core.measures;
|
||||
|
||||
public enum InductanceUnit implements Unit {
|
||||
|
||||
pH(1, "pH"), nH(1e3, "nH"), uH(1e6, "\u03bcH"), mH(1e9, "mH"), H(1e12, "H");
|
||||
|
||||
double factor;
|
||||
String display;
|
||||
|
||||
private InductanceUnit(double factor, String display) {
|
||||
this.factor = factor;
|
||||
this.display = display;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getFactor() {
|
||||
return factor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return display;
|
||||
}
|
||||
}
|
||||
-78
@@ -1,78 +0,0 @@
|
||||
package org.diylc.core.measures;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import org.diylc.common.ResistorColorCode;
|
||||
|
||||
public class Resistance extends AbstractMeasure<ResistanceUnit> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final Color[] COLOR_DIGITS = new Color[] { Color.black, Color.decode("#8B4513"),
|
||||
Color.red, Color.orange, Color.yellow, Color.decode("#76EE00"), Color.blue,
|
||||
Color.decode("#91219E"), Color.lightGray, Color.white };
|
||||
private static final Color[] COLOR_MULTIPLIER = new Color[] { Color.lightGray.brighter(),
|
||||
Color.decode("#FFB90F"), Color.black, Color.decode("#8B4513"), Color.red, Color.orange,
|
||||
Color.yellow, Color.decode("#76EE00"), Color.blue };
|
||||
|
||||
public Resistance() {
|
||||
super();
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public Resistance(Double value, ResistanceUnit multiplier) {
|
||||
super(value, multiplier);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resistance clone() throws CloneNotSupportedException {
|
||||
return new Resistance(value, unit);
|
||||
}
|
||||
|
||||
public Color[] getColorCode(ResistorColorCode resistorColorCode) {
|
||||
Color[] bands;
|
||||
double base = getValue() * getUnit().getFactor();
|
||||
int multiplier = 0;
|
||||
while (base > (resistorColorCode == ResistorColorCode._4_BAND ? 99 : 999)) {
|
||||
multiplier += 1;
|
||||
base /= 10;
|
||||
}
|
||||
while (base < (resistorColorCode == ResistorColorCode._4_BAND ? 10 : 100)) {
|
||||
multiplier -= 1;
|
||||
base *= 10;
|
||||
}
|
||||
if (multiplier > 6 || multiplier < -2) {
|
||||
// Out of range.
|
||||
return new Color[] {};
|
||||
}
|
||||
switch (resistorColorCode) {
|
||||
case _4_BAND:
|
||||
bands = new Color[3];
|
||||
bands[0] = COLOR_DIGITS[(int) (base / 10)];
|
||||
bands[1] = COLOR_DIGITS[(int) (base % 10)];
|
||||
bands[2] = COLOR_MULTIPLIER[multiplier + 2];
|
||||
break;
|
||||
case _5_BAND:
|
||||
bands = new Color[4];
|
||||
bands[0] = COLOR_DIGITS[(int) (base / 100)];
|
||||
bands[1] = COLOR_DIGITS[(int) (base / 10 % 10)];
|
||||
bands[2] = COLOR_DIGITS[(int) (base % 10)];
|
||||
bands[3] = COLOR_MULTIPLIER[multiplier + 2];
|
||||
break;
|
||||
default:
|
||||
bands = new Color[] {};
|
||||
}
|
||||
return bands;
|
||||
}
|
||||
|
||||
public static Resistance parseResistance(String value) {
|
||||
for (ResistanceUnit unit : ResistanceUnit.values()) {
|
||||
if (value.toLowerCase().endsWith(unit.toString().toLowerCase())) {
|
||||
value = value.substring(0, value.length() - unit.toString().length() - 1).trim();
|
||||
return new Resistance(Double.parseDouble(value), unit);
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Could not parse resistance: " + value);
|
||||
}
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
package org.diylc.core.measures;
|
||||
|
||||
public enum ResistanceUnit implements Unit {
|
||||
|
||||
R(1, "\u03a9"), K(1e3, "K"), M(1e6, "M");
|
||||
|
||||
double factor;
|
||||
String display;
|
||||
|
||||
private ResistanceUnit(double factor, String display) {
|
||||
this.factor = factor;
|
||||
this.display = display;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getFactor() {
|
||||
return factor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return display;
|
||||
}
|
||||
}
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
package org.diylc.core.measures;
|
||||
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
public class Size extends AbstractMeasure<SizeUnit> implements Comparable<Size> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public Size() {
|
||||
super();
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public Size(Double value, SizeUnit unit) {
|
||||
super(value, unit);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public double convertToPixels() {
|
||||
// double factor = getUnit().getFactor() / SizeUnit.in.getFactor();
|
||||
// int grids = (int) (factor * getValue() * Constants.GRIDS_PER_INCH);
|
||||
// double remainder = (factor * getValue() * Constants.GRIDS_PER_INCH) - grids;
|
||||
// return (int) Math.round(Constants.PIXELS_PER_INCH / Constants.GRIDS_PER_INCH
|
||||
// * (grids + remainder));
|
||||
return getValue() * getUnit().getFactor() / SizeUnit.in.getFactor() * Constants.PIXELS_PER_INCH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Size clone() throws CloneNotSupportedException {
|
||||
return new Size(value, unit);
|
||||
}
|
||||
|
||||
public static Size parseSize(String value) {
|
||||
for (SizeUnit unit : SizeUnit.values()) {
|
||||
if (value.toLowerCase().endsWith(unit.toString().toLowerCase())) {
|
||||
value = value.substring(0, value.length() - unit.toString().length() - 1).trim();
|
||||
return new Size(Double.parseDouble(value), unit);
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Could not parse size: " + value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Size o) {
|
||||
return new Double(value * unit.getFactor()).compareTo(o.getValue() * o.getUnit().getFactor());
|
||||
}
|
||||
}
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
package org.diylc.core.measures;
|
||||
|
||||
public enum SizeUnit implements Unit {
|
||||
|
||||
mm(1d), cm(10d), m(1e4d), in(25.4d), ft(25.4d * 12), yd(9144d);
|
||||
|
||||
double factor;
|
||||
|
||||
private SizeUnit(double factor) {
|
||||
this.factor = factor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getFactor() {
|
||||
return factor;
|
||||
}
|
||||
}
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
package org.diylc.core.measures;
|
||||
|
||||
public interface Unit {
|
||||
|
||||
double getFactor();
|
||||
}
|
||||
-61
@@ -1,61 +0,0 @@
|
||||
package org.diylc.images;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
|
||||
/**
|
||||
* Loads image resources as Icons.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public enum IconLoader {
|
||||
|
||||
Delete("delete.png"), Add("add.png"), FolderOut("folder_out.png"), Garbage("garbage.png"), DiskBlue(
|
||||
"disk_blue.png"), SaveAs("save_as.png"), Exit("exit.png"), DocumentPlainYellow(
|
||||
"document_plain_yellow.png"), PhotoScenery("photo_scenery.png"), LightBulbOn(
|
||||
"lightbulb_on.png"), LightBulbOff("lightbulb_off.png"), NotebookAdd("notebook_add.png"), FormGreen(
|
||||
"form_green.png"), Gears("gears.png"), About("about.png"), WindowColors(
|
||||
"window_colors.png"), WindowGear("window_gear.png"), NavigateCheck("navigate_check.png"), Undo(
|
||||
"undo.png"), Error("error.png"), Warning("warning.png"), ZoomSmall("zoom_small.png"), MoveSmall(
|
||||
"move_small.png"), Print("print.png"), PDF("pdf.png"), Excel("excel.png"), CSV(
|
||||
"csv.png"), HTML("html.png"), Image("image.png"), Cut("cut.png"), Copy("copy.png"), Paste(
|
||||
"paste.png"), Selection("selection.png"), BOM("bom.png"), BlackBoard("blackboard.png"), IdCard(
|
||||
"id_card.png"), IdCardAdd("id_card_add.png"), Chest("chest.png"), Upload("upload.png"), Wrench(
|
||||
"wrench.png"), Group("group.png"), Ungroup("ungroup.png"), TraceMask("trace_mask.png"), Faq(
|
||||
"faq.png"), Component("component.png"), Plugin("plugin.png"), Manual("manual.png"), Donate(
|
||||
"donate.png"), Bug("bug.png"), IconLarge("icon_large.png"), IconMedium(
|
||||
"icon_medium.png"), IconSmall("icon_small.png"), DocumentEdit("document_edit.png"), EditComponent(
|
||||
"edit_component.png"), Size("size.png"), Front("front.png"), Back("back.png"), Pens(
|
||||
"pens.png"), Sort("sort.png");
|
||||
|
||||
protected String name;
|
||||
|
||||
private IconLoader(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Icon getIcon() {
|
||||
java.net.URL imgURL = getClass().getResource(name);
|
||||
if (imgURL != null) {
|
||||
return new ImageIcon(imgURL, name);
|
||||
} else {
|
||||
System.err.println("Couldn't find file: " + name);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Image getImage() {
|
||||
BufferedImage img = null;
|
||||
try {
|
||||
img = ImageIO.read(getClass().getResourceAsStream(name));
|
||||
} catch (IOException e) {
|
||||
System.err.println("Couldn't find file: " + name);
|
||||
}
|
||||
return img;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
log4j.rootLogger = DEBUG, fileout, stdout
|
||||
log4j.appender.fileout = com.diyfever.gui.miscutils.NewLogForEachRunFileAppender
|
||||
log4j.appender.fileout.layout.ConversionPattern = %d{ABSOLUTE} %5p [%t] %c{1} - %m%n
|
||||
log4j.appender.fileout.layout = org.apache.log4j.PatternLayout
|
||||
log4j.appender.fileout.File = log/log.log
|
||||
|
||||
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout.ConversionPattern = %d{ABSOLUTE} %5p [%t] %c{1} - %m%n
|
||||
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
package org.diylc.presenter;
|
||||
|
||||
import java.awt.Point;
|
||||
|
||||
import org.diylc.core.measures.Size;
|
||||
|
||||
public class CalcUtils {
|
||||
|
||||
/**
|
||||
* Rounds the number to the closest grid line.
|
||||
*
|
||||
* @param x
|
||||
* @return
|
||||
*/
|
||||
public static int roundToGrid(int x, Size gridSpacing) {
|
||||
double grid = gridSpacing.convertToPixels();
|
||||
return (int) (Math.round(1f * x / grid) * grid);
|
||||
}
|
||||
|
||||
public static void snapPointToGrid(Point point, Size gridSpacing) {
|
||||
int x = roundToGrid(point.x, gridSpacing);
|
||||
int y = roundToGrid(point.y, gridSpacing);
|
||||
point.setLocation(x, y);
|
||||
}
|
||||
}
|
||||
-88
@@ -1,88 +0,0 @@
|
||||
package org.diylc.presenter;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.diylc.common.ComponentType;
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
public class ComparatorFactory {
|
||||
|
||||
private static ComparatorFactory instance;
|
||||
|
||||
private Comparator<IDIYComponent<?>> componentNameComparator;
|
||||
private Comparator<ComponentType> componentTypeComparator;
|
||||
private Comparator<PropertyWrapper> propertyNameComparator;
|
||||
private Comparator<IDIYComponent<?>> componentZOrderComparator;
|
||||
|
||||
public static ComparatorFactory getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new ComparatorFactory();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public Comparator<IDIYComponent<?>> getComponentNameComparator() {
|
||||
if (componentNameComparator == null) {
|
||||
componentNameComparator = new Comparator<IDIYComponent<?>>() {
|
||||
|
||||
@Override
|
||||
public int compare(IDIYComponent<?> o1, IDIYComponent<?> o2) {
|
||||
String name1 = o1.getName();
|
||||
String name2 = o2.getName();
|
||||
if (name1 == null || name2 == null) {
|
||||
return 0;
|
||||
}
|
||||
return name1.compareToIgnoreCase(name2);
|
||||
}
|
||||
};
|
||||
}
|
||||
return componentNameComparator;
|
||||
}
|
||||
|
||||
public Comparator<ComponentType> getComponentTypeComparator() {
|
||||
if (componentTypeComparator == null) {
|
||||
componentTypeComparator = new Comparator<ComponentType>() {
|
||||
|
||||
@Override
|
||||
public int compare(ComponentType o1, ComponentType o2) {
|
||||
return o1.getName().compareToIgnoreCase(o2.getName());
|
||||
}
|
||||
};
|
||||
}
|
||||
return componentTypeComparator;
|
||||
}
|
||||
|
||||
public Comparator<PropertyWrapper> getPropertyNameComparator() {
|
||||
if (propertyNameComparator == null) {
|
||||
propertyNameComparator = new Comparator<PropertyWrapper>() {
|
||||
|
||||
@Override
|
||||
public int compare(PropertyWrapper o1, PropertyWrapper o2) {
|
||||
return o1.getName().compareToIgnoreCase(o2.getName());
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
return propertyNameComparator;
|
||||
}
|
||||
|
||||
public Comparator<IDIYComponent<?>> getComponentZOrderComparator() {
|
||||
if (componentZOrderComparator == null) {
|
||||
componentZOrderComparator = new Comparator<IDIYComponent<?>>() {
|
||||
|
||||
@Override
|
||||
public int compare(IDIYComponent<?> o1, IDIYComponent<?> o2) {
|
||||
ComponentType type1 = ComponentProcessor.getInstance()
|
||||
.extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) o1.getClass());
|
||||
ComponentType type2 = ComponentProcessor.getInstance()
|
||||
.extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) o2.getClass());
|
||||
return new Double(type1.getZOrder()).compareTo(type2.getZOrder());
|
||||
}
|
||||
};
|
||||
}
|
||||
return componentZOrderComparator;
|
||||
}
|
||||
}
|
||||
-225
@@ -1,225 +0,0 @@
|
||||
package org.diylc.presenter;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.common.ComponentType;
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.core.CreationMethod;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.IPropertyValidator;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
|
||||
import com.rits.cloning.Cloner;
|
||||
|
||||
/**
|
||||
* Utility class with component processing methods.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class ComponentProcessor {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(ComponentProcessor.class);
|
||||
|
||||
private static ComponentProcessor instance;
|
||||
|
||||
private Map<String, List<PropertyWrapper>> propertyCache;
|
||||
private Map<String, IPropertyValidator> propertyValidatorCache;
|
||||
private Map<String, ComponentType> componentTypeMap;
|
||||
|
||||
private Cloner cloner;
|
||||
|
||||
public static ComponentProcessor getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new ComponentProcessor();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private ComponentProcessor() {
|
||||
super();
|
||||
this.cloner = new Cloner();
|
||||
this.propertyCache = new HashMap<String, List<PropertyWrapper>>();
|
||||
this.componentTypeMap = new HashMap<String, ComponentType>();
|
||||
this.propertyValidatorCache = new HashMap<String, IPropertyValidator>();
|
||||
}
|
||||
|
||||
public ComponentType extractComponentTypeFrom(Class<? extends IDIYComponent<?>> clazz) {
|
||||
if (componentTypeMap.containsKey(clazz.getName())) {
|
||||
return componentTypeMap.get(clazz.getName());
|
||||
}
|
||||
String name;
|
||||
String description;
|
||||
CreationMethod creationMethod;
|
||||
String category;
|
||||
String namePrefix;
|
||||
String author;
|
||||
Icon icon;
|
||||
double zOrder;
|
||||
boolean stretchable;
|
||||
if (clazz.isAnnotationPresent(ComponentDescriptor.class)) {
|
||||
ComponentDescriptor annotation = clazz.getAnnotation(ComponentDescriptor.class);
|
||||
name = annotation.name();
|
||||
description = annotation.description();
|
||||
creationMethod = annotation.creationMethod();
|
||||
category = annotation.category();
|
||||
namePrefix = annotation.instanceNamePrefix();
|
||||
author = annotation.author();
|
||||
zOrder = annotation.zOrder();
|
||||
stretchable = annotation.stretchable();
|
||||
} else {
|
||||
name = clazz.getSimpleName();
|
||||
description = "";
|
||||
creationMethod = CreationMethod.SINGLE_CLICK;
|
||||
category = "Uncategorized";
|
||||
namePrefix = "Unknown";
|
||||
author = "Unknown";
|
||||
zOrder = IDIYComponent.COMPONENT;
|
||||
stretchable = true;
|
||||
}
|
||||
icon = null;
|
||||
// Draw component icon.
|
||||
try {
|
||||
IDIYComponent<?> componentInstance = (IDIYComponent<?>) clazz.newInstance();
|
||||
Image image = new BufferedImage(Presenter.ICON_SIZE, Presenter.ICON_SIZE,
|
||||
java.awt.image.BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g2d = (Graphics2D) image.getGraphics();
|
||||
g2d
|
||||
.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
||||
RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
componentInstance.drawIcon(g2d, Presenter.ICON_SIZE, Presenter.ICON_SIZE);
|
||||
icon = new ImageIcon(image);
|
||||
} catch (InstantiationException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
ComponentType componentType = new ComponentType(name, description, creationMethod,
|
||||
category, namePrefix, author, icon, clazz, zOrder, stretchable);
|
||||
componentTypeMap.put(clazz.getName(), componentType);
|
||||
return componentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts all editable properties from the component class.
|
||||
*
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public List<PropertyWrapper> extractProperties(Class<?> clazz) {
|
||||
if (propertyCache.containsKey(clazz.getName())) {
|
||||
return cloner.deepClone(propertyCache.get(clazz.getName()));
|
||||
}
|
||||
List<PropertyWrapper> properties = new ArrayList<PropertyWrapper>();
|
||||
for (Method method : clazz.getMethods()) {
|
||||
if (method.getName().startsWith("get")) {
|
||||
try {
|
||||
if (method.isAnnotationPresent(EditableProperty.class)
|
||||
&& !method.isAnnotationPresent(Deprecated.class)) {
|
||||
EditableProperty annotation = method.getAnnotation(EditableProperty.class);
|
||||
String name;
|
||||
if (annotation.name().equals("")) {
|
||||
name = method.getName().substring(3);
|
||||
} else {
|
||||
name = annotation.name();
|
||||
}
|
||||
IPropertyValidator validator = getPropertyValidator(annotation
|
||||
.validatorClass());
|
||||
Method setter = clazz.getMethod("set" + method.getName().substring(3),
|
||||
method.getReturnType());
|
||||
PropertyWrapper property = new PropertyWrapper(name,
|
||||
method.getReturnType(), method.getName(), setter.getName(),
|
||||
annotation.defaultable(), validator);
|
||||
properties.add(property);
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
LOG.debug("No matching setter found for \"" + method.getName()
|
||||
+ "\". Skipping...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
propertyCache.put(clazz.getName(), properties);
|
||||
return cloner.deepClone(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns properties that have the same value for all the selected
|
||||
* components.
|
||||
*
|
||||
* @param selectedComponents
|
||||
* @return
|
||||
*/
|
||||
public List<PropertyWrapper> getMutualSelectionProperties(
|
||||
List<IDIYComponent<?>> selectedComponents) throws Exception {
|
||||
if (selectedComponents.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
List<PropertyWrapper> properties = new ArrayList<PropertyWrapper>();
|
||||
IDIYComponent<?> firstComponent = selectedComponents.get(0);
|
||||
properties.addAll(extractProperties(firstComponent.getClass()));
|
||||
// Initialize values
|
||||
for (PropertyWrapper property : properties) {
|
||||
property.readFrom(firstComponent);
|
||||
}
|
||||
for (int i = 1; i < selectedComponents.size(); i++) {
|
||||
IDIYComponent<?> component = selectedComponents.get(i);
|
||||
List<PropertyWrapper> newProperties = extractProperties(component.getClass());
|
||||
for (PropertyWrapper property : newProperties) {
|
||||
property.readFrom(component);
|
||||
}
|
||||
properties.retainAll(newProperties);
|
||||
// Try to find matching properties in old and new lists and see if
|
||||
// their values match.
|
||||
for (PropertyWrapper oldProperty : properties) {
|
||||
if (newProperties.contains(oldProperty)) {
|
||||
PropertyWrapper newProperty = newProperties.get(newProperties
|
||||
.indexOf(oldProperty));
|
||||
if ((newProperty.getValue() != null && newProperty.getValue() == null)
|
||||
|| !newProperty.getValue().equals(oldProperty.getValue())) {
|
||||
// Values don't match, so the property is not unique valued.
|
||||
oldProperty.setUnique(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
// for (PropertyWrapper property : properties) {
|
||||
// try {
|
||||
// property.readUniqueFrom(component);
|
||||
// } catch (Exception e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
Collections.sort(properties, ComparatorFactory.getInstance().getPropertyNameComparator());
|
||||
return properties;
|
||||
}
|
||||
|
||||
private IPropertyValidator getPropertyValidator(Class<? extends IPropertyValidator> clazz) {
|
||||
if (propertyValidatorCache.containsKey(clazz.getName())) {
|
||||
return propertyValidatorCache.get(clazz.getName());
|
||||
}
|
||||
IPropertyValidator validator;
|
||||
try {
|
||||
validator = clazz.newInstance();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Could not instantiate validator for " + clazz.getName(), e);
|
||||
return null;
|
||||
}
|
||||
propertyValidatorCache.put(clazz.getName(), validator);
|
||||
return validator;
|
||||
}
|
||||
}
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
package org.diylc.presenter;
|
||||
|
||||
import org.diylc.common.ComponentType;
|
||||
import org.diylc.common.IComponentFiler;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
public class ComponentZOrderFiler implements IComponentFiler {
|
||||
|
||||
private int zOrder;
|
||||
|
||||
public ComponentZOrderFiler(int zOrder) {
|
||||
super();
|
||||
this.zOrder = zOrder;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public boolean testComponent(IDIYComponent<?> component) {
|
||||
ComponentType componentType = ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) component.getClass());
|
||||
return Math.round(componentType.getZOrder()) == zOrder;
|
||||
}
|
||||
}
|
||||
-396
@@ -1,396 +0,0 @@
|
||||
package org.diylc.presenter;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Area;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.common.DrawOption;
|
||||
import org.diylc.common.EventType;
|
||||
import org.diylc.common.GridType;
|
||||
import org.diylc.common.IComponentFiler;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.Theme;
|
||||
import org.diylc.core.VisibilityPolicy;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
import com.diyfever.gui.miscutils.ConfigurationManager;
|
||||
import com.diyfever.gui.simplemq.MessageDispatcher;
|
||||
|
||||
/**
|
||||
* Utility that deals with painting {@link Project} on the {@link Graphics2D}
|
||||
* and keeps areas taken by each drawn component.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class DrawingManager {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(DrawingManager.class);
|
||||
|
||||
public static int CONTROL_POINT_SIZE = 7;
|
||||
|
||||
public static final String ZOOM_KEY = "zoom";
|
||||
|
||||
public static String DEBUG_COMPONENT_AREAS = "org.diylc.debugComponentAreas";
|
||||
|
||||
public static Color CONTROL_POINT_COLOR = Color.blue;
|
||||
public static Color SELECTED_CONTROL_POINT_COLOR = Color.green;
|
||||
|
||||
private Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
|
||||
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
||||
|
||||
// Keeps Area object of each drawn component.
|
||||
private Map<IDIYComponent<?>, Area> componentAreaMap;
|
||||
// Maps components to the last state they are drawn in. Also, used to
|
||||
// determine which components are invalidated when they are not in the map.
|
||||
private Map<IDIYComponent<?>, ComponentState> lastDrawnStateMap;
|
||||
|
||||
private Composite slotComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f);
|
||||
private Composite lockedComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f);
|
||||
private List<IDIYComponent<?>> failedComponents = new ArrayList<IDIYComponent<?>>();
|
||||
|
||||
private double zoomLevel = 1d;// ConfigurationManager.getInstance().readDouble(ZOOM_KEY,
|
||||
// 1d);
|
||||
|
||||
private MessageDispatcher<EventType> messageDispatcher;
|
||||
|
||||
private boolean debugComponentAreas;
|
||||
|
||||
public DrawingManager(MessageDispatcher<EventType> messageDispatcher) {
|
||||
super();
|
||||
this.messageDispatcher = messageDispatcher;
|
||||
componentAreaMap = new HashMap<IDIYComponent<?>, Area>();
|
||||
lastDrawnStateMap = new HashMap<IDIYComponent<?>, ComponentState>();
|
||||
String debugComponentAreasStr = System.getProperty(DEBUG_COMPONENT_AREAS);
|
||||
debugComponentAreas = debugComponentAreasStr != null
|
||||
&& debugComponentAreasStr.equalsIgnoreCase("true");
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the project onto the canvas and returns the list of components
|
||||
* that failed to draw.
|
||||
*
|
||||
* @param g2d
|
||||
* @param project
|
||||
* @param drawOptions
|
||||
* @param filter
|
||||
* @param selectionRect
|
||||
* @param selectedComponents
|
||||
* @param lockedComponents
|
||||
* @param groupedComponents
|
||||
* @param controlPointSlot
|
||||
* @param componentSlot
|
||||
* @param dragInProgress
|
||||
* @return
|
||||
*/
|
||||
public List<IDIYComponent<?>> drawProject(Graphics2D g2d, Project project,
|
||||
Set<DrawOption> drawOptions, IComponentFiler filter, Rectangle selectionRect,
|
||||
List<IDIYComponent<?>> selectedComponents, Set<IDIYComponent<?>> lockedComponents,
|
||||
Set<IDIYComponent<?>> groupedComponents, List<Point> controlPointSlot,
|
||||
IDIYComponent<?> componentSlot, boolean dragInProgress) {
|
||||
failedComponents.clear();
|
||||
if (project == null) {
|
||||
return failedComponents;
|
||||
}
|
||||
G2DWrapper g2dWrapper = new G2DWrapper(g2d);
|
||||
|
||||
if (drawOptions.contains(DrawOption.ANTIALIASING)) {
|
||||
g2d
|
||||
.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
||||
RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
||||
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
} else {
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
||||
RenderingHints.VALUE_ANTIALIAS_OFF);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
||||
RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
|
||||
}
|
||||
if (ConfigurationManager.getInstance()
|
||||
.readBoolean(IPlugInPort.HI_QUALITY_RENDER_KEY, false)) {
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
|
||||
RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
|
||||
RenderingHints.VALUE_COLOR_RENDER_QUALITY);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
|
||||
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||
} else {
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
|
||||
RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
|
||||
RenderingHints.VALUE_COLOR_RENDER_SPEED);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
|
||||
RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
|
||||
}
|
||||
|
||||
double zoom = 1d;
|
||||
if (drawOptions.contains(DrawOption.ZOOM)) {
|
||||
zoom = zoomLevel;
|
||||
} else {
|
||||
zoom = 1 / Constants.PIXEL_SIZE;
|
||||
}
|
||||
|
||||
// AffineTransform initialTx = g2d.getTransform();
|
||||
Dimension d = getCanvasDimensions(project, zoom, true);
|
||||
|
||||
g2dWrapper.setColor(theme.getBgColor());
|
||||
g2dWrapper.fillRect(0, 0, d.width, d.height);
|
||||
g2d.clip(new Rectangle(new Point(0, 0), d));
|
||||
|
||||
GridType gridType = GridType.LINES;
|
||||
if (drawOptions.contains(DrawOption.GRID) && gridType != GridType.NONE) {
|
||||
double zoomStep = project.getGridSpacing().convertToPixels() * zoom;
|
||||
if (gridType == GridType.CROSSHAIR) {
|
||||
g2d.setStroke(new BasicStroke(1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,
|
||||
10f, new float[] { (float) zoomStep / 2, (float) zoomStep / 2 },
|
||||
(float) zoomStep / 4));
|
||||
} else if (gridType == GridType.DOT) {
|
||||
g2d.setStroke(new BasicStroke(1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,
|
||||
10f, new float[] { 1f, (float) zoomStep - 1 }, 0f));
|
||||
}
|
||||
|
||||
g2dWrapper.setColor(theme.getGridColor());
|
||||
for (double i = zoomStep; i < d.width; i += zoomStep) {
|
||||
g2dWrapper.drawLine((int) i, 0, (int) i, d.height - 1);
|
||||
}
|
||||
for (double j = zoomStep; j < d.height; j += zoomStep) {
|
||||
g2dWrapper.drawLine(0, (int) j, d.width - 1, (int) j);
|
||||
}
|
||||
}
|
||||
|
||||
if (Math.abs(1.0 - zoom) > 1e-4) {
|
||||
g2dWrapper.scale(zoom, zoom);
|
||||
}
|
||||
|
||||
// Composite mainComposite = g2d.getComposite();
|
||||
// Composite alphaComposite =
|
||||
// AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);
|
||||
|
||||
// g2dWrapper.resetTx();
|
||||
|
||||
// componentAreaMap.clear();
|
||||
for (IDIYComponent<?> component : project.getComponents()) {
|
||||
// Do not draw the component if it's filtered out.
|
||||
if (filter != null && !filter.testComponent(component)) {
|
||||
continue;
|
||||
}
|
||||
ComponentState state = ComponentState.NORMAL;
|
||||
if (drawOptions.contains(DrawOption.SELECTION)
|
||||
&& selectedComponents.contains(component)) {
|
||||
if (dragInProgress) {
|
||||
state = ComponentState.DRAGGING;
|
||||
} else {
|
||||
state = ComponentState.SELECTED;
|
||||
}
|
||||
}
|
||||
// Do not track the area if component is not invalidated and was
|
||||
// drawn in the same state.
|
||||
boolean trackArea = lastDrawnStateMap.get(component) != state;
|
||||
g2dWrapper.startedDrawingComponent();
|
||||
if (!trackArea) {
|
||||
g2dWrapper.stopTracking();
|
||||
}
|
||||
// Draw locked components in a new composite.
|
||||
if (lockedComponents.contains(component)) {
|
||||
g2d.setComposite(lockedComposite);
|
||||
}
|
||||
// Draw the component through the g2dWrapper.
|
||||
try {
|
||||
component.draw(g2dWrapper, state, drawOptions.contains(DrawOption.OUTLINE_MODE),
|
||||
project, g2dWrapper);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error drawing " + component.getName(), e);
|
||||
failedComponents.add(component);
|
||||
}
|
||||
Area area = g2dWrapper.finishedDrawingComponent();
|
||||
if (trackArea && area != null && !area.isEmpty()) {
|
||||
componentAreaMap.put(component, area);
|
||||
lastDrawnStateMap.put(component, state);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw control points.
|
||||
if (drawOptions.contains(DrawOption.CONTROL_POINTS)) {
|
||||
// Draw unselected points first to make sure they are below.
|
||||
if (dragInProgress || drawOptions.contains(DrawOption.OUTLINE_MODE)) {
|
||||
for (IDIYComponent<?> component : project.getComponents()) {
|
||||
for (int i = 0; i < component.getControlPointCount(); i++) {
|
||||
VisibilityPolicy visibilityPolicy = component
|
||||
.getControlPointVisibilityPolicy(i);
|
||||
if ((groupedComponents.contains(component)
|
||||
&& (visibilityPolicy == VisibilityPolicy.ALWAYS || (selectedComponents
|
||||
.contains(component) && visibilityPolicy == VisibilityPolicy.WHEN_SELECTED)) || (!groupedComponents
|
||||
.contains(component)
|
||||
&& !selectedComponents.contains(component) && component
|
||||
.getControlPointVisibilityPolicy(i) == VisibilityPolicy.ALWAYS))) {
|
||||
g2dWrapper.setColor(CONTROL_POINT_COLOR);
|
||||
Point controlPoint = component.getControlPoint(i);
|
||||
int pointSize = CONTROL_POINT_SIZE - 2;
|
||||
g2dWrapper.fillOval(controlPoint.x - pointSize / 2, controlPoint.y
|
||||
- pointSize / 2, pointSize, pointSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Then draw the selected ones.
|
||||
for (IDIYComponent<?> component : selectedComponents) {
|
||||
for (int i = 0; i < component.getControlPointCount(); i++) {
|
||||
if (!groupedComponents.contains(component)
|
||||
&& (component.getControlPointVisibilityPolicy(i) == VisibilityPolicy.WHEN_SELECTED || component
|
||||
.getControlPointVisibilityPolicy(i) == VisibilityPolicy.ALWAYS)) {
|
||||
|
||||
Point controlPoint = component.getControlPoint(i);
|
||||
int pointSize = CONTROL_POINT_SIZE;
|
||||
|
||||
g2dWrapper.setColor(SELECTED_CONTROL_POINT_COLOR.darker());
|
||||
g2dWrapper.fillOval(controlPoint.x - pointSize / 2, controlPoint.y
|
||||
- pointSize / 2, pointSize, pointSize);
|
||||
g2dWrapper.setColor(SELECTED_CONTROL_POINT_COLOR);
|
||||
g2dWrapper.fillOval(controlPoint.x - CONTROL_POINT_SIZE / 2 + 1,
|
||||
controlPoint.y - CONTROL_POINT_SIZE / 2 + 1,
|
||||
CONTROL_POINT_SIZE - 2, CONTROL_POINT_SIZE - 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw component slot in a separate composite.
|
||||
if (componentSlot != null) {
|
||||
g2dWrapper.startedDrawingComponent();
|
||||
g2dWrapper.setComposite(slotComposite);
|
||||
try {
|
||||
componentSlot.draw(g2dWrapper, ComponentState.NORMAL, drawOptions
|
||||
.contains(DrawOption.OUTLINE_MODE), project, g2dWrapper);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error drawing " + componentSlot.getName(), e);
|
||||
failedComponents.add(componentSlot);
|
||||
}
|
||||
g2dWrapper.finishedDrawingComponent();
|
||||
}
|
||||
|
||||
// Draw control points of the component in the slot.
|
||||
if (controlPointSlot != null) {
|
||||
for (Point point : controlPointSlot) {
|
||||
if (point != null) {
|
||||
g2dWrapper.setColor(SELECTED_CONTROL_POINT_COLOR.darker());
|
||||
g2dWrapper.fillOval(point.x - CONTROL_POINT_SIZE / 2, point.y
|
||||
- CONTROL_POINT_SIZE / 2, CONTROL_POINT_SIZE, CONTROL_POINT_SIZE);
|
||||
g2dWrapper.setColor(SELECTED_CONTROL_POINT_COLOR);
|
||||
g2dWrapper.fillOval(point.x - CONTROL_POINT_SIZE / 2 + 1, point.y
|
||||
- CONTROL_POINT_SIZE / 2 + 1, CONTROL_POINT_SIZE - 2,
|
||||
CONTROL_POINT_SIZE - 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Go back to the original transformation and zoom in to draw the
|
||||
// selection rectangle and other similar elements.
|
||||
// g2d.setTransform(initialTx);
|
||||
// if ((drawOptions.contains(DrawOption.ZOOM)) && (Math.abs(1.0 -
|
||||
// zoomLevel) > 1e-4)) {
|
||||
// g2d.scale(zoomLevel, zoomLevel);
|
||||
// }
|
||||
|
||||
// At the end draw selection rectangle if needed.
|
||||
if (drawOptions.contains(DrawOption.SELECTION) && (selectionRect != null)) {
|
||||
g2d.setColor(Color.white);
|
||||
g2d.draw(selectionRect);
|
||||
g2d.setColor(Color.black);
|
||||
g2d.setStroke(Constants.DASHED_STROKE);
|
||||
g2d.draw(selectionRect);
|
||||
}
|
||||
|
||||
// Draw component area for test
|
||||
if (debugComponentAreas) {
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
g2d.setColor(Color.red);
|
||||
for (Area area : componentAreaMap.values()) {
|
||||
g2d.draw(area);
|
||||
}
|
||||
}
|
||||
|
||||
return failedComponents;
|
||||
}
|
||||
|
||||
public double getZoomLevel() {
|
||||
return zoomLevel;
|
||||
}
|
||||
|
||||
public void setZoomLevel(double zoomLevel) {
|
||||
this.zoomLevel = zoomLevel;
|
||||
fireZoomChanged();
|
||||
// ConfigurationManager.getInstance().writeValue(ZOOM_KEY, zoomLevel);
|
||||
}
|
||||
|
||||
public void invalidateComponent(IDIYComponent<?> component) {
|
||||
componentAreaMap.remove(component);
|
||||
lastDrawnStateMap.remove(component);
|
||||
}
|
||||
|
||||
public Area getComponentArea(IDIYComponent<?> component) {
|
||||
return componentAreaMap.get(component);
|
||||
}
|
||||
|
||||
public void clearComponentAreaMap() {
|
||||
componentAreaMap.clear();
|
||||
}
|
||||
|
||||
public List<IDIYComponent<?>> findComponentsAt(Point point, Project project) {
|
||||
List<IDIYComponent<?>> components = new ArrayList<IDIYComponent<?>>();
|
||||
for (int i = 0; i < project.getComponents().size(); i++) {
|
||||
Area area = componentAreaMap.get(project.getComponents().get(i));
|
||||
if (area != null && area.contains(point)) {
|
||||
components.add(project.getComponents().get(i));
|
||||
}
|
||||
}
|
||||
return components;
|
||||
}
|
||||
|
||||
public Dimension getCanvasDimensions(Project project, Double zoomLevel, boolean useZoom) {
|
||||
double width = project.getWidth().convertToPixels();
|
||||
double height = project.getHeight().convertToPixels();
|
||||
if (useZoom) {
|
||||
width *= zoomLevel;
|
||||
height *= zoomLevel;
|
||||
} else {
|
||||
width /= Constants.PIXEL_SIZE;
|
||||
height /= Constants.PIXEL_SIZE;
|
||||
}
|
||||
return new Dimension((int) width, (int) height);
|
||||
}
|
||||
|
||||
public void fireZoomChanged() {
|
||||
messageDispatcher.dispatchMessage(EventType.ZOOM_CHANGED, zoomLevel);
|
||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||
}
|
||||
|
||||
public Theme getTheme() {
|
||||
return theme;
|
||||
}
|
||||
|
||||
public void setTheme(Theme theme) {
|
||||
this.theme = theme;
|
||||
ConfigurationManager.getInstance().writeValue(IPlugInPort.THEME_KEY, theme);
|
||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||
}
|
||||
}
|
||||
-673
@@ -1,673 +0,0 @@
|
||||
package org.diylc.presenter;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.Image;
|
||||
import java.awt.Paint;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Shape;
|
||||
import java.awt.Stroke;
|
||||
import java.awt.RenderingHints.Key;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.GlyphVector;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Arc2D;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.CubicCurve2D;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.PathIterator;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.QuadCurve2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.BufferedImageOp;
|
||||
import java.awt.image.ImageObserver;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.renderable.RenderableImage;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
|
||||
/**
|
||||
* {@link Graphics2D} wrapper that keeps track of all drawing actions and
|
||||
* creates an {@link Area} that corresponds to drawn objects. Before each
|
||||
* component is drawn, {@link #startedDrawingComponent()} should be called.
|
||||
* After the component is drawn, area may be retrieved using
|
||||
* {@link #finishedDrawingComponent()}. Graphics configuration (color, font,
|
||||
* etc) is reset between each two components.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
class G2DWrapper extends Graphics2D implements IDrawingObserver {
|
||||
|
||||
public static int LINE_SENSITIVITY_MARGIN = 2;
|
||||
public static int CURVE_SENSITIVITY = 6;
|
||||
|
||||
private boolean drawingComponent = false;
|
||||
private boolean trackingAllowed = true;
|
||||
|
||||
private Graphics2D canvasGraphics;
|
||||
private Stroke originalStroke;
|
||||
private Color originalColor;
|
||||
private Composite originalComposite;
|
||||
private AffineTransform originalTx;
|
||||
private Font originalFont;
|
||||
private AffineTransform currentTx;
|
||||
private Area currentArea;
|
||||
private Shape lastShape;
|
||||
|
||||
/**
|
||||
* Creates a wrapper around specified {@link Graphics2D} object.
|
||||
*
|
||||
* @param canvasGraphics
|
||||
*/
|
||||
public G2DWrapper(Graphics2D canvasGraphics) {
|
||||
super();
|
||||
this.canvasGraphics = canvasGraphics;
|
||||
currentArea = new Area();
|
||||
currentTx = new AffineTransform();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears out the current area and caches canvas settings.
|
||||
*/
|
||||
public void startedDrawingComponent() {
|
||||
drawingComponent = true;
|
||||
currentArea = new Area();
|
||||
originalStroke = canvasGraphics.getStroke();
|
||||
originalColor = canvasGraphics.getColor();
|
||||
originalTx = canvasGraphics.getTransform();
|
||||
originalComposite = canvasGraphics.getComposite();
|
||||
originalFont = canvasGraphics.getFont();
|
||||
currentTx = new AffineTransform();
|
||||
lastShape = null;
|
||||
startTracking();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverts {@link Graphics2D} settings and returns area drawn by component
|
||||
* in the meantime.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Area finishedDrawingComponent() {
|
||||
drawingComponent = false;
|
||||
canvasGraphics.setStroke(originalStroke);
|
||||
canvasGraphics.setColor(originalColor);
|
||||
canvasGraphics.setTransform(originalTx);
|
||||
canvasGraphics.setComposite(originalComposite);
|
||||
canvasGraphics.setFont(originalFont);
|
||||
return currentArea;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startTracking() {
|
||||
this.trackingAllowed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopTracking() {
|
||||
this.trackingAllowed = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends shape interior to the current component area.
|
||||
*
|
||||
* @param s
|
||||
*/
|
||||
private void appendShape(Shape s) {
|
||||
if (!drawingComponent || !trackingAllowed) {
|
||||
return;
|
||||
}
|
||||
Rectangle2D bounds = s.getBounds2D();
|
||||
// Only cache the shape if it's not 1D.
|
||||
if (bounds.getWidth() > 1 && bounds.getHeight() > 1) {
|
||||
Area area = new Area(s);
|
||||
area.transform(currentTx);
|
||||
currentArea.add(area);
|
||||
lastShape = s;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends shape outline to the current component area.
|
||||
*
|
||||
* @param s
|
||||
*/
|
||||
private void appendShapeOutline(Shape s) {
|
||||
// Do not add shape outline if the same shape has been filled recently.
|
||||
if (!drawingComponent || !trackingAllowed || s.equals(lastShape)) {
|
||||
return;
|
||||
}
|
||||
lastShape = s;
|
||||
PathIterator pathIterator = s.getPathIterator(null);
|
||||
double thickness;
|
||||
if (getStroke() instanceof BasicStroke) {
|
||||
thickness = ((BasicStroke) getStroke()).getLineWidth() + 2 * LINE_SENSITIVITY_MARGIN;
|
||||
} else {
|
||||
thickness = 2 * LINE_SENSITIVITY_MARGIN;
|
||||
}
|
||||
Point2D prevPoint = null;
|
||||
while (!pathIterator.isDone()) {
|
||||
double[] coord = new double[6];
|
||||
int type = pathIterator.currentSegment(coord);
|
||||
switch (type) {
|
||||
case PathIterator.SEG_MOVETO:
|
||||
prevPoint = new Point2D.Double(coord[0], coord[1]);
|
||||
break;
|
||||
case PathIterator.SEG_LINETO:
|
||||
// Represent straight line with a rectangle.
|
||||
Point2D nextPoint = new Point2D.Double(coord[0], coord[1]);
|
||||
Double theta = Math.atan2(nextPoint.getY() - prevPoint.getY(), nextPoint.getX()
|
||||
- prevPoint.getX());
|
||||
double width = Math.sqrt(Math.pow(nextPoint.getX() - prevPoint.getX(), 2)
|
||||
+ Math.pow(nextPoint.getY() - prevPoint.getY(), 2));
|
||||
double midX = (prevPoint.getX() + nextPoint.getX()) / 2;
|
||||
double midY = (prevPoint.getY() + nextPoint.getY()) / 2;
|
||||
Rectangle2D rect = new Rectangle2D.Double(midX - width / 2, midY - thickness / 2,
|
||||
width, thickness);
|
||||
Area area = new Area(rect);
|
||||
area.transform(AffineTransform.getRotateInstance(theta, midX, midY));
|
||||
// area.transform(currentTx);
|
||||
appendShape(area);
|
||||
// Set the prev point to line end
|
||||
prevPoint = nextPoint;
|
||||
break;
|
||||
case PathIterator.SEG_CUBICTO:
|
||||
CubicCurve2D cubicCurve = new CubicCurve2D.Double(prevPoint.getX(), prevPoint
|
||||
.getY(), coord[0], coord[1], coord[2], coord[3], coord[4], coord[5]);
|
||||
addCubicCurveArea(cubicCurve);
|
||||
prevPoint = new Point2D.Double(coord[4], coord[5]);
|
||||
break;
|
||||
case PathIterator.SEG_QUADTO:
|
||||
QuadCurve2D quadCurve = new QuadCurve2D.Double(prevPoint.getX(), prevPoint.getY(),
|
||||
coord[0], coord[1], coord[2], coord[3]);
|
||||
addQuadCurveArea(quadCurve);
|
||||
prevPoint = new Point2D.Double(coord[3], coord[3]);
|
||||
break;
|
||||
}
|
||||
pathIterator.next();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a cubic curve to the component area. It uses subdivision to
|
||||
* approximate the curve with a series of straight lines.
|
||||
*
|
||||
* @param curve
|
||||
*/
|
||||
private void addCubicCurveArea(CubicCurve2D curve) {
|
||||
// When end points are close enough, approximate the curve with a
|
||||
// straight line.
|
||||
if (curve.getFlatness() < CURVE_SENSITIVITY) {
|
||||
appendShapeOutline(new Line2D.Double(curve.getP1(), curve.getP2()));
|
||||
} else {
|
||||
CubicCurve2D leftSubcurve = new CubicCurve2D.Double();
|
||||
CubicCurve2D rightSubcurve = new CubicCurve2D.Double();
|
||||
curve.subdivide(leftSubcurve, rightSubcurve);
|
||||
addCubicCurveArea(leftSubcurve);
|
||||
addCubicCurveArea(rightSubcurve);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a quad curve to the component area. It uses subdivision to
|
||||
* approximate the curve with a series of straight lines.
|
||||
*
|
||||
* @param curve
|
||||
*/
|
||||
private void addQuadCurveArea(QuadCurve2D curve) {
|
||||
// When end points are close enough, approximate the curve with a
|
||||
// straight line.
|
||||
if (curve.getFlatness() < CURVE_SENSITIVITY) {
|
||||
appendShapeOutline(new Line2D.Double(curve.getP1(), curve.getP2()));
|
||||
} else {
|
||||
QuadCurve2D leftSubcurve = new QuadCurve2D.Double();
|
||||
QuadCurve2D rightSubcurve = new QuadCurve2D.Double();
|
||||
curve.subdivide(leftSubcurve, rightSubcurve);
|
||||
addQuadCurveArea(leftSubcurve);
|
||||
addQuadCurveArea(rightSubcurve);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRenderingHints(Map<?, ?> hints) {
|
||||
canvasGraphics.addRenderingHints(hints);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clip(Shape s) {
|
||||
canvasGraphics.clip(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Shape s) {
|
||||
canvasGraphics.draw(s);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
appendShapeOutline(s);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawGlyphVector(GlyphVector g, float x, float y) {
|
||||
canvasGraphics.drawGlyphVector(g, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) {
|
||||
// FIXME: process map
|
||||
return canvasGraphics.drawImage(img, xform, obs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) {
|
||||
canvasGraphics.drawImage(img, op, x, y);
|
||||
// FIXME: process map
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRenderableImage(RenderableImage img, AffineTransform xform) {
|
||||
canvasGraphics.drawRenderableImage(img, xform);
|
||||
// FIXME: process map
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRenderedImage(RenderedImage img, AffineTransform xform) {
|
||||
canvasGraphics.drawRenderedImage(img, xform);
|
||||
// FIXME: process map
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawString(String str, int x, int y) {
|
||||
canvasGraphics.drawString(str, x, y);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
FontMetrics fontMetrics = canvasGraphics.getFontMetrics();
|
||||
Rectangle2D rect = fontMetrics.getStringBounds(str, canvasGraphics);
|
||||
appendShape(new Rectangle2D.Double(rect.getX() + x, rect.getY() + y, rect.getWidth(),
|
||||
rect.getHeight()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawString(String str, float x, float y) {
|
||||
canvasGraphics.drawString(str, x, y);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
FontMetrics fontMetrics = canvasGraphics.getFontMetrics();
|
||||
Rectangle2D rect = fontMetrics.getStringBounds(str, canvasGraphics);
|
||||
appendShape(new Rectangle2D.Double(rect.getX() + x, rect.getY() + y, rect.getWidth(),
|
||||
rect.getHeight()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawString(AttributedCharacterIterator iterator, int x, int y) {
|
||||
canvasGraphics.drawString(iterator, x, y);
|
||||
// FIXME: process map
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawString(AttributedCharacterIterator iterator, float x, float y) {
|
||||
canvasGraphics.drawString(iterator, x, y);
|
||||
// FIXME: process map
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fill(Shape s) {
|
||||
canvasGraphics.fill(s);
|
||||
appendShape(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getBackground() {
|
||||
return canvasGraphics.getBackground();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Composite getComposite() {
|
||||
return canvasGraphics.getComposite();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphicsConfiguration getDeviceConfiguration() {
|
||||
return canvasGraphics.getDeviceConfiguration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FontRenderContext getFontRenderContext() {
|
||||
return canvasGraphics.getFontRenderContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Paint getPaint() {
|
||||
return canvasGraphics.getPaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRenderingHint(Key hintKey) {
|
||||
return canvasGraphics.getRenderingHint(hintKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderingHints getRenderingHints() {
|
||||
return canvasGraphics.getRenderingHints();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stroke getStroke() {
|
||||
return canvasGraphics.getStroke();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AffineTransform getTransform() {
|
||||
return canvasGraphics.getTransform();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hit(Rectangle rect, Shape s, boolean onStroke) {
|
||||
return canvasGraphics.hit(rect, s, onStroke);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rotate(double theta) {
|
||||
canvasGraphics.rotate(theta);
|
||||
currentTx.rotate(theta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rotate(double theta, double x, double y) {
|
||||
canvasGraphics.rotate(theta, x, y);
|
||||
currentTx.rotate(theta, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scale(double sx, double sy) {
|
||||
canvasGraphics.scale(sx, sy);
|
||||
currentTx.scale(sx, sy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackground(Color color) {
|
||||
canvasGraphics.setBackground(color);
|
||||
// FIXME: fix map
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setComposite(Composite comp) {
|
||||
canvasGraphics.setComposite(comp);
|
||||
// FIXME: check this.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPaint(Paint paint) {
|
||||
canvasGraphics.setPaint(paint);
|
||||
// FIXME: check this
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRenderingHint(Key hintKey, Object hintValue) {
|
||||
canvasGraphics.setRenderingHint(hintKey, hintValue);
|
||||
// FIXME: check this
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRenderingHints(Map<?, ?> hints) {
|
||||
canvasGraphics.setRenderingHints(hints);
|
||||
// FIXME: check this
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStroke(Stroke s) {
|
||||
canvasGraphics.setStroke(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTransform(AffineTransform Tx) {
|
||||
canvasGraphics.setTransform(Tx);
|
||||
currentTx = Tx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shear(double shx, double shy) {
|
||||
canvasGraphics.shear(shx, shy);
|
||||
currentTx.shear(shx, shy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transform(AffineTransform Tx) {
|
||||
canvasGraphics.transform(Tx);
|
||||
currentTx.concatenate(Tx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(int x, int y) {
|
||||
canvasGraphics.translate(x, y);
|
||||
currentTx.translate(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(double tx, double ty) {
|
||||
canvasGraphics.translate(tx, ty);
|
||||
currentTx.translate(tx, ty);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearRect(int x, int y, int width, int height) {
|
||||
canvasGraphics.clearRect(x, y, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clipRect(int x, int y, int width, int height) {
|
||||
canvasGraphics.clipRect(x, y, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyArea(int x, int y, int width, int height, int dx, int dy) {
|
||||
canvasGraphics.copyArea(x, y, width, height, dx, dy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Graphics create() {
|
||||
return canvasGraphics.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
canvasGraphics.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
|
||||
canvasGraphics.drawArc(x, y, width, height, startAngle, arcAngle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, int x, int y, ImageObserver observer) {
|
||||
boolean result = canvasGraphics.drawImage(img, x, y, observer);
|
||||
appendShape(new Rectangle2D.Double(x, y, img.getWidth(observer), img.getHeight(observer)));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) {
|
||||
// FIXME: map
|
||||
return canvasGraphics.drawImage(img, x, y, bgcolor, observer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) {
|
||||
// FIXME: map
|
||||
return canvasGraphics.drawImage(img, x, y, width, height, observer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor,
|
||||
ImageObserver observer) {
|
||||
// FIXME: map
|
||||
return canvasGraphics.drawImage(img, x, y, width, height, bgcolor, observer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1,
|
||||
int sx2, int sy2, ImageObserver observer) {
|
||||
// FIXME: map
|
||||
return canvasGraphics.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, observer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1,
|
||||
int sx2, int sy2, Color bgcolor, ImageObserver observer) {
|
||||
// FIXME: map
|
||||
return drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, bgcolor, observer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawLine(int x1, int y1, int x2, int y2) {
|
||||
canvasGraphics.drawLine(x1, y1, x2, y2);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
appendShapeOutline(new Line2D.Double(x1, y1, x2, y2));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawOval(int x, int y, int width, int height) {
|
||||
canvasGraphics.drawOval(x, y, width, height);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
appendShapeOutline(new Ellipse2D.Double(x, y, width, height));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawPolygon(int[] points, int[] points2, int points3) {
|
||||
canvasGraphics.drawPolygon(points, points2, points3);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
appendShapeOutline(new Polygon(points, points2, points3));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawPolyline(int[] points, int[] points2, int points3) {
|
||||
canvasGraphics.drawPolyline(points, points2, points3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
|
||||
canvasGraphics.drawRoundRect(x, y, width, height, arcWidth, arcHeight);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
appendShapeOutline(new RoundRectangle2D.Double(x, y, width, height, arcWidth, arcHeight));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
|
||||
canvasGraphics.fillArc(x, y, width, height, startAngle, arcAngle);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
appendShape(new Arc2D.Double(x, y, width, height, startAngle, arcAngle, Arc2D.PIE));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillOval(int x, int y, int width, int height) {
|
||||
canvasGraphics.fillOval(x, y, width, height);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
appendShape(new Ellipse2D.Double(x, y, width, height));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillPolygon(int[] points, int[] points2, int points3) {
|
||||
canvasGraphics.fillPolygon(points, points2, points3);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
appendShape(new Polygon(points, points2, points3));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRect(int x, int y, int width, int height) {
|
||||
canvasGraphics.drawRect(x, y, width, height);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
appendShapeOutline(new Rectangle(x, y, width, height));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillRect(int x, int y, int width, int height) {
|
||||
canvasGraphics.fillRect(x, y, width, height);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
appendShape(new Rectangle(x, y, width, height));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
|
||||
canvasGraphics.fillRoundRect(x, y, width, height, arcWidth, arcHeight);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
appendShape(new RoundRectangle2D.Double(x, y, width, height, arcWidth, arcHeight));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getClip() {
|
||||
return canvasGraphics.getClip();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle getClipBounds() {
|
||||
return canvasGraphics.getClipBounds();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getColor() {
|
||||
return canvasGraphics.getColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Font getFont() {
|
||||
return canvasGraphics.getFont();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FontMetrics getFontMetrics(Font f) {
|
||||
return canvasGraphics.getFontMetrics(f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClip(Shape clip) {
|
||||
canvasGraphics.setClip(clip);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClip(int x, int y, int width, int height) {
|
||||
canvasGraphics.setClip(x, y, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColor(Color c) {
|
||||
canvasGraphics.setColor(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFont(Font font) {
|
||||
canvasGraphics.setFont(font);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPaintMode() {
|
||||
canvasGraphics.setPaintMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setXORMode(Color c1) {
|
||||
canvasGraphics.setXORMode(c1);
|
||||
}
|
||||
}
|
||||
-219
@@ -1,219 +0,0 @@
|
||||
package org.diylc.presenter;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.common.ComponentType;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.measures.Size;
|
||||
|
||||
import com.diyfever.gui.miscutils.ConfigurationManager;
|
||||
import com.rits.cloning.Cloner;
|
||||
|
||||
/**
|
||||
* Manages component instantiation.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class InstantiationManager {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(InstantiationManager.class);
|
||||
|
||||
private static final int MAX_RECENT_COMPONENTS = 16;
|
||||
|
||||
private Cloner cloner;
|
||||
|
||||
private ComponentType componentTypeSlot;
|
||||
private IDIYComponent<?> componentSlot;
|
||||
private Point firstControlPoint;
|
||||
private Point potentialControlPoint;
|
||||
|
||||
public InstantiationManager() {
|
||||
cloner = new Cloner();
|
||||
}
|
||||
|
||||
public ComponentType getComponentTypeSlot() {
|
||||
return componentTypeSlot;
|
||||
}
|
||||
|
||||
public IDIYComponent<?> getComponentSlot() {
|
||||
return componentSlot;
|
||||
}
|
||||
|
||||
public Point getFirstControlPoint() {
|
||||
return firstControlPoint;
|
||||
}
|
||||
|
||||
public Point getPotentialControlPoint() {
|
||||
return potentialControlPoint;
|
||||
}
|
||||
|
||||
public void setComponentTypeSlot(ComponentType componentTypeSlot, Project currentProject)
|
||||
throws Exception {
|
||||
this.componentTypeSlot = componentTypeSlot;
|
||||
if (componentTypeSlot == null) {
|
||||
this.componentSlot = null;
|
||||
} else {
|
||||
switch (componentTypeSlot.getCreationMethod()) {
|
||||
case POINT_BY_POINT:
|
||||
this.componentSlot = null;
|
||||
break;
|
||||
case SINGLE_CLICK:
|
||||
this.componentSlot = instantiateComponent(componentTypeSlot, new Point(0, 0),
|
||||
currentProject);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.firstControlPoint = null;
|
||||
this.potentialControlPoint = null;
|
||||
}
|
||||
|
||||
public void instatiatePointByPoint(Point scaledPoint, Project currentProject) throws Exception {
|
||||
firstControlPoint = scaledPoint;
|
||||
componentSlot = instantiateComponent(componentTypeSlot, firstControlPoint, currentProject);
|
||||
|
||||
// Set the other control point to the same location, we'll
|
||||
// move it later when mouse moves.
|
||||
componentSlot.setControlPoint(firstControlPoint, 0);
|
||||
componentSlot.setControlPoint(firstControlPoint, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates component in the slot with the new second control point.
|
||||
*
|
||||
* @param scaledPoint
|
||||
* @return true, if any change is made
|
||||
*/
|
||||
public boolean updatePointByPoint(Point scaledPoint) {
|
||||
boolean changeMade = !scaledPoint.equals(potentialControlPoint);
|
||||
potentialControlPoint = scaledPoint;
|
||||
if (componentSlot != null) {
|
||||
componentSlot.setControlPoint(scaledPoint, 1);
|
||||
}
|
||||
return changeMade;
|
||||
}
|
||||
|
||||
public boolean updateSingleClick(Point scaledPoint, boolean snapToGrid, Size gridSpacing) {
|
||||
if (potentialControlPoint == null) {
|
||||
potentialControlPoint = new Point(0, 0);
|
||||
}
|
||||
int dx = scaledPoint.x - potentialControlPoint.x;
|
||||
int dy = scaledPoint.y - potentialControlPoint.y;
|
||||
if (snapToGrid) {
|
||||
dx = CalcUtils.roundToGrid(dx, gridSpacing);
|
||||
dy = CalcUtils.roundToGrid(dy, gridSpacing);
|
||||
}
|
||||
// Only repaint if there's an actual change.
|
||||
if (dx == 0 && dy == 0) {
|
||||
return false;
|
||||
}
|
||||
potentialControlPoint.translate(dx, dy);
|
||||
if (componentSlot == null) {
|
||||
LOG.error("Component slot should not be null!");
|
||||
} else {
|
||||
Point p = new Point();
|
||||
for (int i = 0; i < componentSlot.getControlPointCount(); i++) {
|
||||
p.setLocation(componentSlot.getControlPoint(i));
|
||||
p.translate(dx, dy);
|
||||
componentSlot.setControlPoint(p, i);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public IDIYComponent<?> instantiateComponent(ComponentType componentType, Point point,
|
||||
Project currentProject) throws Exception {
|
||||
LOG.info("Instatiating component of type: " + componentType.getInstanceClass().getName());
|
||||
|
||||
// Instantiate the component.
|
||||
IDIYComponent<?> component = componentType.getInstanceClass().newInstance();
|
||||
|
||||
component.setName(createUniqueName(componentType, currentProject));
|
||||
|
||||
// Translate them to the desired location.
|
||||
if (point != null) {
|
||||
for (int j = 0; j < component.getControlPointCount(); j++) {
|
||||
Point controlPoint = new Point(component.getControlPoint(j));
|
||||
controlPoint.translate(point.x, point.y);
|
||||
// snapPointToGrid(controlPoint);
|
||||
component.setControlPoint(controlPoint, j);
|
||||
}
|
||||
}
|
||||
|
||||
fillWithDefaultProperties(component);
|
||||
|
||||
// Write to recent components
|
||||
List<String> recentComponentTypes = (List<String>) ConfigurationManager.getInstance()
|
||||
.readObject(IPlugInPort.RECENT_COMPONENTS_KEY, new ArrayList<ComponentType>());
|
||||
String className = componentType.getInstanceClass().getName();
|
||||
if (recentComponentTypes.size() == 0 || !recentComponentTypes.get(0).equals(className)) {
|
||||
// Remove if it's already somewhere in the list.
|
||||
recentComponentTypes.remove(className);
|
||||
// Add to the end of the list.
|
||||
recentComponentTypes.add(0, className);
|
||||
// Trim the list if necessary.
|
||||
if (recentComponentTypes.size() > MAX_RECENT_COMPONENTS) {
|
||||
recentComponentTypes.remove(recentComponentTypes.size() - 1);
|
||||
}
|
||||
ConfigurationManager.getInstance().writeValue(IPlugInPort.RECENT_COMPONENTS_KEY,
|
||||
recentComponentTypes);
|
||||
}
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
public String createUniqueName(ComponentType componentType, Project currentProject) {
|
||||
int i = 0;
|
||||
boolean exists = true;
|
||||
while (exists) {
|
||||
i++;
|
||||
String name = componentType.getNamePrefix() + i;
|
||||
exists = false;
|
||||
for (IDIYComponent<?> c : currentProject.getComponents()) {
|
||||
if (c.getName().equals(name)) {
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return componentType.getNamePrefix() + i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds any properties that have default values and injects default values.
|
||||
* Typically it should be used for {@link IDIYComponent} and {@link Project}
|
||||
* objects.
|
||||
*
|
||||
* @param object
|
||||
* @throws IllegalArgumentException
|
||||
* @throws IllegalAccessException
|
||||
* @throws InvocationTargetException
|
||||
* @throws NoSuchMethodException
|
||||
* @throws SecurityException
|
||||
*/
|
||||
public void fillWithDefaultProperties(Object object) throws IllegalArgumentException,
|
||||
IllegalAccessException, InvocationTargetException, SecurityException,
|
||||
NoSuchMethodException {
|
||||
// Extract properties.
|
||||
List<PropertyWrapper> properties = ComponentProcessor.getInstance().extractProperties(
|
||||
object.getClass());
|
||||
// Override with default values if available.
|
||||
for (PropertyWrapper property : properties) {
|
||||
Object defaultValue = ConfigurationManager.getInstance().readObject(
|
||||
Presenter.DEFAULTS_KEY_PREFIX + object.getClass().getName() + ":"
|
||||
+ property.getName(), null);
|
||||
if (defaultValue != null) {
|
||||
property.setValue(cloner.deepClone(defaultValue));
|
||||
property.writeTo(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
package org.diylc.presenter;
|
||||
|
||||
import java.awt.Point;
|
||||
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
import com.thoughtworks.xstream.converters.Converter;
|
||||
import com.thoughtworks.xstream.converters.MarshallingContext;
|
||||
import com.thoughtworks.xstream.converters.UnmarshallingContext;
|
||||
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
|
||||
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
|
||||
|
||||
/**
|
||||
* Serializes {@link Point} objects by converting coordinates from pixels to
|
||||
* inches, thus avoiding the resolution to affect point placement.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class PointConverter implements Converter {
|
||||
|
||||
@Override
|
||||
public void marshal(Object object, HierarchicalStreamWriter writer, MarshallingContext context) {
|
||||
Point point = (Point) object;
|
||||
writer.addAttribute("x", Double.toString(1d * point.x / Constants.PIXELS_PER_INCH));
|
||||
writer.addAttribute("y", Double.toString(1d * point.y / Constants.PIXELS_PER_INCH));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
|
||||
double x = Double.parseDouble(reader.getAttribute("x"));
|
||||
double y = Double.parseDouble(reader.getAttribute("y"));
|
||||
return new Point((int) Math.round(x * Constants.PIXELS_PER_INCH), (int) Math.round(y
|
||||
* Constants.PIXELS_PER_INCH));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public boolean canConvert(Class clazz) {
|
||||
return Point.class.isAssignableFrom(clazz);
|
||||
}
|
||||
}
|
||||
-1391
File diff suppressed because it is too large
Load Diff
-456
@@ -1,456 +0,0 @@
|
||||
package org.diylc.presenter;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Point;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.common.EventType;
|
||||
import org.diylc.common.Orientation;
|
||||
import org.diylc.components.boards.AbstractBoard;
|
||||
import org.diylc.components.boards.BlankBoard;
|
||||
import org.diylc.components.boards.PerfBoard;
|
||||
import org.diylc.components.boards.VeroBoard;
|
||||
import org.diylc.components.connectivity.CopperTrace;
|
||||
import org.diylc.components.connectivity.HookupWire;
|
||||
import org.diylc.components.connectivity.Jumper;
|
||||
import org.diylc.components.connectivity.SolderPad;
|
||||
import org.diylc.components.misc.Label;
|
||||
import org.diylc.components.passive.RadialElectrolytic;
|
||||
import org.diylc.components.passive.RadialFilmCapacitor;
|
||||
import org.diylc.components.passive.Resistor;
|
||||
import org.diylc.components.semiconductors.DIL_IC;
|
||||
import org.diylc.components.semiconductors.DiodePlastic;
|
||||
import org.diylc.components.semiconductors.LED;
|
||||
import org.diylc.components.semiconductors.TransistorTO92;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.measures.Capacitance;
|
||||
import org.diylc.core.measures.Resistance;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.diyfever.gui.simplemq.MessageDispatcher;
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import com.thoughtworks.xstream.io.xml.DomDriver;
|
||||
|
||||
public class ProjectFileManager {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(ProjectFileManager.class);
|
||||
|
||||
// private static final int V1_PIXELS_PER_INCH = 200;
|
||||
private static final Size V1_GRID_SPACING = new Size(0.1d, SizeUnit.in);
|
||||
private static final Map<String, Color> V1_COLOR_MAP = new HashMap<String, Color>();
|
||||
static {
|
||||
V1_COLOR_MAP.put("red", Color.red);
|
||||
V1_COLOR_MAP.put("blue", Color.blue);
|
||||
V1_COLOR_MAP.put("white", Color.white);
|
||||
V1_COLOR_MAP.put("green", Color.green.darker());
|
||||
V1_COLOR_MAP.put("black", Color.black);
|
||||
V1_COLOR_MAP.put("yellow", Color.yellow);
|
||||
}
|
||||
|
||||
private XStream xStream;
|
||||
// Legacy deserializer for 3.0.1 through 3.0.7, loads Points referenced in
|
||||
// pixels.
|
||||
private XStream xStreamOld;
|
||||
|
||||
private String currentFileName = null;
|
||||
private boolean modified = false;
|
||||
|
||||
private MessageDispatcher<EventType> messageDispatcher;
|
||||
|
||||
public ProjectFileManager(MessageDispatcher<EventType> messageDispatcher) {
|
||||
super();
|
||||
this.xStream = new XStream(new DomDriver());
|
||||
xStream.autodetectAnnotations(true);
|
||||
xStream.registerConverter(new PointConverter());
|
||||
this.xStreamOld = new XStream(new DomDriver());
|
||||
xStreamOld.autodetectAnnotations(true);
|
||||
this.messageDispatcher = messageDispatcher;
|
||||
}
|
||||
|
||||
public void startNewFile() {
|
||||
currentFileName = null;
|
||||
modified = false;
|
||||
fireFileStatusChanged();
|
||||
}
|
||||
|
||||
public void serializeProjectToFile(Project project, String fileName, boolean isBackup)
|
||||
throws IOException {
|
||||
if (!isBackup) {
|
||||
LOG.info(String.format("saveProjectToFile(%s)", fileName));
|
||||
}
|
||||
FileOutputStream fos;
|
||||
fos = new FileOutputStream(fileName);
|
||||
xStream.toXML(project, fos);
|
||||
fos.close();
|
||||
if (!isBackup) {
|
||||
this.currentFileName = fileName;
|
||||
this.modified = false;
|
||||
fireFileStatusChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public Project deserializeProjectFromFile(String fileName, List<String> warnings)
|
||||
throws SAXException, IOException, ParserConfigurationException {
|
||||
LOG.info(String.format("loadProjectFromFile(%s)", fileName));
|
||||
Project project;
|
||||
File file = new File(fileName);
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
Document doc = db.parse(file);
|
||||
doc.getDocumentElement().normalize();
|
||||
if (doc.getDocumentElement().getNodeName().equalsIgnoreCase(Project.class.getName())) {
|
||||
project = parseV3File(fileName);
|
||||
} else {
|
||||
if (!doc.getDocumentElement().getNodeName().equalsIgnoreCase("layout")) {
|
||||
throw new IllegalArgumentException(
|
||||
"Could not open DIY file. Root node is not named 'Layout'.");
|
||||
}
|
||||
String formatVersion = doc.getDocumentElement().getAttribute("formatVersion");
|
||||
if (formatVersion == null || formatVersion.trim().isEmpty()) {
|
||||
LOG.debug("Detected v1 file.");
|
||||
project = parseV1File(doc.getDocumentElement(), warnings);
|
||||
} else if (formatVersion.equals("2.0")) {
|
||||
LOG.debug("Detected v2 file.");
|
||||
project = parseV2File(doc.getDocumentElement());
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown file format version: " + formatVersion);
|
||||
}
|
||||
}
|
||||
Collections.sort(warnings);
|
||||
this.currentFileName = fileName;
|
||||
this.modified = false;
|
||||
return project;
|
||||
}
|
||||
|
||||
public void notifyFileChange() {
|
||||
this.modified = true;
|
||||
fireFileStatusChanged();
|
||||
}
|
||||
|
||||
public String getCurrentFileName() {
|
||||
return currentFileName;
|
||||
}
|
||||
|
||||
public boolean isModified() {
|
||||
return modified;
|
||||
}
|
||||
|
||||
public void fireFileStatusChanged() {
|
||||
messageDispatcher.dispatchMessage(EventType.FILE_STATUS_CHANGED, getCurrentFileName(),
|
||||
isModified());
|
||||
}
|
||||
|
||||
private Project parseV1File(Element root, List<String> warnings) {
|
||||
Project project = new Project();
|
||||
project.setTitle(root.getAttribute("Project"));
|
||||
project.setAuthor(root.getAttribute("Credits"));
|
||||
project.setGridSpacing(V1_GRID_SPACING);
|
||||
String type = root.getAttribute("Type");
|
||||
|
||||
// Create the board.
|
||||
int width = Integer.parseInt(root.getAttribute("Width")) + 1;
|
||||
int height = Integer.parseInt(root.getAttribute("Height")) + 1;
|
||||
int boardWidth = (int) (width * Constants.PIXELS_PER_INCH * V1_GRID_SPACING.getValue());
|
||||
int boardHeight = (int) (height * Constants.PIXELS_PER_INCH * V1_GRID_SPACING.getValue());
|
||||
int projectWidth = (int) project.getWidth().convertToPixels();
|
||||
int projectHeight = (int) project.getHeight().convertToPixels();
|
||||
int x = (projectWidth - boardWidth) / 2;
|
||||
int y = (projectHeight - boardHeight) / 2;
|
||||
AbstractBoard board;
|
||||
if (type.equalsIgnoreCase("pcb")) {
|
||||
board = new BlankBoard();
|
||||
board.setBoardColor(Color.white);
|
||||
board.setBorderColor(Color.black);
|
||||
} else if (type.equalsIgnoreCase("perfboard")) {
|
||||
board = new PerfBoard();
|
||||
} else if (type.equalsIgnoreCase("stripboard")) {
|
||||
board = new VeroBoard();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unrecognized board type: " + type);
|
||||
}
|
||||
board.setName("Main board");
|
||||
Point referencePoint = new Point(CalcUtils.roundToGrid(x, V1_GRID_SPACING), CalcUtils
|
||||
.roundToGrid(y, V1_GRID_SPACING));
|
||||
board.setControlPoint(referencePoint, 0);
|
||||
board.setControlPoint(new Point(CalcUtils.roundToGrid(x + boardWidth, V1_GRID_SPACING),
|
||||
CalcUtils.roundToGrid(y + boardHeight, V1_GRID_SPACING)), 1);
|
||||
project.getComponents().add(board);
|
||||
|
||||
NodeList childNodes = root.getChildNodes();
|
||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||
Node node = childNodes.item(i);
|
||||
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
String nodeName = node.getNodeName();
|
||||
String nameAttr = node.getAttributes().getNamedItem("Name").getNodeValue();
|
||||
Node valueNode = node.getAttributes().getNamedItem("Value");
|
||||
String valueAttr = valueNode == null ? null : valueNode.getNodeValue();
|
||||
int x1Attr = Integer.parseInt(node.getAttributes().getNamedItem("X1")
|
||||
.getNodeValue());
|
||||
int y1Attr = Integer.parseInt(node.getAttributes().getNamedItem("Y1")
|
||||
.getNodeValue());
|
||||
Point point1 = convertV1CoordinatesToV3Point(referencePoint, x1Attr, y1Attr);
|
||||
Point point2 = null;
|
||||
Integer x2Attr = null;
|
||||
Integer y2Attr = null;
|
||||
Color color = null;
|
||||
if (node.getAttributes().getNamedItem("Color") != null) {
|
||||
String colorAttr = node.getAttributes().getNamedItem("Color").getNodeValue();
|
||||
color = V1_COLOR_MAP.get(colorAttr.toLowerCase());
|
||||
}
|
||||
if (node.getAttributes().getNamedItem("X2") != null
|
||||
&& node.getAttributes().getNamedItem("Y2") != null) {
|
||||
x2Attr = Integer.parseInt(node.getAttributes().getNamedItem("X2")
|
||||
.getNodeValue());
|
||||
y2Attr = Integer.parseInt(node.getAttributes().getNamedItem("Y2")
|
||||
.getNodeValue());
|
||||
point2 = convertV1CoordinatesToV3Point(referencePoint, x2Attr, y2Attr);
|
||||
}
|
||||
IDIYComponent<?> component = null;
|
||||
if (nodeName.equalsIgnoreCase("text")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
Label label = new Label();
|
||||
label.setName(nameAttr);
|
||||
if (color != null) {
|
||||
label.setColor(color);
|
||||
}
|
||||
label.setText(valueAttr);
|
||||
label.setCenter(false);
|
||||
label.setControlPoint(convertV1CoordinatesToV3Point(referencePoint, x1Attr,
|
||||
y1Attr), 0);
|
||||
component = label;
|
||||
} else if (nodeName.equalsIgnoreCase("pad")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
SolderPad pad = new SolderPad();
|
||||
pad.setName(nameAttr);
|
||||
if (color != null) {
|
||||
pad.setColor(color);
|
||||
}
|
||||
pad.setControlPoint(convertV1CoordinatesToV3Point(referencePoint, x1Attr,
|
||||
y1Attr), 0);
|
||||
component = pad;
|
||||
} else if (nodeName.equalsIgnoreCase("trace")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
CopperTrace trace = new CopperTrace();
|
||||
trace.setName(nameAttr);
|
||||
if (color != null) {
|
||||
trace.setLeadColor(color);
|
||||
}
|
||||
trace.setControlPoint(point1, 0);
|
||||
trace.setControlPoint(point2, 1);
|
||||
component = trace;
|
||||
} else if (nodeName.equalsIgnoreCase("jumper")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
Jumper jumper = new Jumper();
|
||||
jumper.setName(nameAttr);
|
||||
jumper.setControlPoint(point1, 0);
|
||||
jumper.setControlPoint(point2, 1);
|
||||
component = jumper;
|
||||
} else if (nodeName.equalsIgnoreCase("wire")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
HookupWire wire = new HookupWire();
|
||||
Point midPoint = new Point((point1.x + point2.x) / 2, (point1.y + point2.y) / 2);
|
||||
wire.setName(nameAttr);
|
||||
wire.setControlPoint(point1, 0);
|
||||
wire.setControlPoint(midPoint, 1);
|
||||
wire.setControlPoint(midPoint, 2);
|
||||
wire.setControlPoint(point2, 3);
|
||||
component = wire;
|
||||
} else if (nodeName.equalsIgnoreCase("resistor")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
Resistor resistor = new Resistor();
|
||||
resistor.setName(nameAttr);
|
||||
try {
|
||||
resistor.setValue(Resistance.parseResistance(valueAttr));
|
||||
} catch (Exception e) {
|
||||
LOG.debug("Could not set value of " + nameAttr);
|
||||
}
|
||||
resistor.setLength(new Size(6d, SizeUnit.mm));
|
||||
resistor.setWidth(new Size(2d, SizeUnit.mm));
|
||||
resistor.setControlPoint(point1, 0);
|
||||
resistor.setControlPoint(point2, 1);
|
||||
component = resistor;
|
||||
} else if (nodeName.equalsIgnoreCase("capacitor")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
RadialFilmCapacitor capacitor = new RadialFilmCapacitor();
|
||||
capacitor.setName(nameAttr);
|
||||
try {
|
||||
capacitor.setValue(Capacitance.parseCapacitance(valueAttr));
|
||||
} catch (Exception e) {
|
||||
LOG.debug("Could not set value of " + nameAttr);
|
||||
}
|
||||
capacitor.setLength(new Size(6d, SizeUnit.mm));
|
||||
capacitor.setWidth(new Size(2d, SizeUnit.mm));
|
||||
capacitor.setControlPoint(point1, 0);
|
||||
capacitor.setControlPoint(point2, 1);
|
||||
component = capacitor;
|
||||
} else if (nodeName.equalsIgnoreCase("electrolyte")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
RadialElectrolytic capacitor = new RadialElectrolytic();
|
||||
capacitor.setName(nameAttr);
|
||||
try {
|
||||
capacitor.setValue(Capacitance.parseCapacitance(valueAttr));
|
||||
} catch (Exception e) {
|
||||
LOG.debug("Could not set value of " + nameAttr);
|
||||
}
|
||||
String sizeAttr = node.getAttributes().getNamedItem("Size").getNodeValue();
|
||||
if (sizeAttr.equalsIgnoreCase("small")) {
|
||||
capacitor.setLength(new Size(3.5d, SizeUnit.mm));
|
||||
} else if (sizeAttr.equalsIgnoreCase("medium")) {
|
||||
capacitor.setLength(new Size(5d, SizeUnit.mm));
|
||||
} else if (sizeAttr.equalsIgnoreCase("large")) {
|
||||
capacitor.setLength(new Size(7d, SizeUnit.mm));
|
||||
} else {
|
||||
capacitor.setLength(new Size(4d, SizeUnit.mm));
|
||||
}
|
||||
capacitor.setControlPoint(point1, 0);
|
||||
capacitor.setControlPoint(point2, 1);
|
||||
component = capacitor;
|
||||
} else if (nodeName.equalsIgnoreCase("diode")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
DiodePlastic capacitor = new DiodePlastic();
|
||||
capacitor.setName(nameAttr);
|
||||
try {
|
||||
capacitor.setValue(valueAttr);
|
||||
} catch (Exception e) {
|
||||
LOG.debug("Could not set value of " + nameAttr);
|
||||
}
|
||||
capacitor.setLength(new Size(6d, SizeUnit.mm));
|
||||
capacitor.setWidth(new Size(2d, SizeUnit.mm));
|
||||
capacitor.setControlPoint(point1, 0);
|
||||
capacitor.setControlPoint(point2, 1);
|
||||
component = capacitor;
|
||||
} else if (nodeName.equalsIgnoreCase("led")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
LED led = new LED();
|
||||
led.setName(nameAttr);
|
||||
led.setValue(valueAttr);
|
||||
led.setBodyColor(Color.red);
|
||||
led.setBorderColor(Color.red.darker());
|
||||
led.setLength(new Size(3d, SizeUnit.mm));
|
||||
led.setControlPoint(point1, 0);
|
||||
led.setControlPoint(point2, 1);
|
||||
component = led;
|
||||
} else if (nodeName.equalsIgnoreCase("transistor")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
TransistorTO92 transistor = new TransistorTO92();
|
||||
transistor.setName(nameAttr);
|
||||
try {
|
||||
transistor.setValue(valueAttr);
|
||||
} catch (Exception e) {
|
||||
LOG.debug("Could not set value of " + nameAttr);
|
||||
}
|
||||
transistor.setControlPoint(point1, 0);
|
||||
if (point1.y > point2.y) {
|
||||
transistor.setOrientation(Orientation._180);
|
||||
} else if (point1.y < point2.y) {
|
||||
transistor.setOrientation(Orientation.DEFAULT);
|
||||
} else if (point1.x < point2.x) {
|
||||
transistor.setOrientation(Orientation._270);
|
||||
} else if (point1.x > point2.x) {
|
||||
transistor.setOrientation(Orientation._90);
|
||||
}
|
||||
// capacitor.setControlPoint(point2, 1);
|
||||
component = transistor;
|
||||
} else if (nodeName.equalsIgnoreCase("ic")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
DIL_IC ic = new DIL_IC();
|
||||
if (x1Attr + 3 == x2Attr) {
|
||||
if (y1Attr < y2Attr) {
|
||||
ic
|
||||
.setPinCount(DIL_IC.PinCount.valueOf("_" + 2
|
||||
* (y2Attr - y1Attr + 1)));
|
||||
} else {
|
||||
ic.setOrientation(Orientation._180);
|
||||
ic
|
||||
.setPinCount(DIL_IC.PinCount.valueOf("_" + 2
|
||||
* (y1Attr - y2Attr + 1)));
|
||||
}
|
||||
}
|
||||
ic.setName(nameAttr);
|
||||
// Translate control points.
|
||||
for (int j = 0; j < ic.getControlPointCount(); j++) {
|
||||
Point p = new Point(ic.getControlPoint(j));
|
||||
p.translate(point1.x, point1.y);
|
||||
ic.setControlPoint(p, j);
|
||||
}
|
||||
ic.setValue(valueAttr);
|
||||
component = ic;
|
||||
} else {
|
||||
String message = "Could not recognize component type " + nodeName;
|
||||
LOG.debug(message);
|
||||
if (!warnings.contains(message)) {
|
||||
warnings.add(message);
|
||||
}
|
||||
}
|
||||
if (component != null) {
|
||||
project.getComponents().add(component);
|
||||
}
|
||||
}
|
||||
}
|
||||
Collections.sort(project.getComponents(), ComparatorFactory.getInstance()
|
||||
.getComponentZOrderComparator());
|
||||
return project;
|
||||
}
|
||||
|
||||
private Point convertV1CoordinatesToV3Point(Point reference, int x, int y) {
|
||||
Point point = new Point(reference);
|
||||
point.translate((int) (x * Constants.PIXELS_PER_INCH * V1_GRID_SPACING.getValue()),
|
||||
(int) (y * Constants.PIXELS_PER_INCH * V1_GRID_SPACING.getValue()));
|
||||
return point;
|
||||
}
|
||||
|
||||
private Project parseV2File(Element root) {
|
||||
Project project = new Project();
|
||||
String projectName = root.getAttribute("projectName");
|
||||
String credits = root.getAttribute("credits");
|
||||
String width = root.getAttribute("width");
|
||||
String height = root.getAttribute("height");
|
||||
NodeList childNodes = root.getChildNodes();
|
||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||
Node node = childNodes.item(i);
|
||||
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
if (node.getNodeName().equalsIgnoreCase("component")) {
|
||||
LOG.debug(node.getAttributes().getNamedItem("name").getNodeValue());
|
||||
} else {
|
||||
LOG.debug("Unrecognized node name found: " + node.getNodeName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return project;
|
||||
}
|
||||
|
||||
private Project parseV3File(String fileName) throws IOException {
|
||||
Project project;
|
||||
FileInputStream fis = new FileInputStream(fileName);
|
||||
try {
|
||||
project = (Project) xStream.fromXML(fis);
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Could not open with the new xStream, trying the old one");
|
||||
fis.close();
|
||||
fis = new FileInputStream(fileName);
|
||||
project = (Project) xStreamOld.fromXML(fis);
|
||||
}
|
||||
fis.close();
|
||||
return project;
|
||||
}
|
||||
}
|
||||
-870
@@ -1,870 +0,0 @@
|
||||
package org.diylc.swing;
|
||||
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.ClipboardOwner;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.print.PrinterException;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.KeyStroke;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ITask;
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.IView;
|
||||
import org.diylc.core.Theme;
|
||||
import org.diylc.images.IconLoader;
|
||||
import org.diylc.swing.gui.DialogFactory;
|
||||
import org.diylc.swing.gui.editor.PropertyEditorDialog;
|
||||
import org.diylc.swing.plugins.edit.ComponentTransferable;
|
||||
import org.diylc.swing.plugins.file.BomDialog;
|
||||
import org.diylc.swing.plugins.file.BomEntry;
|
||||
import org.diylc.swing.plugins.file.BomMaker;
|
||||
import org.diylc.swing.plugins.file.FileFilterEnum;
|
||||
|
||||
import com.diyfever.gui.ButtonDialog;
|
||||
import com.diyfever.gui.IDrawingProvider;
|
||||
import com.diyfever.gui.export.DrawingExporter;
|
||||
import com.diyfever.gui.miscutils.ConfigurationManager;
|
||||
import com.rits.cloning.Cloner;
|
||||
|
||||
public class ActionFactory {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(ActionFactory.class);
|
||||
|
||||
private static ActionFactory instance;
|
||||
private static Cloner cloner = new Cloner();
|
||||
|
||||
public static ActionFactory getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new ActionFactory();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private ActionFactory() {
|
||||
}
|
||||
|
||||
// File menu actions.
|
||||
|
||||
public NewAction createNewAction(IPlugInPort plugInPort) {
|
||||
return new NewAction(plugInPort);
|
||||
}
|
||||
|
||||
public OpenAction createOpenAction(IPlugInPort plugInPort, ISwingUI swingUI) {
|
||||
return new OpenAction(plugInPort, swingUI);
|
||||
}
|
||||
|
||||
public SaveAction createSaveAction(IPlugInPort plugInPort, ISwingUI swingUI) {
|
||||
return new SaveAction(plugInPort, swingUI);
|
||||
}
|
||||
|
||||
public SaveAsAction createSaveAsAction(IPlugInPort plugInPort, ISwingUI swingUI) {
|
||||
return new SaveAsAction(plugInPort, swingUI);
|
||||
}
|
||||
|
||||
public CreateBomAction createBomAction(IPlugInPort plugInPort) {
|
||||
return new CreateBomAction(plugInPort);
|
||||
}
|
||||
|
||||
public ExportPDFAction createExportPDFAction(IDrawingProvider drawingProvider, ISwingUI swingUI) {
|
||||
return new ExportPDFAction(drawingProvider, swingUI);
|
||||
}
|
||||
|
||||
public ExportPNGAction createExportPNGAction(IDrawingProvider drawingProvider, ISwingUI swingUI) {
|
||||
return new ExportPNGAction(drawingProvider, swingUI);
|
||||
}
|
||||
|
||||
public PrintAction createPrintAction(IDrawingProvider drawingProvider) {
|
||||
return new PrintAction(drawingProvider);
|
||||
}
|
||||
|
||||
public ExitAction createExitAction(IPlugInPort plugInPort) {
|
||||
return new ExitAction(plugInPort);
|
||||
}
|
||||
|
||||
// Edit menu actions.
|
||||
|
||||
public CutAction createCutAction(IPlugInPort plugInPort, Clipboard clipboard,
|
||||
ClipboardOwner clipboardOwner) {
|
||||
return new CutAction(plugInPort, clipboard, clipboardOwner);
|
||||
}
|
||||
|
||||
public CopyAction createCopyAction(IPlugInPort plugInPort, Clipboard clipboard,
|
||||
ClipboardOwner clipboardOwner) {
|
||||
return new CopyAction(plugInPort, clipboard, clipboardOwner);
|
||||
}
|
||||
|
||||
public PasteAction createPasteAction(IPlugInPort plugInPort, Clipboard clipboard) {
|
||||
return new PasteAction(plugInPort, clipboard);
|
||||
}
|
||||
|
||||
public SelectAllAction createSelectAllAction(IPlugInPort plugInPort) {
|
||||
return new SelectAllAction(plugInPort);
|
||||
}
|
||||
|
||||
public GroupAction createGroupAction(IPlugInPort plugInPort) {
|
||||
return new GroupAction(plugInPort);
|
||||
}
|
||||
|
||||
public UngroupAction createUngroupAction(IPlugInPort plugInPort) {
|
||||
return new UngroupAction(plugInPort);
|
||||
}
|
||||
|
||||
public EditProjectAction createEditProjectAction(IPlugInPort plugInPort) {
|
||||
return new EditProjectAction(plugInPort);
|
||||
}
|
||||
|
||||
public EditSelectionAction createEditSelectionAction(IPlugInPort plugInPort) {
|
||||
return new EditSelectionAction(plugInPort);
|
||||
}
|
||||
|
||||
public DeleteSelectionAction createDeleteSelectionAction(IPlugInPort plugInPort) {
|
||||
return new DeleteSelectionAction(plugInPort);
|
||||
}
|
||||
|
||||
public SendToBackAction createSendToBackAction(IPlugInPort plugInPort) {
|
||||
return new SendToBackAction(plugInPort);
|
||||
}
|
||||
|
||||
public BringToFrontAction createBringToFrontAction(IPlugInPort plugInPort) {
|
||||
return new BringToFrontAction(plugInPort);
|
||||
}
|
||||
|
||||
// Config actions.
|
||||
|
||||
public ConfigAction createConfigAction(IPlugInPort plugInPort, String title, String configKey,
|
||||
boolean defaultValue) {
|
||||
return new ConfigAction(plugInPort, title, configKey, defaultValue);
|
||||
}
|
||||
|
||||
public ThemeAction createThemeAction(IPlugInPort plugInPort, Theme theme) {
|
||||
return new ThemeAction(plugInPort, theme);
|
||||
}
|
||||
|
||||
public RenumberAction createRenumberAction(IPlugInPort plugInPort, boolean xAxisFirst) {
|
||||
return new RenumberAction(plugInPort, xAxisFirst);
|
||||
}
|
||||
|
||||
// File menu actions.
|
||||
|
||||
public static class NewAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
|
||||
public NewAction(IPlugInPort plugInPort) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
putValue(AbstractAction.NAME, "New");
|
||||
putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_N,
|
||||
ActionEvent.CTRL_MASK));
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.DocumentPlainYellow.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info("NewAction triggered");
|
||||
if (!plugInPort.allowFileAction()) {
|
||||
return;
|
||||
}
|
||||
plugInPort.createNewProject();
|
||||
List<PropertyWrapper> properties = plugInPort.getProjectProperties();
|
||||
PropertyEditorDialog editor = DialogFactory.getInstance().createPropertyEditorDialog(
|
||||
properties, "Edit Project");
|
||||
editor.setVisible(true);
|
||||
if (ButtonDialog.OK.equals(editor.getSelectedButtonCaption())) {
|
||||
plugInPort.applyPropertiesToProject(properties);
|
||||
}
|
||||
// Save default values.
|
||||
for (PropertyWrapper property : editor.getDefaultedProperties()) {
|
||||
if (property.getValue() != null) {
|
||||
plugInPort.setProjectDefaultPropertyValue(property.getName(), property
|
||||
.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class OpenAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
private ISwingUI swingUI;
|
||||
|
||||
public OpenAction(IPlugInPort plugInPort, ISwingUI swingUI) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
this.swingUI = swingUI;
|
||||
putValue(AbstractAction.NAME, "Open");
|
||||
putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_O,
|
||||
ActionEvent.CTRL_MASK));
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.FolderOut.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info("OpenAction triggered");
|
||||
if (!plugInPort.allowFileAction()) {
|
||||
return;
|
||||
}
|
||||
final File file = DialogFactory.getInstance().showOpenDialog(
|
||||
FileFilterEnum.DIY.getFilter(), null, FileFilterEnum.DIY.getExtensions()[0],
|
||||
null);
|
||||
if (file != null) {
|
||||
swingUI.executeBackgroundTask(new ITask<Void>() {
|
||||
|
||||
@Override
|
||||
public Void doInBackground() throws Exception {
|
||||
LOG.debug("Opening from " + file.getAbsolutePath());
|
||||
plugInPort.loadProjectFromFile(file.getAbsolutePath());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void complete(Void result) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Exception e) {
|
||||
swingUI.showMessage("Could not open file. " + e.getMessage(), "Error",
|
||||
ISwingUI.ERROR_MESSAGE);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class SaveAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
private ISwingUI swingUI;
|
||||
|
||||
public SaveAction(IPlugInPort plugInPort, ISwingUI swingUI) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
this.swingUI = swingUI;
|
||||
putValue(AbstractAction.NAME, "Save");
|
||||
putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S,
|
||||
ActionEvent.CTRL_MASK));
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.DiskBlue.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info("SaveAction triggered");
|
||||
if (plugInPort.getCurrentFileName() == null) {
|
||||
final File file = DialogFactory.getInstance().showSaveDialog(
|
||||
FileFilterEnum.DIY.getFilter(), null,
|
||||
FileFilterEnum.DIY.getExtensions()[0], null);
|
||||
if (file != null) {
|
||||
swingUI.executeBackgroundTask(new ITask<Void>() {
|
||||
|
||||
@Override
|
||||
public Void doInBackground() throws Exception {
|
||||
LOG.debug("Saving to " + file.getAbsolutePath());
|
||||
plugInPort.saveProjectToFile(file.getAbsolutePath(), false);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void complete(Void result) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Exception e) {
|
||||
swingUI.showMessage("Could not save to file. " + e.getMessage(),
|
||||
"Error", ISwingUI.ERROR_MESSAGE);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
swingUI.executeBackgroundTask(new ITask<Void>() {
|
||||
|
||||
@Override
|
||||
public Void doInBackground() throws Exception {
|
||||
LOG.debug("Saving to " + plugInPort.getCurrentFileName());
|
||||
plugInPort.saveProjectToFile(plugInPort.getCurrentFileName(), false);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void complete(Void result) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Exception e) {
|
||||
swingUI.showMessage("Could not save to file. " + e.getMessage(), "Error",
|
||||
ISwingUI.ERROR_MESSAGE);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class SaveAsAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
private ISwingUI swingUI;
|
||||
|
||||
public SaveAsAction(IPlugInPort plugInPort, ISwingUI swingUI) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
this.swingUI = swingUI;
|
||||
putValue(AbstractAction.NAME, "Save As");
|
||||
putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S,
|
||||
ActionEvent.CTRL_MASK | ActionEvent.SHIFT_MASK));
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.DiskBlue.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info("SaveAsAction triggered");
|
||||
final File file = DialogFactory.getInstance().showSaveDialog(
|
||||
FileFilterEnum.DIY.getFilter(), null, FileFilterEnum.DIY.getExtensions()[0],
|
||||
null);
|
||||
if (file != null) {
|
||||
swingUI.executeBackgroundTask(new ITask<Void>() {
|
||||
|
||||
@Override
|
||||
public Void doInBackground() throws Exception {
|
||||
LOG.debug("Saving to " + file.getAbsolutePath());
|
||||
plugInPort.saveProjectToFile(file.getAbsolutePath(), false);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void complete(Void result) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Exception e) {
|
||||
swingUI.showMessage("Could not save to file. " + e.getMessage(), "Error",
|
||||
ISwingUI.ERROR_MESSAGE);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class CreateBomAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
|
||||
public CreateBomAction(IPlugInPort plugInPort) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
putValue(AbstractAction.NAME, "Create B.O.M.");
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.BOM.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info("CreateBomAction triggered");
|
||||
List<BomEntry> bom = BomMaker.getInstance().createBom(
|
||||
plugInPort.getCurrentProject().getComponents());
|
||||
BomDialog dialog = DialogFactory.getInstance().createBomDialog(bom);
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExportPDFAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IDrawingProvider drawingProvider;
|
||||
private ISwingUI swingUI;
|
||||
|
||||
public ExportPDFAction(IDrawingProvider drawingProvider, ISwingUI swingUI) {
|
||||
super();
|
||||
this.drawingProvider = drawingProvider;
|
||||
this.swingUI = swingUI;
|
||||
putValue(AbstractAction.NAME, "Export to PDF");
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.PDF.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info("ExportPDFAction triggered");
|
||||
final File file = DialogFactory.getInstance().showSaveDialog(
|
||||
FileFilterEnum.PDF.getFilter(), null, FileFilterEnum.PDF.getExtensions()[0],
|
||||
null);
|
||||
if (file != null) {
|
||||
swingUI.executeBackgroundTask(new ITask<Void>() {
|
||||
|
||||
@Override
|
||||
public Void doInBackground() throws Exception {
|
||||
LOG.debug("Exporting to " + file.getAbsolutePath());
|
||||
DrawingExporter.getInstance().exportPDF(
|
||||
ExportPDFAction.this.drawingProvider, file);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void complete(Void result) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Exception e) {
|
||||
swingUI.showMessage("Could not export to PDF. " + e.getMessage(), "Error",
|
||||
ISwingUI.ERROR_MESSAGE);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExportPNGAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IDrawingProvider drawingProvider;
|
||||
private ISwingUI swingUI;
|
||||
|
||||
public ExportPNGAction(IDrawingProvider drawingProvider, ISwingUI swingUI) {
|
||||
super();
|
||||
this.drawingProvider = drawingProvider;
|
||||
this.swingUI = swingUI;
|
||||
putValue(AbstractAction.NAME, "Export to PNG");
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.Image.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info("ExportPNGAction triggered");
|
||||
final File file = DialogFactory.getInstance().showSaveDialog(
|
||||
FileFilterEnum.PNG.getFilter(), null, FileFilterEnum.PNG.getExtensions()[0],
|
||||
null);
|
||||
if (file != null) {
|
||||
swingUI.executeBackgroundTask(new ITask<Void>() {
|
||||
|
||||
@Override
|
||||
public Void doInBackground() throws Exception {
|
||||
LOG.debug("Exporting to " + file.getAbsolutePath());
|
||||
DrawingExporter.getInstance().exportPNG(
|
||||
ExportPNGAction.this.drawingProvider, file);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void complete(Void result) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Exception e) {
|
||||
swingUI.showMessage("Could not export to PNG. " + e.getMessage(), "Error",
|
||||
ISwingUI.ERROR_MESSAGE);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class PrintAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IDrawingProvider drawingProvider;
|
||||
|
||||
public PrintAction(IDrawingProvider drawingProvider) {
|
||||
super();
|
||||
this.drawingProvider = drawingProvider;
|
||||
putValue(AbstractAction.NAME, "Print...");
|
||||
putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_P,
|
||||
ActionEvent.CTRL_MASK));
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.Print.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info("ExportPNGAction triggered");
|
||||
try {
|
||||
DrawingExporter.getInstance().print(this.drawingProvider);
|
||||
} catch (PrinterException e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExitAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
|
||||
public ExitAction(IPlugInPort plugInPort) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
putValue(AbstractAction.NAME, "Exit");
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.Exit.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (plugInPort.allowFileAction()) {
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Edit menu actions.
|
||||
|
||||
public static class CutAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
private Clipboard clipboard;
|
||||
private ClipboardOwner clipboardOwner;
|
||||
|
||||
public CutAction(IPlugInPort plugInPort, Clipboard clipboard, ClipboardOwner clipboardOwner) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
this.clipboard = clipboard;
|
||||
this.clipboardOwner = clipboardOwner;
|
||||
putValue(AbstractAction.NAME, "Cut");
|
||||
putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_X,
|
||||
ActionEvent.CTRL_MASK));
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.Cut.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info("Cut triggered");
|
||||
clipboard.setContents(new ComponentTransferable(cloner.deepClone(plugInPort
|
||||
.getSelectedComponents())), clipboardOwner);
|
||||
plugInPort.deleteSelectedComponents();
|
||||
}
|
||||
}
|
||||
|
||||
public static class CopyAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
private Clipboard clipboard;
|
||||
private ClipboardOwner clipboardOwner;
|
||||
|
||||
public CopyAction(IPlugInPort plugInPort, Clipboard clipboard, ClipboardOwner clipboardOwner) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
this.clipboard = clipboard;
|
||||
this.clipboardOwner = clipboardOwner;
|
||||
putValue(AbstractAction.NAME, "Copy");
|
||||
putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_C,
|
||||
ActionEvent.CTRL_MASK));
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.Copy.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info("Copy triggered");
|
||||
clipboard.setContents(new ComponentTransferable(cloner.deepClone(plugInPort
|
||||
.getSelectedComponents())), clipboardOwner);
|
||||
}
|
||||
}
|
||||
|
||||
public static class PasteAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
private Clipboard clipboard;
|
||||
|
||||
public PasteAction(IPlugInPort plugInPort, Clipboard clipboard) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
this.clipboard = clipboard;
|
||||
putValue(AbstractAction.NAME, "Paste");
|
||||
putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_V,
|
||||
ActionEvent.CTRL_MASK));
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.Paste.getIcon());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info("Paste triggered");
|
||||
try {
|
||||
List<IDIYComponent<?>> components = (List<IDIYComponent<?>>) clipboard
|
||||
.getData(ComponentTransferable.listFlavor);
|
||||
plugInPort.pasteComponents(cloner.deepClone(components));
|
||||
} catch (Exception ex) {
|
||||
LOG.error("Coule not paste.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class SelectAllAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
|
||||
public SelectAllAction(IPlugInPort plugInPort) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
putValue(AbstractAction.NAME, "Select All");
|
||||
putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_A,
|
||||
ActionEvent.CTRL_MASK));
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.Selection.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info("Select All triggered");
|
||||
plugInPort.selectAll();
|
||||
}
|
||||
}
|
||||
|
||||
public static class GroupAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
|
||||
public GroupAction(IPlugInPort plugInPort) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
putValue(AbstractAction.NAME, "Group Selection");
|
||||
putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_G,
|
||||
ActionEvent.CTRL_MASK));
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.Group.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info("Group Selection triggered");
|
||||
plugInPort.groupSelectedComponents();
|
||||
}
|
||||
}
|
||||
|
||||
public static class UngroupAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
|
||||
public UngroupAction(IPlugInPort plugInPort) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
putValue(AbstractAction.NAME, "Ungroup Selection");
|
||||
putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_U,
|
||||
ActionEvent.CTRL_MASK));
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.Ungroup.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info("Ungroup Selection triggered");
|
||||
plugInPort.ungroupSelectedComponents();
|
||||
}
|
||||
}
|
||||
|
||||
public static class EditProjectAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
|
||||
public EditProjectAction(IPlugInPort plugInPort) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
putValue(AbstractAction.NAME, "Edit Project");
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.DocumentEdit.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info("Edit Project triggered");
|
||||
List<PropertyWrapper> properties = plugInPort.getProjectProperties();
|
||||
PropertyEditorDialog editor = DialogFactory.getInstance().createPropertyEditorDialog(
|
||||
properties, "Edit Project");
|
||||
editor.setVisible(true);
|
||||
if (ButtonDialog.OK.equals(editor.getSelectedButtonCaption())) {
|
||||
plugInPort.applyPropertiesToProject(properties);
|
||||
}
|
||||
// Save default values.
|
||||
for (PropertyWrapper property : editor.getDefaultedProperties()) {
|
||||
if (property.getValue() != null) {
|
||||
plugInPort.setProjectDefaultPropertyValue(property.getName(), property
|
||||
.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class EditSelectionAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
|
||||
public EditSelectionAction(IPlugInPort plugInPort) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
putValue(AbstractAction.NAME, "Edit Selection");
|
||||
putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_E,
|
||||
ActionEvent.CTRL_MASK));
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.EditComponent.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info("Edit Selection triggered");
|
||||
List<PropertyWrapper> properties = plugInPort.getMutualSelectionProperties();
|
||||
if (properties == null || properties.isEmpty()) {
|
||||
LOG.info("Nothing to edit");
|
||||
return;
|
||||
}
|
||||
plugInPort.editSelection();
|
||||
}
|
||||
}
|
||||
|
||||
public static class DeleteSelectionAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
|
||||
public DeleteSelectionAction(IPlugInPort plugInPort) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
putValue(AbstractAction.NAME, "Delete Selection");
|
||||
putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.Delete.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info("Delete Selection triggered");
|
||||
plugInPort.deleteSelectedComponents();
|
||||
}
|
||||
}
|
||||
|
||||
public static class SendToBackAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
|
||||
public SendToBackAction(IPlugInPort plugInPort) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
putValue(AbstractAction.NAME, "Send Backward");
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.Back.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info("Send to Back triggered");
|
||||
plugInPort.sendSelectionToBack();
|
||||
}
|
||||
}
|
||||
|
||||
public static class BringToFrontAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
|
||||
public BringToFrontAction(IPlugInPort plugInPort) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
putValue(AbstractAction.NAME, "Bring Forward");
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.Front.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info("Bring to Front triggered");
|
||||
plugInPort.bringSelectionToFront();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ConfigAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
private String configKey;
|
||||
|
||||
public ConfigAction(IPlugInPort plugInPort, String title, String configKey,
|
||||
boolean defaultValue) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
this.configKey = configKey;
|
||||
putValue(AbstractAction.NAME, title);
|
||||
putValue(IView.CHECK_BOX_MENU_ITEM, true);
|
||||
putValue(AbstractAction.SELECTED_KEY, ConfigurationManager.getInstance().readBoolean(
|
||||
configKey, defaultValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info(getValue(AbstractAction.NAME) + " triggered");
|
||||
ConfigurationManager.getInstance().writeValue(configKey,
|
||||
getValue(AbstractAction.SELECTED_KEY));
|
||||
plugInPort.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ThemeAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
private Theme theme;
|
||||
|
||||
public ThemeAction(IPlugInPort plugInPort, Theme theme) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
this.theme = theme;
|
||||
putValue(AbstractAction.NAME, theme.getName());
|
||||
putValue(IView.RADIO_BUTTON_GROUP_KEY, "theme");
|
||||
putValue(AbstractAction.SELECTED_KEY, plugInPort.getSelectedTheme().getName().equals(
|
||||
theme.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info(getValue(AbstractAction.NAME) + " triggered");
|
||||
plugInPort.setSelectedTheme(theme);
|
||||
}
|
||||
}
|
||||
|
||||
public static class RenumberAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
private boolean xAxisFirst;
|
||||
|
||||
public RenumberAction(IPlugInPort plugInPort, boolean xAxisFirst) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
this.xAxisFirst = xAxisFirst;
|
||||
putValue(AbstractAction.NAME, xAxisFirst ? "X Axis First" : "Y Axis First");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info(getValue(AbstractAction.NAME) + " triggered");
|
||||
plugInPort.renumberSelectedComponents(xAxisFirst);
|
||||
}
|
||||
}
|
||||
}
|
||||
-64
@@ -1,64 +0,0 @@
|
||||
package org.diylc.swing;
|
||||
|
||||
import javax.swing.Action;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.JPopupMenu.Separator;
|
||||
|
||||
import org.diylc.common.BadPositionException;
|
||||
import org.diylc.common.ITask;
|
||||
import org.diylc.core.IView;
|
||||
|
||||
/**
|
||||
* Interface for plugin access to the swing front end.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public interface ISwingUI extends IView {
|
||||
|
||||
/**
|
||||
* Injects a custom GUI panels provided by the plug-in and desired position
|
||||
* in the window. Application will layout plug-in panels accordingly. <br>
|
||||
* Valid positions are:
|
||||
* <ul>
|
||||
* <li> {@link SwingConstants#TOP}</li>
|
||||
* <li> {@link SwingConstants#BOTTOM}</li>
|
||||
* <li> {@link SwingConstants#LEFT}</li>
|
||||
* <li> {@link SwingConstants#RIGHT}</li>
|
||||
* </ul>
|
||||
*
|
||||
* Center position is reserved for the main canvas panel and cannot be used.
|
||||
*
|
||||
* @param component
|
||||
* @param position
|
||||
* @throws BadPositionException
|
||||
* in case invalid position is specified
|
||||
*/
|
||||
void injectGUIComponent(JComponent component, int position) throws BadPositionException;
|
||||
|
||||
/**
|
||||
* Injects a custom menu action into application's main menu. If
|
||||
* <code>action</code> is set to null {@link Separator} will be added. If
|
||||
* the specified menu does not exist it will be automatically created.
|
||||
*
|
||||
* @param action
|
||||
* {@link Action} to inser
|
||||
* @param menuName
|
||||
* name of the menu to insert into
|
||||
*/
|
||||
void injectMenuAction(Action action, String menuName);
|
||||
|
||||
/**
|
||||
* Injects a custom submenu into application's main menu. If
|
||||
* <code>action</code> is set to null {@link Separator} will be added. If
|
||||
* the specified menu does not exist it will be automatically created.
|
||||
*
|
||||
* @param name
|
||||
* @param icon
|
||||
* @param parentMenuName
|
||||
*/
|
||||
void injectSubmenu(String name, Icon icon, String parentMenuName);
|
||||
|
||||
<T extends Object> void executeBackgroundTask(ITask<T> task);
|
||||
}
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
package org.diylc.swing.gui;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseMotionAdapter;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JComponent;
|
||||
|
||||
public class CustomGlassPane extends JComponent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Icon icon;
|
||||
|
||||
public CustomGlassPane() {
|
||||
super();
|
||||
addMouseMotionListener(new MouseMotionAdapter() {
|
||||
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
if (icon != null) {
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setCursorIcon(Icon icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
Point cursor = getMousePosition();
|
||||
if ((icon != null) && (cursor != null)) {
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
icon.paintIcon(this, g2d, cursor.x + 10, cursor.y + 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
-155
@@ -1,155 +0,0 @@
|
||||
package org.diylc.swing.gui;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.swing.gui.components.OverwritePromptFileChooser;
|
||||
import org.diylc.swing.gui.editor.PropertyEditorDialog;
|
||||
import org.diylc.swing.plugins.file.BomDialog;
|
||||
import org.diylc.swing.plugins.file.BomEntry;
|
||||
import org.diylc.swing.plugins.online.view.LoginDialog;
|
||||
import org.diylc.swing.plugins.online.view.NewUserDialog;
|
||||
import org.diylc.swing.plugins.online.view.UploadDialog;
|
||||
|
||||
import com.diyfever.gui.AboutDialog;
|
||||
import com.diyfever.gui.IFileChooserAccessory;
|
||||
import com.diyfever.gui.ProgressDialog;
|
||||
import com.diyfever.gui.miscutils.ConfigurationManager;
|
||||
|
||||
public class DialogFactory {
|
||||
|
||||
private static DialogFactory instance;
|
||||
|
||||
private static final String PATH_KEY = "lastPath";
|
||||
|
||||
public static DialogFactory getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new DialogFactory();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private JFrame mainFrame;
|
||||
private File lastDirectory;
|
||||
|
||||
private DialogFactory() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the frame to be used as dialog parent. This should be called prior
|
||||
* to any other methods in this class.
|
||||
*
|
||||
* @param mainFrame
|
||||
*/
|
||||
public void initialize(JFrame mainFrame) {
|
||||
this.mainFrame = mainFrame;
|
||||
String lastDirectoryPath = (String) ConfigurationManager.getInstance()
|
||||
.readString(PATH_KEY, null);
|
||||
if (lastDirectoryPath != null) {
|
||||
lastDirectory = new File(lastDirectoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
public PropertyEditorDialog createPropertyEditorDialog(List<PropertyWrapper> properties,
|
||||
String title) {
|
||||
PropertyEditorDialog editor = new PropertyEditorDialog(mainFrame, properties, title);
|
||||
return editor;
|
||||
}
|
||||
|
||||
public BomDialog createBomDialog(List<BomEntry> bom) {
|
||||
BomDialog dialog = new BomDialog(mainFrame, bom);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public File showOpenDialog(FileFilter fileFilter, File initialFile, String defaultExtension,
|
||||
IFileChooserAccessory accessory) {
|
||||
JFileChooser openFileChooser = new JFileChooser();
|
||||
initializeFileChooser(openFileChooser, fileFilter, initialFile, defaultExtension, accessory);
|
||||
|
||||
int result = openFileChooser.showOpenDialog(mainFrame);
|
||||
|
||||
return processFileChooserResult(result, openFileChooser, defaultExtension);
|
||||
}
|
||||
|
||||
public File showSaveDialog(FileFilter fileFilter, File initialFile, String defaultExtension,
|
||||
IFileChooserAccessory accessory) {
|
||||
JFileChooser saveFileChooser = new OverwritePromptFileChooser();
|
||||
initializeFileChooser(saveFileChooser, fileFilter, initialFile, defaultExtension, accessory);
|
||||
|
||||
int result = saveFileChooser.showSaveDialog(mainFrame);
|
||||
|
||||
return processFileChooserResult(result, saveFileChooser, defaultExtension);
|
||||
}
|
||||
|
||||
private void initializeFileChooser(JFileChooser fileChooser, FileFilter fileFilter,
|
||||
File initialFile, String defaultExtension, IFileChooserAccessory accessory) {
|
||||
if (accessory != null) {
|
||||
accessory.install(fileChooser);
|
||||
}
|
||||
for (FileFilter filter : fileChooser.getChoosableFileFilters()) {
|
||||
fileChooser.removeChoosableFileFilter(filter);
|
||||
}
|
||||
if (fileChooser instanceof OverwritePromptFileChooser) {
|
||||
((OverwritePromptFileChooser) fileChooser).setFileFilter(fileFilter, defaultExtension);
|
||||
} else {
|
||||
fileChooser.setFileFilter(fileFilter);
|
||||
}
|
||||
if (lastDirectory != null) {
|
||||
fileChooser.setCurrentDirectory(lastDirectory);
|
||||
}
|
||||
fileChooser.setSelectedFile(initialFile);
|
||||
}
|
||||
|
||||
private File processFileChooserResult(int result, JFileChooser fileChooser,
|
||||
String defaultExtension) {
|
||||
fileChooser.setAccessory(null);
|
||||
if (result == JFileChooser.APPROVE_OPTION) {
|
||||
lastDirectory = fileChooser.getCurrentDirectory();
|
||||
ConfigurationManager.getInstance().writeValue(PATH_KEY,
|
||||
lastDirectory.getAbsolutePath());
|
||||
if (fileChooser.getSelectedFile().getAbsolutePath().contains(".")) {
|
||||
return fileChooser.getSelectedFile();
|
||||
} else {
|
||||
return new File(fileChooser.getSelectedFile().getAbsoluteFile() + "."
|
||||
+ defaultExtension);
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public AboutDialog createAboutDialog(String appName, Icon icon, String version, String author,
|
||||
String url, String mail, String htmlContent) {
|
||||
AboutDialog dialog = new AboutDialog(mainFrame, appName, icon, version, author, url, mail,
|
||||
htmlContent);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public NewUserDialog createNewUserDialog() {
|
||||
NewUserDialog dialog = new NewUserDialog(mainFrame);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public LoginDialog createLoginDialog() {
|
||||
LoginDialog dialog = new LoginDialog(mainFrame);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public UploadDialog createUploadDialog() {
|
||||
UploadDialog dialog = new UploadDialog(mainFrame);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public ProgressDialog createProgressDialog(String title, String[] buttonCaptions,
|
||||
String description, boolean useProgress) {
|
||||
ProgressDialog dialog = new ProgressDialog(mainFrame, title, buttonCaptions, description,
|
||||
useProgress);
|
||||
return dialog;
|
||||
}
|
||||
}
|
||||
-370
@@ -1,370 +0,0 @@
|
||||
package org.diylc.swing.gui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Container;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.swing.Action;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.ButtonGroup;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JCheckBoxMenuItem;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JRadioButtonMenuItem;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.Timer;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.common.BadPositionException;
|
||||
import org.diylc.common.EventType;
|
||||
import org.diylc.common.IPlugIn;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ITask;
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.core.IView;
|
||||
import org.diylc.images.IconLoader;
|
||||
import org.diylc.presenter.Presenter;
|
||||
import org.diylc.swing.ISwingUI;
|
||||
import org.diylc.swing.gui.editor.PropertyEditorDialog;
|
||||
import org.diylc.swing.plugins.autosave.AutoSavePlugin;
|
||||
import org.diylc.swing.plugins.canvas.CanvasPlugin;
|
||||
import org.diylc.swing.plugins.config.ConfigPlugin;
|
||||
import org.diylc.swing.plugins.edit.EditMenuPlugin;
|
||||
import org.diylc.swing.plugins.file.FileMenuPlugin;
|
||||
import org.diylc.swing.plugins.help.HelpMenuPlugin;
|
||||
import org.diylc.swing.plugins.layers.LayersMenuPlugin;
|
||||
import org.diylc.swing.plugins.statusbar.StatusBar;
|
||||
import org.diylc.swing.plugins.toolbox.ToolBox;
|
||||
|
||||
import com.diyfever.gui.ButtonDialog;
|
||||
import com.diyfever.gui.miscutils.ConfigurationManager;
|
||||
|
||||
public class MainFrame extends JFrame implements ISwingUI {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(MainFrame.class);
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private JPanel centerPanel;
|
||||
private JPanel leftPanel;
|
||||
private JPanel rightPanel;
|
||||
private JPanel topPanel;
|
||||
private JPanel bottomPanel;
|
||||
|
||||
private Presenter presenter;
|
||||
|
||||
private JMenuBar mainMenuBar;
|
||||
private Map<String, JMenu> menuMap;
|
||||
private Map<String, ButtonGroup> buttonGroupMap;
|
||||
|
||||
private CanvasPlugin canvasPlugin;
|
||||
|
||||
public MainFrame() {
|
||||
super("DIYLC 3");
|
||||
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
||||
setPreferredSize(new Dimension(800, 600));
|
||||
createBasePanels();
|
||||
menuMap = new HashMap<String, JMenu>();
|
||||
buttonGroupMap = new HashMap<String, ButtonGroup>();
|
||||
setIconImages(Arrays.asList(IconLoader.IconSmall.getImage(), IconLoader.IconMedium
|
||||
.getImage(), IconLoader.IconLarge.getImage()));
|
||||
DialogFactory.getInstance().initialize(this);
|
||||
|
||||
this.presenter = new Presenter(this);
|
||||
|
||||
presenter.installPlugin(new ToolBox(this));
|
||||
presenter.installPlugin(new FileMenuPlugin(this));
|
||||
presenter.installPlugin(new EditMenuPlugin(this));
|
||||
presenter.installPlugin(new ConfigPlugin(this));
|
||||
presenter.installPlugin(new LayersMenuPlugin(this));
|
||||
// presenter.installPlugin(new OnlineManager());
|
||||
presenter.installPlugin(new HelpMenuPlugin(this));
|
||||
|
||||
presenter.installPlugin(new StatusBar(this));
|
||||
canvasPlugin = new CanvasPlugin(this);
|
||||
presenter.installPlugin(canvasPlugin);
|
||||
presenter.installPlugin(new FramePlugin());
|
||||
|
||||
try {
|
||||
File testFile = new File("test.tmp");
|
||||
Writer out = new OutputStreamWriter(new FileOutputStream(testFile));
|
||||
out.write("This is a test");
|
||||
out.close();
|
||||
testFile.delete();
|
||||
presenter.installPlugin(new AutoSavePlugin(this));
|
||||
} catch (Exception e) {
|
||||
showMessage(
|
||||
"The current user does not have permissions to access folder "
|
||||
+ new File(".").getAbsolutePath()
|
||||
+ ".\nAuto-save feature will not be available, contact your system administrator.",
|
||||
"Warning", IView.WARNING_MESSAGE);
|
||||
}
|
||||
|
||||
presenter.createNewProject();
|
||||
|
||||
addWindowListener(new WindowAdapter() {
|
||||
|
||||
@Override
|
||||
public void windowClosed(WindowEvent e) {
|
||||
if (presenter.allowFileAction()) {
|
||||
ConfigurationManager.getInstance().writeValue(IPlugInPort.ABNORMAL_EXIT_KEY,
|
||||
false);
|
||||
dispose();
|
||||
presenter.dispose();
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
if (presenter.allowFileAction()) {
|
||||
ConfigurationManager.getInstance().writeValue(IPlugInPort.ABNORMAL_EXIT_KEY,
|
||||
false);
|
||||
dispose();
|
||||
presenter.dispose();
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// setGlassPane(new CustomGlassPane());
|
||||
// getGlassPane().setVisible(true);
|
||||
}
|
||||
|
||||
public Presenter getPresenter() {
|
||||
return presenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean b) {
|
||||
super.setVisible(b);
|
||||
// TODO: hack to prevent painting issues in the scroll bar rulers. Find
|
||||
// a better fix if possible.
|
||||
Timer timer = new Timer(500, new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
canvasPlugin.refresh();
|
||||
}
|
||||
|
||||
});
|
||||
timer.setRepeats(false);
|
||||
timer.start();
|
||||
// if (b) {
|
||||
// SwingUtilities.invokeLater(new Runnable() {
|
||||
// @Override
|
||||
// public void run() {
|
||||
//
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
private void createBasePanels() {
|
||||
Container c = new Container();
|
||||
c.setLayout(new BorderLayout());
|
||||
|
||||
centerPanel = new JPanel(new BorderLayout());
|
||||
c.add(centerPanel, BorderLayout.CENTER);
|
||||
|
||||
topPanel = new JPanel();
|
||||
topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));
|
||||
c.add(topPanel, BorderLayout.NORTH);
|
||||
|
||||
leftPanel = new JPanel();
|
||||
leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.X_AXIS));
|
||||
c.add(leftPanel, BorderLayout.WEST);
|
||||
|
||||
bottomPanel = new JPanel();
|
||||
bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.Y_AXIS));
|
||||
c.add(bottomPanel, BorderLayout.SOUTH);
|
||||
|
||||
rightPanel = new JPanel();
|
||||
rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.X_AXIS));
|
||||
c.add(rightPanel, BorderLayout.EAST);
|
||||
|
||||
setContentPane(c);
|
||||
}
|
||||
|
||||
private JMenuBar getMainMenuBar() {
|
||||
if (mainMenuBar == null) {
|
||||
mainMenuBar = new JMenuBar();
|
||||
setJMenuBar(mainMenuBar);
|
||||
}
|
||||
return mainMenuBar;
|
||||
}
|
||||
|
||||
// IView
|
||||
|
||||
@Override
|
||||
public void showMessage(String message, String title, int messageType) {
|
||||
JOptionPane.showMessageDialog(this, message, title, messageType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int showConfirmDialog(String message, String title, int optionType, int messageType) {
|
||||
return JOptionPane.showConfirmDialog(this, message, title, optionType, messageType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean editProperties(List<PropertyWrapper> properties,
|
||||
Set<PropertyWrapper> defaultedProperties) {
|
||||
PropertyEditorDialog editor = DialogFactory.getInstance().createPropertyEditorDialog(
|
||||
properties, "Edit Selection");
|
||||
editor.setVisible(true);
|
||||
defaultedProperties.addAll(editor.getDefaultedProperties());
|
||||
return ButtonDialog.OK.equals(editor.getSelectedButtonCaption());
|
||||
}
|
||||
|
||||
private JMenu findOrCreateMenu(String menuName) {
|
||||
JMenu menu;
|
||||
if (menuMap.containsKey(menuName)) {
|
||||
menu = menuMap.get(menuName);
|
||||
} else {
|
||||
menu = new JMenu(menuName);
|
||||
menuMap.put(menuName, menu);
|
||||
getMainMenuBar().add(menu);
|
||||
}
|
||||
return menu;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectGUIComponent(JComponent component, int position) throws BadPositionException {
|
||||
LOG.info(String.format("injectGUIComponent(%s, %s)", component.getClass().getName(),
|
||||
position));
|
||||
switch (position) {
|
||||
case SwingConstants.TOP:
|
||||
topPanel.add(component);
|
||||
break;
|
||||
case SwingConstants.LEFT:
|
||||
leftPanel.add(component);
|
||||
break;
|
||||
case SwingConstants.BOTTOM:
|
||||
bottomPanel.add(component);
|
||||
break;
|
||||
case SwingConstants.RIGHT:
|
||||
rightPanel.add(component);
|
||||
break;
|
||||
case SwingConstants.CENTER:
|
||||
centerPanel.add(component, BorderLayout.CENTER);
|
||||
break;
|
||||
default:
|
||||
throw new BadPositionException();
|
||||
}
|
||||
pack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectMenuAction(Action action, String menuName) {
|
||||
LOG.info(String.format("injectMenuAction(%s, %s)", action == null ? "Separator" : action
|
||||
.getValue(Action.NAME), menuName));
|
||||
JMenu menu = findOrCreateMenu(menuName);
|
||||
if (action == null) {
|
||||
menu.addSeparator();
|
||||
} else {
|
||||
Boolean isCheckBox = (Boolean) action.getValue(IView.CHECK_BOX_MENU_ITEM);
|
||||
String groupName = (String) action.getValue(IView.RADIO_BUTTON_GROUP_KEY);
|
||||
if (isCheckBox != null && isCheckBox) {
|
||||
menu.add(new JCheckBoxMenuItem(action));
|
||||
} else if (groupName != null) {
|
||||
ButtonGroup group;
|
||||
if (buttonGroupMap.containsKey(groupName)) {
|
||||
group = buttonGroupMap.get(groupName);
|
||||
} else {
|
||||
group = new ButtonGroup();
|
||||
buttonGroupMap.put(groupName, group);
|
||||
}
|
||||
JRadioButtonMenuItem item = new JRadioButtonMenuItem(action);
|
||||
group.add(item);
|
||||
menu.add(item);
|
||||
} else {
|
||||
menu.add(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectSubmenu(String name, Icon icon, String parentMenuName) {
|
||||
LOG.info(String.format("injectSubmenu(%s, icon, %s)", name, parentMenuName));
|
||||
JMenu menu = findOrCreateMenu(parentMenuName);
|
||||
JMenu submenu = new JMenu(name);
|
||||
submenu.setIcon(icon);
|
||||
menu.add(submenu);
|
||||
menuMap.put(name, submenu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Object> void executeBackgroundTask(final ITask<T> task) {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
SwingWorker<T, Void> worker = new SwingWorker<T, Void>() {
|
||||
|
||||
@Override
|
||||
protected T doInBackground() throws Exception {
|
||||
return task.doInBackground();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
try {
|
||||
T result = get();
|
||||
task.complete(result);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Task failed", e);
|
||||
task.failed(e);
|
||||
}
|
||||
setCursor(Cursor.getDefaultCursor());
|
||||
}
|
||||
};
|
||||
worker.execute();
|
||||
}
|
||||
|
||||
class FramePlugin implements IPlugIn {
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
|
||||
@Override
|
||||
public void connect(IPlugInPort plugInPort) {
|
||||
this.plugInPort = plugInPort;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<EventType> getSubscribedEventTypes() {
|
||||
return EnumSet.of(EventType.FILE_STATUS_CHANGED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processMessage(EventType eventType, Object... params) {
|
||||
if (eventType == EventType.FILE_STATUS_CHANGED) {
|
||||
String fileName = (String) params[0];
|
||||
if (fileName == null) {
|
||||
fileName = "Untitled";
|
||||
}
|
||||
String modified = (Boolean) params[1] ? " (modified)" : "";
|
||||
setTitle(String.format("DIYLC %s beta - %s %s", plugInPort
|
||||
.getCurrentVersionNumber(), fileName, modified));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-285
@@ -1,285 +0,0 @@
|
||||
package org.diylc.swing.gui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.DefaultListCellRenderer;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.common.DrawOption;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.core.IView;
|
||||
import org.diylc.presenter.Presenter;
|
||||
|
||||
import com.diyfever.gui.miscutils.ConfigurationManager;
|
||||
|
||||
public class TemplateDialog extends JDialog {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(TemplateDialog.class);
|
||||
|
||||
private static final Dimension panelSize = new Dimension(400, 300);
|
||||
public static final String SHOW_TEMPLATES_KEY = "showTemplatesAtStartup";
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
|
||||
private JList fileList;
|
||||
private JPanel canvasPanel;
|
||||
private Presenter presenter;
|
||||
private List<File> files;
|
||||
private JCheckBox showTemplatesBox;
|
||||
private JPanel mainPanel;
|
||||
private JButton loadButton;
|
||||
private JPanel infoPanel;
|
||||
|
||||
public TemplateDialog(JFrame owner, IPlugInPort plugInPort) {
|
||||
super(owner, "Templates");
|
||||
setModal(true);
|
||||
setResizable(false);
|
||||
this.plugInPort = plugInPort;
|
||||
this.presenter = new Presenter(new IView() {
|
||||
|
||||
@Override
|
||||
public int showConfirmDialog(String message, String title, int optionType,
|
||||
int messageType) {
|
||||
return JOptionPane.showConfirmDialog(TemplateDialog.this, message, title,
|
||||
optionType, messageType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showMessage(String message, String title, int messageType) {
|
||||
JOptionPane.showMessageDialog(TemplateDialog.this, message, title, messageType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean editProperties(List<PropertyWrapper> properties, Set<PropertyWrapper> defaultedProperties) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
// this.presenter.installPlugin(new IPlugIn() {
|
||||
//
|
||||
// @Override
|
||||
// public void connect(IPlugInPort plugInPort) {
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public EnumSet<EventType> getSubscribedEventTypes() {
|
||||
// return EnumSet.of(EventType.REPAINT);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void processMessage(EventType eventType, Object... params) {
|
||||
// if (eventType == EventType.REPAINT) {
|
||||
// getCanvasPanel().repaint();
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
setContentPane(getMainPanel());
|
||||
pack();
|
||||
setLocationRelativeTo(owner);
|
||||
}
|
||||
|
||||
public JPanel getMainPanel() {
|
||||
if (mainPanel == null) {
|
||||
mainPanel = new JPanel(new GridBagLayout());
|
||||
mainPanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
|
||||
|
||||
GridBagConstraints c = new GridBagConstraints();
|
||||
c.gridx = 0;
|
||||
c.gridy = 0;
|
||||
c.weightx = 0;
|
||||
c.weighty = 1;
|
||||
c.weightx = 1;
|
||||
c.gridwidth = 2;
|
||||
c.fill = GridBagConstraints.BOTH;
|
||||
c.insets = new Insets(0, 0, 4, 0);
|
||||
mainPanel.add(getInfoPanel(), c);
|
||||
|
||||
c.gridy = 1;
|
||||
c.weightx = 0;
|
||||
c.gridwidth = 1;
|
||||
c.insets = new Insets(0, 0, 0, 0);
|
||||
JScrollPane scrollPane = new JScrollPane(getFileList());
|
||||
mainPanel.add(scrollPane, c);
|
||||
|
||||
c.gridx = 1;
|
||||
c.weightx = 1;
|
||||
|
||||
JPanel panel = new JPanel(new BorderLayout());
|
||||
panel.setBorder(scrollPane.getBorder());
|
||||
panel.add(getCanvasPanel(), BorderLayout.CENTER);
|
||||
mainPanel.add(panel, c);
|
||||
|
||||
c.gridx = 0;
|
||||
c.gridy = 2;
|
||||
c.weightx = 0;
|
||||
c.weighty = 0;
|
||||
c.anchor = GridBagConstraints.LAST_LINE_START;
|
||||
c.fill = GridBagConstraints.NONE;
|
||||
mainPanel.add(getShowTemplatesBox(), c);
|
||||
|
||||
c.gridx = 1;
|
||||
c.anchor = GridBagConstraints.LAST_LINE_END;
|
||||
c.insets = new Insets(4, 0, 0, 0);
|
||||
mainPanel.add(getLoadButton(), c);
|
||||
}
|
||||
return mainPanel;
|
||||
}
|
||||
|
||||
public JButton getLoadButton() {
|
||||
if (loadButton == null) {
|
||||
loadButton = new JButton("Load Template");
|
||||
loadButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
plugInPort.loadProject(presenter.getCurrentProject(), true);
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
return loadButton;
|
||||
}
|
||||
|
||||
public JPanel getInfoPanel() {
|
||||
if (infoPanel == null) {
|
||||
infoPanel = new JPanel();
|
||||
infoPanel.setBackground(Color.decode("#FFFFCC"));
|
||||
infoPanel.setBorder(new JTextField().getBorder());
|
||||
JLabel infoLabel = new JLabel(
|
||||
"<html>Templates are semi-product layouts that are used as a starting point for your projects.<br>"
|
||||
+ "Pick a templete in the left list and click \"Load Template\" to load it or close this dialog to continue.<br>"
|
||||
+ "You can create your own templates by placing a DIY file into <b>diylc/templates</b> directory.</html>");
|
||||
infoLabel.setOpaque(false);
|
||||
infoPanel.add(infoLabel);
|
||||
}
|
||||
return infoPanel;
|
||||
}
|
||||
|
||||
public JList getFileList() {
|
||||
if (fileList == null) {
|
||||
fileList = new JList(getFiles().toArray());
|
||||
fileList.setPreferredSize(new Dimension(128, -1));
|
||||
fileList.setCellRenderer(new DefaultListCellRenderer() {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList list, Object value, int index,
|
||||
boolean isSelected, boolean cellHasFocus) {
|
||||
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index,
|
||||
isSelected, cellHasFocus);
|
||||
if (value instanceof File) {
|
||||
label.setText(((File) value).getName());
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
});
|
||||
fileList.addListSelectionListener(new ListSelectionListener() {
|
||||
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
File file = (File) fileList.getSelectedValue();
|
||||
if (file != null) {
|
||||
presenter.loadProjectFromFile(file.getAbsolutePath());
|
||||
Dimension dim = presenter.getCanvasDimensions(true);
|
||||
double xFactor = panelSize.getWidth() / dim.getWidth();
|
||||
double yFactor = panelSize.getHeight() / dim.getHeight();
|
||||
presenter.setZoomLevel(Math.min(xFactor, yFactor));
|
||||
getCanvasPanel().repaint();
|
||||
}
|
||||
}
|
||||
});
|
||||
fileList.setSelectedIndex(0);
|
||||
}
|
||||
return fileList;
|
||||
}
|
||||
|
||||
public JCheckBox getShowTemplatesBox() {
|
||||
if (showTemplatesBox == null) {
|
||||
showTemplatesBox = new JCheckBox("Show this dialog at startup");
|
||||
showTemplatesBox.setSelected(true);
|
||||
showTemplatesBox.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
ConfigurationManager.getInstance().writeValue(SHOW_TEMPLATES_KEY,
|
||||
showTemplatesBox.isSelected());
|
||||
}
|
||||
});
|
||||
}
|
||||
return showTemplatesBox;
|
||||
}
|
||||
|
||||
public List<File> getFiles() {
|
||||
if (files == null) {
|
||||
files = new ArrayList<File>();
|
||||
File dir = new File("templates");
|
||||
if (dir.exists()) {
|
||||
for (File f : dir.listFiles()) {
|
||||
if (f.isFile() && f.getName().toLowerCase().endsWith(".diy")) {
|
||||
files.add(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG.debug("Found " + files.size() + " templates");
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
public JPanel getCanvasPanel() {
|
||||
if (canvasPanel == null) {
|
||||
canvasPanel = new JPanel() {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
super.paint(g);
|
||||
// Graphics2D g2d = (Graphics2D) g;
|
||||
// AffineTransform transform = g2d.getTransform();
|
||||
presenter.draw((Graphics2D) g, EnumSet.of(DrawOption.ZOOM,
|
||||
DrawOption.ANTIALIASING), null);
|
||||
// g2d.setTransform(transform);
|
||||
// Rectangle rect = canvasPanel.getBounds();
|
||||
// BorderFactory.createEtchedBorder().paintBorder(canvasPanel,
|
||||
// g, 0, 0,
|
||||
// (int) rect.getWidth(), (int) rect.getHeight());
|
||||
}
|
||||
};
|
||||
canvasPanel.setBackground(Color.white);
|
||||
canvasPanel.setPreferredSize(panelSize);
|
||||
}
|
||||
return canvasPanel;
|
||||
}
|
||||
}
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
package org.diylc.swing.gui.components;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
|
||||
public class OverwritePromptFileChooser extends JFileChooser {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private String defaultExtension;
|
||||
|
||||
public void approveSelection() {
|
||||
File lSelectedFile;
|
||||
if (getSelectedFile().getAbsolutePath().contains(".")) {
|
||||
lSelectedFile = getSelectedFile();
|
||||
} else {
|
||||
lSelectedFile = new File(getSelectedFile().getAbsoluteFile() + "." + defaultExtension);
|
||||
}
|
||||
|
||||
if (lSelectedFile != null && lSelectedFile.exists()) {
|
||||
int lResponse = JOptionPane.showConfirmDialog(this, lSelectedFile.getAbsolutePath()
|
||||
+ " already exists.\nDo you " + "want to replace it?", "Warning",
|
||||
JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
|
||||
|
||||
if (lResponse != JOptionPane.YES_OPTION) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.approveSelection();
|
||||
}
|
||||
|
||||
public void setFileFilter(FileFilter filter, String defaultExtension) {
|
||||
this.defaultExtension = defaultExtension;
|
||||
super.setFileFilter(filter);
|
||||
}
|
||||
}
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
package org.diylc.swing.gui.editor;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JCheckBox;
|
||||
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
public class BooleanEditor extends JCheckBox {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Color oldBg = getBackground();
|
||||
|
||||
public BooleanEditor(final PropertyWrapper property) {
|
||||
super();
|
||||
setSelected((Boolean) property.getValue());
|
||||
addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
property.setChanged(true);
|
||||
setBackground(oldBg);
|
||||
property.setValue(isSelected());
|
||||
}
|
||||
});
|
||||
if (!property.isUnique()) {
|
||||
setBackground(Constants.MULTI_VALUE_COLOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
package org.diylc.swing.gui.editor;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import javax.swing.JSlider;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
public class ByteEditor extends JSlider {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Color oldBg = getBackground();
|
||||
|
||||
public ByteEditor(final PropertyWrapper property) {
|
||||
super();
|
||||
setMinimum(0);
|
||||
setMaximum(127);
|
||||
setValue((Byte) property.getValue());
|
||||
addChangeListener(new ChangeListener() {
|
||||
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
property.setChanged(true);
|
||||
setBackground(oldBg);
|
||||
property.setValue(new Integer(getValue()).byteValue());
|
||||
}
|
||||
});
|
||||
if (!property.isUnique()) {
|
||||
setBackground(Constants.MULTI_VALUE_COLOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
-52
@@ -1,52 +0,0 @@
|
||||
package org.diylc.swing.gui.editor;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JColorChooser;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
|
||||
public class ColorEditor extends JLabel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final String title = "Click to edit";
|
||||
|
||||
public ColorEditor(final PropertyWrapper property) {
|
||||
super(property.isUnique() ? title : ("(multi value) " + title));
|
||||
setOpaque(true);
|
||||
setHorizontalAlignment(SwingConstants.CENTER);
|
||||
setBorder(BorderFactory.createEtchedBorder());
|
||||
setBackground((Color) property.getValue());
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
addMouseListener(new MouseAdapter() {
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
Color newColor = JColorChooser.showDialog(ColorEditor.this, "Choose Color",
|
||||
getBackground());
|
||||
if (newColor != null) {
|
||||
property.setChanged(true);
|
||||
property.setValue(newColor);
|
||||
setBackground(newColor);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackground(Color bg) {
|
||||
if (bg.getRed() < 127 || bg.getBlue() < 127 || bg.getGreen() < 127) {
|
||||
setForeground(Color.white);
|
||||
} else {
|
||||
setForeground(Color.black);
|
||||
}
|
||||
super.setBackground(bg);
|
||||
}
|
||||
}
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
package org.diylc.swing.gui.editor;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.JComboBox;
|
||||
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
public class EnumEditor extends JComboBox {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Color oldBg = getBackground();
|
||||
|
||||
private final PropertyWrapper property;
|
||||
|
||||
public EnumEditor(final PropertyWrapper property) {
|
||||
this.property = property;
|
||||
Object[] values = property.getType().getEnumConstants();
|
||||
setModel(new DefaultComboBoxModel(values));
|
||||
setSelectedItem(property.getValue());
|
||||
addItemListener(new ItemListener() {
|
||||
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (e.getStateChange() == ItemEvent.SELECTED) {
|
||||
property.setChanged(true);
|
||||
setBackground(oldBg);
|
||||
EnumEditor.this.property.setValue(e.getItem());
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!property.isUnique()) {
|
||||
setBackground(Constants.MULTI_VALUE_COLOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
-61
@@ -1,61 +0,0 @@
|
||||
package org.diylc.swing.gui.editor;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Font;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JLabel;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.core.measures.AbstractMeasure;
|
||||
|
||||
public class FieldEditorFactory {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(FieldEditorFactory.class);
|
||||
|
||||
public static Component createFieldEditor(PropertyWrapper property) {
|
||||
if (property.getType().equals(String.class)) {
|
||||
StringEditor editor = new StringEditor(property);
|
||||
return editor;
|
||||
}
|
||||
if (property.getType().equals(Color.class)) {
|
||||
ColorEditor editor = new ColorEditor(property);
|
||||
return editor;
|
||||
}
|
||||
if (AbstractMeasure.class.isAssignableFrom(property.getType())) {
|
||||
MeasureEditor editor = new MeasureEditor(property);
|
||||
return editor;
|
||||
}
|
||||
if (ImageIcon.class.isAssignableFrom(property.getType())) {
|
||||
ImageEditor editor = new ImageEditor(property);
|
||||
return editor;
|
||||
}
|
||||
if (property.getType().isEnum()) {
|
||||
EnumEditor editor = new EnumEditor(property);
|
||||
return editor;
|
||||
}
|
||||
if (Byte.class.isAssignableFrom(property.getType())
|
||||
|| byte.class.isAssignableFrom(property.getType())) {
|
||||
ByteEditor editor = new ByteEditor(property);
|
||||
return editor;
|
||||
}
|
||||
if (Boolean.class.isAssignableFrom(property.getType())
|
||||
|| boolean.class.isAssignableFrom(property.getType())) {
|
||||
BooleanEditor editor = new BooleanEditor(property);
|
||||
return editor;
|
||||
}
|
||||
if (Font.class.isAssignableFrom(property.getType())) {
|
||||
FontEditor editor = new FontEditor(property);
|
||||
return editor;
|
||||
}
|
||||
if (Integer.class.isAssignableFrom(property.getType())
|
||||
|| int.class.isAssignableFrom(property.getType())) {
|
||||
IntEditor editor = new IntEditor(property);
|
||||
return editor;
|
||||
}
|
||||
LOG.error("Unrecognized parameter type: " + property.getType().getName());
|
||||
return new JLabel("Unrecognized");
|
||||
}
|
||||
}
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
package org.diylc.swing.gui.editor;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
import com.diyfever.gui.FontChooserComboBox;
|
||||
|
||||
public class FontEditor extends FontChooserComboBox {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Color oldBg = getBackground();
|
||||
|
||||
private final PropertyWrapper property;
|
||||
|
||||
public FontEditor(final PropertyWrapper property) {
|
||||
this.property = property;
|
||||
setSelectedItem(((Font) property.getValue()).getName());
|
||||
addItemListener(new ItemListener() {
|
||||
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (e.getStateChange() == ItemEvent.SELECTED) {
|
||||
property.setChanged(true);
|
||||
setBackground(oldBg);
|
||||
Font oldFont = (Font) FontEditor.this.property.getValue();
|
||||
Font newFont = new Font(getSelectedItem().toString(), oldFont.getStyle(),
|
||||
oldFont.getSize());
|
||||
FontEditor.this.property.setValue(newFont);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!property.isUnique()) {
|
||||
setBackground(Constants.MULTI_VALUE_COLOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
-46
@@ -1,46 +0,0 @@
|
||||
package org.diylc.swing.gui.editor;
|
||||
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.swing.gui.DialogFactory;
|
||||
import org.diylc.swing.plugins.file.FileFilterEnum;
|
||||
|
||||
public class ImageEditor extends JButton {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final String title = "Click to load image file";
|
||||
|
||||
public ImageEditor(final PropertyWrapper property) {
|
||||
super(property.isUnique() ? title : ("(multi value) " + title));
|
||||
addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(java.awt.event.ActionEvent e) {
|
||||
File file = DialogFactory.getInstance().showOpenDialog(
|
||||
FileFilterEnum.IMAGES.getFilter(), null,
|
||||
FileFilterEnum.IMAGES.getExtensions()[0], null);
|
||||
if (file != null) {
|
||||
property.setChanged(true);
|
||||
ImageIcon image = new ImageIcon(file.getAbsolutePath());
|
||||
property.setValue(image);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public void setBackground(Color bg) {
|
||||
// if (bg.getRed() < 127 || bg.getBlue() < 127 || bg.getGreen() < 127) {
|
||||
// setForeground(Color.white);
|
||||
// } else {
|
||||
// setForeground(Color.black);
|
||||
// }
|
||||
// super.setBackground(bg);
|
||||
// }
|
||||
}
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
package org.diylc.swing.gui.editor;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
import com.diyfever.gui.DoubleTextField;
|
||||
|
||||
public class IntEditor extends DoubleTextField {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Color oldBg = getBackground();
|
||||
|
||||
public IntEditor(final PropertyWrapper property) {
|
||||
setLayout(new BorderLayout());
|
||||
setValue((double) (Integer) property.getValue());
|
||||
addPropertyChangeListener(DoubleTextField.VALUE_PROPERTY, new PropertyChangeListener() {
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
property.setChanged(true);
|
||||
setBackground(oldBg);
|
||||
property.setValue(((Double) evt.getNewValue()).intValue());
|
||||
}
|
||||
});
|
||||
if (!property.isUnique()) {
|
||||
setBackground(Constants.MULTI_VALUE_COLOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
-97
@@ -1,97 +0,0 @@
|
||||
package org.diylc.swing.gui.editor;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Container;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import javax.swing.JComboBox;
|
||||
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.core.measures.AbstractMeasure;
|
||||
import org.diylc.core.measures.Unit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
import com.diyfever.gui.DoubleTextField;
|
||||
|
||||
public class MeasureEditor extends Container {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Color oldBg;
|
||||
private DoubleTextField valueField;
|
||||
private JComboBox unitBox;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public MeasureEditor(final PropertyWrapper property) {
|
||||
setLayout(new BorderLayout());
|
||||
AbstractMeasure measure = ((AbstractMeasure) property.getValue());
|
||||
valueField = new DoubleTextField(measure.getValue());
|
||||
oldBg = valueField.getBackground();
|
||||
valueField.addPropertyChangeListener(DoubleTextField.VALUE_PROPERTY,
|
||||
new PropertyChangeListener() {
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
try {
|
||||
AbstractMeasure<?> newMeasure = (AbstractMeasure<?>) ((AbstractMeasure) property
|
||||
.getValue()).clone();
|
||||
newMeasure.setValue((Double) evt.getNewValue());
|
||||
property.setValue(newMeasure);
|
||||
property.setChanged(true);
|
||||
valueField.setBackground(oldBg);
|
||||
unitBox.setBackground(oldBg);
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
}
|
||||
}
|
||||
});
|
||||
add(valueField, BorderLayout.CENTER);
|
||||
try {
|
||||
Method method = measure.getUnit().getClass().getMethod("values");
|
||||
unitBox = new JComboBox((Object[]) method.invoke(measure.getUnit()));
|
||||
unitBox.setSelectedItem(measure.getUnit());
|
||||
unitBox.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
try {
|
||||
AbstractMeasure<Enum<? extends Unit>> newMeasure = (AbstractMeasure<Enum<? extends Unit>>) ((AbstractMeasure) property
|
||||
.getValue()).clone();
|
||||
newMeasure.setUnit((Enum<? extends Unit>) unitBox.getSelectedItem());
|
||||
property.setValue(newMeasure);
|
||||
property.setChanged(true);
|
||||
valueField.setBackground(oldBg);
|
||||
unitBox.setBackground(oldBg);
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
}
|
||||
}
|
||||
});
|
||||
add(unitBox, BorderLayout.EAST);
|
||||
|
||||
if (!property.isUnique()) {
|
||||
valueField.setBackground(Constants.MULTI_VALUE_COLOR);
|
||||
unitBox.setBackground(Constants.MULTI_VALUE_COLOR);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (SecurityException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
-170
@@ -1,170 +0,0 @@
|
||||
package org.diylc.swing.gui.editor;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.core.ValidationException;
|
||||
|
||||
import com.diyfever.gui.ButtonDialog;
|
||||
|
||||
public class PropertyEditorDialog extends ButtonDialog {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(PropertyEditorDialog.class);
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final String DEFAULT_BOX_TOOLTIP = "<html>If this box is checked application will use the current value as a<br>default when creating new components of the same type</html>";
|
||||
|
||||
private List<PropertyWrapper> properties;
|
||||
private Set<PropertyWrapper> defaultedProperties;
|
||||
|
||||
public PropertyEditorDialog(JFrame owner, List<PropertyWrapper> properties, String title) {
|
||||
super(owner, title, new String[] { ButtonDialog.OK, ButtonDialog.CANCEL });
|
||||
|
||||
LOG.debug("Creating property editor for: " + properties);
|
||||
|
||||
this.properties = properties;
|
||||
this.defaultedProperties = new HashSet<PropertyWrapper>();
|
||||
|
||||
setMinimumSize(new Dimension(240, 40));
|
||||
|
||||
layoutGui();
|
||||
setLocationRelativeTo(owner);
|
||||
//
|
||||
// setModal(true);
|
||||
//
|
||||
// JPanel holderPanel = new JPanel();
|
||||
// holderPanel.setLayout(new BorderLayout());
|
||||
// holderPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
|
||||
//
|
||||
// holderPanel.add(createEditorFields(), BorderLayout.CENTER);
|
||||
// holderPanel.add(createButtonPanel(), BorderLayout.SOUTH);
|
||||
//
|
||||
// setContentPane(holderPanel);
|
||||
//
|
||||
//
|
||||
// pack();
|
||||
// setLocationRelativeTo(owner);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean validateInput(String button) {
|
||||
if (button.equals(ButtonDialog.OK)) {
|
||||
for (PropertyWrapper property : properties) {
|
||||
try {
|
||||
property.getValidator().validate(property.getValue());
|
||||
} catch (ValidationException ve) {
|
||||
JOptionPane.showMessageDialog(PropertyEditorDialog.this, "Input error for \""
|
||||
+ property.getName() + "\": " + ve.getMessage(), "Error",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private JPanel createEditorFields() {
|
||||
JPanel editorPanel = new JPanel(new GridBagLayout());
|
||||
editorPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
|
||||
|
||||
GridBagConstraints gbc = new GridBagConstraints();
|
||||
|
||||
gbc.gridy = 0;
|
||||
gbc.insets = new Insets(2, 2, 2, 2);
|
||||
gbc.anchor = GridBagConstraints.LINE_START;
|
||||
|
||||
for (PropertyWrapper property : properties) {
|
||||
gbc.gridx = 0;
|
||||
gbc.fill = GridBagConstraints.NONE;
|
||||
gbc.weightx = 0;
|
||||
|
||||
editorPanel.add(new JLabel(property.getName() + ": "), gbc);
|
||||
|
||||
gbc.gridx = 1;
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
gbc.weightx = 1;
|
||||
|
||||
Component editor = FieldEditorFactory.createFieldEditor(property);
|
||||
editor.addKeyListener(new KeyAdapter() {
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
|
||||
getButton(OK).doClick();
|
||||
} else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
|
||||
getButton(CANCEL).doClick();
|
||||
}
|
||||
}
|
||||
});
|
||||
editorPanel.add(editor, gbc);
|
||||
|
||||
if (property.isDefaultable()) {
|
||||
gbc.gridx = 2;
|
||||
gbc.fill = GridBagConstraints.NONE;
|
||||
gbc.weightx = 0;
|
||||
|
||||
editorPanel.add(createDefaultCheckBox(property), gbc);
|
||||
}
|
||||
|
||||
gbc.gridy++;
|
||||
}
|
||||
|
||||
return editorPanel;
|
||||
}
|
||||
|
||||
private JCheckBox createDefaultCheckBox(final PropertyWrapper property) {
|
||||
final JCheckBox checkBox = new JCheckBox();
|
||||
checkBox.setToolTipText(DEFAULT_BOX_TOOLTIP);
|
||||
checkBox.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (checkBox.isSelected()) {
|
||||
defaultedProperties.add(property);
|
||||
} else {
|
||||
defaultedProperties.remove(property);
|
||||
}
|
||||
}
|
||||
});
|
||||
return checkBox;
|
||||
}
|
||||
|
||||
public Set<PropertyWrapper> getDefaultedProperties() {
|
||||
return defaultedProperties;
|
||||
}
|
||||
|
||||
public static boolean showFor(JFrame owner, List<PropertyWrapper> properties, String title) {
|
||||
PropertyEditorDialog editor = new PropertyEditorDialog(owner, properties, title);
|
||||
editor.setVisible(true);
|
||||
if (OK.equals(editor.getSelectedButtonCaption())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent getMainComponent() {
|
||||
return createEditorFields();
|
||||
}
|
||||
}
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
package org.diylc.swing.gui.editor;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
public class StringEditor extends JTextField {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Color oldBg = getBackground();
|
||||
|
||||
private final PropertyWrapper property;
|
||||
|
||||
public StringEditor(PropertyWrapper property) {
|
||||
super(property.getValue() == null ? "" : (String) property.getValue());
|
||||
this.property = property;
|
||||
getDocument().addDocumentListener(new DocumentListener() {
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
textChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
textChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
textChanged();
|
||||
}
|
||||
});
|
||||
if (!property.isUnique()) {
|
||||
setBackground(Constants.MULTI_VALUE_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
private void textChanged() {
|
||||
property.setChanged(true);
|
||||
setBackground(oldBg);
|
||||
property.setValue(getText());
|
||||
}
|
||||
}
|
||||
-73
@@ -1,73 +0,0 @@
|
||||
package org.diylc.swing.plugins.autosave;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.EnumSet;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import org.diylc.common.EventType;
|
||||
import org.diylc.common.IPlugIn;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.core.IView;
|
||||
|
||||
import com.diyfever.gui.miscutils.ConfigurationManager;
|
||||
|
||||
public class AutoSavePlugin implements IPlugIn {
|
||||
|
||||
private static final String AUTO_SAVE_FILE_NAME = "autoSave.diy";
|
||||
|
||||
private ExecutorService executor;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
private IView view;
|
||||
|
||||
public AutoSavePlugin(IView view) {
|
||||
this.view = view;
|
||||
executor = Executors.newSingleThreadExecutor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect(IPlugInPort plugInPort) {
|
||||
this.plugInPort = plugInPort;
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
boolean wasAbnormal = ConfigurationManager.getInstance().readBoolean(
|
||||
IPlugInPort.ABNORMAL_EXIT_KEY, false);
|
||||
if (wasAbnormal && new File(AUTO_SAVE_FILE_NAME).exists()) {
|
||||
int decision = view
|
||||
.showConfirmDialog(
|
||||
"It appears that aplication was not closed normally in the previous session. Do you want to open the last auto-saved file?",
|
||||
"Auto-Save", IView.YES_NO_OPTION, IView.QUESTION_MESSAGE);
|
||||
if (decision == IView.YES_OPTION) {
|
||||
AutoSavePlugin.this.plugInPort.loadProjectFromFile(AUTO_SAVE_FILE_NAME);
|
||||
}
|
||||
}
|
||||
// Set abnormal flag to true, GUI side of the app must flip to
|
||||
// false when app closes regularly.
|
||||
ConfigurationManager.getInstance().writeValue(IPlugInPort.ABNORMAL_EXIT_KEY, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<EventType> getSubscribedEventTypes() {
|
||||
return EnumSet.of(EventType.PROJECT_MODIFIED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processMessage(EventType eventType, Object... params) {
|
||||
if (eventType == EventType.PROJECT_MODIFIED) {
|
||||
executor.execute(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
plugInPort.saveProjectToFile(AUTO_SAVE_FILE_NAME, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
package org.diylc.swing.plugins.canvas;
|
||||
|
||||
import java.awt.dnd.DragGestureEvent;
|
||||
import java.awt.dnd.DragGestureListener;
|
||||
|
||||
import org.diylc.common.IPlugInPort;
|
||||
|
||||
/**
|
||||
* {@link DragGestureListener} for {@link CanvasPanel}.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
class CanvasGestureListener implements DragGestureListener {
|
||||
|
||||
private IPlugInPort presenter;
|
||||
|
||||
public CanvasGestureListener(IPlugInPort presenter) {
|
||||
super();
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dragGestureRecognized(DragGestureEvent dge) {
|
||||
presenter.dragStarted(dge.getDragOrigin(), dge.getTriggerEvent().isControlDown(), dge
|
||||
.getTriggerEvent().isShiftDown(), dge.getTriggerEvent().isAltDown());
|
||||
dge.startDrag(presenter.getCursorAt(dge.getDragOrigin()), new EmptyTransferable(),
|
||||
new CanvasSourceListener(presenter));
|
||||
}
|
||||
}
|
||||
-210
@@ -1,210 +0,0 @@
|
||||
package org.diylc.swing.plugins.canvas;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Image;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.dnd.Autoscroll;
|
||||
import java.awt.dnd.DnDConstants;
|
||||
import java.awt.dnd.DragSource;
|
||||
import java.awt.dnd.DropTarget;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ComponentAdapter;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.image.VolatileImage;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.KeyStroke;
|
||||
|
||||
import org.diylc.common.DrawOption;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
|
||||
import com.diyfever.gui.miscutils.ConfigurationManager;
|
||||
|
||||
/**
|
||||
* GUI class used to draw onto.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
class CanvasPanel extends JComponent implements Autoscroll {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
|
||||
private Image bufferImage;
|
||||
private GraphicsConfiguration screenGraphicsConfiguration;
|
||||
|
||||
private static boolean USE_HARDWARE_ACCELLERATION = false;
|
||||
|
||||
// static final EnumSet<DrawOption> DRAW_OPTIONS = EnumSet.of(DrawOption.GRID,
|
||||
// DrawOption.SELECTION, DrawOption.ZOOM, DrawOption.CONTROL_POINTS);
|
||||
// static final EnumSet<DrawOption> DRAW_OPTIONS_ANTI_ALIASING = EnumSet.of(DrawOption.GRID,
|
||||
// DrawOption.SELECTION, DrawOption.ZOOM, DrawOption.ANTIALIASING,
|
||||
// DrawOption.CONTROL_POINTS);
|
||||
|
||||
public CanvasPanel(IPlugInPort plugInPort) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
setFocusable(true);
|
||||
initializeListeners();
|
||||
initializeDnD();
|
||||
GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
GraphicsDevice[] devices = graphicsEnvironment.getScreenDevices();
|
||||
screenGraphicsConfiguration = devices[0].getDefaultConfiguration();
|
||||
|
||||
initializeActions();
|
||||
}
|
||||
|
||||
public void invalidateCache() {
|
||||
bufferImage = null;
|
||||
}
|
||||
|
||||
private void initializeDnD() {
|
||||
// Initialize drag source recognizer.
|
||||
DragSource.getDefaultDragSource().createDefaultDragGestureRecognizer(this,
|
||||
DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_LINK,
|
||||
new CanvasGestureListener(plugInPort));
|
||||
// Initialize drop target.
|
||||
new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE,
|
||||
new CanvasTargetListener(plugInPort), true);
|
||||
}
|
||||
|
||||
private void initializeActions() {
|
||||
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "clearSlot");
|
||||
getActionMap().put("clearSlot", new AbstractAction() {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
CanvasPanel.this.plugInPort.setNewComponentTypeSlot(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void createBufferImage() {
|
||||
if (USE_HARDWARE_ACCELLERATION) {
|
||||
bufferImage = screenGraphicsConfiguration.createCompatibleVolatileImage(getWidth(),
|
||||
getHeight());
|
||||
((VolatileImage) bufferImage).validate(screenGraphicsConfiguration);
|
||||
} else {
|
||||
bufferImage = createImage(getWidth(), getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
if (plugInPort == null) {
|
||||
return;
|
||||
}
|
||||
if (bufferImage == null) {
|
||||
createBufferImage();
|
||||
}
|
||||
Graphics2D g2d = (Graphics2D) bufferImage.getGraphics();
|
||||
g2d.setClip(getVisibleRect());
|
||||
Set<DrawOption> drawOptions = EnumSet.of(DrawOption.GRID, DrawOption.SELECTION,
|
||||
DrawOption.ZOOM, DrawOption.CONTROL_POINTS);
|
||||
if (ConfigurationManager.getInstance().readBoolean(IPlugInPort.ANTI_ALIASING_KEY, true)) {
|
||||
drawOptions.add(DrawOption.ANTIALIASING);
|
||||
}
|
||||
if (ConfigurationManager.getInstance().readBoolean(IPlugInPort.OUTLINE_KEY, false)) {
|
||||
drawOptions.add(DrawOption.OUTLINE_MODE);
|
||||
}
|
||||
plugInPort.draw(g2d, drawOptions, null);
|
||||
if (USE_HARDWARE_ACCELLERATION) {
|
||||
VolatileImage volatileImage = (VolatileImage) bufferImage;
|
||||
do {
|
||||
try {
|
||||
if (volatileImage.contentsLost()) {
|
||||
createBufferImage();
|
||||
}
|
||||
// int validation =
|
||||
// volatileImage.validate(screenGraphicsConfiguration);
|
||||
// if (validation == VolatileImage.IMAGE_INCOMPATIBLE) {
|
||||
// createBufferImage();
|
||||
// }
|
||||
g.drawImage(bufferImage, 0, 0, this);
|
||||
} catch (NullPointerException e) {
|
||||
createBufferImage();
|
||||
}
|
||||
} while (volatileImage == null || volatileImage.contentsLost());
|
||||
} else {
|
||||
g.drawImage(bufferImage, 0, 0, this);
|
||||
// bufferImage.flush();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Graphics g) {
|
||||
paint(g);
|
||||
}
|
||||
|
||||
private void initializeListeners() {
|
||||
addComponentListener(new ComponentAdapter() {
|
||||
|
||||
@Override
|
||||
public void componentResized(ComponentEvent e) {
|
||||
invalidateCache();
|
||||
invalidate();
|
||||
}
|
||||
});
|
||||
// addKeyListener(new KeyAdapter() {
|
||||
//
|
||||
// @Override
|
||||
// public void keyPressed(KeyEvent e) {
|
||||
// if (e.getKeyCode() == KeyEvent.VK_DELETE) {
|
||||
// plugInPort.deleteSelectedComponents();
|
||||
// }
|
||||
// // plugInPort.mouseMoved(getMousePosition(), e.isControlDown(),
|
||||
// // e.isShiftDown(), e
|
||||
// // .isAltDown());
|
||||
// }
|
||||
// });
|
||||
addMouseMotionListener(new MouseAdapter() {
|
||||
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
setCursor(plugInPort.getCursorAt(e.getPoint()));
|
||||
plugInPort.mouseMoved(e.getPoint(), e.isControlDown(), e.isShiftDown(), e
|
||||
.isAltDown());
|
||||
}
|
||||
});
|
||||
addMouseListener(new MouseAdapter() {
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (e.getButton() == MouseEvent.BUTTON1) {
|
||||
plugInPort.mouseClicked(e.getPoint(), e.isControlDown(), e.isShiftDown(), e
|
||||
.isAltDown(), e.getClickCount());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Autoscroll
|
||||
|
||||
@Override
|
||||
public void autoscroll(Point cursorLocn) {
|
||||
scrollRectToVisible(new Rectangle(cursorLocn.x - 15, cursorLocn.y - 15, 30, 30));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getAutoscrollInsets() {
|
||||
Rectangle rect = getVisibleRect();
|
||||
return new Insets(rect.y - 15, rect.x - 15, rect.y + rect.height + 15, rect.x + rect.width
|
||||
+ 15);
|
||||
}
|
||||
}
|
||||
-319
@@ -1,319 +0,0 @@
|
||||
package org.diylc.swing.plugins.canvas;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.ClipboardOwner;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseWheelEvent;
|
||||
import java.awt.event.MouseWheelListener;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.common.BadPositionException;
|
||||
import org.diylc.common.EventType;
|
||||
import org.diylc.common.IPlugIn;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.presenter.Presenter;
|
||||
import org.diylc.swing.ActionFactory;
|
||||
import org.diylc.swing.ISwingUI;
|
||||
import org.diylc.swing.plugins.edit.ComponentTransferable;
|
||||
import org.diylc.swing.plugins.file.ProjectDrawingProvider;
|
||||
|
||||
import com.diyfever.gui.miscutils.ConfigurationManager;
|
||||
import com.diyfever.gui.miscutils.IConfigListener;
|
||||
import com.diyfever.gui.ruler.IRulerListener;
|
||||
import com.diyfever.gui.ruler.RulerScrollPane;
|
||||
|
||||
public class CanvasPlugin implements IPlugIn, ClipboardOwner {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(CanvasPlugin.class);
|
||||
|
||||
private RulerScrollPane scrollPane;
|
||||
private CanvasPanel canvasPanel;
|
||||
private JPopupMenu popupMenu;
|
||||
|
||||
private ActionFactory.CutAction cutAction;
|
||||
private ActionFactory.CopyAction copyAction;
|
||||
private ActionFactory.PasteAction pasteAction;
|
||||
private ActionFactory.EditSelectionAction editSelectionAction;
|
||||
private ActionFactory.DeleteSelectionAction deleteSelectionAction;
|
||||
private ActionFactory.GroupAction groupAction;
|
||||
private ActionFactory.UngroupAction ungroupAction;
|
||||
private ActionFactory.SendToBackAction sendToBackAction;
|
||||
private ActionFactory.BringToFrontAction bringToFrontAction;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
private ISwingUI swingUI;
|
||||
|
||||
private Clipboard clipboard;
|
||||
|
||||
private double zoomLevel = 1;
|
||||
|
||||
public CanvasPlugin(ISwingUI swingUI) {
|
||||
this.swingUI = swingUI;
|
||||
clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect(IPlugInPort plugInPort) {
|
||||
this.plugInPort = plugInPort;
|
||||
try {
|
||||
swingUI.injectGUIComponent(getScrollPane(), SwingConstants.CENTER);
|
||||
} catch (BadPositionException e) {
|
||||
LOG.error("Could not install canvas plugin", e);
|
||||
}
|
||||
}
|
||||
|
||||
public CanvasPanel getCanvasPanel() {
|
||||
if (canvasPanel == null) {
|
||||
canvasPanel = new CanvasPanel(plugInPort);
|
||||
canvasPanel.addMouseListener(new MouseAdapter() {
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
if (e.isPopupTrigger()) {
|
||||
// Enable actions.
|
||||
boolean enabled = !plugInPort.getSelectedComponents().isEmpty();
|
||||
getCutAction().setEnabled(enabled);
|
||||
getCopyAction().setEnabled(enabled);
|
||||
try {
|
||||
getPasteAction()
|
||||
.setEnabled(
|
||||
clipboard
|
||||
.isDataFlavorAvailable(ComponentTransferable.listFlavor));
|
||||
} catch (Exception ex) {
|
||||
getPasteAction().setEnabled(false);
|
||||
}
|
||||
getEditSelectionAction().setEnabled(enabled);
|
||||
getDeleteSelectionAction().setEnabled(enabled);
|
||||
getGroupAction().setEnabled(enabled);
|
||||
getUngroupAction().setEnabled(enabled);
|
||||
getSendToBackAction().setEnabled(enabled);
|
||||
getBringToFrontAction().setEnabled(enabled);
|
||||
|
||||
getPopupMenu().show(canvasPanel, e.getX(), e.getY());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return canvasPanel;
|
||||
}
|
||||
|
||||
private RulerScrollPane getScrollPane() {
|
||||
if (scrollPane == null) {
|
||||
scrollPane = new RulerScrollPane(getCanvasPanel(), new ProjectDrawingProvider(
|
||||
plugInPort, true, false), new Size(1d, SizeUnit.cm).convertToPixels(),
|
||||
new Size(1d, SizeUnit.in).convertToPixels());
|
||||
boolean metric = ConfigurationManager.getInstance().readBoolean(Presenter.METRIC_KEY,
|
||||
true);
|
||||
boolean wheelZoom = ConfigurationManager.getInstance().readBoolean(
|
||||
IPlugInPort.WHEEL_ZOOM_KEY, false);
|
||||
ConfigurationManager.getInstance().addConfigListener(IPlugInPort.WHEEL_ZOOM_KEY,
|
||||
new IConfigListener() {
|
||||
|
||||
@Override
|
||||
public void valueChanged(String key, Object value) {
|
||||
scrollPane.setWheelScrollingEnabled(!(Boolean) value);
|
||||
}
|
||||
});
|
||||
scrollPane.setMetric(metric);
|
||||
scrollPane.setWheelScrollingEnabled(!wheelZoom);
|
||||
scrollPane.addUnitListener(new IRulerListener() {
|
||||
|
||||
@Override
|
||||
public void unitsChanged(boolean isMetric) {
|
||||
plugInPort.setMetric(isMetric);
|
||||
}
|
||||
});
|
||||
scrollPane.addMouseWheelListener(new MouseWheelListener() {
|
||||
|
||||
@Override
|
||||
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||
boolean wheelZoom = ConfigurationManager.getInstance().readBoolean(
|
||||
IPlugInPort.WHEEL_ZOOM_KEY, false);
|
||||
if (!wheelZoom) {
|
||||
return;
|
||||
}
|
||||
double d = plugInPort.getZoomLevel();
|
||||
Double[] availableZoomLevels = plugInPort.getAvailableZoomLevels();
|
||||
if (e.getWheelRotation() > 0) {
|
||||
int i = availableZoomLevels.length - 1;
|
||||
while (i > 0 && availableZoomLevels[i] >= d) {
|
||||
i--;
|
||||
}
|
||||
plugInPort.setZoomLevel(availableZoomLevels[i]);
|
||||
} else {
|
||||
int i = 0;
|
||||
while (i < availableZoomLevels.length - 1 && availableZoomLevels[i] <= d) {
|
||||
i++;
|
||||
}
|
||||
plugInPort.setZoomLevel(availableZoomLevels[i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return scrollPane;
|
||||
}
|
||||
|
||||
public JPopupMenu getPopupMenu() {
|
||||
if (popupMenu == null) {
|
||||
popupMenu = new JPopupMenu();
|
||||
popupMenu.add(getCutAction());
|
||||
popupMenu.add(getCopyAction());
|
||||
popupMenu.add(getPasteAction());
|
||||
popupMenu.addSeparator();
|
||||
popupMenu.add(getEditSelectionAction());
|
||||
popupMenu.add(getDeleteSelectionAction());
|
||||
popupMenu.add(getGroupAction());
|
||||
popupMenu.add(getUngroupAction());
|
||||
popupMenu.add(getSendToBackAction());
|
||||
popupMenu.add(getBringToFrontAction());
|
||||
popupMenu.addSeparator();
|
||||
popupMenu.add(ActionFactory.getInstance().createEditProjectAction(plugInPort));
|
||||
}
|
||||
return popupMenu;
|
||||
}
|
||||
|
||||
public ActionFactory.CutAction getCutAction() {
|
||||
if (cutAction == null) {
|
||||
cutAction = ActionFactory.getInstance().createCutAction(plugInPort, clipboard, this);
|
||||
}
|
||||
return cutAction;
|
||||
}
|
||||
|
||||
public ActionFactory.CopyAction getCopyAction() {
|
||||
if (copyAction == null) {
|
||||
copyAction = ActionFactory.getInstance().createCopyAction(plugInPort, clipboard, this);
|
||||
}
|
||||
return copyAction;
|
||||
}
|
||||
|
||||
public ActionFactory.PasteAction getPasteAction() {
|
||||
if (pasteAction == null) {
|
||||
pasteAction = ActionFactory.getInstance().createPasteAction(plugInPort, clipboard);
|
||||
}
|
||||
return pasteAction;
|
||||
}
|
||||
|
||||
public ActionFactory.EditSelectionAction getEditSelectionAction() {
|
||||
if (editSelectionAction == null) {
|
||||
editSelectionAction = ActionFactory.getInstance().createEditSelectionAction(plugInPort);
|
||||
}
|
||||
return editSelectionAction;
|
||||
}
|
||||
|
||||
public ActionFactory.DeleteSelectionAction getDeleteSelectionAction() {
|
||||
if (deleteSelectionAction == null) {
|
||||
deleteSelectionAction = ActionFactory.getInstance().createDeleteSelectionAction(
|
||||
plugInPort);
|
||||
}
|
||||
return deleteSelectionAction;
|
||||
}
|
||||
|
||||
public ActionFactory.GroupAction getGroupAction() {
|
||||
if (groupAction == null) {
|
||||
groupAction = ActionFactory.getInstance().createGroupAction(plugInPort);
|
||||
}
|
||||
return groupAction;
|
||||
}
|
||||
|
||||
public ActionFactory.UngroupAction getUngroupAction() {
|
||||
if (ungroupAction == null) {
|
||||
ungroupAction = ActionFactory.getInstance().createUngroupAction(plugInPort);
|
||||
}
|
||||
return ungroupAction;
|
||||
}
|
||||
|
||||
public ActionFactory.SendToBackAction getSendToBackAction() {
|
||||
if (sendToBackAction == null) {
|
||||
sendToBackAction = ActionFactory.getInstance().createSendToBackAction(plugInPort);
|
||||
}
|
||||
return sendToBackAction;
|
||||
}
|
||||
|
||||
public ActionFactory.BringToFrontAction getBringToFrontAction() {
|
||||
if (bringToFrontAction == null) {
|
||||
bringToFrontAction = ActionFactory.getInstance().createBringToFrontAction(plugInPort);
|
||||
}
|
||||
return bringToFrontAction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<EventType> getSubscribedEventTypes() {
|
||||
return EnumSet.of(EventType.PROJECT_LOADED, EventType.ZOOM_CHANGED, EventType.REPAINT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processMessage(final EventType eventType, Object... params) {
|
||||
// SwingUtilities.invokeLater(new Runnable() {
|
||||
//
|
||||
// @Override
|
||||
// public void run() {
|
||||
// LOG.debug("event: " + eventType);
|
||||
switch (eventType) {
|
||||
case PROJECT_LOADED:
|
||||
refreshSize();
|
||||
if ((Boolean) params[1]) {
|
||||
// Scroll to the center.
|
||||
Rectangle visibleRect = canvasPanel.getVisibleRect();
|
||||
visibleRect.setLocation((canvasPanel.getWidth() - visibleRect.width) / 2,
|
||||
(canvasPanel.getHeight() - visibleRect.height) / 2);
|
||||
canvasPanel.scrollRectToVisible(visibleRect);
|
||||
canvasPanel.revalidate();
|
||||
}
|
||||
break;
|
||||
case ZOOM_CHANGED:
|
||||
Rectangle visibleRect = canvasPanel.getVisibleRect();
|
||||
refreshSize();
|
||||
// Try to set the visible area to be centered with the previous
|
||||
// one.
|
||||
double zoomFactor = (Double) params[0] / zoomLevel;
|
||||
visibleRect.setBounds((int) (visibleRect.x * zoomFactor),
|
||||
(int) (visibleRect.y * zoomFactor), visibleRect.width, visibleRect.height);
|
||||
canvasPanel.scrollRectToVisible(visibleRect);
|
||||
canvasPanel.revalidate();
|
||||
|
||||
zoomLevel = (Double) params[0];
|
||||
break;
|
||||
case REPAINT:
|
||||
canvasPanel.repaint();
|
||||
break;
|
||||
}
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
private void refreshSize() {
|
||||
Dimension d = plugInPort.getCanvasDimensions(true);
|
||||
canvasPanel.setSize(d);
|
||||
canvasPanel.setPreferredSize(d);
|
||||
getScrollPane().setZoomLevel(plugInPort.getZoomLevel());
|
||||
}
|
||||
|
||||
/**
|
||||
* Causes ruler scroll pane to refresh by sending a fake mouse moved message
|
||||
* to the canvasPanel.
|
||||
*/
|
||||
public void refresh() {
|
||||
MouseEvent event = new MouseEvent(canvasPanel, MouseEvent.MOUSE_MOVED, System
|
||||
.currentTimeMillis(), 0, 1, 1,// canvasPanel.getWidth() / 2,
|
||||
// canvasPanel.getHeight() / 2,
|
||||
0, false);
|
||||
canvasPanel.dispatchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lostOwnership(Clipboard clipboard, Transferable contents) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
}
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
package org.diylc.swing.plugins.canvas;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.dnd.DragSourceDragEvent;
|
||||
import java.awt.dnd.DragSourceDropEvent;
|
||||
import java.awt.dnd.DragSourceEvent;
|
||||
import java.awt.dnd.DragSourceListener;
|
||||
|
||||
import org.diylc.common.IPlugInPort;
|
||||
|
||||
|
||||
/**
|
||||
* {@link DragSourceListener} for {@link CanvasPanel}.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
class CanvasSourceListener implements DragSourceListener {
|
||||
|
||||
private IPlugInPort presenter;
|
||||
|
||||
public CanvasSourceListener(IPlugInPort presenter) {
|
||||
super();
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dragDropEnd(DragSourceDropEvent dsde) {
|
||||
presenter.dragEnded(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dragEnter(DragSourceDragEvent dsde) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dragExit(DragSourceEvent dse) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dragOver(DragSourceDragEvent dsde) {
|
||||
Point p = dsde.getDragSourceContext().getComponent().getMousePosition();
|
||||
if (p != null) {
|
||||
dsde.getDragSourceContext().getComponent().firePropertyChange("dragPoint", p.x, p.y);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropActionChanged(DragSourceDragEvent dsde) {
|
||||
}
|
||||
}
|
||||
-95
@@ -1,95 +0,0 @@
|
||||
package org.diylc.swing.plugins.canvas;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.dnd.DnDConstants;
|
||||
import java.awt.dnd.DropTargetDragEvent;
|
||||
import java.awt.dnd.DropTargetDropEvent;
|
||||
import java.awt.dnd.DropTargetEvent;
|
||||
import java.awt.dnd.DropTargetListener;
|
||||
|
||||
import org.diylc.common.IPlugInPort;
|
||||
|
||||
|
||||
/**
|
||||
* {@link DropTargetListener} for {@link CanvasPanel}.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
class CanvasTargetListener implements DropTargetListener {
|
||||
|
||||
private IPlugInPort presenter;
|
||||
|
||||
// Cached values
|
||||
private Point currentPoint = null;
|
||||
private boolean lastAccept;
|
||||
|
||||
public CanvasTargetListener(IPlugInPort presenter) {
|
||||
super();
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dragEnter(DropTargetDragEvent dtde) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dragExit(DropTargetEvent dte) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dragOver(DropTargetDragEvent dtde) {
|
||||
// If dragOver was previously called for this location use cached value.
|
||||
if (dtde.getLocation().equals(currentPoint)) {
|
||||
if (lastAccept) {
|
||||
dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
|
||||
} else {
|
||||
dtde.rejectDrag();
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// Transferable t = dtde.getTransferable();
|
||||
// if
|
||||
// (t.isDataFlavorSupported(SelectionTransferable.selectionFlavor))
|
||||
// {
|
||||
// if (currentPoint != null) {
|
||||
// List<IDIYComponent> selection = (List<IDIYComponent>) t
|
||||
// .getTransferData(SelectionTransferable.selectionFlavor);
|
||||
// Point startPoint = (Point) t
|
||||
// .getTransferData(PointTransferable.pointFlavor);
|
||||
// presenter.selectionMoved(dtde.getLocation().x
|
||||
// - currentPoint.x, dtde.getLocation().y
|
||||
// - currentPoint.y);
|
||||
// }
|
||||
// } else if
|
||||
// (t.isDataFlavorSupported(PointTransferable.pointFlavor)) {
|
||||
// Point startPoint = (Point) t
|
||||
// .getTransferData(PointTransferable.pointFlavor);
|
||||
// Point endPoint = dtde.getLocation();
|
||||
// presenter.setSelectionRect(Utils.createRectangle(startPoint,
|
||||
// endPoint));
|
||||
// }
|
||||
currentPoint = dtde.getLocation();
|
||||
if (presenter.dragOver(currentPoint)) {
|
||||
dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
|
||||
lastAccept = true;
|
||||
} else {
|
||||
dtde.rejectDrag();
|
||||
lastAccept = false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
dtde.rejectDrag();
|
||||
lastAccept = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drop(DropTargetDropEvent dtde) {
|
||||
presenter.dragEnded(dtde.getLocation());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropActionChanged(DropTargetDragEvent dtde) {
|
||||
}
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
package org.diylc.swing.plugins.canvas;
|
||||
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
import java.io.IOException;
|
||||
|
||||
public class EmptyTransferable implements Transferable {
|
||||
|
||||
@Override
|
||||
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
|
||||
throw new UnsupportedFlavorException(flavor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataFlavor[] getTransferDataFlavors() {
|
||||
return new DataFlavor[] {};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDataFlavorSupported(DataFlavor flavor) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
package org.diylc.swing.plugins.canvas;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
import java.io.IOException;
|
||||
|
||||
public class PointTransferable implements Transferable {
|
||||
|
||||
public static final DataFlavor pointFlavor = new DataFlavor(Point.class, "Java Point");
|
||||
|
||||
private Point startPoint;
|
||||
|
||||
public PointTransferable(Point startPoint) {
|
||||
super();
|
||||
this.startPoint = startPoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
|
||||
if (flavor.equals(pointFlavor)) {
|
||||
return startPoint;
|
||||
}
|
||||
throw new UnsupportedFlavorException(flavor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataFlavor[] getTransferDataFlavors() {
|
||||
return new DataFlavor[] { pointFlavor };
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDataFlavorSupported(DataFlavor flavor) {
|
||||
return flavor.equals(pointFlavor);
|
||||
}
|
||||
|
||||
}
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
package org.diylc.swing.plugins.canvas;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
|
||||
public class SelectionTransferable implements Transferable {
|
||||
|
||||
public static final DataFlavor selectionFlavor = new DataFlavor(List.class,
|
||||
"Component Selection");
|
||||
|
||||
private Point startPoint;
|
||||
private List<IDIYComponent<?>> selection;
|
||||
|
||||
public SelectionTransferable(List<IDIYComponent<?>> selection, Point startPoint) {
|
||||
super();
|
||||
this.selection = selection;
|
||||
this.startPoint = startPoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
|
||||
if (flavor.equals(selectionFlavor)) {
|
||||
return selection;
|
||||
}
|
||||
if (flavor.equals(PointTransferable.pointFlavor)) {
|
||||
return startPoint;
|
||||
}
|
||||
throw new UnsupportedFlavorException(flavor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataFlavor[] getTransferDataFlavors() {
|
||||
return new DataFlavor[] { selectionFlavor, PointTransferable.pointFlavor };
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDataFlavorSupported(DataFlavor flavor) {
|
||||
return flavor.equals(selectionFlavor) || flavor.equals(selectionFlavor);
|
||||
}
|
||||
}
|
||||
-90
@@ -1,90 +0,0 @@
|
||||
package org.diylc.swing.plugins.config;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.common.EventType;
|
||||
import org.diylc.common.IPlugIn;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.core.Theme;
|
||||
import org.diylc.images.IconLoader;
|
||||
import org.diylc.swing.ActionFactory;
|
||||
import org.diylc.swing.ISwingUI;
|
||||
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import com.thoughtworks.xstream.io.xml.DomDriver;
|
||||
|
||||
/**
|
||||
* Controls configuration menu.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class ConfigPlugin implements IPlugIn {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(ConfigPlugin.class);
|
||||
|
||||
private static final String CONFIG_MENU = "Config";
|
||||
private static final String THEME_MENU = "Theme";
|
||||
|
||||
private ISwingUI swingUI;
|
||||
|
||||
public ConfigPlugin(ISwingUI swingUI) {
|
||||
super();
|
||||
this.swingUI = swingUI;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect(IPlugInPort plugInPort) {
|
||||
swingUI.injectMenuAction(ActionFactory.getInstance().createConfigAction(plugInPort,
|
||||
"Anti-Aliasing", IPlugInPort.ANTI_ALIASING_KEY, true), CONFIG_MENU);
|
||||
swingUI.injectMenuAction(ActionFactory.getInstance().createConfigAction(plugInPort,
|
||||
"Auto-Create Pads", IPlugInPort.AUTO_PADS_KEY, false), CONFIG_MENU);
|
||||
swingUI.injectMenuAction(ActionFactory.getInstance().createConfigAction(plugInPort,
|
||||
"Auto-Edit Mode", IPlugInPort.AUTO_EDIT_KEY, false), CONFIG_MENU);
|
||||
swingUI.injectMenuAction(ActionFactory.getInstance().createConfigAction(plugInPort,
|
||||
"Continuous Creation", IPlugInPort.CONTINUOUS_CREATION_KEY, false), CONFIG_MENU);
|
||||
swingUI.injectMenuAction(ActionFactory.getInstance().createConfigAction(plugInPort,
|
||||
"Export Grid", IPlugInPort.EXPORT_GRID_KEY, false), CONFIG_MENU);
|
||||
swingUI.injectMenuAction(ActionFactory.getInstance().createConfigAction(plugInPort,
|
||||
"Hi-Quality Rendering", IPlugInPort.HI_QUALITY_RENDER_KEY, false), CONFIG_MENU);
|
||||
swingUI.injectMenuAction(ActionFactory.getInstance().createConfigAction(plugInPort,
|
||||
"Mouse Wheel Zoom", IPlugInPort.WHEEL_ZOOM_KEY, false), CONFIG_MENU);
|
||||
swingUI.injectMenuAction(ActionFactory.getInstance().createConfigAction(plugInPort,
|
||||
"Outline Mode", IPlugInPort.OUTLINE_KEY, false), CONFIG_MENU);
|
||||
swingUI.injectMenuAction(ActionFactory.getInstance().createConfigAction(plugInPort,
|
||||
"Snap to Grid", IPlugInPort.SNAP_TO_GRID_KEY, true), CONFIG_MENU);
|
||||
swingUI.injectMenuAction(ActionFactory.getInstance().createConfigAction(plugInPort,
|
||||
"Sticky Points", IPlugInPort.STICKY_POINTS_KEY, true), CONFIG_MENU);
|
||||
|
||||
File themeDir = new File("themes");
|
||||
if (themeDir.exists()) {
|
||||
XStream xStream = new XStream(new DomDriver());
|
||||
swingUI.injectSubmenu(THEME_MENU, IconLoader.Pens.getIcon(), CONFIG_MENU);
|
||||
for (File file : themeDir.listFiles()) {
|
||||
if (file.getName().toLowerCase().endsWith(".xml")) {
|
||||
try {
|
||||
InputStream in = new FileInputStream(file);
|
||||
Theme theme = (Theme) xStream.fromXML(in);
|
||||
LOG.debug("Found theme: " + theme.getName());
|
||||
swingUI.injectMenuAction(ActionFactory.getInstance().createThemeAction(
|
||||
plugInPort, theme), THEME_MENU);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Could not load theme file " + file.getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<EventType> getSubscribedEventTypes() {
|
||||
return EnumSet.noneOf(EventType.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processMessage(EventType eventType, Object... params) {
|
||||
}
|
||||
}
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
package org.diylc.swing.plugins.edit;
|
||||
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
/**
|
||||
* Represents component selection as a {@link List} of {@link IDIYComponent}
|
||||
* objects. Implements {@link Transferable}, so it is suitable for clipboard
|
||||
* usage.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class ComponentTransferable extends ArrayList<IDIYComponent<?>> implements Transferable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final DataFlavor listFlavor = new DataFlavor(ComponentTransferable.class, "application/diylc");
|
||||
|
||||
public ComponentTransferable() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ComponentTransferable(Collection<IDIYComponent<?>> selectedComponents) {
|
||||
super(selectedComponents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
|
||||
if (flavor.equals(listFlavor)) {
|
||||
return this;
|
||||
}
|
||||
throw new UnsupportedFlavorException(flavor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataFlavor[] getTransferDataFlavors() {
|
||||
return new DataFlavor[] { listFlavor };
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDataFlavorSupported(DataFlavor flavor) {
|
||||
return flavor.equals(listFlavor);
|
||||
}
|
||||
}
|
||||
-224
@@ -1,224 +0,0 @@
|
||||
package org.diylc.swing.plugins.edit;
|
||||
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.ClipboardOwner;
|
||||
import java.awt.datatransfer.FlavorEvent;
|
||||
import java.awt.datatransfer.FlavorListener;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import org.diylc.common.EventType;
|
||||
import org.diylc.common.IPlugIn;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.images.IconLoader;
|
||||
import org.diylc.swing.ActionFactory;
|
||||
import org.diylc.swing.ISwingUI;
|
||||
|
||||
import com.diyfever.gui.undo.IUndoListener;
|
||||
import com.diyfever.gui.undo.UndoHandler;
|
||||
|
||||
public class EditMenuPlugin implements IPlugIn, ClipboardOwner {
|
||||
|
||||
private static final String EDIT_TITLE = "Edit";
|
||||
private static final String RENUMBER_TITLE = "Renumber Selection";
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
private ISwingUI swingUI;
|
||||
|
||||
private Clipboard clipboard;
|
||||
|
||||
private ActionFactory.CutAction cutAction;
|
||||
private ActionFactory.CopyAction copyAction;
|
||||
private ActionFactory.PasteAction pasteAction;
|
||||
private ActionFactory.EditSelectionAction editSelectionAction;
|
||||
private ActionFactory.DeleteSelectionAction deleteSelectionAction;
|
||||
private ActionFactory.GroupAction groupAction;
|
||||
private ActionFactory.UngroupAction ungroupAction;
|
||||
private ActionFactory.SendToBackAction sendToBackAction;
|
||||
private ActionFactory.BringToFrontAction bringToFrontAction;
|
||||
private ActionFactory.RenumberAction renumberXAxisAction;
|
||||
private ActionFactory.RenumberAction renumberYAxisAction;
|
||||
|
||||
private UndoHandler<Project> undoHandler;
|
||||
|
||||
public EditMenuPlugin(ISwingUI swingUI) {
|
||||
this.swingUI = swingUI;
|
||||
// SecurityManager securityManager = System.getSecurityManager();
|
||||
// if (securityManager != null) {
|
||||
// try {
|
||||
// securityManager.checkSystemClipboardAccess();
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
undoHandler = new UndoHandler<Project>(new IUndoListener<Project>() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(Project currentState) {
|
||||
plugInPort.loadProject(currentState, false);
|
||||
}
|
||||
});
|
||||
clipboard.addFlavorListener(new FlavorListener() {
|
||||
|
||||
@Override
|
||||
public void flavorsChanged(FlavorEvent e) {
|
||||
refreshActions();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ActionFactory.CutAction getCutAction() {
|
||||
if (cutAction == null) {
|
||||
cutAction = ActionFactory.getInstance().createCutAction(plugInPort, clipboard, this);
|
||||
}
|
||||
return cutAction;
|
||||
}
|
||||
|
||||
public ActionFactory.CopyAction getCopyAction() {
|
||||
if (copyAction == null) {
|
||||
copyAction = ActionFactory.getInstance().createCopyAction(plugInPort, clipboard, this);
|
||||
}
|
||||
return copyAction;
|
||||
}
|
||||
|
||||
public ActionFactory.PasteAction getPasteAction() {
|
||||
if (pasteAction == null) {
|
||||
pasteAction = ActionFactory.getInstance().createPasteAction(plugInPort, clipboard);
|
||||
}
|
||||
return pasteAction;
|
||||
}
|
||||
|
||||
public ActionFactory.EditSelectionAction getEditSelectionAction() {
|
||||
if (editSelectionAction == null) {
|
||||
editSelectionAction = ActionFactory.getInstance().createEditSelectionAction(plugInPort);
|
||||
}
|
||||
return editSelectionAction;
|
||||
}
|
||||
|
||||
public ActionFactory.DeleteSelectionAction getDeleteSelectionAction() {
|
||||
if (deleteSelectionAction == null) {
|
||||
deleteSelectionAction = ActionFactory.getInstance().createDeleteSelectionAction(
|
||||
plugInPort);
|
||||
}
|
||||
return deleteSelectionAction;
|
||||
}
|
||||
|
||||
public ActionFactory.GroupAction getGroupAction() {
|
||||
if (groupAction == null) {
|
||||
groupAction = ActionFactory.getInstance().createGroupAction(plugInPort);
|
||||
}
|
||||
return groupAction;
|
||||
}
|
||||
|
||||
public ActionFactory.UngroupAction getUngroupAction() {
|
||||
if (ungroupAction == null) {
|
||||
ungroupAction = ActionFactory.getInstance().createUngroupAction(plugInPort);
|
||||
}
|
||||
return ungroupAction;
|
||||
}
|
||||
|
||||
public ActionFactory.SendToBackAction getSendToBackAction() {
|
||||
if (sendToBackAction == null) {
|
||||
sendToBackAction = ActionFactory.getInstance().createSendToBackAction(plugInPort);
|
||||
}
|
||||
return sendToBackAction;
|
||||
}
|
||||
|
||||
public ActionFactory.BringToFrontAction getBringToFrontAction() {
|
||||
if (bringToFrontAction == null) {
|
||||
bringToFrontAction = ActionFactory.getInstance().createBringToFrontAction(plugInPort);
|
||||
}
|
||||
return bringToFrontAction;
|
||||
}
|
||||
|
||||
public ActionFactory.RenumberAction getRenumberXAxisAction() {
|
||||
if (renumberXAxisAction == null) {
|
||||
renumberXAxisAction = ActionFactory.getInstance()
|
||||
.createRenumberAction(plugInPort, true);
|
||||
}
|
||||
return renumberXAxisAction;
|
||||
}
|
||||
|
||||
public ActionFactory.RenumberAction getRenumberYAxisAction() {
|
||||
if (renumberYAxisAction == null) {
|
||||
renumberYAxisAction = ActionFactory.getInstance().createRenumberAction(plugInPort,
|
||||
false);
|
||||
}
|
||||
return renumberYAxisAction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect(IPlugInPort plugInPort) {
|
||||
this.plugInPort = plugInPort;
|
||||
|
||||
ActionFactory actionFactory = ActionFactory.getInstance();
|
||||
|
||||
swingUI.injectMenuAction(undoHandler.getUndoAction(), EDIT_TITLE);
|
||||
swingUI.injectMenuAction(undoHandler.getRedoAction(), EDIT_TITLE);
|
||||
swingUI.injectMenuAction(null, EDIT_TITLE);
|
||||
swingUI.injectMenuAction(getCutAction(), EDIT_TITLE);
|
||||
swingUI.injectMenuAction(getCopyAction(), EDIT_TITLE);
|
||||
swingUI.injectMenuAction(getPasteAction(), EDIT_TITLE);
|
||||
swingUI.injectMenuAction(null, EDIT_TITLE);
|
||||
swingUI.injectMenuAction(actionFactory.createSelectAllAction(plugInPort), EDIT_TITLE);
|
||||
swingUI.injectMenuAction(getEditSelectionAction(), EDIT_TITLE);
|
||||
swingUI.injectMenuAction(getDeleteSelectionAction(), EDIT_TITLE);
|
||||
swingUI.injectMenuAction(getGroupAction(), EDIT_TITLE);
|
||||
swingUI.injectMenuAction(getUngroupAction(), EDIT_TITLE);
|
||||
swingUI.injectMenuAction(getSendToBackAction(), EDIT_TITLE);
|
||||
swingUI.injectMenuAction(getBringToFrontAction(), EDIT_TITLE);
|
||||
swingUI.injectMenuAction(null, EDIT_TITLE);
|
||||
swingUI.injectSubmenu(RENUMBER_TITLE, IconLoader.Sort.getIcon(), EDIT_TITLE);
|
||||
swingUI.injectMenuAction(getRenumberXAxisAction(), RENUMBER_TITLE);
|
||||
swingUI.injectMenuAction(getRenumberYAxisAction(), RENUMBER_TITLE);
|
||||
swingUI.injectMenuAction(null, EDIT_TITLE);
|
||||
swingUI.injectMenuAction(actionFactory.createEditProjectAction(plugInPort), EDIT_TITLE);
|
||||
|
||||
refreshActions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<EventType> getSubscribedEventTypes() {
|
||||
return EnumSet.of(EventType.SELECTION_CHANGED, EventType.PROJECT_MODIFIED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processMessage(EventType eventType, Object... params) {
|
||||
switch (eventType) {
|
||||
case SELECTION_CHANGED:
|
||||
refreshActions();
|
||||
break;
|
||||
case PROJECT_MODIFIED:
|
||||
undoHandler.stateChanged((Project) params[0], (Project) params[1], (String) params[2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshActions() {
|
||||
boolean enabled = !plugInPort.getSelectedComponents().isEmpty();
|
||||
getCutAction().setEnabled(enabled);
|
||||
getCopyAction().setEnabled(enabled);
|
||||
try {
|
||||
getPasteAction().setEnabled(
|
||||
clipboard.isDataFlavorAvailable(ComponentTransferable.listFlavor));
|
||||
} catch (Exception e) {
|
||||
getPasteAction().setEnabled(false);
|
||||
}
|
||||
getEditSelectionAction().setEnabled(enabled);
|
||||
getDeleteSelectionAction().setEnabled(enabled);
|
||||
getGroupAction().setEnabled(enabled);
|
||||
getUngroupAction().setEnabled(enabled);
|
||||
getSendToBackAction().setEnabled(enabled);
|
||||
getBringToFrontAction().setEnabled(enabled);
|
||||
}
|
||||
|
||||
// ClipboardOwner
|
||||
|
||||
@Override
|
||||
public void lostOwnership(Clipboard clipboard, Transferable contents) {
|
||||
refreshActions();
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user