Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d166c58161 | |||
| 144c19b44b | |||
| aef300d902 | |||
| 7ae773ab77 | |||
| 698fba5630 | |||
| 34d475b18a | |||
| 1fe823270e | |||
| 13b31e6dd5 | |||
| 5ef6952ef4 | |||
| 19c78e5fa9 | |||
| 7f8c790936 | |||
| 27b32b0b3c | |||
| eeca9f112d | |||
| 122a91a6f0 | |||
| 246763419c | |||
| 9721307586 | |||
| 9765f04e3c | |||
| df873df04a | |||
| 16f54fa479 | |||
| b76d315f44 | |||
| 90e10f4597 | |||
| 3506c97403 | |||
| 324cb20634 | |||
| 39c7743c30 | |||
| 0c26a71174 | |||
| f73574641c |
|
Before Width: | Height: | Size: 231 KiB After Width: | Height: | Size: 231 KiB |
|
Before Width: | Height: | Size: 375 KiB After Width: | Height: | Size: 377 KiB |
|
Before Width: | Height: | Size: 293 KiB After Width: | Height: | Size: 312 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 286 KiB After Width: | Height: | Size: 286 KiB |
|
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 180 KiB |
|
Before Width: | Height: | Size: 196 KiB After Width: | Height: | Size: 195 KiB |
|
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 111 KiB |
|
Before Width: | Height: | Size: 178 KiB After Width: | Height: | Size: 180 KiB |
|
Before Width: | Height: | Size: 200 KiB After Width: | Height: | Size: 216 KiB |
|
Before Width: | Height: | Size: 433 KiB After Width: | Height: | Size: 432 KiB |
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 210 KiB After Width: | Height: | Size: 210 KiB |
|
Before Width: | Height: | Size: 601 KiB After Width: | Height: | Size: 600 KiB |
|
Before Width: | Height: | Size: 229 KiB After Width: | Height: | Size: 229 KiB |
|
Before Width: | Height: | Size: 463 KiB After Width: | Height: | Size: 463 KiB |
|
Before Width: | Height: | Size: 775 KiB After Width: | Height: | Size: 775 KiB |
|
Before Width: | Height: | Size: 358 KiB After Width: | Height: | Size: 359 KiB |
|
Before Width: | Height: | Size: 350 KiB After Width: | Height: | Size: 350 KiB |
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 156 KiB After Width: | Height: | Size: 156 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 805 KiB After Width: | Height: | Size: 966 KiB |
|
Before Width: | Height: | Size: 268 KiB After Width: | Height: | Size: 267 KiB |
|
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 169 KiB After Width: | Height: | Size: 178 KiB |
|
Before Width: | Height: | Size: 721 KiB After Width: | Height: | Size: 722 KiB |
|
Before Width: | Height: | Size: 506 KiB After Width: | Height: | Size: 531 KiB |
|
Before Width: | Height: | Size: 208 KiB After Width: | Height: | Size: 231 KiB |
|
Before Width: | Height: | Size: 268 KiB After Width: | Height: | Size: 268 KiB |
|
Before Width: | Height: | Size: 3.6 MiB After Width: | Height: | Size: 3.7 MiB |
|
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
|
Before Width: | Height: | Size: 161 KiB After Width: | Height: | Size: 162 KiB |
|
Before Width: | Height: | Size: 730 KiB After Width: | Height: | Size: 732 KiB |
|
Before Width: | Height: | Size: 174 KiB After Width: | Height: | Size: 178 KiB |
|
Before Width: | Height: | Size: 593 KiB After Width: | Height: | Size: 594 KiB |
|
Before Width: | Height: | Size: 251 KiB After Width: | Height: | Size: 250 KiB |
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 186 KiB After Width: | Height: | Size: 186 KiB |
|
Before Width: | Height: | Size: 13 MiB After Width: | Height: | Size: 13 MiB |
|
Before Width: | Height: | Size: 410 KiB After Width: | Height: | Size: 410 KiB |
|
Before Width: | Height: | Size: 358 KiB After Width: | Height: | Size: 358 KiB |
|
Before Width: | Height: | Size: 398 KiB After Width: | Height: | Size: 398 KiB |
|
Before Width: | Height: | Size: 862 KiB After Width: | Height: | Size: 862 KiB |
|
Before Width: | Height: | Size: 314 KiB After Width: | Height: | Size: 314 KiB |
|
Before Width: | Height: | Size: 235 KiB After Width: | Height: | Size: 233 KiB |
|
Before Width: | Height: | Size: 143 KiB After Width: | Height: | Size: 142 KiB |
|
Before Width: | Height: | Size: 218 KiB After Width: | Height: | Size: 216 KiB |
|
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 141 KiB |
|
Before Width: | Height: | Size: 246 KiB After Width: | Height: | Size: 245 KiB |
|
Before Width: | Height: | Size: 230 KiB After Width: | Height: | Size: 229 KiB |
|
Before Width: | Height: | Size: 249 KiB After Width: | Height: | Size: 248 KiB |
|
Before Width: | Height: | Size: 231 KiB After Width: | Height: | Size: 230 KiB |
|
Before Width: | Height: | Size: 3.8 MiB After Width: | Height: | Size: 3.8 MiB |
|
Before Width: | Height: | Size: 351 KiB After Width: | Height: | Size: 350 KiB |
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 219 KiB After Width: | Height: | Size: 220 KiB |
|
Before Width: | Height: | Size: 582 KiB After Width: | Height: | Size: 616 KiB |
|
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 149 KiB |
|
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 178 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 251 KiB After Width: | Height: | Size: 261 KiB |
|
Before Width: | Height: | Size: 266 KiB After Width: | Height: | Size: 285 KiB |
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 107 KiB |
|
Before Width: | Height: | Size: 204 KiB After Width: | Height: | Size: 235 KiB |
|
Before Width: | Height: | Size: 275 KiB After Width: | Height: | Size: 297 KiB |
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 124 KiB |
|
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 142 KiB |
|
Before Width: | Height: | Size: 216 KiB After Width: | Height: | Size: 238 KiB |
|
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 166 KiB |
|
Before Width: | Height: | Size: 308 KiB After Width: | Height: | Size: 318 KiB |
|
Before Width: | Height: | Size: 226 KiB After Width: | Height: | Size: 225 KiB |
|
Before Width: | Height: | Size: 138 KiB After Width: | Height: | Size: 149 KiB |
|
Before Width: | Height: | Size: 212 KiB After Width: | Height: | Size: 219 KiB |
|
Before Width: | Height: | Size: 319 KiB After Width: | Height: | Size: 319 KiB |
|
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 155 KiB |
@@ -210,6 +210,14 @@ logic, netlist and analyzer behaviour, datasheet parsing, core utilities. Compon
|
|||||||
user interaction are covered by the regression suite instead, not by unit tests. Test classes are
|
user interaction are covered by the regression suite instead, not by unit tests. Test classes are
|
||||||
named `*Test` or `*Tests` and carry the license header like any other file.
|
named `*Test` or `*Tests` and carry the license header like any other file.
|
||||||
|
|
||||||
|
## Changelog
|
||||||
|
|
||||||
|
User-facing changes are listed in `diylc-core/src/main/resources/update.xml`, one `Version` block
|
||||||
|
per release. Within a block, all `NEW_FEATURE` entries come first, then `IMPROVEMENT`, then
|
||||||
|
`BUG_FIX`; keep the existing order inside each group and add a new entry at the end of its own
|
||||||
|
group, not at the end of the block. After a merge that brings entries in from both sides, sort the
|
||||||
|
unreleased block again. Released blocks stay exactly as they shipped.
|
||||||
|
|
||||||
## Git
|
## Git
|
||||||
|
|
||||||
**Do not commit or push.** Make the change in the working tree and stop; the maintainer reviews and
|
**Do not commit or push.** Make the change in the working tree and stop; the maintainer reviews and
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version" : "6.10.0",
|
"version" : "6.11.0",
|
||||||
"components" : [ {
|
"components" : [ {
|
||||||
"name" : "Blank Board",
|
"name" : "Blank Board",
|
||||||
"className" : "boards.BlankBoard",
|
"className" : "boards.BlankBoard",
|
||||||
@@ -1035,7 +1035,7 @@
|
|||||||
}, {
|
}, {
|
||||||
"name" : "Layer",
|
"name" : "Layer",
|
||||||
"type" : "PCBLayer",
|
"type" : "PCBLayer",
|
||||||
"possibleValues" : [ "_1", "_2", "_3", "_4", "_5", "_6", "_7", "_8" ],
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
"defaultValue" : "_1"
|
"defaultValue" : "_1"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Name",
|
"name" : "Name",
|
||||||
@@ -1077,7 +1077,7 @@
|
|||||||
}, {
|
}, {
|
||||||
"name" : "Layer",
|
"name" : "Layer",
|
||||||
"type" : "PCBLayer",
|
"type" : "PCBLayer",
|
||||||
"possibleValues" : [ "_1", "_2", "_3", "_4", "_5", "_6", "_7", "_8" ],
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
"defaultValue" : "_1"
|
"defaultValue" : "_1"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Name",
|
"name" : "Name",
|
||||||
@@ -1196,6 +1196,11 @@
|
|||||||
"creationMethod" : "SINGLE_CLICK",
|
"creationMethod" : "SINGLE_CLICK",
|
||||||
"notes" : [ "A junction marker for schematics and wiring diagrams; it is drawing only and connects nothing, since ends that meet at the same point are already connected. For a pad on a board use Solder Pad" ],
|
"notes" : [ "A junction marker for schematics and wiring diagrams; it is drawing only and connects nothing, since ends that meet at the same point are already connected. For a pad on a board use Solder Pad" ],
|
||||||
"properties" : [ {
|
"properties" : [ {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
|
}, {
|
||||||
"name" : "Color",
|
"name" : "Color",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
"format" : "hex",
|
"format" : "hex",
|
||||||
@@ -1277,7 +1282,7 @@
|
|||||||
}, {
|
}, {
|
||||||
"name" : "Layer",
|
"name" : "Layer",
|
||||||
"type" : "PCBLayer",
|
"type" : "PCBLayer",
|
||||||
"possibleValues" : [ "_1", "_2", "_3", "_4", "_5", "_6", "_7", "_8" ],
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
"defaultValue" : "_1"
|
"defaultValue" : "_1"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Name",
|
"name" : "Name",
|
||||||
@@ -1459,6 +1464,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Body",
|
"name" : "Body",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -1706,7 +1716,7 @@
|
|||||||
}, {
|
}, {
|
||||||
"name" : "Layer",
|
"name" : "Layer",
|
||||||
"type" : "PCBLayer",
|
"type" : "PCBLayer",
|
||||||
"possibleValues" : [ "_1", "_2", "_3", "_4", "_5", "_6", "_7", "_8" ],
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
"defaultValue" : "_1"
|
"defaultValue" : "_1"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Node Name",
|
"name" : "Node Name",
|
||||||
@@ -7155,6 +7165,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Font Size Override",
|
"name" : "Font Size Override",
|
||||||
"type" : "Integer"
|
"type" : "Integer"
|
||||||
@@ -7228,6 +7243,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Font Size Override",
|
"name" : "Font Size Override",
|
||||||
"type" : "Integer"
|
"type" : "Integer"
|
||||||
@@ -7306,6 +7326,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Font Size Override",
|
"name" : "Font Size Override",
|
||||||
"type" : "Integer"
|
"type" : "Integer"
|
||||||
@@ -7746,6 +7771,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Display",
|
"name" : "Display",
|
||||||
"type" : "Display",
|
"type" : "Display",
|
||||||
@@ -7851,6 +7881,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Body",
|
"name" : "Body",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -8509,6 +8544,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Name",
|
"name" : "Name",
|
||||||
"type" : "String"
|
"type" : "String"
|
||||||
@@ -8577,6 +8617,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Font Size Override",
|
"name" : "Font Size Override",
|
||||||
"type" : "Integer"
|
"type" : "Integer"
|
||||||
@@ -8645,6 +8690,11 @@
|
|||||||
}, {
|
}, {
|
||||||
"name" : "Angle Offset",
|
"name" : "Angle Offset",
|
||||||
"type" : "Angle"
|
"type" : "Angle"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Color",
|
"name" : "Color",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -9035,6 +9085,11 @@
|
|||||||
}, {
|
}, {
|
||||||
"name" : "Angle",
|
"name" : "Angle",
|
||||||
"type" : "Angle"
|
"type" : "Angle"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Color",
|
"name" : "Color",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -9372,6 +9427,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Body",
|
"name" : "Body",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -9496,6 +9556,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Body",
|
"name" : "Body",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -11842,6 +11907,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Border",
|
"name" : "Border",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -11970,7 +12040,7 @@
|
|||||||
}, {
|
}, {
|
||||||
"name" : "Layer",
|
"name" : "Layer",
|
||||||
"type" : "PCBLayer",
|
"type" : "PCBLayer",
|
||||||
"possibleValues" : [ "_1", "_2", "_3", "_4", "_5", "_6", "_7", "_8" ],
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
"defaultValue" : "_1"
|
"defaultValue" : "_1"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Orientation",
|
"name" : "Orientation",
|
||||||
@@ -12082,6 +12152,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Border",
|
"name" : "Border",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -12170,6 +12245,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Border",
|
"name" : "Border",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -12252,6 +12332,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Border",
|
"name" : "Border",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -12367,6 +12452,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Border",
|
"name" : "Border",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -12492,6 +12582,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Border",
|
"name" : "Border",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -12589,6 +12684,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Border",
|
"name" : "Border",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -12693,6 +12793,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Border",
|
"name" : "Border",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -12804,6 +12909,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Border",
|
"name" : "Border",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -12913,6 +13023,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Border",
|
"name" : "Border",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -12994,6 +13109,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Border",
|
"name" : "Border",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -13083,6 +13203,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Coil",
|
"name" : "Coil",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -13222,6 +13347,11 @@
|
|||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
"format" : "hex",
|
"format" : "hex",
|
||||||
"defaultValue" : "#333333"
|
"defaultValue" : "#333333"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Body",
|
"name" : "Body",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -13301,6 +13431,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Body",
|
"name" : "Body",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -13459,6 +13594,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Body",
|
"name" : "Body",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -13527,6 +13667,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Border",
|
"name" : "Border",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -13621,6 +13766,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Border",
|
"name" : "Border",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -13728,6 +13878,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Body",
|
"name" : "Body",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -13786,6 +13941,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Body",
|
"name" : "Body",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -13844,6 +14004,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Body",
|
"name" : "Body",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -16501,6 +16666,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Body",
|
"name" : "Body",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -16574,6 +16744,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Body",
|
"name" : "Body",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -16837,6 +17012,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Border",
|
"name" : "Border",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -16930,6 +17110,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Border",
|
"name" : "Border",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -17017,6 +17202,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Color",
|
"name" : "Color",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -17102,6 +17292,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Body",
|
"name" : "Body",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -17263,6 +17458,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Body",
|
"name" : "Body",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -17344,6 +17544,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Body",
|
"name" : "Body",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -17779,6 +17984,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Body",
|
"name" : "Body",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -18210,6 +18420,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Body",
|
"name" : "Body",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -19072,6 +19287,11 @@
|
|||||||
"type" : "Percentage",
|
"type" : "Percentage",
|
||||||
"format" : "number without the % sign, e.g. 100",
|
"format" : "number without the % sign, e.g. 100",
|
||||||
"defaultValue" : "100"
|
"defaultValue" : "100"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Body",
|
"name" : "Body",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
@@ -20011,6 +20231,11 @@
|
|||||||
"type" : "Base",
|
"type" : "Base",
|
||||||
"possibleValues" : [ "B9A", "OCTAL", "B7G", "B12C", "UX4" ],
|
"possibleValues" : [ "B9A", "OCTAL", "B7G", "B12C", "UX4" ],
|
||||||
"defaultValue" : "B9A"
|
"defaultValue" : "B9A"
|
||||||
|
}, {
|
||||||
|
"name" : "Board Side",
|
||||||
|
"type" : "PCBLayer",
|
||||||
|
"possibleValues" : [ "_1", "_2" ],
|
||||||
|
"defaultValue" : "_2"
|
||||||
}, {
|
}, {
|
||||||
"name" : "Color",
|
"name" : "Color",
|
||||||
"type" : "Color",
|
"type" : "Color",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version" : "6.10.0",
|
"version" : "6.11.0",
|
||||||
"categories" : {
|
"categories" : {
|
||||||
"Boards" : [ {
|
"Boards" : [ {
|
||||||
"name" : "Blank Board",
|
"name" : "Blank Board",
|
||||||
|
|||||||
@@ -72,5 +72,9 @@ public enum DrawOption {
|
|||||||
/**
|
/**
|
||||||
* When applied, all colors will be converted to blackest black or whitest white
|
* When applied, all colors will be converted to blackest black or whitest white
|
||||||
*/
|
*/
|
||||||
MONOCHROMATIC;
|
MONOCHROMATIC,
|
||||||
|
/**
|
||||||
|
* Paint on the bottom side of a board is drawn at reduced opacity, as if seen through the board.
|
||||||
|
*/
|
||||||
|
FADE_FAR_SIDE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,6 +110,8 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
|
|||||||
|
|
||||||
public static final String LOCKED_ALPHA = "lockedAlpha";
|
public static final String LOCKED_ALPHA = "lockedAlpha";
|
||||||
|
|
||||||
|
public static final String FADE_FAR_SIDE_KEY = "fadeFarSide";
|
||||||
|
|
||||||
public static final String LANGUAGE = "language";
|
public static final String LANGUAGE = "language";
|
||||||
public static final String LANGUAGE_DEFAULT = "English";
|
public static final String LANGUAGE_DEFAULT = "English";
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,11 @@ import org.diylc.core.gerber.GerberLayer;
|
|||||||
|
|
||||||
public enum PCBLayer {
|
public enum PCBLayer {
|
||||||
|
|
||||||
_1("Bottom"), _2("Top"), _3("Inner 1"), _4("Inner 2"), _5("Inner 3"), _6("Inner 4"), _7("Inner 5"), _8("Inner 6");
|
_1("Bottom"), _2("Top"),
|
||||||
|
// DIYLC models two-sided boards only. The inner layers are kept, in order, so that files using
|
||||||
|
// them still load with the same layer ids; the editor hides them and Gerber export rejects them.
|
||||||
|
@Deprecated _3("Inner 1"), @Deprecated _4("Inner 2"), @Deprecated _5("Inner 3"),
|
||||||
|
@Deprecated _6("Inner 4"), @Deprecated _7("Inner 5"), @Deprecated _8("Inner 6");
|
||||||
|
|
||||||
private String label;
|
private String label;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
DIY Layout Creator (DIYLC).
|
||||||
|
Copyright (c) 2009-2025 held jointly by the individual authors.
|
||||||
|
|
||||||
|
This file is part of DIYLC.
|
||||||
|
|
||||||
|
DIYLC is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
DIYLC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
*/
|
||||||
|
package org.diylc.core;
|
||||||
|
|
||||||
|
import org.diylc.common.PCBLayer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for components on one side of a board, such as a resistor, an IC or a trace. The side
|
||||||
|
* says where the part sits physically; it is separate from {@link ILayeredComponent}, which drives
|
||||||
|
* continuity, because the leads of a through-hole part connect to copper on both sides whichever
|
||||||
|
* side the part is mounted on. Copper implements it through {@link IPCBLayerComponent}, whose layer
|
||||||
|
* is its side and also drives its continuity.
|
||||||
|
*
|
||||||
|
* @author Branislav Stojkovic
|
||||||
|
*/
|
||||||
|
public interface IBoardSideComponent {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@link PCBLayer#_2} for the top of the board or {@link PCBLayer#_1} for the bottom,
|
||||||
|
* never an inner layer or null
|
||||||
|
*/
|
||||||
|
PCBLayer getBoardSide();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the side of the board the component is mounted on. The component is not mirrored.
|
||||||
|
*
|
||||||
|
* @param boardSide {@link PCBLayer#_2} for the top or {@link PCBLayer#_1} for the bottom
|
||||||
|
*/
|
||||||
|
void setBoardSide(PCBLayer boardSide);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@link PCBLayer#_1} for a component mounted on the bottom of the board, and
|
||||||
|
* {@link PCBLayer#_2} for any other, including components that have no side
|
||||||
|
*/
|
||||||
|
static PCBLayer sideOf(IDIYComponent<?> component) {
|
||||||
|
return component instanceof IBoardSideComponent sided && sided.getBoardSide() == PCBLayer._1
|
||||||
|
? PCBLayer._1 : PCBLayer._2;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.diylc.core;
|
package org.diylc.core;
|
||||||
|
|
||||||
|
import org.diylc.common.PCBLayer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for tracking component drawing process. Components may use it to stop or restart
|
* 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.
|
* tracking. Anything drawn while tracking is stopped will not be added to the mouse hot-spot area.
|
||||||
@@ -65,4 +67,26 @@ public interface IDrawingObserver {
|
|||||||
* @param marker
|
* @param marker
|
||||||
*/
|
*/
|
||||||
void setContinuityMarker(String marker);
|
void setContinuityMarker(String marker);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies the observer that what follows is painted on the given side of the board, until
|
||||||
|
* {@link #stopDrawingSide()}. Paint that is not bracketed is on the top (component) side. The
|
||||||
|
* observer may draw paint on the side facing away from the viewer at reduced opacity, as if seen
|
||||||
|
* through the board. Inner layers count as the bottom side.
|
||||||
|
*
|
||||||
|
* @param side the layer the paint lies on
|
||||||
|
*/
|
||||||
|
default void startDrawingSide(PCBLayer side) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies the observer that what follows is visible from both sides of the board, such as a
|
||||||
|
* drilled hole or a cut through the copper, and is never drawn faded, until
|
||||||
|
* {@link #stopDrawingSide()}.
|
||||||
|
*/
|
||||||
|
default void startDrawingBothSides() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies the observer that paint is back on the top (component) side.
|
||||||
|
*/
|
||||||
|
default void stopDrawingSide() {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
DIY Layout Creator (DIYLC).
|
||||||
|
Copyright (c) 2009-2025 held jointly by the individual authors.
|
||||||
|
|
||||||
|
This file is part of DIYLC.
|
||||||
|
|
||||||
|
DIYLC is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
DIYLC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
*/
|
||||||
|
package org.diylc.core;
|
||||||
|
|
||||||
|
import org.diylc.common.PCBLayer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for copper drawn on a layer of a PCB, such as a trace, pad, ground fill or PCB text.
|
||||||
|
* The layer is the copper's board side, but unlike the side of a mounted part it also decides
|
||||||
|
* which other copper the copper connects to. It keeps the name 'Layer' in the editor, which is
|
||||||
|
* what PCB tools call it for copper.
|
||||||
|
*
|
||||||
|
* @author Branislav Stojkovic
|
||||||
|
*/
|
||||||
|
public interface IPCBLayerComponent extends IBoardSideComponent {
|
||||||
|
|
||||||
|
PCBLayer getLayer();
|
||||||
|
|
||||||
|
void setLayer(PCBLayer layer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the layer, with the deprecated inner layers counted as the bottom
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default PCBLayer getBoardSide() {
|
||||||
|
return getLayer() == PCBLayer._2 ? PCBLayer._2 : PCBLayer._1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void setBoardSide(PCBLayer boardSide) {
|
||||||
|
setLayer(boardSide);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,8 +16,10 @@ import org.apache.log4j.Logger;
|
|||||||
|
|
||||||
import com.bancika.gerberwriter.DataLayer;
|
import com.bancika.gerberwriter.DataLayer;
|
||||||
|
|
||||||
|
import org.diylc.common.PCBLayer;
|
||||||
import org.diylc.core.ComponentState;
|
import org.diylc.core.ComponentState;
|
||||||
import org.diylc.core.IBoard;
|
import org.diylc.core.IBoard;
|
||||||
|
import org.diylc.core.IBoardSideComponent;
|
||||||
import org.diylc.core.IDIYComponent;
|
import org.diylc.core.IDIYComponent;
|
||||||
import org.diylc.core.IView;
|
import org.diylc.core.IView;
|
||||||
import org.diylc.core.Project;
|
import org.diylc.core.Project;
|
||||||
@@ -145,8 +147,12 @@ public class GerberExporter {
|
|||||||
LOG.info("Completed export to gerber");
|
LOG.info("Completed export to gerber");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void drawComponent(Project currentProject, GerberG2DWrapper g2d,
|
/**
|
||||||
IDIYComponent<?> c, boolean outlineMode) {
|
* Draws the specified component into the Gerber layers it belongs to. This is the only place that
|
||||||
|
* decides which layer a component's output goes to.
|
||||||
|
*/
|
||||||
|
static void drawComponent(Project currentProject, GerberG2DWrapper g2d,
|
||||||
|
IDIYComponent<?> c, boolean outlineMode) {
|
||||||
IGerberComponent gerberComponent = (IGerberComponent) c;
|
IGerberComponent gerberComponent = (IGerberComponent) c;
|
||||||
g2d.startedDrawingComponent();
|
g2d.startedDrawingComponent();
|
||||||
if (gerberComponent instanceof IGerberComponentCustom) {
|
if (gerberComponent instanceof IGerberComponentCustom) {
|
||||||
@@ -156,7 +162,10 @@ public class GerberExporter {
|
|||||||
IGerberComponentSimple gerberComponentSimple = (IGerberComponentSimple) gerberComponent;
|
IGerberComponentSimple gerberComponentSimple = (IGerberComponentSimple) gerberComponent;
|
||||||
g2d.startGerberOutput(gerberComponentSimple.getGerberLayer(),
|
g2d.startGerberOutput(gerberComponentSimple.getGerberLayer(),
|
||||||
gerberComponentSimple.getGerberFunction(), gerberComponentSimple.isGerberNegative());
|
gerberComponentSimple.getGerberFunction(), gerberComponentSimple.isGerberNegative());
|
||||||
|
// text on the bottom silkscreen is read from below, so it is written mirrored
|
||||||
|
g2d.setMirrorText(IBoardSideComponent.sideOf(c) == PCBLayer._1);
|
||||||
c.draw(g2d, ComponentState.NORMAL, outlineMode, currentProject, g2d);
|
c.draw(g2d, ComponentState.NORMAL, outlineMode, currentProject, g2d);
|
||||||
|
g2d.setMirrorText(false);
|
||||||
g2d.stopGerberOutput();
|
g2d.stopGerberOutput();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ public class GerberG2DWrapper extends Graphics2D
|
|||||||
private double tolerance;
|
private double tolerance;
|
||||||
|
|
||||||
private Rectangle2D boardRect;
|
private Rectangle2D boardRect;
|
||||||
|
private boolean mirrorText = false;
|
||||||
|
|
||||||
public GerberG2DWrapper(Graphics2D graphics2d, String diylcVersion, Rectangle2D boardRect) {
|
public GerberG2DWrapper(Graphics2D graphics2d, String diylcVersion, Rectangle2D boardRect) {
|
||||||
super();
|
super();
|
||||||
@@ -154,6 +155,15 @@ public class GerberG2DWrapper extends Graphics2D
|
|||||||
return layerMap;
|
return layerMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether text is written mirrored, each string about its own centre. The output is in top
|
||||||
|
* view, so text on the bottom side has to be mirrored to read correctly once the board is turned
|
||||||
|
* over.
|
||||||
|
*/
|
||||||
|
public void setMirrorText(boolean mirrorText) {
|
||||||
|
this.mirrorText = mirrorText;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Shape s) {
|
public void draw(Shape s) {
|
||||||
if (trackingGerber && !getColor().equals(Constants.TRANSPARENT_COLOR)) {
|
if (trackingGerber && !getColor().equals(Constants.TRANSPARENT_COLOR)) {
|
||||||
@@ -181,6 +191,10 @@ public class GerberG2DWrapper extends Graphics2D
|
|||||||
GlyphVector gv = font.createGlyphVector(graphics2d.getFontRenderContext(), str);
|
GlyphVector gv = font.createGlyphVector(graphics2d.getFontRenderContext(), str);
|
||||||
|
|
||||||
AffineTransform translateInstance = AffineTransform.getTranslateInstance(x, y);
|
AffineTransform translateInstance = AffineTransform.getTranslateInstance(x, y);
|
||||||
|
if (mirrorText) {
|
||||||
|
translateInstance.translate(gv.getLogicalBounds().getWidth(), 0);
|
||||||
|
translateInstance.scale(-1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < gv.getNumGlyphs(); i++) {
|
for (int i = 0; i < gv.getNumGlyphs(); i++) {
|
||||||
Shape glyphShape = gv.getGlyphOutline(i);
|
Shape glyphShape = gv.getGlyphOutline(i);
|
||||||
|
|||||||
@@ -25,29 +25,10 @@ import com.bancika.gerberwriter.Point;
|
|||||||
import com.bancika.gerberwriter.path.MoveTo;
|
import com.bancika.gerberwriter.path.MoveTo;
|
||||||
import com.bancika.gerberwriter.path.Path;
|
import com.bancika.gerberwriter.path.Path;
|
||||||
|
|
||||||
import org.diylc.core.ComponentState;
|
|
||||||
import org.diylc.core.IDIYComponent;
|
|
||||||
import org.diylc.core.Project;
|
|
||||||
import org.diylc.core.measures.SizeUnit;
|
import org.diylc.core.measures.SizeUnit;
|
||||||
|
|
||||||
public class GerberPathRenderer {
|
public class GerberPathRenderer {
|
||||||
|
|
||||||
public static void drawComponent(Project currentProject, GerberG2DWrapper g2d, IDIYComponent<?> c,
|
|
||||||
boolean outlineMode) {
|
|
||||||
IGerberComponent gerberComponent = (IGerberComponent) c;
|
|
||||||
g2d.startedDrawingComponent();
|
|
||||||
if (gerberComponent instanceof IGerberComponentCustom) {
|
|
||||||
IGerberComponentCustom gerberComponentCustom = (IGerberComponentCustom) gerberComponent;
|
|
||||||
gerberComponentCustom.draw(g2d, ComponentState.NORMAL, outlineMode, currentProject, g2d, g2d);
|
|
||||||
} else if (gerberComponent instanceof IGerberComponentSimple) {
|
|
||||||
IGerberComponentSimple gerberComponentSimple = (IGerberComponentSimple) gerberComponent;
|
|
||||||
g2d.startGerberOutput(gerberComponentSimple.getGerberLayer(),
|
|
||||||
gerberComponentSimple.getGerberFunction(), gerberComponentSimple.isGerberNegative());
|
|
||||||
c.draw(g2d, ComponentState.NORMAL, outlineMode, currentProject, g2d);
|
|
||||||
g2d.stopGerberOutput();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void outputPathArea(PathIterator pathIterator, DataLayer dataLayer, double d,
|
public static void outputPathArea(PathIterator pathIterator, DataLayer dataLayer, double d,
|
||||||
boolean isNegative, String function) {
|
boolean isNegative, String function) {
|
||||||
List<PathWithNegative> outputPath =
|
List<PathWithNegative> outputPath =
|
||||||
|
|||||||
@@ -1,9 +1,18 @@
|
|||||||
package org.diylc.core.gerber;
|
package org.diylc.core.gerber;
|
||||||
|
|
||||||
|
import org.diylc.common.PCBLayer;
|
||||||
|
import org.diylc.core.IBoardSideComponent;
|
||||||
|
import org.diylc.core.IDIYComponent;
|
||||||
|
|
||||||
public interface IGerberComponentSimple extends IGerberComponent {
|
public interface IGerberComponentSimple extends IGerberComponent {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the silkscreen on the side of the board the component is mounted on
|
||||||
|
*/
|
||||||
default GerberLayer getGerberLayer() {
|
default GerberLayer getGerberLayer() {
|
||||||
return GerberLayer.SilkscreenTop;
|
return this instanceof IDIYComponent<?> component
|
||||||
|
&& IBoardSideComponent.sideOf(component) == PCBLayer._1
|
||||||
|
? GerberLayer.SilkscreenBot : GerberLayer.SilkscreenTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
default String getGerberFunction() {
|
default String getGerberFunction() {
|
||||||
|
|||||||
@@ -21,10 +21,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.diylc.filter;
|
package org.diylc.filter;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
import org.diylc.common.PCBLayer;
|
import org.diylc.common.PCBLayer;
|
||||||
import org.diylc.core.IDIYComponent;
|
import org.diylc.core.IDIYComponent;
|
||||||
|
import org.diylc.core.IPCBLayerComponent;
|
||||||
|
|
||||||
public class PCBLayerFilter implements IComponentFilter {
|
public class PCBLayerFilter implements IComponentFilter {
|
||||||
|
|
||||||
@@ -37,13 +36,6 @@ public class PCBLayerFilter implements IComponentFilter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean testComponent(IDIYComponent<?> component) {
|
public boolean testComponent(IDIYComponent<?> component) {
|
||||||
Class<?> clazz = component.getClass();
|
return component instanceof IPCBLayerComponent copper && copper.getLayer() == layer;
|
||||||
try {
|
|
||||||
Method m = clazz.getMethod("getLayer");
|
|
||||||
PCBLayer l = (PCBLayer) m.invoke(component);
|
|
||||||
return layer == l;
|
|
||||||
} catch (Exception e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package org.diylc.filter;
|
package org.diylc.filter;
|
||||||
|
|
||||||
|
import org.diylc.common.PCBLayer;
|
||||||
import org.diylc.core.IBoard;
|
import org.diylc.core.IBoard;
|
||||||
|
import org.diylc.core.IBoardSideComponent;
|
||||||
import org.diylc.core.IDIYComponent;
|
import org.diylc.core.IDIYComponent;
|
||||||
import org.diylc.core.gerber.GerberRenderMode;
|
import org.diylc.core.gerber.GerberRenderMode;
|
||||||
import org.diylc.core.gerber.IGerberComponent;
|
import org.diylc.core.gerber.IGerberComponent;
|
||||||
@@ -9,6 +11,20 @@ import java.util.Set;
|
|||||||
|
|
||||||
public class SilkScreenFilter implements IComponentFilter {
|
public class SilkScreenFilter implements IComponentFilter {
|
||||||
|
|
||||||
|
private PCBLayer side;
|
||||||
|
|
||||||
|
public SilkScreenFilter() {
|
||||||
|
this(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param side the side of the board whose silkscreen to keep, or null for both; board outlines
|
||||||
|
* are kept on either side
|
||||||
|
*/
|
||||||
|
public SilkScreenFilter(PCBLayer side) {
|
||||||
|
this.side = side;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean testComponent(IDIYComponent<?> component) {
|
public boolean testComponent(IDIYComponent<?> component) {
|
||||||
if (component instanceof IBoard board) {
|
if (component instanceof IBoard board) {
|
||||||
@@ -17,6 +33,9 @@ public class SilkScreenFilter implements IComponentFilter {
|
|||||||
if (!(component instanceof IGerberComponent gerberComponent)) {
|
if (!(component instanceof IGerberComponent gerberComponent)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (side != null && IBoardSideComponent.sideOf(component) != side) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
Set<GerberRenderMode> gerberRenderModes = gerberComponent.getGerberRenderModes();
|
Set<GerberRenderMode> gerberRenderModes = gerberComponent.getGerberRenderModes();
|
||||||
return gerberRenderModes.contains(GerberRenderMode.Outline);
|
return gerberRenderModes.contains(GerberRenderMode.Outline);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ import org.diylc.presenter.ComparatorFactory;
|
|||||||
import org.diylc.presenter.ComponentProcessor;
|
import org.diylc.presenter.ComponentProcessor;
|
||||||
import org.diylc.presenter.DatasheetService;
|
import org.diylc.presenter.DatasheetService;
|
||||||
import org.diylc.presenter.ReleaseHistory;
|
import org.diylc.presenter.ReleaseHistory;
|
||||||
|
import org.diylc.utils.ReflectionUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standalone tool that generates component catalog JSON files from the current codebase.
|
* Standalone tool that generates component catalog JSON files from the current codebase.
|
||||||
@@ -227,9 +228,11 @@ public class ComponentCatalogGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include enum possible values (using name() instead of toString())
|
// Include enum possible values (using name() instead of toString()), leaving out the
|
||||||
|
// deprecated ones the editor does not offer either
|
||||||
if (propType.isEnum()) {
|
if (propType.isEnum()) {
|
||||||
List<String> possibleValues = Arrays.stream(propType.getEnumConstants())
|
List<String> possibleValues = Arrays.stream(propType.getEnumConstants())
|
||||||
|
.filter(e -> !ReflectionUtils.isDeprecated((Enum<?>) e))
|
||||||
.map(e -> ((Enum<?>) e).name())
|
.map(e -> ((Enum<?>) e).name())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
prop.put("possibleValues", possibleValues);
|
prop.put("possibleValues", possibleValues);
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import org.diylc.common.ComponentType;
|
|||||||
import org.diylc.common.DrawOption;
|
import org.diylc.common.DrawOption;
|
||||||
import org.diylc.core.ComponentForRender;
|
import org.diylc.core.ComponentForRender;
|
||||||
import org.diylc.core.ComponentState;
|
import org.diylc.core.ComponentState;
|
||||||
|
import org.diylc.core.IBoardSideComponent;
|
||||||
import org.diylc.core.IDIYComponent;
|
import org.diylc.core.IDIYComponent;
|
||||||
import org.diylc.core.Project;
|
import org.diylc.core.Project;
|
||||||
import org.diylc.core.annotations.ComponentDescriptor;
|
import org.diylc.core.annotations.ComponentDescriptor;
|
||||||
@@ -153,12 +154,16 @@ public class DrawingCache {
|
|||||||
if (Math.abs(1.0 - zoom) > 1e-4) {
|
if (Math.abs(1.0 - zoom) > 1e-4) {
|
||||||
g2d.getCanvasGraphics().scale(1 / zoom, 1 / zoom);
|
g2d.getCanvasGraphics().scale(1 / zoom, 1 / zoom);
|
||||||
}
|
}
|
||||||
|
// the image was rendered with the far-side fade already applied, so pasting it must not
|
||||||
|
// fade it again
|
||||||
|
g2d.startDrawingBothSides();
|
||||||
try {
|
try {
|
||||||
// draw cached image
|
// draw cached image
|
||||||
g2d.scale(1 / scaleFactor, 1 / scaleFactor);
|
g2d.scale(1 / scaleFactor, 1 / scaleFactor);
|
||||||
g2d.getCanvasGraphics().drawImage(value.getImage(), (int) ((firstPoint.getX() - value.getDx()) * zoom * scaleFactor),
|
g2d.getCanvasGraphics().drawImage(value.getImage(), (int) ((firstPoint.getX() - value.getDx()) * zoom * scaleFactor),
|
||||||
(int) ((firstPoint.getY() - value.getDy())* zoom * scaleFactor), null);
|
(int) ((firstPoint.getY() - value.getDy())* zoom * scaleFactor), null);
|
||||||
} finally {
|
} finally {
|
||||||
|
g2d.stopDrawingSide();
|
||||||
if (Math.abs(1.0 - zoom) > 1e-4) {
|
if (Math.abs(1.0 - zoom) > 1e-4) {
|
||||||
g2d.getCanvasGraphics().scale(zoom, zoom);
|
g2d.getCanvasGraphics().scale(zoom, zoom);
|
||||||
}
|
}
|
||||||
@@ -347,6 +352,7 @@ public class DrawingCache {
|
|||||||
|
|
||||||
// initialize wrapper
|
// initialize wrapper
|
||||||
wrapper.startedDrawingComponent(zOrder);
|
wrapper.startedDrawingComponent(zOrder);
|
||||||
|
wrapper.setUndeclaredSide(IBoardSideComponent.sideOf(component));
|
||||||
|
|
||||||
long componentStart = System.nanoTime();
|
long componentStart = System.nanoTime();
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ import org.diylc.utils.Constants;
|
|||||||
public class DrawingManager {
|
public class DrawingManager {
|
||||||
|
|
||||||
private static final Logger LOG = Logger.getLogger(DrawingManager.class);
|
private static final Logger LOG = Logger.getLogger(DrawingManager.class);
|
||||||
public static final Percentage MIRROR_ALPHA = new Percentage(50);
|
public static Percentage FAR_SIDE_ALPHA = new Percentage(55);
|
||||||
|
|
||||||
public static int CONTROL_POINT_SIZE = 7;
|
public static int CONTROL_POINT_SIZE = 7;
|
||||||
public static double EXTRA_SPACE = 0.25;
|
public static double EXTRA_SPACE = 0.25;
|
||||||
@@ -118,6 +118,9 @@ public class DrawingManager {
|
|||||||
|
|
||||||
private List<Area> proximityMarkers = null;
|
private List<Area> proximityMarkers = null;
|
||||||
|
|
||||||
|
// the board whose underside mirror the component in the slot is being placed through
|
||||||
|
private IBoard slotMirrorBoard = null;
|
||||||
|
|
||||||
public DrawingManager(MessageDispatcher<EventType> messageDispatcher,
|
public DrawingManager(MessageDispatcher<EventType> messageDispatcher,
|
||||||
IConfigurationManager<?> configManager) {
|
IConfigurationManager<?> configManager) {
|
||||||
super();
|
super();
|
||||||
@@ -193,37 +196,12 @@ public class DrawingManager {
|
|||||||
|
|
||||||
configureRenderingHints(g2d, drawOptions);
|
configureRenderingHints(g2d, drawOptions);
|
||||||
|
|
||||||
// group components with boards that contain them
|
// group components with the boards whose underside mirror shows them
|
||||||
Map<IBoard, List<IDIYComponent<?>>> boardMap = project.getComponents().stream()
|
|
||||||
.filter(IBoard.class::isInstance)
|
|
||||||
.map(IBoard.class::cast)
|
|
||||||
.filter(b -> b.getUndersideDisplay() != null && b.getUndersideDisplay() != BoardUndersideDisplay.NONE)
|
|
||||||
.collect(Collectors.toMap(x -> x, x -> new ArrayList<IDIYComponent<?>>()));
|
|
||||||
Map<IDIYComponent<?>, Set<IBoard>> componentBoardMap = new HashMap<IDIYComponent<?>, Set<IBoard>>();
|
Map<IDIYComponent<?>, Set<IBoard>> componentBoardMap = new HashMap<IDIYComponent<?>, Set<IBoard>>();
|
||||||
|
List<IBoard> mirroringBoards = UndersideMirror.getMirroringBoards(project);
|
||||||
for (IBoard board : boardMap.keySet()) {
|
for (IBoard board : mirroringBoards) {
|
||||||
Rectangle2D boardRect = board.getBoardRectangle();
|
|
||||||
if (boardRect == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
double minX = Math.min(boardRect.getMinX(), boardRect.getMaxX());
|
|
||||||
double maxX = Math.max(boardRect.getMinX(), boardRect.getMaxX());
|
|
||||||
double minY = Math.min(boardRect.getMinY(), boardRect.getMaxY());
|
|
||||||
double maxY = Math.max(boardRect.getMinY(), boardRect.getMaxY());
|
|
||||||
Rectangle2D normalizedBoardRect = new Rectangle2D.Double(minX, minY, maxX - minX, maxY - minY);
|
|
||||||
for (IDIYComponent<?> c : project.getComponents()) {
|
for (IDIYComponent<?> c : project.getComponents()) {
|
||||||
if (c == board) {
|
if (c != board && UndersideMirror.isMirrored(board, c)) {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
boolean include = false;
|
|
||||||
for (int i = 0; i < c.getControlPointCount(); i++) {
|
|
||||||
if (normalizedBoardRect.contains(c.getControlPoint(i))) {
|
|
||||||
include = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (include) {
|
|
||||||
boardMap.get(board).add(c);
|
|
||||||
componentBoardMap.computeIfAbsent(c, key -> new HashSet<IBoard>()).add(board);
|
componentBoardMap.computeIfAbsent(c, key -> new HashSet<IBoard>()).add(board);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -328,6 +306,8 @@ public class DrawingManager {
|
|||||||
if (lockedComponents.contains(component) && drawOptions.contains(DrawOption.LOCKED_ALPHA)) {
|
if (lockedComponents.contains(component) && drawOptions.contains(DrawOption.LOCKED_ALPHA)) {
|
||||||
g2d.setComposite(lockedComposite);
|
g2d.setComposite(lockedComposite);
|
||||||
}
|
}
|
||||||
|
// after the locked composite, which is set on the canvas and would replace the fade
|
||||||
|
g2dWrapper.setUndeclaredSide(IBoardSideComponent.sideOf(component));
|
||||||
// Draw the component through the g2dWrapper.
|
// Draw the component through the g2dWrapper.
|
||||||
long componentStart = System.nanoTime();
|
long componentStart = System.nanoTime();
|
||||||
try {
|
try {
|
||||||
@@ -359,6 +339,7 @@ public class DrawingManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ComponentArea area = g2dWrapper.finishedDrawingComponent();
|
ComponentArea area = g2dWrapper.finishedDrawingComponent();
|
||||||
|
g2dWrapper.setUndeclaredSide(PCBLayer._2);
|
||||||
// after finishedDrawingComponent, which reverts the transform the clip was taken in
|
// after finishedDrawingComponent, which reverts the transform the clip was taken in
|
||||||
if (visibleClip != null) {
|
if (visibleClip != null) {
|
||||||
g2d.setClip(visibleClip);
|
g2d.setClip(visibleClip);
|
||||||
@@ -427,20 +408,23 @@ public class DrawingManager {
|
|||||||
|| component.getControlPointVisibilityPolicy(i) == VisibilityPolicy.ALWAYS)) {
|
|| component.getControlPointVisibilityPolicy(i) == VisibilityPolicy.ALWAYS)) {
|
||||||
|
|
||||||
Point2D controlPoint = component.getControlPoint(i);
|
Point2D controlPoint = component.getControlPoint(i);
|
||||||
int pointSize = CONTROL_POINT_SIZE;
|
drawSelectedControlPoint(g2dWrapper, controlPoint);
|
||||||
|
// the part can be selected through its mirrored copy, which then shows its points too
|
||||||
g2dWrapper.setColor(SELECTED_CONTROL_POINT_COLOR.darker());
|
for (IBoard board : mirroringBoards) {
|
||||||
g2dWrapper.fillOval((int) Math.round(controlPoint.getX() - pointSize / 2),
|
if (UndersideMirror.isMirrored(board, component)) {
|
||||||
(int) Math.round(controlPoint.getY() - pointSize / 2), pointSize, pointSize);
|
drawSelectedControlPoint(g2dWrapper,
|
||||||
g2dWrapper.setColor(SELECTED_CONTROL_POINT_COLOR);
|
UndersideMirror.createTransform(board).transform(controlPoint, null));
|
||||||
g2dWrapper.fillOval((int) Math.round(controlPoint.getX() - CONTROL_POINT_SIZE / 2 + 1),
|
}
|
||||||
(int) Math.round(controlPoint.getY() - CONTROL_POINT_SIZE / 2 + 1), CONTROL_POINT_SIZE - 2,
|
}
|
||||||
CONTROL_POINT_SIZE - 2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// a component being placed through an underside mirror is shown there, under the cursor
|
||||||
|
AffineTransform slotTx =
|
||||||
|
slotMirrorBoard == null ? null : UndersideMirror.createTransform(slotMirrorBoard);
|
||||||
|
|
||||||
// Draw component slot in a separate composite.
|
// Draw component slot in a separate composite.
|
||||||
if (componentSlot != null) {
|
if (componentSlot != null) {
|
||||||
for (IDIYComponent<?> component : componentSlot) {
|
for (IDIYComponent<?> component : componentSlot) {
|
||||||
@@ -448,6 +432,9 @@ public class DrawingManager {
|
|||||||
// leaves behind (e.g. a rotated Label) is reverted before the next one is drawn
|
// leaves behind (e.g. a rotated Label) is reverted before the next one is drawn
|
||||||
g2dWrapper.startedDrawingComponent(project.getComponents().size());
|
g2dWrapper.startedDrawingComponent(project.getComponents().size());
|
||||||
g2dWrapper.setComposite(slotComposite);
|
g2dWrapper.setComposite(slotComposite);
|
||||||
|
if (slotTx != null) {
|
||||||
|
viewThroughMirror(g2dWrapper, slotMirrorBoard, slotTx, component);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
component.draw(g2dWrapper, ComponentState.NORMAL,
|
component.draw(g2dWrapper, ComponentState.NORMAL,
|
||||||
drawOptions.contains(DrawOption.OUTLINE_MODE), project, g2dWrapper);
|
drawOptions.contains(DrawOption.OUTLINE_MODE), project, g2dWrapper);
|
||||||
@@ -455,6 +442,9 @@ public class DrawingManager {
|
|||||||
LOG.error("Error drawing " + component.getName(), e);
|
LOG.error("Error drawing " + component.getName(), e);
|
||||||
failedComponents.add(component);
|
failedComponents.add(component);
|
||||||
} finally {
|
} finally {
|
||||||
|
if (slotTx != null) {
|
||||||
|
stopViewingThroughMirror(g2dWrapper);
|
||||||
|
}
|
||||||
g2dWrapper.finishedDrawingComponent();
|
g2dWrapper.finishedDrawingComponent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -462,7 +452,9 @@ public class DrawingManager {
|
|||||||
|
|
||||||
// Draw control points of the component in the slot.
|
// Draw control points of the component in the slot.
|
||||||
if (controlPointSlot != null) {
|
if (controlPointSlot != null) {
|
||||||
for (Point2D point : controlPointSlot) {
|
for (Point2D slotPoint : controlPointSlot) {
|
||||||
|
Point2D point =
|
||||||
|
slotTx == null || slotPoint == null ? slotPoint : slotTx.transform(slotPoint, null);
|
||||||
if (point != null) {
|
if (point != null) {
|
||||||
g2dWrapper.setColor(SELECTED_CONTROL_POINT_COLOR.darker());
|
g2dWrapper.setColor(SELECTED_CONTROL_POINT_COLOR.darker());
|
||||||
g2dWrapper.fillOval((int) Math.round(point.getX() - CONTROL_POINT_SIZE / 2),
|
g2dWrapper.fillOval((int) Math.round(point.getX() - CONTROL_POINT_SIZE / 2),
|
||||||
@@ -553,89 +545,58 @@ public class DrawingManager {
|
|||||||
return failedComponents;
|
return failedComponents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void drawSelectedControlPoint(G2DWrapper g2dWrapper, Point2D controlPoint) {
|
||||||
|
g2dWrapper.setColor(SELECTED_CONTROL_POINT_COLOR.darker());
|
||||||
|
g2dWrapper.fillOval((int) Math.round(controlPoint.getX() - CONTROL_POINT_SIZE / 2),
|
||||||
|
(int) Math.round(controlPoint.getY() - CONTROL_POINT_SIZE / 2), CONTROL_POINT_SIZE,
|
||||||
|
CONTROL_POINT_SIZE);
|
||||||
|
g2dWrapper.setColor(SELECTED_CONTROL_POINT_COLOR);
|
||||||
|
g2dWrapper.fillOval((int) Math.round(controlPoint.getX() - CONTROL_POINT_SIZE / 2 + 1),
|
||||||
|
(int) Math.round(controlPoint.getY() - CONTROL_POINT_SIZE / 2 + 1), CONTROL_POINT_SIZE - 2,
|
||||||
|
CONTROL_POINT_SIZE - 2);
|
||||||
|
}
|
||||||
|
|
||||||
private static void drawMirroredComponent(Project project, IBoard board, IDIYComponent<?> component,
|
private static void drawMirroredComponent(Project project, IBoard board, IDIYComponent<?> component,
|
||||||
G2DWrapper g2dWrapper, ComponentState state, boolean outlineMode) {
|
G2DWrapper g2dWrapper, ComponentState state, boolean outlineMode) {
|
||||||
if (board.getUndersideDisplay() == null || board.getUndersideDisplay() == BoardUndersideDisplay.NONE) {
|
AffineTransform mirrorTx = UndersideMirror.createTransform(board);
|
||||||
|
if (mirrorTx == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
double offset = board.getUndersideOffset() == null ? 0 : board.getUndersideOffset().convertToPixels();
|
|
||||||
Rectangle2D boardRectangle = board.getBoardRectangle();
|
|
||||||
if (boardRectangle == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
double minX = Math.min(boardRectangle.getMinX(), boardRectangle.getMaxX());
|
|
||||||
double maxX = Math.max(boardRectangle.getMinX(), boardRectangle.getMaxX());
|
|
||||||
double minY = Math.min(boardRectangle.getMinY(), boardRectangle.getMaxY());
|
|
||||||
double maxY = Math.max(boardRectangle.getMinY(), boardRectangle.getMaxY());
|
|
||||||
|
|
||||||
AffineTransform mirrorTx = new AffineTransform();
|
|
||||||
switch (board.getUndersideDisplay()) {
|
|
||||||
case ABOVE: {
|
|
||||||
double pivotY = minY - offset / 2;
|
|
||||||
mirrorTx.translate(0, pivotY);
|
|
||||||
mirrorTx.scale(1.0, -1.0);
|
|
||||||
mirrorTx.translate(0, -pivotY);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BELOW: {
|
|
||||||
double pivotY = maxY + offset / 2;
|
|
||||||
mirrorTx.translate(0, pivotY);
|
|
||||||
mirrorTx.scale(1.0, -1.0);
|
|
||||||
mirrorTx.translate(0, -pivotY);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LEFT: {
|
|
||||||
double pivotX = minX - offset / 2;
|
|
||||||
mirrorTx.translate(pivotX, 0);
|
|
||||||
mirrorTx.scale(-1.0, 1.0);
|
|
||||||
mirrorTx.translate(-pivotX, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case RIGHT: {
|
|
||||||
double pivotX = maxX + offset / 2;
|
|
||||||
mirrorTx.translate(pivotX, 0);
|
|
||||||
mirrorTx.scale(-1.0, 1.0);
|
|
||||||
mirrorTx.translate(-pivotX, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
G2DWrapper.MirrorDirection mirrorDirection;
|
|
||||||
switch (board.getUndersideDisplay()) {
|
|
||||||
case ABOVE:
|
|
||||||
case BELOW:
|
|
||||||
mirrorDirection = G2DWrapper.MirrorDirection.VERTICAL;
|
|
||||||
break;
|
|
||||||
case LEFT:
|
|
||||||
case RIGHT:
|
|
||||||
mirrorDirection = G2DWrapper.MirrorDirection.HORIZONTAL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
mirrorDirection = G2DWrapper.MirrorDirection.NONE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
AffineTransform oldTx = g2dWrapper.getTransform();
|
AffineTransform oldTx = g2dWrapper.getTransform();
|
||||||
Composite oldComposite = g2dWrapper.getComposite();
|
Composite oldComposite = g2dWrapper.getComposite();
|
||||||
g2dWrapper.setMirrorDirection(mirrorDirection);
|
|
||||||
try {
|
try {
|
||||||
g2dWrapper.transform(mirrorTx);
|
viewThroughMirror(g2dWrapper, board, mirrorTx, component);
|
||||||
if (Boolean.TRUE.equals(board.getUndersideTransparency())) {
|
|
||||||
g2dWrapper.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float)(MIRROR_ALPHA.getValue().doubleValue() / 100d)));
|
|
||||||
}
|
|
||||||
component.draw(g2dWrapper, state, outlineMode, project, g2dWrapper);
|
component.draw(g2dWrapper, state, outlineMode, project, g2dWrapper);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.error("Error drawing mirrored " + component.getName(), e);
|
LOG.error("Error drawing mirrored " + component.getName(), e);
|
||||||
} finally {
|
} finally {
|
||||||
g2dWrapper.setMirrorDirection(G2DWrapper.MirrorDirection.NONE);
|
stopViewingThroughMirror(g2dWrapper);
|
||||||
g2dWrapper.setTransform(oldTx);
|
g2dWrapper.setTransform(oldTx);
|
||||||
g2dWrapper.setComposite(oldComposite);
|
g2dWrapper.setComposite(oldComposite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the wrapper up to draw the component into the board's underside mirror: reflected, with
|
||||||
|
* text kept readable, and seen from the bottom.
|
||||||
|
*/
|
||||||
|
private static void viewThroughMirror(G2DWrapper g2dWrapper, IBoard board,
|
||||||
|
AffineTransform mirrorTx, IDIYComponent<?> component) {
|
||||||
|
g2dWrapper.setMirrorDirection(UndersideMirror.getMirrorDirection(board));
|
||||||
|
g2dWrapper.transform(mirrorTx);
|
||||||
|
// the mirror is the copper side, so copper and the parts mounted on it are drawn solid and
|
||||||
|
// the component side faded
|
||||||
|
g2dWrapper.setViewedSide(PCBLayer._1, Boolean.TRUE.equals(board.getUndersideTransparency()),
|
||||||
|
component instanceof IBoard ? PCBLayer._1 : IBoardSideComponent.sideOf(component));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void stopViewingThroughMirror(G2DWrapper g2dWrapper) {
|
||||||
|
g2dWrapper.setMirrorDirection(G2DWrapper.MirrorDirection.NONE);
|
||||||
|
g2dWrapper.stopDrawingSide();
|
||||||
|
g2dWrapper.resetViewedSide();
|
||||||
|
}
|
||||||
|
|
||||||
private static void drawComponent(Project project, Set<DrawOption> drawOptions, Double scaleFactor,
|
private static void drawComponent(Project project, Set<DrawOption> drawOptions, Double scaleFactor,
|
||||||
Rectangle2D visibleRect, IDIYComponent<?> component, G2DWrapper g2dWrapper, ComponentState state,
|
Rectangle2D visibleRect, IDIYComponent<?> component, G2DWrapper g2dWrapper, ComponentState state,
|
||||||
double zoom, int i, boolean outlineMode, boolean cacheable) {
|
double zoom, int i, boolean outlineMode, boolean cacheable) {
|
||||||
@@ -777,6 +738,16 @@ public class DrawingManager {
|
|||||||
proximityMarkers = null;
|
proximityMarkers = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the board whose underside mirror the component being placed is drawn through, or null to
|
||||||
|
* draw it in the main view.
|
||||||
|
*
|
||||||
|
* @param slotMirrorBoard
|
||||||
|
*/
|
||||||
|
public void setSlotMirrorBoard(IBoard slotMirrorBoard) {
|
||||||
|
this.slotMirrorBoard = slotMirrorBoard;
|
||||||
|
}
|
||||||
|
|
||||||
public void clearContinuityArea() {
|
public void clearContinuityArea() {
|
||||||
currentContinuityAreas = null;
|
currentContinuityAreas = null;
|
||||||
continuityGraphCache = null;
|
continuityGraphCache = null;
|
||||||
@@ -796,6 +767,50 @@ public class DrawingManager {
|
|||||||
return components;
|
return components;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the components that the underside mirror of a board shows at the specified point, top
|
||||||
|
* first, or none when the point is not in a mirror.
|
||||||
|
*
|
||||||
|
* @param point
|
||||||
|
* @param project
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<IDIYComponent<?>> findMirroredComponentsAt(Point2D point, Project project) {
|
||||||
|
List<IDIYComponent<?>> components = new ArrayList<IDIYComponent<?>>();
|
||||||
|
for (IBoard board : UndersideMirror.findBoardsMirroredAt(project, point)) {
|
||||||
|
for (IDIYComponent<?> component : findMirroredComponentsAt(point, project, board)) {
|
||||||
|
if (!components.contains(component)) {
|
||||||
|
components.add(component);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return components;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the components that the underside mirror of the specified board shows at the specified
|
||||||
|
* point, top first, or none when the point is not in that mirror.
|
||||||
|
*
|
||||||
|
* @param point
|
||||||
|
* @param project
|
||||||
|
* @param board
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<IDIYComponent<?>> findMirroredComponentsAt(Point2D point, Project project,
|
||||||
|
IBoard board) {
|
||||||
|
List<IDIYComponent<?>> components = new ArrayList<IDIYComponent<?>>();
|
||||||
|
AffineTransform mirrorTx = UndersideMirror.createTransform(board);
|
||||||
|
if (mirrorTx == null || !UndersideMirror.getMirrorRegion(board).contains(point)) {
|
||||||
|
return components;
|
||||||
|
}
|
||||||
|
for (IDIYComponent<?> component : findComponentsAt(mirrorTx.transform(point, null), project)) {
|
||||||
|
if (UndersideMirror.isMirrored(board, component)) {
|
||||||
|
components.add(component);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return components;
|
||||||
|
}
|
||||||
|
|
||||||
public double getExtraSpace(Project project) {
|
public double getExtraSpace(Project project) {
|
||||||
double width = project.getWidth().convertToPixels();
|
double width = project.getWidth().convertToPixels();
|
||||||
double height = project.getHeight().convertToPixels();
|
double height = project.getHeight().convertToPixels();
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.diylc.presenter;
|
package org.diylc.presenter;
|
||||||
|
|
||||||
|
import java.awt.AlphaComposite;
|
||||||
import java.awt.BasicStroke;
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Composite;
|
import java.awt.Composite;
|
||||||
@@ -60,6 +61,7 @@ import java.util.Map.Entry;
|
|||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.diylc.common.DrawOption;
|
import org.diylc.common.DrawOption;
|
||||||
import org.diylc.common.ObjectCache;
|
import org.diylc.common.ObjectCache;
|
||||||
|
import org.diylc.common.PCBLayer;
|
||||||
import org.diylc.common.ZoomableStroke;
|
import org.diylc.common.ZoomableStroke;
|
||||||
import org.diylc.core.IDrawingObserver;
|
import org.diylc.core.IDrawingObserver;
|
||||||
|
|
||||||
@@ -118,6 +120,17 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver {
|
|||||||
|
|
||||||
private MirrorDirection mirrorDirection = MirrorDirection.NONE;
|
private MirrorDirection mirrorDirection = MirrorDirection.NONE;
|
||||||
|
|
||||||
|
private PCBLayer viewedSide = PCBLayer._2;
|
||||||
|
// the side assumed for paint a component does not bracket with startDrawingSide
|
||||||
|
private PCBLayer undeclaredSide = PCBLayer._2;
|
||||||
|
private PCBLayer paintedSide = PCBLayer._2;
|
||||||
|
private boolean fadeFarSide;
|
||||||
|
// the composite the component asked for, held while far-side paint is drawn faded on top of it
|
||||||
|
private Composite unfadedComposite;
|
||||||
|
// boards switch sides once per strip or pad, so the last faded composite is reused
|
||||||
|
private Composite lastFadeInput;
|
||||||
|
private Composite lastFadeOutput;
|
||||||
|
|
||||||
private double zoom;
|
private double zoom;
|
||||||
private int zOrder;
|
private int zOrder;
|
||||||
|
|
||||||
@@ -131,6 +144,7 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver {
|
|||||||
super();
|
super();
|
||||||
this.canvasGraphics = canvasGraphics;
|
this.canvasGraphics = canvasGraphics;
|
||||||
this.drawOptions = drawOptions;
|
this.drawOptions = drawOptions;
|
||||||
|
this.fadeFarSide = drawOptions.contains(DrawOption.FADE_FAR_SIDE);
|
||||||
String debugAreaPerformanceStr = System.getProperty(DEBUG_AREA_PERFORMANCE);
|
String debugAreaPerformanceStr = System.getProperty(DEBUG_AREA_PERFORMANCE);
|
||||||
debugAreaPerformance = "true".equalsIgnoreCase(debugAreaPerformanceStr);
|
debugAreaPerformance = "true".equalsIgnoreCase(debugAreaPerformanceStr);
|
||||||
this.zoom = zoom;
|
this.zoom = zoom;
|
||||||
@@ -154,6 +168,44 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver {
|
|||||||
return mirrorDirection;
|
return mirrorDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the side of the board the viewer is looking at and whether paint on the other side is
|
||||||
|
* drawn faded. The main view looks at the top side; the underside mirror looks at the bottom.
|
||||||
|
*
|
||||||
|
* @param viewedSide
|
||||||
|
* @param fadeFarSide
|
||||||
|
* @param undeclaredSide the side assumed for paint that is not bracketed with
|
||||||
|
* {@link #startDrawingSide(PCBLayer)}; a board body is seen from both sides, so the mirror
|
||||||
|
* draws it as the viewed side
|
||||||
|
*/
|
||||||
|
public void setViewedSide(PCBLayer viewedSide, boolean fadeFarSide, PCBLayer undeclaredSide) {
|
||||||
|
this.viewedSide = viewedSide;
|
||||||
|
this.fadeFarSide = fadeFarSide;
|
||||||
|
this.undeclaredSide = undeclaredSide;
|
||||||
|
this.paintedSide = undeclaredSide;
|
||||||
|
updateFarSideFade();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the side assumed for paint that is not bracketed with
|
||||||
|
* {@link #startDrawingSide(PCBLayer)}, keeping the viewed side. A part mounted on the bottom of
|
||||||
|
* the board is drawn on the bottom side as a whole.
|
||||||
|
*
|
||||||
|
* @param undeclaredSide
|
||||||
|
*/
|
||||||
|
public void setUndeclaredSide(PCBLayer undeclaredSide) {
|
||||||
|
this.undeclaredSide = undeclaredSide;
|
||||||
|
this.paintedSide = undeclaredSide;
|
||||||
|
updateFarSideFade();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns to the top-side view, fading the bottom side only if the draw options ask for it.
|
||||||
|
*/
|
||||||
|
public void resetViewedSide() {
|
||||||
|
setViewedSide(PCBLayer._2, drawOptions.contains(DrawOption.FADE_FAR_SIDE), PCBLayer._2);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears out the current area and caches canvas settings.
|
* Clears out the current area and caches canvas settings.
|
||||||
*
|
*
|
||||||
@@ -168,6 +220,8 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver {
|
|||||||
this.debugOutline = new Area();
|
this.debugOutline = new Area();
|
||||||
// trackingStacks.clear();
|
// trackingStacks.clear();
|
||||||
this.continuityMarker = null;
|
this.continuityMarker = null;
|
||||||
|
this.paintedSide = undeclaredSide;
|
||||||
|
updateFarSideFade();
|
||||||
this.originalStroke = canvasGraphics.getStroke();
|
this.originalStroke = canvasGraphics.getStroke();
|
||||||
this.originalColor = canvasGraphics.getColor();
|
this.originalColor = canvasGraphics.getColor();
|
||||||
this.originalTx = canvasGraphics.getTransform();
|
this.originalTx = canvasGraphics.getTransform();
|
||||||
@@ -189,6 +243,8 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver {
|
|||||||
public ComponentArea finishedDrawingComponent() {
|
public ComponentArea finishedDrawingComponent() {
|
||||||
drawingComponent = false;
|
drawingComponent = false;
|
||||||
recordingDrawnBounds = false;
|
recordingDrawnBounds = false;
|
||||||
|
paintedSide = undeclaredSide;
|
||||||
|
unfadedComposite = null;
|
||||||
canvasGraphics.setStroke(originalStroke);
|
canvasGraphics.setStroke(originalStroke);
|
||||||
canvasGraphics.setColor(originalColor);
|
canvasGraphics.setColor(originalColor);
|
||||||
canvasGraphics.setTransform(originalTx);
|
canvasGraphics.setTransform(originalTx);
|
||||||
@@ -280,6 +336,54 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver {
|
|||||||
continuityMarker = marker;
|
continuityMarker = marker;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startDrawingSide(PCBLayer side) {
|
||||||
|
this.paintedSide = side == null ? undeclaredSide : side;
|
||||||
|
updateFarSideFade();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startDrawingBothSides() {
|
||||||
|
this.paintedSide = viewedSide;
|
||||||
|
updateFarSideFade();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stopDrawingSide() {
|
||||||
|
this.paintedSide = undeclaredSide;
|
||||||
|
updateFarSideFade();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateFarSideFade() {
|
||||||
|
boolean fade = fadeFarSide && !drawOptions.contains(DrawOption.OUTLINE_MODE)
|
||||||
|
&& isBottom(paintedSide) != isBottom(viewedSide);
|
||||||
|
if (fade && unfadedComposite == null) {
|
||||||
|
unfadedComposite = canvasGraphics.getComposite();
|
||||||
|
canvasGraphics.setComposite(fade(unfadedComposite));
|
||||||
|
} else if (!fade && unfadedComposite != null) {
|
||||||
|
canvasGraphics.setComposite(unfadedComposite);
|
||||||
|
unfadedComposite = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isBottom(PCBLayer layer) {
|
||||||
|
return layer != PCBLayer._2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the stronger of the two fades wins rather than multiplying, so that copper on a locked board,
|
||||||
|
// already drawn at the locked alpha, does not all but disappear
|
||||||
|
private Composite fade(Composite composite) {
|
||||||
|
if (composite != lastFadeInput || lastFadeOutput == null) {
|
||||||
|
float alpha = (float) (DrawingManager.FAR_SIDE_ALPHA.getValue().doubleValue() / 100d);
|
||||||
|
if (composite instanceof AlphaComposite ac && ac.getRule() == AlphaComposite.SRC_OVER) {
|
||||||
|
alpha = Math.min(alpha, ac.getAlpha());
|
||||||
|
}
|
||||||
|
lastFadeInput = composite;
|
||||||
|
lastFadeOutput = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
|
||||||
|
}
|
||||||
|
return lastFadeOutput;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appends shape interior to the current component area.
|
* Appends shape interior to the current component area.
|
||||||
*
|
*
|
||||||
@@ -669,7 +773,7 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Composite getComposite() {
|
public Composite getComposite() {
|
||||||
return canvasGraphics.getComposite();
|
return unfadedComposite != null ? unfadedComposite : canvasGraphics.getComposite();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -738,7 +842,13 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setComposite(Composite comp) {
|
public void setComposite(Composite comp) {
|
||||||
if (!drawOptions.contains(DrawOption.OUTLINE_MODE)) {
|
if (drawOptions.contains(DrawOption.OUTLINE_MODE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (unfadedComposite != null) {
|
||||||
|
unfadedComposite = comp;
|
||||||
|
canvasGraphics.setComposite(fade(comp));
|
||||||
|
} else {
|
||||||
canvasGraphics.setComposite(comp);
|
canvasGraphics.setComposite(comp);
|
||||||
}
|
}
|
||||||
// FIXME: check this.
|
// FIXME: check this.
|
||||||
|
|||||||