Compare commits

...

206 Commits

Author SHA1 Message Date
Bane Stojkovic 033f94f331 Capacitor components now label their terminal nodes as '+' and '-' instead of '1' and '2' when 'Polarized' property is ticked 2026-09-04 13:13:03 +02:00
Bane Stojkovic 8b48f34df0 Diode components now label their terminal nodes as 'A' (anode) and 'K' (cathode) instead of '1' and '2' 2026-09-03 22:29:34 +02:00
Bane Stojkovic 1b21436ad6 <org.diylc.appframework.update.Change> <changeType>IMPROVEMENT</changeType> <description>When saving building blocks, present a drop down list with most recently used building blocks for quick selection</description> </org.diylc.appframework.update.Change> 2026-09-03 21:39:14 +02:00
Bane Stojkovic 5f02fe15d9 Update CompositeComponent.java 2026-09-03 19:14:32 +02:00
Bane Stojkovic 819e802a37 cleanup 2026-09-03 19:12:17 +02:00
Bane Stojkovic be5387cbb0 Update CompositeComponent.java 2026-09-03 19:01:33 +02:00
Bane Stojkovic c8ead57679 cleanup 2026-09-03 18:59:27 +02:00
Bane Stojkovic 9ee44125db Update CompositeComponentTest.java 2026-09-03 18:57:00 +02:00
Bane Stojkovic 7069cacd0a add alpha to composite 2026-09-03 16:41:22 +02:00
Bane Stojkovic a44b349705 Prompt to confirm the overwrite when saving over the existing building blocks; When saving building blocks, present a drop down list with most recently used building blocks 2026-09-03 16:33:15 +02:00
Bane Stojkovic a2bd8524ae Include building blocks in the Recently Used category 2026-09-03 16:11:05 +02:00
Bane Stojkovic 825a90bbb4 cleanup 2026-09-03 15:47:31 +02:00
Bane Stojkovic 42c833d706 Added ability to set node name (or names) for some connectivity components 2026-09-03 15:45:20 +02:00
Bane Stojkovic 47250ed612 naming 2026-09-03 14:25:27 +02:00
Bane Stojkovic 9f52efafbb composite block support 2026-09-03 14:22:05 +02:00
Bane Stojkovic 26d6ca48fd Percentage values such as transparency Alpha, image Scale, etc, can have decimal values and not just integers 2026-08-31 14:32:01 +02:00
Bane Stojkovic e209ecdcb8 Made announcement bubbles and dialogs that contain links clickable 2026-08-24 17:09:35 +02:00
Bane Stojkovic ac6c38b115 Merge branch 'master' of https://github.com/bancika/diy-layout-creator 2026-08-22 20:22:28 +02:00
Bane Stojkovic cdc635b7da release 2026-08-22 20:22:14 +02:00
Bane Stojkovic 0598cc441c Update README for audio and HAM enthusiasts 2026-08-21 23:26:13 +02:00
Bane Stojkovic 18b6bfb1db Added support for stacked guitar pickups 2026-08-21 12:52:31 +02:00
Bane Stojkovic 8d506b21c4 Images can randomly disappear when zooming in and scrolling 2026-08-20 14:53:36 +02:00
Bane Stojkovic b766c55263 Renamed Mac OS build files to start with a 'mac' prefix instead of 'osx' 2026-08-18 09:26:46 +02:00
Bane Stojkovic 09b53a0685 Fix formatting in contribution section of README 2026-08-16 23:47:06 +02:00
Bane Stojkovic 98d9319938 Added 'Node Name Tooltips' feature that can be toggled in the Config menu 2026-08-16 23:39:11 +02:00
Bane Stojkovic 63ad65152a Revise README for clarity and additional content
Updated README to enhance descriptions and add new images.
2026-08-15 23:23:38 +02:00
Bane Stojkovic 040e959d8d Improved the accuracy of board underside rendering; some of the components were not rendered in the right place or at all 2026-08-15 19:41:13 +02:00
Bane Stojkovic 657521e7f5 Update update.xml 2026-08-08 14:43:49 +02:00
Bane Stojkovic af4064912b Update update.xml 2026-08-07 11:50:03 +02:00
Bane Stojkovic c34e5a2d38 remove knowledge SQLs 2026-08-07 11:49:56 +02:00
Bane Stojkovic c37a2b8310 Show a progress dialog while waiting for a long-running AI Analysis to complet 2026-08-06 15:44:45 +02:00
Bane Stojkovic 02237c9255 release 2026-08-06 14:51:38 +02:00
Bane Stojkovic ee188475d4 Pot improvements (#1064)
* Update PotentiometerPanel.java

* Update PotentiometerPanel.java

* improve node names for pot

* Update settings.json

* Update GuitarDiagramAnalyzerTests.java
2026-08-06 14:45:55 +02:00
Bane Stojkovic 2e1787f5d0 Update pom.xml 2026-08-02 23:29:26 +02:00
dependabot[bot] b1629680ff Bump com.fasterxml.jackson.core:jackson-databind in /diylc/diylc-core (#1060)
Bumps [com.fasterxml.jackson.core:jackson-databind](https://github.com/FasterXML/jackson) from 2.16.1 to 2.18.9.
- [Commits](https://github.com/FasterXML/jackson/commits)

---
updated-dependencies:
- dependency-name: com.fasterxml.jackson.core:jackson-databind
  dependency-version: 2.18.9
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-02 23:28:27 +02:00
dependabot[bot] 769bf1a381 Bump com.fasterxml.jackson.core:jackson-databind in /diylc/diylc-swing (#1061)
Bumps [com.fasterxml.jackson.core:jackson-databind](https://github.com/FasterXML/jackson) from 2.22.0 to 2.22.1.
- [Commits](https://github.com/FasterXML/jackson/commits)

---
updated-dependencies:
- dependency-name: com.fasterxml.jackson.core:jackson-databind
  dependency-version: 2.22.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-02 23:27:24 +02:00
Bane Stojkovic 85a17279b5 Use either username of email to log into DIYLC cloud 2026-08-02 23:15:51 +02:00
Bane Stojkovic f5b9faecd4 Merge branch 'master' of https://github.com/bancika/diy-layout-creator 2026-08-01 21:58:44 +02:00
Bane Stojkovic 769770bd8a Add ebook links 2026-08-01 21:58:39 +02:00
Bane Stojkovic fc103b6c2e Revise README for clarity and feature updates
Updated README to enhance clarity and add new features.
2026-08-01 20:13:05 +02:00
Bane Stojkovic 64ffc3a826 Update PCBTerminalBlock.java 2026-07-26 21:48:15 +02:00
Bane Stojkovic dbbd8a7f5a Merge branch 'master' of https://github.com/bancika/diy-layout-creator 2026-07-24 11:04:17 +02:00
Bane Stojkovic e89eb1cbdf Update CompareService.java 2026-07-24 11:04:13 +02:00
Bane Stojkovic 0476dbb876 cleanup isPolarized 2026-07-17 16:45:15 +02:00
Bane Stojkovic 1571d78048 Increased width of tree panel to fit all components 2026-07-17 16:38:52 +02:00
Bane Stojkovic d8a2538b35 Improved comparison logic of the 'Compare With..' tool 2026-07-17 16:38:41 +02:00
dependabot[bot] 717892c38e Bump com.fasterxml.jackson.core:jackson-databind in /diylc/diylc-swing (#1057)
Bumps [com.fasterxml.jackson.core:jackson-databind](https://github.com/FasterXML/jackson) from 2.16.1 to 2.22.0.
- [Commits](https://github.com/FasterXML/jackson/commits)

---
updated-dependencies:
- dependency-name: com.fasterxml.jackson.core:jackson-databind
  dependency-version: 2.22.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-30 10:57:09 +02:00
Bane Stojkovic 896b6e5f69 6.1.0 release 2026-06-30 10:08:29 +02:00
Bane Stojkovic 475b829562 Merge branch 'master' of https://github.com/bancika/diy-layout-creator 2026-06-14 22:38:21 +02:00
Bane Stojkovic aeabec7392 Update tests.yml 2026-06-14 22:38:19 +02:00
Bane Stojkovic 2261433bf0 launcher update 2026-06-14 22:30:17 +02:00
Bane Stojkovic e85d618498 java upgrade, 6.0.0 release 2026-06-14 22:03:29 +02:00
Bane Stojkovic 3425fff3a0 Fixed errors while analyzing guitar wiring diagrams caused by treble bleed enhancements 2026-06-14 20:48:12 +02:00
Bane Stojkovic cc09c59fe5 Fixed scaling for 'Image' and 'SVG Image' components; it was showing as undefined 2026-06-14 10:05:15 +02:00
Bane Stojkovic 0219aa5c2a release 2026-06-13 22:39:04 +02:00
Bane Stojkovic 9b3274e30c update 2026-06-13 22:33:33 +02:00
Bane Stojkovic 9c29d2c4d6 minor 2026-06-10 17:19:45 +02:00
Bane Stojkovic 1d7dd87d85 Improved precision of rendering 2026-06-10 17:19:21 +02:00
Bane Stojkovic 9179086bd5 Update TrebleBleed.java 2026-06-10 17:05:44 +02:00
Bane Stojkovic 3fbc7f5bc9 'Schaller Megaswitch' not rendered correctly when rotated for 90 or 270 degrees 2026-06-08 22:35:41 +02:00
Bane Stojkovic 0526ce38f4 Merge branch 'master' of https://github.com/bancika/diy-layout-creator 2026-06-07 23:09:23 +02:00
Bane Stojkovic 880fa1e9e1 Update update.xml 2026-06-07 23:09:21 +02:00
Martin Morrell fb0821bce2 WIP: Add Freeway Blade Switch: 3B3-01, 5B5-01. 5B5-02 (#1042)
* Add Freeway Blade Switch: 3B3-01, 5B5-01. 5B5-02

* Fix labels and connections - reverse them to be correct
2026-06-07 23:08:21 +02:00
Bane Stojkovic 6a590af026 treble bleed enhancements 2026-06-07 23:02:47 +02:00
Bane Stojkovic efa803d7d0 Treble bleed enhancements 2026-06-07 22:37:27 +02:00
Bane Stojkovic f481542d5a Dragging a component from the component tree to the canvas sometimes does not work as expected without clicking on it first and then dragging it 2026-06-05 21:38:25 +02:00
Bane Stojkovic 140c052d39 Update update.xml 2026-06-05 20:40:54 +02:00
Jamie Drinkell 75edc427f7 Add IEC/IEEE schematic symbols for Potentiometer and Fuse (#995)
* Add new IEC and IEEE styles to Fuse symbol

* Add IEC style to potentiometer
For some reason it refuses to redraw on changing, it must be moved?

* Fix redraw on standard selection

* Fix indentation

* Change draw_style to camelCase drawStyle
2026-06-05 20:38:11 +02:00
Bane Stojkovic 717c16e88a Release 5.14.0 2026-06-03 21:55:22 +02:00
Bane Stojkovic ffa8e34497 Added thonk jack 2026-06-03 19:45:06 +02:00
Bane Stojkovic 9de5fe6ebc 'Line' component set to px used to render slightly thicker than 1px, appearing thicker than schematic symbols 2026-06-03 19:44:58 +02:00
Bane Stojkovic 0cdbcd60fe Increase maximum number of switch combination for analysis to 1024 2026-05-05 23:33:50 +02:00
Bane Stojkovic 491d48f0ec enable trimmers and mini pots for analysis 2026-05-05 23:33:08 +02:00
Bane Stojkovic 9f6a0c537a Added 'Potentiometer (Miniature)' component with two variations - right-angled and vertically mounted 2026-05-03 21:18:27 +02:00
Bane Stojkovic e674a1f23f version bump 2026-04-27 22:33:36 +02:00
Bane Stojkovic 9481b7e6a3 splash improvement 2026-04-07 20:50:23 +02:00
Bane Stojkovic 833ef947d5 fix tests 2026-04-07 20:17:22 +02:00
Bane Stojkovic c092b5f56e Ability to blank-out previously populated values for unit-type measures, e.g. resistance, capacitance, dimensions, etc 2026-04-07 20:16:27 +02:00
Bane Stojkovic 5546a66c94 outline drag to false by default 2026-04-07 20:06:02 +02:00
Bane Stojkovic b034c8c761 fix for transparency when dragging 2026-04-06 21:34:58 +02:00
Bane Stojkovic 8318b34967 Fix for null in int editor 2026-04-06 21:18:15 +02:00
Bane Stojkovic 194c8e0606 Improved data model for storing transparency alpha and other properties that are edited using a slider widget; as a result, the editing is more precise and does not randomly change to neighboring values 2026-04-06 21:04:55 +02:00
Bane Stojkovic 124d1ab577 Improved editing experience of integer properties (e.g. number of terminals on a tag strip) by using the spinner text field 2026-04-04 23:14:59 +02:00
Bane Stojkovic 5ce17b4ca2 Improved logic when moving component(s) that have other components stuck with them; in case there are non-sticky control points within the included components, they will be moved along retaining component shape (e.g. wires or curved traces) 2026-04-04 20:54:32 +02:00
Bane Stojkovic 30c6b4ec76 Added air-core inductor variation 2026-04-03 23:40:25 +02:00
Bane Stojkovic 2001a1af7b Added 'Envelope' property to tube symbol components which can be used to display one side of the outer envelope dashed indicating section A or section B of a tube 2026-04-03 21:09:24 +02:00
Bane Stojkovic 27f5c53afc Added more ceramic resistor variants to 'Resistor' component 2026-04-02 20:43:16 +02:00
Bane Stojkovic 10cbbea3d3 Added heat sink resistor 2026-04-02 20:22:25 +02:00
Bane Stojkovic b26a489f3a Remove loadline editor 2026-04-01 22:45:26 +02:00
Bane Stojkovic dab4975347 Added new 'Dial Scale' variations - 'Ticks + Numeric (0/5.5/11)' a'la Friedman and another variation of 'Ticks' with more pronounced 9/12/3 o'clock indices 2026-03-28 20:58:36 +01:00
Bane Stojkovic 5d8555e316 Update ChatbotPane.java 2026-03-26 22:49:38 +01:00
Bane Stojkovic 614652ca97 release 2026-03-26 22:47:14 +01:00
Bane Stojkovic af3887b9ac Clicking on a component type in the left-hand component tree sometimes does not register and does not instantiate the component 2026-03-26 20:33:16 +01:00
Bane Stojkovic 150e03c023 Pressing the 'Esc' key closes selection editor dialog 2026-03-26 19:57:18 +01:00
Bane Stojkovic cd0cb776b0 Right click (or two finger tap on mac) after selecting a component with a regular click opens editor dialog in addition to the context menu 2026-03-26 19:51:56 +01:00
Bane Stojkovic ebd66eea4f minor improvements 2026-02-27 14:13:46 +01:00
Bane Stojkovic 7d24621c18 Cleanup of code that doesn't work for fixing tooltip colors on linux mint (kde bug) 2026-02-22 22:34:10 +01:00
Bane Stojkovic a7442e14e4 Better error handling for AI tools< 2026-02-21 22:36:32 +01:00
Bane Stojkovic 03af702933 Redo unit conversion 2026-02-20 22:31:40 +01:00
Bane Stojkovic 303e59303b Added a new section in the output of 'AI Circuit Analyzer' which provides insights into the operation of the circuit and individual components 2026-02-20 22:12:19 +01:00
Bane Stojkovic 508d1db513 Added 'Auto-Unit Conversion' configuration which automatically converts between metric and imperial units based on the ruler unit preference 2026-02-17 20:44:50 +01:00
Bane Stojkovic c4efe7d20f Update draft-github-release.sh 2026-02-15 22:52:53 +01:00
Bane Stojkovic fccda215fc release 2026-02-15 22:49:47 +01:00
Bane Stojkovic d89061b355 Windows installer prompts for installation folder instead of forcing one 2026-02-15 22:26:27 +01:00
Bane Stojkovic f0c482d2d5 Added ability to export chat history from 'AI Assistant' to a HTML file 2026-02-15 20:40:05 +01:00
Bane Stojkovic f5fedc1a24 Update update.xml 2026-02-14 23:17:06 +01:00
Bane Stojkovic b3a1187c1c Improved rendering of 'Switch (Latching)' symbol to clearly make visual contact between the terminals 2026-02-13 22:26:23 +01:00
Bane Stojkovic 7e79143079 Ensure no duplicate IDs when loading 2026-02-11 16:59:16 +01:00
Bane Stojkovic d976959e95 Using "Duplicate Selection" results in duplicates of component ids, breaking Project Explorer panel and causing other issues downstream 2026-02-11 16:47:08 +01:00
Bane Stojkovic 8b69903893 Consolidate a few keyboard shortcuts for consistency 2026-02-09 23:15:35 +01:00
Bane Stojkovic 391d161c59 Add support for logging all component types to JSON 2026-02-09 16:18:05 +01:00
Bane Stojkovic d970fa10a7 Create component_index.prompt 2026-02-09 16:17:19 +01:00
Bane Stojkovic b6816e6a62 typo 2026-02-09 16:17:15 +01:00
Bane Stojkovic 3272efc8bf Typo fix 2026-02-09 16:14:35 +01:00
Bane Stojkovic 0aed29f072 Remove shapes from BOM 2026-02-06 22:56:08 +01:00
Bane Stojkovic 7e2319746e Bring back calculate length for curved components 2026-02-06 22:55:40 +01:00
Bane Stojkovic 1cf776ace5 Resize dimensions do not show for 'Chassis Panel' component when dragging a corner point 2026-01-30 12:52:00 +01:00
Bane Stojkovic b9da7510a8 5.10 release 2026-01-20 20:37:04 +01:00
Bane Stojkovic 6fde016ed4 All building blocks of the same type get added to the same group 2026-01-20 20:34:32 +01:00
Bane Stojkovic a32ad6b733 fix issue with null objects in groups 2026-01-19 23:22:19 +01:00
Bane Stojkovic be16910767 fix copy paste groups 2026-01-19 23:15:46 +01:00
Bane Stojkovic 457f47782f Added E-C-B BJT pinout to TO-92 transistor package 2026-01-16 22:29:14 +01:00
Bane Stojkovic b69729c14f Trimmer improvements 2026-01-16 20:37:21 +01:00
Clive Hayward a88d8f5e03 Added Box style multi-turn potentiometer component. (#987)
* Added Box style multi-turn potentiometer component.

Implements box style multi-turn trimmer potentiometer (e.g. Bourns PV36W/X) with inline pins for stripboard layouts.

Features:
- 3 inline pins on 0.1" spacing (CCW, Wiper, CW)
- Configurable resistance value and orientation
- Blue body (4.82mm × 9.53mm) with brass adjustment screw
- Screw positioned in lower left corner with horizontal slot
- Label positioned outside body for readability
- Pins centered in body width for all orientations
- Side profile icon showing brass screw and three pins
- Locked pin movement - component moves as single unit

Dimensions based on common box-style multi-turn potentiometers.
Default orientation is vertical (_90) with pins horizontal.

Category: Passive
Instance prefix: VR

* Handles mirroring and rotational transforms.

* Handles mirroring and rotational transforms.
2026-01-16 20:19:21 +01:00
Bane Stojkovic f4223f5773 Merge branch 'master' of https://github.com/bancika/diy-layout-creator 2026-01-16 20:08:34 +01:00
Bane Stojkovic 513cc67362 Update update.xml 2026-01-16 20:08:27 +01:00
Martin Morrell d8f2a3b6e0 Add 'M' and 'N' potentiometer taper options (#990) 2026-01-16 20:07:33 +01:00
Bane Stojkovic 7900128d7c Tactile Micro Switch' editor doesn't show up on double click 2026-01-16 20:03:01 +01:00
Bane Stojkovic 1cef0c0977 Explorer group (#992)
* show groups in explorer

* introduce component ids. Refactor how groups are modeled in the Project

* Group naming added

* cleanup

* release
2026-01-10 20:44:52 +01:00
Bane Stojkovic 2383f9ae77 'Potentiometer Panel' can now render numerical lug markers for easier identification 2026-01-06 19:46:14 +01:00
Bane Stojkovic 14ec18dfef Update update.xml 2026-01-06 19:06:10 +01:00
Bane Stojkovic 2f492c8fa8 Ability to resize 'Transformer Core' schematic symbol after it's already placed 2026-01-06 19:06:04 +01:00
Bane Stojkovic 9db43cd2f4 Make the label of schematic symbols (e.g. 'Resistor Symbol') clickable as well 2026-01-06 18:54:08 +01:00
Bane Stojkovic 344c238f73 Fixed the offset of terminals on a DP4T Tele type of 'Lever Switch' to be aligned with the physical switch 2026-01-05 21:30:13 +01:00
Bane Stojkovic 3376aa995a 'Open 1/8" Jack' and 'Open 1/4" Jack' can be rotated 2026-01-05 21:10:10 +01:00
Bane Stojkovic ec75f1b6eb 'Cliff 1/8" Jack' can be rotated 2026-01-05 21:06:22 +01:00
Bane Stojkovic 5f2b20ea41 New lines at the end of the 'Label' text get erroneously rendered as <br> 2026-01-05 20:53:00 +01:00
Bane Stojkovic 9d130c0ff3 Minor cleamup 2026-01-05 20:17:17 +01:00
Martin Morrell 119c41dc86 Add Freeway 3x3-05 (Ultra) Switch (#989) 2026-01-05 20:10:37 +01:00
Bane Stojkovic c5613a6fea 'Auto-Wrap Label' retains line breaks from the input text 2026-01-02 22:16:17 +01:00
Bane Stojkovic 479bd50540 Label adjustment 2026-01-02 21:42:09 +01:00
Bane Stojkovic 502a4b8d39 Tactile switch improvements 2026-01-02 21:06:27 +01:00
Bane Stojkovic 1f85c07453 Configurable 'Tactile Micro Switch' dimensions and added a few most commonly used variants 2026-01-02 10:17:23 +01:00
Bane Stojkovic 53ec1e780e fix: Clicking on 'Tactile Micro Switch' body doesn't register 2026-01-01 22:29:39 +01:00
Bane Stojkovic 2de3def32e Resize tooltip (#986)
* resize tooltip

* Fix blank board area rendering

* Fixes

* translations

* Add length

* Update update.xml
2025-12-31 15:07:22 +01:00
Bane Stojkovic 61b3c63bbf Revert "Introduce unique component instance ID"
This reverts commit 348eb3ac00.
2025-12-31 15:04:18 +01:00
Bane Stojkovic 348eb3ac00 Introduce unique component instance ID 2025-12-31 12:29:48 +01:00
Bane Stojkovic 9972e0ee46 Update .gitignore 2025-12-31 09:59:21 +01:00
Bane Stojkovic de971b707b Update build-all-profiles.sh 2025-12-30 20:09:57 +01:00
Bane Stojkovic 0dcc06f712 Update update.xml 2025-12-30 19:44:05 +01:00
Bane Stojkovic 109b0788a8 5.8.0 release 2025-12-30 14:37:56 +01:00
Bane Stojkovic d190ebe208 Cleanup 2025-12-30 10:44:12 +01:00
Bane Stojkovic fa93af2707 'Rotary Switch (Open)' cannot be selected by clicking on the wafer for 4-pole variations 2025-12-29 22:58:15 +01:00
Bane Stojkovic 6b59966816 Minor chassis panel optimization 2025-12-29 22:39:39 +01:00
Bane Stojkovic b065c9d6fb Reorganized export and print related items in the File menu to reduce clutter 2025-12-29 16:12:36 +01:00
Bane Stojkovic 49d805a60c Improved behavior of mouse cursor during drag operations; this should also fix behavior on some linux machines that show a "forbidden" cursor while dragging 2025-12-29 15:44:59 +01:00
Bane Stojkovic a9a98bf3a4 Language improvements 2025-12-29 14:01:59 +01:00
Bane Stojkovic 840d416282 Honor label color settings for 'Tape Measure' component 2025-12-29 13:40:06 +01:00
Bane Stojkovic dc2cc4c7c8 Do not use composites in outline mode 2025-12-29 13:00:41 +01:00
Bane Stojkovic 3d51d2a38d trace ending default values 2025-12-29 12:59:03 +01:00
Bane Stojkovic 4dfb1ca630 fix default LP Switch behavior for back compatibility 2025-12-29 11:15:59 +01:00
Bane Stojkovic e9c8686960 Added new property in 'LP Switch' that allows having the middle terminals connected (as they were) or disconnected to allow more flexibility 2025-12-29 10:55:45 +01:00
Bane Stojkovic 9be97f5213 fix tests 2025-12-29 10:54:39 +01:00
Bane Stojkovic 721d582dcd Update G2DWrapper.java 2025-12-28 23:09:04 +01:00
Bane Stojkovic 443f76f3f9 Monochromatic mode 2025-12-28 23:07:50 +01:00
Bane Stojkovic 3ad9c49f53 Update update.xml 2025-12-26 23:04:28 +01:00
Bane Stojkovic 61077ed5a4 Added Silkscreen export to PDF/PNG and print capabilities 2025-12-26 23:04:26 +01:00
Bane Stojkovic 1fe3706d0f improve multiwatt icon 2025-12-26 20:24:55 +01:00
Bane Stojkovic 16df8fd173 Added multiwat IC 2025-12-26 19:53:37 +01:00
Bane Stojkovic f7806d4d3c Added trace Ending Style property 2025-12-26 12:28:16 +01:00
Bane Stojkovic 04e44e174e Improve contrast of tooltips on some Linux machines that show white text against yellow ballon 2025-12-26 12:06:31 +01:00
Bane Stojkovic f74fe19b77 Update update.xml 2025-12-26 11:57:46 +01:00
Bane Stojkovic e7487069a5 Application freezes when using underside rendering or mirroring on 'Pin Header' when sized at 1x1 2025-12-26 11:57:43 +01:00
Bane Stojkovic 9c48b80515 Use configuration for scale factor 2025-12-26 11:48:52 +01:00
Bane Stojkovic 814f4296a9 Added configuration for text scale factor in rare cases when system scale factor is not applied correctly 2025-12-25 16:27:47 +01:00
Bane Stojkovic 6fa0e7d56a Improved sensitivity of 'Multimeter Probe' that required pixel-level precision to detect connectivity; improved rendering of the probe in outline mode 2025-12-25 11:36:51 +01:00
Bane Stojkovic 12726338ef Fixed underside rendering and mirroring position issues that affected only SPDT 'Mini Toggle Switch' types 2025-12-25 10:59:31 +01:00
Bane Stojkovic f3a8e3cfb1 release 5.7.9 2025-12-21 22:07:21 +01:00
Bane Stojkovic 1ac8ba8a24 Merge pull request #980 from mm-rnd/Lever_4P3T
Lever 4P3T
2025-12-21 22:03:47 +01:00
Bane Stojkovic 7b5bb3a152 Merge branch 'master' into Lever_4P3T 2025-12-21 22:01:05 +01:00
Martin Morrell ce7753744a Lever 2502N import switch (#981)
* Add 4P3T AxLabs Lever Switch variant

* Add 2502N Lever Switch

* Bridge is now pos1 and neck pos5 as expected

Re-worked acording to the diagram here:
https://guitarpartscenter.eu/en_US/p/ALPHA-SW-2502N-5-Way-Lever-Switch-ADWH/23036
2025-12-21 21:58:20 +01:00
Martin Morrell 3adaa16537 Add 4P3T AxLabs Lever Switch variant 2025-12-20 07:46:36 +00:00
Bane Stojkovic aa4f4c9c66 'Drill Hole' changes color to red when selected 2025-12-19 20:20:07 +01:00
Bane Stojkovic ef01d52905 Update update.xml 2025-12-19 20:10:05 +01:00
Bane Stojkovic 892de712b2 Merge branch 'master' of https://github.com/bancika/diy-layout-creator 2025-12-19 20:09:53 +01:00
Martin Morrell 79aa25f14c Update positon names to match switch positions (#977) 2025-12-19 20:07:12 +01:00
Bane Stojkovic 165b61329c Merge branch 'master' of https://github.com/bancika/diy-layout-creator 2025-12-19 20:02:33 +01:00
Bane Stojkovic c251e5ace2 flip S1 position names 2025-12-19 20:02:24 +01:00
Martin Morrell 550e221265 Fix S1 Switch markers (#978) 2025-12-19 20:02:10 +01:00
Martin Morrell 7110897e9d Add 6P5T AxLabs Lever Switch variant (#979) 2025-12-19 19:54:15 +01:00
Bane Stojkovic 74badd8a01 Update DrillHole.java 2025-08-11 22:29:03 +02:00
Bane Stojkovic 95eccffa4a 'Connect to Patreon' option says that it connected account with username 'a b c' but doesn't do anything 2025-08-11 19:25:00 +02:00
Bane Stojkovic 35a190b02f Added 'Drill Hole' component 2025-06-21 22:45:46 +02:00
Bane Stojkovic 92457ae0fb Increase maximum size of the backup folder from 64MB to 1GB for deeper history 2025-06-18 21:35:14 +02:00
Bane Stojkovic 73d3dd1cd4 fix: Alignment issues of some visual elements in the resulting Gerber files, e.g. DIL IC pin designators 2025-06-16 23:33:56 +02:00
Bane Stojkovic cb9cd46261 fix: When a switch position is selected (i.e. set to a value other than None), DIYLC will treat the terminals that are internally connected in that switching logic as connected in analysis tools 2025-06-06 23:52:28 +02:00
Bane Stojkovic 4bd3943345 bigger cloud search window 2025-06-06 00:09:28 +02:00
Bane Stojkovic 30bdc7fc3d disable patreon connect when not logged in 2025-06-05 00:05:17 +02:00
Bane Stojkovic a1d31c1ae2 add join patreon link at the top and randomly show 2025-06-05 00:05:04 +02:00
Bane Stojkovic 90fb3095bd More intuitive user account creation dialog for DIYLC Cloud - showing exact requirements for password and marking optional entries 2025-06-04 23:33:50 +02:00
Bane Stojkovic 0c468369cd Simplify zoom in/out keyboard shortcuts to only plus/minus keys and zero numerical key for zoom reset to 100 2025-06-02 23:02:33 +02:00
Bane Stojkovic f88b0c642a mac build naming. Enable windows arm 2025-05-30 23:47:04 +02:00
Bane Stojkovic 1b8bdbe7ed Reduce logging 2025-05-29 23:45:40 +02:00
Bane Stojkovic 185b5da4d5 Bundle Java JRE with Linux AppImage to avoid having to install it 2025-05-29 23:32:27 +02:00
Bane Stojkovic cd92464467 fix auto-edit 2025-05-26 22:35:18 +02:00
Bane Stojkovic 59e18c6be2 Feature/compare (#929)
* add compare tool

* improvements

* diff improvements

* license

* diff logic and tests fixed

* update license info

* add isPolarized to component interface

* handle comparison of non-polarized components
2025-05-26 14:57:47 +02:00
633 changed files with 35733 additions and 29589 deletions
+2 -2
View File
@@ -14,10 +14,10 @@ jobs:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up JDK 17
- name: Set up JDK 21
uses: actions/setup-java@v3
with:
java-version: '17'
java-version: '21'
distribution: 'temurin'
cache: maven
+2 -1
View File
@@ -1,3 +1,4 @@
{
"java.configuration.updateBuildConfiguration": "interactive"
"java.configuration.updateBuildConfiguration": "disabled",
"java.compile.nullAnalysis.mode": "disabled"
}
+92 -60
View File
@@ -1,63 +1,95 @@
<h3><a name="News"></a>Introduction<a href="#Introduction" class="section_anchor"></a></h3>
<p align="justify">
DIY Layout Creator (DIYLC) is a specialized software tool designed for hobbyists and electronics enthusiasts to create circuit layouts on stripboard, perfboard, PCB, and point-to-point wiring. It provides an intuitive, drag-and-drop interface for placing components, arranging connections, and visualizing circuit designs before assembly. With a built-in component library and customization options, it allows users to design layouts with precision and clarity. The software is particularly useful for designing, analyzing, and debugging guitar wiring diagrams, helping musicians and builders plan and troubleshoot custom wiring configurations for pickups, switches, and controls. Its versatility makes it an ideal solution for DIY electronics projects, prototyping, and documentation.</p>
<br>
<a href="https://github.com/bancika/diy-layout-creator/releases/latest">Click here</a> to get the latest version for all platforms.</a><br>
<a href="https://github.com/bancika/diy-layout-creator/tree/wiki">Click here</a> to read the user documentation as well as developer documentation.<br>
<br>
<b>Mac users</b>: in most instances, the Gatekeeper will block DIYLC and mark it as damaged because it's a 3rd party app from an independent vendor (me). <a href="[https://support.apple.com/en-us/HT202491](https://support.apple.com/kb/ph18657?locale=en_US)">This document</a> covers how to allow DIYLC on your Mac.
### 🛠️ Introduction
<h3><a name="Samples"></a>Samples<a href="#Samples" class="section_anchor"></a></h3>
DIY Layout Creator (DIYLC) is a specialized software tool designed for hobbyists and electronics enthusiasts to create circuit layouts on stripboard, perfboard, PCB, and point-to-point wiring.
<h4>Point-to-point tube amplifier</h4>
<p align="center"><a href="http://diy-fever.com/wordpress/wp-content/gallery/diylc/slo.png" rel="nofollow"><img src="https://diy-fever.com/wordpress/wp-content/gallery/diylc/cache/slo.png-nggid041072-ngg0dyn-450x350-00f0w010c010r110f110r010t010.png"></a></p>
<h4>Guitar wiring</h4>
<p align="center"><a href="http://diy-fever.com/wordpress/wp-content/gallery/diylc/travelcaster.png" rel="nofollow"><img src="https://diy-fever.com/nextgen-image/1073/450x350/34b70d759e46422208d61e376b4633dc"></a></p>
<h4>PCB tube amplifier</h4>
<p align="center"><a href="http://diy-fever.com/wordpress/wp-content/gallery/diylc/iic.png" rel="nofollow"><img src="https://diy-fever.com/nextgen-image/1070/450x350/ccb592ec5828b6f5bc75e840438918f1"></a></p>
<h4>Perfboard guitar effect</h4>
<p align="center"><a href="http://diy-fever.com/wordpress/wp-content/gallery/diylc/split.png" rel="nofollow"><img src="https://diy-fever.com/nextgen-image/1069/450x350/358e43165de40e9c4043726c9efde4a7"></a></p>
It provides an intuitive, drag-and-drop interface for placing components, arranging connections, and visualizing circuit designs before assembly. With a built-in component library and customization options, it allows users to design layouts with precision and clarity.
<h3><a name="Key Features"></a>Features<a href="#Features" class="section_anchor"></a></h3>
<ul>
<li>platform independence, will run on any machine having Java JRE/JDK 8 or newer </li>
<li>easy to use interface, most of the operations can be done using mouse </li>
<li>draw PCB, perfboard, stripboard or point-to-point circuit layouts layouts, schematics and guitar wiring diagrams </li>
<li>high flexibility, has the API to allow plug-ins and new components to be added</li>
<li>improved performance and reduced memory consumption compared to the previous versions </li>
<li>save default values for each property of a component individually </li>
<li>group components together and treat them as one, e.g. move, edit or delete </li>
<li>export the output to image, PDF or printer </li>
<li>export PCB trace mask suitable for toner transfer </li>
<li>export PCB designs to Gerber for fabrication </li>
<li>create a Bill of Materials as a part of the project or export it to few different file formats </li>
<li>analyze guitar wirings and show detailed pickup configuration in each switch configuration</li>
<li>zoom in/out feature </li>
<li>configurable grid spacing on the project level </li>
<li>auto update checks for new versions </li>
<li>import files created with older versions of the application </li>
<li>cloud feature - share your projects, search through the cloud and download other users' projects </li>
<li>highlight connected areas to simplify validation and circuit debugging</li>
<li>analyze guitar wiring diagrams and visualize pickup wirings for each switch configuration</li>
<li>export circuits to SPICE-compatible netlists</li>
</ul>
<p>To report bugs or request a new feature go to <a href="https://github.com/bancika/diy-layout-creator/issues" rel="nofollow">Issues</a> page and create a new issue describing your problem or request. </p>
<p>To join the discussion or request technical assistance, use the dedicated <a href="http://groups.google.com/group/diy-layout-creator" rel="nofollow">Discussion Group</a>. </p>
<h3><a name="Want_to_contribute?"></a>Want to contribute?<a href="#Want_to_contribute?" class="section_anchor"></a></h3>
<p align="justify"><strong>DIYLC is provided free of charge and can be used and redistributed freely. Please note that it takes a lot of time and effort to build, test and maintain it and to interact with the growing community of users. If you find DIYLC useful and want to support further development, these are some of the ways you can contribute</strong></p>
<ul>
<li><a href="https://www.patreon.com/c/user?u=5213116">Become a Patreon.</a></li>
<li><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=U6GLS8HLTSU88">Make a one-time donation with PayPal.</a></li>
<li>Help with adding the information to the <a href="https://github.com/bancika/diy-layout-creator/blob/wiki/Manual.md">user manual</a> or other project documentation.</li>
<li>Extend the component base, read <a href="https://github.com/bancika/diy-layout-creator/blob/wiki/ComponentAPI.md" rel="nofollow">this wiki</a> to learn how to create new components. </li>
<li>Add a new functionality though plug-ins, read <a href="https://github.com/bancika/diy-layout-creator/blob/wiki/PluginAPI.md" rel="nofollow">this wiki</a> to learn how to create new plug-ins. </li>
</ul>
<!--<p align="center"><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=U6GLS8HLTSU88" rel="nofollow"><img src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif"></a> </p>-->
<h3><a name="License_information"></a>License information<a href="#License_information" class="section_anchor"></a></h3>
<p>Source code is released under <a href="https://www.gnu.org/licenses/gpl-3.0.txt">GNU General Public License version 3</a>. Contact the project owner to obtain a license in case you plan to use the source code, or any part of it, in commercial purposes. </p>
<p></p>
<h3><a name="Credits"></a>Credits<a href="#Credits" class="section_anchor"></a></h3>
<ul>
<li>Big thanks goes to folks from the following online communities for contributing ideas and helped test the app: <a href="http://www.diystompboxes.com/smfforum/" rel="nofollow">DIY Stompboxes</a>, <a href="http://ax84.com/bbs" rel="nofollow">AX84</a> and <a href="http://freestompboxes.org" rel="nofollow">Free Stompboxes</a>. </li>
<li>I'm happy to report that DIYLC 4 is the fastest version ever. <a href="http://www.yourkit.com/java/profiler/index.jsp" rel="nofollow">YourKit Java Profiler</a> helped tremendously with memory and performance profiling and pointed me to places in the code that took longer to run or consumed more memory than I'd like them to. I strongly recommend this tool to anyone developing Java or .NET applications because it helps finding bottlenecks and allocation hot-spots very fast.<br><br>YourKit is kindly supporting open source projects with its full-featured Java Profiler.<br>YourKit, LLC is the creator of innovative and intelligent tools for profiling Java and .NET applications.<br>Take a look at YourKit's leading software products: <a href="http://www.yourkit.com/java/profiler/index.jsp" rel="nofollow">YourKit Java Profiler</a> and <a href="http://www.yourkit.com/.net/profiler/index.jsp" rel="nofollow">YourKit .NET Profiler</a> </li>
</ul>
🎸 **Perfect for guitar pedal builders, guitar, synth, audio and HAM enthusiasts!** DIYLC is particularly useful for designing, analyzing, and debugging guitar wiring diagrams, helping musicians and builders plan and troubleshoot custom wiring configurations for pickups, switches, and controls. Its versatility makes it an ideal solution for DIY electronics projects, prototyping, and documentation.
### 🚀 Quick Links
* **[⬇️ Download the latest release](https://github.com/bancika/diy-layout-creator/releases/latest)** for all platforms.
* **[📄 Read the Wiki](https://github.com/bancika/diy-layout-creator/tree/wiki)** for free user and developer documentation.
> 🍎 **Mac users:** Gatekeeper may block DIYLC since it's from an independent developer. [Read this guide](https://support.apple.com/kb/ph18657?locale=en_US) on how to easily allow DIYLC on your Mac.
---
### 📖 The Official DIYLC Guide
<a href="https://www.diy-fever.com/diylc-book">
<img src="https://www.diy-fever.com/diylc/book/book_v1_thumb.png" alt="DIYLC Official Guide" width="220" align="left" style="margin-right: 20px; margin-bottom: 20px;">
</a>
**Master DIY Layout Creator and streamline your design workflow!**
The **Official DIYLC Guide (v1.0)** is a comprehensive 174-page eBook that goes way beyond the basics. It features step-by-step design workflows for everything from multi-layer PCBs to hot-rodded point-to-point tube amps. Learn to master advanced tools like the Virtual Multimeter, Netlist generation, the Guitar Wiring Analyzer, and the new AI Assistant.
🎉 **Launch Special:** Get **40% off** during our 14-day introductory sale! Buying v1.0 guarantees you free lifetime updates as the app evolves.
👉 **[Click here to grab your copy!](https://www.diy-fever.com/diylc-book)**
*Active Patreon supporters get an additional 50% off or a completely free copy. Check the [Patreon feed](https://www.patreon.com/c/user?u=5213116) for your VIP link!*
<br clear="all">
---
### 🖼️ Gallery & Samples
<p align="center">
<img src="https://diy-fever.com/wordpress/wp-content/gallery/diylc/slo.png" width="48%" alt="Point-to-point tube amplifier">
<img src="https://diy-fever.com/wordpress/wp-content/gallery/diylc/travelcaster.png" width="48%" alt="Guitar wiring">
<br>
<sup><i>Left: Point-to-point tube amplifier &nbsp; | &nbsp; Right: Guitar wiring</i></sup>
<br><br>
<img src="https://diy-fever.com/wordpress/wp-content/gallery/diylc/iic.png" width="48%" alt="PCB tube amplifier">
<img src="https://diy-fever.com/wordpress/wp-content/gallery/diylc/split.png" width="48%" alt="Perfboard guitar effect">
<br>
<sup><i>Left: PCB tube amplifier &nbsp; | &nbsp; Right: Perfboard guitar effect</i></sup>
</p>
---
### ✨ Key Features
* 🆓 **Free for Life**: A true old-school offline app—the app you download is yours forever and the files you created are yours.
* 💻 **Platform Independence:** Runs locally on any machine capable of running Java JRE/JDK 21 or newer.
* 🖱️ **Intuitive UI:** Easy-to-use interface; most operations can be done seamlessly with a mouse.
* 🎛️ **Versatile Designs:** Draw PCB, perfboard, stripboard, or point-to-point layouts, schematics, guitar wiring diagrams or custom faceplates.
* 🔌 **Highly Extensible:** API allows custom plug-ins and new components to be added easily.
* 🚀 **Optimized:** Improved performance and reduced memory consumption.
* 💾 **Smart Defaults:** Save default values individually for each component property.
* 🖨️ **Export Options:** Export outputs to image, PDF, or printer.
* 📄 **Toner Transfer & Gerber:** Export PCB trace masks for toner transfer or Gerber files for fabrication.
* 📋 **Bill of Materials:** Create a BOM within the project or export to multiple file formats.
* 🔍 **Guitar Wiring Analysis:** Analyze guitar wirings and visualize detailed pickup configurations for each switch state.
* ☁️ **Cloud Integration:** Share your projects, search the cloud, and download other users' designs.
* 🤖 **AI Powered:** Features a built-in AI assistant to help answer general electronics questions, guide you through DIYLC's usability, and provide insights or troubleshooting for the specific circuit you are designing.
* ⚡ **Circuit Analysis:** Various tools aimed to help you debug and analyze your circuits.
* 📈 **SPICE Netlists:** Export circuits directly to SPICE-compatible netlists.
---
### 🐛 Support & Community
* **Found a bug or have a feature request?** Head over to the [Issues page](https://github.com/bancika/diy-layout-creator/issues) to open a ticket.
* **Need technical assistance or want to chat?** Join the discussion in our [Google Group](http://groups.google.com/group/diy-layout-creator).
---
### ❤️ Want to contribute?
DIYLC is provided free of charge and can be used and redistributed freely. Building, testing, and maintaining this tool—while supporting our growing community—takes a significant amount of time and effort.
If you find DIYLC useful, here are the best ways you can support its future development:
* 🧡 **[Become a Patreon](https://www.patreon.com/c/user?u=5213116):** Join the inner circle for exclusive perks.
* 📖 **[Purchase the Official DIYLC Guide](https://www.diy-fever.com/diylc-book):** Level up your layout skills while directly supporting the app!
* ☕ **[Make a PayPal donation](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=U6GLS8HLTSU88):** A one-time donation helps keep the lights on.
* 📝 **Documentation:** Help us improve the [user manual](https://github.com/bancika/diy-layout-creator/blob/wiki/Manual.md) or other project docs.
* 🧩 **Extend the App:** Read the [Component API Wiki](https://github.com/bancika/diy-layout-creator/blob/wiki/ComponentAPI.md) to add new components, or the [Plugin API Wiki](https://github.com/bancika/diy-layout-creator/blob/wiki/PluginAPI.md) to create new plug-ins.
---
### 📜 License Information
The source code is released under the [GNU General Public License version 3](https://www.gnu.org/licenses/gpl-3.0.txt). Please contact the project owner to obtain a commercial license if you plan to use the source code, or any part of it, for commercial purposes.
### 🙌 Credits
* Huge thanks to the online communities that contributed ideas and helped test the app: [DIY Stompboxes](http://www.diystompboxes.com/smfforum/), [AX84](http://ax84.com/bbs), and [Free Stompboxes](http://freestompboxes.org).
* DIYLC is highly optimized thanks to [YourKit Java Profiler](http://www.yourkit.com/java/profiler/index.jsp). YourKit is kindly supporting open-source projects with its full-featured Java Profiler, which helped tremendously with memory and performance profiling. *YourKit, LLC is the creator of innovative and intelligent tools for profiling Java and .NET applications.*
+7
View File
@@ -147,3 +147,10 @@ buildNumber.properties
# Avoid ignoring Maven wrapper jar file (.jar files are usually ignored)
!/.mvn/wrapper/maven-wrapper.jar
######################
###### Custom ######
######################
# Deployment folder
deploy/
+3 -1
View File
@@ -1,8 +1,10 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="DIYLCStarter" type="Application" factoryName="Application" nameIsGenerated="true">
<option name="ALTERNATIVE_JRE_PATH" value="temurin-21" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
<option name="MAIN_CLASS_NAME" value="org.diylc.DIYLCStarter" />
<module name="diylc-swing" />
<option name="VM_PARAMETERS" value="-Xms1024m -Xmx4096m -Ddorg.diylc.debugAreaPerformance=true -Dorg.diylc.scriptRun=true -Dfile.encoding=UTF-8 --add-exports java.desktop/com.apple.eawt.event=ALL-UNNAMED --add-exports java.desktop/com.apple.eio=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.desktop/java.awt=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED --add-opens java.desktop/java.awt.geom=ALL-UNNAMED" />
<option name="VM_PARAMETERS" value="-Xms1024m -Xmx4096m -Ddorg.diylc.debugAreaPerformance=true -Dorg.diylc.scriptRun=true -Ddorg.diylc.cloud.baseUrl=http://localhost:8080 -Dfile.encoding=UTF-8 --add-exports java.desktop/com.apple.eawt.event=ALL-UNNAMED --add-exports java.desktop/com.apple.eio=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.desktop/java.awt=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED --add-opens java.desktop/java.awt.geom=ALL-UNNAMED" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="org.diylc.*" />
+17
View File
@@ -0,0 +1,17 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="RegressionTestRunner" type="Application" factoryName="Application" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="org.diylc.RegressionTestRunner" />
<module name="diylc-swing" />
<option name="PROGRAM_PARAMETERS" value="$PROJECT_DIR$/../diylc-regression-data TEST" />
<option name="VM_PARAMETERS" value="--add-exports java.desktop/com.apple.eawt.event=ALL-UNNAMED --add-exports java.desktop/com.apple.eio=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.desktop/java.awt=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED --add-opens java.desktop/java.awt.geom=ALL-UNNAMED" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="org.diylc.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>
+1 -1
View File
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
+123
View File
@@ -0,0 +1,123 @@
#!/bin/bash
# Script to build all Maven profiles and copy zip files to deployment folder
# Usage: ./build-all-profiles.sh [to-deploy-folder]
set -e # Exit on error
# Parse arguments
DEPLOY_DIR="${1:-}"
# Configuration
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SWING_MODULE_DIR="${PROJECT_DIR}/diylc-swing"
DEPLOY_DIR="${DEPLOY_DIR:-${PROJECT_DIR}/deploy}"
# List of profiles to build
PROFILES=(
"universal-zip"
"linux-appimage"
"win64-zip"
"win64-installer"
"mac-x86"
"mac-arm"
)
echo "=========================================="
echo "Building all Maven profiles"
echo "=========================================="
echo "Project directory: ${PROJECT_DIR}"
echo "Swing module directory: ${SWING_MODULE_DIR}"
echo "Deployment directory: ${DEPLOY_DIR}"
echo "Tests: Skipped"
echo ""
# Create deployment directory if it doesn't exist
mkdir -p "${DEPLOY_DIR}"
# Change to project root directory
cd "${PROJECT_DIR}"
# Build each profile (clean before each one)
TARGET_DIR="${SWING_MODULE_DIR}/target"
TOTAL_ZIP_COUNT=0
for profile in "${PROFILES[@]}"; do
echo "----------------------------------------"
echo "Building profile: ${profile}"
echo "----------------------------------------"
# Clean and build from root, specifying the swing module and profile
# This ensures dependencies (diylc-core, diylc-library) are built first
mvn clean package -pl diylc-swing -am -P"${profile}" -DskipTests || {
echo "ERROR: Failed to build profile ${profile}"
echo "Continuing with next profile..."
continue
}
echo "✓ Profile ${profile} built successfully"
# Copy zip and exe files immediately after each build (before next clean)
if [ -d "${TARGET_DIR}" ]; then
echo "Looking for artifacts in ${TARGET_DIR}..."
PROFILE_FILE_COUNT=0
# Find all zip files in target directory (excluding DIYLC-notarize.zip)
while IFS= read -r -d '' zipfile; do
filename=$(basename "${zipfile}")
# Skip DIYLC-notarize.zip files
if [[ "${filename}" != "DIYLC-notarize.zip" ]] && [ -f "${zipfile}" ]; then
dest="${DEPLOY_DIR}/${filename}"
echo " → Copying: ${filename}"
cp "${zipfile}" "${dest}"
TOTAL_ZIP_COUNT=$((TOTAL_ZIP_COUNT + 1))
PROFILE_FILE_COUNT=$((PROFILE_FILE_COUNT + 1))
fi
done < <(find "${TARGET_DIR}" -maxdepth 1 -type f -name "*.zip" -print0 2>/dev/null)
# Find all exe files in target directory
while IFS= read -r -d '' exefile; do
if [ -f "${exefile}" ]; then
filename=$(basename "${exefile}")
dest="${DEPLOY_DIR}/${filename}"
echo " → Copying: ${filename}"
cp "${exefile}" "${dest}"
TOTAL_ZIP_COUNT=$((TOTAL_ZIP_COUNT + 1))
PROFILE_FILE_COUNT=$((PROFILE_FILE_COUNT + 1))
fi
done < <(find "${TARGET_DIR}" -maxdepth 1 -type f -name "*.exe" -print0 2>/dev/null)
if [ ${PROFILE_FILE_COUNT} -eq 0 ]; then
echo " ⚠ Warning: No artifacts found for profile ${profile}"
# List what's actually in the target directory for debugging
echo " Debug: Files in target directory:"
ls -la "${TARGET_DIR}"/*.{zip,exe} 2>/dev/null | head -5 || echo " (no zip/exe files found)"
else
echo " ✓ Copied ${PROFILE_FILE_COUNT} file(s) from ${profile}"
fi
else
echo " ⚠ Warning: Target directory ${TARGET_DIR} does not exist"
fi
echo ""
done
echo "=========================================="
echo "Copying summary"
echo "=========================================="
if [ ${TOTAL_ZIP_COUNT} -eq 0 ]; then
echo "No artifacts were copied"
else
echo "✓ Copied ${TOTAL_ZIP_COUNT} file(s) total to ${DEPLOY_DIR}"
fi
echo ""
echo "=========================================="
echo "Build and deployment complete!"
echo "=========================================="
echo "Deployment folder: ${DEPLOY_DIR}"
echo "Files:"
ls -lh "${DEPLOY_DIR}"/*.{zip,exe} 2>/dev/null || echo " (no zip/exe files found)"
+4 -4
View File
@@ -7,15 +7,15 @@
<parent>
<groupId>org.diylc</groupId>
<artifactId>diylc-parent</artifactId>
<version>5.4.0</version>
<version>6.4.0</version>
</parent>
<artifactId>diylc-core</artifactId>
<!-- No need to specify version - it inherits from parent -->
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
<dependencies>
@@ -60,7 +60,7 @@
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.16.1</version>
<version>2.22.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -0,0 +1,95 @@
/*
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.announcements;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Utility methods for detecting and extracting URLs from announcements and HTML.
*/
public class AnnouncementUtils {
private static final Pattern HREF_PATTERN = Pattern.compile(
"href=[\"']([^\"']+)[\"']", Pattern.CASE_INSENSITIVE);
/**
* Extracts the first URL found in the text or HTML.
*
* @param html text or HTML content
* @return first URL found, or null if none
*/
public static String extractFirstUrl(String html) {
List<String> urls = extractUrls(html);
return urls.isEmpty() ? null : urls.get(0);
}
/**
* Extracts all unique URLs found in the HTML href attributes in order of appearance.
*
* @param html text or HTML content
* @return list of unique URLs
*/
public static List<String> extractUrls(String html) {
List<String> urls = new ArrayList<String>();
if (html == null || html.isEmpty()) {
return urls;
}
Matcher hrefMatcher = HREF_PATTERN.matcher(html);
while (hrefMatcher.find()) {
String url = hrefMatcher.group(1).trim();
url = normalizeUrl(url);
if (!urls.contains(url)) {
urls.add(url);
}
}
return urls;
}
/**
* Checks whether the HTML contains any link.
*
* @param html text or HTML content
* @return true if at least one URL is detected, false otherwise
*/
public static boolean containsLink(String html) {
return extractFirstUrl(html) != null;
}
/**
* Normalizes a URL to ensure it has a valid protocol if starting with www.
*/
public static String normalizeUrl(String url) {
if (url == null) {
return null;
}
String trimmed = url.trim();
if (trimmed.startsWith("www.")) {
return "http://" + trimmed;
}
return trimmed;
}
}
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -29,6 +29,7 @@ import java.io.Serializable;
import java.util.List;
import java.util.Set;
import org.diylc.core.ComponentGroup;
import org.diylc.core.IDIYComponent;
/**
@@ -44,19 +45,21 @@ public class ComponentTransferable implements Transferable, Serializable {
public static final DataFlavor listFlavor = new DataFlavor(ComponentTransferable.class, "application/diylc");
private List<IDIYComponent<?>> components;
private Set<Set<IDIYComponent<?>>> groups;
private Set<ComponentGroup> groups;
private String name;
public ComponentTransferable() {
super();
}
public ComponentTransferable(List<IDIYComponent<?>> components) {
public ComponentTransferable(List<IDIYComponent<?>> components, String name) {
super();
this.components = components;
this.name = name;
this.groups = null;
}
public ComponentTransferable(List<IDIYComponent<?>> components, Set<Set<IDIYComponent<?>>> groups) {
public ComponentTransferable(List<IDIYComponent<?>> components, Set<ComponentGroup> groups) {
super();
this.components = components;
this.groups = groups;
@@ -84,7 +87,11 @@ public class ComponentTransferable implements Transferable, Serializable {
return components;
}
public Set<Set<IDIYComponent<?>>> getGroups() {
public Set<ComponentGroup> getGroups() {
return groups;
}
public String getName() {
return name;
}
}
@@ -1,6 +1,6 @@
/*
*
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors.
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2025 held jointly by the individual authors.
*
* This file is part of DIYLC.
*
@@ -17,15 +17,11 @@
*/
package org.diylc.clipboard;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import org.apache.log4j.Logger;
import org.diylc.core.ComponentGroup;
import org.diylc.core.IDIYComponent;
public class ComponentTransferableFactory {
@@ -40,13 +36,19 @@ public class ComponentTransferableFactory {
return instance;
}
public ComponentTransferable build(Collection<IDIYComponent<?>> selectedComponents, Set<Set<IDIYComponent<?>>> groups) {
Set<IDIYComponent<?>> originalComponentSet = new HashSet<IDIYComponent<?>>(selectedComponents);
public ComponentTransferable build(Collection<IDIYComponent<?>> selectedComponents, Set<ComponentGroup> groups) {
List<IDIYComponent<?>> originalComponents = new ArrayList<IDIYComponent<?>>(selectedComponents);
Map<UUID, UUID> idMap = new HashMap<>();
List<IDIYComponent<?>> clonedComponents = originalComponents.stream(
).map(x -> {
try {
return x.clone();
IDIYComponent<?> clone = x.clone();
clone.setId(UUID.randomUUID());
idMap.put(x.getId(), clone.getId());
return clone;
} catch (CloneNotSupportedException e) {
LOG.error(e);
return null;
@@ -54,22 +56,18 @@ public class ComponentTransferableFactory {
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
Set<Set<IDIYComponent<?>>> clonedGroups = new HashSet<Set<IDIYComponent<?>>>();
for (Set<IDIYComponent<?>> group : groups) {
if (group.isEmpty())
continue;
if (originalComponentSet.contains(group.iterator().next())) {
Set<IDIYComponent<?>> clonedGroup = new HashSet<IDIYComponent<?>>();
clonedGroups.add(clonedGroup);
for (int i = 0; i < originalComponents.size(); i++) {
if (group.contains(originalComponents.get(i))) {
clonedGroup.add(clonedComponents.get(i));
}
}
}
}
Set<ComponentGroup> clonedGroups = groups.stream()
.map(group -> {
Set<UUID> newIds = group.getComponentIds().stream()
.map(idMap::get)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
// Only create group if it has at least one valid ID
return newIds.isEmpty() ? null : new ComponentGroup(newIds, group.getName());
})
.filter(Objects::nonNull)
.collect(Collectors.toSet());
return new ComponentTransferable(clonedComponents, clonedGroups);
}
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -0,0 +1,43 @@
/*
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.common;
/**
* The two ways a saved {@link BuildingBlock} can be placed on the canvas.
*
* @author Branislav Stojkovic
*/
public enum BlockInstantiationMode {
/**
* The block's components are cloned as individual, independently selectable components and
* grouped together (the original, and only, behavior before composite mode was introduced).
*/
GROUP,
/**
* The block's components are cloned and wrapped in a single
* {@code org.diylc.components.composite.CompositeComponent} that behaves as one rigid
* component with its own name, aggregating the control points of all its children.
*/
COMPOSITE
}
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,6 +1,6 @@
/*
*
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors.
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2025 held jointly by the individual authors.
*
* This file is part of DIYLC.
*
@@ -56,14 +56,14 @@ public class ComponentType implements Serializable {
private boolean enableCache;
private List<String[]> datasheet;
private int datasheetCreationStepCount;
public ComponentType() {
public ComponentType() {
}
public ComponentType(String name, String description, CreationMethod creationMethod, String category,
String namePrefix, String author, Icon icon, Class<? extends IDIYComponent<?>> instanceClass, double zOrder,
boolean flexibleZOrder, BomPolicy bomPolicy, boolean autoEdit, IComponentTransformer transformer,
KeywordPolicy keywordPolicy, String keywordTag, boolean enableCache, List<String[]> datasheet,
boolean flexibleZOrder, BomPolicy bomPolicy, boolean autoEdit, IComponentTransformer transformer,
KeywordPolicy keywordPolicy, String keywordTag, boolean enableCache, List<String[]> datasheet,
int datasheetCreationStepCount) {
super();
this.name = name;
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -68,5 +68,9 @@ public enum DrawOption {
/**
* Whether locked components should be rendered as transparent or not.
*/
LOCKED_ALPHA;
LOCKED_ALPHA,
/**
* When applied, all colors will be converted to blackest black or whitest white
*/
MONOCHROMATIC;
}
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -19,13 +19,12 @@
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
*/
package org.diylc.swing.gui;
package org.diylc.common;
import java.io.File;
import java.util.List;
import java.util.Set;
import org.diylc.common.PropertyWrapper;
import org.diylc.core.IView;
public class DummyView implements IView {
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -21,7 +21,6 @@
*/
package org.diylc.common;
import java.awt.Rectangle;
import java.awt.geom.Point2D;
import org.diylc.core.Project;
@@ -55,12 +54,7 @@ public enum EventType {
*/
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
* Called when component selection is changed. New list of components and control point map is attached as a
* parameter.
*/
SELECTION_CHANGED,
@@ -118,5 +112,10 @@ public enum EventType {
/**
* Signals that the Cloud account is logged out.
*/
CLOUD_LOGGED_OUT;
CLOUD_LOGGED_OUT,
/**
* Called when the mouse hovers over sticky control points (nodes) in tooltip mode.
* Parameters: String text (semicolon-separated component and node names, or null), Point point.
*/
NODE_NAME_HOVER_TOOLTIP;
}
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -25,13 +25,28 @@ import java.io.IOException;
public interface IBlockProcessor {
public static final String BLOCKS_KEY = "buildingBlocks";
public static final String BLOCKS_KEY = "buildingBlocks";
public static final String DEFAULT_BLOCKS_IMPORTED_KEY = "defaultBlocksImported";
/**
* Prefix that marks a string as a reference to a building block rather than a component class
* name. Used wherever components and blocks share a single identifier list, such as keyboard
* shortcuts ({@code COMPONENT_SHORTCUT_KEY}) and the recently used list
* ({@link org.diylc.common.IPlugInPort#RECENT_COMPONENTS_KEY}). A block identifier looks like
* {@code "block:My Block Name"}.
*/
public static final String BLOCK_PREFIX = "block:";
void saveSelectionAsBlock(String blockName);
void loadBlock(String blockName) throws InvalidBlockException;
/**
* Loads the block in the given {@link BlockInstantiationMode}. {@link BlockInstantiationMode#COMPOSITE}
* (a single rigid component) is the default mode used by most call sites (see design decision D10 in
* {@code docs/plans/composite-building-blocks.md}); {@link BlockInstantiationMode#GROUP} instantiates
* the block as a group of loose components.
*/
void loadBlock(String blockName, BlockInstantiationMode mode) throws InvalidBlockException;
void deleteBlock(String blockName);
int importBlocks(String fileName) throws IOException;
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -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.common;
import java.util.Set;
import org.diylc.core.ComponentGroup;
/**
* Interface for component grouping operations.
*
* @author Branislav Stojkovic
*/
public interface IGroupProcessor {
/**
* Returns the set of component groups in the current project. Each group is a set of components
* that are grouped together.
*
* @return set of component groups
*/
Set<ComponentGroup> getComponentGroups();
/**
* Groups all selected components.
*/
void groupSelectedComponents();
/**
* Ungroups all selected components.
*/
void ungroupSelectedComponents();
}
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -41,16 +41,18 @@ import org.diylc.core.IDIYComponent;
import org.diylc.core.Project;
import org.diylc.core.Template;
import org.diylc.core.Theme;
import org.diylc.core.measures.ResizeDimensions;
import org.diylc.core.measures.Size;
import org.diylc.filter.IComponentFilter;
import org.diylc.test.ITestProcessor;
/**
* 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
@@ -84,18 +86,24 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
public static final String RENUMBER_ON_PASTE_KEY = "renumberOnPaste";
public static final String RULER_IN_SUBDIVISION_KEY = "rulerInSubdivision";
public static final String CACHING_ENABLED_KEY = "cachingEnabled";
public static final String FONT_SCALE_FACTOR_KEY = "fontScaleFactor";
public static final String SHOW_RESIZE_DIMENSIONS_TOOLTIP_KEY = "showResizeDimensionsTooltip";
public static final String AUTO_UNIT_CONVERSION_KEY = "autoUnitConversion";
public static final String RULER_IN_SUBDIVISION_2 = "base of 2";
public static final String RULER_IN_SUBDIVISION_10 = "base of 10";
public static final String RULER_IN_SUBDIVISION_DEFAULT = RULER_IN_SUBDIVISION_10;
public static final String SNAP_TO_NONE = "None";
public static final String SNAP_TO_GRID = "Grid";
public static final String SNAP_TO_COMPONENTS = "Components";
public static final String SNAP_TO_DEFAULT = SNAP_TO_GRID;
public static final String SHOW_NODE_NAME_TOOLTIPS_KEY = "showNodeNameTooltips";
public static final String LOCKED_ALPHA = "lockedAlpha";
public static final String LANGUAGE = "language";
public static final String LANGUAGE_DEFAULT = "English";
@@ -108,25 +116,25 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
public static final int NOBUTTON = 0;
public static final int BUTTON1 = 1;
public static final int BUTTON2 = 2;
public static final int BUTTON3 = 3;
public static final int BUTTON3 = 3;
/**
* 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
* @param includeExtraSpace
*
*
* @return canvas dimensions
*/
Dimension getCanvasDimensions(boolean useZoom, boolean includeExtraSpace);
/**
* Returns an instance of {@link Cursor} that should be used at the specified location.
*
*
* Note: point coordinates are scaled for zoom factor.
*
*
* @param point
* @param ctrlDown
* @param shiftDown
@@ -137,14 +145,14 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
/**
* Returns an instance of currently loaded project.
*
*
* @return
*/
Project getCurrentProject();
/**
* Loads specified {@link Project}.
*
*
* @param project
* @param freshStart
* @param filename file name when loading from a file
@@ -158,22 +166,22 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
/**
* 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);
/**
* Exports the current project into one or more files - one per layer and potentially drill layer.
*
*
* @param fileNameBase
* @param g2d
*/
@@ -191,7 +199,7 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
/**
* 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();
@@ -200,7 +208,7 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
* 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();
@@ -208,7 +216,7 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
/**
* 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
@@ -222,35 +230,35 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
/**
* 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);
/**
* Returns current version number.
*
*
* @return
*/
VersionNumber getCurrentVersionNumber();
/**
* Returns few most recent versions.
*
* Returns few most recent versions.
*
* @return
*/
List<Version> getRecentUpdates();
/**
* Adds a list of components to the project.
*
*
* @param componentTransferable
* @param autoGroup
* @param assignNewNames
@@ -269,7 +277,7 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
/**
* 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
*/
@@ -277,7 +285,7 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
/**
* Sets default value for the specified property name for projects.
*
*
* @param clazz class to set defaults to
* @param propertyName display name for property
* @param value new default value, must not be null
@@ -291,6 +299,15 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
*/
List<PropertyWrapper> getMutualSelectionProperties();
/**
* Available only during resizing, returns the dimensions of the component being resized.
* Otherwise returns null.
*
* @return ResizeDimensions with width, height (in mm or in depending on configuration),
* and length (if component implements IHaveLength), or null if not resizing
*/
ResizeDimensions getResizeDimensions();
void editSelection();
/**
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -31,7 +31,7 @@ import org.diylc.core.ExpansionMode;
import org.diylc.core.IDIYComponent;
import org.diylc.core.measures.Size;
public interface ISelectionProcessor {
public interface ISelectionProcessor extends IGroupProcessor {
/**
* Returns the current {@link ComponentTransferable}.
@@ -89,16 +89,6 @@ public interface ISelectionProcessor {
*/
void rotateSelection(int direction);
/**
* Groups all selected components.
*/
void groupSelectedComponents();
/**
* Ungroups all selected components.
*/
void ungroupSelectedComponents();
/**
* Mirrors selected components in the given axis.
*
@@ -3,6 +3,7 @@ package org.diylc.common;
import org.diylc.appframework.simplemq.MessageDispatcher;
import org.diylc.plugins.chatbot.service.ChatbotService;
import org.diylc.plugins.cloud.service.CloudService;
import org.diylc.plugins.compare.service.CompareService;
import org.diylc.presenter.DrawingManager;
public interface IServiceManager {
@@ -11,6 +12,8 @@ public interface IServiceManager {
ChatbotService getChatbotService();
CompareService getCompareService();
MessageDispatcher<EventType> getMessageDispatcher();
DrawingManager getDrawingManager();
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,6 +1,6 @@
/*
*
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors.
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2025 held jointly by the individual authors.
*
* This file is part of DIYLC.
*
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -0,0 +1,89 @@
/*
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.common;
import java.io.Serializable;
import java.math.BigDecimal;
public class Percentage implements Serializable, Cloneable {
private static final long serialVersionUID = 1L;
private BigDecimal value;
public Percentage(BigDecimal value) {
this.value = value;
}
public Percentage(double value) {
this.value = BigDecimal.valueOf(value);
}
public Percentage(int value) {
this.value = BigDecimal.valueOf((long) value);
}
public BigDecimal getValue() {
return value;
}
public void setValue(BigDecimal value) {
this.value = value;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((value == null) ? 0 : value.stripTrailingZeros().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;
Percentage other = (Percentage) obj;
if (value == null) {
if (other.value != null)
return false;
} else if (value.compareTo(other.value) != 0)
return false;
return true;
}
@Override
public String toString() {
if (value == null) return "null%";
BigDecimal stripped = value.stripTrailingZeros();
return String.format("%s%%", stripped.toPlainString());
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -24,8 +24,11 @@ package org.diylc.common;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.core.IDynamicPropertySource;
import org.diylc.core.IPropertyValidator;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
/**
* Entity class for editable properties extracted from component objects. Represents a single
@@ -65,7 +68,8 @@ public class PropertyWrapper implements Cloneable {
public void readFrom(Object object) throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException, SecurityException, NoSuchMethodException {
this.ownerObject = object;
this.value = getGetter().invoke(object);
Object value = getGetter().invoke(object);
this.value = value;
}
// public void readUniqueFrom(IDIYComponent component)
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -30,6 +30,7 @@ import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.UUID;
import java.util.stream.Collectors;
import org.diylc.core.IDIYComponent;
@@ -52,6 +53,7 @@ public abstract class AbstractComponent<T> implements IDIYComponent<T> {
private static final long serialVersionUID = 1L;
protected UUID id = UUID.randomUUID();
protected String name = "";
public static Color SELECTION_COLOR = Color.red;
@@ -62,6 +64,7 @@ public abstract class AbstractComponent<T> implements IDIYComponent<T> {
public static Color LIGHT_METAL_COLOR = Color.decode("#EEEEEE");
public static Color COPPER_COLOR = Color.decode("#DA8A67");
public static Color GOLD_COLOR = Color.decode("#F4B301");
public static Color BRASS_COLOR = Color.decode("#B8860B");
public static Color FR4_COLOR = Color.decode("#6B9B6B");
public static Color FR4_LIGHT_COLOR = Color.decode("#BABE71");
public static Color PHENOLIC_COLOR = Color.decode("#F8EBB3");
@@ -78,6 +81,19 @@ public abstract class AbstractComponent<T> implements IDIYComponent<T> {
this.name = name;
}
@Override
public UUID getId() {
if (id == null) {
id = UUID.randomUUID();
}
return id;
}
@Override
public void setId(UUID id) {
this.id = id;
}
@Override
public boolean canControlPointOverlap(int index) {
return false;
@@ -186,6 +202,10 @@ public abstract class AbstractComponent<T> implements IDIYComponent<T> {
field.setAccessible(true);
Object value = field.get(this);
if (field.getName().equalsIgnoreCase("id")) {
value = getId();
}
// Deep copy point arrays.
// TODO: something nicer
if (value != null && value.getClass().isArray()
@@ -274,11 +294,6 @@ public abstract class AbstractComponent<T> implements IDIYComponent<T> {
return null;
}
@Override
public String[] getSectionNames(int pointIndex) {
return null;
}
@Override
public boolean canPointMoveFreely(int pointIndex) {
return true;
@@ -1,6 +1,6 @@
/*
*
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors.
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2025 held jointly by the individual authors.
*
* This file is part of DIYLC.
*
@@ -37,16 +37,14 @@ import com.thoughtworks.xstream.annotations.XStreamOmitField;
import org.diylc.common.IPlugInPort;
import org.diylc.common.LineStyle;
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.*;
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> {
public abstract class AbstractCurvedComponent<T> extends AbstractTransparentComponent<T> implements
IHaveLength {
private static final long serialVersionUID = 1L;
@@ -151,10 +149,7 @@ public abstract class AbstractCurvedComponent<T> extends AbstractTransparentComp
path.curveTo(p[4].getX(), p[4].getY(), p[5].getX(), p[5].getY(), p[6].getX(), p[6].getY());
}
Composite oldComposite = g2d.getComposite();
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA));
}
Composite oldComposite = applyAlpha(g2d);
drawCurve(path, g2d, componentState, drawingObserver);
@@ -337,8 +332,12 @@ public abstract class AbstractCurvedComponent<T> extends AbstractTransparentComp
// }
}
@EditableProperty
@EditableProperty(name = "Length")
public Size getLength() {
return calculateLength();
}
public Size calculateLength() {
double d = 0;
try {
Point2D[] p = getControlPoints();
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -22,24 +22,57 @@
package org.diylc.components;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.ComponentState;
import org.diylc.common.Percentage;
import java.awt.*;
public abstract class AbstractTransparentComponent<T> extends AbstractComponent<T> {
private static final long serialVersionUID = 1L;
private static final boolean OUTLINE_MODE_WHILE_DRAGGING = false;
public static byte MAX_ALPHA = 127;
public static byte MAX_ALPHA_LEGACY = Byte.MAX_VALUE;
public static int MAX_ALPHA = 100;
protected Byte alpha = MAX_ALPHA;
@Deprecated
protected Byte alpha;
@EditableProperty
public Byte getAlpha() {
if (alpha == null) {
alpha = MAX_ALPHA;
protected Percentage alphaPercent = new Percentage(100);
@EditableProperty(name = "Alpha")
public Percentage getAlpha() {
if (alphaPercent == null) {
if (alpha != null) {
alphaPercent = new Percentage(Math.round(100f * alpha / MAX_ALPHA_LEGACY));
alpha = null;
} else {
alphaPercent = new Percentage(100);
}
}
return alpha;
return alphaPercent;
}
public void setAlpha(Byte alpha) {
this.alpha = alpha;
public void setAlpha(Percentage alphaPercent) {
this.alphaPercent = alphaPercent;
}
public Composite applyAlpha(Graphics2D g2d, ComponentState componentState) {
Composite oldComposite = g2d.getComposite();
double alpha = (OUTLINE_MODE_WHILE_DRAGGING && componentState == ComponentState.DRAGGING) ? 0 :
getAlpha().getValue().doubleValue();
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float)(alpha / 100d)));
}
return oldComposite;
}
public Composite applyAlpha(Graphics2D g2d) {
Composite oldComposite = g2d.getComposite();
double alpha = getAlpha().getValue().doubleValue();
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float)(alpha / 100d)));
}
return oldComposite;
}
}
@@ -0,0 +1,296 @@
/*
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.components.composite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import org.diylc.components.AbstractComponent;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.utils.Constants;
/**
* Instantiation of a {@code BuildingBlock} as a single, rigid component rather than a group of
* loose ones. Wraps an embedded list of child components and aggregates their control points,
* so it can be placed, moved, rotated and wired up like any other component while the netlist,
* BOM and AI project description still see its individual terminals (see
* {@link #getControlPointNodeName(int)}).
*
* @author Branislav Stojkovic
*/
@ComponentDescriptor(
name = "Building Block",
description = "A group of components instantiated as a single rigid component",
category = "Building Blocks",
author = "Branislav Stojkovic",
instanceNamePrefix = "BLK",
zOrder = IDIYComponent.COMPONENT,
flexibleZOrder = true,
bomPolicy = BomPolicy.SHOW_ALL_NAMES,
autoEdit = false,
enableCache = false,
transformer = CompositeComponentTransformer.class,
hiddenInPalette = true)
public class CompositeComponent extends AbstractTransparentComponent<String> {
private static final long serialVersionUID = 1L;
private List<IDIYComponent<?>> childComponents = new ArrayList<IDIYComponent<?>>();
// Name of the building block this instance was created from. Drives its display identity in
// the BOM, netlist report and AI project description (see ComponentProcessor.getDisplayTypeName).
private String blockName;
// Free-form label the user can edit after placement, independent of blockName. Shown in the BOM.
private String value;
// Flat index mapping a composite control point index to (child ordinal, child point index).
// Rebuilt lazily since children never change after construction and the arrays are not
// serialized (transient).
private transient int[] childOf;
private transient int[] pointOf;
/**
* Required no-arg constructor, used reflectively by {@code ComponentProcessor} and XStream.
*/
public CompositeComponent() {
super();
}
private void buildIndexIfNeeded() {
if (childOf != null) {
return;
}
int total = 0;
for (IDIYComponent<?> c : childComponents) {
total += c.getControlPointCount();
}
int[] newChildOf = new int[total];
int[] newPointOf = new int[total];
int idx = 0;
for (int ci = 0; ci < childComponents.size(); ci++) {
IDIYComponent<?> c = childComponents.get(ci);
int count = c.getControlPointCount();
for (int pi = 0; pi < count; pi++) {
newChildOf[idx] = ci;
newPointOf[idx] = pi;
idx++;
}
}
childOf = newChildOf;
pointOf = newPointOf;
}
/**
* @return the embedded child components, in save order. Never {@code null}.
*/
public List<IDIYComponent<?>> getChildComponents() {
if (childComponents == null) {
childComponents = new ArrayList<IDIYComponent<?>>();
}
return childComponents;
}
@EditableProperty(name = "Block", defaultable = false, sortOrder = 1)
public String getBlockName() {
return blockName;
}
/**
* Sets the source block name. Deliberately not named {@code setBlockName} so that
* {@code ComponentProcessor}'s getter/setter matching does not turn the "Block" property
* editable in the property editor - it is metadata about the instance, not a value the user
* should be able to change after placement.
*/
public void initBlockName(String blockName) {
this.blockName = blockName;
}
@Override
public int getControlPointCount() {
buildIndexIfNeeded();
return childOf.length;
}
@Override
public Point2D getControlPoint(int index) {
buildIndexIfNeeded();
return childComponents.get(childOf[index]).getControlPoint(pointOf[index]);
}
@Override
public void setControlPoint(Point2D point, int index) {
buildIndexIfNeeded();
childComponents.get(childOf[index]).setControlPoint(point, pointOf[index]);
}
@Override
public boolean isControlPointSticky(int index) {
buildIndexIfNeeded();
return childComponents.get(childOf[index]).isControlPointSticky(pointOf[index]);
}
@Override
public boolean canControlPointOverlap(int index) {
buildIndexIfNeeded();
return childComponents.get(childOf[index]).canControlPointOverlap(pointOf[index]);
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
buildIndexIfNeeded();
return childComponents.get(childOf[index]).getControlPointVisibilityPolicy(pointOf[index]);
}
@Override
public String getControlPointNodeName(int index) {
buildIndexIfNeeded();
return childComponents.get(childOf[index]).getControlPointNodeName(pointOf[index]);
}
/**
* The composite is always rigid: it moves and rotates as a unit and never stretches. See design
* decision D4 in {@code docs/plans/composite-building-blocks.md}.
*/
@Override
public boolean canPointMoveFreely(int pointIndex) {
return false;
}
@Override
public void createdIn(Project project) {
for (IDIYComponent<?> c : getChildComponents()) {
c.createdIn(project);
}
}
@Override
@EditableProperty
public String getValue() {
return value;
}
@Override
public void setValue(String value) {
this.value = value;
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
Composite oldComposite = applyAlpha(g2d, componentState);
for (IDIYComponent<?> c : getChildComponents()) {
// Children always draw in their normal state - the composite draws its own selection
// outline below instead of letting every child paint its own highlight.
c.draw(g2d, componentState, outlineMode, project, drawingObserver);
}
g2d.setComposite(oldComposite);
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
// Must not touch `components` - ComponentProcessor draws this on a default-constructed,
// childless instance to build the palette icon.
g2d.setColor(LIGHT_METAL_COLOR);
g2d.fillRect(2, 2, width - 4, height - 4);
g2d.setColor(METAL_COLOR);
g2d.drawRect(2, 2, width - 4, height - 4);
int halfW = width / 2;
int halfH = height / 2;
g2d.drawLine(halfW, 2, halfW, height - 2);
g2d.drawLine(2, halfH, width - 2, halfH);
}
/**
* Deep-clones the composite together with all its children, so that two placed instances never
* share child objects (that would make moving one instance move the other - see the "clone()
* is the sharp edge" risk in {@code docs/plans/composite-building-blocks.md}). Preserves this
* component's own id and every child's id, matching {@link AbstractComponent#clone()}'s
* contract of copying identity by default - callers that need a genuinely new component
* reassign ids themselves, exactly as {@code BuildingBlockManager.loadBlock} does when it
* clones each source component individually to place a brand new instance of a block. This also
* keeps id-sensitive reflective comparisons (like the default {@code equalsTo} most child
* component classes inherit) working correctly between a composite and its own clone, which the
* undo dirty-check in {@code Presenter.notifyProjectModifiedIfNeeded} relies on.
*/
@Override
public IDIYComponent<String> clone() throws CloneNotSupportedException {
CompositeComponent clone = new CompositeComponent();
clone.setId(getId());
clone.setName(getName());
clone.blockName = this.blockName;
clone.value = this.value;
// matches AbstractComponent.clone(), which shallow-copies the Percentage reference
clone.setAlpha(getAlpha());
List<IDIYComponent<?>> clonedComponents = new ArrayList<IDIYComponent<?>>(getChildComponents().size());
for (IDIYComponent<?> c : getChildComponents()) {
clonedComponents.add(c.clone());
}
clone.childComponents = clonedComponents;
return clone;
}
/**
* Overridden because {@link AbstractComponent#equalsTo(IDIYComponent)} compares the
* {@code components} field with {@code List.equals()}, which falls back to child object
* identity since no component class overrides {@code Object.equals()} - two structurally
* identical composites built from different object graphs (e.g. an original and its clone)
* would otherwise never compare equal, defeating the undo dirty-check in
* {@code Presenter.notifyProjectModifiedIfNeeded}.
*/
@Override
public boolean equalsTo(IDIYComponent<?> other) {
if (!(other instanceof CompositeComponent)) {
return false;
}
CompositeComponent o = (CompositeComponent) other;
if (!Objects.equals(getName(), o.getName()) || !Objects.equals(blockName, o.blockName)
|| !Objects.equals(value, o.value) || !Objects.equals(getAlpha(), o.getAlpha())) {
return false;
}
List<IDIYComponent<?>> otherComponents = o.getChildComponents();
if (getChildComponents().size() != otherComponents.size()) {
return false;
}
for (int i = 0; i < childComponents.size(); i++) {
if (!childComponents.get(i).equalsTo(otherComponents.get(i))) {
return false;
}
}
return true;
}
}
@@ -0,0 +1,97 @@
/*
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.components.composite;
import java.awt.geom.Point2D;
import org.diylc.common.ComponentType;
import org.diylc.common.IComponentTransformer;
import org.diylc.core.IDIYComponent;
import org.diylc.presenter.ComponentProcessor;
/**
* Rotates and mirrors a {@link CompositeComponent} by delegating to each child's own
* {@link IComponentTransformer}, around the same centre for every child so the assembly stays
* geometrically consistent. If any child's type cannot rotate (or mirror), the whole composite
* reports that it cannot either - silently leaving one child un-rotated would be worse (see
* design decision D9 in {@code docs/plans/composite-building-blocks.md}).
*
* @author Branislav Stojkovic
*/
public class CompositeComponentTransformer implements IComponentTransformer {
@Override
public boolean canRotate(IDIYComponent<?> component) {
CompositeComponent composite = (CompositeComponent) component;
if (composite.getChildComponents().isEmpty())
return false;
for (IDIYComponent<?> child : composite.getChildComponents()) {
if (!childTransformer(child).canRotate(child))
return false;
}
return true;
}
@Override
public boolean canMirror(IDIYComponent<?> component) {
CompositeComponent composite = (CompositeComponent) component;
if (composite.getChildComponents().isEmpty())
return false;
for (IDIYComponent<?> child : composite.getChildComponents()) {
if (!childTransformer(child).canMirror(child))
return false;
}
return true;
}
@Override
public boolean mirroringChangesCircuit() {
// This transformer instance is shared by every CompositeComponent (ComponentProcessor caches
// one instance per class), so it has no access to a specific composite's children here.
// Conservatively assume mirroring can change the circuit, so the user is always warned - a
// spurious confirmation is far cheaper than silently flipping a board's pinout.
return true;
}
@Override
public void rotate(IDIYComponent<?> component, Point2D center, int direction) {
CompositeComponent composite = (CompositeComponent) component;
for (IDIYComponent<?> child : composite.getChildComponents()) {
childTransformer(child).rotate(child, center, direction);
}
}
@Override
public void mirror(IDIYComponent<?> component, Point2D center, int direction) {
CompositeComponent composite = (CompositeComponent) component;
for (IDIYComponent<?> child : composite.getChildComponents()) {
childTransformer(child).mirror(child, center, direction);
}
}
@SuppressWarnings({"unchecked", "rawtypes"})
private IComponentTransformer childTransformer(IDIYComponent<?> child) {
ComponentType type =
ComponentProcessor.getInstance().extractComponentTypeFrom((Class) child.getClass());
return type.getTransformer();
}
}
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -0,0 +1,43 @@
package org.diylc.core;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
public class ComponentGroup implements Serializable {
private Set<UUID> componentIds;
private String name;
public ComponentGroup(Set<UUID> componentIds) {
this.componentIds = componentIds;
}
public ComponentGroup(Set<UUID> componentIds, String name) {
this.componentIds = componentIds;
this.name = name;
}
public static ComponentGroup from(Collection<IDIYComponent<?>> components, String name) {
Set<UUID> componentIds = components.stream()
.map(IDIYComponent::getId)
.filter(id -> id != null)
.collect(Collectors.toSet());
return new ComponentGroup(componentIds, name);
}
public Set<UUID> getComponentIds() {
return componentIds;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,6 +1,6 @@
/*
*
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors.
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2025 held jointly by the individual authors.
*
* This file is part of DIYLC.
*
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -25,6 +25,7 @@ import java.awt.Graphics2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import java.util.UUID;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
@@ -55,6 +56,10 @@ public interface IDIYComponent<T> extends Serializable, Cloneable {
public static final int WIRING = 5;
public static final int TEXT = 6;
UUID getId();
void setId(UUID id);
/**
* @return component instance name.
*/
@@ -132,13 +137,6 @@ public interface IDIYComponent<T> extends Serializable, Cloneable {
*/
String getInternalLinkName(int index1, int index2);
/**
* @param pointIndex
* @return name of the internal section containing the specified point, or null if the component does not have internal sections.
* One point can be shared between multiple sections, in which case, the result may contain more than one element.
*/
String[] getSectionNames(int pointIndex);
/**
* @param pointIndex
* @return true if the control point can move without affecting other points' position, false otherwise
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -0,0 +1,29 @@
/*
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.core.measures.Size;
public interface IHaveLength {
Size calculateLength();
}
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -23,13 +23,9 @@ package org.diylc.core;
import java.awt.Font;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import org.diylc.appframework.update.VersionNumber;
import org.diylc.core.annotations.EditableProperty;
@@ -67,6 +63,7 @@ public class Project implements Serializable, Cloneable {
private Integer dotSpacing;
private List<IDIYComponent<?>> components;
private Set<Set<IDIYComponent<?>>> groups;
private Set<ComponentGroup> groupsEx;
private Set<Integer> lockedLayers;
private Set<IDIYComponent<?>> lockedComponents;
private Set<Integer> hiddenLayers;
@@ -75,6 +72,7 @@ public class Project implements Serializable, Cloneable {
public Project() {
components = new ArrayList<IDIYComponent<?>>();
groups = new HashSet<Set<IDIYComponent<?>>>();
groupsEx = new HashSet<>();
lockedLayers = new HashSet<Integer>();
hiddenLayers = new HashSet<Integer>();
lockedComponents = new HashSet<IDIYComponent<?>>();
@@ -153,22 +151,35 @@ public class Project implements Serializable, Cloneable {
/**
* List of components sorted by z-order ascending.
*
* s
* @return
*/
public List<IDIYComponent<?>> getComponents() {
return components;
}
/**
* Set of grouped components.
*
* @return
*/
public Set<Set<IDIYComponent<?>>> getGroups() {
return groups;
public Set<ComponentGroup> getGroupsEx() {
if (groupsEx == null) {
groupsEx = new HashSet<>();
if (groups != null && !groups.isEmpty()) {
for (Set<IDIYComponent<?>> group : groups) {
Set<IDIYComponent<?>> nonNullIds =
group.stream().filter(Objects::nonNull).collect(Collectors.toSet());
if (!nonNullIds.isEmpty()) {
ComponentGroup newGroup = ComponentGroup.from(group, null);
groupsEx.add(newGroup);
}
}
groups.clear();
}
}
groupsEx.removeAll(groupsEx.stream().
filter(x -> x.getComponentIds() == null ||
x.getComponentIds().stream().noneMatch(Objects::nonNull)).collect(Collectors.toSet()));
return groupsEx;
}
public Set<IDIYComponent<?>> getLockedComponents() {
if (lockedComponents == null)
lockedComponents = new HashSet<IDIYComponent<?>>();
@@ -292,6 +303,11 @@ public class Project implements Serializable, Cloneable {
return false;
} else if (!groups.equals(other.groups))
return false;
if (groupsEx == null) {
if (other.groupsEx != null)
return false;
} else if (!groupsEx.equals(other.groupsEx))
return false;
if (lockedLayers == null) {
if (other.lockedLayers != null)
return false;
@@ -356,12 +372,15 @@ public class Project implements Serializable, Cloneable {
}
}
for (Set<IDIYComponent<?>> group : this.groups) {
Set<IDIYComponent<?>> cloneGroup = new HashSet<IDIYComponent<?>>();
for (IDIYComponent<?> component : group) {
cloneGroup.add(cloneMap.get(component));
for (ComponentGroup group : this.getGroupsEx()) {
// Filter out null IDs when cloning groups
Set<UUID> validIds = group.getComponentIds().stream()
.filter(id -> id != null)
.collect(Collectors.toSet());
// Only add group if it has valid component IDs
if (!validIds.isEmpty()) {
project.getGroupsEx().add(new ComponentGroup(validIds, group.getName()));
}
project.groups.add(cloneGroup);
}
for (IDIYComponent<?> component : this.getLockedComponents()) {
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -123,9 +123,18 @@ public @interface ComponentDescriptor {
boolean enableDatasheet() default false;
/**
* If datasheet is enabled, this property determines how many columns define a component, e.g. in how many steps we can instantiate a component
*
* If datasheet is enabled, this property determines how many columns define a component, e.g. in how many steps we can instantiate a component
*
* @return
*/
int datasheetCreationStepCount() default 0;
/**
* @return true if the component type should not be listed in the palette (toolbox and
* component tree), while still being resolvable via
* {@code ComponentProcessor.extractComponentTypeFrom} for netlist, BOM and name
* generation purposes. Used by component types that are only ever created
* programmatically, e.g. {@code CompositeComponent}.
*/
boolean hiddenInPalette() default false;
}
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -27,5 +27,7 @@ import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface PercentEditor {
public byte _100PercentValue();
public int minValue() default 0;
public int maxValue() default 100;
}
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -1,7 +1,7 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
Copyright (c) 2009-2025 held jointly by the individual authors.
This file is part of DIYLC.
@@ -300,7 +300,7 @@ public class GerberG2DWrapper extends Graphics2D
@Override
public AffineTransform getTransform() {
return tx;
return new AffineTransform(tx);
}
@Override
@@ -1,80 +1,84 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 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.images;
import org.apache.log4j.Logger;
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"), ElementsSelection(
"elements_selection.png"), Schaller("schaller.png");
protected String name;
private IconLoader(String name) {
this.name = name;
}
public Icon getIcon() {
java.net.URL imgURL = getClass().getResource("/diylc-core-images/" + name);
if (imgURL != null) {
return new ImageIcon(imgURL, name);
} else {
Logger.getLogger(IconLoader.class).error("Couldn't find file: " + name);
return null;
}
}
public Image getImage() {
BufferedImage img = null;
try {
img = ImageIO.read(getClass().getResourceAsStream("/diylc-core-images/" + name));
} catch (IOException e) {
Logger.getLogger(IconLoader.class).error("Couldn't find file: " + name);
}
return img;
}
}
/*
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.images;
import org.apache.log4j.Logger;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
/**
* Loads image resources as Icons.
*
* @author Branislav Stojkovic
*/
public enum IconLoader {
About("about.png"), Add("add.png"), BOM("bom.png"), Back("back.png"), BlackBoard(
"blackboard.png"), Bug("bug.png"), CSV("csv.png"), Chest("chest.png"), Component(
"component.png"), Copy("copy.png"), Cut("cut.png"), Delete("delete.png"), DiskBlue(
"disk_blue.png"), DocumentEdit("document_edit.png"), DocumentPlainYellow(
"document_plain_yellow.png"), Donate("donate.png"), EditComponent(
"edit_component.png"), ElementsSelection("elements_selection.png"), Error("error.png"), Excel(
"excel.png"), Exit("exit.png"), Faq("faq.png"), FolderOut("folder_out.png"), FormGreen(
"form_green.png"), Front("front.png"), Garbage("garbage.png"), Gears("gears.png"), Group(
"group.png"), HTML("html.png"), IconLarge("icon_large.png"), IconMedium(
"icon_medium.png"), IconSmall("icon_small.png"), IdCard("id_card.png"), IdCardAdd(
"id_card_add.png"), Image("image.png"), LightBulbOff("lightbulb_off.png"), LightBulbOn(
"lightbulb_on.png"), Manual("manual.png"), MoveSmall("move_small.png"), NavigateCheck(
"navigate_check.png"), NotebookAdd("notebook_add.png"), PDF("pdf.png"), Paste(
"paste.png"), Pens("pens.png"), PhotoScenery("photo_scenery.png"), Plugin(
"plugin.png"), Print("print.png"), SaveAs("save_as.png"), Schaller("schaller.png"), Selection(
"selection.png"), Size("size.png"), Sort("sort.png"), TraceMask("trace_mask.png"), Undo(
"undo.png"), Ungroup("ungroup.png"), Upload("upload.png"), Warning(
"warning.png"), WindowColors("window_colors.png"), WindowGear("window_gear.png"), Wrench(
"wrench.png"), ZoomSmall("zoom_small.png");
protected String name;
private IconLoader(String name) {
this.name = name;
}
public Icon getIcon() {
java.net.URL imgURL = getClass().getResource("/diylc-core-images/" + name);
if (imgURL != null) {
return new ImageIcon(imgURL, name);
} else {
Logger.getLogger(IconLoader.class).error("Couldn't find file: " + name);
return null;
}
}
public Image getImage() {
BufferedImage img = null;
try {
img = ImageIO.read(getClass().getResourceAsStream("/diylc-core-images/" + name));
} catch (IOException e) {
Logger.getLogger(IconLoader.class).error("Couldn't find file: " + name);
}
return img;
}
}

Some files were not shown because too many files have changed in this diff Show More