Compare commits

..

107 Commits

Author SHA1 Message Date
Branislav Stojkovic bb3b37f23b patched osx component loading issue, investigate further 2019-03-25 08:21:20 +01:00
Branislav Stojkovic fcea5975a8 change backup folder name 2019-03-24 21:38:27 +01:00
Branislav Stojkovic 2294ac45a2 copy loaded file as-is to backup folder 2019-03-24 21:37:37 +01:00
Branislav Stojkovic 5598f22b2f Added "Auto-Wrap Label" component
extracted string rendering function into a separate class
2019-03-24 08:34:28 +01:00
Branislav Stojkovic 812b7adb28 remove newPoints and reuse points for backward compatibility 2019-03-23 22:44:09 +01:00
Branislav Stojkovic 9fd5a8fe96 redo relaxed validation 2019-03-23 19:11:06 +01:00
Branislav Stojkovic 0b8952e354 relax validation of control point collision while dragging 2019-03-23 18:54:44 +01:00
Branislav Stojkovic 5c47ff1ef0 added ability to include or exclude switches from netlist analyzer 2019-03-23 18:05:28 +01:00
Branislav Stojkovic b85b93404b Added mini toolbar in the top-right corner of the screen with transform
actions exposed for quick access
2019-03-22 23:37:59 +01:00
Branislav Stojkovic b46f46aa99 When pasting a group of components that contain at least one "PCB Text"
instance, some of the other components get rendered mirrored while
position the pasted components
2019-03-22 22:29:05 +01:00
Branislav Stojkovic 48266d3b27 fix the 3rd control point when copy-pasting 2019-03-22 21:04:54 +01:00
Branislav Stojkovic eb6cc76f02 make autosave params configurable 2019-03-22 20:58:27 +01:00
Branislav Stojkovic a5d512ca37 Merge branch 'master' of https://github.com/bancika/diy-layout-creator.git 2019-03-22 16:39:23 +01:00
Branislav Stojkovic 1d038b5f8c better log 2019-03-22 16:39:08 +01:00
Branislav Stojkovic 9366f9c602 Auto-save plugin now works by periodically creating project backups in
user\.diylc\autoSave directory and maintains file history, keeping the
last X versions of the file. Maximum size for all backups is
configurable and pre-set to 64MB
2019-03-22 16:38:01 +01:00
bancika 23b4fcae02 Update README.md 2019-03-22 10:34:55 +01:00
Branislav Stojkovic 14a994e68f Improve "Expand Selection" feature to use the same algorithm as netlists
for better precision<
2019-03-22 00:47:28 +01:00
Branislav Stojkovic 894ff1a2cb Assign new name for pasted component if the project already contains
components under that name
2019-03-20 22:35:28 +01:00
Branislav Stojkovic 78dcd27e1d Some schematic symbols (transistors, potentiometer...) get into bad
state when rotated and flipped at the same time
2019-03-20 20:06:38 +01:00
Branislav Stojkovic 714db98afa deleted old file
fixed pin rendering on some components
2019-03-20 19:27:46 +01:00
Branislav Stojkovic 2faa2c6d61 reorganized "stretchable" property into more granular control at the
point level

added controlable label to pot symbol and transistor symbols
2019-03-20 19:21:31 +01:00
Branislav Stojkovic 3c45336afe rename a function 2019-03-19 21:26:03 +01:00
Branislav Stojkovic a0601cc83d better default label position on schematic symbols 2019-03-19 19:03:21 +01:00
Branislav Stojkovic 9925d58347 keep label oriantation the same between the two modes 2019-03-18 22:57:30 +01:00
Branislav Stojkovic 6c241b3180 added third control point to leaded components to set label position 2019-03-18 22:49:27 +01:00
Branislav Stojkovic 838adc9a51 reorganize netlist code, comment out unused functions 2019-03-14 22:36:43 +01:00
Branislav Stojkovic 41d2b73cca Merge switch configurations that yield with the same effective wiring
for "Analyze Guitar Wirings" module, for more compact report
2019-03-14 22:26:49 +01:00
Branislav Stojkovic 8d3789a0b0 update file 2019-03-14 11:19:15 +01:00
Branislav Stojkovic 95f65dcdf1 scan library folder for more jars 2019-03-14 11:14:32 +01:00
Branislav Stojkovic 3d0f9554b0 Honor all possible combinations of "DIP Switch" positions when creating
a netlist
2019-03-14 10:32:51 +01:00
Branislav Stojkovic 0c21e013b4 improve node display for single point componenets 2019-03-14 10:03:04 +01:00
Branislav Stojkovic f8e24b0937 Improve performance of netlist calculations 2019-03-14 00:08:39 +01:00
Branislav Stojkovic 37d5ce18fc Z-order of components sometimes gets wrong when importing a DIY file
into another file
2019-03-13 21:24:55 +01:00
Branislav Stojkovic e9a2785344 Honor "Terminal Strip" connectivity when creating a netlist 2019-03-13 20:54:24 +01:00
Branislav Stojkovic 4de3b6d97c Output SPICE node names in the "Nxxx" format
join all nodes connected to GND together
2019-03-13 19:23:35 +01:00
Branislav Stojkovic 92a2bb9809 fix "Ground Symbol" jumping 2019-03-10 22:58:36 +01:00
Branislav Stojkovic 440b953531 fix orientation parsing 2019-03-10 22:53:01 +01:00
Branislav Stojkovic 1bc11e09ab release 2019-03-10 22:36:09 +01:00
Branislav Stojkovic f20b896184 release 2019-03-10 22:32:34 +01:00
Branislav Stojkovic 49d93b42a4 update.xml 2019-03-10 17:51:21 +01:00
Branislav Stojkovic b279510e5c Detect when a file is created with a newer version of DIYLC and show a
warning

Force correct prefix for transistors in spice
2019-03-10 09:03:22 +01:00
Branislav Stojkovic a83cda9ecd custom XStream converters for more compact files 2019-03-09 21:45:34 +01:00
Branislav Stojkovic f63b422a8c Cleaner XML format for .DIY files with less cross-references
pinout update
2019-03-09 20:15:36 +01:00
Branislav Stojkovic 7af919b303 move section handling to base component interface
do analysis in background thread
2019-03-09 18:01:42 +01:00
Branislav Stojkovic 1c1ec2fcf5 refactor transistor packages with a base class, add pinouts 2019-03-09 17:24:34 +01:00
Branislav Stojkovic 8ccdd84a6f add support to map DIYLC pin indices to spice 2019-03-09 16:47:18 +01:00
Branislav Stojkovic 54ff518438 basic implementation of spice exporter 2019-03-09 14:46:00 +01:00
Branislav Stojkovic c893b37fdf don't show favorites for categories 2019-03-09 11:27:15 +01:00
Branislav Stojkovic 81e259bb62 fix the sorting for favorites 2019-03-09 11:24:44 +01:00
Branislav Stojkovic d5aac6b265 When in "Highlight Connected Area" mode, the status bar shows useful
information making it harder to forget what the mode does
2019-03-09 11:19:32 +01:00
Branislav Stojkovic d544797047 Ability to tag components and building blocks as favorites 2019-03-09 10:42:39 +01:00
Branislav Stojkovic 8ed2c0c9a5 "Mini Toggle Switch" doesn't reset body size after changing terminal
spacing
2019-03-08 18:36:37 +01:00
Branislav Stojkovic 2d1cf515d6 "Highlight Connected Areas" doesn't follow multiple chained wires and
jumpers
2019-03-06 00:15:53 +01:00
Branislav Stojkovic 2553ffbba7 z-order of building blocks 2019-03-04 10:34:53 +01:00
Branislav Stojkovic 04418f8101 fix update file 2019-03-02 21:02:24 +01:00
Branislav Stojkovic c548a35939 3.55 release 2019-03-02 20:59:38 +01:00
Branislav Stojkovic 777f4aa3fd protect PropertyWrapper writeTo call 2019-03-02 15:55:24 +01:00
Branislav Stojkovic c0c226c580 improve tree analysis 2019-03-02 12:48:10 +01:00
Branislav Stojkovic 40d234d1c4 <org.diylc.appframework.update.Change>
<changeType>IMPROVEMENT</changeType>
					<description>Increase the range of zoom slider for images to
500%</description>
				</org.diylc.appframework.update.Change>
2019-03-02 12:32:42 +01:00
Branislav Stojkovic bc0d759d39 detect volume and tone pots 2019-03-02 12:31:02 +01:00
Branislav Stojkovic b3497cdca8 Fix lever switch rotation issue
Render pickup name instead of model

Netlist algorithm would sometimes create overlapping groups of nodes
which are supposed to be merged
2019-03-02 09:11:00 +01:00
Branislav Stojkovic cc0f698c8b detect humbucking or split mode 2019-03-01 20:49:07 +01:00
Branislav Stojkovic b0123db3e7 Fixed bug with "Highlight Continuity Areas" that makes random components
conductive
2019-03-01 09:51:55 +01:00
Branislav Stojkovic c9a32cc390 better handling for cold start without logs folder 2019-02-28 23:40:29 +01:00
Branislav Stojkovic 46d9e1f82a improve pickup label rendering 2019-02-28 23:34:02 +01:00
Branislav Stojkovic 9596d6ca8e "Analyze Guitar Wiring" can figure out if wiring is hum-cancelling and
in or out of phase for each position
2019-02-28 22:26:12 +01:00
Branislav Stojkovic 65315ed559 fix connectivity 2019-02-28 21:26:41 +01:00
Branislav Stojkovic 57bce6b8e5 Added 4-position Tele switch type to the "Lever Switch" component 2019-02-28 21:25:21 +01:00
Branislav Stojkovic 403d0ea433 Added two or four terminal hookup to bass pickups types 2019-02-28 19:11:02 +01:00
Branislav Stojkovic 595cfb3ed1 Increase the range of zoom slider for images to 500% 2019-02-28 17:36:04 +01:00
Branislav Stojkovic 2c689c584d Merge branch 'master' of https://github.com/bancika/diy-layout-creator.git 2019-02-27 19:23:09 +01:00
Branislav Stojkovic 84eaa1bf29 reuse awg calcs 2019-02-27 19:20:37 +01:00
Branislav Stojkovic 20e01762b8 Show wire diameter in mm and in next to AWG gauge 2019-02-27 19:16:44 +01:00
Branislav Stojkovic 08aec6fa9b startup fix 2019-02-26 23:27:32 +01:00
bancika f51d19b39a Update README.md 2019-02-26 16:47:41 +01:00
Branislav Stojkovic 8bfb3ade55 fix array comparison for byte[] 2019-02-26 16:20:40 +01:00
bancika 3847813351 Update README.md 2019-02-26 15:38:31 +01:00
Branislav Stojkovic 67761b1027 error handling for analyzer 2019-02-26 10:25:20 +01:00
Branislav Stojkovic 7cca8f86b2 build 3.54 2019-02-26 10:10:42 +01:00
Branislav Stojkovic 39976ec3d6 tests 2019-02-25 15:28:10 +01:00
Branislav Stojkovic a155aef596 fix bom test 2019-02-25 11:10:36 +01:00
Branislav Stojkovic b24bfafb39 add unit tests for netlist 2019-02-25 11:05:15 +01:00
Branislav Stojkovic 31ce46f147 minor image update 2019-02-24 14:49:35 +01:00
Branislav Stojkovic ce43a5d2e6 Improve performance of "Image" component and greatly reduce file size
when images are present
2019-02-24 14:32:30 +01:00
Branislav Stojkovic 0d007e5737 tree construction improvement 2019-02-24 13:15:30 +01:00
Branislav Stojkovic c0dac1a1db generate connectivity tree 2019-02-23 17:40:15 +01:00
Branislav Stojkovic ec7244042d wiring analysis improvements 2019-02-17 09:31:42 +01:00
Branislav Stojkovic 88275e95e2 wiring analysys, ground work 2019-02-17 01:37:37 +01:00
Branislav Stojkovic add8566d4f netlist summarizer infrastructure added 2019-02-17 00:13:22 +01:00
Branislav Stojkovic c5495ad14f Version 3.53 would not start unless there was an older version running
on the same machine before
2019-02-16 23:04:38 +01:00
Branislav Stojkovic 94f1c68c7b pickup improvements 2019-02-16 22:14:08 +01:00
Branislav Stojkovic 3e67515f69 improved netlist display
minor component updates
2019-02-16 20:12:44 +01:00
Branislav Stojkovic 2091b8a03d add terminal labels to pickups 2019-02-16 18:41:22 +01:00
Branislav Stojkovic 235acf538f Added ability to mark common lugs on all "Lever Switch" types with a
different color

add switch logic to lever switch
2019-02-16 17:04:09 +01:00
Branislav Stojkovic 45404aaabd add center-off switch types 2019-02-16 16:05:15 +01:00
Branislav Stojkovic 2727276a09 minor rendering improvement for LP switch 2019-02-16 12:27:11 +01:00
Branislav Stojkovic cb6aa83269 better netlist html format 2019-02-16 12:15:52 +01:00
Branislav Stojkovic 39daa9e61f LP switch updates 2019-02-16 12:12:08 +01:00
Branislav Stojkovic 8313a62324 added netlist menu item and dialog 2019-02-16 12:11:54 +01:00
Branislav Stojkovic c1d718a0f9 add netlist support to LP switch 2019-02-16 11:46:47 +01:00
Branislav Stojkovic 6e5174750f rename graph-related stuff into netlists 2019-02-16 09:40:55 +01:00
Branislav Stojkovic 1cfb30f35e pickup graph improvements 2019-02-16 09:14:49 +01:00
Branislav Stojkovic ddfc615a6a graph improvmeents 2019-02-15 23:39:54 +01:00
Branislav Stojkovic f53ad8c206 Allow a file to be loaded if it references a missing component property,
but show a warning.
2019-02-15 23:23:12 +01:00
Branislav Stojkovic 20645fed13 fix switched jack point location
proper node names
2019-02-15 22:52:36 +01:00
Branislav Stojkovic d3c2e20359 new app-framework 2019-02-15 21:48:26 +01:00
Branislav Stojkovic 46f693addf ground work for graph analysis 2019-02-15 20:25:57 +01:00
166 changed files with 8272 additions and 3351 deletions
+6 -5
View File
@@ -12,19 +12,20 @@
<ul>
<li>platform independence, will run on any machine having Java JRE/JDK 1.6.0_45 or newer </li>
<li>easy to use interface, most of the operations can be done using mouse </li>
<li>can be used to 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 without much trouble </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 the circuit to a SPICE compatible netlist (beta) </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>create and load project templates </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>
</ul>
@@ -44,6 +45,6 @@
<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 sites that helped with testing and ideas: <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>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 3 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>
Binary file not shown.
@@ -21,23 +21,23 @@
*/
package org.diylc.common;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.diylc.core.IDIYComponent;
public class BuildingBlockPackage {
private Map<String, Collection<IDIYComponent<?>>> block;
private Map<String, List<IDIYComponent<?>>> block;
private String owner;
public BuildingBlockPackage(Map<String, Collection<IDIYComponent<?>>> blocks, String owner) {
public BuildingBlockPackage(Map<String, List<IDIYComponent<?>>> blocks, String owner) {
super();
this.block = blocks;
this.owner = owner;
}
public Map<String, Collection<IDIYComponent<?>>> getBlocks() {
public Map<String, List<IDIYComponent<?>>> getBlocks() {
return block;
}
@@ -43,18 +43,16 @@ public class ComponentType {
private Class<? extends IDIYComponent<?>> instanceClass;
private double zOrder;
private boolean flexibleZOrder;
private boolean stretchable;
private BomPolicy bomPolicy;
private boolean autoEdit;
private IComponentTransformer transformer;
private KeywordPolicy keywordPolicy;
private String keywordTag;
private boolean continuity;
public ComponentType(String name, String description, CreationMethod creationMethod, String category,
String namePrefix, String author, Icon icon, Class<? extends IDIYComponent<?>> instanceClass, double zOrder,
boolean flexibleZOrder, boolean stretchable, BomPolicy bomPolicy, boolean autoEdit,
IComponentTransformer transformer, KeywordPolicy keywordPolicy, String keywordTag, boolean continuity) {
boolean flexibleZOrder, BomPolicy bomPolicy, boolean autoEdit, IComponentTransformer transformer,
KeywordPolicy keywordPolicy, String keywordTag) {
super();
this.name = name;
this.description = description;
@@ -66,13 +64,11 @@ public class ComponentType {
this.instanceClass = instanceClass;
this.zOrder = zOrder;
this.flexibleZOrder = flexibleZOrder;
this.stretchable = stretchable;
this.bomPolicy = bomPolicy;
this.autoEdit = autoEdit;
this.transformer = transformer;
this.keywordPolicy = keywordPolicy;
this.keywordTag = keywordTag;
this.continuity = continuity;
}
public String getName() {
@@ -115,10 +111,6 @@ public class ComponentType {
return flexibleZOrder;
}
public boolean isStretchable() {
return stretchable;
}
public BomPolicy getBomPolicy() {
return bomPolicy;
}
@@ -139,10 +131,6 @@ public class ComponentType {
return keywordTag;
}
public boolean isContinuity() {
return continuity;
}
@Override
public String toString() {
return name;
@@ -0,0 +1,93 @@
/*
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.common;
import java.io.Serializable;
public class Favorite implements Serializable, Comparable<Favorite> {
private static final long serialVersionUID = 1L;
private FavoriteType type;
private String name;
public Favorite(FavoriteType type, String name) {
super();
this.type = type;
this.name = name;
}
public FavoriteType getType() {
return type;
}
public String getName() {
return name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Favorite other = (Favorite) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (type != other.type)
return false;
return true;
}
@Override
public String toString() {
return type + ":" + name;
}
public enum FavoriteType {
Component, Block
}
public String toDisplay() {
String[] parts = name.split("\\.");
return parts[parts.length - 1];
}
@Override
public int compareTo(Favorite o) {
return toDisplay().compareToIgnoreCase(o.toDisplay());
}
}
@@ -0,0 +1,57 @@
/*
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.common;
import java.util.List;
import org.diylc.netlist.Netlist;
import org.diylc.netlist.Node;
import org.diylc.netlist.Summary;
import org.diylc.netlist.TreeException;
public interface INetlistAnalyzer {
/**
* @return summarizer name
*/
String getName();
/**
* @return name of the icon to use
*/
String getIconName();
/**
* Summarizes all {@link Netlist}s provided.
*
* @param netlists
* @param preferredOutput optional, needed only where there's more than one possible output node.
* @return
* @throws TreeException
*/
List<Summary> summarize(List<Netlist> netlists, Node preferredOutput) throws TreeException;
/**
* @return name of the font to be used for display.
*/
String getFontName();
}
@@ -0,0 +1,51 @@
/*
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.common;
import java.util.List;
import org.diylc.netlist.Netlist;
/**
* Interface for {@link Netlist} related operations.
*
* @author Branislav Stojkovic
*/
public interface INetlistProcessor {
/**
* Finds all {@link Netlist}s for each switch position combination.
*
* @param includeSwitches
* @return
*/
List<Netlist> extractNetlists(boolean includeSwitches);
/**
* Finds all available {@link INetlistAnalyzer} implementations.
*
* @return
*/
List<INetlistAnalyzer> getNetlistAnalyzers();
}
@@ -53,7 +53,7 @@ import org.diylc.core.Theme;
* @see EventType
*/
public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyProcessor, IVariantProcessor,
IBlockProcessor {
IBlockProcessor, INetlistProcessor {
public static final String ANTI_ALIASING_KEY = "antiAliasing";
public static final String HI_QUALITY_RENDER_KEY = "hiQualityRender";
@@ -74,7 +74,8 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
public static final String SHOW_GRID_KEY = "showGrid";
public static final String HIGHLIGHT_CONTINUITY_AREA = "highlightContinuityArea";
public static final String HARDWARE_ACCELERATION = "hardwareAcceleration";
public static final String EXTRA_SPACE_KEY = "extraSpace";
public static final String EXTRA_SPACE_KEY = "extraSpace";
public static final String FAVORITES_KEY = "favorites";
public static final int DND_TOGGLE_STICKY = 0x1;
public static final int DND_TOGGLE_SNAP = 0x40000000;
@@ -120,9 +121,10 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
* Loads specified {@link Project}.
*
* @param project
* @param freshStart
* @param freshStart
* @param optional file name when loading from a file
*/
void loadProject(Project project, boolean freshStart);
void loadProject(Project project, boolean freshStart, String filename);
/**
* Creates a new project.
@@ -21,25 +21,18 @@
*/
package org.diylc.components;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.Rectangle2D;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.VerticalAlignment;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.EditableProperty;
import java.awt.Color;
import java.awt.Font;
import java.awt.Point;
import java.awt.Shape;
import java.awt.geom.Rectangle2D;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.EditableProperty;
/**
* Abstract implementation of {@link IDIYComponent} that contains component name and toString.
@@ -147,54 +140,6 @@ public abstract class AbstractComponent<T> implements IDIYComponent<T> {
return !clip.intersects(rect);
}
protected void drawCenteredText(Graphics2D g2d, String text, int x, int y, HorizontalAlignment horizontalAlignment,
VerticalAlignment verticalAlignment) {
String[] parts = text.split("\n");
if (parts.length > 1) {
FontMetrics fontMetrics = g2d.getFontMetrics();
Rectangle stringBounds = fontMetrics.getStringBounds(parts[0], g2d).getBounds();
for (int i = 0; i < parts.length; i++)
drawCenteredText(g2d, parts[i], x, (int)(y - stringBounds.height * (parts.length - 1) / 2d + i * stringBounds.height), horizontalAlignment, verticalAlignment);
return;
}
FontMetrics fontMetrics = g2d.getFontMetrics();
Rectangle stringBounds = fontMetrics.getStringBounds(text, g2d).getBounds();
Font font = g2d.getFont();
FontRenderContext renderContext = g2d.getFontRenderContext();
GlyphVector glyphVector = font.createGlyphVector(renderContext, text);
Rectangle visualBounds = glyphVector.getVisualBounds().getBounds();
int textX = 0;
switch (horizontalAlignment) {
case CENTER:
textX = x - stringBounds.width / 2;
break;
case LEFT:
textX = x;
break;
case RIGHT:
textX = x - stringBounds.width;
break;
}
int textY = 0;
switch (verticalAlignment) {
case TOP:
textY = y + stringBounds.height;
break;
case CENTER:
textY = y - visualBounds.height / 2 - visualBounds.y;
break;
case BOTTOM:
textY = y - visualBounds.y;
break;
}
g2d.drawString(text, textX, textY);
}
@SuppressWarnings("unchecked")
public IDIYComponent<T> clone() throws CloneNotSupportedException {
try {
@@ -275,9 +220,36 @@ public abstract class AbstractComponent<T> implements IDIYComponent<T> {
return true;
if (o1 == null || o2 == null)
return false;
if (o1.getClass().isArray()) {
if (o1.getClass().isArray()) {
if (o1.getClass().getComponentType() == byte.class)
return Arrays.equals((byte[]) o1, (byte[]) o2);
return Arrays.equals((Object[]) o1, (Object[]) o2);
}
return o1.equals(o2);
}
@Override
public String getControlPointNodeName(int index) {
return Integer.toString(index + 1);
}
@Override
public String getInternalLinkName(int index1, int index2) {
return null;
}
@Override
public String[] getSectionNames(int pointIndex) {
return null;
}
@Override
public String getCommonPointName(int pointIndex) {
return null;
}
@Override
public boolean canPointMoveFreely(int pointIndex) {
return true;
}
}
@@ -0,0 +1,34 @@
/*
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;
public interface IContinuity {
/**
* Tests control point connectivity.
*
* @param index1
* @param index2
* @return true if the two points are connected, false otherwise.
*/
boolean arePointsConnected(int index1, int index2);
}
@@ -24,7 +24,7 @@ package org.diylc.core;
import java.awt.Graphics2D;
import java.awt.Point;
import java.io.Serializable;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
@@ -110,8 +110,44 @@ public interface IDIYComponent<T> extends Serializable {
* same component</b>. The other control point must be able to overlap too.
*/
boolean canControlPointOverlap(int index);
VisibilityPolicy getControlPointVisibilityPolicy(int index);
/**
* @param index
* @return {@link VisibilityPolicy} of the control point.
*/
VisibilityPolicy getControlPointVisibilityPolicy(int index);
/**
* @param index
* @return name of the control point node, if the control point represents a graph node, null otherwise.
*/
String getControlPointNodeName(int index);
/**
* @param index1
* @param index2
* @return name of the internal linked formed by the two control points, null if they do not form an internal link
*/
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 name of the common point that joins all the other points with the same name together, e.g. GND
*/
String getCommonPointName(int pointIndex);
/**
* @param pointIndex
* @return true if the control point can move without affecting other points' position, false otherwise
*/
boolean canPointMoveFreely(int pointIndex);
/**
* Draws the component onto the {@link Graphics2D}.
@@ -153,5 +189,5 @@ public interface IDIYComponent<T> extends Serializable {
* @param other
* @return
*/
boolean equalsTo(IDIYComponent<?> other);
boolean equalsTo(IDIYComponent<?> other);
}
@@ -35,5 +35,7 @@ public interface IDrawingObserver {
void stopTrackingContinuityArea();
void startTrackingContinuityArea(boolean positive);
void startTrackingContinuityArea(boolean positive);
boolean isTrackingContinuityArea();
}
@@ -0,0 +1,51 @@
/*
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;
/**
* Interface for all component that can act as switches. They must have at least one position.
*
* @author Branislav Stojkovic
*/
public interface ISwitch {
/**
* @return a positive number of positions.
*/
int getPositionCount();
/**
* @param position
* @return name of switch positions, e.g. "ON", "OFF"...
*/
String getPositionName(int position);
/**
* Tests control point connectivity.
*
* @param index1
* @param index2
* @param position
* @return true if the two points are connected in the given switch position, false otherwise.
*/
boolean arePointsConnected(int index1, int index2, int position);
}
@@ -82,12 +82,6 @@ public @interface ComponentDescriptor {
*/
boolean flexibleZOrder() default false;
/**
* @return when false, moving one control point will cause all the others to move together with
* it.
*/
boolean stretchable() default true;
/**
* @return controls what should be shown the BOM
*/
@@ -116,13 +110,5 @@ public @interface ComponentDescriptor {
*
* @return
*/
String keywordTag() default "";
/**
* For components that show continuity between the two ending points, e.d. wires, jumpers, etc.
*
* @return
*/
boolean continuity() default false;
String keywordTag() default "";
}
@@ -1,25 +0,0 @@
package org.diylc.graph;
import java.util.Dictionary;
import java.util.Set;
public class Graph {
private Dictionary<String, Position> positions;
private Set<Node> nodes;
public Graph() {
}
public Dictionary<String, Position> getPositions() {
return positions;
}
public Set<Node> getNodes() {
return nodes;
}
public boolean nodesMatch(Graph other) {
return this.nodes.equals(other.nodes);
}
}
@@ -1,65 +0,0 @@
package org.diylc.graph;
public class Node {
private String type;
private String component;
private String terminal;
public Node() {}
public String getType() {
return type;
}
public String getComponent() {
return component;
}
public String getTerminal() {
return terminal;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((component == null) ? 0 : component.hashCode());
result = prime * result + ((terminal == null) ? 0 : terminal.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Node other = (Node) obj;
if (component == null) {
if (other.component != null)
return false;
} else if (!component.equals(other.component))
return false;
if (terminal == null) {
if (other.terminal != null)
return false;
} else if (!terminal.equals(other.terminal))
return false;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
return true;
}
@Override
public String toString() {
return type + "." + component + "." + terminal;
}
}
@@ -1,65 +0,0 @@
package org.diylc.graph;
public class Position {
private String ownerType;
private String owner;
private String name;
public Position() {
}
public String getOwnerType() {
return ownerType;
}
public String getOwner() {
return owner;
}
public String getName() {
return name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((owner == null) ? 0 : owner.hashCode());
result = prime * result + ((ownerType == null) ? 0 : ownerType.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;
Position other = (Position) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (owner == null) {
if (other.owner != null)
return false;
} else if (!owner.equals(other.owner))
return false;
if (ownerType == null) {
if (other.ownerType != null)
return false;
} else if (!ownerType.equals(other.ownerType))
return false;
return true;
}
@Override
public String toString() {
return ownerType + "." + owner + "." + name;
}
}
@@ -1,54 +0,0 @@
package org.diylc.graph;
public class Vertex {
private Node node1;
private Node node2;
public Vertex() {
}
public Node getNode1() {
return node1;
}
public Node getNode2() {
return node2;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((node1 == null) ? 0 : node1.hashCode());
result = prime * result + ((node2 == null) ? 0 : node2.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;
Vertex other = (Vertex) obj;
if (node1 == null) {
if (other.node1 != null)
return false;
} else if (!node1.equals(other.node1))
return false;
if (node2 == null) {
if (other.node2 != null)
return false;
} else if (!node2.equals(other.node2))
return false;
return true;
}
@Override
public String toString() {
return node1.toString() + " -> " + node2.toString();
}
}
@@ -0,0 +1,113 @@
/*
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.netlist;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.diylc.core.IDIYComponent;
/**
* Represents a group of {@link Node}s that are connected together.
*
* @author Branislav Stojkovic
*/
public class Group implements Comparable<Group> {
private Set<Node> nodes = new HashSet<Node>();
public Group() {
}
public Group(Node node1, Node node2) {
nodes.add(node1);
nodes.add(node2);
}
public Group connect(IDIYComponent<?> component, int index) {
getNodes().add(new Node(component, index));
return this;
}
public Set<Node> getNodes() {
return nodes;
}
public List<Node> getSortedNodes() {
List<Node> list = new ArrayList<Node>(nodes);
Collections.sort(list);
return list;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((nodes == null) ? 0 : nodes.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;
Group other = (Group) obj;
if (nodes == null) {
if (other.nodes != null)
return false;
} else if (!nodes.equals(other.nodes))
return false;
return true;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
List<Node> list = getSortedNodes();
for (Node n : list) {
if (sb.length() > 0)
sb.append(" <-> ");
sb.append(n);
}
return sb.toString();
}
@Override
public int compareTo(Group o) {
return toString().compareToIgnoreCase(o.toString());
}
@Override
public Group clone() {
Group g = new Group();
g.nodes.addAll(nodes);
return g;
}
}
@@ -0,0 +1,31 @@
/*
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.netlist;
import java.util.List;
public interface ITree {
List<ITree> getChildren();
TreeConnectionType getConnectionType();
}
@@ -0,0 +1,100 @@
/*
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.netlist;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Netlist implements Comparable<Netlist> {
private Set<Group> groups = new HashSet<Group>();
private List<SwitchSetup> switchSetup = new ArrayList<SwitchSetup>();
public Netlist() {
}
public Set<Group> getGroups() {
return groups;
}
public Netlist add(Group g) {
groups.add(g);
return this;
}
public List<Group> getSortedGroups() {
List<Group> list = new ArrayList<Group>(groups);
Collections.sort(list);
return list;
}
public List<SwitchSetup> getSwitchSetup() {
return switchSetup;
}
public void done() {
Collections.sort(switchSetup);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((groups == null) ? 0 : groups.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;
Netlist other = (Netlist) obj;
if (groups == null) {
if (other.groups != null)
return false;
} else if (!groups.equals(other.groups))
return false;
return true;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
List<Group> list = getSortedGroups();
for (Group g : list) {
sb.append("\t").append(g).append("\n");
}
return sb.toString();
}
@Override
public int compareTo(Netlist o) {
return switchSetup.toString().compareToIgnoreCase(o.switchSetup.toString());
}
}
@@ -0,0 +1,496 @@
/*
*
* 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.netlist;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.diylc.core.IDIYComponent;
public abstract class NetlistAnalyzer {
public NetlistAnalyzer() {}
public List<Summary> summarize(List<Netlist> netlists, Node preferredOutput) throws TreeException {
Map<String, Summary> summaries = new HashMap<String, Summary>();
for (Netlist n : netlists) {
Summary s = summarize(n, preferredOutput);
if (summaries.containsKey(s.getSummary()))
summaries.get(s.getSummary()).append(n);
else
summaries.put(s.getSummary(), s);
}
List<Summary> res = new ArrayList<Summary>(summaries.values());
Collections.sort(res);
return res;
}
protected abstract Summary summarize(Netlist netlist, Node preferredOutput) throws TreeException;
public Tree constructTreeBetween(Netlist netlist, Node nodeA, Node nodeB) {
Tree tree = new Tree(TreeConnectionType.Parallel);
connectNodes(netlist, nodeA, nodeB, tree.getChildren(), new Tree(TreeConnectionType.Series), new HashSet<Node>());
// System.out.println(netlist.getSwitchSetup());
// System.out.println(tree);
//
// System.out.println("opposite:");
// Tree tree1 = new Tree(TreeConnectionType.Parallel);
// connectNodes(netlist, nodeB, nodeA, tree1.getChildren(), new Tree(TreeConnectionType.Series),
// new HashSet<Node>());
// System.out.println(tree1);
return tree;
}
protected void connectNodes(Netlist netlist, Node nodeA, Node nodeB, List<Tree> concurrentPaths, Tree currentPath,
Set<Node> visited) {
if (nodeA == nodeB) {
concurrentPaths.add(currentPath);
return;
}
Group groupA = findGroup(netlist, nodeA);
if (groupA == null)
return;
if (groupA.getNodes().contains(nodeB)) {
concurrentPaths.add(currentPath);
return;
}
visited.addAll(groupA.getNodes());
List<Tree> newConcurrentPaths = new ArrayList<Tree>();
for (Node n : groupA.getNodes()) {
IDIYComponent<?> c = n.getComponent();
for (int i = 0; i < c.getControlPointCount(); i++) {
if (i != n.getPointIndex() && c.getInternalLinkName(i, n.getPointIndex()) != null) {
TreeLeaf l = new TreeLeaf(c, i, n.getPointIndex());
Node newNodeA = new Node(c, i);
if (!visited.contains(newNodeA)) {
// visited.add(n);
Tree newCurrentPath = null;
try {
newCurrentPath = (Tree) currentPath.clone();
} catch (CloneNotSupportedException e) {
}
Tree newItem = new Tree(l);
if (!newCurrentPath.getChildren().contains(newItem))
newCurrentPath.getChildren().add(newItem);
// if (!currentPath.contains(l))
// newCurrentPath.add(l);
Set<Node> newVisited = new HashSet<Node>(visited);
connectNodes(netlist, newNodeA, nodeB, newConcurrentPaths, newCurrentPath, newVisited);
}
}
}
}
if (newConcurrentPaths.size() == 0)
return;
if (newConcurrentPaths.size() == 1) {
if (newConcurrentPaths.get(0).getConnectionType() == TreeConnectionType.Series) {
currentPath.getChildren().clear();
currentPath.getChildren().addAll(newConcurrentPaths.get(0).getChildren());
} else {
currentPath.getChildren().add(newConcurrentPaths.get(0));
}
concurrentPaths.add(currentPath);
return;
}
mergePaths(newConcurrentPaths, false);
concurrentPaths.addAll(newConcurrentPaths);
}
protected void mergePaths(List<Tree> paths, boolean backward) {
Map<Tree, Integer> uniques = new HashMap<Tree, Integer>();
for (Tree t : paths) {
if (t.getConnectionType() != TreeConnectionType.Series)
continue;
Tree key = t.getChildren().get(backward ? t.getChildren().size() - 1 : 0);
Integer count = uniques.get(key);
uniques.put(key, count == null ? 1 : count + 1);
}
List<Tree> unmerged = new ArrayList<Tree>(paths);
for (Map.Entry<Tree, Integer> e : uniques.entrySet()) {
if (e.getValue() > 1) {
List<Tree> pathsToMerge = new ArrayList<Tree>();
for (Tree t : paths) {
Tree key = t.getChildren().get(backward ? t.getChildren().size() - 1 : 0);
if (key.equals(e.getKey()))
pathsToMerge.add(t);
}
unmerged.removeAll(pathsToMerge);
Tree jointStart = new Tree(new ArrayList<Tree>(), TreeConnectionType.Series);
Tree jointFinish = new Tree(new ArrayList<Tree>(), TreeConnectionType.Series);
Tree unique = e.getKey();
for (int i = 0; i < pathsToMerge.get(0).getChildren().size(); i++) {
boolean canMerge = true;
unique = pathsToMerge.get(0).getChildren().get(backward ? pathsToMerge.get(0).getChildren().size() - i - 1 : i);
for (Tree t : pathsToMerge) {
if (t.getChildren().size() <= i || !t.getChildren().get(backward ? t.getChildren().size() - i - 1 : i).equals(unique)) {
canMerge = false;
break;
}
}
if (canMerge)
(backward ? jointFinish : jointStart).getChildren().add(unique);
else
break;
}
for (int i = 0; i < pathsToMerge.get(0).getChildren().size(); i++) {
boolean canMerge = true;
unique = pathsToMerge.get(0).getChildren().get(backward ? i : pathsToMerge.get(0).getChildren().size() - i - 1);
for (Tree t : pathsToMerge) {
if (t.getChildren().size() <= i || !t.getChildren().get(backward ? 0 : t.getChildren().size() - 1).equals(unique)) {
canMerge = false;
break;
}
}
if (canMerge)
(backward ? jointStart : jointFinish).getChildren().add(unique);
else
break;
}
if (!jointStart.getChildren().isEmpty() || !jointFinish.getChildren().isEmpty()) {
Tree mergedTree = new Tree(new ArrayList<Tree>(), TreeConnectionType.Series);
Tree parallelSection = new Tree(new ArrayList<Tree>(pathsToMerge), TreeConnectionType.Parallel);
if (!jointStart.getChildren().isEmpty()) {
mergedTree.getChildren().add(jointStart);
for (Tree t : parallelSection.getChildren()) {
t.trimChildrenLeft(jointStart.getChildren().size());
}
}
mergedTree.getChildren().add(parallelSection);
if (!jointFinish.getChildren().isEmpty()) {
mergedTree.getChildren().add(jointFinish);
for (Tree t : parallelSection.getChildren()) {
t.trimChildrenRight(jointFinish.getChildren().size());
}
}
paths.removeAll(pathsToMerge);
paths.add(mergedTree);
}
}
}
// try in the opposite direction for paths we haven't merged
if (!backward && !unmerged.isEmpty()) {
paths.removeAll(unmerged);
mergePaths(unmerged, true);
paths.addAll(unmerged);
}
}
//
// protected void findAllPaths(Netlist netlist, Node nodeA, Node nodeB, List<TreeLeaf> currentPath,
// List<List<TreeLeaf>> allPaths, Set<Node> visited) {
// if (nodeA == nodeB) {
// allPaths.add(currentPath);
// return;
// }
//
// // System.out.println("Finding path between " + nodeA + " and " + nodeB);
//
// Group groupA = findGroup(netlist, nodeA);
//
// if (groupA == null)
// return;
//
// if (groupA.getNodes().contains(nodeB)) {
// allPaths.add(currentPath);
// return;
// }
//
// for (Node n : groupA.getNodes()) {
// IDIYComponent<?> c = n.getComponent();
// for (int i = 0; i < c.getControlPointCount(); i++) {
// if (i != n.getPointIndex() && c.getInternalLinkName(i, n.getPointIndex()) != null) {
// TreeLeaf l = new TreeLeaf(c, i, n.getPointIndex());
// Node newNodeA = new Node(c, i);
// if (!visited.contains(newNodeA)) {
// List<TreeLeaf> newCurrentPath = new ArrayList<TreeLeaf>(currentPath);
// if (!currentPath.contains(l))
// newCurrentPath.add(l);
// Set<Node> newVisited = new HashSet<Node>(visited);
// newVisited.add(nodeA);
// newVisited.add(newNodeA);
// findAllPaths(netlist, newNodeA, nodeB, newCurrentPath, allPaths, newVisited);
// }
// }
// }
// }
// }
protected Group findGroup(Netlist netlist, Node node) {
for (Group g : netlist.getGroups())
if (g.getNodes().contains(node))
return g;
return null;
}
// protected List<Group> trace(Set<String> typeNames, String nodeName, Netlist netlist) {
// List<Group> res = new ArrayList<Group>();
// for (Group g : netlist.getGroups()) {
// for (Node n : g.getNodes()) {
// if (typeNames.contains(n.getComponent().getClass().getCanonicalName())
// && (nodeName == null || n.getDisplayName().equalsIgnoreCase(nodeName))) {
// res.add(g);
// break;
// }
// }
// }
// return res;
// }
// protected List<Node> find(Set<String> typeNames, String nodeName, Group group) {
// List<Node> res = new ArrayList<Node>();
//
// for (Node n : group.getNodes()) {
// if (typeNames.contains(n.getComponent().getClass().getCanonicalName())
// && (nodeName == null || n.getDisplayName().equalsIgnoreCase(nodeName))) {
// res.add(n);
// }
// }
//
// return res;
// }
// protected List<Group> findGroups(Set<String> typeNames, String nodeName, Netlist netlist) {
// List<Group> res = new ArrayList<Group>();
// for (Group g : netlist.getGroups()) {
// for (Node n : g.getNodes()) {
// if (typeNames.contains(n.getComponent().getClass().getCanonicalName())
// && (nodeName == null || n.getDisplayName().equalsIgnoreCase(nodeName))) {
// res.add(g);
// break;
// }
// }
// }
// return res;
// }
// protected List<Group> findGroups(Set<String> typeNames, String nodeName, Netlist netlist,
// Collection<IDIYComponent<?>> belongTo) {
// List<Group> res = new ArrayList<Group>();
// for (Group g : netlist.getGroups()) {
// for (Node n : g.getNodes()) {
// if ((belongTo == null || belongTo.contains(n.getComponent()))
// && (typeNames.contains(n.getComponent().getClass().getCanonicalName()))
// && (nodeName == null || n.getDisplayName().equalsIgnoreCase(nodeName))) {
// res.add(g);
// break;
// }
// }
// }
// return res;
// }
protected List<Node> find(Set<String> typeNames, String nodeName, Netlist netlist) {
List<Node> res = new ArrayList<Node>();
for (Group g : netlist.getGroups()) {
for (Node n : g.getNodes()) {
if (typeNames.contains(n.getComponent().getClass().getCanonicalName())
&& (nodeName == null || n.getDisplayName().equalsIgnoreCase(nodeName))) {
res.add(n);
}
}
}
return res;
}
// protected List<Node> find(Set<String> typeNames, String nodeName, Netlist netlist, List<Node> inGroupWith) {
// List<Node> res = new ArrayList<Node>();
// for (Group g : netlist.getGroups()) {
//
// boolean inGroup;
// if (inGroupWith == null) {
// inGroup = true;
// } else {
// inGroup = true;
// for (Node n1 : inGroupWith)
// if (!g.getNodes().contains(n1)) {
// inGroup = false;
// break;
// }
// }
//
// for (Node n : g.getNodes()) {
// if (inGroup && typeNames.contains(n.getComponent().getClass().getCanonicalName())
// && (nodeName == null || n.getDisplayName().equalsIgnoreCase(nodeName))) {
// res.add(n);
// }
// }
// }
// return res;
// }
// protected List<Node> find(Set<String> typeNames, String nodeName, Netlist netlist,
// Collection<IDIYComponent<?>> belongTo) {
// List<Node> res = new ArrayList<Node>();
// for (Group g : netlist.getGroups()) {
//
// for (Node n : g.getNodes()) {
// if ((belongTo == null || belongTo.contains(n.getComponent()))
// && typeNames.contains(n.getComponent().getClass().getCanonicalName())
// && (nodeName == null || n.getDisplayName().equalsIgnoreCase(nodeName))) {
// res.add(n);
// }
// }
// }
// return res;
// }
// protected boolean allMatch(Collection<Node> nodes, String name) {
// for (Node n : nodes)
// if (!n.getDisplayName().equalsIgnoreCase(name))
// return false;
//
// return true;
// }
// protected boolean allComponentsMatch(Collection<Node> nodes, Set<IDIYComponent<?>> components) {
// Set<IDIYComponent<?>> extracted = extractComponents(nodes);
// return extracted.containsAll(components);
// }
//
// protected Set<IDIYComponent<?>> extractComponents(Collection<Node> nodes) {
// Set<IDIYComponent<?>> components = new HashSet<IDIYComponent<?>>();
// for (Node n : nodes)
// components.add(n.getComponent());
// return components;
// }
protected String extractName(IDIYComponent<?> c) {
return c.getName() + " " + c.getValueForDisplay();
}
public static List<Set<IDIYComponent<?>>> extractComponentGroups(List<Netlist> netlists) {
List<Set<IDIYComponent<?>>> res = new ArrayList<Set<IDIYComponent<?>>>();
for (Netlist n : netlists) {
res.addAll(extractComponentGroups(n));
}
return res;
}
public static List<Set<IDIYComponent<?>>> extractComponentGroups(Netlist netlist) {
List<Set<IDIYComponent<?>>> res = new ArrayList<Set<IDIYComponent<?>>>();
for (Group g : netlist.getGroups()) {
Set<IDIYComponent<?>> components = new HashSet<IDIYComponent<?>>();
for (Node n : g.getNodes())
components.add(n.getComponent());
res.add(components);
}
return res;
}
public static Set<IDIYComponent<?>> extractComponents(Netlist netlist) {
Set<IDIYComponent<?>> res = new HashSet<IDIYComponent<?>>();
for (Group g : netlist.getGroups())
for (Node n : g.getNodes())
res.add(n.getComponent());
return res;
}
protected int find(Node node, List<Group> groups) {
for (int i = 0; i < groups.size(); i++)
if (groups.get(i).getNodes().contains(node))
return i;
return -1;
}
// protected List<String> extractNames(Collection<IDIYComponent<?>> components) {
// List<String> names = new ArrayList<String>();
// for (IDIYComponent<?> c : components)
// names.add(c.getName() + " " + c.getValueForDisplay());
// Collections.sort(names);
// return names;
// }
//
// protected Netlist simplify(Netlist netlist, Set<Node> nodesToMerge, Collection<Node> nodesToPurge) {
// Netlist res = new Netlist();
// res.getSwitchSetup().addAll(netlist.getSwitchSetup());
//
// Group merged = new Group();
//
// // merge
// for (Group g : netlist.getGroups()) {
// boolean needsMerging = false;
// for (Node n : nodesToMerge) {
// if (g.getNodes().contains(n)) {
// needsMerging = true;
// break;
// }
// }
// if (needsMerging) {
// for (Node n : g.getNodes()) {
// if (!nodesToMerge.contains(n))
// merged.getNodes().add(n);
// }
// } else {
// res.getGroups().add(g.clone());
// }
// }
//
// if (!merged.getNodes().isEmpty())
// res.getGroups().add(merged);
//
// // purge
// for (Group g : res.getGroups()) {
// g.getNodes().removeAll(nodesToPurge);
// }
//
// System.out.println("Before:\n" + netlist);
// System.out.println("After:\n" + res);
//
// return res;
// }
//
protected boolean intersect(List<Group> groups, Node node) {
for (Group g : groups)
if (g.getNodes().contains(node))
return true;
return false;
}
protected Node intersect(List<Group> groups, Group group) {
for (Group g : groups)
for (Node node : group.getNodes())
if (g.getNodes().contains(node))
return node;
return null;
}
}
@@ -0,0 +1,94 @@
/*
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.netlist;
import org.diylc.core.IDIYComponent;
/**
* Represents a single node in a {@link Netlist}, uniquely defined by a component and a control point.
*
* @author Branislav Stojkovic
*/
public class Node implements Comparable<Node> {
private IDIYComponent<?> component;
private int pointIndex;
public Node(IDIYComponent<?> component, int pointIndex) {
super();
this.component = component;
this.pointIndex = pointIndex;
}
public IDIYComponent<?> getComponent() {
return component;
}
public int getPointIndex() {
return pointIndex;
}
public String getDisplayName() {
String[] section = component.getSectionNames(pointIndex);
return (section == null || section.length > 1 ? "" : section[0] + ".") + component.getControlPointNodeName(pointIndex);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((component == null) ? 0 : component.hashCode());
result = prime * result + pointIndex;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Node other = (Node) obj;
if (component == null) {
if (other.component != null)
return false;
} else if (!component.equals(other.component))
return false;
if (pointIndex != other.pointIndex)
return false;
return true;
}
@Override
public String toString() {
if (component.getControlPointCount() == 1)
return component.getName();
return component.getName() + "." + getDisplayName() /*+ " @ (" + component.getControlPoint(pointIndex).getX() + ":" + component.getControlPoint(pointIndex).getY() + ")"*/;
}
@Override
public int compareTo(Node o) {
return toString().compareToIgnoreCase(o.toString());
}
}
@@ -0,0 +1,90 @@
/*
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.netlist;
import org.diylc.core.IDIYComponent;
import org.diylc.core.ISwitch;
/**
* Represents a single position of a switch, uniquely defined by the switch and the position.
*
* @author Branislav Stojkovic
*/
public class Position implements Comparable<Position> {
private ISwitch theSwitch;
private int position;
public Position(ISwitch theSwitch, int position) {
super();
this.theSwitch = theSwitch;
this.position = position;
}
public ISwitch getSwitch() {
return theSwitch;
}
public int getPosition() {
return position;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + position;
result = prime * result + ((theSwitch == null) ? 0 : theSwitch.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;
Position other = (Position) obj;
if (position != other.position)
return false;
if (theSwitch == null) {
if (other.theSwitch != null)
return false;
} else if (!theSwitch.equals(other.theSwitch))
return false;
return true;
}
@Override
public String toString() {
return (theSwitch instanceof IDIYComponent<?> ? ((IDIYComponent<?>) theSwitch).getName() + "." : "") + theSwitch.getPositionName(position);
}
@Override
public int compareTo(Position o) {
if (theSwitch instanceof IDIYComponent<?> && o.theSwitch instanceof IDIYComponent<?>)
return ((IDIYComponent<?>) theSwitch).getName().compareToIgnoreCase(((IDIYComponent<?>) o.theSwitch).getName());
return 0;
}
}
@@ -0,0 +1,87 @@
/*
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.netlist;
public class Summary implements Comparable<Summary> {
private Netlist netlist;
private String summary;
public Summary(Netlist netlist, String summary) {
super();
this.netlist = netlist;
this.summary = summary;
}
public Netlist getNetlist() {
return netlist;
}
public void append(Netlist netlist) {
this.netlist.getSwitchSetup().addAll(netlist.getSwitchSetup());
}
public String getSummary() {
return summary;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((netlist == null) ? 0 : netlist.hashCode());
result = prime * result + ((summary == null) ? 0 : summary.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;
Summary other = (Summary) obj;
if (netlist == null) {
if (other.netlist != null)
return false;
} else if (!netlist.equals(other.netlist))
return false;
if (summary == null) {
if (other.summary != null)
return false;
} else if (!summary.equals(other.summary))
return false;
return true;
}
@Override
public String toString() {
return summary.toString();
}
@Override
public int compareTo(Summary o) {
return netlist.compareTo(o.netlist);
}
}
@@ -0,0 +1,87 @@
/*
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.netlist;
import java.util.Collections;
import java.util.List;
/**
* Represents a full switch configuration of the whole {@link Netlist}, containing one position of each switch in the {@link Netlist}.
*
* @author Branislav Stojkovic
*/
public class SwitchSetup implements Comparable<SwitchSetup> {
private List<Position> positions;
public SwitchSetup(List<Position> positions) {
super();
this.positions = positions;
Collections.sort(this.positions);
}
public List<Position> getPositions() {
return positions;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((positions == null) ? 0 : positions.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;
SwitchSetup other = (SwitchSetup) obj;
if (positions == null) {
if (other.positions != null)
return false;
} else if (!positions.equals(other.positions))
return false;
return true;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (Position s : positions)
{
if (sb.length() > 0)
sb.append(":");
sb.append(s.toString());
}
return sb.toString();
}
@Override
public int compareTo(SwitchSetup o) {
return toString().compareToIgnoreCase(o.toString());
}
}
@@ -0,0 +1,309 @@
/*
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.netlist;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.diylc.core.IDIYComponent;
public class Tree {
private List<Tree> children;
private TreeConnectionType connectionType;
private TreeLeaf leaf;
public Tree(TreeConnectionType connectionType) {
this.children = new ArrayList<Tree>();
this.connectionType = connectionType;
}
public Tree(TreeLeaf leaf) {
this.leaf = leaf;
}
public Tree(List<Tree> children, TreeConnectionType connectionType) {
this.children = children;
this.connectionType = connectionType;
}
public List<Tree> getChildren() {
return children;
}
public void trimChildrenLeft(int count) {
children = children.subList(count, children.size());
}
public void trimChildrenRight(int count) {
children = children.subList(0, children.size() - count);
}
public TreeConnectionType getConnectionType() {
return connectionType;
}
public TreeLeaf getLeaf() {
return leaf;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((children == null) ? 0 : children.hashCode());
result = prime * result + ((connectionType == null) ? 0 : connectionType.hashCode());
result = prime * result + ((leaf == null) ? 0 : leaf.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;
Tree other = (Tree) obj;
if (children == null) {
if (other.children != null)
return false;
} else if (!children.equals(other.children))
return false;
if (connectionType != other.connectionType)
return false;
if (leaf == null) {
if (other.leaf != null)
return false;
} else if (!leaf.equals(other.leaf))
return false;
return true;
}
private List<Tree> getOrderedChildren() {
if (getConnectionType() == TreeConnectionType.Series)
return children;
List<Tree> ordered = new ArrayList<Tree>(children);
Collections.sort(ordered, new Comparator<Tree>() {
@Override
public int compare(Tree o1, Tree o2) {
return o1.toString().compareToIgnoreCase(o2.toString());
}});
return ordered;
}
@Override
public String toString() {
if (leaf != null)
return leaf.toString();
StringBuilder sb = new StringBuilder("(");
boolean first = true;
for(Tree child : getOrderedChildren()) {
if (!first)
sb.append(" " ).append(connectionType).append(" ");
first = false;
sb.append(child);
}
sb.append(")");
return sb.toString();
}
public String toHTML(int depth) {
if (leaf != null)
return leaf.toHTML();
List<Tree> children = getOrderedChildren();
StringBuilder sb = new StringBuilder();
if (depth > 0 && children.size() > 1)
sb.append("(");
boolean first = true;
for(Tree child : children) {
if (!first) {
sb.append("&nbsp;").append(connectionType.toHTML()).append("&nbsp;");
if (depth == 0)
sb.append("<br>");
}
first = false;
sb.append(child.toHTML(depth + children.size() > 1 ? 1 : 0));
}
if (depth > 0 && children.size() > 1)
sb.append(")");
return sb.toString();
}
@Override
protected Object clone() throws CloneNotSupportedException {
if (leaf != null)
return new Tree(leaf);
List<Tree> newChildren = new ArrayList<Tree>();
for (Tree t : children)
newChildren.add((Tree) t.clone());
return new Tree(newChildren, connectionType);
}
public Tree filter(Set<String> types) {
if (leaf != null) {
if (types.contains(leaf.getComponent().getClass().getCanonicalName()))
return new Tree(leaf);
return null;
}
List<Tree> newChildren = new ArrayList<Tree>();
for (Tree t : children) {
Tree child = t.filter(types);
if (child != null)
newChildren.add(child);
}
if (newChildren.isEmpty())
return null;
return new Tree(newChildren, connectionType);
}
public void walk(ITreeWalker walker) {
if (leaf != null) {
walker.visit(leaf);
} else {
for (Tree t : children) {
walker.visit(t);
t.walk(walker);
}
}
}
public Set<IDIYComponent<?>> extractComponents(Set<String> types) {
Set<IDIYComponent<?>> res = new HashSet<IDIYComponent<?>>();
if (leaf != null && types.contains(leaf.getComponent().getClass().getCanonicalName())) {
res.add(leaf.getComponent());
} else if (children != null) {
for (Tree t : children) {
Set<IDIYComponent<?>> childRes = t.extractComponents(types);
if (childRes != null)
res.addAll(childRes);
}
}
return res;
}
public Tree locate(TreeLeaf l, boolean forceDirection) {
if (leaf != null && leaf.equals(l, forceDirection))
return this;
if (children != null) {
for (Tree t : children) {
Tree childL = t.locate(l, forceDirection);
if (childL != null) {
// if (t.getLeaf() != null)
// return this;
return childL;
}
}
}
return null;
}
public Tree findCommonParent(Tree t1, Tree t2) {
if (t1 == null)
return t2;
if (t2 == null)
return t1;
if (children == null)
return null;
if (!this.contains(t1) || !this.contains(t2))
return null;
Tree p1 = this;
Tree p2 = this;
for (Tree c : children) {
if (c.contains(t1))
p1 = c;
if (c.contains(t2))
p2 = c;
}
if (p1 != p2 || p1 == this || p2 == this)
return this;
return p1.findCommonParent(t1, t2);
}
public Tree findCommonParent(List<Tree> t) {
if (t.contains(null))
{
while(t.contains(null))
t.remove(null);
return findCommonParent(t);
}
if (t.size() == 0)
return null;
if (t.size() == 1)
return t.get(0);
if (t.size() == 2)
return findCommonParent(t.get(0), t.get(1));
List<Tree> remainder = t.subList(1, t.size());
return findCommonParent(t.get(0), findCommonParent(remainder));
}
public Tree findParent(Tree t) {
if (children == null)
return null;
if (children.contains(t))
return this;
for (Tree c : children)
{
Tree p = c.findParent(t);
if (p != null)
return p;
}
return null;
}
public boolean contains(Tree t) {
if (this == t)
return true;
if (children == null)
return false;
if (children.contains(t))
return true;
for (Tree c : children)
if (c.contains(t))
return true;
return false;
}
public interface ITreeWalker {
void visit(Tree t);
void visit(TreeLeaf l);
}
}
@@ -0,0 +1,44 @@
/*
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.netlist;
public enum TreeConnectionType {
Series("+", "red"), Parallel("||", "blue");
private String label;
private String color;
private TreeConnectionType(String label, String color) {
this.label = label;
this.color = color;
}
@Override
public String toString() {
return label;
}
public String toHTML() {
return "<b><font color='" + color + "'>" + label + "</font></b>";
}
}
@@ -0,0 +1,26 @@
package org.diylc.netlist;
public class TreeException extends Exception {
private static final long serialVersionUID = 1L;
public TreeException() {
// TODO Auto-generated constructor stub
}
public TreeException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public TreeException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
public TreeException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
}
@@ -0,0 +1,113 @@
/*
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.netlist;
import java.util.List;
import org.diylc.core.IDIYComponent;
public class TreeLeaf implements ITree {
private IDIYComponent<?> component;
private int pointIndex1;
private int pointIndex2;
public TreeLeaf(IDIYComponent<?> component, int pointIndex1, int pointIndex2) {
this.component = component;
this.pointIndex1 = pointIndex1;
this.pointIndex2 = pointIndex2;
}
public IDIYComponent<?> getComponent() {
return component;
}
public int getPointIndex1() {
return pointIndex1;
}
public int getPointIndex2() {
return pointIndex2;
}
@Override
public List<ITree> getChildren() {
return null;
}
@Override
public TreeConnectionType getConnectionType() {
return null;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((component == null) ? 0 : component.hashCode());
result = prime * result + pointIndex1;
result = prime * result + pointIndex2;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TreeLeaf other = (TreeLeaf) obj;
if (component == null) {
if (other.component != null)
return false;
} else if (!component.equals(other.component))
return false;
if (pointIndex1 != other.pointIndex1)
return false;
if (pointIndex2 != other.pointIndex2)
return false;
return true;
}
public boolean equals(TreeLeaf other, boolean forceDirection) {
if (component == null) {
if (other.component != null)
return false;
} else if (!component.equals(other.component))
return false;
return (pointIndex1 == other.pointIndex1 && pointIndex2 == other.pointIndex2) || (!forceDirection && (pointIndex1 == other.pointIndex2 && pointIndex2 == other.pointIndex1));
}
@Override
public String toString() {
String linkName = component.getInternalLinkName(pointIndex1, pointIndex2);
if (component.getName().equals(linkName))
return linkName;
return component.getName() + "." + linkName;
}
public String toHTML() {
return toString().replace("<", "&lt;").replace(">", "&gt");
}
}
@@ -0,0 +1,56 @@
/*
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.presenter;
import java.awt.Color;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
/**
* Serializes {@link Color} objects as hex values instead of r/g/b. Backwards compatible when unmarshalling.
*
* @author Branislav Stojkovic
*/
public class ColorConverter extends com.thoughtworks.xstream.converters.extended.ColorConverter {
@Override
public void marshal(Object object, HierarchicalStreamWriter writer, MarshallingContext context) {
Color c = (Color) object;
writer.addAttribute("hex", String.format("%02x%02x%02x", c.getRed(), c.getGreen(), c.getBlue()));
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
if (reader.getAttribute("hex") != null)
return Color.decode("#" + reader.getAttribute("hex"));
return super.unmarshal(reader, context);
}
@SuppressWarnings("rawtypes")
@Override
public boolean canConvert(Class clazz) {
return Color.class.isAssignableFrom(clazz);
}
}
@@ -92,13 +92,11 @@ public class ComponentProcessor {
Icon icon;
double zOrder;
boolean flexibleZOrder;
boolean stretchable;
BomPolicy bomPolicy;
boolean autoEdit;
IComponentTransformer transformer;
KeywordPolicy keywordPolicy;
String keywordTag;
boolean continuity;
String keywordTag;
if (clazz.isAnnotationPresent(ComponentDescriptor.class)) {
ComponentDescriptor annotation = clazz.getAnnotation(ComponentDescriptor.class);
name = annotation.name();
@@ -109,13 +107,11 @@ public class ComponentProcessor {
author = annotation.author();
zOrder = annotation.zOrder();
flexibleZOrder = annotation.flexibleZOrder();
stretchable = annotation.stretchable();
bomPolicy = annotation.bomPolicy();
autoEdit = annotation.autoEdit();
transformer = getComponentTransformer(annotation.transformer());
keywordPolicy = annotation.keywordPolicy();
keywordTag = annotation.keywordTag();
continuity = annotation.continuity();
keywordTag = annotation.keywordTag();
} else { // default
return null;
}
@@ -137,7 +133,7 @@ public class ComponentProcessor {
}
ComponentType componentType =
new ComponentType(name, description, creationMethod, category, namePrefix, author, icon, clazz, zOrder,
flexibleZOrder, stretchable, bomPolicy, autoEdit, transformer, keywordPolicy, keywordTag, continuity);
flexibleZOrder, bomPolicy, autoEdit, transformer, keywordPolicy, keywordTag);
componentTypeMap.put(clazz.getName(), componentType);
return componentType;
}
@@ -0,0 +1,53 @@
package org.diylc.presenter;
import java.awt.geom.Point2D;
public class Connection {
private Point2D p1;
private Point2D p2;
public Connection(Point2D p1, Point2D p2) {
this.p1 = p1.getX() < p2.getX() || p1.getX() == p2.getX() && p1.getY() < p2.getY() ? p1 : p2;
this.p2 = p1.getX() < p2.getX() || p1.getX() == p2.getX() && p1.getY() < p2.getY() ? p2 : p1;
}
public Point2D getP1() {
return p1;
}
public Point2D getP2() {
return p2;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((p1 == null) ? 0 : p1.hashCode());
result = prime * result + ((p2 == null) ? 0 : p2.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;
Connection other = (Connection) obj;
if (p1 == null) {
if (other.p1 != null)
return false;
} else if (!p1.equals(other.p1))
return false;
if (p2 == null) {
if (other.p2 != null)
return false;
} else if (!p2.equals(other.p2))
return false;
return true;
}
}
@@ -35,6 +35,7 @@ import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -42,7 +43,6 @@ import java.util.Set;
import org.apache.log4j.Logger;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.appframework.simplemq.MessageDispatcher;
import org.diylc.common.ComponentType;
import org.diylc.common.DrawOption;
import org.diylc.common.EventType;
import org.diylc.common.GridType;
@@ -50,6 +50,7 @@ import org.diylc.common.IComponentFiler;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.core.ComponentState;
import org.diylc.core.IContinuity;
import org.diylc.core.IDIYComponent;
import org.diylc.core.Project;
import org.diylc.core.Theme;
@@ -264,6 +265,10 @@ public class DrawingManager {
// Draw the component through the g2dWrapper.
try {
component.draw(g2dWrapper, state, drawOptions.contains(DrawOption.OUTLINE_MODE), project, g2dWrapper);
if (g2dWrapper.isTrackingContinuityArea()) {
LOG.info("Component " + component.getName() + " of type " + component.getClass().getName() + " did not stop tracking continuity area.");
g2dWrapper.stopTrackingContinuityArea();
}
} catch (Exception e) {
LOG.error("Error drawing " + component.getName(), e);
failedComponents.add(component);
@@ -486,20 +491,33 @@ public class DrawingManager {
ConfigurationManager.getInstance().writeValue(IPlugInPort.THEME_KEY, theme);
messageDispatcher.dispatchMessage(EventType.REPAINT);
}
@SuppressWarnings("unchecked")
public void findContinuityAreaAtPoint(Project project, Point p) {
List<Area> areas = getContinuityAreas(project);
for (Area a : areas) {
if (a.contains(p)) {
continuityArea = a;
return;
}
}
continuityArea = null;
}
public List<Area> getContinuityAreas(Project project) {
// Find all individual continuity areas for all components
List<Area> preliminaryAreas = new ArrayList<Area>();
List<Boolean> checkBreakout = new ArrayList<Boolean>();
List<Connection> connections = new ArrayList<Connection>();
Set<Connection> connections = new HashSet<Connection>();
for (IDIYComponent<?> c : project.getComponents()) {
ComponentArea a = getComponentArea(c);
ComponentType type =
ComponentProcessor.getInstance().extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) c.getClass());
if (type.isContinuity()) {
connections.add(new Connection(c.getControlPoint(0), c.getControlPoint(c.getControlPointCount() - 1)));
if (c instanceof IContinuity) {
for (int i = 0; i < c.getControlPointCount() - 1; i++)
for (int j = i + 1; j < c.getControlPointCount(); j++)
if (((IContinuity)c).arePointsConnected(i, j))
connections.add(new Connection(c.getControlPoint(i), c.getControlPoint(j)));
}
if (a == null || a.getOutlineArea() == null)
@@ -530,20 +548,41 @@ public class DrawingManager {
// else
// areas.add(a);
}
expandConnections(connections);
crunchAreas(areas, connections);
for (Area a : areas) {
if (a.contains(p)) {
continuityArea = a;
return;
return areas;
}
public void expandConnections(Set<Connection> connections) {
Set<Connection> toAdd = new HashSet<Connection>();
for (Connection c1 : connections)
for (Connection c2 : connections) {
if (c1 == c2)
continue;
if (c1.getP1().distance(c2.getP1()) < CONTROL_POINT_SIZE)
toAdd.add(new Connection(c1.getP2(), c2.getP2()));
if (c1.getP1().distance(c2.getP2()) < CONTROL_POINT_SIZE)
toAdd.add(new Connection(c1.getP2(), c2.getP1()));
if (c1.getP2().distance(c2.getP1()) < CONTROL_POINT_SIZE)
toAdd.add(new Connection(c1.getP1(), c2.getP2()));
if (c1.getP2().distance(c2.getP2()) < CONTROL_POINT_SIZE)
toAdd.add(new Connection(c1.getP1(), c2.getP1()));
}
}
continuityArea = null;
if (connections.addAll(toAdd))
expandConnections(connections);
}
private boolean crunchAreas(List<Area> areas, List<Connection> connections) {
/**
* Merges all areas that either overlap or are joined by connections.
*
* @param areas
* @param connections
* @return
*/
private boolean crunchAreas(List<Area> areas, Set<Connection> connections) {
boolean isChanged = false;
List<Area> newAreas = new ArrayList<Area>();
@@ -557,15 +596,19 @@ public class DrawingManager {
continue;
Area a1 = areas.get(i);
Area a2 = areas.get(j);
Area intersection = new Area(a1);
intersection.intersect(a2);
Area intersection = null;
if (a1.getBounds2D().intersects(a2.getBounds())) {
intersection = new Area(a1);
intersection.intersect(a2);
}
// if the two areas intersect, make a union and consume the second area
if (!intersection.isEmpty()) {
if (intersection != null && !intersection.isEmpty()) {
a1.add(a2);
consumed.set(j, true);
} else { // maybe there's a connection between them
for (Connection p : connections) {
if ((a1.contains(p.pointA) && a2.contains(p.pointB)) || (a1.contains(p.pointB) && a2.contains(p.pointA))) {
for (Connection p : connections) { // use getBounds to optimize the computation, don't get into complex math if not needed
if ((a1.getBounds().contains(p.getP1()) && a2.getBounds().contains(p.getP2()) && a1.contains(p.getP1()) && a2.contains(p.getP2())) ||
(a1.getBounds().contains(p.getP2()) && a2.getBounds().contains(p.getP1())) && a1.contains(p.getP2()) && a2.contains(p.getP1())) {
a1.add(a2);
consumed.set(j, true);
break;
@@ -624,24 +667,4 @@ public class DrawingManager {
return toReturn;
}
class Connection {
private Point pointA;
private Point pointB;
public Connection(Point pointA, Point pointB) {
super();
this.pointA = pointA;
this.pointB = pointB;
}
public Point getPointA() {
return pointA;
}
public Point getPointB() {
return pointB;
}
}
}
@@ -0,0 +1,59 @@
/*
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.presenter;
import java.awt.Font;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
/**
* Serializes {@link Font} objects in a more compact fashion. Backwards compatible when unmarshalling.
*
* @author Branislav Stojkovic
*/
public class FontConverter extends com.thoughtworks.xstream.converters.extended.FontConverter {
@Override
public void marshal(Object object, HierarchicalStreamWriter writer, MarshallingContext context) {
Font f = (Font) object;
writer.addAttribute("name", f.getFontName());
writer.addAttribute("size", Integer.toString(f.getSize()));
writer.addAttribute("style", Integer.toString(f.getStyle()));
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
if (reader.getAttribute("name") != null) {
return new Font(reader.getAttribute("name"), Integer.parseInt(reader.getAttribute("style")), Integer.parseInt(reader.getAttribute("size")));
}
return super.unmarshal(reader, context);
}
@SuppressWarnings("rawtypes")
@Override
public boolean canConvert(Class clazz) {
return Font.class.isAssignableFrom(clazz);
}
}
@@ -162,6 +162,10 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver {
this.trackingContinuityAllowed = false;
}
@Override
public boolean isTrackingContinuityArea() {
return trackingContinuityAllowed;
}
/**
* Appends shape interior to the current component area.
@@ -27,8 +27,10 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import org.diylc.appframework.miscutils.ConfigurationManager;
@@ -62,11 +64,11 @@ public class InstantiationManager {
private Point potentialControlPoint;
public static final ComponentType clipboardType = new ComponentType("Clipboard contents",
"Components from the clipboard", CreationMethod.SINGLE_CLICK, "Multi", "", "", null, null, 0, false, false, null,
false, null, KeywordPolicy.NEVER_SHOW, null, false);
"Components from the clipboard", CreationMethod.SINGLE_CLICK, "Multi", "", "", null, null, 0, false, null,
false, null, KeywordPolicy.NEVER_SHOW, null);
public static final ComponentType blockType = new ComponentType("Building block",
"Components from the building block", CreationMethod.SINGLE_CLICK, "Multi", "", "", null, null, 0, false, false, null,
false, null, KeywordPolicy.NEVER_SHOW, null, false);
"Components from the building block", CreationMethod.SINGLE_CLICK, "Multi", "", "", null, null, 0, false, null,
false, null, KeywordPolicy.NEVER_SHOW, null);
public InstantiationManager() {}
@@ -139,16 +141,34 @@ public class InstantiationManager {
return changeMade;
}
@SuppressWarnings("unchecked")
public void pasteComponents(Collection<IDIYComponent<?>> components, Point scaledPoint, boolean snapToGrid,
Size gridSpacing, boolean autoGroup) {
Size gridSpacing, boolean autoGroup, Project currentProject) {
// Adjust location of components so they are centered under the mouse
// cursor
int minX = Integer.MAX_VALUE;
int maxX = Integer.MIN_VALUE;
int minY = Integer.MAX_VALUE;
int maxY = Integer.MIN_VALUE;
for (IDIYComponent<?> component : components) {
for (int i = 0; i < component.getControlPointCount(); i++) {
int maxY = Integer.MIN_VALUE;
Set<String> existingNames = new HashSet<String>();
for (IDIYComponent<?> c : currentProject.getComponents())
existingNames.add(c.getName());
List<IDIYComponent<?>> allComponents = new ArrayList<IDIYComponent<?>>(currentProject.getComponents());
for (IDIYComponent<?> component : components) {
// assign a new name if it already exists in the project
if (existingNames.contains(component.getName())) {
ComponentType componentType =
ComponentProcessor.getInstance().extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) component.getClass());
String newName = createUniqueName(componentType, allComponents);
existingNames.add(newName);
component.setName(newName);
allComponents.add(component);
}
for (int i = 0; i < component.getControlPointCount(); i++) {
Point p = component.getControlPoint(i);
if (p.x > maxX) {
maxX = p.x;
@@ -236,7 +256,7 @@ public class InstantiationManager {
@SuppressWarnings("unchecked")
public List<IDIYComponent<?>> instantiateComponent(ComponentType componentType, Template template, Point point,
Project currentProject) throws Exception {
Project currentProject) throws InstantiationException, IllegalAccessException {
LOG.info("Instatiating component of type: " + componentType.getInstanceClass().getName());
// Instantiate the component.
@@ -321,8 +341,7 @@ public class InstantiationManager {
* @throws NoSuchMethodException
* @throws SecurityException
*/
public void fillWithDefaultProperties(Object object, Template template) throws IllegalArgumentException,
IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException {
public void fillWithDefaultProperties(Object object, Template template) {
// Extract properties.
List<PropertyWrapper> properties = ComponentProcessor.getInstance().extractProperties(object.getClass());
Map<String, PropertyWrapper> propertyCache = new HashMap<String, PropertyWrapper>();
@@ -333,8 +352,12 @@ public class InstantiationManager {
ConfigurationManager.getInstance().readObject(
Presenter.DEFAULTS_KEY_PREFIX + object.getClass().getName() + ":" + property.getName(), null);
if (defaultValue != null) {
property.setValue(defaultValue);
property.writeTo(object);
property.setValue(defaultValue);
try {
property.writeTo(object);
} catch (Exception e) {
LOG.error("Could not write property " + property.getName(), e);
}
}
}
if (template != null) {
@@ -344,8 +367,12 @@ public class InstantiationManager {
LOG.warn("Cannot find property " + pair.getKey());
} else {
LOG.debug("Filling value from template for " + pair.getKey());
property.setValue(pair.getValue());
property.writeTo(object);
property.setValue(pair.getValue());
try {
property.writeTo(object);
} catch (Exception e) {
LOG.error("Could not write property " + property.getName(), e);
}
}
}
}
@@ -0,0 +1,95 @@
/*
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.presenter;
import org.diylc.core.measures.AbstractMeasure;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
/**
* Serializes objects of types derived from {@link AbstractMeasure} objects in a compact format. Backwards compatible when unmarshalling.
*
* @author Branislav Stojkovic
*/
public class MeasureConverter implements Converter {
@SuppressWarnings("rawtypes")
@Override
public void marshal(Object object, HierarchicalStreamWriter writer, MarshallingContext context) {
AbstractMeasure m = (AbstractMeasure) object;
if (m.getValue() != null)
writer.addAttribute("value", Double.toString(m.getValue()));
if (m.getUnit() != null)
writer.addAttribute("unit", m.getUnit().name());
}
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
Double value = null;
String unitStr = null;
if (reader.getAttribute("value") != null) {
value = Double.parseDouble(reader.getAttribute("value"));
unitStr = reader.getAttribute("unit");
} else {
if (reader.hasMoreChildren()) {
reader.moveDown();
if (reader.getNodeName().equals("value"))
value = Double.parseDouble(reader.getValue());
else if (reader.getNodeName().equals("unit"))
unitStr = reader.getValue();
reader.moveUp();
}
if (reader.hasMoreChildren()) {
reader.moveDown();
if (reader.getNodeName().equals("value"))
value = Double.parseDouble(reader.getValue());
else if (reader.getNodeName().equals("unit"))
unitStr = reader.getValue();
reader.moveUp();
}
}
try {
Class requiredType = context.getRequiredType();
ParameterizedTypeImpl generic = (ParameterizedTypeImpl)requiredType.getGenericSuperclass();
Class unitType = (Class)generic.getActualTypeArguments()[0];
Object unit = unitStr == null ? null : Enum.valueOf(unitType, unitStr);
return requiredType.getConstructor(Double.class, unitType).newInstance(value, unit);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@SuppressWarnings("rawtypes")
@Override
public boolean canConvert(Class clazz) {
return AbstractMeasure.class.isAssignableFrom(clazz);
}
}
File diff suppressed because it is too large Load Diff
@@ -21,36 +21,42 @@
*/
package org.diylc.presenter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.log4j.Logger;
import org.diylc.appframework.miscutils.Utils;
import org.diylc.appframework.simplemq.MessageDispatcher;
import org.diylc.common.EventType;
import org.diylc.core.Project;
import org.diylc.parsing.IOldFileParser;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import java.awt.Color;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.log4j.Logger;
import org.diylc.appframework.miscutils.Utils;
import org.diylc.appframework.simplemq.MessageDispatcher;
import org.diylc.appframework.update.VersionNumber;
import org.diylc.common.EventType;
import org.diylc.core.Project;
import org.diylc.parsing.IOldFileParser;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.mapper.MapperWrapper;
public class ProjectFileManager {
@@ -66,13 +72,47 @@ public class ProjectFileManager {
private MessageDispatcher<EventType> messageDispatcher;
private List<IOldFileParser> parsers;
private List<IOldFileParser> parsers;
private Set<String> missingFields = new HashSet<String>();
public ProjectFileManager(MessageDispatcher<EventType> messageDispatcher) {
super();
this.xStream = new XStream(new DomDriver("UTF-8"));
xStream.autodetectAnnotations(true);
xStream.registerConverter(new PointConverter());
this.xStream = new XStream(new DomDriver("UTF-8")) {
@Override
protected MapperWrapper wrapMapper(MapperWrapper next) {
return new MapperWrapper(next) {
@SuppressWarnings("rawtypes")
@Override
public boolean shouldSerializeMember(Class definedIn, String fieldName) {
if (definedIn == Object.class) {
missingFields.add(definedIn.getName() + "." + fieldName);
return false;
}
return super.shouldSerializeMember(definedIn, fieldName);
}
};
}
};
xStream.autodetectAnnotations(true);
xStream.alias("point", java.awt.Point.class);
xStream.alias("font", java.awt.Font.class);
xStream.alias("project", Project.class);
xStream.aliasPackage("diylc", "org.diylc.components");
xStream.registerConverter(new PointConverter());
xStream.registerConverter(new ColorConverter());
xStream.registerConverter(new FontConverter());
xStream.registerConverter(new MeasureConverter());
xStream.addImmutableType(Color.class);
xStream.addImmutableType(java.awt.Point.class);
xStream.addImmutableType(org.diylc.core.measures.Voltage.class);
xStream.addImmutableType(org.diylc.core.measures.Resistance.class);
xStream.addImmutableType(org.diylc.core.measures.Capacitance.class);
xStream.addImmutableType(org.diylc.core.measures.Current.class);
xStream.addImmutableType(org.diylc.core.measures.Power.class);
xStream.addImmutableType(org.diylc.core.measures.Inductance.class);
xStream.addImmutableType(org.diylc.core.measures.Size.class);
this.xStreamOld = new XStream(new DomDriver());
xStreamOld.autodetectAnnotations(true);
this.messageDispatcher = messageDispatcher;
@@ -130,8 +170,8 @@ public class ProjectFileManager {
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(new InputStreamReader(new FileInputStream(file))));
doc.getDocumentElement().normalize();
if (doc.getDocumentElement().getNodeName().equalsIgnoreCase(Project.class.getName())) {
project = parseV3File(fileName);
if (doc.getDocumentElement().getNodeName().equals(Project.class.getName()) || doc.getDocumentElement().getNodeName().equals("project")) {
project = parseV3File(fileName, warnings);
} else {
if (!doc.getDocumentElement().getNodeName().equalsIgnoreCase("layout")) {
throw new IllegalArgumentException("Could not open DIY file. Root node is not named 'Layout'.");
@@ -171,19 +211,58 @@ public class ProjectFileManager {
messageDispatcher.dispatchMessage(EventType.FILE_STATUS_CHANGED, getCurrentFileName(), isModified());
}
private Project parseV3File(String fileName) throws IOException {
Project project;
FileInputStream fis = new FileInputStream(fileName);
private Project parseV3File(String fileName, List<String> warnings) throws IOException {
Project project;
VersionNumber fileVersion;
try {
fileVersion = readV3Version(fileName);
if (fileVersion.compareTo(Presenter.CURRENT_VERSION) > 0)
warnings.add("The file is created with a newer version of DIYLC and may contain features that are not supported by your version of DIYLC. Please update.");
} catch (Exception e) {
warnings.add("Could not read file version number, the file may be corrupted.");
}
FileInputStream fis = new FileInputStream(fileName);
missingFields.clear();
try {
Reader reader = new InputStreamReader(fis, "UTF-8");
project = (Project) xStream.fromXML(reader);
} catch (Exception e) {
LOG.warn("Could not open with the new xStream, trying the old one");
LOG.warn("Could not open with the new xStream, trying the old one", e);
fis.close();
fis = new FileInputStream(fileName);
project = (Project) xStreamOld.fromXML(fis);
}
if (!missingFields.isEmpty()) {
warnings.add("The project references unknown component properties, most likely because it was created with a newer version of DIYLC.");
}
fis.close();
return project;
}
private VersionNumber readV3Version(String fileName) throws Exception {
File fXmlFile = new File(fileName);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("fileVersion");
int items = nList.getLength();
if (items != 1)
throw new Exception("File version information could not be read from the XML.");
Node versionNode = nList.item(0);
Node n = versionNode.getFirstChild().getNextSibling();
int major = Integer.parseInt(n.getFirstChild().getNodeValue());
n = n.getNextSibling().getNextSibling();
int minor = Integer.parseInt(n.getFirstChild().getNodeValue());
n = n.getNextSibling().getNextSibling();
int build = Integer.parseInt(n.getFirstChild().getNodeValue());
return new VersionNumber(major, minor, build);
}
}
@@ -23,10 +23,12 @@ package org.diylc.plugins.file;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.diylc.core.IDIYComponent;
import org.diylc.core.measures.Capacitance;
import org.diylc.core.measures.CapacitanceUnit;
@@ -47,12 +49,18 @@ public class BomMakerTest {
components.add(new MockDIYComponent());
List<BomEntry> bom = BomMaker.getInstance().createBom(components);
assertNotNull(bom);
assertEquals(2, bom.size());
assertEquals(2, bom.size());
Collections.sort(bom, new Comparator<BomEntry>() {
@Override
public int compare(BomEntry o1, BomEntry o2) {
return o1.getQuantity().compareTo(o2.getQuantity());
}});
BomEntry entry1 = bom.get(0);
assertEquals("something", entry1.getName());
assertEquals(2, (int) entry1.getQuantity());
assertEquals(1, (int) entry1.getQuantity());
BomEntry entry2 = bom.get(1);
assertEquals("something", entry2.getName());
assertEquals(1, (int) entry2.getQuantity());
assertEquals("something, something", entry2.getName());
assertEquals(2, (int) entry2.getQuantity());
}
}
@@ -163,5 +163,10 @@ public class MockDIYComponent extends AbstractComponent<Capacitance> {
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.drawString("X", 10, 10);
}
@Override
public String getControlPointNodeName(int index) {
return null;
}
}
+3
View File
@@ -1,11 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="test"/>
<classpathentry kind="lib" path="lib/log4j-1.2.15.jar"/>
<classpathentry kind="lib" path="lib/app-framework.jar"/>
<classpathentry kind="lib" path="lib/jep-2.4.1.jar"/>
<classpathentry kind="lib" path="lib/poi-3.5-FINAL-20090928.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/diylc-core"/>
<classpathentry kind="lib" path="lib/xstream-1.4.3.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk1.6.0_45"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="output" path="bin"/>
</classpath>
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,245 @@
/*
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.awt;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.VerticalAlignment;
/**
* Globally available utility classes, mostly for string manipulation.
*
* @author Jim Menard, <a href="mailto:jimm@io.com">jimm@io.com</a>
*/
public class StringUtils {
public static void drawWrappedText(String text, Graphics2D g2d, int x, int y, int maxWidth, HorizontalAlignment horizontalAlignment) {
FontMetrics textMetrics = g2d.getFontMetrics();
List<String> lines = wrap(text, textMetrics, maxWidth);
int lineHeight = textMetrics.getHeight();
if (horizontalAlignment == HorizontalAlignment.CENTER)
x += maxWidth / 2;
else if (horizontalAlignment == HorizontalAlignment.RIGHT)
x += maxWidth;
for (String line : lines) {
drawCenteredText(g2d, line, x, y, horizontalAlignment, VerticalAlignment.BOTTOM);
y += lineHeight;
}
}
/**
* Returns an array of strings, one for each line in the string after it has been wrapped to fit
* lines of <var>maxWidth</var>. Lines end with any of cr, lf, or cr lf. A line ending at the end
* of the string will not output a further, empty string.
* <p>
* This code assumes <var>str</var> is not <code>null</code>.
*
* @param str the string to split
* @param fm needed for string width calculations
* @param maxWidth the max line width, in points
* @return a non-empty list of strings
*/
public static List<String> wrap(String str, FontMetrics fm, int maxWidth) {
List<String> lines = splitIntoLines(str);
if (lines.size() == 0)
return lines;
ArrayList<String> strings = new ArrayList<String>();
for (Iterator<String> iter = lines.iterator(); iter.hasNext();)
wrapLineInto((String) iter.next(), strings, fm, maxWidth);
return strings;
}
/**
* Given a line of text and font metrics information, wrap the line and add the new line(s) to
* <var>list</var>.
*
* @param line a line of text
* @param list an output list of strings
* @param fm font metrics
* @param maxWidth maximum width of the line(s)
*/
public static void wrapLineInto(String line, List<String> list, FontMetrics fm, int maxWidth) {
int len = line.length();
int width;
while (len > 0 && (width = fm.stringWidth(line)) > maxWidth) {
// Guess where to split the line. Look for the next space before
// or after the guess.
int guess = len * maxWidth / width;
String before = line.substring(0, guess).trim();
width = fm.stringWidth(before);
int pos;
if (width > maxWidth) // Too long
pos = findBreakBefore(line, guess);
else { // Too short or possibly just right
pos = findBreakAfter(line, guess);
if (pos != -1) { // Make sure this doesn't make us too long
before = line.substring(0, pos).trim();
if (fm.stringWidth(before) > maxWidth)
pos = findBreakBefore(line, guess);
}
}
if (pos == -1)
pos = guess; // Split in the middle of the word
list.add(line.substring(0, pos).trim());
line = line.substring(pos).trim();
len = line.length();
}
if (len > 0)
list.add(line);
}
/**
* Returns the index of the first whitespace character or '-' in <var>line</var> that is at or
* before <var>start</var>. Returns -1 if no such character is found.
*
* @param line a string
* @param start where to star looking
*/
public static int findBreakBefore(String line, int start) {
for (int i = start; i >= 0; --i) {
char c = line.charAt(i);
if (Character.isWhitespace(c) || c == '-')
return i;
}
return -1;
}
/**
* Returns the index of the first whitespace character or '-' in <var>line</var> that is at or
* after <var>start</var>. Returns -1 if no such character is found.
*
* @param line a string
* @param start where to star looking
*/
public static int findBreakAfter(String line, int start) {
int len = line.length();
for (int i = start; i < len; ++i) {
char c = line.charAt(i);
if (Character.isWhitespace(c) || c == '-')
return i;
}
return -1;
}
/**
* Returns an array of strings, one for each line in the string. Lines end with any of cr, lf, or
* cr lf. A line ending at the end of the string will not output a further, empty string.
* <p>
* This code assumes <var>str</var> is not <code>null</code>.
*
* @param str the string to split
* @return a non-empty list of strings
*/
public static List<String> splitIntoLines(String str) {
List<String> strings = new ArrayList<String>();
int len = str.length();
if (len == 0) {
strings.add("");
return strings;
}
int lineStart = 0;
for (int i = 0; i < len; ++i) {
char c = str.charAt(i);
if (c == '\r') {
int newlineLength = 1;
if ((i + 1) < len && str.charAt(i + 1) == '\n')
newlineLength = 2;
strings.add(str.substring(lineStart, i));
lineStart = i + newlineLength;
if (newlineLength == 2) // skip \n next time through loop
++i;
} else if (c == '\n') {
strings.add(str.substring(lineStart, i));
lineStart = i + 1;
}
}
if (lineStart < len)
strings.add(str.substring(lineStart));
return strings;
}
public static void drawCenteredText(Graphics2D g2d, String text, int x, int y, HorizontalAlignment horizontalAlignment,
VerticalAlignment verticalAlignment) {
String[] parts = text.split("\n");
if (parts.length > 1) {
FontMetrics fontMetrics = g2d.getFontMetrics();
Rectangle stringBounds = fontMetrics.getStringBounds(parts[0], g2d).getBounds();
for (int i = 0; i < parts.length; i++)
drawCenteredText(g2d, parts[i], x, (int)(y - stringBounds.height * (parts.length - 1) / 2d + i * stringBounds.height), horizontalAlignment, verticalAlignment);
return;
}
FontMetrics fontMetrics = g2d.getFontMetrics();
Rectangle stringBounds = fontMetrics.getStringBounds(text, g2d).getBounds();
Font font = g2d.getFont();
FontRenderContext renderContext = g2d.getFontRenderContext();
GlyphVector glyphVector = font.createGlyphVector(renderContext, text);
Rectangle visualBounds = glyphVector.getVisualBounds().getBounds();
int textX = 0;
switch (horizontalAlignment) {
case CENTER:
textX = x - stringBounds.width / 2;
break;
case LEFT:
textX = x;
break;
case RIGHT:
textX = x - stringBounds.width;
break;
}
int textY = 0;
switch (verticalAlignment) {
case TOP:
textY = y + stringBounds.height;
break;
case CENTER:
textY = y - visualBounds.height / 2 - visualBounds.y;
break;
case BOTTOM:
textY = y - visualBounds.y;
break;
}
g2d.drawString(text, textX, textY);
}
}
@@ -21,14 +21,11 @@
*/
package org.diylc.awt;
import java.awt.Shape;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
/**
* Creates an are covered by the two circles and the area between them bordered by the two external common tangents.
*
@@ -54,8 +51,4 @@ public class TwoCircleTangent extends Area {
a.add(new Area(path));
add(a);
}
public TwoCircleTangent(Shape s) {
throw new NotImplementedException();
}
}
@@ -21,33 +21,33 @@
*/
package org.diylc.components;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.Display;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractComponent;
import org.diylc.components.semiconductors.SymbolFlipping;
import org.diylc.core.ComponentState;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.Theme;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.awt.StringUtils;
import org.diylc.common.Display;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.semiconductors.SymbolFlipping;
import org.diylc.core.ComponentState;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.Theme;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
public abstract class Abstract3LegSymbol extends AbstractComponent<String> {
@@ -57,16 +57,31 @@ public abstract class Abstract3LegSymbol extends AbstractComponent<String> {
public static Color COLOR = Color.black;
protected String value = "";
protected Point[] controlPoints = new Point[] {new Point(0, 0), new Point(0, 0), new Point(0, 0)};
protected Point[] controlPoints = new Point[] { new Point(0, 0), new Point(0, 0), new Point(0, 0), new Point(0, 0) };
protected Color color = COLOR;
protected SymbolFlipping flip = SymbolFlipping.NONE;
protected Display display = Display.NAME;
transient protected Shape[] body;
protected Orientation orientation = Orientation.DEFAULT;
protected Orientation orientation = Orientation.DEFAULT;
protected boolean moveLabel = false;
public Abstract3LegSymbol() {
super();
updateControlPoints();
updateControlPoints();
controlPoints[3] = getDefaultLabelPosition(controlPoints);
}
public Point[] getControlPoints() {
if (controlPoints.length == 3) {
controlPoints = new Point[] { controlPoints[0], controlPoints[1], controlPoints[2], getDefaultLabelPosition(controlPoints) };
}
return controlPoints;
}
protected Point getDefaultLabelPosition(Point[] oldControlPoints) {
int f = flip == SymbolFlipping.X ? -1 : 1;
int d = flip == SymbolFlipping.X ? (int) PIN_SPACING.convertToPixels() / 2 : 0;
return new Point(oldControlPoints[0].x + f * (int) (PIN_SPACING.convertToPixels() * 1.5 + d), oldControlPoints[0].y);
}
@Override
@@ -88,14 +103,14 @@ public abstract class Abstract3LegSymbol extends AbstractComponent<String> {
}
g2d.setColor(finalColor);
// Draw transistor
if (this.body == null) {
this.body = getBody();
applyOrientation(this.body);
}
AffineTransform old = g2d.getTransform();
AffineTransform old = g2d.getTransform();
Point[] controlPoints = getControlPoints();
if (this.flip == SymbolFlipping.Y) {
g2d.translate(0, controlPoints[0].y);
@@ -142,61 +157,82 @@ public abstract class Abstract3LegSymbol extends AbstractComponent<String> {
FontMetrics fontMetrics = g2d.getFontMetrics();
Rectangle2D textRect = fontMetrics.getStringBounds(label, g2d);
Rectangle shapeRect = body[0].getBounds().union(body[1].getBounds()).union(body[2].getBounds());
drawCenteredText(g2d, label, getLabelX(shapeRect, textRect, fontMetrics, outlineMode),
getLabelY(shapeRect, textRect, fontMetrics, outlineMode), flip == SymbolFlipping.X ? HorizontalAlignment.RIGHT
: HorizontalAlignment.LEFT, VerticalAlignment.CENTER);
Rectangle shapeRect = body[0].getBounds().union(body[1].getBounds()).union(body[2].getBounds());
if (getMoveLabel()) {
StringUtils.drawCenteredText(g2d, label, controlPoints[3].x, controlPoints[3].y, flip == SymbolFlipping.X ? HorizontalAlignment.RIGHT
: HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
} else {
StringUtils.drawCenteredText(g2d, label, getLabelX(shapeRect, textRect, fontMetrics, outlineMode),
getLabelY(shapeRect, textRect, fontMetrics, outlineMode), flip == SymbolFlipping.X ? HorizontalAlignment.RIGHT
: HorizontalAlignment.LEFT, VerticalAlignment.CENTER);
}
}
@Override
public Point getControlPoint(int index) {
return controlPoints[index];
return getControlPoints()[index];
}
@Override
public int getControlPointCount() {
return controlPoints.length;
return getControlPoints().length;
}
protected int getLabelX(Rectangle2D shapeRect, Rectangle2D textRect, FontMetrics fontMetrics, boolean outlineMode) {
int f = flip == SymbolFlipping.X ? -1 : 1;
int d = flip == SymbolFlipping.X ? (int) PIN_SPACING.convertToPixels() / 2 : 0;
return controlPoints[0].x + f * (int) (PIN_SPACING.convertToPixels() * 1.5 + d);
return getControlPoints()[0].x + f * (int) (PIN_SPACING.convertToPixels() * 1.5 + d);
}
protected int getLabelY(Rectangle2D shapeRect, Rectangle2D textRect, FontMetrics fontMetrics, boolean outlineMode) {
return controlPoints[0].y;
return getControlPoints()[0].y;
}
protected void updateControlPoints() {
int pinSpacing = (int) PIN_SPACING.convertToPixels();
// Update control points.
int pinSpacing = (int) PIN_SPACING.convertToPixels();
Point[] controlPoints = getControlPoints();
int x = controlPoints[0].x;
int y = controlPoints[0].y;
int f = flip == SymbolFlipping.X ? -1 : 1;
controlPoints[1].x = x + f * pinSpacing * 2;
// set default point positions
controlPoints[1].x = x + pinSpacing * 2;
controlPoints[1].y = y - pinSpacing * 2;
controlPoints[2].x = x + f * pinSpacing * 2;
controlPoints[2].x = x + pinSpacing * 2;
controlPoints[2].y = y + pinSpacing * 2;
controlPoints[3].x = x + (int) (PIN_SPACING.convertToPixels() * 2);
controlPoints[3].y = y;
// apply rotation if needed
if (getOrientation() != Orientation.DEFAULT)
{
Point first = this.controlPoints[0];
Point first = controlPoints[0];
double angle = Double.parseDouble(getOrientation().name().replace("_", ""));
AffineTransform rotate = AffineTransform.getRotateInstance(Math.toRadians(angle), first.x, first.y);
for (int i = 1; i < this.controlPoints.length; i++) {
rotate.transform(this.controlPoints[i], this.controlPoints[i]);
for (int i = 1; i < controlPoints.length; i++) {
rotate.transform(controlPoints[i], controlPoints[i]);
}
}
// flip at the end
if (flip == SymbolFlipping.X) {
controlPoints[1].x = controlPoints[0].x - (controlPoints[1].x - controlPoints[0].x);
controlPoints[2].x = controlPoints[0].x - (controlPoints[2].x - controlPoints[0].x);
controlPoints[3].x = controlPoints[0].x - (controlPoints[3].x - controlPoints[0].x);
}
if (flip == SymbolFlipping.Y) {
controlPoints[1].y = controlPoints[0].y - (controlPoints[1].y - controlPoints[0].y);
controlPoints[2].y = controlPoints[0].y - (controlPoints[2].y - controlPoints[0].y);
controlPoints[3].y = controlPoints[0].y - (controlPoints[3].y - controlPoints[0].y);
}
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.WHEN_SELECTED;
return index < 3 || getMoveLabel() ? VisibilityPolicy.WHEN_SELECTED : VisibilityPolicy.NEVER;
}
@EditableProperty
@@ -212,15 +248,25 @@ public abstract class Abstract3LegSymbol extends AbstractComponent<String> {
@Override
public boolean isControlPointSticky(int index) {
return true;
return index < 3;
}
@Override
public void setControlPoint(Point point, int index) {
controlPoints[index].setLocation(point);
getControlPoints()[index].setLocation(point);
// make sure we have a new drawing
body = null;
}
@Override
public boolean canPointMoveFreely(int pointIndex) {
return pointIndex == 3;
}
@Override
public boolean canControlPointOverlap(int index) {
return index >= 3;
}
@EditableProperty
@@ -243,6 +289,15 @@ public abstract class Abstract3LegSymbol extends AbstractComponent<String> {
public void setColor(Color color) {
this.color = color;
}
@EditableProperty(name = "Moveable Label")
public boolean getMoveLabel() {
return moveLabel;
}
public void setMoveLabel(boolean moveLabel) {
this.moveLabel = moveLabel;
}
@EditableProperty
@@ -274,7 +329,7 @@ public abstract class Abstract3LegSymbol extends AbstractComponent<String> {
if (getOrientation() == Orientation.DEFAULT)
return;
Point first = this.controlPoints[0];
Point first = getControlPoints()[0];
double angle = Double.parseDouble(getOrientation().name().replace("_", ""));
AffineTransform rotate = AffineTransform.getRotateInstance(Math.toRadians(angle), first.x, first.y);
@@ -283,6 +338,13 @@ public abstract class Abstract3LegSymbol extends AbstractComponent<String> {
body[i] = rotate.createTransformedShape(body[i]);
}
}
}
@Override
public String getControlPointNodeName(int index) {
if (index >= 3)
return null;
return Integer.toString(index + 1);
}
/**
@@ -36,10 +36,13 @@ import java.awt.geom.Rectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.awt.ShadedPaint;
import org.diylc.awt.StringUtils;
import org.diylc.common.Display;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.LineStyle;
import org.diylc.common.ObjectCache;
import org.diylc.common.VerticalAlignment;
import org.diylc.core.ComponentState;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
@@ -70,7 +73,7 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
protected Size length;
protected Size width;
protected Point[] points = new Point[] {new Point((int) (-DEFAULT_SIZE.convertToPixels() / 2), 0),
new Point((int) (DEFAULT_SIZE.convertToPixels() / 2), 0)};
new Point((int) (DEFAULT_SIZE.convertToPixels() / 2), 0), new Point(0, 0)};
protected Color bodyColor = Color.white;
protected Color borderColor = Color.black;
protected Color labelColor = LABEL_COLOR;
@@ -78,6 +81,11 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
protected Display display = Display.NAME;
private boolean flipStanding = false;
private LabelOriantation labelOriantation = LabelOriantation.Directional;
protected boolean moveLabel = false;
// parameters for adjusting the label control point
protected Double gamma = null;
protected Double r = null;
protected AbstractLeadedComponent() {
super();
@@ -88,28 +96,67 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
// This should never happen because Size supports cloning.
} catch (NullPointerException e) {
// This will happen if components do not have any shape.
}
}
points[2] = calculateLabelPosition(points[0], points[1]);
}
protected boolean IsCopperArea() {
return false;
}
protected Point[] getPoints() {
// convert old points to new
if (points.length == 2) {
points = new Point[] { points[0], points[1], calculateLabelPosition(points[0], points[1]) };
// to make standing components backward compatible and not show a label until the user switches the display to something else
if (isStanding())
display = Display.NONE;
}
return points;
}
protected Point calculateLabelPosition(Point point1, Point point2) {
double x = (point1.x + point2.x) / 2.0;
double y = (point1.y + point2.y) / 2.0;
return new Point((int) x, (int) y);
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
double distance = points[0].distance(points[1]);
if (gamma != null) {
// recalculate center position and theta, then adjust label point accordingly, while preserving alpha and p
double x = (getPoints()[1].x + getPoints()[0].x) / 2.0;
double y = (getPoints()[1].y + getPoints()[0].y) / 2.0;
double theta = Math.atan2(getPoints()[1].y - getPoints()[0].y, getPoints()[1].x - getPoints()[0].x);
double beta = gamma - (Math.PI / 2 - theta);
getPoints()[2].setLocation(x + Math.cos(beta) * r, y + Math.sin(beta) * r);
gamma = null;
r = null;
}
double distance = getPoints()[0].distance(getPoints()[1]);
Shape shape = getBodyShape();
// If there's no body, just draw the line connecting the ending points.
if (shape == null) {
drawLead(g2d, componentState, drawingObserver, IsCopperArea());
} else if (supportsStandingMode() && length.convertToPixels() > points[0].distance(points[1])) {
return;
}
AffineTransform oldTransform = g2d.getTransform();
double width;
double length;
Rectangle shapeRect;
double theta = Math.atan2(getPoints()[1].y - getPoints()[0].y, getPoints()[1].x - getPoints()[0].x);
if (isStanding()) {
// When ending points are too close draw the component in standing
// mode.
int width = getClosestOdd(this.width.convertToPixels());
width = length = getClosestOdd(this.width.convertToPixels());
Shape body =
new Ellipse2D.Double((getFlipStanding() ? points[1] : points[0]).x - width / 2,
(getFlipStanding() ? points[1] : points[0]).y - width / 2, width, width);
new Ellipse2D.Double((getFlipStanding() ? getPoints()[1] : getPoints()[0]).x - width / 2,
(getFlipStanding() ? getPoints()[1] : getPoints()[0]).y - width / 2, width, width);
shapeRect = body.getBounds();
Composite oldComposite = g2d.getComposite();
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA));
@@ -130,6 +177,7 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
: borderColor;
}
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1f));
g2d.setColor(finalBorderColor);
g2d.draw(body);
if (!outlineMode) {
@@ -137,11 +185,10 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
}
} else {
// Normal mode with component body in the center and two lead parts.
Rectangle shapeRect = shape.getBounds();
double theta = Math.atan2(points[1].y - points[0].y, points[1].x - points[0].x);
shapeRect = shape.getBounds();
// Go back to the original transformation to draw leads.
if (!outlineMode) {
AffineTransform textTransform = g2d.getTransform();
// AffineTransform textTransform = g2d.getTransform();
// if (length.convertToPixels() > points[0].distance(points[1]))
// {
// g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
@@ -156,14 +203,14 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
Area leadArea = new Area();
int endX = (int) (points[0].x + Math.cos(theta) * leadLength);
int endY = (int) (points[0].y + Math.sin(theta) * leadLength);
Line2D line = new Line2D.Double(points[0].x, points[0].y, endX, endY);
int endX = (int) (getPoints()[0].x + Math.cos(theta) * leadLength);
int endY = (int) (getPoints()[0].y + Math.sin(theta) * leadLength);
Line2D line = new Line2D.Double(getPoints()[0].x, getPoints()[0].y, endX, endY);
leadArea.add(new Area(leadStroke.createStrokedShape(line)));
endX = (int) (points[1].x + Math.cos(theta - Math.PI) * leadLength);
endY = (int) (points[1].y + Math.sin(theta - Math.PI) * leadLength);
line = new Line2D.Double(points[1].x, points[1].y, endX, endY);
endX = (int) (getPoints()[1].x + Math.cos(theta - Math.PI) * leadLength);
endY = (int) (getPoints()[1].y + Math.sin(theta - Math.PI) * leadLength);
line = new Line2D.Double(getPoints()[1].x, getPoints()[1].y, endX, endY);
leadArea.add(new Area(leadStroke.createStrokedShape(line)));
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1f));
@@ -177,13 +224,10 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
g2d.setColor(leadColor);
drawLeads(g2d, theta, leadLength);
}
g2d.setTransform(textTransform);
// g2d.setTransform(textTransform);
}
// Transform graphics to draw the body in the right place and at the
// right angle.
AffineTransform oldTransform = null;
double width;
double length;
// right angle.
if (useShapeRectAsPosition()) {
width = shapeRect.getHeight();
length = shapeRect.getWidth();
@@ -191,8 +235,7 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
width = getWidth().convertToPixels();
length = getLength().convertToPixels();
}
oldTransform = g2d.getTransform();
g2d.translate((points[0].x + points[1].x - length) / 2, (points[0].y + points[1].y - width) / 2);
g2d.translate((getPoints()[0].x + getPoints()[1].x - length) / 2, (getPoints()[0].y + getPoints()[1].y - width) / 2);
g2d.rotate(theta, length / 2, width / 2);
// Draw body.
Composite oldComposite = g2d.getComposite();
@@ -243,64 +286,91 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
decorateComponentBody(g2d, outlineMode);
g2d.setComposite(oldComposite);
}
}
// Draw label.
g2d.setFont(project.getFont());
if (useShapeRectAsPosition()) {
g2d.translate(shapeRect.x, shapeRect.y);
// Draw label.
g2d.setFont(project.getFont());
if (useShapeRectAsPosition()) {
g2d.translate(shapeRect.x, shapeRect.y);
}
Color finalLabelColor;
if (outlineMode) {
Theme theme =
(Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalLabelColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: theme.getOutlineColor();
} else {
finalLabelColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: labelColor;
}
g2d.setColor(finalLabelColor);
FontMetrics fontMetrics = g2d.getFontMetrics();
String label = "";
label = display == Display.NAME ? getName() : (getValue() == null ? "" : getValue().toString());
if (display == Display.NONE) {
label = "";
}
if (display == Display.BOTH) {
label = getName() + " " + (getValue() == null ? "" : getValue().toString());
}
Rectangle2D textRect = fontMetrics.getStringBounds(label, g2d);
// Don't offset in outline mode.
int offset = outlineMode ? 0 : getLabelOffset((int) length, (int) width, (int) textRect.getWidth());
// Adjust label angle if needed to make sure that it's readable.
if ((theta >= Math.PI / 2 && theta <= Math.PI) || (theta < -Math.PI / 2 && theta > -Math.PI)) {
g2d.rotate(Math.PI, length / 2, width / 2);
theta += Math.PI;
offset = -offset;
}
if (getMoveLabel()) {
g2d.setTransform(oldTransform);
g2d.translate(getPoints()[2].x, getPoints()[2].y);
if (getLabelOriantation() != LabelOriantation.Horizontal) {
g2d.rotate(theta);
}
Color finalLabelColor;
if (outlineMode) {
Theme theme =
(Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalLabelColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: theme.getOutlineColor();
} else {
finalLabelColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: labelColor;
}
g2d.setColor(finalLabelColor);
FontMetrics fontMetrics = g2d.getFontMetrics();
String label = "";
label = display == Display.NAME ? getName() : (getValue() == null ? "" : getValue().toString());
if (display == Display.NONE) {
label = "";
}
if (display == Display.BOTH) {
label = getName() + " " + (getValue() == null ? "" : getValue().toString());
}
Rectangle2D textRect = fontMetrics.getStringBounds(label, g2d);
// Don't offset in outline mode.
int offset = outlineMode ? 0 : getLabelOffset((int) length, (int) width, (int) textRect.getWidth());
// Adjust label angle if needed to make sure that it's readable.
if ((theta >= Math.PI / 2 && theta <= Math.PI) || (theta < -Math.PI / 2 && theta > -Math.PI)) {
g2d.rotate(Math.PI, length / 2, width / 2);
offset = -offset;
}
if (getLabelOriantation() == LabelOriantation.Horizontal) {
StringUtils.drawCenteredText(g2d, label, offset, 0, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
g2d.setTransform(oldTransform);
} else {
if (isStanding() || getLabelOriantation() == LabelOriantation.Horizontal) {
g2d.setTransform(oldTransform);
double x = (points[0].x + points[1].x - length) / 2.0;
double y = (points[0].y + points[1].y - width) / 2.0;
double x = (getPoints()[0].x + getPoints()[1].x - length) / 2.0;
double y = (getPoints()[0].y + getPoints()[1].y - width) / 2.0;
g2d.drawString(label, (int) (x + (length - textRect.getWidth()) / 2 + offset),
(int)(y + calculateLabelYCoordinate(shapeRect, textRect, fontMetrics)));
(int)(y + calculateLabelYOffset(shapeRect, textRect, fontMetrics)));
} else {
g2d.drawString(label, (int) (length - textRect.getWidth()) / 2 + offset,
calculateLabelYCoordinate(shapeRect, textRect, fontMetrics));
calculateLabelYOffset(shapeRect, textRect, fontMetrics));
g2d.setTransform(oldTransform);
}
}
}
// if (getLabelOriantation() == LabelOriantation.Horizontal) {
//
// drawCenteredText(g2d, label, getNewPoints()[2].x, getNewPoints()[2].x, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
// g2d.drawString(label, (int) (x + (length - textRect.getWidth()) / 2 + offset),
// (int)(y + calculateLabelYCoordinate(shapeRect, textRect, fontMetrics)));
// } else {
// g2d.drawString(label, (int) (length - textRect.getWidth()) / 2 + offset,
// calculateLabelYCoordinate(shapeRect, textRect, fontMetrics));
// g2d.setTransform(oldTransform);
// }
}
protected boolean isStanding() {
return supportsStandingMode() && this.length.convertToPixels() > getPoints()[0].distance(getPoints()[1]);
}
private void drawLeads(Graphics2D g2d, double theta, double leadLength) {
double endX = points[0].x + Math.cos(theta) * leadLength;
double endY = points[0].y + Math.sin(theta) * leadLength;
g2d.draw(new Line2D.Double(points[0].x, points[0].y, endX, endY));
double endX = getPoints()[0].x + Math.cos(theta) * leadLength;
double endY = getPoints()[0].y + Math.sin(theta) * leadLength;
g2d.draw(new Line2D.Double(getPoints()[0].x, getPoints()[0].y, endX, endY));
endX = points[1].x + Math.cos(theta - Math.PI) * leadLength;
endY = points[1].y + Math.sin(theta - Math.PI) * leadLength;
g2d.draw(new Line2D.Double(points[1].x, points[1].y, endX, endY));
endX = getPoints()[1].x + Math.cos(theta - Math.PI) * leadLength;
endY = getPoints()[1].y + Math.sin(theta - Math.PI) * leadLength;
g2d.draw(new Line2D.Double(getPoints()[1].x, getPoints()[1].y, endX, endY));
}
private void drawLead(Graphics2D g2d, ComponentState componentState, IDrawingObserver observer, boolean isCopperArea) {
@@ -309,7 +379,7 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
float thickness = getLeadThickness();
Line2D line = new Line2D.Double(points[0].x, points[0].y, points[1].x, points[1].y);
Line2D line = new Line2D.Double(getPoints()[0].x, getPoints()[0].y, getPoints()[1].x, getPoints()[1].y);
if (shouldShadeLeads()) {
// for some reason the stroked line gets approx 1px thicker when converted to shape
@@ -347,6 +417,9 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
g2d.setColor(getLeadColorForPainting(componentState));
g2d.setStroke(stroke);
g2d.draw(line);
if (isCopperArea)
observer.stopTrackingContinuityArea();
}
}
@@ -362,7 +435,7 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
return false;
}
protected int calculateLabelYCoordinate(Rectangle2D shapeRect, Rectangle2D textRect, FontMetrics fontMetrics) {
protected int calculateLabelYOffset(Rectangle2D shapeRect, Rectangle2D textRect, FontMetrics fontMetrics) {
return (int) (shapeRect.getHeight() - textRect.getHeight()) / 2 + fontMetrics.getAscent();
}
@@ -443,27 +516,48 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
@Override
public int getControlPointCount() {
return points.length;
return getPoints().length;
}
@Override
public Point getControlPoint(int index) {
return (Point) points[index];
return (Point) getPoints()[index];
}
@Override
public boolean isControlPointSticky(int index) {
return true;
return index < 2;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.ALWAYS;
return getMoveLabel() || index < 2 ? VisibilityPolicy.ALWAYS : VisibilityPolicy.NEVER;
}
@Override
public boolean canControlPointOverlap(int index) {
return index >= 2;
}
@Override
public void setControlPoint(Point point, int index) {
points[index].setLocation(point);
public void setControlPoint(Point point, int index) {
// when moving one of the ending points, try to retain the angle and distance from the center point to label point
if (index < 2) {
if (gamma == null) {
double x = (getPoints()[1].x + getPoints()[0].x) / 2.0;
double y = (getPoints()[1].y + getPoints()[0].y) / 2.0;
double theta = Math.atan2(getPoints()[1].y - getPoints()[0].y, getPoints()[1].x - getPoints()[0].x);
double beta = Math.atan2(getPoints()[2].y - y, getPoints()[2].x - x);
gamma = beta + (Math.PI / 2 - theta);
r = getPoints()[2].distance(x, y);
} else { // in case when we are copy pasting we don't want to recalculate 3rd point position as they will all move in unison
// when we moved the first point, gamma and r were initialized, so now we are canceling
gamma = null;
r = null;
}
}
getPoints()[index].setLocation(point);
}
@EditableProperty(name = "Color")
@@ -534,6 +628,13 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
public void setLabelOriantation(LabelOriantation labelOriantation) {
this.labelOriantation = labelOriantation;
}
@Override
public String getInternalLinkName(int index1, int index2) {
if ((index1 == 0 && index2 == 1) || (index2 == 0 && index1 == 1))
return getName();
return null;
}
/**
* Override this method with @EditableProperty annotation in child classes where standing mode is
@@ -548,7 +649,23 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
public void setFlipStanding(boolean flipStanding) {
this.flipStanding = flipStanding;
}
@EditableProperty(name = "Moveable Label")
public boolean getMoveLabel() {
return moveLabel;
}
public void setMoveLabel(boolean moveLabel) {
this.moveLabel = moveLabel;
}
@Override
public String getControlPointNodeName(int index) {
if (index >= 2)
return null;
return Integer.toString(index + 1);
}
public enum LabelOriantation {
Directional, Horizontal
}
@@ -21,13 +21,14 @@
*/
package org.diylc.components;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.geom.Rectangle2D;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Point;
import java.awt.geom.Rectangle2D;
import org.diylc.common.LabelPosition;
import org.diylc.core.ComponentState;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.common.LabelPosition;
import org.diylc.core.ComponentState;
import org.diylc.core.annotations.EditableProperty;
public abstract class AbstractSchematicLeadedSymbol<T> extends AbstractLeadedComponent<T> {
@@ -62,12 +63,21 @@ public abstract class AbstractSchematicLeadedSymbol<T> extends AbstractLeadedCom
}
@Override
protected int calculateLabelYCoordinate(Rectangle2D shapeRect, Rectangle2D textRect, FontMetrics fontMetrics) {
protected int calculateLabelYOffset(Rectangle2D shapeRect, Rectangle2D textRect, FontMetrics fontMetrics) {
if (labelPosition == LabelPosition.ABOVE) {
return -5;
} else {
return (int) (shapeRect.getHeight() + textRect.getHeight());
}
}
@Override
protected Point calculateLabelPosition(Point point1, Point point2) {
double x = (point1.x + point2.x) / 2.0;
double y = (point1.y + point2.y) / 2.0;
double theta = Math.atan2(point2.y - point1.y, point2.x - point2.x) - Math.PI / 2;
double r = width.convertToPixels() / 2 + LABEL_FONT.getSize() / 2;
return new Point((int) (x + Math.cos(theta) * r), (int) (y + Math.sin(theta) * r));
}
@EditableProperty(name = "Label Position")
@@ -27,6 +27,7 @@ import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Point;
import org.diylc.awt.StringUtils;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.ObjectCache;
import org.diylc.common.VerticalAlignment;
@@ -116,11 +117,11 @@ public abstract class AbstractBoard extends AbstractTransparentComponent<String>
String label = yType == CoordinateType.Letters ? getCoordinateLabel(c) : Integer.toString(c);
drawPoint.y += yOffset;
drawCenteredText(g2d, label,
StringUtils.drawCenteredText(g2d, label,
firstPoint.x + xOffset, drawPoint.y,
HorizontalAlignment.LEFT, VerticalAlignment.CENTER);
if (getCoordinateDisplay() == CoordinateDisplay.Both_Sides) {
drawCenteredText(g2d, label,
StringUtils.drawCenteredText(g2d, label,
secondPoint.x - xOffset, drawPoint.y,
HorizontalAlignment.RIGHT, VerticalAlignment.CENTER);
}
@@ -146,11 +147,11 @@ public abstract class AbstractBoard extends AbstractTransparentComponent<String>
String label = xType == CoordinateType.Letters ? getCoordinateLabel(c) : Integer.toString(c);
drawPoint.x += xOffset;
drawCenteredText(g2d, label,
StringUtils.drawCenteredText(g2d, label,
drawPoint.x, firstPoint.y - 2,
HorizontalAlignment.CENTER, VerticalAlignment.TOP);
if (getCoordinateDisplay() == CoordinateDisplay.Both_Sides) {
drawCenteredText(g2d, label,
StringUtils.drawCenteredText(g2d, label,
drawPoint.x, (int) (secondPoint.y - COORDINATE_FONT_SIZE),
HorizontalAlignment.CENTER, VerticalAlignment.BOTTOM);
}
@@ -122,6 +122,11 @@ public class BlankBoard extends AbstractBoard {
public void setType(Type type) {
this.type = type;
}
@Override
public String getControlPointNodeName(int index) {
return null;
}
static enum Type {
@@ -28,6 +28,7 @@ import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.AffineTransform;
import org.diylc.awt.StringUtils;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
@@ -46,7 +47,7 @@ import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Breadboard", category = "Boards", author = "Branislav Stojkovic",
description = "Prototyping solderless breadboard", instanceNamePrefix = "BB", stretchable = false,
description = "Prototyping solderless breadboard", instanceNamePrefix = "BB",
zOrder = IDIYComponent.BOARD, bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME, autoEdit = false,
keywordPolicy = KeywordPolicy.SHOW_TYPE_NAME)
public class Breadboard extends AbstractComponent<Void> {
@@ -146,7 +147,7 @@ public class Breadboard extends AbstractComponent<Void> {
} else {
coordinateX = (int) (point.x + offset + 10.5 * spacing);
}
drawCenteredText(g2d, new Integer(y + 1).toString(), coordinateX, (int) (point.y + (y + 1) * spacing),
StringUtils.drawCenteredText(g2d, new Integer(y + 1).toString(), coordinateX, (int) (point.y + (y + 1) * spacing),
section == 0 ? HorizontalAlignment.RIGHT : HorizontalAlignment.LEFT, VerticalAlignment.CENTER);
for (int x = 0; x < 5; x++) {
int holeX = (int) (point.x + offset + (x + 6) * spacing);
@@ -159,9 +160,9 @@ public class Breadboard extends AbstractComponent<Void> {
// Draw horizontal labels
if (y == 0) {
g2d.setColor(COORDINATE_COLOR);
drawCenteredText(g2d, new String(new byte[] {(byte) (a + x + 5 * section)}), holeX, (int) (point.y),
StringUtils.drawCenteredText(g2d, new String(new byte[] {(byte) (a + x + 5 * section)}), holeX, (int) (point.y),
HorizontalAlignment.CENTER, VerticalAlignment.TOP);
drawCenteredText(g2d, new String(new byte[] {(byte) (a + x + 5 * section)}), holeX, (int) (point.y
StringUtils.drawCenteredText(g2d, new String(new byte[] {(byte) (a + x + 5 * section)}), holeX, (int) (point.y
+ spacing * 30 + COORDINATE_FONT_SIZE / 2), HorizontalAlignment.CENTER, VerticalAlignment.TOP);
}
}
@@ -218,7 +219,7 @@ public class Breadboard extends AbstractComponent<Void> {
} else {
coordinateX = (int) (point.x + offset + 10.5 * spacing);
}
drawCenteredText(g2d, new Integer(y + 1).toString(), coordinateX, (int) (point.y + (y + 1) * spacing),
StringUtils.drawCenteredText(g2d, new Integer(y + 1).toString(), coordinateX, (int) (point.y + (y + 1) * spacing),
section == 0 ? HorizontalAlignment.RIGHT : HorizontalAlignment.LEFT, VerticalAlignment.CENTER);
// for (int x = 0; x < 5; x++) {
int holeX1 = (int) (point.x + offset + 6 * spacing);
@@ -312,6 +313,11 @@ public class Breadboard extends AbstractComponent<Void> {
@Override
public int getControlPointCount() {
return 2;
}
@Override
public boolean canPointMoveFreely(int pointIndex) {
return false;
}
@SuppressWarnings("incomplete-switch")
@@ -364,7 +370,12 @@ public class Breadboard extends AbstractComponent<Void> {
}
@Override
public void setValue(Void value) {}
public void setValue(Void value) {}
@Override
public String getControlPointNodeName(int index) {
return null;
}
public enum BreadboardSize {
Half, Full
@@ -119,6 +119,11 @@ public class EyeletBoard extends AbstractBoard {
public void setSpacing(Size spacing) {
this.spacing = spacing;
}
@Override
public String getControlPointNodeName(int index) {
return null;
}
@Override
@@ -103,6 +103,11 @@ public class MarshallPerfBoard extends AbstractBoard {
public void setSpacing(Size spacing) {
this.spacing = spacing;
}
@Override
public String getControlPointNodeName(int index) {
return null;
}
@Override
@@ -112,6 +112,11 @@ public class PerfBoard extends AbstractBoard {
public void setSpacing(Size spacing) {
this.spacing = spacing;
}
@Override
public String getControlPointNodeName(int index) {
return null;
}
@Override
@@ -37,6 +37,7 @@ import org.diylc.common.Orientation;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.components.transform.TerminalStripTransformer;
import org.diylc.core.ComponentState;
import org.diylc.core.IContinuity;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
@@ -51,9 +52,9 @@ import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Terminal Strip", author = "Branislav Stojkovic", category = "Boards",
instanceNamePrefix = "TS", description = "Row of terminals for point-to-point construction", stretchable = false,
instanceNamePrefix = "TS", description = "Row of terminals for point-to-point construction",
zOrder = IDIYComponent.BOARD, keywordPolicy = KeywordPolicy.SHOW_TYPE_NAME, transformer = TerminalStripTransformer.class)
public class TerminalStrip extends AbstractTransparentComponent<String> {
public class TerminalStrip extends AbstractTransparentComponent<String> implements IContinuity {
private static final long serialVersionUID = 1L;
@@ -449,5 +450,20 @@ public class TerminalStrip extends AbstractTransparentComponent<String> {
public void setBorderColor(Color borderColor) {
this.borderColor = borderColor;
}
@Override
public String getControlPointNodeName(int index) {
return "TerminalStrip" + index;
}
@Override
public boolean arePointsConnected(int index1, int index2) {
return Math.abs(index1 - index2) == getTerminalCount();
}
@Override
public boolean canPointMoveFreely(int pointIndex) {
return false;
}
}
@@ -236,5 +236,10 @@ public class TriPadBoard extends AbstractBoard {
} else {
this.stripSpan = stripSpan;
}
}
@Override
public String getControlPointNodeName(int index) {
return null;
}
}
@@ -148,6 +148,11 @@ public class VeroBoard extends AbstractBoard {
public void setOrientation(OrientationHV orientation) {
this.orientation = orientation;
}
@Override
public String getControlPointNodeName(int index) {
return null;
}
@Override
@@ -23,11 +23,15 @@ package org.diylc.components.connectivity;
public enum AWG {
_8, _10, _12, _14, _16, _18, _20, _22, _24, _26, _28, _30;
_8, _10, _12, _14, _16, _18, _20, _22, _24, _26, _28, _30, _32, _34, _36;
@Override
public String toString() {
return "#" + name().replace("_", "");
return "#" + name().replace("_", "") + " (" + String.format("%1$,.2f", diameterIn() * 25.4) + "mm / " + String.format("%1$,.5f", diameterIn()) + "in)";
}
public double diameterIn() {
return Math.pow(Math.E, -1.12436 - 0.11594 * getValue());
}
public int getValue() {
@@ -162,4 +162,14 @@ public class CopperTrace extends AbstractLeadedComponent<Void> {
protected boolean IsCopperArea() {
return true;
}
@Override
public String getControlPointNodeName(int index) {
return null;
}
public boolean getMoveLabel() {
// override to disable edit
return false;
}
}
@@ -111,4 +111,9 @@ public class CurvedTrace extends AbstractCurvedComponent<Void> {
public LineStyle getStyle() {
return super.getStyle();
}
@Override
public String getControlPointNodeName(int index) {
return null;
}
}
@@ -39,7 +39,7 @@ import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Cut Line", category = "Connectivity", author = "Branislav Stojkovic",
description = "Cut line", instanceNamePrefix = "CL", stretchable = false, zOrder = IDIYComponent.COMPONENT,
description = "Cut line", instanceNamePrefix = "CL", zOrder = IDIYComponent.COMPONENT,
bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, transformer = SimpleComponentTransformer.class)
public class CutLine extends AbstractTransparentComponent<Void> {
@@ -157,4 +157,9 @@ public class CutLine extends AbstractTransparentComponent<Void> {
@Override
public void setValue(Void value) {}
@Override
public String getControlPointNodeName(int index) {
return null;
}
}
@@ -40,7 +40,7 @@ import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Dot", category = "Connectivity", author = "Branislav Stojkovic",
description = "Connector dot", instanceNamePrefix = "Dot", stretchable = false, zOrder = IDIYComponent.COMPONENT,
description = "Connector dot", instanceNamePrefix = "Dot", zOrder = IDIYComponent.COMPONENT,
bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, transformer = SimpleComponentTransformer.class)
public class Dot extends AbstractComponent<Void> {
@@ -126,5 +126,10 @@ public class Dot extends AbstractComponent<Void> {
}
@Override
public void setValue(Void value) {}
public void setValue(Void value) {}
@Override
public String getControlPointNodeName(int index) {
return null;
}
}
@@ -44,7 +44,7 @@ import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Eyelet", category = "Connectivity", author = "Branislav Stojkovic",
description = "Eyelet or turret terminal", instanceNamePrefix = "Eyelet", stretchable = false,
description = "Eyelet or turret terminal", instanceNamePrefix = "Eyelet",
zOrder = IDIYComponent.TRACE + 0.1, bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME, autoEdit = false,
keywordPolicy = KeywordPolicy.SHOW_TYPE_NAME, transformer = SimpleComponentTransformer.class)
public class Eyelet extends AbstractComponent<String> {
@@ -164,5 +164,10 @@ public class Eyelet extends AbstractComponent<String> {
@Override
public void setValue(String value) {
this.value = value;
}
@Override
public String getControlPointNodeName(int index) {
return null;
}
}
@@ -159,7 +159,12 @@ public class GroundFill extends AbstractComponent<Void> {
@Deprecated
@Override
public void setValue(Void value) {}
public void setValue(Void value) {}
@Override
public String getControlPointNodeName(int index) {
return null;
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
@@ -28,6 +28,7 @@ import org.diylc.common.ObjectCache;
import org.diylc.common.SimpleComponentTransformer;
import org.diylc.components.AbstractCurvedComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IContinuity;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.annotations.BomPolicy;
@@ -38,8 +39,8 @@ import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Hookup Wire", author = "Branislav Stojkovic", category = "Connectivity",
instanceNamePrefix = "W", description = "Flexible wire with two control points", zOrder = IDIYComponent.COMPONENT,
flexibleZOrder = true, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false,
transformer = SimpleComponentTransformer.class, continuity = true)
public class HookupWire extends AbstractCurvedComponent<Void> {
transformer = SimpleComponentTransformer.class)
public class HookupWire extends AbstractCurvedComponent<Void> implements IContinuity {
private static final long serialVersionUID = 1L;
@@ -59,8 +60,7 @@ public class HookupWire extends AbstractCurvedComponent<Void> {
@Override
protected void drawCurve(Path2D curve, Graphics2D g2d, ComponentState componentState, IDrawingObserver drawingObserver) {
int thickness =
(int) (Math.pow(Math.E, -1.12436 - 0.11594 * gauge.getValue()) * Constants.PIXELS_PER_INCH * (1 + 2 * INSULATION_THICKNESS_PCT)) - 1;
int thickness = (int) (gauge.diameterIn() * Constants.PIXELS_PER_INCH * (1 + 2 * INSULATION_THICKNESS_PCT)) - 1;
Color curveColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: color;
@@ -133,4 +133,9 @@ public class HookupWire extends AbstractCurvedComponent<Void> {
public void setStripeColor(Color stripeColor) {
this.stripeColor = stripeColor;
}
@Override
public boolean arePointsConnected(int index1, int index2) {
return Math.abs(index1 - index2) == getControlPointCount() - 1;
}
}
@@ -32,6 +32,7 @@ import org.diylc.common.SimpleComponentTransformer;
import org.diylc.components.AbstractLeadedComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.CreationMethod;
import org.diylc.core.IContinuity;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
@@ -41,8 +42,8 @@ import org.diylc.core.measures.Size;
@ComponentDescriptor(name = "Jumper", author = "Branislav Stojkovic", category = "Connectivity",
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "J", description = "",
zOrder = IDIYComponent.COMPONENT, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false,
transformer = SimpleComponentTransformer.class, continuity = true)
public class Jumper extends AbstractLeadedComponent<Void> {
transformer = SimpleComponentTransformer.class)
public class Jumper extends AbstractLeadedComponent<Void> implements IContinuity {
private static final long serialVersionUID = 1L;
@@ -156,5 +157,15 @@ public class Jumper extends AbstractLeadedComponent<Void> {
@Override
public Display getDisplay() {
return super.getDisplay();
}
@Override
public boolean arePointsConnected(int index1, int index2) {
return true;
}
public boolean getMoveLabel() {
// override to disable edit
return false;
}
}
@@ -262,6 +262,11 @@ public class Line extends AbstractLeadedComponent<Void> {
@Override
protected Size getDefaultLength() {
return null;
}
@Override
public String getControlPointNodeName(int index) {
return null;
}
@Deprecated
@@ -42,7 +42,7 @@ import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Solder Pad", category = "Connectivity", author = "Branislav Stojkovic",
description = "Copper solder pad, round or square", instanceNamePrefix = "Pad", stretchable = false,
description = "Copper solder pad, round or square", instanceNamePrefix = "Pad",
zOrder = IDIYComponent.TRACE + 0.1, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false,
keywordPolicy = KeywordPolicy.SHOW_TAG, keywordTag = "PCB", transformer = SimpleComponentTransformer.class)
public class SolderPad extends AbstractComponent<Void> {
@@ -182,6 +182,11 @@ public class SolderPad extends AbstractComponent<Void> {
public Void getValue() {
return null;
}
@Override
public String getControlPointNodeName(int index) {
return null;
}
@Override
public void setValue(Void value) {}
@@ -25,6 +25,7 @@ import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import org.diylc.common.ObjectCache;
import org.diylc.common.SimpleComponentTransformer;
import org.diylc.components.AbstractComponent;
import org.diylc.components.boards.AbstractBoard;
@@ -43,7 +44,7 @@ import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Trace Cut", category = "Connectivity", author = "Branislav Stojkovic",
description = "Designates the place where a trace on the vero board needs to be cut", instanceNamePrefix = "Cut",
stretchable = false, zOrder = IDIYComponent.BOARD + 1, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false,
zOrder = IDIYComponent.BOARD + 1, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false,
transformer = SimpleComponentTransformer.class)
public class TraceCut extends AbstractComponent<Void> {
@@ -71,7 +72,8 @@ public class TraceCut extends AbstractComponent<Void> {
IDrawingObserver drawingObserver) {
if (checkPointsClipped(g2d.getClip())) {
return;
}
}
g2d.setStroke(ObjectCache.getInstance().fetchZoomableStroke(1f));
int size = getClosestOdd((int) this.size.convertToPixels());
int cutWidth = getClosestOdd((int) CUT_WIDTH.convertToPixels());
if (getCutBetweenHoles()) {
@@ -230,5 +232,10 @@ public class TraceCut extends AbstractComponent<Void> {
@Override
public String getName() {
return super.getName();
}
@Override
public String getControlPointNodeName(int index) {
return null;
}
}
@@ -42,7 +42,7 @@ import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Turret Lug", category = "Connectivity", author = "Branislav Stojkovic",
description = "Turret terminal lug", instanceNamePrefix = "Turret", stretchable = false,
description = "Turret terminal lug", instanceNamePrefix = "Turret",
zOrder = IDIYComponent.TRACE + 0.1, bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME, autoEdit = false,
keywordPolicy = KeywordPolicy.SHOW_TYPE_NAME, transformer = SimpleComponentTransformer.class)
public class Turret extends AbstractComponent<String> {
@@ -162,5 +162,10 @@ public class Turret extends AbstractComponent<String> {
@Override
public void setValue(String value) {
this.value = value;
}
@Override
public String getControlPointNodeName(int index) {
return null;
}
}
@@ -37,6 +37,7 @@ import org.diylc.common.ObjectCache;
import org.diylc.common.SimpleComponentTransformer;
import org.diylc.components.AbstractCurvedComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IContinuity;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.annotations.BomPolicy;
@@ -47,8 +48,8 @@ import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Twisted Leads", author = "Branislav Stojkovic", category = "Connectivity",
instanceNamePrefix = "W", description = "A pair of flexible leads twisted tighly together", zOrder = IDIYComponent.COMPONENT,
flexibleZOrder = true, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false,
transformer = SimpleComponentTransformer.class, continuity = true)
public class TwistedWire extends AbstractCurvedComponent<Void> {
transformer = SimpleComponentTransformer.class)
public class TwistedWire extends AbstractCurvedComponent<Void> implements IContinuity {
private static final long serialVersionUID = 1L;
@@ -80,8 +81,7 @@ public class TwistedWire extends AbstractCurvedComponent<Void> {
@Override
protected void drawCurve(Path2D curve, Graphics2D g2d, ComponentState componentState, IDrawingObserver drawingObserver) {
int thickness =
(int) (Math.pow(Math.E, -1.12436 - 0.11594 * gauge.getValue()) * Constants.PIXELS_PER_INCH * (1 + 2 * INSULATION_THICKNESS_PCT)) - 1;
int thickness = (int) (gauge.diameterIn() * Constants.PIXELS_PER_INCH * (1 + 2 * INSULATION_THICKNESS_PCT)) - 1;
Color curveColor1 =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: color;
@@ -433,4 +433,9 @@ public class TwistedWire extends AbstractCurvedComponent<Void> {
return calculateLength(left, precision) + calculateLength(right, precision);
}
@Override
public boolean arePointsConnected(int index1, int index2) {
return Math.abs(index1 - index2) == getControlPointCount() - 1;
}
}
@@ -52,7 +52,7 @@ import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "9V Battery Snap", category = "Electro-Mechanical", author = "Branislav Stojkovic",
description = "", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "BTR",
description = "", zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "BTR",
autoEdit = false, transformer = BatterySnapTransformer.class)
public class BatterySnap9V extends AbstractTransparentComponent<String> {
@@ -34,6 +34,7 @@ import java.awt.geom.Ellipse2D;
import java.awt.geom.RoundRectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.awt.StringUtils;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
@@ -54,7 +55,7 @@ import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Cliff 1/4\" Jack", category = "Electro-Mechanical", author = "Branislav Stojkovic",
description = "Cliff-style closed panel mount 1/4\" phono jack", stretchable = false,
description = "Cliff-style closed panel mount 1/4\" phono jack",
zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "J", autoEdit = false, transformer = CliffJackTransformer.class)
public class CliffJack1_4 extends AbstractMultiPartComponent<String> {
@@ -246,7 +247,7 @@ public class CliffJack1_4 extends AbstractMultiPartComponent<String> {
g2d.setFont(project.getFont());
int centerX = (controlPoints[0].x + controlPoints[3].x) / 2;
int centerY = (controlPoints[0].y + controlPoints[3].y) / 2;
drawCenteredText(g2d, name, centerX, centerY, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
StringUtils.drawCenteredText(g2d, name, centerX, centerY, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
drawSelectionOutline(g2d, componentState, outlineMode, project, drawingObserver);
}
@@ -337,5 +338,10 @@ public class CliffJack1_4 extends AbstractMultiPartComponent<String> {
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
updateControlPoints();
}
@Override
public boolean canPointMoveFreely(int pointIndex) {
return false;
}
}
@@ -34,6 +34,7 @@ import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.awt.StringUtils;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
@@ -54,7 +55,7 @@ import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Closed 1/4\" Jack", category = "Electro-Mechanical", author = "Branislav Stojkovic",
description = "Enclosed panel mount 1/4\" phono jack", stretchable = false, zOrder = IDIYComponent.COMPONENT,
description = "Enclosed panel mount 1/4\" phono jack", zOrder = IDIYComponent.COMPONENT,
instanceNamePrefix = "J", autoEdit = false, transformer = ClosedJackTransformer.class)
public class ClosedJack1_4 extends AbstractMultiPartComponent<String> {
@@ -269,7 +270,7 @@ public class ClosedJack1_4 extends AbstractMultiPartComponent<String> {
Rectangle bounds = body[0].getBounds();
int centerX = bounds.x + bounds.width / 2;
int centerY = bounds.y + bounds.height / 2;
drawCenteredText(g2d, name, centerX, centerY, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
StringUtils.drawCenteredText(g2d, name, centerX, centerY, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
drawSelectionOutline(g2d, componentState, outlineMode, project, drawingObserver);
}
@@ -350,5 +351,23 @@ public class ClosedJack1_4 extends AbstractMultiPartComponent<String> {
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
updateControlPoints();
}
@Override
public String getControlPointNodeName(int index) {
switch (index) {
case 0:
return "Tip";
case 1:
return "Sleeve";
case 2:
return "Ring";
}
return null;
}
@Override
public boolean canPointMoveFreely(int pointIndex) {
return false;
}
}
@@ -43,6 +43,7 @@ import org.diylc.components.transform.DIL_ICTransformer;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.ISwitch;
import org.diylc.core.Project;
import org.diylc.core.Theme;
import org.diylc.core.VisibilityPolicy;
@@ -55,9 +56,9 @@ import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "DIP Switch", author = "Branislav Stojkovic", category = "Electro-Mechanical",
instanceNamePrefix = "SW", description = "Dual-in-line package switch", stretchable = false,
instanceNamePrefix = "SW", description = "Dual-in-line package switch",
zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, transformer = DIL_ICTransformer.class)
public class DIPSwitch extends AbstractTransparentComponent<String> {
public class DIPSwitch extends AbstractTransparentComponent<String> implements ISwitch {
private static final long serialVersionUID = 1L;
@@ -312,7 +313,8 @@ public class DIPSwitch extends AbstractTransparentComponent<String> {
IDrawingObserver drawingObserver) {
if (checkPointsClipped(g2d.getClip())) {
return;
}
}
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
Area mainArea = getBody()[0];
if (!outlineMode) {
int pinSize = (int) PIN_SIZE.convertToPixels() / 2 * 2;
@@ -512,5 +514,44 @@ public class DIPSwitch extends AbstractTransparentComponent<String> {
public int getValue() {
return Integer.parseInt(toString());
}
}
@Override
public int getPositionCount() {
return (int) Math.pow(2, getSwitchCount().getValue());
}
@Override
public String getPositionName(int position) {
String binary = toBinary(position);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < getSwitchCount().getValue(); i++) {
if (sb.length() > 0)
sb.append("-");
sb.append(binary.charAt(i) == '0' ? "OFF" : "ON");
}
return sb.toString();
}
@Override
public boolean arePointsConnected(int index1, int index2, int position) {
String binary = toBinary(position);
return Math.abs(index1 - index2) == getSwitchCount().getValue() && binary.charAt(index1 < index2 ? index1 : index2) == '1';
}
@Override
public boolean canPointMoveFreely(int pointIndex) {
return false;
}
private String toBinary(int n) {
StringBuilder builder = new StringBuilder();
do {
builder.append(n % 2);
n = n / 2;
} while (n > 0);
while (builder.length() < getSwitchCount().getValue())
builder.append("0");
return builder.toString();
}
}
@@ -52,7 +52,7 @@ import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Fuse Holder (Panel)", category = "Electro-Mechanical", author = "Branislav Stojkovic",
description = "Panel mounted fuse holder", stretchable = false, zOrder = IDIYComponent.COMPONENT,
description = "Panel mounted fuse holder", zOrder = IDIYComponent.COMPONENT,
instanceNamePrefix = "FH", autoEdit = false)
public class FuseHolderPanel extends AbstractMultiPartComponent<String> {
@@ -69,7 +69,7 @@ public class FuseHolderPanel extends AbstractMultiPartComponent<String> {
private static Color BORDER_COLOR = BODY_COLOR.darker();
private static Color LABEL_COLOR = Color.white;
protected Point[] controlPoints = new Point[] {new Point(0, 0), new Point(0, 0)};
protected Point[] controlPoints = new Point[] { new Point(0, 0), new Point(0, 0) };
transient protected Area[] body;
protected String name;
protected String value = "";
@@ -330,5 +330,10 @@ public class FuseHolderPanel extends AbstractMultiPartComponent<String> {
public void setLabelColor(Color labelColor) {
this.labelColor = labelColor;
}
@Override
public boolean canPointMoveFreely(int pointIndex) {
return false;
}
}
@@ -50,7 +50,7 @@ import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "IEC Socket", category = "Electro-Mechanical", author = "Branislav Stojkovic",
description = "Panel mounted IEC power socket", stretchable = false, zOrder = IDIYComponent.COMPONENT,
description = "Panel mounted IEC power socket", zOrder = IDIYComponent.COMPONENT,
instanceNamePrefix = "IEC", autoEdit = false)
public class IECSocket extends AbstractMultiPartComponent<String> {
@@ -384,5 +384,10 @@ public class IECSocket extends AbstractMultiPartComponent<String> {
public void setBorderColor(Color borderColor) {
this.borderColor = borderColor;
}
@Override
public boolean canPointMoveFreely(int pointIndex) {
return false;
}
}
@@ -31,7 +31,7 @@ import java.awt.Rectangle;
import java.awt.geom.Area;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.Display;
import org.diylc.common.IPlugInPort;
@@ -54,7 +54,7 @@ import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Mini Relay", author = "Branislav Stojkovic", category = "Electro-Mechanical",
instanceNamePrefix = "RY", description = "Miniature PCB mount relay, like Omron G5V-1 or G5V-2",
stretchable = false, zOrder = IDIYComponent.COMPONENT)
zOrder = IDIYComponent.COMPONENT)
public class MiniRelay extends AbstractTransparentComponent<String> {
private static final long serialVersionUID = 1L;
@@ -302,7 +302,9 @@ public class MiniRelay extends AbstractTransparentComponent<String> {
}
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : BODY_COLOR);
g2d.fill(mainArea);
g2d.setComposite(oldComposite);
g2d.setComposite(oldComposite);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
int pinSize = (int) PIN_SIZE.convertToPixels() / 2 * 2;
@@ -423,12 +425,15 @@ public class MiniRelay extends AbstractTransparentComponent<String> {
updateControlPoints();
// Invalidate body
this.body = null;
}
@Override
public boolean canPointMoveFreely(int pointIndex) {
return false;
}
public static enum RelayType {
SPDT, DPDT;
}
public static enum RelaySize {
@@ -39,6 +39,7 @@ import org.diylc.components.AbstractTransparentComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.ISwitch;
import org.diylc.core.Project;
import org.diylc.core.Theme;
import org.diylc.core.VisibilityPolicy;
@@ -50,9 +51,9 @@ import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Mini Toggle Switch", category = "Electro-Mechanical", author = "Branislav Stojkovic",
description = "Panel mounted mini toggle switch", stretchable = false, zOrder = IDIYComponent.COMPONENT,
description = "Panel mounted mini toggle switch", zOrder = IDIYComponent.COMPONENT,
instanceNamePrefix = "SW", autoEdit = false)
public class MiniToggleSwitch extends AbstractTransparentComponent<ToggleSwitchType> {
public class MiniToggleSwitch extends AbstractTransparentComponent<ToggleSwitchType> implements ISwitch {
private static final long serialVersionUID = 1L;
@@ -88,12 +89,14 @@ public class MiniToggleSwitch extends AbstractTransparentComponent<ToggleSwitchT
case SPST:
controlPoints = new Point[] {firstPoint, new Point(firstPoint.x, firstPoint.y + spacing)};
break;
case SPDT:
case SPDT:
case SPDT_off:
controlPoints =
new Point[] {firstPoint, new Point(firstPoint.x, firstPoint.y + spacing),
new Point(firstPoint.x, firstPoint.y + 2 * spacing)};
break;
case DPDT:
case DPDT:
case DPDT_off:
controlPoints =
new Point[] {firstPoint, new Point(firstPoint.x, firstPoint.y + spacing),
new Point(firstPoint.x, firstPoint.y + 2 * spacing), new Point(firstPoint.x + spacing, firstPoint.y),
@@ -111,7 +114,8 @@ public class MiniToggleSwitch extends AbstractTransparentComponent<ToggleSwitchT
new Point(firstPoint.x + spacing, firstPoint.y + 2 * spacing),
new Point(firstPoint.x + spacing, firstPoint.y + 3 * spacing)};
break;
case _3PDT:
case _3PDT:
case _3PDT_off:
controlPoints =
new Point[] {firstPoint, new Point(firstPoint.x, firstPoint.y + spacing),
new Point(firstPoint.x, firstPoint.y + 2 * spacing), new Point(firstPoint.x + spacing, firstPoint.y),
@@ -121,7 +125,8 @@ public class MiniToggleSwitch extends AbstractTransparentComponent<ToggleSwitchT
new Point(firstPoint.x + 2 * spacing, firstPoint.y + spacing),
new Point(firstPoint.x + 2 * spacing, firstPoint.y + 2 * spacing)};
break;
case _4PDT:
case _4PDT:
case _4PDT_off:
controlPoints =
new Point[] {firstPoint, new Point(firstPoint.x, firstPoint.y + spacing),
new Point(firstPoint.x, firstPoint.y + 2 * spacing), new Point(firstPoint.x + spacing, firstPoint.y),
@@ -134,7 +139,8 @@ public class MiniToggleSwitch extends AbstractTransparentComponent<ToggleSwitchT
new Point(firstPoint.x + 3 * spacing, firstPoint.y + spacing),
new Point(firstPoint.x + 3 * spacing, firstPoint.y + 2 * spacing)};
break;
case _5PDT:
case _5PDT:
case _5PDT_off:
controlPoints =
new Point[] {firstPoint, new Point(firstPoint.x, firstPoint.y + spacing),
new Point(firstPoint.x, firstPoint.y + 2 * spacing), new Point(firstPoint.x + spacing, firstPoint.y),
@@ -236,7 +242,9 @@ public class MiniToggleSwitch extends AbstractTransparentComponent<ToggleSwitchT
public void setSpacing(Size spacing) {
this.spacing = spacing;
updateControlPoints();
updateControlPoints();
// Reset body shape.
body = null;
}
@Override
@@ -301,12 +309,14 @@ public class MiniToggleSwitch extends AbstractTransparentComponent<ToggleSwitchT
new RoundRectangle2D.Double(firstPoint.x - margin, firstPoint.y - margin, 2 * margin, 2 * margin
+ spacing, margin, margin);
break;
case SPDT:
case SPDT:
case SPDT_off:
body =
new RoundRectangle2D.Double(firstPoint.x - margin, firstPoint.y - margin, 2 * margin, 2 * margin + 2
* spacing, margin, margin);
break;
case DPDT:
case DPDT:
case DPDT_off:
body =
new RoundRectangle2D.Double(firstPoint.x - margin, firstPoint.y - margin, 2 * margin + spacing, 2
* margin + 2 * spacing, margin, margin);
@@ -316,17 +326,20 @@ public class MiniToggleSwitch extends AbstractTransparentComponent<ToggleSwitchT
new RoundRectangle2D.Double(firstPoint.x - margin, firstPoint.y - margin, 2 * margin + spacing, 2
* margin + 3 * spacing, margin, margin);
break;
case _3PDT:
case _3PDT:
case _3PDT_off:
body =
new RoundRectangle2D.Double(firstPoint.x - margin, firstPoint.y - margin, 2 * margin + 2 * spacing, 2
* margin + 2 * spacing, margin, margin);
break;
case _4PDT:
case _4PDT:
case _4PDT_off:
body =
new RoundRectangle2D.Double(firstPoint.x - margin, firstPoint.y - margin, 2 * margin + 3 * spacing, 2
* margin + 2 * spacing, margin, margin);
break;
case _5PDT:
case _5PDT:
case _5PDT_off:
body =
new RoundRectangle2D.Double(firstPoint.x - margin, firstPoint.y - margin, 2 * margin + 4 * spacing, 2
* margin + 2 * spacing, margin, margin);
@@ -377,5 +390,69 @@ public class MiniToggleSwitch extends AbstractTransparentComponent<ToggleSwitchT
public void setBorderColor(Color borderColor) {
this.borderColor = borderColor;
}
// switch stuff
//
// @Override
// public String getControlPointNodeName(int index) {
// // we don't want the switch to produce any nodes, it just makes connections
// return null;
// }
@Override
public boolean canPointMoveFreely(int pointIndex) {
return false;
}
@Override
public int getPositionCount() {
switch (switchType) {
case SPST:
case SPDT:
case DPDT:
case _3PDT:
case _4PDT:
case _5PDT:
return 2;
case _DP3T_mustang:
case SPDT_off:
case DPDT_off:
case _3PDT_off:
case _4PDT_off:
case _5PDT_off:
return 3;
}
return 2;
}
@Override
public String getPositionName(int position) {
if (switchType.name().endsWith("_off") && position == 2)
return "OFF";
return "ON" + Integer.toString(position + 1);
}
@Override
public boolean arePointsConnected(int index1, int index2, int position) {
switch (switchType) {
case SPST:
return position == 0;
case SPDT:
case DPDT:
case _3PDT:
case _4PDT:
case _5PDT:
return (index2 - index1) < 3 && index1 % 3 == position && index2 % 3 == position + 1;
case SPDT_off:
case DPDT_off:
case _3PDT_off:
case _4PDT_off:
case _5PDT_off:
return position != 2 && (index2 - index1) < 3 && index1 % 3 == position && index2 % 3 == position + 1;
case _DP3T_mustang:
return (index2 - index1) < 3 && index1 % 3 == 0 && index2 % 3 == position + 1;
}
return false;
}
}
@@ -33,6 +33,7 @@ import java.awt.geom.Ellipse2D;
import java.awt.geom.RoundRectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.awt.StringUtils;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
@@ -52,12 +53,12 @@ import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Open 1/4\" Jack", category = "Electro-Mechanical", author = "Branislav Stojkovic",
description = "Switchcraft-style open panel mount 1/4\" phono jack, stereo and mono", stretchable = false,
description = "Switchcraft-style open panel mount 1/4\" phono jack, stereo and mono",
zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "J")
public class OpenJack1_4 extends AbstractMultiPartComponent<String> {
private static final double RING_THETA = Math.PI * 0.795;
private static final double SLEEVE_THETA = Math.PI * 0.295;
private static final double SLEEVE_THETA = Math.PI * 0.29444444444;
private static final double SLEEVE_SWITCHED_THETA = Math.PI * 4 / 3;
private static final double SWITCH_THETA = Math.PI * 5 / 3;
@@ -76,8 +77,10 @@ public class OpenJack1_4 extends AbstractMultiPartComponent<String> {
private String value = "";
private Point[] controlPoints = new Point[] {new Point(0, 0), new Point(0, 0), new Point(0, 0)};
transient Area[] body;
private Orientation orientation = Orientation.DEFAULT;
transient Area[] body;
@Deprecated
private Orientation orientation = Orientation.DEFAULT;
private Integer angle = 0;
private OpenJackType type = OpenJackType.MONO;
private boolean showLabels = true;
@@ -86,7 +89,6 @@ public class OpenJack1_4 extends AbstractMultiPartComponent<String> {
updateControlPoints();
}
@SuppressWarnings("incomplete-switch")
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
@@ -162,40 +164,24 @@ public class OpenJack1_4 extends AbstractMultiPartComponent<String> {
Point sleeveLabel = new Point(0, 0);
ringTransform.transform(tipLabel, ringOrSwitchLabel);
sleeveTransform.transform(tipLabel, sleeveLabel);
double theta = 0;
// Rotate if needed
if (orientation != Orientation.DEFAULT) {
switch (orientation) {
case _90:
theta = Math.PI / 2;
break;
case _180:
theta = Math.PI;
break;
case _270:
theta = Math.PI * 3 / 2;
break;
}
}
if (theta != 0) {
AffineTransform rotation = AffineTransform.getRotateInstance(theta, controlPoints[0].x, controlPoints[0].y);
if (getTheta() != 0) {
AffineTransform rotation = AffineTransform.getRotateInstance(getTheta(), controlPoints[0].x, controlPoints[0].y);
rotation.transform(tipLabel, tipLabel);
rotation.transform(ringOrSwitchLabel, ringOrSwitchLabel);
rotation.transform(sleeveLabel, sleeveLabel);
}
drawCenteredText(g2d, "T", tipLabel.x, tipLabel.y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
drawCenteredText(g2d, "S", sleeveLabel.x, sleeveLabel.y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
StringUtils.drawCenteredText(g2d, "T", tipLabel.x, tipLabel.y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
StringUtils.drawCenteredText(g2d, "S", sleeveLabel.x, sleeveLabel.y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
if (getType() == OpenJackType.STEREO)
drawCenteredText(g2d, "R", ringOrSwitchLabel.x, ringOrSwitchLabel.y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
StringUtils.drawCenteredText(g2d, "R", ringOrSwitchLabel.x, ringOrSwitchLabel.y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
if (getType() == OpenJackType.SWITCHED)
drawCenteredText(g2d, "Sw", ringOrSwitchLabel.x, ringOrSwitchLabel.y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
StringUtils.drawCenteredText(g2d, "Sw", ringOrSwitchLabel.x, ringOrSwitchLabel.y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
}
drawSelectionOutline(g2d, componentState, outlineMode, project, drawingObserver);
}
@SuppressWarnings("incomplete-switch")
public Area[] getBody() {
if (body == null) {
body = new Area[4];
@@ -255,25 +241,9 @@ public class OpenJack1_4 extends AbstractMultiPartComponent<String> {
body[3] = ringOrSwitch;
}
double theta = 0;
// Rotate if needed
if (orientation != Orientation.DEFAULT) {
switch (orientation) {
case _90:
theta = Math.PI / 2;
break;
case _180:
theta = Math.PI;
break;
case _270:
theta = Math.PI * 3 / 2;
break;
}
}
// Rotate if needed
if (theta != 0) {
AffineTransform rotation = AffineTransform.getRotateInstance(theta, x, y);
if (getTheta() != 0) {
AffineTransform rotation = AffineTransform.getRotateInstance(getTheta(), x, y);
// Skip the last one because it's already rotated
for (int i = 0; i < body.length; i++) {
Shape shape = body[i];
@@ -288,7 +258,6 @@ public class OpenJack1_4 extends AbstractMultiPartComponent<String> {
return body;
}
@SuppressWarnings("incomplete-switch")
private void updateControlPoints() {
int x = controlPoints[0].x;
int y = controlPoints[0].y;
@@ -298,24 +267,12 @@ public class OpenJack1_4 extends AbstractMultiPartComponent<String> {
int centerY = y + springLength - holeToEdge;
AffineTransform.getRotateInstance(SLEEVE_THETA, x, centerY).transform(controlPoints[0], controlPoints[1]);
AffineTransform.getRotateInstance(RING_THETA, x, centerY).transform(controlPoints[0], controlPoints[2]);
AffineTransform.getRotateInstance(getType() == OpenJackType.SWITCHED ? SLEEVE_SWITCHED_THETA : SLEEVE_THETA, x, centerY).transform(controlPoints[0], controlPoints[1]);
AffineTransform.getRotateInstance(getType() == OpenJackType.SWITCHED ? SWITCH_THETA : RING_THETA, x, centerY).transform(controlPoints[0], controlPoints[2]);
// Rotate if needed
if (orientation != Orientation.DEFAULT) {
double theta = 0;
switch (orientation) {
case _90:
theta = Math.PI / 2;
break;
case _180:
theta = Math.PI;
break;
case _270:
theta = Math.PI * 3 / 2;
break;
}
AffineTransform rotation = AffineTransform.getRotateInstance(theta, x, y);
if (getTheta() != 0) {
AffineTransform rotation = AffineTransform.getRotateInstance(getTheta(), x, y);
for (Point point : controlPoints) {
rotation.transform(point, point);
}
@@ -386,17 +343,27 @@ public class OpenJack1_4 extends AbstractMultiPartComponent<String> {
public void setValue(String value) {
this.value = value;
}
@EditableProperty
public Orientation getOrientation() {
return orientation;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
updateControlPoints();
// Invalidate the body
body = null;
public Integer getAngle() {
if (angle == null) {
if (orientation != null && orientation != Orientation.DEFAULT)
angle = Integer.parseInt(orientation.name().replace("_", ""));
else
angle = 0;
}
return angle;
}
public void setAngle(Integer angle) {
this.angle = angle;
updateControlPoints();
// Invalidate the body
body = null;
}
protected double getTheta() {
return Math.toRadians(getAngle());
}
@EditableProperty
@@ -420,6 +387,24 @@ public class OpenJack1_4 extends AbstractMultiPartComponent<String> {
this.showLabels = showLabels;
}
@Override
public String getControlPointNodeName(int index) {
if (index == 0)
return "Tip";
if (index == 1)
return "Sleeve";
if (index == 2 && getType() == OpenJackType.STEREO)
return "Ring";
if (index == 2 && getType() == OpenJackType.SWITCHED)
return "Shunt";
return null;
}
@Override
public boolean canPointMoveFreely(int pointIndex) {
return false;
}
public enum OpenJackType {
MONO, STEREO, SWITCHED;
@@ -52,14 +52,16 @@ import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Pilot Lamp Holder", category = "Electro-Mechanical", author = "Branislav Stojkovic",
description = "Fender-style pilot bulb holder for T2 and T-3 ¼ miniature bayonet lamps", stretchable = false,
description = "Fender-style pilot bulb holder for T2 and T-3 ¼ miniature bayonet lamps",
zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "PL")
public class PilotLampHolder extends AbstractMultiPartComponent<String> {
private static final long serialVersionUID = 1L;
private static Color BASE_COLOR = Color.lightGray;
private static Color WAFER_COLOR = Color.decode("#CD8500");
private static Color WAFER_COLOR = Color.decode("#CD8500");
private static final double SLEEVE_THETA = Math.PI * 0.29444444444;
private static Size THREAD_OUTER_DIAMETER = new Size(11 / 16d, SizeUnit.in);
private static Size NUT_DIAMETER = new Size(14 / 16d, SizeUnit.in);
@@ -75,8 +77,10 @@ public class PilotLampHolder extends AbstractMultiPartComponent<String> {
private String value = "";
private Point[] controlPoints = new Point[] { new Point(0, 0), new Point(0, 0), new Point(0, 0), new Point(0, 0) };
transient Area[] body;
private Orientation orientation = Orientation.DEFAULT;
transient Area[] body;
@Deprecated
private Orientation orientation = Orientation.DEFAULT;
private Integer angle = 0;
public PilotLampHolder() {
super();
@@ -154,7 +158,6 @@ public class PilotLampHolder extends AbstractMultiPartComponent<String> {
drawSelectionOutline(g2d, componentState, outlineMode, project, drawingObserver);
}
@SuppressWarnings("incomplete-switch")
public Area[] getBody() {
if (body == null) {
body = new Area[6];
@@ -191,7 +194,7 @@ public class PilotLampHolder extends AbstractMultiPartComponent<String> {
Area sleeve =
new Area(new RoundRectangle2D.Double(x - springWidth / 2, y - holeToEdge, springWidth, springLength,
springWidth, springWidth));
sleeve.transform(AffineTransform.getRotateInstance(Math.PI * 0.295, x, centerY));
sleeve.transform(AffineTransform.getRotateInstance(SLEEVE_THETA, x, centerY));
sleeve.add(new Area(new Ellipse2D.Double(x - ringDiameter / 2, centerY - ringDiameter / 2, ringDiameter, ringDiameter)));
sleeve.subtract(new Area(new Ellipse2D.Double(x - innerDiameter / 2, centerY - innerDiameter / 2, innerDiameter, innerDiameter)));
@@ -230,26 +233,10 @@ public class PilotLampHolder extends AbstractMultiPartComponent<String> {
body[5] = link;
nut.subtract(link);
thread.subtract(link);
double theta = 0;
// Rotate if needed
if (orientation != Orientation.DEFAULT) {
switch (orientation) {
case _90:
theta = Math.PI / 2;
break;
case _180:
theta = Math.PI;
break;
case _270:
theta = Math.PI * 3 / 2;
break;
}
}
thread.subtract(link);
if (theta != 0) {
AffineTransform rotation = AffineTransform.getRotateInstance(theta, x, y);
if (getTheta() != 0) {
AffineTransform rotation = AffineTransform.getRotateInstance(getTheta(), x, y);
for (Area area : body) {
if (area != null)
area.transform(rotation);
@@ -264,7 +251,6 @@ public class PilotLampHolder extends AbstractMultiPartComponent<String> {
return body;
}
@SuppressWarnings("incomplete-switch")
private void updateControlPoints() {
int x = controlPoints[0].x;
int y = controlPoints[0].y;
@@ -283,20 +269,8 @@ public class PilotLampHolder extends AbstractMultiPartComponent<String> {
rotation.transform(controlPoints[2], controlPoints[3]);
// Rotate if needed
if (orientation != Orientation.DEFAULT) {
double theta = 0;
switch (orientation) {
case _90:
theta = Math.PI / 2;
break;
case _180:
theta = Math.PI;
break;
case _270:
theta = Math.PI * 3 / 2;
break;
}
rotation = AffineTransform.getRotateInstance(theta, x, y);
if (getTheta() != 0) {
rotation = AffineTransform.getRotateInstance(getTheta(), x, y);
for (Point point : controlPoints) {
rotation.transform(point, point);
}
@@ -412,15 +386,30 @@ public class PilotLampHolder extends AbstractMultiPartComponent<String> {
this.value = value;
}
@EditableProperty
public Orientation getOrientation() {
return orientation;
@EditableProperty
public Integer getAngle() {
if (angle == null) {
if (orientation != null && orientation != Orientation.DEFAULT)
angle = Integer.parseInt(orientation.name().replace("_", ""));
else
angle = 0;
}
return angle;
}
public void setAngle(Integer angle) {
this.angle = angle;
updateControlPoints();
// Invalidate the body
body = null;
}
@Override
public boolean canPointMoveFreely(int pointIndex) {
return false;
}
protected double getTheta() {
return Math.toRadians(getAngle());
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
updateControlPoints();
// Invalidate the body
body = null;
}
}
@@ -32,6 +32,7 @@ import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.awt.StringUtils;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
@@ -50,7 +51,7 @@ import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Plastic DC Jack", category = "Electro-Mechanical", author = "Branislav Stojkovic",
description = "Panel mount plastic DC jack", stretchable = false, zOrder = IDIYComponent.COMPONENT,
description = "Panel mount plastic DC jack", zOrder = IDIYComponent.COMPONENT,
instanceNamePrefix = "J", autoEdit = false)
public class PlasticDCJack extends AbstractMultiPartComponent<String> {
@@ -182,9 +183,9 @@ public class PlasticDCJack extends AbstractMultiPartComponent<String> {
int spacing = (int) SPACING.convertToPixels();
g2d.setColor(MARKING_COLOR);
g2d.setFont(project.getFont().deriveFont(12f));
drawCenteredText(g2d, getPolarity() == DCPolarity.CENTER_NEGATIVE ? "+" : "-", controlPoints[0].x,
StringUtils.drawCenteredText(g2d, getPolarity() == DCPolarity.CENTER_NEGATIVE ? "+" : "-", controlPoints[0].x,
controlPoints[0].y - spacing * 7 / 16, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
drawCenteredText(g2d, getPolarity() == DCPolarity.CENTER_NEGATIVE ? "_" : "+", controlPoints[2].x,
StringUtils.drawCenteredText(g2d, getPolarity() == DCPolarity.CENTER_NEGATIVE ? "_" : "+", controlPoints[2].x,
controlPoints[2].y - spacing * 3 / 4, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
}
@@ -261,5 +262,10 @@ public class PlasticDCJack extends AbstractMultiPartComponent<String> {
public void setPolarity(DCPolarity polarity) {
this.polarity = polarity;
}
@Override
public boolean canPointMoveFreely(int pointIndex) {
return false;
}
}
@@ -52,8 +52,7 @@ import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "RCA Jack", category = "Electro-Mechanical", author = "Branislav Stojkovic",
description = "Panel mount RCA phono jack socket", stretchable = false,
zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "J")
description = "Panel mount RCA phono jack socket", zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "J")
public class RCAJack extends AbstractMultiPartComponent<String> {
private static final long serialVersionUID = 1L;
@@ -314,5 +313,15 @@ public class RCAJack extends AbstractMultiPartComponent<String> {
updateControlPoints();
// Invalidate the body
body = null;
}
@Override
public String getControlPointNodeName(int index) {
return getName() + (index == 0 ? "Tip" : "Sleeve");
}
@Override
public boolean canPointMoveFreely(int pointIndex) {
return false;
}
}
@@ -1,473 +0,0 @@
/*
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.components.electromechanical;
//
//import java.awt.AlphaComposite;
//import java.awt.Color;
//import java.awt.Composite;
//import java.awt.FontMetrics;
//import java.awt.Graphics2D;
//import java.awt.Point;
//import java.awt.Rectangle;
//import java.awt.geom.Area;
//import java.awt.geom.Rectangle2D;
//import java.awt.geom.RoundRectangle2D;
//
//import org.diylc.appframework.miscutils.ConfigurationManager;
//import org.diylc.common.Display;
//import org.diylc.common.IPlugInPort;
//import org.diylc.common.ObjectCache;
//import org.diylc.common.Orientation;
//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.Theme;
//import org.diylc.core.VisibilityPolicy;
//import org.diylc.core.annotations.ComponentDescriptor;
//import org.diylc.core.annotations.EditableProperty;
//import org.diylc.core.annotations.KeywordPolicy;
//import org.diylc.core.measures.Size;
//import org.diylc.core.measures.SizeUnit;
//import org.diylc.utils.Constants;
//
//@ComponentDescriptor(name = "Subminiature DIL Relay", author = "Branislav Stojkovic", category = "Electromechanical",
// instanceNamePrefix = "RY", description = "Subminiature DIL relay with one or two poles", stretchable = false,
// zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE)
//public class SubminiatureDILRelay extends AbstractTransparentComponent<String> {
//
// private static final long serialVersionUID = 1L;
//
// public static Color BODY_COLOR = Color.decode("#EDEDD5");
// public static Color BORDER_COLOR = BODY_COLOR.darker();
// public static Color PIN_COLOR = Color.decode("#00B2EE");
// public static Color PIN_BORDER_COLOR = PIN_COLOR.darker();
// public static Color INDENT_COLOR = Color.gray.darker();
// public static Color LABEL_COLOR = Color.darkGray;
// public static int EDGE_RADIUS = 6;
// public static Size PIN_SIZE = new Size(0.04d, SizeUnit.in);
// public static Size INDENT_SIZE = new Size(0.05d, SizeUnit.in);
//
// public static Size PIN_SPACING = new Size(0.2d, SizeUnit.in);
// public static Size ROW_SPACING = new Size(0.3d, SizeUnit.in);
// public static Size SECTION_SPACING = new Size(0.3d, SizeUnit.in);
//
// private String value = "";
// private Orientation orientation = Orientation.DEFAULT;
// private PinCount pinCount = PinCount._4;
// private Size pinSpacing = PIN_SPACING;
// private Size rowSpacing = ROW_SPACING;
// private Size sectionSpacing = SECTION_SPACING;
// private Point[] controlPoints = new Point[] {new Point(0, 0)};
// protected Display display = Display.NAME;
// private Color bodyColor = BODY_COLOR;
// private Color borderColor = BORDER_COLOR;
// private Color labelColor = LABEL_COLOR;
// private Color indentColor = INDENT_COLOR;
// transient private Area[] body;
//
// public SubminiatureDILRelay() {
// super();
// updateControlPoints();
// }
//
// @EditableProperty
// public String getValue() {
// return value;
// }
//
// public void setValue(String value) {
// this.value = value;
// }
//
// @EditableProperty
// public Orientation getOrientation() {
// return orientation;
// }
//
// public void setOrientation(Orientation orientation) {
// this.orientation = orientation;
// updateControlPoints();
// // Reset body shape.
// body = null;
// }
//
// @EditableProperty(name = "Contacts")
// public PinCount getPinCount() {
// return pinCount;
// }
//
// public void setPinCount(PinCount pinCount) {
// this.pinCount = pinCount;
// updateControlPoints();
// // Reset body shape;
// body = null;
// }
//
// @EditableProperty(name = "Pin spacing")
// public Size getPinSpacing() {
// return pinSpacing;
// }
//
// public void setPinSpacing(Size pinSpacing) {
// this.pinSpacing = pinSpacing;
// updateControlPoints();
// // Reset body shape;
// body = null;
// }
//
// @EditableProperty(name = "Row spacing")
// public Size getRowSpacing() {
// return rowSpacing;
// }
//
// public void setRowSpacing(Size rowSpacing) {
// this.rowSpacing = rowSpacing;
// updateControlPoints();
// // Reset body shape;
// body = null;
// }
//
// @EditableProperty(name = "Section spacing")
// public Size getSectionSpacing() {
// return sectionSpacing;
// }
//
// public void setSectionSpacing(Size sectionSpacing) {
// this.sectionSpacing = sectionSpacing;
// updateControlPoints();
// // Reset body shape;
// body = null;
// }
//
// @EditableProperty
// public Display getDisplay() {
// if (display == null) {
// display = Display.VALUE;
// }
// return display;
// }
//
// public void setDisplay(Display display) {
// this.display = display;
// }
//
// @Override
// public int getControlPointCount() {
// return controlPoints.length;
// }
//
// @Override
// public Point getControlPoint(int index) {
// return controlPoints[index];
// }
//
// @Override
// public boolean isControlPointSticky(int index) {
// return true;
// }
//
// @Override
// public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
// return VisibilityPolicy.NEVER;
// }
//
// @Override
// public void setControlPoint(Point point, int index) {
// controlPoints[index].setLocation(point);
// body = null;
// }
//
// private void updateControlPoints() {
// Point firstPoint = controlPoints[0];
// controlPoints = new Point[pinCount.getValue() * 2];
// controlPoints[0] = firstPoint;
// int pinSpacing = (int) this.pinSpacing.convertToPixels();
// int sectionSpacing = (int) this.sectionSpacing.convertToPixels();
// int rowSpacing = (int) this.rowSpacing.convertToPixels();
// // Update control points.
// int dx1;
// int dy1;
// int dx2;
// int dy2;
// for (int i = 0; i < pinCount.getValue(); i++) {
// int spacing = i == pinCount.getValue() - 1 ? sectionSpacing + (i - 1) * pinSpacing : i * pinSpacing;
// switch (orientation) {
// case DEFAULT:
// dx1 = 0;
// dy1 = spacing;
// dx2 = rowSpacing;
// dy2 = spacing;
// break;
// case _90:
// dx1 = -spacing;
// dy1 = 0;
// dx2 = -spacing;
// dy2 = rowSpacing;
// break;
// case _180:
// dx1 = 0;
// dy1 = -spacing;
// dx2 = -rowSpacing;
// dy2 = -spacing;
// break;
// case _270:
// dx1 = spacing;
// dy1 = 0;
// dx2 = spacing;
// dy2 = -rowSpacing;
// break;
// default:
// throw new RuntimeException("Unexpected orientation: " + orientation);
// }
// controlPoints[i] = new Point(firstPoint.x + dx1, firstPoint.y + dy1);
// controlPoints[i + pinCount.getValue()] = new Point(firstPoint.x + dx2, firstPoint.y + dy2);
// }
// }
//
// public Area[] getBody() {
// if (body == null) {
// body = new Area[2];
//
// int pinSize = (int) PIN_SIZE.convertToPixels();
//
// int minX = Integer.MAX_VALUE;
// int maxX = Integer.MIN_VALUE;
// int minY = Integer.MAX_VALUE;
// int maxY = Integer.MIN_VALUE;
// for (int i = 0; i < this.controlPoints.length; i++) {
// if (this.controlPoints[i].x > maxX)
// maxX = this.controlPoints[i].x;
// if (this.controlPoints[i].x < minX)
// minX = this.controlPoints[i].x;
// if (this.controlPoints[i].y > maxY)
// maxY = this.controlPoints[i].y;
// if (this.controlPoints[i].y < minY)
// minY = this.controlPoints[i].y;
// }
// int width = maxX - minX;
// int height = maxY - minY;
//
// Area indentation = null;
// int indentationSize = getClosestOdd(INDENT_SIZE.convertToPixels());
// switch (orientation) {
// case DEFAULT:
// indentation =
// new Area(new Rectangle2D.Double(minX + width / 2 - indentationSize / 2, minY - indentationSize / 2
// - pinSize, indentationSize, indentationSize));
// break;
// case _90:
// indentation =
// new Area(new Rectangle2D.Double(minX + width - indentationSize / 2 + pinSize, minY + height / 2
// - indentationSize / 2, indentationSize, indentationSize));
// break;
// case _180:
// indentation =
// new Area(new Rectangle2D.Double(minX + width / 2 - indentationSize / 2, minY + height - indentationSize
// / 2 + pinSize, indentationSize, indentationSize));
// break;
// case _270:
// indentation =
// new Area(new Rectangle2D.Double(minX - indentationSize / 2 - pinSize, minY + height / 2 - indentationSize
// / 2, indentationSize, indentationSize));
// break;
// default:
// throw new RuntimeException("Unexpected orientation: " + orientation);
// }
//
// body[0] =
// new Area(new RoundRectangle2D.Double(minX - pinSize, minY - pinSize, width + 2 * pinSize, height + 2
// * pinSize, EDGE_RADIUS, EDGE_RADIUS));
// body[1] = indentation;
// if (indentation != null) {
// indentation.intersect(body[0]);
// }
// }
// return body;
// }
//
// @Override
// public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
// IDrawingObserver drawingObserver) {
// if (checkPointsClipped(g2d.getClip())) {
// return;
// }
// Area mainArea = getBody()[0];
//
// Composite oldComposite = g2d.getComposite();
// if (alpha < MAX_ALPHA) {
// g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA));
// }
// g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : getBodyColor());
// g2d.fill(mainArea);
// g2d.setComposite(oldComposite);
//
// Color finalBorderColor;
// if (outlineMode) {
// Theme theme =
// (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
// finalBorderColor =
// componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
// : theme.getOutlineColor();
// } else {
// finalBorderColor =
// componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
// : getBorderColor();
// }
// g2d.setColor(finalBorderColor);
// g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
// if (outlineMode) {
// Area area = new Area(mainArea);
// area.subtract(getBody()[1]);
// g2d.draw(area);
// } else {
// g2d.draw(mainArea);
// if (getBody()[1] != null) {
// g2d.setColor(getIndentColor());
// g2d.fill(getBody()[1]);
// }
// }
//
// if (!outlineMode) {
// int pinSize = (int) PIN_SIZE.convertToPixels() / 2 * 2;
// for (Point point : controlPoints) {
// g2d.setColor(PIN_COLOR);
// g2d.fillOval(point.x - pinSize / 2, point.y - pinSize / 2, pinSize, pinSize);
// g2d.setColor(PIN_BORDER_COLOR);
// g2d.drawOval(point.x - pinSize / 2, point.y - pinSize / 2, pinSize, pinSize);
// }
// }
//
// // Draw label.
// g2d.setFont(LABEL_FONT);
// Color finalLabelColor;
// if (outlineMode) {
// Theme theme =
// (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
// finalLabelColor =
// componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
// : theme.getOutlineColor();
// } else {
// finalLabelColor =
// componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
// : getLabelColor();
// }
// g2d.setColor(finalLabelColor);
// FontMetrics fontMetrics = g2d.getFontMetrics(g2d.getFont());
// String label = "";
// label = (getDisplay() == Display.NAME) ? getName() : getValue();
// if (getDisplay() == Display.NONE) {
// label = "";
// }
// if (getDisplay() == Display.BOTH) {
// label = getName() + " " + (getValue() == null ? "" : getValue().toString());
// }
// Rectangle2D rect = fontMetrics.getStringBounds(label, g2d);
// int textHeight = (int) (rect.getHeight());
// int textWidth = (int) (rect.getWidth());
// // Center text horizontally and vertically
// Rectangle bounds = mainArea.getBounds();
// int x = bounds.x + (bounds.width - textWidth) / 2;
// int y = bounds.y + (bounds.height - textHeight) / 2 + fontMetrics.getAscent();
// g2d.drawString(label, x, y);
// }
//
// @Override
// public void drawIcon(Graphics2D g2d, int width, int height) {
// int radius = 6 * width / 32;
// g2d.setColor(BODY_COLOR);
// g2d.fillRoundRect(width / 6, 1, 4 * width / 6, height - 4, radius, radius);
// g2d.setColor(BORDER_COLOR);
// g2d.drawRoundRect(width / 6, 1, 4 * width / 6, height - 4, radius, radius);
// int pinSize = 2 * width / 32;
// g2d.setColor(PIN_COLOR);
// for (int i = 0; i < 4; i++) {
// if (i == 1)
// continue;
// g2d.fillOval(width / 3 - pinSize, (height / 5) * (i + 1) - 1, pinSize, pinSize);
// g2d.fillOval(2 * width / 3 + 1, (height / 5) * (i + 1) - 1, pinSize, pinSize);
// }
// }
//
// @EditableProperty(name = "Body")
// public Color getBodyColor() {
// if (bodyColor == null) {
// bodyColor = BODY_COLOR;
// }
// return bodyColor;
// }
//
// public void setBodyColor(Color bodyColor) {
// this.bodyColor = bodyColor;
// }
//
// @EditableProperty(name = "Border")
// public Color getBorderColor() {
// if (borderColor == null) {
// borderColor = BORDER_COLOR;
// }
// return borderColor;
// }
//
// public void setBorderColor(Color borderColor) {
// this.borderColor = borderColor;
// }
//
// @EditableProperty(name = "Label")
// public Color getLabelColor() {
// if (labelColor == null) {
// labelColor = LABEL_COLOR;
// }
// return labelColor;
// }
//
// public void setLabelColor(Color labelColor) {
// this.labelColor = labelColor;
// }
//
// @EditableProperty(name = "Indent")
// public Color getIndentColor() {
// if (indentColor == null) {
// indentColor = INDENT_COLOR;
// }
// return indentColor;
// }
//
// public void setIndentColor(Color indentColor) {
// this.indentColor = indentColor;
// }
//
// public static enum PinCount {
//
// _3, _4, _5;
//
// @Override
// public String toString() {
// return name().replace("_", "").concat(" per side");
// }
//
// public int getValue() {
// return Integer.parseInt(name().replace("_", ""));
// }
// }
//}
@@ -23,10 +23,16 @@ package org.diylc.components.electromechanical;
public enum ToggleSwitchType {
SPST, SPDT, DPDT, _DP3T_mustang, _3PDT, _4PDT, _5PDT;
SPST, SPDT, DPDT, _DP3T_mustang, _3PDT, _4PDT, _5PDT, SPDT_off, DPDT_off, _3PDT_off, _4PDT_off, _5PDT_off;
@Override
public String toString() {
return name().replace("_", "");
String name = name();
if (name.startsWith("_"))
name = name.substring(1);
name = name.replace("_", " ");
name = name.replace("mustang", "");
name = name.replace("off", " (Center OFF)");
return name;
}
}
@@ -0,0 +1,256 @@
/*
*
* 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.components.guitar;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.awt.StringUtils;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.Orientation;
import org.diylc.common.OrientationHV;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.Project;
import org.diylc.core.Theme;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
public abstract class AbstractGuitarPickup extends AbstractTransparentComponent<String> {
private static final long serialVersionUID = 1L;
protected static Size POINT_SPACING = new Size(0.1d, SizeUnit.in);
protected static final int TERMINAL_FONT_SIZE = 11;
protected String value = "";
protected Orientation orientation = Orientation.DEFAULT;
protected transient Shape[] body;
protected Point controlPoint = new Point(0, 0);
protected Point[] controlPoints = new Point[] {new Point(0, 0), new Point(0, 0), new Point(0, 0), new Point(0, 0)};
protected Polarity polarity = Polarity.North;
protected Color labelColor;
public AbstractGuitarPickup() {
updateControlPoints();
}
protected void drawlTerminalLabels(Graphics2D g2d, Color color, Project project) {
Point[] points = getControlPoints();
g2d.setColor(color);
g2d.setFont(project.getFont().deriveFont(TERMINAL_FONT_SIZE * 1f));
int dx = 0;
int dy = 0;
switch (orientation) {
case DEFAULT:
dx = getControlPointDirection() == OrientationHV.HORIZONTAL ? 0 : (int) (TERMINAL_FONT_SIZE * 0.8);
dy = getControlPointDirection() == OrientationHV.HORIZONTAL ? -TERMINAL_FONT_SIZE : 0;
break;
case _90:
dx = getControlPointDirection() == OrientationHV.HORIZONTAL ? TERMINAL_FONT_SIZE : 0;
dy = getControlPointDirection() == OrientationHV.HORIZONTAL ? 0 : (int) (TERMINAL_FONT_SIZE * 0.8);
break;
case _180:
dx = getControlPointDirection() == OrientationHV.HORIZONTAL ? 0 : -(int) (TERMINAL_FONT_SIZE * 0.8);
dy = getControlPointDirection() == OrientationHV.HORIZONTAL ? TERMINAL_FONT_SIZE : 0;
break;
case _270:
dx = getControlPointDirection() == OrientationHV.HORIZONTAL ? -TERMINAL_FONT_SIZE : 0;
dy = getControlPointDirection() == OrientationHV.HORIZONTAL ? 0 : -(int) (TERMINAL_FONT_SIZE * 0.8);
break;
}
StringUtils.drawCenteredText(g2d, "N", (points[0].x + points[1].x) / 2 + dx, (points[0].y + points[1].y) / 2 + dy, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
StringUtils.drawCenteredText(g2d, "S", (points[2].x + points[3].x) / 2 + dx, (points[2].y + points[3].y) / 2 + dy, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
}
protected void drawMainLabel(Graphics2D g2d, Project project, boolean outlineMode, ComponentState componentState) {
Color finalLabelColor;
if (outlineMode) {
Theme theme =
(Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalLabelColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: theme.getOutlineColor();
} else {
finalLabelColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: getLabelColor();
}
g2d.setColor(finalLabelColor);
g2d.setFont(project.getFont().deriveFont(Font.BOLD));
Rectangle bounds = getBody()[0].getBounds();
AffineTransform originalTx = g2d.getTransform();
g2d.translate(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2);
if (orientation == Orientation._90)
g2d.rotate(Math.PI / 2);
else if (orientation == Orientation._270){
g2d.rotate(-Math.PI / 2);
}
g2d.translate(0, getMainLabelYOffset());
StringUtils.drawCenteredText(g2d, getName(), 0, 0, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
g2d.setTransform(originalTx);
}
protected abstract Shape[] getBody();
public abstract boolean isHumbucker();
protected int getMainLabelYOffset() {
return 0;
}
@EditableProperty(name = "Model")
@Override
public String getValue() {
return value;
}
@Override
public void setValue(String value) {
this.value = value;
}
@EditableProperty
public Orientation getOrientation() {
return orientation;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
// Invalidate the body
body = null;
updateControlPoints();
}
protected Point[] getControlPoints() {
if (controlPoints == null) {
controlPoints =
new Point[] {controlPoint, new Point(controlPoint.x, controlPoint.y),
new Point(controlPoint.x, controlPoint.y), new Point(controlPoint.x, controlPoint.y)};
updateControlPoints();
}
return controlPoints;
}
@Override
public int getControlPointCount() {
return getControlPoints().length;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.ALWAYS;
}
@Override
public Point getControlPoint(int index) {
return getControlPoints()[index];
}
@Override
public void setControlPoint(Point point, int index) {
getControlPoints()[index].setLocation(point);
// Invalidate the body
body = null;
}
@Override
public boolean canPointMoveFreely(int pointIndex) {
return false;
}
@EditableProperty
public Polarity getPolarity() {
if (polarity == null)
polarity = Polarity.North;
return polarity;
}
public void setPolarity(Polarity polarity) {
this.polarity = polarity;
// Invalidate the body
body = null;
}
@EditableProperty(name = "Label")
public Color getLabelColor() {
if (labelColor == null)
labelColor = LABEL_COLOR;
return labelColor;
}
public void setLabelColor(Color labelColor) {
this.labelColor = labelColor;
}
protected abstract OrientationHV getControlPointDirection();
@SuppressWarnings("incomplete-switch")
protected void updateControlPoints() {
Point[] points = getControlPoints();
int pointSpacing = (int) POINT_SPACING.convertToPixels();
int dx = getControlPointDirection() == OrientationHV.HORIZONTAL ? 1 : 0;
int dy = getControlPointDirection() == OrientationHV.HORIZONTAL ? 0 : 1;
if (orientation != Orientation.DEFAULT) {
switch (orientation) {
case _90:
dx = getControlPointDirection() == OrientationHV.HORIZONTAL ? 0 : -1;
dy = getControlPointDirection() == OrientationHV.HORIZONTAL ? -1 : 0;
break;
case _180:
dx = getControlPointDirection() == OrientationHV.HORIZONTAL ? -1 : 0;
dy = getControlPointDirection() == OrientationHV.HORIZONTAL ? 0 : -1;
break;
case _270:
dx = getControlPointDirection() == OrientationHV.HORIZONTAL ? 0 : 1;
dy = getControlPointDirection() == OrientationHV.HORIZONTAL ? 1 : 0;
break;
}
}
points[1].setLocation(points[0].x + dx * pointSpacing, points[0].y + dy * pointSpacing);
points[2]
.setLocation(points[0].x + 2 * dx * pointSpacing, points[0].y + 2 * dy * pointSpacing);
points[3]
.setLocation(points[0].x + 3 * dx * pointSpacing, points[0].y + 3 * dy * pointSpacing);
}
public enum Polarity {
North, South, Humbucking;
}
}
@@ -0,0 +1,140 @@
/*
*
* 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.components.guitar;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import org.diylc.awt.StringUtils;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.OrientationHV;
import org.diylc.common.VerticalAlignment;
import org.diylc.core.Project;
import org.diylc.core.VisibilityPolicy;
public abstract class AbstractSingleOrHumbuckerPickup extends AbstractGuitarPickup {
private static final long serialVersionUID = 1L;
@Override
protected void drawlTerminalLabels(Graphics2D g2d, Color color, Project project) {
Point[] points = getControlPoints();
g2d.setColor(color);
g2d.setFont(project.getFont().deriveFont(TERMINAL_FONT_SIZE * 1f));
int dx = 0;
int dy = 0;
switch (orientation) {
case DEFAULT:
dx = getControlPointDirection() == OrientationHV.HORIZONTAL ? 0 : (int) (TERMINAL_FONT_SIZE * 0.8);
dy = getControlPointDirection() == OrientationHV.HORIZONTAL ? -TERMINAL_FONT_SIZE : 0;
break;
case _90:
dx = getControlPointDirection() == OrientationHV.HORIZONTAL ? TERMINAL_FONT_SIZE : 0;
dy = getControlPointDirection() == OrientationHV.HORIZONTAL ? 0 : (int) (TERMINAL_FONT_SIZE * 0.8);
break;
case _180:
dx = getControlPointDirection() == OrientationHV.HORIZONTAL ? 0 : -(int) (TERMINAL_FONT_SIZE * 0.8);
dy = getControlPointDirection() == OrientationHV.HORIZONTAL ? TERMINAL_FONT_SIZE : 0;
break;
case _270:
dx = getControlPointDirection() == OrientationHV.HORIZONTAL ? -TERMINAL_FONT_SIZE : 0;
dy = getControlPointDirection() == OrientationHV.HORIZONTAL ? 0 : -(int) (TERMINAL_FONT_SIZE * 0.8);
break;
}
if (getPolarity() == Polarity.North || getPolarity() == Polarity.South) {
StringUtils.drawCenteredText(g2d, getPolarity().name().substring(0, 1), (points[1].x + points[2].x) / 2 + dx, (points[1].y + points[2].y) / 2 + dy, HorizontalAlignment.CENTER,
VerticalAlignment.CENTER);
} else {
StringUtils.drawCenteredText(g2d, "N", (points[0].x + points[1].x) / 2 + dx, (points[0].y + points[1].y) / 2 + dy, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
StringUtils.drawCenteredText(g2d, "S", (points[2].x + points[3].x) / 2 + dx, (points[2].y + points[3].y) / 2 + dy, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
}
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
if (getPolarity() != Polarity.Humbucking && (index == 0 || index == 3))
return VisibilityPolicy.NEVER;
return VisibilityPolicy.ALWAYS;
}
@Override
public boolean isControlPointSticky(int index) {
if (getPolarity() != Polarity.Humbucking && (index == 0 || index == 3))
return false;
return true;
}
@Override
public String getControlPointNodeName(int index) {
switch (index) {
case 0:
if (getPolarity() != Polarity.Humbucking)
return null;
return"North Start";
case 1:
if (getPolarity() == Polarity.South)
return "South Start";
if (getPolarity() == Polarity.North)
return "North Start";
return "North Finish";
case 2:
if (getPolarity() == Polarity.South)
return "South Finish";
if (getPolarity() == Polarity.North)
return "North Finish";
return "South Start";
case 3:
if (getPolarity() != Polarity.Humbucking)
return null;
return "South Finish";
}
return null;
}
@Override
public String getInternalLinkName(int index1, int index2) {
switch (getPolarity()) {
case Humbucking:
if (index1 == 0 && index2 == 1)
return Polarity.North.toString() + "->";
else if (index1 == 1 && index2 == 0)
return Polarity.North.toString() + "<-";
else if (index1 == 2 && index2 == 3)
return Polarity.South.toString() + "->";
else if (index1 == 3 && index2 == 2)
return Polarity.South.toString() + "<-";
break;
case North:
case South:
if (index1 == 1 && index2 == 2)
return getPolarity().toString() + "->";
else if (index1 == 2 && index2 == 1)
return getPolarity().toString() + "<-";
}
return null;
}
public boolean isHumbucker() {
return getPolarity() == Polarity.Humbucking;
}
}
File diff suppressed because it is too large Load Diff
@@ -26,7 +26,6 @@ import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
@@ -34,18 +33,15 @@ import java.awt.geom.Ellipse2D;
import java.awt.geom.RoundRectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.common.OrientationHV;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.Theme;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.annotations.KeywordPolicy;
@@ -54,15 +50,14 @@ import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Jazz Bass Pickup", category = "Guitar", author = "Branislav Stojkovic",
description = "Single coil pickup for Jazz Bass and similar guitars", stretchable = false,
description = "Single coil pickup for Jazz Bass and similar guitars",
zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "PKP", autoEdit = false,
keywordPolicy = KeywordPolicy.SHOW_TAG, keywordTag = "Guitar Wiring Diagram")
public class JazzBassPickup extends AbstractTransparentComponent<String> {
public class JazzBassPickup extends AbstractSingleOrHumbuckerPickup {
private static final long serialVersionUID = 1L;
private static Color BODY_COLOR = Color.decode("#333333");;
private static Color POINT_COLOR = Color.gray;
private static Color BODY_COLOR = Color.decode("#333333");
private static Size WIDTH = new Size(0.73, SizeUnit.in);
private static Size LENGTH = new Size(4.1, SizeUnit.in);
@@ -78,10 +73,6 @@ public class JazzBassPickup extends AbstractTransparentComponent<String> {
private static Size POLE_SPACING = new Size(0.85d, SizeUnit.in);
private static Size POLE_SPACING_MINOR = new Size(0.28d, SizeUnit.in);
private String value = "";
private Point controlPoint = new Point(0, 0);
transient Shape[] body;
private Orientation orientation = Orientation.DEFAULT;
private Color color = BODY_COLOR;
private Color poleColor = METAL_COLOR;
@@ -98,9 +89,7 @@ public class JazzBassPickup extends AbstractTransparentComponent<String> {
}
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : color);
g2d.fill(body[0]);
g2d.fill(body[1]);
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : POINT_COLOR);
g2d.fill(body[2]);
g2d.fill(body[1]);
g2d.setComposite(oldComposite);
Color finalBorderColor;
@@ -127,32 +116,37 @@ public class JazzBassPickup extends AbstractTransparentComponent<String> {
g2d.draw(body[3]);
}
Color finalLabelColor;
if (outlineMode) {
Theme theme =
(Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalLabelColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: theme.getOutlineColor();
} else {
finalLabelColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: LABEL_COLOR;
}
g2d.setColor(finalLabelColor);
g2d.setFont(project.getFont());
Rectangle bounds = body[0].getBounds();
drawCenteredText(g2d, value, bounds.x + bounds.width / 2, bounds.y + bounds.height / 2, HorizontalAlignment.CENTER,
VerticalAlignment.CENTER);
// Color finalLabelColor;
// if (outlineMode) {
// Theme theme =
// (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
// finalLabelColor =
// componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
// : theme.getOutlineColor();
// } else {
// finalLabelColor =
// componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
// : LABEL_COLOR;
// }
// g2d.setColor(finalLabelColor);
// g2d.setFont(project.getFont());
// Rectangle bounds = body[0].getBounds();
// drawCenteredText(g2d, value, bounds.x + bounds.width / 2, bounds.y + bounds.height / 2, HorizontalAlignment.CENTER,
// VerticalAlignment.CENTER);
drawMainLabel(g2d, project, outlineMode, componentState);
drawlTerminalLabels(g2d, finalBorderColor, project);
}
@SuppressWarnings("incomplete-switch")
@SuppressWarnings("incomplete-switch")
@Override
public Shape[] getBody() {
if (body == null) {
body = new Shape[4];
int x = controlPoint.x;
int y = controlPoint.y;
Point[] points = getControlPoints();
int x = points[0].x;
int y = points[0].y;
int width = (int) WIDTH.convertToPixels();
int length = (int) LENGTH.convertToPixels();
int edgeRadius = (int) EDGE_RADIUS.convertToPixels();
@@ -164,12 +158,12 @@ public class JazzBassPickup extends AbstractTransparentComponent<String> {
int lipHoleSpacing = getClosestOdd(LIP_HOLE_SPACING.convertToPixels());
body[0] =
new Area(new RoundRectangle2D.Double(x + pointMargin - length, y - pointMargin, length, width, edgeRadius,
new Area(new RoundRectangle2D.Double(x - length, y - pointMargin, length, width, edgeRadius,
edgeRadius));
Area lip = new Area(new Ellipse2D.Double(-lipRadius / 2, -lipRadius / 2, lipRadius, lipRadius));
lip.subtract(new Area(new Ellipse2D.Double(-lipHoleSize / 2, -lipHoleSpacing - lipHoleSize / 2, lipHoleSize, lipHoleSize)));
lip.transform(AffineTransform.getTranslateInstance(x + pointMargin - length / 2 - lipSpacing / 2, y - pointMargin));
lip.transform(AffineTransform.getTranslateInstance(x - length / 2 - lipSpacing / 2, y - pointMargin));
body[1] = new Area(lip);
lip.transform(AffineTransform.getTranslateInstance(lipSpacing, 0));
@@ -191,11 +185,11 @@ public class JazzBassPickup extends AbstractTransparentComponent<String> {
Area poleArea = new Area();
for (int i = 0; i < 4; i++) {
Ellipse2D pole =
new Ellipse2D.Double(x + pointMargin - length + poleMargin + i * poleSpacing - poleSize / 2 - poleSpacingMinor / 2, y
new Ellipse2D.Double(x - length + poleMargin + i * poleSpacing - poleSize / 2 - poleSpacingMinor / 2, y
- pointMargin - poleSize / 2 + width / 2, poleSize, poleSize);
poleArea.add(new Area(pole));
pole =
new Ellipse2D.Double(x + pointMargin - length + poleMargin + i * poleSpacing - poleSize / 2 + poleSpacingMinor / 2, y
new Ellipse2D.Double(x - length + poleMargin + i * poleSpacing - poleSize / 2 + poleSpacingMinor / 2, y
- pointMargin - poleSize / 2 + width / 2, poleSize, poleSize);
poleArea.add(new Area(pole));
}
@@ -224,7 +218,17 @@ public class JazzBassPickup extends AbstractTransparentComponent<String> {
}
}
return body;
}
}
@Override
protected int getMainLabelYOffset() {
return (int) (WIDTH.convertToPixels() / 2 - 20);
}
@Override
protected OrientationHV getControlPointDirection() {
return OrientationHV.VERTICAL;
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
@@ -256,57 +260,8 @@ public class JazzBassPickup extends AbstractTransparentComponent<String> {
for (int i = 0; i < 4; i++) {
g2d.fillOval((width - poleSize) / 2, (height - poleSpacing) / 2 + (i * poleSpacing / 3), poleSize, poleSize);
}
}
@Override
public int getControlPointCount() {
return 1;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.WHEN_SELECTED;
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public Point getControlPoint(int index) {
return controlPoint;
}
@Override
public void setControlPoint(Point point, int index) {
this.controlPoint.setLocation(point);
// Invalidate the body
body = null;
}
@EditableProperty(name = "Model")
@Override
public String getValue() {
return value;
}
@Override
public void setValue(String value) {
this.value = value;
}
@EditableProperty
public Orientation getOrientation() {
return orientation;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
// Invalidate the body
body = null;
}
}
@EditableProperty
public Color getColor() {
return color;
@@ -325,5 +280,5 @@ public class JazzBassPickup extends AbstractTransparentComponent<String> {
public void setPoleColor(Color poleColor) {
this.poleColor = poleColor;
}
}
}
@@ -31,7 +31,7 @@ import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
@@ -40,6 +40,7 @@ import org.diylc.components.AbstractTransparentComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.ISwitch;
import org.diylc.core.Project;
import org.diylc.core.Theme;
import org.diylc.core.VisibilityPolicy;
@@ -50,9 +51,9 @@ import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "LP Toggle Switch", category = "Guitar", author = "Branislav Stojkovic",
description = "Les Paul style 3 position toggle switch", stretchable = false, zOrder = IDIYComponent.COMPONENT,
description = "Les Paul style 3 position toggle switch", zOrder = IDIYComponent.COMPONENT,
instanceNamePrefix = "SW")
public class LPSwitch extends AbstractTransparentComponent<String> {
public class LPSwitch extends AbstractTransparentComponent<String> implements ISwitch {
private static final long serialVersionUID = 1L;
@@ -141,19 +142,19 @@ public class LPSwitch extends AbstractTransparentComponent<String> {
int waferThickness = getClosestOdd(WAFER_THICKNESS.convertToPixels());
Rectangle2D ground =
new Rectangle2D.Double(x - waferThickness / 2, y, waferThickness, baseLength + (length - baseLength) / 2);
new Rectangle2D.Double(x - waferThickness / 2, y, waferThickness - 1, baseLength + (length - baseLength) / 2);
body[0] = new Area(ground);
int bodyY = y + (length - baseLength) / 2;
Area waferArea = new Area(new Rectangle2D.Double(x - waferThickness * 3 / 2, bodyY, waferThickness, baseLength));
waferArea.add(new Area(new Rectangle2D.Double(x + waferThickness / 2, bodyY, waferThickness, baseLength)));
Area waferArea = new Area();//new Area(new Rectangle2D.Double(x - waferThickness * 3 / 2, bodyY, waferThickness, baseLength));
waferArea.add(new Area(new Rectangle2D.Double(x + waferThickness / 2, bodyY, waferThickness *3, baseLength)));
waferArea.add(new Area(new Rectangle2D.Double(x - waferThickness * 5 / 2, bodyY, waferThickness, baseLength)));
waferArea.add(new Area(new Rectangle2D.Double(x + waferThickness * 3 / 2, bodyY, waferThickness, baseLength)));
waferArea.add(new Area(new Rectangle2D.Double(x - waferThickness * 7 / 2, bodyY, waferThickness, baseLength)));
waferArea.add(new Area(new Rectangle2D.Double(x + waferThickness * 5 / 2, bodyY, waferThickness, baseLength)));
waferArea.add(new Area(new Rectangle2D.Double(x - waferThickness * 7 / 2, bodyY, waferThickness * 3, baseLength)));
// waferArea.add(new Area(new Rectangle2D.Double(x + waferThickness * 5 / 2, bodyY, waferThickness, baseLength)));
body[1] = waferArea;
@@ -280,7 +281,7 @@ public class LPSwitch extends AbstractTransparentComponent<String> {
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.NEVER;
return VisibilityPolicy.ALWAYS;
}
@Override
@@ -298,6 +299,11 @@ public class LPSwitch extends AbstractTransparentComponent<String> {
this.controlPoints[index].setLocation(point);
// Invalidate the body
body = null;
}
@Override
public boolean canPointMoveFreely(int pointIndex) {
return false;
}
@Override
@@ -320,5 +326,44 @@ public class LPSwitch extends AbstractTransparentComponent<String> {
updateControlPoints();
// Invalidate the body
body = null;
}
// @Override
// public String getControlPointNodeName(int index) {
// // we don't want the switch to produce any nodes, it just makes connections
// return null;
// }
//
// switch stuff
@Override
public int getPositionCount() {
return 3;
}
@Override
public String getPositionName(int position) {
switch (position) {
case 0:
return "Treble";
case 1:
return "Middle";
case 2:
return "Rhythm";
}
return null;
}
@Override
public boolean arePointsConnected(int index1, int index2, int position) {
switch (position) {
case 0:
return index1 == 1 && index2 == 2;
case 1:
return index1 > 0;
case 2:
return index1 == 2 && index2 == 3;
}
return false;
}
}
@@ -21,46 +21,49 @@
*/
package org.diylc.components.guitar;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
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.Theme;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.annotations.KeywordPolicy;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.ISwitch;
import org.diylc.core.Project;
import org.diylc.core.Theme;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.annotations.KeywordPolicy;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Lever Switch", category = "Guitar", author = "Branislav Stojkovic",
description = "Strat-style lever switch", stretchable = false, zOrder = IDIYComponent.COMPONENT,
description = "Strat-style lever switch", zOrder = IDIYComponent.COMPONENT,
instanceNamePrefix = "SW", keywordPolicy = KeywordPolicy.SHOW_TAG,
keywordTag = "Guitar Wiring Diagram")
public class LeverSwitch extends AbstractTransparentComponent<String> {
public class LeverSwitch extends AbstractTransparentComponent<String> implements ISwitch {
private static final long serialVersionUID = 1L;
private static Color BASE_COLOR = Color.lightGray;
private static Color WAFER_COLOR = Color.decode("#CD8500");
private static Color WAFER_COLOR = Color.decode("#CD8500");
private static Color LUG_COLOR = METAL_COLOR;
private static Color COMMON_LUG_COLOR = Color.decode("#FF9999");
private static Size BASE_WIDTH = new Size(10d, SizeUnit.mm);
private static Size BASE_LENGTH = new Size(47.5d, SizeUnit.mm);
@@ -77,7 +80,8 @@ public class LeverSwitch extends AbstractTransparentComponent<String> {
private Point[] controlPoints = new Point[] {new Point(0, 0)};
transient Shape[] body;
private Orientation orientation = Orientation.DEFAULT;
private LeverSwitchType type = LeverSwitchType.DP3T;
private LeverSwitchType type = LeverSwitchType.DP3T;
private Boolean highlightCommon;
public LeverSwitch() {
super();
@@ -132,16 +136,20 @@ public class LeverSwitch extends AbstractTransparentComponent<String> {
g2d.draw(body[1]);
g2d.setColor(METAL_COLOR);
g2d.setColor(LUG_COLOR);
g2d.fill(body[2]);
g2d.setColor(METAL_COLOR.darker());
g2d.draw(body[2]);
g2d.setColor(LUG_COLOR.darker());
g2d.draw(body[2]);
g2d.setColor(COMMON_LUG_COLOR);
g2d.fill(body[3]);
g2d.setColor(COMMON_LUG_COLOR.darker());
g2d.draw(body[3]);
}
@SuppressWarnings("incomplete-switch")
public Shape[] getBody() {
if (body == null) {
body = new Shape[3];
body = new Shape[4];
int x = controlPoints[0].x;
int y = controlPoints[0].y;
@@ -154,10 +162,18 @@ public class LeverSwitch extends AbstractTransparentComponent<String> {
int waferThickness = (int) WAFER_THICKNESS.convertToPixels();
int terminalSpacing = (int) TERMINAL_SPACING.convertToPixels();
int terminalLength = getClosestOdd(TERMINAL_LENGTH.convertToPixels());
int terminalWidth = getClosestOdd(TERMINAL_WIDTH.convertToPixels());
int terminalWidth = getClosestOdd(TERMINAL_WIDTH.convertToPixels());
int yOffset;
if (type == LeverSwitchType.DP3T || type == LeverSwitchType.DP4T || type == LeverSwitchType.DP3T_5pos) {
x += terminalLength;
yOffset = 7;
} else {
yOffset = 12;
}
int baseX = x - terminalLength / 2 - waferSpacing;
int baseY = y - (baseLength - terminalSpacing * (type == LeverSwitchType.DP3T ? 7 : 12)) / 2;
int baseY = y - (baseLength - terminalSpacing * yOffset) / 2;
Area baseArea = new Area(new Rectangle2D.Double(baseX, baseY, baseWidth, baseLength));
baseArea.subtract(new Area(new Ellipse2D.Double(baseX + baseWidth / 2 - holeSize / 2, baseY
+ (baseLength - holeSpacing) / 2 - holeSize / 2, holeSize, holeSize)));
@@ -167,12 +183,12 @@ public class LeverSwitch extends AbstractTransparentComponent<String> {
Area waferArea =
new Area(new Rectangle2D.Double(x - terminalLength / 2 - waferThickness / 2, y
- (waferLength - terminalSpacing * (type == LeverSwitchType.DP3T ? 7 : 12)) / 2, waferThickness,
- (waferLength - terminalSpacing * yOffset) / 2, waferThickness,
waferLength));
if (type == LeverSwitchType._4P5T) {
waferArea.add(new Area(new Rectangle2D.Double(x - terminalLength / 2 - waferThickness / 2 + waferSpacing, y
- (waferLength - terminalSpacing * (type == LeverSwitchType.DP3T ? 7 : 12)) / 2, waferThickness,
- (waferLength - terminalSpacing * 12) / 2, waferThickness,
waferLength)));
}
body[1] = waferArea;
@@ -193,8 +209,10 @@ public class LeverSwitch extends AbstractTransparentComponent<String> {
}
}
Area terminalArea = new Area();
for (Point point : controlPoints) {
Area terminalArea = new Area();
Area commonTerminalArea = new Area();
for (int i = 0; i < controlPoints.length; i++) {
Point point = controlPoints[i];
Area terminal =
new Area(new RoundRectangle2D.Double(point.x - terminalLength / 2, point.y - terminalWidth / 2,
terminalLength, terminalWidth, terminalWidth / 2, terminalWidth / 2));
@@ -205,15 +223,23 @@ public class LeverSwitch extends AbstractTransparentComponent<String> {
AffineTransform rotation = AffineTransform.getRotateInstance(theta, point.x, point.y);
terminal.transform(rotation);
}
terminalArea.add(terminal);
terminalArea.add(terminal);
if (getHighlightCommon() &&
(((type == LeverSwitchType.DP3T || type == LeverSwitchType.DP3T_5pos) && (i == 1 || i == 6)) ||
(type == LeverSwitchType.DP4T && (i == 1 || i == 8)) ||
((type == LeverSwitchType._4P5T || type == LeverSwitchType.DP5T) && (i == 0 || i == 11 || i == 12 || i == 23))))
commonTerminalArea.add(terminal);
else
terminalArea.add(terminal);
}
body[2] = terminalArea;
body[2] = terminalArea;
body[3] = commonTerminalArea;
// Rotate if needed
if (theta != 0) {
AffineTransform rotation = AffineTransform.getRotateInstance(theta, x, y);
// Skip the last one because it's already rotated
for (int i = 0; i < body.length - 1; i++) {
AffineTransform rotation = AffineTransform.getRotateInstance(theta, controlPoints[0].x, controlPoints[0].y);
// Skip the last two because terminals are already rotated
for (int i = 0; i < body.length - 2; i++) {
Shape shape = body[i];
Area area = (Area) shape;
area.transform(rotation);
@@ -232,11 +258,18 @@ public class LeverSwitch extends AbstractTransparentComponent<String> {
int terminalLength = (int) TERMINAL_LENGTH.convertToPixels();
switch (type) {
case DP3T:
case DP3T:
case DP3T_5pos:
controlPoints = new Point[8];
for (int i = 0; i < 8; i++) {
controlPoints[i] = new Point(x - (i % 2 == 1 ? terminalLength : 0), y + i * terminalSpacing);
controlPoints[i] = new Point(x + (i % 2 == 1 ? terminalLength : 0), y + i * terminalSpacing);
}
break;
case DP4T:
controlPoints = new Point[10];
for (int i = 0; i < 10; i++) {
controlPoints[i] = new Point(x + (i % 2 == 1 ? terminalLength : 0), y + i * terminalSpacing);
}
break;
case DP5T:
controlPoints = new Point[12];
@@ -365,10 +398,23 @@ public class LeverSwitch extends AbstractTransparentComponent<String> {
updateControlPoints();
// Invalidate the body
body = null;
}
}
@EditableProperty(name = "Mark Common Lugs")
public Boolean getHighlightCommon() {
if (highlightCommon == null)
highlightCommon = true;
return highlightCommon;
}
public void setHighlightCommon(Boolean highlightCommon) {
this.highlightCommon = highlightCommon;
body = null;
}
public enum LeverSwitchType {
DP3T("DP3T (Standard Strat)"), _4P5T("4P5T (Super/Mega)"), DP5T("DP5T");
DP3T("DP3T (Standard 3-Position Strat)"), DP3T_5pos("DP3T (Standard 5-Position Strat)"), _4P5T("4P5T (Super/Mega)"), DP4T("DP4T (4-Position Tele)"), DP5T("DP5T");
private String title;
@@ -380,5 +426,59 @@ public class LeverSwitch extends AbstractTransparentComponent<String> {
public String toString() {
return title;
}
}
// @Override
// public String getControlPointNodeName(int index) {
// // we don't want the switch to produce any nodes, it just makes connections
// return null;
// }
// switch stuff
@Override
public int getPositionCount() {
switch (type) {
case DP3T:
return 3;
case DP4T:
return 4;
case DP3T_5pos:
case DP5T:
case _4P5T:
return 5;
}
return 0;
}
@Override
public String getPositionName(int position) {
return Integer.toString(position + 1);
}
@Override
public boolean arePointsConnected(int index1, int index2, int position) {
switch (type) {
case DP3T:
return (index1 == 1 && index2 == index1 + 2 * (position + 1)) || (index2 == 6 && index2 == index1 + 2 * (3 - position));
case DP4T:
return (index1 == 1 && index2 == index1 + 2 * (position + 1)) || (index2 == 8 && index2 == index1 + 2 * (4 - position));
case DP3T_5pos:
if (position % 2 == 0)
return (index1 == 1 && index2 == index1 + position + 2) || (index2 == 6 && index2 == index1 + 6 - position);
else
return (index2 == 6 && (index1 == 2 || (index1 == 0 && position == 1) || (index1 == 4 && position == 3))) ||
(index1 == 1 && (index2 == 5 || (index2 == 3 && position == 1) || (index2 == 7 && position == 3)));
case DP5T:
return (index1 == 0 || index2 == 11) && index2 - index1 == position + 1;
case _4P5T:
return (index1 == 0 || index1 == 12 || index2 == 11 || index2 == 23) && index2 - index1 == position + 1;
}
return false;
}
@Override
public boolean canPointMoveFreely(int pointIndex) {
return false;
}
}
@@ -21,49 +21,46 @@
*/
package org.diylc.components.guitar;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.RoundRectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
import org.diylc.common.VerticalAlignment;
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.Theme;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.annotations.KeywordPolicy;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.RoundRectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
import org.diylc.common.OrientationHV;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.Theme;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.annotations.KeywordPolicy;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "P-90 Single Coil Pickup", category = "Guitar", author = "Branislav Stojkovic",
description = "Single coil P-90 guitar pickup, both \"dog ear\" and \"soap bar\"", stretchable = false,
description = "Single coil P-90 guitar pickup, both \"dog ear\" and \"soap bar\"",
zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "PKP", autoEdit = false,
keywordPolicy = KeywordPolicy.SHOW_TAG, keywordTag = "Guitar Wiring Diagram")
public class P90Pickup extends AbstractTransparentComponent<String> {
public class P90Pickup extends AbstractSingleOrHumbuckerPickup {
private static final long serialVersionUID = 1L;
private static Color BODY_COLOR = Color.decode("#D8C989");;
private static Color POINT_COLOR = Color.darkGray;
// private static Color POINT_COLOR = Color.darkGray;
// dog ear
private static Size DOG_EAR_WIDTH = new Size(41d, SizeUnit.mm);
@@ -77,20 +74,21 @@ public class P90Pickup extends AbstractTransparentComponent<String> {
private static Size SOAP_BAR_EDGE_RADIUS = new Size(8d, SizeUnit.mm);
private static Size LIP_RADIUS = new Size(10d, SizeUnit.mm);
private static Size POINT_MARGIN = new Size(1.5d, SizeUnit.mm);
private static Size POINT_MARGIN = new Size(3.5d, SizeUnit.mm);
private static Size POINT_SIZE = new Size(2d, SizeUnit.mm);
private static Size LIP_HOLE_SIZE = new Size(2.5d, SizeUnit.mm);
private static Size LIP_HOLE_SPACING = new Size(97d, SizeUnit.mm);
private static Size POLE_SIZE = new Size(4d, SizeUnit.mm);
private static Size POLE_SPACING = new Size(11.68d, SizeUnit.mm);
private String value = "";
private Point controlPoint = new Point(0, 0);
transient Shape[] body;
private Orientation orientation = Orientation.DEFAULT;
private static Size POLE_SPACING = new Size(11.68d, SizeUnit.mm);
private Color color = BODY_COLOR;
private P90Type type = P90Type.DOG_EAR;
private Color poleColor = METAL_COLOR;
private Color poleColor = METAL_COLOR;
@Override
protected OrientationHV getControlPointDirection() {
return OrientationHV.VERTICAL;
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
@@ -107,8 +105,8 @@ public class P90Pickup extends AbstractTransparentComponent<String> {
g2d.fill(body[0]);
if (body[1] != null)
g2d.fill(body[1]);
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : POINT_COLOR);
g2d.fill(body[2]);
// g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : POINT_COLOR);
// g2d.fill(body[2]);
g2d.setComposite(oldComposite);
Color finalBorderColor;
@@ -136,32 +134,70 @@ public class P90Pickup extends AbstractTransparentComponent<String> {
g2d.draw(body[3]);
}
Color finalLabelColor;
if (outlineMode) {
Theme theme =
(Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalLabelColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: theme.getOutlineColor();
} else {
finalLabelColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: LABEL_COLOR;
}
g2d.setColor(finalLabelColor);
g2d.setFont(project.getFont());
Rectangle bounds = body[0].getBounds();
drawCenteredText(g2d, value, bounds.x + bounds.width / 2, bounds.y + bounds.height / 2, HorizontalAlignment.CENTER,
VerticalAlignment.CENTER);
// Color finalLabelColor;
// if (outlineMode) {
// Theme theme =
// (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
// finalLabelColor =
// componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
// : theme.getOutlineColor();
// } else {
// finalLabelColor =
// componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
// : LABEL_COLOR;
// }
// g2d.setColor(finalLabelColor);
// g2d.setFont(project.getFont());
// Rectangle bounds = body[0].getBounds();
// drawCenteredText(g2d, value, bounds.x + bounds.width / 2, bounds.y + bounds.height / 2, HorizontalAlignment.CENTER,
// VerticalAlignment.CENTER);
drawMainLabel(g2d, project, outlineMode, componentState);
drawlTerminalLabels(g2d, finalBorderColor, project);
// terminal labels
// Point[] points = getControlPoints();
// g2d.setColor(finalBorderColor);
//
// g2d.setFont(project.getFont().deriveFont(TERMINAL_FONT_SIZE * 1f));
// int dx = 0;
// int dy = 0;
// switch (orientation) {
// case DEFAULT:
// dx = (int) (TERMINAL_FONT_SIZE * 0.8);
// dy = 0;
// break;
// case _90:
// dx = 0;
// dy = (int) (TERMINAL_FONT_SIZE * 0.8);
// break;
// case _180:
// dx = -(int) (TERMINAL_FONT_SIZE * 0.8);
// dy = 0;
// break;
// case _270:
// dx = 0;
// dy = -(int) (TERMINAL_FONT_SIZE * 0.8);
// break;
// }
//
// if (getPolarity() == Polarity.North || getPolarity() == Polarity.South) {
// drawCenteredText(g2d, getPolarity().name().substring(0, 1), (points[1].x + points[2].x) / 2 + dx, (points[1].y + points[2].y) / 2 + dy, HorizontalAlignment.CENTER,
// VerticalAlignment.CENTER);
// } else {
// drawCenteredText(g2d, "N", (points[0].x + points[1].x) / 2 + dx, (points[0].y + points[1].y) / 2 + dy, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
// drawCenteredText(g2d, "S", (points[2].x + points[3].x) / 2 + dx, (points[2].y + points[3].y) / 2 + dy, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
// }
}
@SuppressWarnings("incomplete-switch")
@SuppressWarnings("incomplete-switch")
@Override
public Shape[] getBody() {
if (body == null) {
body = new Shape[4];
int x = controlPoint.x;
int y = controlPoint.y;
Point[] points = getControlPoints();
int x = points[0].x;
int y = points[0].y;
int width = (int) getType().getWidth().convertToPixels();
int length = (int) getType().getLength().convertToPixels();
int edgeRadius = (int) getType().getEdgeRadius().convertToPixels();
@@ -173,7 +209,7 @@ public class P90Pickup extends AbstractTransparentComponent<String> {
int lipHoleSpacing = getClosestOdd(LIP_HOLE_SPACING.convertToPixels());
body[0] =
new Area(new RoundRectangle2D.Double(x + pointMargin - length, y - pointMargin, length, width, edgeRadius,
new Area(new RoundRectangle2D.Double(x /*+ pointMargin*/ - length, y - pointMargin, length, width, edgeRadius,
edgeRadius));
if (getType() == P90Type.DOG_EAR) {
@@ -183,18 +219,18 @@ public class P90Pickup extends AbstractTransparentComponent<String> {
Area leftEar = new Area(roundRect);
leftEar.transform(AffineTransform.getRotateInstance(Math.PI / 4));
leftEar.transform(AffineTransform.getScaleInstance(1.1, 1.45));
leftEar.transform(AffineTransform.getTranslateInstance(x + pointMargin - length, y - pointMargin + width / 2));
leftEar.transform(AffineTransform.getTranslateInstance(x /*+ pointMargin*/ - length, y - pointMargin + width / 2));
leftEar.subtract((Area) body[0]);
Area rightEar = new Area(roundRect);
rightEar.transform(AffineTransform.getRotateInstance(Math.PI / 4));
rightEar.transform(AffineTransform.getScaleInstance(1.1, 1.45));
rightEar.transform(AffineTransform.getTranslateInstance(x + pointMargin, y - pointMargin + width / 2));
rightEar.transform(AffineTransform.getTranslateInstance(x /*+ pointMargin*/, y - pointMargin + width / 2));
rightEar.subtract((Area) body[0]);
Area lipArea = leftEar;
lipArea.add(rightEar);
lipArea.subtract(new Area(new Ellipse2D.Double(x + pointMargin - length / 2 - lipHoleSpacing / 2 - lipHoleSize
lipArea.subtract(new Area(new Ellipse2D.Double(x /*+ pointMargin*/ - length / 2 - lipHoleSpacing / 2 - lipHoleSize
/ 2, y - pointMargin + width / 2 - lipHoleSize / 2, lipHoleSize, lipHoleSize)));
lipArea.subtract(new Area(new Ellipse2D.Double(x + pointMargin - length / 2 + lipHoleSpacing / 2 - lipHoleSize
lipArea.subtract(new Area(new Ellipse2D.Double(x /*+ pointMargin*/ - length / 2 + lipHoleSpacing / 2 - lipHoleSize
/ 2, y - pointMargin + width / 2 - lipHoleSize / 2, lipHoleSize, lipHoleSize)));
body[1] = lipArea;
@@ -208,7 +244,7 @@ public class P90Pickup extends AbstractTransparentComponent<String> {
Area poleArea = new Area();
for (int i = 0; i < 6; i++) {
Ellipse2D pole =
new Ellipse2D.Double(x + pointMargin - length + poleMargin + i * poleSpacing - poleSize / 2, y
new Ellipse2D.Double(x /*+ pointMargin*/ - length + poleMargin + i * poleSpacing - poleSize / 2, y
- pointMargin - poleSize / 2 + width / 2, poleSize, poleSize);
poleArea.add(new Area(pole));
}
@@ -237,6 +273,11 @@ public class P90Pickup extends AbstractTransparentComponent<String> {
}
}
return body;
}
@Override
protected int getMainLabelYOffset() {
return (int) (getType().getWidth().convertToPixels() / 2 - 20);
}
@Override
@@ -282,55 +323,6 @@ public class P90Pickup extends AbstractTransparentComponent<String> {
body = null;
}
@Override
public int getControlPointCount() {
return 1;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.WHEN_SELECTED;
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public Point getControlPoint(int index) {
return controlPoint;
}
@Override
public void setControlPoint(Point point, int index) {
this.controlPoint.setLocation(point);
// Invalidate the body
body = null;
}
@EditableProperty(name = "Model")
@Override
public String getValue() {
return value;
}
@Override
public void setValue(String value) {
this.value = value;
}
@EditableProperty
public Orientation getOrientation() {
return orientation;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
// Invalidate the body
body = null;
}
@EditableProperty
public Color getColor() {
return color;
@@ -349,7 +341,7 @@ public class P90Pickup extends AbstractTransparentComponent<String> {
public void setPoleColor(Color poleColor) {
this.poleColor = poleColor;
}
}
public enum P90Type {
DOG_EAR("Dog Ear", DOG_EAR_LENGTH, DOG_EAR_WIDTH, DOG_EAR_EDGE_RADIUS), SOAP_BAR("Soap Bar", SOAP_BAR_LENGTH,
@@ -26,7 +26,6 @@ import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
@@ -34,18 +33,15 @@ import java.awt.geom.Ellipse2D;
import java.awt.geom.RoundRectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.common.OrientationHV;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.Theme;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.annotations.KeywordPolicy;
@@ -54,15 +50,14 @@ import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "P- Bass Pickup", category = "Guitar", author = "Branislav Stojkovic",
description = "Split-coil pickup for P-Bass and similar guitars", stretchable = false,
description = "Split-coil pickup for P-Bass and similar guitars",
zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "PKP", autoEdit = false,
keywordPolicy = KeywordPolicy.SHOW_TAG, keywordTag = "Guitar Wiring Diagram")
public class PBassPickup extends AbstractTransparentComponent<String> {
public class PBassPickup extends AbstractSingleOrHumbuckerPickup {
private static final long serialVersionUID = 1L;
private static Color BODY_COLOR = Color.decode("#333333");;
private static Color POINT_COLOR = Color.gray;
private static Size WIDTH = new Size(1.1, SizeUnit.in);
private static Size LENGTH = new Size(2.2, SizeUnit.in);
@@ -76,10 +71,6 @@ public class PBassPickup extends AbstractTransparentComponent<String> {
private static Size POLE_SIZE = new Size(4d, SizeUnit.mm);
private static Size POLE_SPACING = new Size(0.38d, SizeUnit.in);
private String value = "";
private Point controlPoint = new Point(0, 0);
transient Shape[] body;
private Orientation orientation = Orientation.DEFAULT;
private Color color = BODY_COLOR;
private Color poleColor = METAL_COLOR;
@@ -97,8 +88,6 @@ public class PBassPickup extends AbstractTransparentComponent<String> {
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : color);
g2d.fill(body[0]);
g2d.fill(body[1]);
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : POINT_COLOR);
g2d.fill(body[2]);
g2d.setComposite(oldComposite);
Color finalBorderColor;
@@ -125,32 +114,37 @@ public class PBassPickup extends AbstractTransparentComponent<String> {
g2d.draw(body[3]);
}
Color finalLabelColor;
if (outlineMode) {
Theme theme =
(Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalLabelColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: theme.getOutlineColor();
} else {
finalLabelColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: LABEL_COLOR;
}
g2d.setColor(finalLabelColor);
g2d.setFont(project.getFont());
Rectangle bounds = body[0].getBounds();
drawCenteredText(g2d, value, bounds.x + bounds.width / 2, bounds.y + bounds.height / 2, HorizontalAlignment.CENTER,
VerticalAlignment.CENTER);
// Color finalLabelColor;
// if (outlineMode) {
// Theme theme =
// (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
// finalLabelColor =
// componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
// : theme.getOutlineColor();
// } else {
// finalLabelColor =
// componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
// : LABEL_COLOR;
// }
// g2d.setColor(finalLabelColor);
// g2d.setFont(project.getFont());
// Rectangle bounds = body[0].getBounds();
// drawCenteredText(g2d, value, bounds.x + bounds.width / 2, bounds.y + bounds.height / 2, HorizontalAlignment.CENTER,
// VerticalAlignment.CENTER);
drawMainLabel(g2d, project, outlineMode, componentState);
drawlTerminalLabels(g2d, finalBorderColor, project);
}
@SuppressWarnings("incomplete-switch")
@SuppressWarnings("incomplete-switch")
@Override
public Shape[] getBody() {
if (body == null) {
body = new Shape[4];
int x = controlPoint.x;
int y = controlPoint.y;
Point[] points = getControlPoints();
int x = points[0].x;
int y = points[0].y;
int width = (int) WIDTH.convertToPixels();
int length = (int) LENGTH.convertToPixels();
int edgeRadius = (int) EDGE_RADIUS.convertToPixels();
@@ -161,16 +155,16 @@ public class PBassPickup extends AbstractTransparentComponent<String> {
int lipHoleSpacing = getClosestOdd(LIP_HOLE_SPACING.convertToPixels());
body[0] =
new Area(new RoundRectangle2D.Double(x + pointMargin - length, y - pointMargin, length, width, edgeRadius,
new Area(new RoundRectangle2D.Double(x - length, y - pointMargin, length, width, edgeRadius,
edgeRadius));
Area lip = new Area(new Ellipse2D.Double(-lipRadius / 2, -lipRadius / 2, lipRadius, lipRadius));
lip.subtract(new Area(new Ellipse2D.Double(-lipHoleSize / 2 + lipHoleSpacing, -lipHoleSize / 2, lipHoleSize, lipHoleSize)));
lip.transform(AffineTransform.getTranslateInstance(x + pointMargin, y - pointMargin + width / 2));
lip.transform(AffineTransform.getTranslateInstance(x, y - pointMargin + width / 2));
Area lip2 = new Area(new Ellipse2D.Double(-lipRadius / 2, -lipRadius / 2, lipRadius, lipRadius));
lip2 = new Area(new Ellipse2D.Double(-lipRadius / 2, -lipRadius / 2, lipRadius, lipRadius));
lip2.subtract(new Area(new Ellipse2D.Double(-lipHoleSize / 2 - lipHoleSpacing, -lipHoleSize / 2, lipHoleSize, lipHoleSize)));
lip2.transform(AffineTransform.getTranslateInstance(x + pointMargin - length, y - pointMargin + width / 2));
lip2.transform(AffineTransform.getTranslateInstance(x - length, y - pointMargin + width / 2));
lip.add(lip2);
body[1] = new Area(lip);
@@ -185,7 +179,7 @@ public class PBassPickup extends AbstractTransparentComponent<String> {
Area poleArea = new Area();
for (int i = 0; i < 4; i++) {
Ellipse2D pole =
new Ellipse2D.Double(x + pointMargin - length + poleMargin + i * poleSpacing - poleSize / 2, y
new Ellipse2D.Double(x - length + poleMargin + i * poleSpacing - poleSize / 2, y
- pointMargin - poleSize / 2 + width / 2, poleSize, poleSize);
poleArea.add(new Area(pole));
}
@@ -214,6 +208,11 @@ public class PBassPickup extends AbstractTransparentComponent<String> {
}
}
return body;
}
@Override
protected int getMainLabelYOffset() {
return (int) (WIDTH.convertToPixels() / 2 - 20);
}
@Override
@@ -246,53 +245,9 @@ public class PBassPickup extends AbstractTransparentComponent<String> {
}
}
@Override
public int getControlPointCount() {
return 1;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.WHEN_SELECTED;
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public Point getControlPoint(int index) {
return controlPoint;
}
@Override
public void setControlPoint(Point point, int index) {
this.controlPoint.setLocation(point);
// Invalidate the body
body = null;
}
@EditableProperty(name = "Model")
@Override
public String getValue() {
return value;
}
@Override
public void setValue(String value) {
this.value = value;
}
@EditableProperty
public Orientation getOrientation() {
return orientation;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
// Invalidate the body
body = null;
@Override
protected OrientationHV getControlPointDirection() {
return OrientationHV.VERTICAL;
}
@EditableProperty
@@ -21,54 +21,52 @@
*/
package org.diylc.components.guitar;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.components.RoundedPath;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.Theme;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.annotations.KeywordPolicy;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
import org.diylc.common.OrientationHV;
import org.diylc.components.RoundedPath;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.Theme;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.annotations.KeywordPolicy;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Single Coil Pickup", category = "Guitar", author = "Branislav Stojkovic",
description = "Single coil guitar pickup, both Strat and Tele style", stretchable = false,
description = "Single coil guitar pickup, both Strat and Tele style",
zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "PKP", autoEdit = false,
keywordPolicy = KeywordPolicy.SHOW_TAG, keywordTag = "Guitar Wiring Diagram")
public class SingleCoilPickup extends AbstractTransparentComponent<String> {
public class SingleCoilPickup extends AbstractSingleOrHumbuckerPickup {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L;
private static Color BODY_COLOR = Color.white;
private static Color BASE_COLOR = Color.gray;
private static Color POINT_COLOR = Color.lightGray;
private static Color BASE_COLOR = Color.gray;
public static Color LUG_COLOR = Color.decode("#E0C04C");
// private static Color POINT_COLOR = Color.lightGray;
private static Size WIDTH = new Size(15.5d, SizeUnit.mm);
private static Size LENGTH = new Size(83d, SizeUnit.mm);
private static Size BASE_RADIUS = new Size(0.15d, SizeUnit.in);
private static Size BASE_RADIUS = new Size(0.15d, SizeUnit.in);
private static Size LUG_DIAMETER = new Size(0.06d, SizeUnit.in);
// strat-specific
private static Size STRAT_LIP_WIDTH = new Size(5d, SizeUnit.mm);
@@ -79,9 +77,8 @@ public class SingleCoilPickup extends AbstractTransparentComponent<String> {
private static Size TELE_BASE_WIDTH = new Size(1.5d, SizeUnit.in);
private static Size TELE_LIP_LENGTH = new Size(1.735d, SizeUnit.in);
private static Size TELE_LENGTH = new Size(2.87d, SizeUnit.in);
private static Size TELE_HOLE_SPACING = new Size(1.135d, SizeUnit.in);
private static Size POINT_SIZE = new Size(2d, SizeUnit.mm);
private static Size TELE_HOLE_SPACING = new Size(1.135d, SizeUnit.in);
private static Size HOLE_SIZE = new Size(2d, SizeUnit.mm);
private static Size HOLE_MARGIN = new Size(4d, SizeUnit.mm);
private static Size POLE_SIZE = new Size(4d, SizeUnit.mm);
@@ -90,16 +87,18 @@ public class SingleCoilPickup extends AbstractTransparentComponent<String> {
private static Size RAIL_WIDTH = new Size(1.5d, SizeUnit.mm);
private static Size RAIL_LENGTH = new Size(60d, SizeUnit.mm);
private static Size COIL_SPACING = new Size(7.5d, SizeUnit.mm);
private String value = "";
private Point controlPoint = new Point(0, 0);
transient Shape[] body;
private Orientation orientation = Orientation.DEFAULT;
private Color color = BODY_COLOR;
private Color poleColor = METAL_COLOR;
private Color baseColor = BASE_COLOR;
private SingleCoilType type = SingleCoilType.Stratocaster;
private PolePieceType polePieceType = PolePieceType.Rods;
private PolePieceType polePieceType = PolePieceType.Rods;
private Color lugColor = LUG_COLOR;
@Override
protected OrientationHV getControlPointDirection() {
return OrientationHV.HORIZONTAL;
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
@@ -111,17 +110,23 @@ public class SingleCoilPickup extends AbstractTransparentComponent<String> {
Composite oldComposite = g2d.getComposite();
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA));
}
}
Theme theme =
(Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : getBaseColor());
g2d.fill(body[4]);
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : getColor());
if (body[0] == null)
g2d.fill(body[3]);
else
if (body[3] == null)
g2d.fill(body[0]);
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : POINT_COLOR);
g2d.fill(body[1]);
else
g2d.fill(body[3]);
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : getLugColor());
g2d.fill(body[1]);
g2d.setColor(outlineMode ? theme.getOutlineColor() : darkerOrLighter(LUG_COLOR));
g2d.draw(body[1]);
// g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : color);
// g2d.fill(body[3]);
@@ -129,8 +134,6 @@ public class SingleCoilPickup extends AbstractTransparentComponent<String> {
Color finalBorderColor;
if (outlineMode) {
Theme theme =
(Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalBorderColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: theme.getOutlineColor();
@@ -143,9 +146,7 @@ public class SingleCoilPickup extends AbstractTransparentComponent<String> {
g2d.setColor(finalBorderColor);
g2d.draw(body[4]);
if (outlineMode) {
Theme theme =
(Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
if (outlineMode) {
finalBorderColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: theme.getOutlineColor();
@@ -155,10 +156,10 @@ public class SingleCoilPickup extends AbstractTransparentComponent<String> {
: darkerOrLighter(color);
}
g2d.setColor(finalBorderColor);
if (body[0] != null)
g2d.draw(body[0]);
g2d.draw(body[3]);
g2d.setColor(finalBorderColor);
g2d.draw(body[0]);
if (body[3] != null)
g2d.draw(body[3]);
if (!outlineMode) {
g2d.setColor(getPoleColor());
@@ -166,33 +167,28 @@ public class SingleCoilPickup extends AbstractTransparentComponent<String> {
g2d.setColor(darkerOrLighter(getPoleColor()));
g2d.draw(body[2]);
}
Color finalLabelColor;
if (outlineMode) {
Theme theme =
(Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalLabelColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: theme.getOutlineColor();
} else {
finalLabelColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: LABEL_COLOR;
}
g2d.setColor(finalLabelColor);
g2d.setFont(project.getFont());
Rectangle bounds = body[3].getBounds();
drawCenteredText(g2d, value, bounds.x + bounds.width / 2, bounds.y + bounds.height / 2, HorizontalAlignment.CENTER,
VerticalAlignment.CENTER);
drawMainLabel(g2d, project, outlineMode, componentState);
drawlTerminalLabels(g2d, finalBorderColor, project);
}
@Override
protected int getMainLabelYOffset() {
if (getPolePieceType() == PolePieceType.RailHumbucker || getPolePieceType() == PolePieceType.RodHumbucker || getPolePieceType() == PolePieceType.None)
return 0;
return (int) (WIDTH.convertToPixels() / 2 - 20);
}
@SuppressWarnings("incomplete-switch")
@SuppressWarnings("incomplete-switch")
@Override
public Shape[] getBody() {
if (body == null) {
body = new Shape[5];
int x = controlPoint.x;
int y = controlPoint.y;
Point[] points = getControlPoints();
int x = (points[0].x + points[3].x) / 2;
int y = (points[0].y + points[3].y) / 2;;
int width = (int) WIDTH.convertToPixels();
int length = (int) LENGTH.convertToPixels();
int stratInnerLength = (int) STRAT_INNER_LENGTH.convertToPixels();
@@ -203,11 +199,11 @@ public class SingleCoilPickup extends AbstractTransparentComponent<String> {
int coilLength = getType() == SingleCoilType.Stratocaster ? stratInnerLength : teleLength;
int lipWidth = (int) STRAT_LIP_WIDTH.convertToPixels();
int lipLength = (int) STRAT_LIP_LENGTH.convertToPixels();
int pointSize = getClosestOdd(POINT_SIZE.convertToPixels());
int lugDiameter = getClosestOdd(LUG_DIAMETER.convertToPixels());
int holeSize = getClosestOdd(HOLE_SIZE.convertToPixels());
int holeMargin = getClosestOdd(HOLE_MARGIN.convertToPixels());
int baseRadius = (int) BASE_RADIUS.convertToPixels();
int coilOffset = 0;
int coilOffset = 0;
if (getType() == SingleCoilType.Stratocaster) {
coilOffset = lipWidth / 2;
@@ -220,7 +216,7 @@ public class SingleCoilPickup extends AbstractTransparentComponent<String> {
mainArea.subtract(new Area(new Ellipse2D.Double(x + length / 2 - holeMargin - holeSize / 2, y - lipWidth / 2
- width / 2 - holeSize / 2, holeSize, holeSize)));
body[0] = mainArea;
body[3] = mainArea;
RoundedPath basePath = new RoundedPath(baseRadius);
basePath.moveTo(x, y + lipWidth / 2);
basePath.lineTo(x + lipLength / 2, y + lipWidth / 2);
@@ -255,11 +251,9 @@ public class SingleCoilPickup extends AbstractTransparentComponent<String> {
base.subtract(new Area(new Ellipse2D.Double(x - teleLipLength / 2 - holeSize / 2, y, holeSize, holeSize)));
base.subtract(new Area(new Ellipse2D.Double(x + teleLipLength / 2 - holeSize / 2, y, holeSize, holeSize)));
base.subtract(new Area(new Ellipse2D.Double(x - holeSize / 2, y - teleHoleSpacing, holeSize, holeSize)));
body[4] = base;
}
body[1] = new Area(new Ellipse2D.Double(x - pointSize / 2, y - pointSize / 2, pointSize, pointSize));
}
Area poleArea = new Area();
if (getPolePieceType() == PolePieceType.Rods) {
@@ -296,15 +290,17 @@ public class SingleCoilPickup extends AbstractTransparentComponent<String> {
int railLength = (int) RAIL_LENGTH.convertToPixels();
poleArea.add(new Area(new RoundRectangle2D.Double(x - railLength / 2, y - coilOffset - width / 2 - railWidth
/ 2, railLength, railWidth, railWidth / 2, railWidth / 2)));
}
body[2] = poleArea;
body[3] =
new Area(new RoundRectangle2D.Double(x - coilLength / 2, y - coilOffset - width, coilLength, width, width,
}
body[0] =
new Area(new RoundRectangle2D.Double(x - coilLength / 2, y - coilOffset - width, coilLength, width, width,
width));
((Area) body[4]).subtract((Area) body[3]);
body[2] = poleArea;
if (body[3] == null) {
((Area)body[4]).subtract((Area) body[0]);
}
// Rotate if needed
if (orientation != Orientation.DEFAULT) {
@@ -326,7 +322,15 @@ public class SingleCoilPickup extends AbstractTransparentComponent<String> {
if (area != null)
area.transform(rotation);
}
}
}
body[1] = new Area();
double lugHole = getClosestOdd(lugDiameter * 0.4);
for (int i = getPolarity() == Polarity.Humbucking ? 0 : 1; i < (getPolarity() == Polarity.Humbucking ? 4 : 3); i++) {
Point p = points[i];
((Area)body[1]).add(new Area(new Ellipse2D.Double(p.x - lugDiameter / 2, p.y - lugDiameter / 2, lugDiameter, lugDiameter)));
((Area)body[1]).subtract(new Area(new Ellipse2D.Double(p.x - lugHole / 2, p.y - lugHole / 2, lugHole, lugHole)));
}
}
return body;
}
@@ -386,55 +390,6 @@ public class SingleCoilPickup extends AbstractTransparentComponent<String> {
body = null;
}
@Override
public int getControlPointCount() {
return 1;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.WHEN_SELECTED;
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public Point getControlPoint(int index) {
return controlPoint;
}
@Override
public void setControlPoint(Point point, int index) {
this.controlPoint.setLocation(point);
// Invalidate the body
body = null;
}
@EditableProperty(name = "Model")
@Override
public String getValue() {
return value;
}
@Override
public void setValue(String value) {
this.value = value;
}
@EditableProperty
public Orientation getOrientation() {
return orientation;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
// Invalidate the body
body = null;
}
@EditableProperty
public Color getColor() {
return color;
@@ -464,7 +419,20 @@ public class SingleCoilPickup extends AbstractTransparentComponent<String> {
public void setPoleColor(Color poleColor) {
this.poleColor = poleColor;
}
}
@EditableProperty(name = "Lugs")
public Color getLugColor() {
if (lugColor == null) {
lugColor = LUG_COLOR;
}
return lugColor;
}
public void setLugColor(Color lugColor) {
this.lugColor = lugColor;
}
public enum SingleCoilType {
Stratocaster, Telecaster;
@@ -29,7 +29,7 @@ import java.awt.Point;
import java.awt.geom.Rectangle2D;
import java.util.Iterator;
import java.util.List;
import org.diylc.components.AbstractComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
@@ -45,7 +45,7 @@ import org.diylc.utils.BomEntry;
import org.diylc.utils.BomMaker;
@ComponentDescriptor(name = "Bill of Materials", author = "Branislav Stojkovic", category = "Misc", description = "",
instanceNamePrefix = "BOM", zOrder = IDIYComponent.TEXT, stretchable = false, bomPolicy = BomPolicy.NEVER_SHOW,
instanceNamePrefix = "BOM", zOrder = IDIYComponent.TEXT, bomPolicy = BomPolicy.NEVER_SHOW,
autoEdit = false)
public class BOM extends AbstractComponent<Void> {
@@ -58,7 +58,12 @@ public class BOM extends AbstractComponent<Void> {
private Size size = DEFAULT_SIZE;
private Point point = new Point(0, 0);
private Color color = COLOR;
private Color color = COLOR;
@Override
public String getControlPointNodeName(int index) {
return null;
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
@@ -24,7 +24,7 @@ package org.diylc.components.misc;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.GeneralPath;
import org.diylc.components.AbstractSchematicLeadedSymbol;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
@@ -130,7 +130,10 @@ public class BatterySymbol extends AbstractSchematicLeadedSymbol<String> {
* width / 32);
g2d.drawLine(height / 2 - 6 * width / 32, height / 2 - 3 * width / 32, height / 2 - 6 * width / 32, height / 2 - 7
* width / 32);
}
@Override
public String getControlPointNodeName(int index) {
return getName() + "." + (index == 0 ? "+" : "-");
}
}
@@ -25,7 +25,7 @@ import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import org.diylc.common.ObjectCache;
import org.diylc.components.AbstractComponent;
import org.diylc.core.ComponentState;
@@ -40,7 +40,7 @@ import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Ground", author = "Branislav Stojkovic", category = "Schematic Symbols",
instanceNamePrefix = "GND", description = "Ground schematic symbol", stretchable = false,
instanceNamePrefix = "GND", description = "Ground schematic symbol",
zOrder = IDIYComponent.COMPONENT, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false)
public class GroundSymbol extends AbstractComponent<Void> {
@@ -133,7 +133,17 @@ public class GroundSymbol extends AbstractComponent<Void> {
@Override
public void setControlPoint(Point point, int index) {
this.point = point;
this.point.setLocation(point);
}
//
// @Override
// public String getControlPointNodeName(int index) {
// return getName();
// }
@Override
public String getCommonPointName(int pointIndex) {
return "GND";
}
@Override

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