mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-07 20:34:55 +10:00
Compare commits
23 Commits
dark-theme
...
scolling
| Author | SHA1 | Date | |
|---|---|---|---|
| cef1dbcaa9 | |||
| 6b59966816 | |||
| b065c9d6fb | |||
| 49d805a60c | |||
| a9a98bf3a4 | |||
| 840d416282 | |||
| dc2cc4c7c8 | |||
| 3d51d2a38d | |||
| 4dfb1ca630 | |||
| e9c8686960 | |||
| 9be97f5213 | |||
| 721d582dcd | |||
| 443f76f3f9 | |||
| 3ad9c49f53 | |||
| 61077ed5a4 | |||
| 1fe3706d0f | |||
| 16df8fd173 | |||
| f7806d4d3c | |||
| 04e44e174e | |||
| f74fe19b77 | |||
| e7487069a5 | |||
| 9c48b80515 | |||
| 814f4296a9 |
@@ -68,5 +68,9 @@ public enum DrawOption {
|
||||
/**
|
||||
* Whether locked components should be rendered as transparent or not.
|
||||
*/
|
||||
LOCKED_ALPHA;
|
||||
LOCKED_ALPHA,
|
||||
/**
|
||||
* When applied, all colors will be converted to blackest black or whitest white
|
||||
*/
|
||||
MONOCHROMATIC;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.diylc.core.Project;
|
||||
import org.diylc.core.Template;
|
||||
import org.diylc.core.Theme;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.filter.IComponentFilter;
|
||||
import org.diylc.test.ITestProcessor;
|
||||
|
||||
/**
|
||||
@@ -84,6 +85,7 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
|
||||
public static final String RENUMBER_ON_PASTE_KEY = "renumberOnPaste";
|
||||
public static final String RULER_IN_SUBDIVISION_KEY = "rulerInSubdivision";
|
||||
public static final String CACHING_ENABLED_KEY = "cachingEnabled";
|
||||
public static final String FONT_SCALE_FACTOR_KEY = "fontScaleFactor";
|
||||
|
||||
public static final String RULER_IN_SUBDIVISION_2 = "base of 2";
|
||||
public static final String RULER_IN_SUBDIVISION_10 = "base of 10";
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
package org.diylc.common;
|
||||
package org.diylc.filter;
|
||||
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
+1
-2
@@ -19,11 +19,10 @@
|
||||
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
package org.diylc.presenter;
|
||||
package org.diylc.filter;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.diylc.common.IComponentFilter;
|
||||
import org.diylc.common.PCBLayer;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.diylc.filter;
|
||||
|
||||
import org.diylc.core.IBoard;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.gerber.GerberRenderMode;
|
||||
import org.diylc.core.gerber.IGerberComponent;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class SilkScreenFilter implements IComponentFilter {
|
||||
|
||||
@Override
|
||||
public boolean testComponent(IDIYComponent<?> component) {
|
||||
if (component instanceof IBoard board) {
|
||||
return board.shouldExportToGerber();
|
||||
}
|
||||
if (!(component instanceof IGerberComponent gerberComponent)) {
|
||||
return false;
|
||||
}
|
||||
Set<GerberRenderMode> gerberRenderModes = gerberComponent.getGerberRenderModes();
|
||||
return gerberRenderModes.contains(GerberRenderMode.Outline);
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.diylc.presenter;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.util.List;
|
||||
|
||||
@@ -71,4 +72,54 @@ public class CalcUtils {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the relative luminance (perceived brightness) of a color.
|
||||
* Uses the standard formula: L = 0.299*R + 0.587*G + 0.114*B
|
||||
*
|
||||
* @param color the color to calculate luminance for
|
||||
* @return the luminance value between 0 and 255
|
||||
*/
|
||||
public static double calculateLuminance(Color color) {
|
||||
if (color == null) {
|
||||
return 0.0;
|
||||
}
|
||||
return 0.299 * color.getRed() + 0.587 * color.getGreen() + 0.114 * color.getBlue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a color to monochrome (black or white) based on its luminance.
|
||||
* Colors with luminance below the threshold (128) are converted to black,
|
||||
* otherwise to white. The alpha channel is preserved if present.
|
||||
*
|
||||
* @param color the color to convert
|
||||
* @param threshold the luminance threshold (default 128 for middle gray)
|
||||
* @return black or white color, preserving alpha channel
|
||||
*/
|
||||
public static Color convertToMonochrome(Color color, double threshold) {
|
||||
if (color == null) {
|
||||
return null;
|
||||
}
|
||||
double luminance = calculateLuminance(color);
|
||||
// Use <= to handle edge case where luminance equals threshold (should be white)
|
||||
// Add small epsilon to account for floating point precision issues
|
||||
Color monochromeColor = (luminance < threshold - 1e-10) ? Color.BLACK : Color.WHITE;
|
||||
// Preserve alpha channel if present
|
||||
if (color.getAlpha() < 255) {
|
||||
monochromeColor = new Color(monochromeColor.getRed(), monochromeColor.getGreen(),
|
||||
monochromeColor.getBlue(), color.getAlpha());
|
||||
}
|
||||
return monochromeColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a color to monochrome (black or white) based on its luminance.
|
||||
* Uses the default threshold of 128 (middle gray).
|
||||
*
|
||||
* @param color the color to convert
|
||||
* @return black or white color, preserving alpha channel
|
||||
*/
|
||||
public static Color convertToMonochrome(Color color) {
|
||||
return convertToMonochrome(color, 128.0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,10 +26,12 @@ import java.lang.ref.SoftReference;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.diylc.common.ComponentType;
|
||||
import org.diylc.common.DrawOption;
|
||||
import org.diylc.core.ComponentForRender;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
@@ -67,14 +69,14 @@ public class DrawingCache {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void bulkPrepare(Collection<ComponentForRender> components, G2DWrapper g2d, boolean outlineMode, Project project,
|
||||
double zoom, double scaleFactor) {
|
||||
double zoom, double scaleFactor, Set<DrawOption> drawOptions) {
|
||||
// run all renders in parallel to utilize all CPU cores
|
||||
components.stream().parallel().forEach(x -> {
|
||||
ComponentType type = ComponentProcessor.getInstance()
|
||||
.extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) x.getComponent().getClass());
|
||||
|
||||
if (type != null && type.getEnableCache()) {
|
||||
renderAndCache(x.getComponent(), g2d, x.getState(), outlineMode, project, zoom, scaleFactor, x.getZOrder());
|
||||
renderAndCache(x.getComponent(), g2d, x.getState(), outlineMode, project, zoom, scaleFactor, x.getZOrder(), drawOptions);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -92,7 +94,7 @@ public class DrawingCache {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void draw(IDIYComponent<?> component, G2DWrapper g2d, ComponentState componentState,
|
||||
boolean outlineMode, Project project, double zoom, double scaleFactor, int zOrder, Rectangle2D visibleRect) {
|
||||
boolean outlineMode, Project project, double zoom, double scaleFactor, int zOrder, Rectangle2D visibleRect, Set<DrawOption> drawOptions) {
|
||||
ComponentType type = ComponentProcessor.getInstance()
|
||||
.extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) component.getClass());
|
||||
|
||||
@@ -100,7 +102,7 @@ public class DrawingCache {
|
||||
// if we need to apply caching
|
||||
Point2D firstPoint = component.getControlPoint(0);
|
||||
|
||||
CacheValue value = renderAndCache(component, g2d, componentState, outlineMode, project, zoom, scaleFactor, zOrder);
|
||||
CacheValue value = renderAndCache(component, g2d, componentState, outlineMode, project, zoom, scaleFactor, zOrder, drawOptions);
|
||||
|
||||
if (value == null) {
|
||||
return;
|
||||
@@ -180,7 +182,7 @@ public class DrawingCache {
|
||||
}
|
||||
|
||||
private CacheValue renderAndCache(IDIYComponent<?> component, G2DWrapper g2d, ComponentState componentState,
|
||||
boolean outlineMode, Project project, double zoom, double scaleFactor, int zOrder) {
|
||||
boolean outlineMode, Project project, double zoom, double scaleFactor, int zOrder, Set<DrawOption> drawOptions) {
|
||||
|
||||
if (!g2d.getClipBounds().intersects(component.getCachingBounds())) {
|
||||
return null;
|
||||
@@ -199,9 +201,11 @@ public class DrawingCache {
|
||||
}
|
||||
|
||||
// only honor the cache if the component hasn't changed in the meantime
|
||||
// Also check if drawOptions changed (e.g., MONOCHROMATIC affects rendering)
|
||||
boolean drawOptionsChanged = value == null || !value.getDrawOptions().equals(drawOptions);
|
||||
if (value == null || !value.getComponent().equalsTo(component)
|
||||
|| value.getState() != componentState || value.getZoom() != zoom || value.getOutlineMode() != outlineMode
|
||||
|| value.getScaleFactor() != scaleFactor) {
|
||||
|| value.getScaleFactor() != scaleFactor || drawOptionsChanged) {
|
||||
// figure out size and placement of buffer image
|
||||
Rectangle2D rect = component.getCachingBounds();
|
||||
int width = (int)Math.round(rect.getWidth() * zoom);
|
||||
@@ -233,7 +237,7 @@ public class DrawingCache {
|
||||
cg2d.translate(-firstPoint.getX() + dx, -firstPoint.getY() + dy);
|
||||
|
||||
// wrap the graphics so we can track
|
||||
G2DWrapper wrapper = new G2DWrapper(cg2d, zoom);
|
||||
G2DWrapper wrapper = new G2DWrapper(cg2d, zoom, drawOptions);
|
||||
|
||||
// initialize wrapper
|
||||
wrapper.startedDrawingComponent(zOrder);
|
||||
@@ -275,7 +279,7 @@ public class DrawingCache {
|
||||
|
||||
// add to the cache
|
||||
value = new CacheValue(component, image, wrapper.getCurrentArea(), wrapper.getContinuityPositiveAreas(),
|
||||
wrapper.getContinuityNegativeAreas(), componentState, outlineMode, zoom, scaleFactor, dx, dy, rect);
|
||||
wrapper.getContinuityNegativeAreas(), componentState, outlineMode, zoom, scaleFactor, dx, dy, rect, drawOptions);
|
||||
imageCache.put(component, new SoftReference<DrawingCache.CacheValue>(value));
|
||||
}
|
||||
|
||||
@@ -295,11 +299,12 @@ public class DrawingCache {
|
||||
int dx;
|
||||
int dy;
|
||||
Rectangle2D cacheBounds;
|
||||
Set<DrawOption> drawOptions;
|
||||
|
||||
public CacheValue(IDIYComponent<?> component, BufferedImage image, Area currentArea,
|
||||
Map<String, Area> continuityPositiveAreas, Map<String, Area> continuityNegativeAreas,
|
||||
ComponentState state, boolean outlineMode, double zoom, double scaleFactor, int dx, int dy,
|
||||
Rectangle2D cacheBounds) {
|
||||
Rectangle2D cacheBounds, Set<DrawOption> drawOptions) {
|
||||
super();
|
||||
this.cacheBounds = cacheBounds;
|
||||
// take a copy of the component, so we can check if it changed in the meantime
|
||||
@@ -317,6 +322,7 @@ public class DrawingCache {
|
||||
this.dx = dx;
|
||||
this.dy = dy;
|
||||
this.scaleFactor = scaleFactor;
|
||||
this.drawOptions = drawOptions;
|
||||
}
|
||||
|
||||
public IDIYComponent<?> getComponent() {
|
||||
@@ -366,6 +372,10 @@ public class DrawingCache {
|
||||
public Rectangle2D getCacheBounds() {
|
||||
return cacheBounds;
|
||||
}
|
||||
|
||||
public Set<DrawOption> getDrawOptions() {
|
||||
return drawOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
@@ -54,6 +54,7 @@ import org.diylc.components.AbstractTransparentComponent;
|
||||
import org.diylc.core.*;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.filter.IComponentFilter;
|
||||
import org.diylc.netlist.ContinuityGraph;
|
||||
import org.diylc.netlist.NetlistBuilder;
|
||||
import org.diylc.utils.Constants;
|
||||
@@ -183,7 +184,7 @@ public class DrawingManager {
|
||||
if (externalZoom != null)
|
||||
zoom *= externalZoom;
|
||||
|
||||
G2DWrapper g2dWrapper = new G2DWrapper(g2d, zoom);
|
||||
G2DWrapper g2dWrapper = new G2DWrapper(g2d, zoom, drawOptions);
|
||||
|
||||
configureRenderingHints(g2d, drawOptions);
|
||||
|
||||
@@ -267,7 +268,7 @@ public class DrawingManager {
|
||||
|
||||
// give the cache a chance to prepare all the components in multiple threads
|
||||
if (drawOptions.contains(DrawOption.ENABLE_CACHING)) {
|
||||
DrawingCache.Instance.bulkPrepare(componentForRenderList, g2dWrapper, outlineMode, project, zoom, scaleFactor);
|
||||
DrawingCache.Instance.bulkPrepare(componentForRenderList, g2dWrapper, outlineMode, project, zoom, scaleFactor, drawOptions);
|
||||
}
|
||||
|
||||
// componentAreaMap.clear();
|
||||
@@ -561,10 +562,12 @@ public class DrawingManager {
|
||||
}
|
||||
}
|
||||
|
||||
private static void drawComponent(Project project, Set<DrawOption> drawOptions, Double scaleFactor, Rectangle2D visibleRect, IDIYComponent<?> component, G2DWrapper g2dWrapper, ComponentState state, double zoom, int i, boolean outlineMode) {
|
||||
private static void drawComponent(Project project, Set<DrawOption> drawOptions, Double scaleFactor,
|
||||
Rectangle2D visibleRect, IDIYComponent<?> component, G2DWrapper g2dWrapper, ComponentState state,
|
||||
double zoom, int i, boolean outlineMode) {
|
||||
if (drawOptions.contains(DrawOption.ENABLE_CACHING)) // go through the DrawingCache
|
||||
DrawingCache.Instance.draw(component, g2dWrapper, state,
|
||||
drawOptions.contains(DrawOption.OUTLINE_MODE), project, zoom, scaleFactor, i, visibleRect);
|
||||
drawOptions.contains(DrawOption.OUTLINE_MODE), project, zoom, scaleFactor, i, visibleRect, drawOptions);
|
||||
else // go straight to the wrapper
|
||||
component.draw(g2dWrapper, state, outlineMode, project, g2dWrapper);
|
||||
}
|
||||
|
||||
@@ -53,17 +53,11 @@ import java.awt.image.renderable.RenderableImage;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.common.DrawOption;
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.common.ZoomableStroke;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
@@ -71,7 +65,7 @@ import org.diylc.core.IDrawingObserver;
|
||||
/**
|
||||
* {@link Graphics2D} wrapper that keeps track of all drawing actions and creates an {@link Area}
|
||||
* that corresponds to drawn objects. Before each component is drawn,
|
||||
* {@link #startedDrawingComponent()} should be called. After the component is drawn, area may be
|
||||
* {@link #startedDrawingComponent(int)} should be called. After the component is drawn, area may be
|
||||
* retrieved using {@link #finishedDrawingComponent()}. Graphics configuration (color, font, etc) is
|
||||
* reset between each two components.
|
||||
*
|
||||
@@ -96,7 +90,9 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver {
|
||||
|
||||
private int uniqueCounter = 0;
|
||||
|
||||
private Graphics2D canvasGraphics;
|
||||
private final Graphics2D canvasGraphics;
|
||||
private final Set<DrawOption> drawOptions;
|
||||
|
||||
private Stroke originalStroke;
|
||||
private Color originalColor;
|
||||
private Composite originalComposite;
|
||||
@@ -115,12 +111,14 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver {
|
||||
|
||||
/**
|
||||
* Creates a wrapper around specified {@link Graphics2D} object.
|
||||
*
|
||||
*
|
||||
* @param canvasGraphics
|
||||
* @param drawOptions
|
||||
*/
|
||||
public G2DWrapper(Graphics2D canvasGraphics, double zoom) {
|
||||
public G2DWrapper(Graphics2D canvasGraphics, double zoom, Set<DrawOption> drawOptions) {
|
||||
super();
|
||||
this.canvasGraphics = canvasGraphics;
|
||||
this.drawOptions = drawOptions;
|
||||
String debugAreaPerformanceStr = System.getProperty(DEBUG_AREA_PERFORMANCE);
|
||||
debugAreaPerformance = "true".equalsIgnoreCase(debugAreaPerformanceStr);
|
||||
this.zoom = zoom;
|
||||
@@ -482,7 +480,9 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver {
|
||||
|
||||
@Override
|
||||
public void setComposite(Composite comp) {
|
||||
canvasGraphics.setComposite(comp);
|
||||
if (!drawOptions.contains(DrawOption.OUTLINE_MODE)) {
|
||||
canvasGraphics.setComposite(comp);
|
||||
}
|
||||
// FIXME: check this.
|
||||
}
|
||||
|
||||
@@ -758,7 +758,11 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver {
|
||||
|
||||
@Override
|
||||
public void setColor(Color c) {
|
||||
canvasGraphics.setColor(c);
|
||||
if (drawOptions.contains(DrawOption.MONOCHROMATIC) && c != null) {
|
||||
canvasGraphics.setColor(CalcUtils.convertToMonochrome(c));
|
||||
} else {
|
||||
canvasGraphics.setColor(c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -71,6 +71,7 @@ import org.diylc.core.annotations.IAutoCreator;
|
||||
import org.diylc.core.gerber.GerberExporter;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.filter.IComponentFilter;
|
||||
import org.diylc.lang.LangUtil;
|
||||
import org.diylc.netlist.INetlistParser;
|
||||
import org.diylc.netlist.Netlist;
|
||||
@@ -250,8 +251,10 @@ public class Presenter implements IPlugInPort {
|
||||
@Override
|
||||
public Cursor getCursorAt(Point point, boolean ctrlDown, boolean shiftDown, boolean altDown) {
|
||||
// Only change the cursor if we're not making a new component.
|
||||
if (operationMode == OperationMode.HIGHLIGHT_CONNECTED_AREAS || altDown)
|
||||
if (operationMode == OperationMode.HIGHLIGHT_CONNECTED_AREAS || altDown) {
|
||||
return Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR);
|
||||
}
|
||||
|
||||
if (instantiationManager.getComponentTypeSlot() == null) {
|
||||
// Scale point to remove zoom factor.
|
||||
Point2D scaledPoint = scalePoint(point);
|
||||
@@ -268,6 +271,7 @@ public class Presenter implements IPlugInPort {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Cursor.getDefaultCursor();
|
||||
}
|
||||
|
||||
@@ -427,7 +431,7 @@ public class Presenter implements IPlugInPort {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, Set<DrawOption> drawOptions, final IComponentFilter filter, Double externalZoom,
|
||||
public void draw(Graphics2D g2d, Set<DrawOption> drawOptions, final IComponentFilter filter, Double externalZoom,
|
||||
Double scaleFactor, Rectangle2D visibleRect) {
|
||||
if (currentProject == null) {
|
||||
return;
|
||||
@@ -1580,6 +1584,7 @@ public class Presenter implements IPlugInPort {
|
||||
drawingManager.clearContinuityArea();
|
||||
projectFileManager.notifyFileChange();
|
||||
}
|
||||
|
||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||
dragInProgress = false;
|
||||
}
|
||||
|
||||
@@ -425,14 +425,58 @@
|
||||
<releaseDate>2025-12-21 00:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added Silkscreen export to PDF/PNG and print capabilities</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added 'Multiwatt IC' package with 11 and 15 pin varieties</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added new property in 'LP Switch' that allows having the middle terminals connected (as they were) or disconnected to allow more flexibility</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added 'Ending Style' property to 'Copper Trace' and 'Curved Trace' to allow choosing round or flat style</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added Chinese simplified (thank you chenjingyuanku) and Hindi UI translation and updated all other languages with new translations</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added configuration for text scale factor in rare cases when system scale factor is not applied correctly; requires adding a configuration property to config.xml with key 'fontScaleFactor' and a desired float value</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Improved behavior of mouse cursor during drag operations; this should also fix behavior on some linux machines that show a "forbidden" cursor while dragging</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Improved sensitivity of 'Multimeter Probe' that required pixel-level precision to detect connectivity; improved rendering of the probe in outline mode</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Improve contrast of tooltips on some Linux machines that show white text against yellow balloon</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Honor label color settings for 'Tape Measure' component</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Reorganized export and print related items in the File menu to reduce clutter</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Fixed underside rendering and mirroring position issues that affected only SPDT 'Mini Toggle Switch' types</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Application freezes when using underside rendering or mirroring on 'Pin Header' when sized at 1x1</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.diylc.presenter;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -142,4 +143,116 @@ public class CalcUtilsTest {
|
||||
point2.setLocation(10.0, 21.0);
|
||||
assertFalse(CalcUtils.pointsMatch(point1, point2, 0.5));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCalculateLuminance() {
|
||||
// Test pure black
|
||||
assertEquals(0.0, CalcUtils.calculateLuminance(Color.BLACK), 0.001);
|
||||
|
||||
// Test pure white
|
||||
assertEquals(255.0, CalcUtils.calculateLuminance(Color.WHITE), 0.001);
|
||||
|
||||
// Test pure red
|
||||
double redLuminance = CalcUtils.calculateLuminance(Color.RED);
|
||||
assertEquals(76.245, redLuminance, 0.001); // 0.299 * 255
|
||||
|
||||
// Test pure green
|
||||
double greenLuminance = CalcUtils.calculateLuminance(Color.GREEN);
|
||||
assertEquals(149.685, greenLuminance, 0.001); // 0.587 * 255
|
||||
|
||||
// Test pure blue
|
||||
double blueLuminance = CalcUtils.calculateLuminance(Color.BLUE);
|
||||
assertEquals(29.07, blueLuminance, 0.001); // 0.114 * 255
|
||||
|
||||
// Test middle gray (128, 128, 128)
|
||||
Color gray = new Color(128, 128, 128);
|
||||
double grayLuminance = CalcUtils.calculateLuminance(gray);
|
||||
assertEquals(128.0, grayLuminance, 0.001);
|
||||
|
||||
// Test null color
|
||||
assertEquals(0.0, CalcUtils.calculateLuminance(null), 0.001);
|
||||
|
||||
// Test custom color
|
||||
Color custom = new Color(100, 150, 200);
|
||||
double customLuminance = CalcUtils.calculateLuminance(custom);
|
||||
double expected = 0.299 * 100 + 0.587 * 150 + 0.114 * 200;
|
||||
assertEquals(expected, customLuminance, 0.001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertToMonochrome() {
|
||||
// Test pure black -> should stay black
|
||||
Color result = CalcUtils.convertToMonochrome(Color.BLACK);
|
||||
assertEquals(Color.BLACK, result);
|
||||
|
||||
// Test pure white -> should stay white
|
||||
result = CalcUtils.convertToMonochrome(Color.WHITE);
|
||||
assertEquals(Color.WHITE, result);
|
||||
|
||||
// Test dark color -> should become black
|
||||
Color darkBlue = new Color(0, 0, 50);
|
||||
result = CalcUtils.convertToMonochrome(darkBlue);
|
||||
assertEquals(Color.BLACK, result);
|
||||
|
||||
// Test light color -> should become white
|
||||
Color lightYellow = new Color(255, 255, 200);
|
||||
result = CalcUtils.convertToMonochrome(lightYellow);
|
||||
assertEquals(Color.WHITE, result);
|
||||
|
||||
// Test middle gray -> should become white (threshold is 128, gray is exactly 128)
|
||||
Color gray = new Color(128, 128, 128);
|
||||
result = CalcUtils.convertToMonochrome(gray);
|
||||
assertEquals(Color.WHITE, result);
|
||||
|
||||
// Test color just below threshold -> should become black
|
||||
Color darkGray = new Color(127, 127, 127);
|
||||
result = CalcUtils.convertToMonochrome(darkGray);
|
||||
assertEquals(Color.BLACK, result);
|
||||
|
||||
// Test color just above threshold -> should become white
|
||||
Color lightGray = new Color(129, 129, 129);
|
||||
result = CalcUtils.convertToMonochrome(lightGray);
|
||||
assertEquals(Color.WHITE, result);
|
||||
|
||||
// Test with custom threshold
|
||||
Color mediumColor = new Color(100, 100, 100);
|
||||
result = CalcUtils.convertToMonochrome(mediumColor, 50.0);
|
||||
assertEquals(Color.WHITE, result); // Luminance ~100, threshold 50, so white
|
||||
|
||||
result = CalcUtils.convertToMonochrome(mediumColor, 150.0);
|
||||
assertEquals(Color.BLACK, result); // Luminance ~100, threshold 150, so black
|
||||
|
||||
// Test null color
|
||||
assertNull(CalcUtils.convertToMonochrome(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertToMonochromeWithAlpha() {
|
||||
// Test color with alpha channel - alpha should be preserved
|
||||
// Red (255, 0, 0) has luminance ~76, which is < 128, so it becomes BLACK
|
||||
Color transparentRed = new Color(255, 0, 0, 128);
|
||||
Color result = CalcUtils.convertToMonochrome(transparentRed);
|
||||
assertEquals(Color.BLACK.getRed(), result.getRed());
|
||||
assertEquals(Color.BLACK.getGreen(), result.getGreen());
|
||||
assertEquals(Color.BLACK.getBlue(), result.getBlue());
|
||||
assertEquals(128, result.getAlpha());
|
||||
|
||||
// Test light color with alpha - should become WHITE
|
||||
Color transparentLight = new Color(255, 255, 200, 128);
|
||||
result = CalcUtils.convertToMonochrome(transparentLight);
|
||||
assertEquals(Color.WHITE.getRed(), result.getRed());
|
||||
assertEquals(Color.WHITE.getGreen(), result.getGreen());
|
||||
assertEquals(Color.WHITE.getBlue(), result.getBlue());
|
||||
assertEquals(128, result.getAlpha());
|
||||
|
||||
// Test fully transparent color
|
||||
Color transparent = new Color(100, 150, 200, 0);
|
||||
result = CalcUtils.convertToMonochrome(transparent);
|
||||
assertEquals(0, result.getAlpha());
|
||||
|
||||
// Test opaque color - alpha should remain 255
|
||||
Color opaque = new Color(50, 50, 50);
|
||||
result = CalcUtils.convertToMonochrome(opaque);
|
||||
assertEquals(255, result.getAlpha());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,6 @@ import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.LineStyle;
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.common.VerticalAlignment;
|
||||
import org.diylc.components.AbstractLabeledComponent;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.Project;
|
||||
@@ -434,7 +433,7 @@ public abstract class AbstractLeadedComponent<T> extends AbstractLabeledComponen
|
||||
Stroke stroke = null;
|
||||
switch (getStyle()) {
|
||||
case SOLID:
|
||||
stroke = ObjectCache.getInstance().fetchBasicStroke(thickness);
|
||||
stroke = ObjectCache.getInstance().fetchStroke(thickness, getEndingStyle() == LineEndingStyle.Round ? BasicStroke.CAP_ROUND : BasicStroke.CAP_BUTT);
|
||||
break;
|
||||
case DASHED:
|
||||
stroke =
|
||||
@@ -747,6 +746,10 @@ public abstract class AbstractLeadedComponent<T> extends AbstractLabeledComponen
|
||||
hideShortLeads = false;
|
||||
return hideShortLeads;
|
||||
}
|
||||
|
||||
protected LineEndingStyle getEndingStyle() {
|
||||
return LineEndingStyle.Round;
|
||||
}
|
||||
|
||||
public void setHideShortLeads(Boolean hideShortLeads) {
|
||||
this.hideShortLeads = hideShortLeads;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package org.diylc.components;
|
||||
|
||||
public enum LineEndingStyle {
|
||||
Round, Flat
|
||||
}
|
||||
@@ -64,8 +64,15 @@ public class ChassisPanel extends AbstractShape {
|
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA));
|
||||
}
|
||||
g2d.setColor(color);
|
||||
g2d.fillRoundRect((int)firstPoint.getX(), (int)firstPoint.getY(), (int)(secondPoint.getX() - firstPoint.getX()), (int)(secondPoint.getY() - firstPoint.getY()), radius,
|
||||
radius);
|
||||
if (radius == 0) {
|
||||
g2d.fillRect((int) firstPoint.getX(), (int) firstPoint.getY(),
|
||||
(int) (secondPoint.getX() - firstPoint.getX()),
|
||||
(int) (secondPoint.getY() - firstPoint.getY()));
|
||||
} else {
|
||||
g2d.fillRoundRect((int) firstPoint.getX(), (int) firstPoint.getY(),
|
||||
(int) (secondPoint.getX() - firstPoint.getX()),
|
||||
(int) (secondPoint.getY() - firstPoint.getY()), radius, radius);
|
||||
}
|
||||
g2d.setComposite(oldComposite);
|
||||
}
|
||||
// Do not track any changes that follow because the whole rect has been
|
||||
@@ -73,8 +80,15 @@ public class ChassisPanel extends AbstractShape {
|
||||
drawingObserver.stopTracking();
|
||||
g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
|
||||
: borderColor);
|
||||
g2d.drawRoundRect((int)(firstPoint.getX()), (int)(firstPoint.getY()), (int)(secondPoint.getX() - firstPoint.getX()), (int)(secondPoint.getY() - firstPoint.getY()), radius,
|
||||
radius);
|
||||
if (radius == 0) {
|
||||
g2d.drawRect((int) (firstPoint.getX()), (int) (firstPoint.getY()),
|
||||
(int) (secondPoint.getX() - firstPoint.getX()),
|
||||
(int) (secondPoint.getY() - firstPoint.getY()));
|
||||
} else {
|
||||
g2d.drawRoundRect((int) (firstPoint.getX()), (int) (firstPoint.getY()),
|
||||
(int) (secondPoint.getX() - firstPoint.getX()),
|
||||
(int) (secondPoint.getY() - firstPoint.getY()), radius, radius);
|
||||
}
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Radius")
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.bancika.gerberwriter.GerberFunctions;
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.common.PCBLayer;
|
||||
import org.diylc.components.AbstractLeadedComponent;
|
||||
import org.diylc.components.LineEndingStyle;
|
||||
import org.diylc.components.transform.SimpleComponentTransformer;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.CreationMethod;
|
||||
@@ -58,6 +59,7 @@ public class CopperTrace extends AbstractLeadedComponent<Void> implements ILayer
|
||||
|
||||
private Size thickness = THICKNESS;
|
||||
private PCBLayer layer = PCBLayer._1;
|
||||
private LineEndingStyle endingStyle = LineEndingStyle.Round;
|
||||
|
||||
public CopperTrace() {
|
||||
super();
|
||||
@@ -202,6 +204,19 @@ public class CopperTrace extends AbstractLeadedComponent<Void> implements ILayer
|
||||
return false;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Ending Style")
|
||||
@Override
|
||||
public LineEndingStyle getEndingStyle() {
|
||||
if (endingStyle == null) {
|
||||
endingStyle = LineEndingStyle.Round;
|
||||
}
|
||||
return endingStyle;
|
||||
}
|
||||
|
||||
public void setEndingStyle(LineEndingStyle endingStyle) {
|
||||
this.endingStyle = endingStyle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<GerberRenderMode> getGerberRenderModes() {
|
||||
return EnumSet.of(GerberRenderMode.Normal);
|
||||
|
||||
+17
-3
@@ -17,8 +17,7 @@
|
||||
*/
|
||||
package org.diylc.components.connectivity;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.*;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
@@ -29,6 +28,8 @@ import org.diylc.common.LineStyle;
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.common.PCBLayer;
|
||||
import org.diylc.components.AbstractCurvedComponent;
|
||||
import org.diylc.components.AbstractLeadedComponent;
|
||||
import org.diylc.components.LineEndingStyle;
|
||||
import org.diylc.components.transform.SimpleComponentTransformer;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
@@ -58,6 +59,7 @@ public class CurvedTrace extends AbstractCurvedComponent<Void> implements ILayer
|
||||
|
||||
protected Size size = SIZE;
|
||||
private PCBLayer layer = PCBLayer._1;
|
||||
private LineEndingStyle endingStyle = LineEndingStyle.Round;
|
||||
|
||||
@Override
|
||||
protected Color getDefaultColor() {
|
||||
@@ -67,7 +69,7 @@ public class CurvedTrace extends AbstractCurvedComponent<Void> implements ILayer
|
||||
@Override
|
||||
protected void drawCurve(Path2D curve, Graphics2D g2d, ComponentState componentState, IDrawingObserver drawingObserver) {
|
||||
float thickness = (float) size.convertToPixels();
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(thickness));
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchStroke(thickness, getEndingStyle() == LineEndingStyle.Round ? BasicStroke.CAP_ROUND : BasicStroke.CAP_BUTT));
|
||||
Color curveColor =
|
||||
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
|
||||
: color;
|
||||
@@ -97,6 +99,18 @@ public class CurvedTrace extends AbstractCurvedComponent<Void> implements ILayer
|
||||
public void setLayer(PCBLayer layer) {
|
||||
this.layer = layer;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Ending Style")
|
||||
public LineEndingStyle getEndingStyle() {
|
||||
if (endingStyle == null) {
|
||||
endingStyle = LineEndingStyle.Round;
|
||||
}
|
||||
return endingStyle;
|
||||
}
|
||||
|
||||
public void setEndingStyle(LineEndingStyle endingStyle) {
|
||||
this.endingStyle = endingStyle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLayerId() {
|
||||
|
||||
@@ -63,15 +63,18 @@ public class LPSwitch extends AbstractTransparentComponent<String> implements IS
|
||||
private static Size LENGTH = new Size(1.3d, SizeUnit.in);
|
||||
private static Size BASE_LENGTH = new Size(18d, SizeUnit.mm);
|
||||
private static Size WAFER_THICKNESS = new Size(0.05d, SizeUnit.in);
|
||||
private static Size TERMINAL_SPACING = new Size(0.2d, SizeUnit.in);
|
||||
private static Size TERMINAL_SPACING_CONNECTED = new Size(0.2d, SizeUnit.in);
|
||||
private static Size TERMINAL_SPACING_DISCONNECTED = new Size(0.1d, SizeUnit.in);
|
||||
|
||||
private String value = "";
|
||||
private Point2D[] controlPoints = new Point2D[] {new Point2D.Double(0, 0), new Point2D.Double(0, 0), new Point2D.Double(0, 0), new Point2D.Double(0, 0)};
|
||||
transient Shape[] body;
|
||||
private Orientation orientation = Orientation.DEFAULT;
|
||||
private MiddleTerminalConfiguration middleTerminalConfiguration;
|
||||
|
||||
public LPSwitch() {
|
||||
super();
|
||||
middleTerminalConfiguration = MiddleTerminalConfiguration.Connected;
|
||||
updateControlPoints();
|
||||
}
|
||||
|
||||
@@ -127,7 +130,7 @@ public class LPSwitch extends AbstractTransparentComponent<String> implements IS
|
||||
g2d.setColor(finalBorderColor);
|
||||
g2d.draw(body[1]);
|
||||
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(3));
|
||||
g2d.setColor(METAL_COLOR);
|
||||
drawingObserver.startTracking();
|
||||
g2d.draw(body[2]);
|
||||
@@ -178,24 +181,44 @@ public class LPSwitch extends AbstractTransparentComponent<String> implements IS
|
||||
}
|
||||
}
|
||||
|
||||
int terminalSpacing = (int) TERMINAL_SPACING.convertToPixels();
|
||||
|
||||
GeneralPath terminalPath = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
|
||||
terminalPath.moveTo(x - waferThickness * 3 / 2, bodyY + 1);
|
||||
terminalPath.lineTo(x - waferThickness * 3 / 2, bodyY + baseLength);
|
||||
terminalPath.lineTo(x, y + length);
|
||||
|
||||
terminalPath.moveTo(x + waferThickness * 3 / 2, bodyY + 1);
|
||||
terminalPath.lineTo(x + waferThickness * 3 / 2, bodyY + baseLength);
|
||||
terminalPath.lineTo(x, y + length);
|
||||
if (getMiddleTerminalConfiguration() == MiddleTerminalConfiguration.Connected) {
|
||||
int terminalSpacing = (int) TERMINAL_SPACING_CONNECTED.convertToPixels();
|
||||
terminalPath.moveTo(x - waferThickness * 3 / 2, bodyY + 1);
|
||||
terminalPath.lineTo(x - waferThickness * 3 / 2, bodyY + baseLength);
|
||||
terminalPath.lineTo(x, y + length);
|
||||
|
||||
terminalPath.moveTo(x - waferThickness * 5 / 2, bodyY + 1);
|
||||
terminalPath.lineTo(x - waferThickness * 5 / 2, bodyY + baseLength);
|
||||
terminalPath.lineTo(x - terminalSpacing, y + length);
|
||||
terminalPath.moveTo(x + waferThickness * 3 / 2, bodyY + 1);
|
||||
terminalPath.lineTo(x + waferThickness * 3 / 2, bodyY + baseLength);
|
||||
terminalPath.lineTo(x, y + length);
|
||||
|
||||
terminalPath.moveTo(x + waferThickness * 5 / 2, bodyY + 1);
|
||||
terminalPath.lineTo(x + waferThickness * 5 / 2, bodyY + baseLength);
|
||||
terminalPath.lineTo(x + terminalSpacing, y + length);
|
||||
terminalPath.moveTo(x - waferThickness * 5 / 2, bodyY + 1);
|
||||
terminalPath.lineTo(x - waferThickness * 5 / 2, bodyY + baseLength);
|
||||
terminalPath.lineTo(x - terminalSpacing, y + length);
|
||||
|
||||
terminalPath.moveTo(x + waferThickness * 5 / 2, bodyY + 1);
|
||||
terminalPath.lineTo(x + waferThickness * 5 / 2, bodyY + baseLength);
|
||||
terminalPath.lineTo(x + terminalSpacing, y + length);
|
||||
} else {
|
||||
int terminalSpacing = (int) TERMINAL_SPACING_DISCONNECTED.convertToPixels();
|
||||
terminalPath.moveTo(x - waferThickness * 3 / 2, bodyY + 1);
|
||||
terminalPath.lineTo(x - waferThickness * 3 / 2, bodyY + baseLength);
|
||||
terminalPath.lineTo(x- terminalSpacing, y + length);
|
||||
|
||||
terminalPath.moveTo(x + waferThickness * 3 / 2, bodyY + 1);
|
||||
terminalPath.lineTo(x + waferThickness * 3 / 2, bodyY + baseLength);
|
||||
terminalPath.lineTo(x + terminalSpacing, y + length);
|
||||
|
||||
terminalPath.moveTo(x - waferThickness * 5 / 2, bodyY + 1);
|
||||
terminalPath.lineTo(x - waferThickness * 5 / 2, bodyY + baseLength);
|
||||
terminalPath.lineTo(x - terminalSpacing * 2, y + length);
|
||||
|
||||
terminalPath.moveTo(x + waferThickness * 5 / 2, bodyY + 1);
|
||||
terminalPath.lineTo(x + waferThickness * 5 / 2, bodyY + baseLength);
|
||||
terminalPath.lineTo(x + terminalSpacing * 2, y + length);
|
||||
}
|
||||
body[2] = terminalPath;
|
||||
|
||||
// Rotate if needed
|
||||
@@ -219,14 +242,37 @@ public class LPSwitch extends AbstractTransparentComponent<String> implements IS
|
||||
|
||||
@SuppressWarnings("incomplete-switch")
|
||||
private void updateControlPoints() {
|
||||
|
||||
Point2D[] newControlPoints = null;
|
||||
if (getMiddleTerminalConfiguration() == MiddleTerminalConfiguration.Connected && controlPoints.length == 5) {
|
||||
newControlPoints = new Point2D[4];
|
||||
} else if (getMiddleTerminalConfiguration() == MiddleTerminalConfiguration.Disconnected && controlPoints.length == 4) {
|
||||
newControlPoints = new Point2D[5];
|
||||
newControlPoints[4] = new Point2D.Double();
|
||||
}
|
||||
if (newControlPoints != null) {
|
||||
for (int i = 0; i < newControlPoints.length && i < controlPoints.length; i++) {
|
||||
newControlPoints[i] = controlPoints[i];
|
||||
}
|
||||
controlPoints = newControlPoints;
|
||||
}
|
||||
|
||||
double x = controlPoints[0].getX();
|
||||
double y = controlPoints[0].getY();
|
||||
int terminalSpacing = (int) TERMINAL_SPACING.convertToPixels();
|
||||
int length = (int) LENGTH.convertToPixels();
|
||||
|
||||
controlPoints[1].setLocation(x - terminalSpacing, y + length);
|
||||
controlPoints[2].setLocation(x, y + length);
|
||||
controlPoints[3].setLocation(x + terminalSpacing, y + length);
|
||||
if (getMiddleTerminalConfiguration() == MiddleTerminalConfiguration.Connected) {
|
||||
int terminalSpacing = (int) TERMINAL_SPACING_CONNECTED.convertToPixels();
|
||||
controlPoints[1].setLocation(x - terminalSpacing, y + length);
|
||||
controlPoints[2].setLocation(x, y + length);
|
||||
controlPoints[3].setLocation(x + terminalSpacing, y + length);
|
||||
} else {
|
||||
int terminalSpacing = (int) TERMINAL_SPACING_DISCONNECTED.convertToPixels();
|
||||
controlPoints[1].setLocation(x - terminalSpacing * 2, y + length);
|
||||
controlPoints[2].setLocation(x - terminalSpacing, y + length);
|
||||
controlPoints[3].setLocation(x + terminalSpacing, y + length);
|
||||
controlPoints[4].setLocation(x + terminalSpacing * 2, y + length);
|
||||
}
|
||||
|
||||
// Rotate if needed
|
||||
if (orientation != Orientation.DEFAULT) {
|
||||
@@ -331,8 +377,24 @@ public class LPSwitch extends AbstractTransparentComponent<String> implements IS
|
||||
// Invalidate the body
|
||||
body = null;
|
||||
}
|
||||
|
||||
// @Override
|
||||
|
||||
@EditableProperty(name = "Middle Terminals")
|
||||
public MiddleTerminalConfiguration getMiddleTerminalConfiguration() {
|
||||
if (middleTerminalConfiguration == null) {
|
||||
middleTerminalConfiguration = MiddleTerminalConfiguration.Connected;
|
||||
}
|
||||
return middleTerminalConfiguration;
|
||||
}
|
||||
|
||||
public void setMiddleTerminalConfiguration(
|
||||
MiddleTerminalConfiguration middleTerminalConfiguration) {
|
||||
this.middleTerminalConfiguration = middleTerminalConfiguration;
|
||||
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;
|
||||
@@ -347,27 +409,34 @@ public class LPSwitch extends AbstractTransparentComponent<String> implements IS
|
||||
|
||||
@Override
|
||||
public String getPositionName(int position) {
|
||||
switch (position) {
|
||||
case 0:
|
||||
return "Treble";
|
||||
case 1:
|
||||
return "Middle";
|
||||
case 2:
|
||||
return "Rhythm";
|
||||
}
|
||||
return null;
|
||||
return switch (position) {
|
||||
case 0 -> "Treble";
|
||||
case 1 -> "Middle";
|
||||
case 2 -> "Rhythm";
|
||||
default -> 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 && index2 > 0 && index1 < index2;
|
||||
case 2:
|
||||
return index1 == 2 && index2 == 3;
|
||||
if (getMiddleTerminalConfiguration() == MiddleTerminalConfiguration.Connected) {
|
||||
return switch (position) {
|
||||
case 0 -> index1 == 1 && index2 == 2;
|
||||
case 1 -> index1 > 0 && index2 > 0 && index1 < index2;
|
||||
case 2 -> index1 == 2 && index2 == 3;
|
||||
default -> false;
|
||||
};
|
||||
} else {
|
||||
return switch (position) {
|
||||
case 0 -> index1 == 1 && index2 == 2;
|
||||
case 1 -> (index1 == 1 && index2 == 2) || (index1 == 3 && index2 == 4);
|
||||
case 2 -> index1 == 3 && index2 == 4;
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public enum MiddleTerminalConfiguration {
|
||||
Connected, Disconnected
|
||||
}
|
||||
}
|
||||
|
||||
+693
@@ -0,0 +1,693 @@
|
||||
/*
|
||||
|
||||
DIY Layout Creator (DIYLC).
|
||||
Copyright (c) 2009-2025 held jointly by the individual authors.
|
||||
|
||||
This file is part of DIYLC.
|
||||
|
||||
DIYLC is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DIYLC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
package org.diylc.components.semiconductors;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
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.gerber.IGerberComponentSimple;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
@ComponentDescriptor(name = "Multiwatt IC", author = "Branislav Stojkovic", category = "Semiconductors",
|
||||
instanceNamePrefix = "IC", description = "Multiwatt package IC typically used for audio amplifiers of high power applications",
|
||||
zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE,
|
||||
enableCache = true)
|
||||
public class MultiwattIC extends AbstractTransparentComponent<String> implements IGerberComponentSimple {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static Color BODY_COLOR = Color.gray;
|
||||
public static Color BORDER_COLOR = Color.gray.darker();
|
||||
public static Color PIN_COLOR = Color.decode("#00B2EE");
|
||||
public static Color PIN_BORDER_COLOR = PIN_COLOR.darker();
|
||||
public static Color LABEL_COLOR = Color.white;
|
||||
public static Color TAB_COLOR = Color.lightGray;
|
||||
public static Color TAB_BORDER_COLOR = TAB_COLOR.darker();
|
||||
public static int EDGE_RADIUS = 6;
|
||||
public static Size PIN_SIZE = new Size(0.7d, SizeUnit.mm);
|
||||
public static Size THICKNESS = new Size(5d, SizeUnit.mm);
|
||||
public static Size TAB_THICKNESS = new Size(1.6d, SizeUnit.mm);
|
||||
// Multiwatt packages use 0.1 inch (2.54mm) spacing between pins in the same row
|
||||
public static Size PIN_SPACING = new Size(0.1d, SizeUnit.in);
|
||||
// Multiwatt packages have staggered pins with 0.2 inch (5.08mm) row spacing
|
||||
public static Size ROW_SPACING = new Size(0.2d, SizeUnit.in);
|
||||
// Lead offset due to bent leads
|
||||
public static Size LEAD_OFFSET = new Size(4d, SizeUnit.mm);
|
||||
|
||||
private String value = "";
|
||||
private Orientation orientation = Orientation.DEFAULT;
|
||||
private MultiwattType type = MultiwattType.MULTIWATT_11;
|
||||
private Point2D[] controlPoints = new Point2D[] {new Point2D.Double(0, 0)};
|
||||
protected Display display = Display.NAME;
|
||||
private Color bodyColor = BODY_COLOR;
|
||||
private Color borderColor = BORDER_COLOR;
|
||||
private Color labelColor = LABEL_COLOR;
|
||||
private Color tabColor = TAB_COLOR;
|
||||
private Color tabBorderColor = TAB_BORDER_COLOR;
|
||||
transient private Area[] body;
|
||||
|
||||
public MultiwattIC() {
|
||||
super();
|
||||
updateControlPoints();
|
||||
alpha = 100;
|
||||
}
|
||||
|
||||
@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 = "Type")
|
||||
public MultiwattType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(MultiwattType type) {
|
||||
this.type = type;
|
||||
updateControlPoints();
|
||||
// Reset body shape;
|
||||
body = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPointMoveFreely(int pointIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@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 Point2D 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(Point2D point, int index) {
|
||||
controlPoints[index].setLocation(point);
|
||||
body = null;
|
||||
}
|
||||
|
||||
private void updateControlPoints() {
|
||||
Point2D firstPoint = controlPoints[0];
|
||||
int pinCount = type.getPinCount();
|
||||
int pinsLeft = type.getPinsLeft();
|
||||
int pinsRight = type.getPinsRight();
|
||||
controlPoints = new Point2D.Double[pinCount];
|
||||
controlPoints[0] = firstPoint;
|
||||
double pinSpacing = PIN_SPACING.convertToPixels();
|
||||
double rowSpacing = ROW_SPACING.convertToPixels();
|
||||
// Update control points for staggered layout
|
||||
double dx1, dy1, dx2, dy2;
|
||||
|
||||
// Left side pins (first row)
|
||||
for (int i = 0; i < pinsLeft; i++) {
|
||||
switch (orientation) {
|
||||
case DEFAULT:
|
||||
dx1 = 0;
|
||||
dy1 = i * pinSpacing;
|
||||
break;
|
||||
case _90:
|
||||
dx1 = -i * pinSpacing;
|
||||
dy1 = 0;
|
||||
break;
|
||||
case _180:
|
||||
dx1 = 0;
|
||||
dy1 = -i * pinSpacing;
|
||||
break;
|
||||
case _270:
|
||||
dx1 = i * pinSpacing;
|
||||
dy1 = 0;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Unexpected orientation: " + orientation);
|
||||
}
|
||||
controlPoints[i] = new Point2D.Double((int) (firstPoint.getX() + dx1), (int) (firstPoint.getY() + dy1));
|
||||
}
|
||||
|
||||
// Right side pins (second row, staggered - offset by half pin spacing)
|
||||
for (int i = 0; i < pinsRight; i++) {
|
||||
switch (orientation) {
|
||||
case DEFAULT:
|
||||
dx2 = rowSpacing;
|
||||
dy2 = (i + 0.5) * pinSpacing; // Offset by half spacing for staggered effect
|
||||
break;
|
||||
case _90:
|
||||
dx2 = -(i + 0.5) * pinSpacing; // Offset by half spacing for staggered effect
|
||||
dy2 = rowSpacing;
|
||||
break;
|
||||
case _180:
|
||||
dx2 = -rowSpacing;
|
||||
dy2 = -(i + 0.5) * pinSpacing; // Offset by half spacing for staggered effect
|
||||
break;
|
||||
case _270:
|
||||
dx2 = (i + 0.5) * pinSpacing; // Offset by half spacing for staggered effect
|
||||
dy2 = -rowSpacing;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Unexpected orientation: " + orientation);
|
||||
}
|
||||
controlPoints[i + pinsLeft] = new Point2D.Double((int) (firstPoint.getX() + dx2), (int) (firstPoint.getY() + dy2));
|
||||
}
|
||||
}
|
||||
|
||||
public Area[] getBody() {
|
||||
if (body == null) {
|
||||
body = new Area[2];
|
||||
double x = controlPoints[0].getX();
|
||||
double y = controlPoints[0].getY();
|
||||
double pinSize = PIN_SIZE.convertToPixels();
|
||||
double pinSpacing = PIN_SPACING.convertToPixels();
|
||||
double rowSpacing = ROW_SPACING.convertToPixels();
|
||||
double tabThickness = TAB_THICKNESS.convertToPixels();
|
||||
double leadOffset = LEAD_OFFSET.convertToPixels();
|
||||
int pinsLeft = type.getPinsLeft();
|
||||
int pinsRight = type.getPinsRight();
|
||||
// Calculate height accounting for staggered pins (right row offset by half spacing)
|
||||
double leftRowHeight = (pinsLeft - 1) * pinSpacing;
|
||||
double rightRowHeight = (pinsRight - 1 + 0.5) * pinSpacing; // Account for half-spacing offset
|
||||
double maxHeight = Math.max(leftRowHeight, rightRowHeight) + pinSpacing; // Add spacing for last pin
|
||||
double bodyX, bodyY, bodyWidth, bodyHeight;
|
||||
double tabX, tabY, tabWidth, tabHeight;
|
||||
|
||||
switch (orientation) {
|
||||
case DEFAULT:
|
||||
bodyWidth = rowSpacing - pinSize;
|
||||
bodyHeight = maxHeight;
|
||||
// Offset body to the left by lead offset (bent leads)
|
||||
bodyX = x + pinSize / 2 - leadOffset;
|
||||
bodyY = y - pinSpacing / 2;
|
||||
// Tab on the left side (where there are more pins) inside the body bounds
|
||||
tabX = bodyX;
|
||||
tabY = bodyY;
|
||||
tabWidth = tabThickness;
|
||||
tabHeight = bodyHeight;
|
||||
break;
|
||||
case _90:
|
||||
bodyWidth = maxHeight;
|
||||
bodyHeight = rowSpacing - pinSize;
|
||||
// Body positioned between the two pin rows
|
||||
// Left pins extend to negative X, body starts from leftmost pin
|
||||
// For _90: left pins go left (negative X), so leftmost is at x - (pinsLeft-1)*pinSpacing
|
||||
// Offset body upward by lead offset (bent leads)
|
||||
bodyX = x - (pinsLeft - 1) * pinSpacing - pinSpacing / 2;
|
||||
bodyY = y + pinSize / 2 - leadOffset;
|
||||
// Tab on the top side (where there are more pins - left row at y) inside the body bounds
|
||||
tabX = bodyX;
|
||||
tabY = bodyY;
|
||||
tabWidth = bodyWidth;
|
||||
tabHeight = tabThickness;
|
||||
break;
|
||||
case _180:
|
||||
bodyWidth = rowSpacing - pinSize;
|
||||
bodyHeight = maxHeight;
|
||||
// Body positioned between the two pin rows
|
||||
// For _180: left pins go up (negative Y), right pins at x - rowSpacing
|
||||
// Left row is at x, right row is at x - rowSpacing
|
||||
// Pins extend upward from y, so body should start from top of pin array
|
||||
// Offset body to the right by lead offset (bent leads)
|
||||
bodyX = x - rowSpacing + pinSize / 2 + leadOffset;
|
||||
bodyY = y - (pinsLeft - 1) * pinSpacing - pinSpacing / 2;
|
||||
// Tab on the right side (where there are more pins - left row at x) inside the body bounds
|
||||
tabX = bodyX + bodyWidth - tabThickness;
|
||||
tabY = bodyY;
|
||||
tabWidth = tabThickness;
|
||||
tabHeight = bodyHeight;
|
||||
break;
|
||||
case _270:
|
||||
bodyWidth = maxHeight;
|
||||
bodyHeight = rowSpacing - pinSize;
|
||||
// Body positioned between the two pin rows
|
||||
// For _270: left pins go right (positive X), so leftmost is at x
|
||||
// Left row is at y, right row is at y - rowSpacing
|
||||
// Similar to _90 but mirrored
|
||||
// Offset body downward by lead offset (bent leads)
|
||||
bodyX = x - pinSpacing / 2;
|
||||
bodyY = y - rowSpacing + pinSize / 2 + leadOffset;
|
||||
// Tab on the bottom side (where there are more pins - left row at y) inside the body bounds
|
||||
tabX = bodyX;
|
||||
tabY = bodyY + bodyHeight - tabThickness;
|
||||
tabWidth = bodyWidth;
|
||||
tabHeight = tabThickness;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Unexpected orientation: " + orientation);
|
||||
}
|
||||
body[0] = new Area(new Rectangle2D.Double(bodyX, bodyY, bodyWidth, bodyHeight));
|
||||
body[1] = new Area(new Rectangle2D.Double(tabX, tabY, tabWidth, tabHeight));
|
||||
}
|
||||
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];
|
||||
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1f));
|
||||
if (!outlineMode) {
|
||||
int pinSize = (int) PIN_SIZE.convertToPixels() / 2 * 2;
|
||||
Rectangle2D bodyBounds = mainArea.getBounds2D();
|
||||
double leadThickness = pinSize; // Lead width matches pin size
|
||||
|
||||
for (Point2D point : controlPoints) {
|
||||
double pinX = point.getX();
|
||||
double pinY = point.getY();
|
||||
|
||||
// Check if pin is inside the body
|
||||
boolean insideBody = mainArea.contains(pinX, pinY);
|
||||
|
||||
if (insideBody) {
|
||||
// Draw pin as square inside body
|
||||
Rectangle2D rect = new Rectangle2D.Double(pinX - pinSize / 2,
|
||||
pinY - pinSize / 2, pinSize, pinSize);
|
||||
g2d.setColor(PIN_COLOR);
|
||||
drawingObserver.startTracking();
|
||||
g2d.fill(rect);
|
||||
drawingObserver.stopTracking();
|
||||
g2d.setColor(PIN_BORDER_COLOR);
|
||||
g2d.draw(rect);
|
||||
} else {
|
||||
// Draw rectangular lead from body edge to pin position
|
||||
double bodyX = bodyBounds.getX();
|
||||
double bodyY = bodyBounds.getY();
|
||||
double bodyWidth = bodyBounds.getWidth();
|
||||
double bodyHeight = bodyBounds.getHeight();
|
||||
|
||||
// Find the closest point on body edge to the pin
|
||||
double edgeX, edgeY;
|
||||
|
||||
// Determine which side of the body the pin is on
|
||||
if (pinX < bodyX) {
|
||||
// Pin is to the left of body
|
||||
edgeX = bodyX;
|
||||
edgeY = Math.max(bodyY, Math.min(bodyY + bodyHeight, pinY));
|
||||
} else if (pinX > bodyX + bodyWidth) {
|
||||
// Pin is to the right of body
|
||||
edgeX = bodyX + bodyWidth;
|
||||
edgeY = Math.max(bodyY, Math.min(bodyY + bodyHeight, pinY));
|
||||
} else if (pinY < bodyY) {
|
||||
// Pin is above body
|
||||
edgeX = Math.max(bodyX, Math.min(bodyX + bodyWidth, pinX));
|
||||
edgeY = bodyY;
|
||||
} else {
|
||||
// Pin is below body
|
||||
edgeX = Math.max(bodyX, Math.min(bodyX + bodyWidth, pinX));
|
||||
edgeY = bodyY + bodyHeight;
|
||||
}
|
||||
|
||||
// Draw rectangular lead
|
||||
double leadX = Math.min(edgeX, pinX) - leadThickness / 2;
|
||||
double leadY = Math.min(edgeY, pinY) - leadThickness / 2;
|
||||
double leadWidth = Math.abs(pinX - edgeX) + leadThickness;
|
||||
double leadHeight = Math.abs(pinY - edgeY) + leadThickness;
|
||||
|
||||
// If lead is horizontal or vertical, draw as rectangle
|
||||
if (Math.abs(pinX - edgeX) < 0.1) {
|
||||
// Vertical lead
|
||||
leadWidth = leadThickness;
|
||||
leadX = edgeX - leadThickness / 2;
|
||||
} else if (Math.abs(pinY - edgeY) < 0.1) {
|
||||
// Horizontal lead
|
||||
leadHeight = leadThickness;
|
||||
leadY = edgeY - leadThickness / 2;
|
||||
}
|
||||
|
||||
Rectangle2D leadRect = new Rectangle2D.Double(leadX, leadY, leadWidth, leadHeight);
|
||||
g2d.setColor(PIN_COLOR);
|
||||
drawingObserver.startTracking();
|
||||
g2d.fill(leadRect);
|
||||
drawingObserver.stopTracking();
|
||||
g2d.setColor(PIN_BORDER_COLOR);
|
||||
g2d.draw(leadRect);
|
||||
|
||||
// Draw pin at the end of the lead
|
||||
Rectangle2D pinRect = new Rectangle2D.Double(pinX - pinSize / 2,
|
||||
pinY - pinSize / 2, pinSize, pinSize);
|
||||
g2d.setColor(PIN_COLOR);
|
||||
drawingObserver.startTracking();
|
||||
g2d.fill(pinRect);
|
||||
drawingObserver.stopTracking();
|
||||
g2d.setColor(PIN_BORDER_COLOR);
|
||||
g2d.draw(pinRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drawingObserver.startTracking();
|
||||
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);
|
||||
drawingObserver.stopTracking();
|
||||
|
||||
// Draw heat sink tab
|
||||
Area tabArea = getBody()[1];
|
||||
Color finalTabColor;
|
||||
if (outlineMode) {
|
||||
Theme theme =
|
||||
(Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
||||
finalTabColor = theme.getOutlineColor();
|
||||
} else {
|
||||
finalTabColor = tabColor;
|
||||
}
|
||||
g2d.setColor(finalTabColor);
|
||||
drawingObserver.startTracking();
|
||||
g2d.fill(tabArea);
|
||||
drawingObserver.stopTracking();
|
||||
g2d.setComposite(oldComposite);
|
||||
|
||||
if (!outlineMode) {
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
g2d.setColor(tabBorderColor);
|
||||
g2d.draw(tabArea);
|
||||
}
|
||||
|
||||
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));
|
||||
g2d.draw(mainArea);
|
||||
// Draw label.
|
||||
g2d.setFont(project.getFont());
|
||||
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 = (int) (bounds.getX() + (bounds.width - textWidth) / 2);
|
||||
int y = (int) (bounds.getY() + (bounds.height - textHeight) / 2 + fontMetrics.getAscent());
|
||||
g2d.drawString(label, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
int margin = 2;
|
||||
int pinSize = 2 * width / 32;
|
||||
int leftPinX = width / 6 + 9; // Move left pins 9px to the right (4px + 3px + 2px)
|
||||
int rightPinX = 5 * width / 6;
|
||||
int leadOffset = (int) (LEAD_OFFSET.convertToPixels() * width / 100); // Scale lead offset for icon
|
||||
int bodyX = leftPinX + pinSize - leadOffset + 2; // Offset body to the left, then move 2px to the right
|
||||
int bodyWidth = (rightPinX - bodyX - pinSize) / 2 + 2; // Thinner body, make 2px thicker
|
||||
int bodyHeight = height - 2 * margin;
|
||||
int bodyY = margin;
|
||||
|
||||
// Calculate pin spacing to use all vertical space
|
||||
// Use same spacing for both rows, with front row offset by half spacing
|
||||
int backPins = 4;
|
||||
int frontPins = 3;
|
||||
// Use the spacing that fits the back row (more pins)
|
||||
int pinSpacing = (bodyHeight - pinSize) / (backPins - 1);
|
||||
int backStartY = margin + pinSize / 2 + 1; // Move pins 1px down
|
||||
// Front pins start with half spacing offset for staggered effect
|
||||
int frontStartY = margin + pinSize / 2 + pinSpacing / 2 + 1; // Move pins 1px down
|
||||
|
||||
// Draw thin body between pin rows
|
||||
g2d.setColor(BODY_COLOR);
|
||||
g2d.fillRect(bodyX, bodyY, bodyWidth, bodyHeight);
|
||||
g2d.setColor(BORDER_COLOR);
|
||||
g2d.drawRect(bodyX, bodyY, bodyWidth, bodyHeight);
|
||||
|
||||
// Draw heat sink tab on left side (where there are more pins)
|
||||
int tabWidth = pinSize * 2;
|
||||
g2d.setColor(TAB_COLOR);
|
||||
g2d.fillRect(bodyX, bodyY, tabWidth, bodyHeight);
|
||||
g2d.setColor(TAB_BORDER_COLOR);
|
||||
g2d.drawRect(bodyX, bodyY, tabWidth, bodyHeight);
|
||||
|
||||
// Draw 4 pins in the back (left row, more pins) as squares - inside body
|
||||
g2d.setColor(PIN_COLOR);
|
||||
for (int i = 0; i < backPins; i++) {
|
||||
int pinY = backStartY + i * pinSpacing - pinSize / 2;
|
||||
g2d.fillRect(leftPinX - pinSize, pinY, pinSize, pinSize);
|
||||
g2d.setColor(PIN_BORDER_COLOR);
|
||||
g2d.drawRect(leftPinX - pinSize, pinY, pinSize, pinSize);
|
||||
g2d.setColor(PIN_COLOR);
|
||||
}
|
||||
|
||||
// Draw 3 pins in the front (right row, fewer pins) with leads going left to body
|
||||
// Use same spacing as back row, just offset by half spacing
|
||||
g2d.setColor(PIN_COLOR);
|
||||
for (int i = 0; i < frontPins; i++) {
|
||||
int pinY = frontStartY + i * pinSpacing;
|
||||
int pinX = rightPinX;
|
||||
int bodyRightEdge = bodyX + bodyWidth;
|
||||
|
||||
// Draw lead from body edge to pin (horizontal lead going left)
|
||||
if (pinX > bodyRightEdge) {
|
||||
int leadX = bodyRightEdge;
|
||||
int leadY = pinY - pinSize / 2;
|
||||
int leadWidth = pinX - bodyRightEdge;
|
||||
int leadHeight = pinSize;
|
||||
|
||||
g2d.fillRect(leadX, leadY, leadWidth, leadHeight);
|
||||
g2d.setColor(PIN_BORDER_COLOR);
|
||||
g2d.drawRect(leadX, leadY, leadWidth, leadHeight);
|
||||
g2d.setColor(PIN_COLOR);
|
||||
}
|
||||
|
||||
// Draw pin at the end of the lead
|
||||
g2d.fillRect(pinX - pinSize / 2, pinY - pinSize / 2, pinSize, pinSize);
|
||||
g2d.setColor(PIN_BORDER_COLOR);
|
||||
g2d.drawRect(pinX - pinSize / 2, pinY - pinSize / 2, pinSize, pinSize);
|
||||
g2d.setColor(PIN_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
@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 = "Tab")
|
||||
public Color getTabColor() {
|
||||
if (tabColor == null) {
|
||||
tabColor = TAB_COLOR;
|
||||
}
|
||||
return tabColor;
|
||||
}
|
||||
|
||||
public void setTabColor(Color tabColor) {
|
||||
this.tabColor = tabColor;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Tab Border")
|
||||
public Color getTabBorderColor() {
|
||||
if (tabBorderColor == null) {
|
||||
tabBorderColor = TAB_BORDER_COLOR;
|
||||
}
|
||||
return tabBorderColor;
|
||||
}
|
||||
|
||||
public void setTabBorderColor(Color tabBorderColor) {
|
||||
this.tabBorderColor = tabBorderColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle2D getCachingBounds() {
|
||||
double minX = Integer.MAX_VALUE;
|
||||
double maxX = Integer.MIN_VALUE;
|
||||
double minY = Integer.MAX_VALUE;
|
||||
double maxY = Integer.MIN_VALUE;
|
||||
int margin = 50;
|
||||
for (int i = 0; i < getControlPointCount(); i++) {
|
||||
Point2D p = getControlPoint(i);
|
||||
if (p.getX() < minX)
|
||||
minX = p.getX();
|
||||
if (p.getX() > maxX)
|
||||
maxX = p.getX();
|
||||
if (p.getY() < minY)
|
||||
minY = p.getY();
|
||||
if (p.getY() > maxY)
|
||||
maxY = p.getY();
|
||||
}
|
||||
|
||||
return new Rectangle2D.Double(minX - margin, minY - margin, maxX - minX + 2 * margin, maxY - minY + 2 * margin);
|
||||
}
|
||||
|
||||
public static enum MultiwattType {
|
||||
// Multiwatt-11: 6 pins on left, 5 pins on right (staggered)
|
||||
MULTIWATT_11(11, 6, 5),
|
||||
// Multiwatt-15: 8 pins on left, 7 pins on right (staggered)
|
||||
MULTIWATT_15(15, 8, 7);
|
||||
|
||||
private final int pinCount;
|
||||
private final int pinsLeft;
|
||||
private final int pinsRight;
|
||||
|
||||
MultiwattType(int pinCount, int pinsLeft, int pinsRight) {
|
||||
this.pinCount = pinCount;
|
||||
this.pinsLeft = pinsLeft;
|
||||
this.pinsRight = pinsRight;
|
||||
}
|
||||
|
||||
public int getPinCount() {
|
||||
return pinCount;
|
||||
}
|
||||
|
||||
public int getPinsLeft() {
|
||||
return pinsLeft;
|
||||
}
|
||||
|
||||
public int getPinsRight() {
|
||||
return pinsRight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Multiwatt " + pinCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ public class TapeMeasure extends AbstractLeadedComponent<String> {
|
||||
g2d.setColor(COLOR);
|
||||
g2d.drawLine(1, height - 2, width / 4, height * 3 / 4 - 1);
|
||||
g2d.drawLine(width * 3 / 4, height / 4 - 1, width - 2, 1);
|
||||
g2d.setBackground(Color.black);
|
||||
g2d.setColor(Color.black);
|
||||
g2d.fillPolygon(new int[] {1, 1, 4}, new int[] {height - 4, height - 1, height - 1}, 3);
|
||||
g2d.fillPolygon(new int[] {width - 4, width - 1, width - 1}, new int[] {1, 1, 4}, 3);
|
||||
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
|
||||
@@ -174,6 +174,7 @@ public class TapeMeasure extends AbstractLeadedComponent<String> {
|
||||
g2d.rotate(theta);
|
||||
|
||||
g2d.setFont(font);
|
||||
g2d.setColor(componentState == ComponentState.SELECTED ? SELECTION_COLOR : labelColor);
|
||||
g2d.drawString(text, x, y);
|
||||
}
|
||||
|
||||
|
||||
+14
@@ -70,6 +70,20 @@ public class PinHeaderTransformer implements IComponentTransformer {
|
||||
@Override
|
||||
public void mirror(IDIYComponent<?> component, Point2D center, int direction) {
|
||||
PinHeader header = (PinHeader) component;
|
||||
int controlPointCount = header.getControlPointCount();
|
||||
|
||||
// Handle single-pin case
|
||||
if (controlPointCount == 1) {
|
||||
Point2D p = header.getControlPoint(0);
|
||||
if (direction == IComponentTransformer.HORIZONTAL) {
|
||||
double dx = 2 * (center.getX() - p.getX());
|
||||
header.setControlPoint(new Point2D.Double(p.getX() + dx, p.getY()), 0);
|
||||
} else {
|
||||
double dy = 2 * (center.getY() - p.getY());
|
||||
header.setControlPoint(new Point2D.Double(p.getX(), p.getY() + dy), 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (direction == IComponentTransformer.HORIZONTAL) {
|
||||
double dx = 2 * (center.getX() - header.getControlPoint(1).getX());
|
||||
|
||||
@@ -1,15 +1,117 @@
|
||||
package org.diylc.netlist;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.diylc.components.guitar.LPSwitch;
|
||||
import org.diylc.components.guitar.LPSwitch.MiddleTerminalConfiguration;
|
||||
import org.diylc.common.Orientation;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
public class LPSwitchTests extends AbstractSwitchTests {
|
||||
|
||||
@Test
|
||||
public void testLPSwitch() {
|
||||
public void testLPSwitchConnected() {
|
||||
LPSwitch lpSwitch = new LPSwitch();
|
||||
// Default configuration is Connected
|
||||
assertEquals(MiddleTerminalConfiguration.Connected, lpSwitch.getMiddleTerminalConfiguration());
|
||||
// Connected has 4 control points (0, 1, 2, 3)
|
||||
assertEquals(4, ((IDIYComponent<?>) lpSwitch).getControlPointCount());
|
||||
// Position 0 (Treble): 1-2 connected
|
||||
// Position 1 (Middle): 1-2, 1-3, 2-3 connected (all terminals > 0 connected)
|
||||
// Position 2 (Rhythm): 2-3 connected
|
||||
String[] validCombinations = new String[] {"0,1,2", "1,1,2", "1,2,3", "1,1,3", "2,2,3"};
|
||||
testSwitch(lpSwitch, validCombinations);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLPSwitchDisconnected() {
|
||||
LPSwitch lpSwitch = new LPSwitch();
|
||||
lpSwitch.setMiddleTerminalConfiguration(MiddleTerminalConfiguration.Disconnected);
|
||||
assertEquals(MiddleTerminalConfiguration.Disconnected, lpSwitch.getMiddleTerminalConfiguration());
|
||||
// Disconnected has 5 control points (0, 1, 2, 3, 4)
|
||||
assertEquals(5, ((IDIYComponent<?>) lpSwitch).getControlPointCount());
|
||||
// Position 0 (Treble): 1-2 connected
|
||||
// Position 1 (Middle): 1-2 and 3-4 connected (both pairs)
|
||||
// Position 2 (Rhythm): 3-4 connected
|
||||
String[] validCombinations = new String[] {"0,1,2", "1,1,2", "1,3,4", "2,3,4"};
|
||||
testSwitch(lpSwitch, validCombinations);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testControlPointCountChange() {
|
||||
LPSwitch lpSwitch = new LPSwitch();
|
||||
// Start with Connected (4 points)
|
||||
assertEquals(4, ((IDIYComponent<?>) lpSwitch).getControlPointCount());
|
||||
|
||||
// Switch to Disconnected (5 points)
|
||||
lpSwitch.setMiddleTerminalConfiguration(MiddleTerminalConfiguration.Disconnected);
|
||||
assertEquals(5, ((IDIYComponent<?>) lpSwitch).getControlPointCount());
|
||||
|
||||
// Switch back to Connected (4 points)
|
||||
lpSwitch.setMiddleTerminalConfiguration(MiddleTerminalConfiguration.Connected);
|
||||
assertEquals(4, ((IDIYComponent<?>) lpSwitch).getControlPointCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPositionNames() {
|
||||
LPSwitch lpSwitch = new LPSwitch();
|
||||
assertEquals(3, lpSwitch.getPositionCount());
|
||||
assertEquals("Treble", lpSwitch.getPositionName(0));
|
||||
assertEquals("Middle", lpSwitch.getPositionName(1));
|
||||
assertEquals("Rhythm", lpSwitch.getPositionName(2));
|
||||
assertNull(lpSwitch.getPositionName(3)); // Invalid position
|
||||
assertNull(lpSwitch.getPositionName(-1)); // Invalid position
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOrientationDoesNotAffectConnectivity() {
|
||||
LPSwitch lpSwitch = new LPSwitch();
|
||||
// Test with default Connected configuration
|
||||
String[] validCombinations = new String[] {"0,1,2", "1,1,2", "1,2,3", "1,1,3", "2,2,3"};
|
||||
|
||||
// Test all orientations - connectivity should remain the same
|
||||
for (Orientation orientation : Orientation.values()) {
|
||||
lpSwitch.setOrientation(orientation);
|
||||
assertEquals(orientation, lpSwitch.getOrientation());
|
||||
// Connectivity should be unchanged regardless of orientation
|
||||
testSwitch(lpSwitch, validCombinations);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOrientationWithDisconnectedConfiguration() {
|
||||
LPSwitch lpSwitch = new LPSwitch();
|
||||
lpSwitch.setMiddleTerminalConfiguration(MiddleTerminalConfiguration.Disconnected);
|
||||
String[] validCombinations = new String[] {"0,1,2", "1,1,2", "1,3,4", "2,3,4"};
|
||||
|
||||
// Test all orientations with Disconnected configuration
|
||||
for (Orientation orientation : Orientation.values()) {
|
||||
lpSwitch.setOrientation(orientation);
|
||||
assertEquals(orientation, lpSwitch.getOrientation());
|
||||
// Connectivity should be unchanged regardless of orientation
|
||||
testSwitch(lpSwitch, validCombinations);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfigurationSwitchPreservesConnectivity() {
|
||||
LPSwitch lpSwitch = new LPSwitch();
|
||||
|
||||
// Test Connected configuration
|
||||
lpSwitch.setMiddleTerminalConfiguration(MiddleTerminalConfiguration.Connected);
|
||||
String[] connectedCombinations = new String[] {"0,1,2", "1,1,2", "1,2,3", "1,1,3", "2,2,3"};
|
||||
testSwitch(lpSwitch, connectedCombinations);
|
||||
|
||||
// Switch to Disconnected
|
||||
lpSwitch.setMiddleTerminalConfiguration(MiddleTerminalConfiguration.Disconnected);
|
||||
String[] disconnectedCombinations = new String[] {"0,1,2", "1,1,2", "1,3,4", "2,3,4"};
|
||||
testSwitch(lpSwitch, disconnectedCombinations);
|
||||
|
||||
// Switch back to Connected
|
||||
lpSwitch.setMiddleTerminalConfiguration(MiddleTerminalConfiguration.Connected);
|
||||
testSwitch(lpSwitch, connectedCombinations);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.diylc.serialization.ProjectFileManager;
|
||||
import org.diylc.swing.gui.MainFrame;
|
||||
import org.diylc.swing.gui.TemplateDialog;
|
||||
import org.diylc.swing.plugins.file.ProjectDrawingProvider;
|
||||
import org.diylc.utils.SwingUtils;
|
||||
|
||||
/**
|
||||
* Main class that runs DIYLC.
|
||||
@@ -137,6 +138,12 @@ public class DIYLCStarter {
|
||||
|
||||
try {
|
||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
|
||||
// Fix tooltip colors for Linux systems where they may be unreadable
|
||||
SwingUtils.fixTooltipColors();
|
||||
|
||||
// Apply configurable font scaling from VM argument: -Dorg.diylc.fontScaleFactor=X
|
||||
org.diylc.utils.FontScalingUtils.applyFontScaling();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Could not set Look&Feel", e);
|
||||
}
|
||||
|
||||
+12
-1
@@ -21,6 +21,7 @@
|
||||
*/
|
||||
package org.diylc.swing.plugins.canvas;
|
||||
|
||||
import java.awt.Cursor;
|
||||
import java.awt.dnd.DragGestureEvent;
|
||||
import java.awt.dnd.DragGestureListener;
|
||||
import java.awt.event.InputEvent;
|
||||
@@ -54,7 +55,17 @@ class CanvasDragGestureListener implements DragGestureListener {
|
||||
}
|
||||
canvasPanel.setClickInProgress(false);
|
||||
presenter.dragStarted(dge.getDragOrigin(), dge.getDragAction(), forceReSelection);
|
||||
dge.startDrag(presenter.getCursorAt(dge.getDragOrigin(), false, false, false), new EmptyTransferable(), new CanvasSourceListener(
|
||||
// Get the appropriate cursor from the presenter (e.g., HAND_CURSOR over components)
|
||||
// Preserve the cursor context (HAND_CURSOR, CROSSHAIR_CURSOR, etc.) for drag operations
|
||||
// On Linux, DEFAULT_CURSOR during drag can show "No" cursor, so use MOVE_CURSOR as fallback
|
||||
Cursor requestedCursor = presenter.getCursorAt(dge.getDragOrigin(), false, false, false);
|
||||
Cursor dragCursor = requestedCursor;
|
||||
// Only replace DEFAULT_CURSOR with MOVE_CURSOR on Linux to prevent "No" cursor issue
|
||||
// Preserve HAND_CURSOR, CROSSHAIR_CURSOR, etc. as they are appropriate for drag operations
|
||||
if (requestedCursor.getType() == Cursor.DEFAULT_CURSOR) {
|
||||
dragCursor = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR);
|
||||
}
|
||||
dge.startDrag(dragCursor, new EmptyTransferable(), new CanvasSourceListener(
|
||||
presenter));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,6 +271,8 @@ public class CanvasPlugin implements IPlugIn{
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
if (scrollPane.isMouseScrollMode())
|
||||
return;
|
||||
// if needed uncomment this code, it forces the cursor to refresh when it's stuck
|
||||
// canvasPanel.setCursor(null);
|
||||
canvasPanel.setCursor(plugInPort.getCursorAt(e.getPoint(), Utils.isMac() ? e.isMetaDown() : e.isControlDown(),
|
||||
e.isShiftDown(), e.isAltDown()));
|
||||
plugInPort.mouseMoved(e.getPoint(), Utils.isMac() ? e.isMetaDown() : e.isControlDown(),
|
||||
@@ -359,35 +361,40 @@ public class CanvasPlugin implements IPlugIn{
|
||||
double extraSpace = plugInPort.getExtraSpace();
|
||||
scrollPane.setZeroLocation(new Point2D.Double(extraSpace, extraSpace));
|
||||
|
||||
// disable built-in scrolling mechanism, we'll do it manually
|
||||
scrollPane.setWheelScrollingEnabled(false);
|
||||
// Enable built-in wheel scrolling to support horizontal scroll from tilt wheels on Windows/Linux
|
||||
// The scroll pane's native handling supports horizontal scrolling from tilt wheels
|
||||
scrollPane.setWheelScrollingEnabled(true);
|
||||
|
||||
scrollPane.addMouseWheelListener(new MouseWheelListener() {
|
||||
|
||||
@Override
|
||||
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||
final JScrollBar horizontalScrollBar = scrollPane.getHorizontalScrollBar();
|
||||
final JScrollBar verticalScrollBar = scrollPane.getVerticalScrollBar();
|
||||
|
||||
boolean wheelZoom =
|
||||
configManager.readBoolean(IPlugInPort.WHEEL_ZOOM_KEY, false);
|
||||
|
||||
// Handle zoom - consume to prevent default scrolling
|
||||
if (wheelZoom || (Utils.isMac() ? e.isMetaDown() : e.isControlDown())) {
|
||||
e.consume();
|
||||
CanvasPlugin.this.zoom(e.getWheelRotation());
|
||||
return;
|
||||
}
|
||||
|
||||
// For Shift+wheel (horizontal scroll), handle manually to maintain existing behavior
|
||||
if (e.isShiftDown()) {
|
||||
e.consume(); // Consume to prevent default handling
|
||||
final JScrollBar horizontalScrollBar = scrollPane.getHorizontalScrollBar();
|
||||
int iScrollAmount = e.getScrollAmount();
|
||||
int iNewValue = horizontalScrollBar.getValue()
|
||||
+ horizontalScrollBar.getBlockIncrement() * iScrollAmount * e.getWheelRotation();
|
||||
if (iNewValue <= horizontalScrollBar.getMaximum())
|
||||
if (iNewValue >= horizontalScrollBar.getMinimum() && iNewValue <= horizontalScrollBar.getMaximum())
|
||||
horizontalScrollBar.setValue(iNewValue);
|
||||
} else {
|
||||
int iScrollAmount = e.getScrollAmount();
|
||||
int iNewValue = verticalScrollBar.getValue()
|
||||
+ verticalScrollBar.getBlockIncrement() * iScrollAmount * e.getWheelRotation();
|
||||
if (iNewValue <= verticalScrollBar.getMaximum())
|
||||
verticalScrollBar.setValue(iNewValue);
|
||||
return;
|
||||
}
|
||||
|
||||
// For regular vertical scrolling and horizontal scrolling from tilt wheels,
|
||||
// let the scroll pane handle it natively. The scroll pane's built-in handling
|
||||
// supports horizontal scroll events from tilt wheels on Windows/Linux.
|
||||
// We don't consume the event, so the scroll pane can process it.
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+31
-2
@@ -21,11 +21,16 @@
|
||||
*/
|
||||
package org.diylc.swing.plugins.canvas;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Point;
|
||||
import java.awt.dnd.DragSourceDragEvent;
|
||||
import java.awt.dnd.DragSourceDropEvent;
|
||||
import java.awt.dnd.DragSourceEvent;
|
||||
import java.awt.dnd.DragSourceListener;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import org.diylc.common.IPlugInPort;
|
||||
|
||||
@@ -50,13 +55,16 @@ class CanvasSourceListener implements DragSourceListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dragEnter(DragSourceDragEvent dsde) {}
|
||||
public void dragEnter(DragSourceDragEvent dsde) {
|
||||
updateCursor(dsde);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dragExit(DragSourceEvent dse) {}
|
||||
|
||||
@Override
|
||||
public void dragOver(DragSourceDragEvent dsde) {
|
||||
updateCursor(dsde);
|
||||
Point p = dsde.getDragSourceContext().getComponent().getMousePosition();
|
||||
if (p != null) {
|
||||
dsde.getDragSourceContext().getComponent().firePropertyChange("dragPoint", p.x, p.y);
|
||||
@@ -64,5 +72,26 @@ class CanvasSourceListener implements DragSourceListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropActionChanged(DragSourceDragEvent dsde) {}
|
||||
public void dropActionChanged(DragSourceDragEvent dsde) {
|
||||
updateCursor(dsde);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the cursor during drag operations using the presenter as the single source of truth.
|
||||
* If the presenter returns DEFAULT_CURSOR, uses MOVE_CURSOR to prevent "No" cursor issues.
|
||||
*/
|
||||
private void updateCursor(DragSourceDragEvent dsde) {
|
||||
Point mousePos = dsde.getDragSourceContext().getComponent().getMousePosition();
|
||||
if (mousePos != null) {
|
||||
// Use presenter as single source of truth for cursor
|
||||
Cursor requestedCursor = presenter.getCursorAt(mousePos, false, false, false);
|
||||
Cursor dragCursor = requestedCursor;
|
||||
// If DEFAULT_CURSOR, use MOVE_CURSOR to prevent "No" cursor during drag operations
|
||||
if (requestedCursor.getType() == Cursor.DEFAULT_CURSOR) {
|
||||
dragCursor = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR);
|
||||
}
|
||||
dsde.getDragSourceContext().setCursor(null);
|
||||
dsde.getDragSourceContext().setCursor(dragCursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+29
-6
@@ -21,15 +21,13 @@
|
||||
*/
|
||||
package org.diylc.swing.plugins.canvas;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.dnd.DnDConstants;
|
||||
import java.awt.dnd.DropTargetDragEvent;
|
||||
import java.awt.dnd.DropTargetDropEvent;
|
||||
import java.awt.dnd.DropTargetEvent;
|
||||
import java.awt.dnd.DropTargetListener;
|
||||
import java.awt.*;
|
||||
import java.awt.dnd.*;
|
||||
|
||||
import org.diylc.common.IPlugInPort;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
|
||||
/**
|
||||
* {@link DropTargetListener} for {@link CanvasPanel}.
|
||||
@@ -106,10 +104,35 @@ class CanvasTargetListener implements DropTargetListener {
|
||||
@Override
|
||||
public void drop(DropTargetDropEvent dtde) {
|
||||
presenter.dragEnded(dtde.getLocation());
|
||||
updateCursor(dtde);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropActionChanged(DropTargetDragEvent dtde) {
|
||||
presenter.dragActionChanged(dtde.getDropAction());
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the cursor during drag operations using the presenter as the single source of truth.
|
||||
* If the presenter returns DEFAULT_CURSOR, uses MOVE_CURSOR to prevent "No" cursor issues.
|
||||
*/
|
||||
private void updateCursor(DropTargetDropEvent dsde) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Point mousePos = dsde.getDropTargetContext().getComponent().getMousePosition();
|
||||
if (mousePos != null) {
|
||||
// Use presenter as single source of truth for cursor
|
||||
Cursor requestedCursor = presenter.getCursorAt(mousePos, false, false, false);
|
||||
Cursor dragCursor = requestedCursor;
|
||||
// If DEFAULT_CURSOR, use MOVE_CURSOR to prevent "No" cursor during drag operations
|
||||
if (requestedCursor.getType() == Cursor.DEFAULT_CURSOR) {
|
||||
dragCursor = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR);
|
||||
}
|
||||
dsde.getDropTargetContext().getComponent().setCursor(null);
|
||||
dsde.getDropTargetContext().getComponent().setCursor(dragCursor);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,11 +43,13 @@ public class FileMenuPlugin implements IPlugIn, IDynamicSubmenuHandler {
|
||||
|
||||
private static final String FILE_TITLE = "File";
|
||||
private static final String TRACE_MASK_TITLE = "Trace Mask";
|
||||
private static final String SILK_SCREEN_TITLE = "Silkscreen";
|
||||
private static final String INTEGRATION_TITLE = "Integration";
|
||||
private static final String EXPORT_TITLE = "Export";
|
||||
private static final String PROJECT_TITLE = "Project";
|
||||
|
||||
private ProjectDrawingProvider drawingProvider;
|
||||
private TraceMaskDrawingProvider traceMaskDrawingProvider;
|
||||
private SilkScreenDrawingProvider silkScreenDrawingProvider;
|
||||
|
||||
private ISwingUI swingUI;
|
||||
private IPlugInPort plugInPort;
|
||||
@@ -62,6 +64,7 @@ public class FileMenuPlugin implements IPlugIn, IDynamicSubmenuHandler {
|
||||
this.plugInPort = plugInPort;
|
||||
this.drawingProvider = new ProjectDrawingProvider(plugInPort, false, true, false);
|
||||
this.traceMaskDrawingProvider = new TraceMaskDrawingProvider(plugInPort);
|
||||
this.silkScreenDrawingProvider = new SilkScreenDrawingProvider(plugInPort);
|
||||
|
||||
ActionFactory actionFactory = ActionFactory.getInstance();
|
||||
swingUI.injectMenuAction(actionFactory.createNewAction(plugInPort), FILE_TITLE);
|
||||
@@ -73,15 +76,17 @@ public class FileMenuPlugin implements IPlugIn, IDynamicSubmenuHandler {
|
||||
swingUI.injectMenuAction(actionFactory.createSaveAsAction(plugInPort, swingUI), FILE_TITLE);
|
||||
swingUI.injectDynamicSubmenu("Recent Files", IconLoader.History.getIcon(), FILE_TITLE, this);
|
||||
swingUI.injectMenuAction(null, FILE_TITLE);
|
||||
swingUI.injectSubmenu(EXPORT_TITLE, IconLoader.Export.getIcon(), FILE_TITLE);
|
||||
|
||||
swingUI.injectSubmenu(PROJECT_TITLE, IconLoader.Project.getIcon(), FILE_TITLE);
|
||||
swingUI.injectMenuAction(
|
||||
actionFactory.createExportPDFAction(plugInPort, drawingProvider, swingUI, ""), EXPORT_TITLE);
|
||||
actionFactory.createExportPDFAction(plugInPort, drawingProvider, swingUI, ""), PROJECT_TITLE);
|
||||
swingUI.injectMenuAction(
|
||||
actionFactory.createExportPNGAction(plugInPort, drawingProvider, swingUI, ""), EXPORT_TITLE);
|
||||
actionFactory.createExportPNGAction(plugInPort, drawingProvider, swingUI, ""), PROJECT_TITLE);
|
||||
swingUI.injectMenuAction(
|
||||
actionFactory.createExportGerberAction(plugInPort, swingUI), EXPORT_TITLE);
|
||||
actionFactory.createExportGerberAction(plugInPort, swingUI), PROJECT_TITLE);
|
||||
swingUI.injectMenuAction(actionFactory.createPrintAction(drawingProvider, swingUI,
|
||||
Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx()), FILE_TITLE);
|
||||
Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx()), PROJECT_TITLE);
|
||||
|
||||
swingUI.injectSubmenu(TRACE_MASK_TITLE, IconLoader.TraceMask.getIcon(), FILE_TITLE);
|
||||
swingUI.injectMenuAction(actionFactory.createExportPDFAction(plugInPort,
|
||||
traceMaskDrawingProvider, swingUI, " (mask)"), TRACE_MASK_TITLE);
|
||||
@@ -92,6 +97,17 @@ public class FileMenuPlugin implements IPlugIn, IDynamicSubmenuHandler {
|
||||
Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx() | KeyEvent.SHIFT_DOWN_MASK),
|
||||
TRACE_MASK_TITLE);
|
||||
|
||||
swingUI.injectSubmenu(SILK_SCREEN_TITLE, IconLoader.Silkscreen.getIcon(), FILE_TITLE);
|
||||
swingUI.injectMenuAction(actionFactory.createExportPDFAction(plugInPort,
|
||||
silkScreenDrawingProvider, swingUI, " (silkscreen)"), SILK_SCREEN_TITLE);
|
||||
swingUI.injectMenuAction(actionFactory.createExportPNGAction(plugInPort,
|
||||
silkScreenDrawingProvider, swingUI, " (silkscreen)"), SILK_SCREEN_TITLE);
|
||||
swingUI.injectMenuAction(
|
||||
actionFactory.createPrintAction(silkScreenDrawingProvider, swingUI,
|
||||
Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx() | KeyEvent.ALT_DOWN_MASK),
|
||||
SILK_SCREEN_TITLE);
|
||||
|
||||
|
||||
swingUI.injectMenuAction(null, FILE_TITLE);
|
||||
swingUI.injectSubmenu(INTEGRATION_TITLE, IconLoader.Node.getIcon(), FILE_TITLE);
|
||||
swingUI.injectMenuAction(actionFactory.createImportBlocksAction(swingUI, plugInPort),
|
||||
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
|
||||
DIY Layout Creator (DIYLC).
|
||||
Copyright (c) 2009-2025 held jointly by the individual authors.
|
||||
|
||||
This file is part of DIYLC.
|
||||
|
||||
DIYLC is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DIYLC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
package org.diylc.swing.plugins.file;
|
||||
|
||||
import org.diylc.common.DrawOption;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.filter.PCBLayerFilter;
|
||||
import org.diylc.filter.SilkScreenFilter;
|
||||
import org.diylc.swingframework.IDrawingProvider;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* {@link IDrawingProvider} implementation that uses {@link IPlugInPort} to draw a project onto the
|
||||
* canvas.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class SilkScreenDrawingProvider implements IDrawingProvider {
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
|
||||
public SilkScreenDrawingProvider(IPlugInPort plugInPort) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getSize() {
|
||||
return plugInPort.getCanvasDimensions(false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int page, Graphics g, double zoomFactor) {
|
||||
plugInPort.draw((Graphics2D) g, EnumSet.of(DrawOption.ANTIALIASING, DrawOption.OUTLINE_MODE, DrawOption.MONOCHROMATIC),
|
||||
new SilkScreenFilter(), zoomFactor, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPageCount() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -37,7 +37,7 @@ import org.diylc.common.DrawOption;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.PCBLayer;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.presenter.PCBLayerFilter;
|
||||
import org.diylc.filter.PCBLayerFilter;
|
||||
|
||||
/**
|
||||
* {@link IDrawingProvider} implementation that uses {@link IPlugInPort} to draw a project onto the
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
*
|
||||
* DIY Layout Creator (DIYLC).
|
||||
* Copyright (c) 2009-2025 held jointly by the individual authors.
|
||||
*
|
||||
* This file is part of DIYLC.
|
||||
*
|
||||
* DIYLC is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* DIYLC is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package org.diylc.utils;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.util.Enumeration;
|
||||
import javax.swing.UIDefaults;
|
||||
import javax.swing.UIManager;
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
|
||||
/**
|
||||
* Utility class for applying a configurable font scaling factor to all UI components.
|
||||
*
|
||||
* The scaling factor is stored in the application configuration and can be set
|
||||
* programmatically or through the configuration system.
|
||||
* For example, a factor of 1.5 will make all fonts 50% larger.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class FontScalingUtils {
|
||||
|
||||
private static final double DEFAULT_FONT_SCALE_FACTOR = 1.0;
|
||||
private static final double MIN_FONT_SCALE_FACTOR = 0.5;
|
||||
private static final double MAX_FONT_SCALE_FACTOR = 3.0;
|
||||
|
||||
/**
|
||||
* Gets the font scaling factor from ConfigurationManager.
|
||||
*
|
||||
* @return The scaling factor (defaults to 1.0 if not set or invalid)
|
||||
*/
|
||||
public static double getFontScaleFactor() {
|
||||
try {
|
||||
Object factorObj = ConfigurationManager.getInstance().readObject(
|
||||
IPlugInPort.FONT_SCALE_FACTOR_KEY, DEFAULT_FONT_SCALE_FACTOR);
|
||||
|
||||
if (factorObj instanceof Number) {
|
||||
double factor = ((Number) factorObj).doubleValue();
|
||||
// Validate the factor is reasonable (between 0.5 and 3.0)
|
||||
if (factor >= MIN_FONT_SCALE_FACTOR && factor <= MAX_FONT_SCALE_FACTOR) {
|
||||
return factor;
|
||||
} else {
|
||||
System.err.println("Warning: Font scale factor " + factor + " is out of range ("
|
||||
+ MIN_FONT_SCALE_FACTOR + "-" + MAX_FONT_SCALE_FACTOR + "). Using default "
|
||||
+ DEFAULT_FONT_SCALE_FACTOR);
|
||||
return DEFAULT_FONT_SCALE_FACTOR;
|
||||
}
|
||||
} else if (factorObj instanceof String) {
|
||||
// Handle string values (for backward compatibility or manual config editing)
|
||||
try {
|
||||
double factor = Double.parseDouble((String) factorObj);
|
||||
if (factor >= MIN_FONT_SCALE_FACTOR && factor <= MAX_FONT_SCALE_FACTOR) {
|
||||
return factor;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// Invalid string format, use default
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("Warning: Could not read font scale factor from configuration: " + e.getMessage());
|
||||
}
|
||||
|
||||
return DEFAULT_FONT_SCALE_FACTOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the font scaling factor in ConfigurationManager.
|
||||
*
|
||||
* @param factor The scaling factor (must be between 0.5 and 3.0)
|
||||
* @return true if the factor was set successfully, false if invalid
|
||||
*/
|
||||
public static boolean setFontScaleFactor(double factor) {
|
||||
if (factor < MIN_FONT_SCALE_FACTOR || factor > MAX_FONT_SCALE_FACTOR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
ConfigurationManager.getInstance().writeValue(IPlugInPort.FONT_SCALE_FACTOR_KEY, factor);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
System.err.println("Warning: Could not write font scale factor to configuration: " + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the font scaling factor to all UIManager font defaults.
|
||||
* This should be called once during application initialization, after setting the
|
||||
* Look and Feel but before creating any UI components.
|
||||
*
|
||||
* The scaling factor is read from ConfigurationManager using the key
|
||||
* IPlugInPort.FONT_SCALE_FACTOR_KEY. The factor should be a number between 0.5 and 3.0
|
||||
* (e.g., 1.5 for 50% larger fonts). Use setFontScaleFactor() to change the value
|
||||
* programmatically.
|
||||
*/
|
||||
public static void applyFontScaling() {
|
||||
double scaleFactor = getFontScaleFactor();
|
||||
|
||||
// If factor is 1.0, no scaling needed
|
||||
if (scaleFactor == 1.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
UIDefaults defaults = UIManager.getDefaults();
|
||||
Enumeration<Object> keys = defaults.keys();
|
||||
|
||||
while (keys.hasMoreElements()) {
|
||||
Object key = keys.nextElement();
|
||||
Object value = defaults.get(key);
|
||||
|
||||
// Check if this is a font property
|
||||
if (value instanceof Font font) {
|
||||
float newSize = (float) (font.getSize() * scaleFactor);
|
||||
Font scaledFont = font.deriveFont(newSize);
|
||||
defaults.put(key, scaledFont);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("Warning: Could not apply font scaling: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,8 @@ public enum IconLoader {
|
||||
ComponentLarge("component_large.png"), ImportNetlist("import_netlist.png"), SplashIC("splash_ic.png"),
|
||||
ComponentPreferences("component_preferences.png"), ComponentReplace("component_replace.png"), Barcode("barcode.png"),
|
||||
DocumentGerber("document_gerber.png"), DocumentX2("document_x2.png"), Export("export.png"), Multimeter("multimeter.png"),
|
||||
Patreon("patreon.png"), Brain("brain.png"), Tables("tables.png");
|
||||
Patreon("patreon.png"), Brain("brain.png"), Tables("tables.png"), Silkscreen("silkscreen.png"),
|
||||
Project("project.png");
|
||||
|
||||
protected String name;
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
*
|
||||
* DIY Layout Creator (DIYLC).
|
||||
* Copyright (c) 2009-2025 held jointly by the individual authors.
|
||||
*
|
||||
* This file is part of DIYLC.
|
||||
*
|
||||
* DIYLC is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* DIYLC is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package org.diylc.utils;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.function.Function;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
/**
|
||||
* Utility class for Swing UI-related operations.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class SwingUtils {
|
||||
|
||||
/**
|
||||
* Fixes tooltip colors for Linux systems where they may be unreadable.
|
||||
* Some Linux L&F themes set white text on light backgrounds, making tooltips invisible.
|
||||
* This method ensures tooltips always have dark text on light background for readability.
|
||||
*
|
||||
* Should be called after UIManager.setLookAndFeel() to override system defaults.
|
||||
*/
|
||||
public static void fixTooltipColors() {
|
||||
Color tooltipBg = UIManager.getColor("ToolTip.background");
|
||||
Color tooltipFg = UIManager.getColor("ToolTip.foreground");
|
||||
|
||||
// Helper function to calculate brightness (0.0 = black, 1.0 = white)
|
||||
Function<Color, Double> getBrightness = (c) -> {
|
||||
return (0.299 * c.getRed() + 0.587 * c.getGreen() + 0.114 * c.getBlue()) / 255.0;
|
||||
};
|
||||
|
||||
// Check if we have a problematic color combination (light text on light background)
|
||||
boolean needsFix = false;
|
||||
if (tooltipFg != null && tooltipBg != null) {
|
||||
double fgBrightness = getBrightness.apply(tooltipFg);
|
||||
double bgBrightness = getBrightness.apply(tooltipBg);
|
||||
// If both foreground and background are light, it's unreadable
|
||||
if (fgBrightness > 0.7 && bgBrightness > 0.5) {
|
||||
needsFix = true;
|
||||
}
|
||||
} else if (tooltipFg == null || tooltipBg == null) {
|
||||
// Missing color definitions - set safe defaults
|
||||
needsFix = true;
|
||||
}
|
||||
|
||||
if (needsFix) {
|
||||
UIManager.put("ToolTip.background", new Color(255, 255, 220)); // Light yellow
|
||||
UIManager.put("ToolTip.foreground", Color.BLACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 869 B |
Binary file not shown.
|
After Width: | Height: | Size: 906 B |
@@ -195,6 +195,7 @@ Image|Bild
|
||||
Immediate Only|Nur sofort
|
||||
Import|Importieren
|
||||
Import Building Blocks|Bausteine importieren
|
||||
Import Netlist|Netlist importieren
|
||||
Import Variants|Varianten importieren
|
||||
In-Line D-44|Inline D-44
|
||||
In-line|Inline
|
||||
@@ -231,6 +232,7 @@ Loadline Editor|Kennliniendiagramm
|
||||
Lock|Sperren
|
||||
Log|Log
|
||||
Log In|Anmelden
|
||||
Look for|Suchen
|
||||
Log Out|Abmelden
|
||||
Lug Size|Lötpadgröße
|
||||
Lugs|Lötpad
|
||||
@@ -303,6 +305,7 @@ Power Rating|Nennleistung
|
||||
Power Strip|Steckdosenleiste
|
||||
Primary CT|Primärer Mittelabgriff
|
||||
Print...|Drucken...
|
||||
Project|Projekt
|
||||
Project Cloud|Projekt Cloud
|
||||
Public Announcement|Öffentliche Ankündigung
|
||||
Radius|Radius
|
||||
@@ -457,3 +460,34 @@ Zoom|Vergrößern
|
||||
base of 10|Zehntel
|
||||
base of 2|Achtel
|
||||
hold %s and drag to unstick from|Halten Sie X gedrückt und ziehen Sie, zum lösen von
|
||||
Are you sure you want to clear the chat history for this project? This action cannot be undone!|Sind Sie sicher, dass Sie den Chat-Verlauf für dieses Projekt löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden!
|
||||
Component reordering is possible only when Project Explorer is sorted by z-index.|Komponenten können nur neu angeordnet werden, wenn der Projekt-Explorer nach z-index sortiert ist.
|
||||
Could not apply changes. Check the log for details.|Änderungen konnten nicht angewendet werden. Überprüfen Sie die Protokolldatei für Details.
|
||||
Exporting outline for board %s to file %s|Exportiere Umriss für Platte %s in Datei %s
|
||||
Failed to export the project to gerber. Please check the log for details|Fehler beim Exportieren des Projekts zu Gerber. Bitte überprüfen Sie die Protokolldatei für Details
|
||||
Forgot Password?|Passwort vergessen?
|
||||
Gerber Export|Gerber Export
|
||||
Gerber export completed successfully. The following files were created:%s|Gerber-Export erfolgreich abgeschlossen. Die folgenden Dateien wurden erstellt:%s
|
||||
Get Premium|Premium erhalten
|
||||
Netlist files|Netlist-Dateien
|
||||
No proximity issues detected.|Keine Näherungsprobleme erkannt.
|
||||
Nothing to export.|Nichts zu exportieren.
|
||||
Password|Passwort
|
||||
Send|Senden
|
||||
There are some components that are outside of the bounds of boards.%sThey will be ignored unless you add a board component underneath them.%sDo you want to continue?|Es gibt einige Komponenten, die außerhalb der Grenzen der Platten liegen.%sSie werden ignoriert, es sei denn, Sie fügen eine Plattenkomponente darunter hinzu.%sMöchten Sie fortfahren?
|
||||
User Name|Benutzername
|
||||
AI Circuit Analyzer|KI-Schaltungsanalysator
|
||||
Cloud|Cloud
|
||||
Compare With...|Vergleichen mit...
|
||||
Connect to Patreon|Mit Patreon verbinden
|
||||
Export|Exportieren
|
||||
Export to Gerber|Als Gerber exportieren
|
||||
Generate DIYLC Netlist (excl. Switches)|DIYLC-Netzliste erstellen (ohne Schalter)
|
||||
Generate DIYLC Netlist (incl. Switches)|DIYLC-Netzliste erstellen (mit Schaltern)
|
||||
Generate Spice Netlist (excl. Switches)|Spice-Netzliste erstellen (ohne Schalter)
|
||||
Generate Spice Netlist (incl. Switches)|Spice-Netzliste erstellen (mit Schaltern)
|
||||
Silkscreen|Siebdruck
|
||||
Virtual Multimeter (excl. Switches)|Virtuelles Multimeter (ohne Schalter)
|
||||
Virtual Multimeter (incl. Switches)|Virtuelles Multimeter (mit Schaltern)
|
||||
Become a Patreon and enjoy perks|Werden Sie Patreon und genießen Sie Vorteile
|
||||
Join Patreon|Patreon beitreten
|
||||
|
||||
@@ -300,6 +300,7 @@ Power Rating
|
||||
Power Strip
|
||||
Primary CT
|
||||
Print...
|
||||
Project
|
||||
Project Cloud
|
||||
Public Announcement
|
||||
Radius
|
||||
@@ -462,4 +463,35 @@ Update Axis
|
||||
Apply Variant
|
||||
Save as Building Block
|
||||
Select
|
||||
Unlock
|
||||
Unlock
|
||||
Are you sure you want to clear the chat history for this project? This action cannot be undone!
|
||||
Component reordering is possible only when Project Explorer is sorted by z-index.
|
||||
Could not apply changes. Check the log for details.
|
||||
Exporting outline for board %s to file %s
|
||||
Failed to export the project to gerber. Please check the log for details
|
||||
Forgot Password?
|
||||
Gerber Export
|
||||
Gerber export completed successfully. The following files were created:%s
|
||||
Get Premium
|
||||
Netlist files
|
||||
No proximity issues detected.
|
||||
Nothing to export.
|
||||
Password
|
||||
Send
|
||||
There are some components that are outside of the bounds of boards.%sThey will be ignored unless you add a board component underneath them.%sDo you want to continue?
|
||||
User Name
|
||||
AI Circuit Analyzer
|
||||
Cloud
|
||||
Compare With...
|
||||
Connect to Patreon
|
||||
Export
|
||||
Export to Gerber
|
||||
Generate DIYLC Netlist (excl. Switches)
|
||||
Generate DIYLC Netlist (incl. Switches)
|
||||
Generate Spice Netlist (excl. Switches)
|
||||
Generate Spice Netlist (incl. Switches)
|
||||
Silkscreen
|
||||
Virtual Multimeter (excl. Switches)
|
||||
Virtual Multimeter (incl. Switches)
|
||||
Become a Patreon and enjoy perks
|
||||
Join Patreon
|
||||
@@ -193,6 +193,7 @@ Image|Imagen
|
||||
Immediate Only|Solo Inmediato
|
||||
Import|Importar
|
||||
Import Building Blocks|Importar Bloques
|
||||
Import Netlist|Importar Lista de Redes
|
||||
Import Variants|Importar variantes
|
||||
In-Line D-44|En Línea D-44
|
||||
In-line|En línea
|
||||
@@ -298,6 +299,7 @@ Power Rating|Potencia Nominal
|
||||
Power Strip|Regleta
|
||||
Primary CT|Toma Central en primario
|
||||
Print...|Imprimir...
|
||||
Project|Proyecto
|
||||
Project Cloud|Proyectos en la Nube
|
||||
Public Announcement|Anuncio Público
|
||||
Radius|Radio
|
||||
@@ -457,4 +459,35 @@ Update Axis|Actualizar Ejes
|
||||
Apply Variant|Aplicar Variante
|
||||
Save as Building Block|Guardar como Bloque
|
||||
Select|Seleccionar
|
||||
Unlock|Desbloquear
|
||||
Unlock|Desbloquear
|
||||
Are you sure you want to clear the chat history for this project? This action cannot be undone!|¿Está seguro de que desea borrar el historial de chat de este proyecto? ¡Esta acción no se puede deshacer!
|
||||
Component reordering is possible only when Project Explorer is sorted by z-index.|El reordenamiento de componentes solo es posible cuando el Explorador de Proyectos está ordenado por z-index.
|
||||
Could not apply changes. Check the log for details.|No se pudieron aplicar los cambios. Verifique el registro para más detalles.
|
||||
Exporting outline for board %s to file %s|Exportando el contorno de la placa %s al archivo %s
|
||||
Failed to export the project to gerber. Please check the log for details|No se pudo exportar el proyecto a gerber. Por favor verifique el registro para más detalles
|
||||
Forgot Password?|¿Olvidó la Contraseña?
|
||||
Gerber Export|Exportar Gerber
|
||||
Gerber export completed successfully. The following files were created:%s|La exportación Gerber se completó exitosamente. Se crearon los siguientes archivos:%s
|
||||
Get Premium|Obtener Premium
|
||||
Netlist files|Archivos de lista de red
|
||||
No proximity issues detected.|No se detectaron problemas de proximidad.
|
||||
Nothing to export.|Nada que exportar.
|
||||
Password|Contraseña
|
||||
Send|Enviar
|
||||
There are some components that are outside of the bounds of boards.%sThey will be ignored unless you add a board component underneath them.%sDo you want to continue?|Hay algunos componentes que están fuera de los límites de las placas.%sSerán ignorados a menos que agregue un componente de placa debajo de ellos.%s¿Desea continuar?
|
||||
User Name|Nombre de Usuario
|
||||
AI Circuit Analyzer|Analizador de Circuitos IA
|
||||
Cloud|Nube
|
||||
Compare With...|Comparar con...
|
||||
Connect to Patreon|Conectar con Patreon
|
||||
Export|Exportar
|
||||
Export to Gerber|Exportar a Gerber
|
||||
Generate DIYLC Netlist (excl. Switches)|Generar Lista de Redes DIYLC (sin interruptores)
|
||||
Generate DIYLC Netlist (incl. Switches)|Generar Lista de Redes DIYLC (con interruptores)
|
||||
Generate Spice Netlist (excl. Switches)|Generar Lista Especial de Redes (sin interruptores)
|
||||
Generate Spice Netlist (incl. Switches)|Generar Lista Especial de Redes (con interruptores)
|
||||
Silkscreen|Serigrafía
|
||||
Virtual Multimeter (excl. Switches)|Multímetro Virtual (sin interruptores)
|
||||
Virtual Multimeter (incl. Switches)|Multímetro Virtual (con interruptores)
|
||||
Become a Patreon and enjoy perks|Conviértete en Patreon y disfruta de beneficios
|
||||
Join Patreon|Únete a Patreon
|
||||
@@ -193,6 +193,7 @@ Image|Image
|
||||
Immediate Only|Immédiatement proches seulement
|
||||
Import|Importer
|
||||
Import Building Blocks|Importer des blocs de construction
|
||||
Import Netlist|Importer la liste de connexions
|
||||
Import Variants|Importer des variantes
|
||||
In-Line D-44|En ligne D-44
|
||||
In-line|En ligne
|
||||
@@ -226,6 +227,7 @@ Light|Lumière
|
||||
Lock|Verrouiller
|
||||
Log In|Se connecter
|
||||
Log Out|Se déconnecter
|
||||
Look for|Rechercher
|
||||
Lug Size|Taille des cosses
|
||||
Lugs|Cosses
|
||||
Make a Donation|Faire un don
|
||||
@@ -294,6 +296,7 @@ Power Rating|Puissance nominale
|
||||
Power Strip|Multiprise
|
||||
Primary CT|Prise centrale primaire
|
||||
Print...|Imprimer...
|
||||
Project|Projet
|
||||
Project Cloud|Projet Cloud
|
||||
Public Announcement|Annonce publique
|
||||
Radius|Rayon
|
||||
@@ -440,17 +443,48 @@ Zoom|Zoom
|
||||
base of 10|base de 10
|
||||
base of 2|base de 2
|
||||
hold %s and drag to unstick from|maintenez %s et faites glisser pour décoller
|
||||
Add a Curve
|
||||
Clear
|
||||
Insert Image
|
||||
Load From File
|
||||
Loadline Editor
|
||||
Max Current (mA)
|
||||
Max Dissipation (W)
|
||||
Max Voltage (V)
|
||||
Save To File
|
||||
Update Axis
|
||||
Apply Variant
|
||||
Save as Building Block
|
||||
Select
|
||||
Unlock
|
||||
Add a Curve|Ajouter une courbe
|
||||
Clear|Effacer
|
||||
Insert Image|Insérer une image
|
||||
Load From File|Charger depuis un fichier
|
||||
Loadline Editor|Éditeur de ligne de charge
|
||||
Max Current (mA)|Courant maximum (mA)
|
||||
Max Dissipation (W)|Dissipation maximale (W)
|
||||
Max Voltage (V)|Tension maximale (V)
|
||||
Save To File|Enregistrer dans un fichier
|
||||
Update Axis|Mettre à jour les axes
|
||||
Apply Variant|Appliquer la variante
|
||||
Save as Building Block|Enregistrer comme bloc de construction
|
||||
Select|Sélectionner
|
||||
Unlock|Déverrouiller
|
||||
Are you sure you want to clear the chat history for this project? This action cannot be undone!|Êtes-vous sûr de vouloir effacer l'historique de chat de ce projet? Cette action ne peut pas être annulée!
|
||||
Component reordering is possible only when Project Explorer is sorted by z-index.|Le réordonnancement des composants n'est possible que lorsque l'Explorateur de projet est trié par z-index.
|
||||
Could not apply changes. Check the log for details.|Impossible d'appliquer les modifications. Consultez le journal pour plus de détails.
|
||||
Exporting outline for board %s to file %s|Exportation du contour de la carte %s vers le fichier %s
|
||||
Failed to export the project to gerber. Please check the log for details|Échec de l'exportation du projet vers gerber. Veuillez consulter le journal pour plus de détails
|
||||
Forgot Password?|Mot de passe oublié?
|
||||
Gerber Export|Export Gerber
|
||||
Gerber export completed successfully. The following files were created:%s|L'export Gerber a été complété avec succès. Les fichiers suivants ont été créés:%s
|
||||
Get Premium|Obtenir Premium
|
||||
Netlist files|Fichiers de liste de connexions
|
||||
No proximity issues detected.|Aucun problème de proximité détecté.
|
||||
Nothing to export.|Rien à exporter.
|
||||
Password|Mot de passe
|
||||
Send|Envoyer
|
||||
There are some components that are outside of the bounds of boards.%sThey will be ignored unless you add a board component underneath them.%sDo you want to continue?|Il y a des composants qui sont en dehors des limites des cartes.%sIls seront ignorés sauf si vous ajoutez un composant de carte en dessous.%sVoulez-vous continuer?
|
||||
User Name|Nom d'utilisateur
|
||||
AI Circuit Analyzer|Analyseur de circuit IA
|
||||
Cloud|Cloud
|
||||
Compare With...|Comparer avec...
|
||||
Connect to Patreon|Se connecter à Patreon
|
||||
Export|Exporter
|
||||
Export to Gerber|Exporter vers Gerber
|
||||
Generate DIYLC Netlist (excl. Switches)|Générer la Netlist DIYLC (sans commutateurs)
|
||||
Generate DIYLC Netlist (incl. Switches)|Générer la Netlist DIYLC (avec commutateurs)
|
||||
Generate Spice Netlist (excl. Switches)|Générer la Netlist Spice (sans commutateurs)
|
||||
Generate Spice Netlist (incl. Switches)|Générer la Netlist Spice (avec commutateurs)
|
||||
Silkscreen|Sérigraphie
|
||||
Virtual Multimeter (excl. Switches)|Multimètre virtuel (sans commutateurs)
|
||||
Virtual Multimeter (incl. Switches)|Multimètre virtuel (avec commutateurs)
|
||||
Become a Patreon and enjoy perks|Devenez un Patreon et profitez d'avantages
|
||||
Join Patreon|Rejoindre Patreon
|
||||
@@ -196,6 +196,7 @@ Image|Immagine
|
||||
Immediate Only|Solo immediato
|
||||
Import|Importa
|
||||
Import Building Blocks|Importa blocchi di costruzione
|
||||
Import Netlist|Importa netlist
|
||||
Import Variants|Importa varianti
|
||||
In-Line D-44|In linea D-44
|
||||
In-line|In linea
|
||||
@@ -235,6 +236,7 @@ Lock|Blocco
|
||||
Log|Accesso
|
||||
Log In|Accedi
|
||||
Log Out|Esci
|
||||
Look for|Cerca
|
||||
Lug Size|Dimensione dell'aletta
|
||||
Lugs|Alette
|
||||
Make a Donation|Fai una donazione
|
||||
@@ -307,6 +309,7 @@ Power Rating|Potenza nominale
|
||||
Power Strip|Ciabatta
|
||||
Primary CT|CT primario
|
||||
Print...|Stampa ...
|
||||
Project|Progetto
|
||||
Project Cloud|Progetto Cloud
|
||||
Public Announcement|Annuncio pubblico
|
||||
Radius|raggio
|
||||
@@ -456,4 +459,35 @@ Y-axis|Asse Y
|
||||
Zoom|Ingrandimento
|
||||
base of 10|base di 10
|
||||
base of 2|base di 2
|
||||
hold %s and drag to unstick from|tieni premuto %s e trascina per sbloccare da
|
||||
hold %s and drag to unstick from|tieni premuto %s e trascina per sbloccare da
|
||||
Are you sure you want to clear the chat history for this project? This action cannot be undone!|Sei sicuro di voler cancellare la cronologia della chat per questo progetto? Questa azione non può essere annullata!
|
||||
Component reordering is possible only when Project Explorer is sorted by z-index.|Il riordinamento dei componenti è possibile solo quando Project Explorer è ordinato per z-index.
|
||||
Could not apply changes. Check the log for details.|Impossibile applicare le modifiche. Controlla il registro per i dettagli.
|
||||
Exporting outline for board %s to file %s|Esportazione del contorno per la scheda %s nel file %s
|
||||
Failed to export the project to gerber. Please check the log for details|Impossibile esportare il progetto in gerber. Controlla il registro per i dettagli
|
||||
Forgot Password?|Password dimenticata?
|
||||
Gerber Export|Esporta Gerber
|
||||
Gerber export completed successfully. The following files were created:%s|Esportazione Gerber completata con successo. Sono stati creati i seguenti file:%s
|
||||
Get Premium|Ottieni Premium
|
||||
Netlist files|File netlist
|
||||
No proximity issues detected.|Nessun problema di prossimità rilevato.
|
||||
Nothing to export.|Niente da esportare.
|
||||
Password|Password
|
||||
Send|Invia
|
||||
There are some components that are outside of the bounds of boards.%sThey will be ignored unless you add a board component underneath them.%sDo you want to continue?|Ci sono alcuni componenti che sono al di fuori dei limiti delle schede.%sVerranno ignorati a meno che non aggiungi un componente scheda sotto di loro.%sVuoi continuare?
|
||||
User Name|Nome utente
|
||||
AI Circuit Analyzer|Analizzatore di Circuiti IA
|
||||
Cloud|Cloud
|
||||
Compare With...|Confronta con...
|
||||
Connect to Patreon|Connetti a Patreon
|
||||
Export|Esporta
|
||||
Export to Gerber|Esporta in Gerber
|
||||
Generate DIYLC Netlist (excl. Switches)|Genera netlist DIYLC (escl. interruttori)
|
||||
Generate DIYLC Netlist (incl. Switches)|Genera netlist DIYLC (incl. interruttori)
|
||||
Generate Spice Netlist (excl. Switches)|Genera netlist Spice (escl. interruttori)
|
||||
Generate Spice Netlist (incl. Switches)|Genera netlist Spice (incl. interruttori)
|
||||
Silkscreen|Serigrafia
|
||||
Virtual Multimeter (excl. Switches)|Multimetro Virtuale (escl. interruttori)
|
||||
Virtual Multimeter (incl. Switches)|Multimetro Virtuale (incl. interruttori)
|
||||
Become a Patreon and enjoy perks|Diventa un Patreon e goditi i vantaggi
|
||||
Join Patreon|Unisciti a Patreon
|
||||
@@ -195,6 +195,7 @@ Image|Afbeelding
|
||||
Immediate Only|Alleen direct
|
||||
Import|Importeren
|
||||
Import Building Blocks|Bouwstenen importeren
|
||||
Import Netlist|Netlist importeren
|
||||
Import Variants|Varianten importeren
|
||||
In-Line D-44|Inline D-44
|
||||
In-line|Inline
|
||||
@@ -232,6 +233,7 @@ Lock|Vastpinnen
|
||||
Log|Logaritmisch
|
||||
Log In|Inloggen
|
||||
Log Out|Uitloggen
|
||||
Look for|Zoeken
|
||||
Lug Size|Solderooggrootte
|
||||
Lugs|Solderogen
|
||||
Make a Donation|Doneren
|
||||
@@ -303,6 +305,7 @@ Power Rating|Nominale vermogen
|
||||
Power Strip|Voedingslijn
|
||||
Primary CT|Primaire middenaftakking
|
||||
Print...|Afdrukken...
|
||||
Project|Project
|
||||
Project Cloud|Project cloud
|
||||
Public Announcement|Openbare aankondiging
|
||||
Radius|Straal
|
||||
@@ -456,4 +459,35 @@ Y-axis|Y-as
|
||||
Zoom|Zoom
|
||||
base of 10|Tienden
|
||||
base of 2|Achtsten
|
||||
hold %s and drag to unstick from|houd %s vast en sleep, om los te maken van
|
||||
hold %s and drag to unstick from|houd %s vast en sleep, om los te maken van
|
||||
Are you sure you want to clear the chat history for this project? This action cannot be undone!|Weet u zeker dat u de chatgeschiedenis voor dit project wilt wissen? Deze actie kan niet ongedaan worden gemaakt!
|
||||
Component reordering is possible only when Project Explorer is sorted by z-index.|Het opnieuw ordenen van componenten is alleen mogelijk wanneer Project Explorer is gesorteerd op z-index.
|
||||
Could not apply changes. Check the log for details.|Wijzigingen konden niet worden toegepast. Controleer het logbestand voor details.
|
||||
Exporting outline for board %s to file %s|Omtrek exporteren voor printplaat %s naar bestand %s
|
||||
Failed to export the project to gerber. Please check the log for details|Het exporteren van het project naar gerber is mislukt. Controleer het logbestand voor details
|
||||
Forgot Password?|Wachtwoord vergeten?
|
||||
Gerber Export|Gerber Export
|
||||
Gerber export completed successfully. The following files were created:%s|Gerber export succesvol voltooid. De volgende bestanden zijn aangemaakt:%s
|
||||
Get Premium|Premium krijgen
|
||||
Netlist files|Netlist bestanden
|
||||
No proximity issues detected.|Geen nabijheidsproblemen gedetecteerd.
|
||||
Nothing to export.|Niets te exporteren.
|
||||
Password|Wachtwoord
|
||||
Send|Verzenden
|
||||
There are some components that are outside of the bounds of boards.%sThey will be ignored unless you add a board component underneath them.%sDo you want to continue?|Er zijn enkele componenten die buiten de grenzen van printplaten liggen.%sZe worden genegeerd tenzij u een printplaatcomponent eronder toevoegt.%sWilt u doorgaan?
|
||||
User Name|Gebruikersnaam
|
||||
AI Circuit Analyzer|AI Circuit Analysator
|
||||
Cloud|Cloud
|
||||
Compare With...|Vergelijken met...
|
||||
Connect to Patreon|Verbinden met Patreon
|
||||
Export|Exporteren
|
||||
Export to Gerber|Exporteren naar Gerber
|
||||
Generate DIYLC Netlist (excl. Switches)|DIYLC netlist genereren (zonder schakelaars)
|
||||
Generate DIYLC Netlist (incl. Switches)|DIYLC netlist genereren (met schakelaars)
|
||||
Generate Spice Netlist (excl. Switches)|Spice netlist genereren (zonder schakelaars)
|
||||
Generate Spice Netlist (incl. Switches)|Spice netlist genereren (met schakelaars)
|
||||
Silkscreen|Zijdezeefdruk
|
||||
Virtual Multimeter (excl. Switches)|Virtuele Multimeter (zonder schakelaars)
|
||||
Virtual Multimeter (incl. Switches)|Virtuele Multimeter (met schakelaars)
|
||||
Become a Patreon and enjoy perks|Word een Patreon en geniet van voordelen
|
||||
Join Patreon|Lid worden van Patreon
|
||||
@@ -193,6 +193,7 @@ Image|Imagem
|
||||
Immediate Only|Apenas Imediato
|
||||
Import|Importar
|
||||
Import Building Blocks|Importar Blocos
|
||||
Import Netlist|Importar Lista de Redes
|
||||
Import Variants|Importar variações
|
||||
In-Line D-44|Em linha D-44
|
||||
In-line|Em linha
|
||||
@@ -298,6 +299,7 @@ Power Rating|Potência Nominal
|
||||
Power Strip|Listra Eletrificada
|
||||
Primary CT|CT Primário
|
||||
Print...|Imprimir...
|
||||
Project|Projeto
|
||||
Project Cloud|Projetos na Núvem
|
||||
Public Announcement|Anúncio Público
|
||||
Radius|Raio
|
||||
@@ -358,7 +360,7 @@ Size|Tamanho
|
||||
Sizing Mode|Modo de Dimensionamento
|
||||
Small-button B7G|Botão pequeno B7G
|
||||
Smooth|Suave
|
||||
Snap To...|Ajustarse a...
|
||||
Snap To|Ajustar a
|
||||
Soap Bar|Soap Bar
|
||||
Solid|Sólido
|
||||
South|Sul
|
||||
@@ -457,4 +459,35 @@ Update Axis|Atualizar Eixos
|
||||
Apply Variant|Aplicar Variante
|
||||
Save as Building Block|Salvar como Bloco
|
||||
Select|Selecionar
|
||||
Unlock|Desbloquear
|
||||
Unlock|Desbloquear
|
||||
Are you sure you want to clear the chat history for this project? This action cannot be undone!|Tem certeza de que deseja limpar o histórico de chat deste projeto? Esta ação não pode ser desfeita!
|
||||
Component reordering is possible only when Project Explorer is sorted by z-index.|A reordenação de componentes só é possível quando o Explorador de Projetos está ordenado por z-index.
|
||||
Could not apply changes. Check the log for details.|Não foi possível aplicar as alterações. Verifique o registro para mais detalhes.
|
||||
Exporting outline for board %s to file %s|Exportando o contorno da placa %s para o arquivo %s
|
||||
Failed to export the project to gerber. Please check the log for details|Falha ao exportar o projeto para gerber. Por favor, verifique o registro para mais detalhes
|
||||
Forgot Password?|Esqueceu a Senha?
|
||||
Gerber Export|Exportar Gerber
|
||||
Gerber export completed successfully. The following files were created:%s|A exportação Gerber foi concluída com sucesso. Os seguintes arquivos foram criados:%s
|
||||
Get Premium|Obter Premium
|
||||
Netlist files|Arquivos de lista de rede
|
||||
No proximity issues detected.|Nenhum problema de proximidade detectado.
|
||||
Nothing to export.|Nada para exportar.
|
||||
Password|Senha
|
||||
Send|Enviar
|
||||
There are some components that are outside of the bounds of boards.%sThey will be ignored unless you add a board component underneath them.%sDo you want to continue?|Há alguns componentes que estão fora dos limites das placas.%sEles serão ignorados a menos que você adicione um componente de placa abaixo deles.%sDeseja continuar?
|
||||
User Name|Nome de Usuário
|
||||
AI Circuit Analyzer|Analisador de Circuito IA
|
||||
Cloud|Nuvem
|
||||
Compare With...|Comparar com...
|
||||
Connect to Patreon|Conectar ao Patreon
|
||||
Export|Exportar
|
||||
Export to Gerber|Exportar para Gerber
|
||||
Generate DIYLC Netlist (excl. Switches)|Gerar Lista de Redes DIYLC (sem interruptores)
|
||||
Generate DIYLC Netlist (incl. Switches)|Gerar Lista de Redes DIYLC (com interruptores)
|
||||
Generate Spice Netlist (excl. Switches)|Gerar Lista Especial de Redes (sem interruptores)
|
||||
Generate Spice Netlist (incl. Switches)|Gerar Lista Especial de Redes (com interruptores)
|
||||
Silkscreen|Serigrafia
|
||||
Virtual Multimeter (excl. Switches)|Multímetro Virtual (sem interruptores)
|
||||
Virtual Multimeter (incl. Switches)|Multímetro Virtual (com interruptores)
|
||||
Become a Patreon and enjoy perks|Torne-se um Patreon e aproveite benefícios
|
||||
Join Patreon|Juntar-se ao Patreon
|
||||
@@ -191,6 +191,7 @@ Image|Slika
|
||||
Immediate Only|Samo Neposredne
|
||||
Import|Uvoz
|
||||
Import Building Blocks|Uvezi Blokove za Gradnju
|
||||
Import Netlist|Uvezi Netlistu
|
||||
Import Variants|Uvezi Varijacije
|
||||
In-Line D-44|U Redu D-44
|
||||
In-line|U Redu
|
||||
@@ -224,6 +225,7 @@ Light|Svetla
|
||||
Lock|Zaključaj
|
||||
Log In|Prijava
|
||||
Log Out|Odjava
|
||||
Look for|Traži
|
||||
Lug Size|Veličina Ušica
|
||||
Lugs|Ušice
|
||||
Make a Donation|Doniraj
|
||||
@@ -291,6 +293,7 @@ Power Rating|Snaga
|
||||
Power Strip|Naponska Magistrala
|
||||
Primary CT|Primarni Srednji Izvod
|
||||
Print...|Štampa...
|
||||
Project|Projekat
|
||||
Project Cloud|Projektni Oblak
|
||||
Public Announcement|Javna Objava
|
||||
Radius|Poluprečnik
|
||||
@@ -449,4 +452,35 @@ Update Axis|Osveži Ose
|
||||
Apply Variant|Primeni Varijaciju
|
||||
Save as Building Block|Sačuvaj Kao Blok
|
||||
Select|Izaberi
|
||||
Unlock|Otključaj
|
||||
Unlock|Otključaj
|
||||
Are you sure you want to clear the chat history for this project? This action cannot be undone!|Da li ste sigurni da želite da obrišete istoriju četa za ovaj projekat? Ova akcija se ne može poništiti!
|
||||
Component reordering is possible only when Project Explorer is sorted by z-index.|Preuređivanje komponenti je moguće samo kada je Project Explorer sortiran po z-index-u.
|
||||
Could not apply changes. Check the log for details.|Nije moguće primeniti izmene. Proverite log za više informacija.
|
||||
Exporting outline for board %s to file %s|Izvoz obrisa za pločicu %s u datoteku %s
|
||||
Failed to export the project to gerber. Please check the log for details|Neuspelo izvoženje projekta u gerber. Proverite log za više informacija
|
||||
Forgot Password?|Zaboravili ste lozinku?
|
||||
Gerber Export|Gerber Izvoz
|
||||
Gerber export completed successfully. The following files were created:%s|Gerber izvoz je uspešno završen. Sledeće datoteke su kreirane:%s
|
||||
Get Premium|Dobij Premium
|
||||
Netlist files|Netlist datoteke
|
||||
No proximity issues detected.|Nisu detektovani problemi sa blizinom.
|
||||
Nothing to export.|Nema ništa za izvoz.
|
||||
Password|Lozinka
|
||||
Send|Pošalji
|
||||
There are some components that are outside of the bounds of boards.%sThey will be ignored unless you add a board component underneath them.%sDo you want to continue?|Postoje neke komponente koje su van granica pločica.%sOne će biti ignorisane osim ako ne dodate komponentu pločice ispod njih.%sDa li želite da nastavite?
|
||||
User Name|Korisničko Ime
|
||||
AI Circuit Analyzer|AI Analizator Kola
|
||||
Cloud|Oblak
|
||||
Compare With...|Uporedi sa...
|
||||
Connect to Patreon|Poveži sa Patreon-om
|
||||
Export|Izvoz
|
||||
Export to Gerber|Izvoz u Gerber
|
||||
Generate DIYLC Netlist (excl. Switches)|Generiši DIYLC Netlistu (bez prekidača)
|
||||
Generate DIYLC Netlist (incl. Switches)|Generiši DIYLC Netlistu (sa prekidačima)
|
||||
Generate Spice Netlist (excl. Switches)|Generiši Spice Netlistu (bez prekidača)
|
||||
Generate Spice Netlist (incl. Switches)|Generiši Spice Netlistu (sa prekidačima)
|
||||
Silkscreen|Serigrafija
|
||||
Virtual Multimeter (excl. Switches)|Virtuelni Multimetar (bez prekidača)
|
||||
Virtual Multimeter (incl. Switches)|Virtuelni Multimetar (sa prekidačima)
|
||||
Become a Patreon and enjoy perks|Postanite Patreon i uživajte u prednostima
|
||||
Join Patreon|Pridružite se Patreon-u
|
||||
@@ -0,0 +1,498 @@
|
||||
#start-internal
|
||||
icon=india
|
||||
#end-internal
|
||||
(Building Blocks)|(बिल्डिंग ब्लॉक्स)
|
||||
(Favorites)|(पसंदीदा)
|
||||
(Recently Used)|(हाल ही में उपयोग किए गए)
|
||||
180 degrees clockwise|दक्षिणावर्त 180 डिग्री
|
||||
270 degrees clockwise|दक्षिणावर्त 270 डिग्री
|
||||
90 degrees clockwise|दक्षिणावर्त 90 डिग्री
|
||||
A variant with that name already exists. Overwrite?|उस नाम का एक वेरिएंट पहले से मौजूद है। अधिलेखित करें?
|
||||
About|के बारे में
|
||||
Above|ऊपर
|
||||
Access User Files|उपयोगकर्ता फ़ाइलें एक्सेस करें
|
||||
Add Flexible Leads|लचीली लीड जोड़ें
|
||||
Add Validation Step|सत्यापन चरण जोड़ें
|
||||
All Connected|सभी जुड़े हुए
|
||||
Alpha|अल्फा
|
||||
Analyze|विश्लेषण करें
|
||||
Analyze Guitar Diagrams|गिटार आरेखों का विश्लेषण करें
|
||||
Angle|कोण
|
||||
Anti-Aliasing|एंटी-अलियासिंग
|
||||
Arrow Size|तीर का आकार
|
||||
Author|लेखक
|
||||
Auto-Create Pads|ऑटो-क्रिएट पैड
|
||||
Auto-Edit Mode|ऑटो-एडिट मोड
|
||||
Base|आधार
|
||||
Below|नीचे
|
||||
Blueprint|ब्लूप्रिंट
|
||||
Board|बोर्ड
|
||||
Boards|बोर्ड
|
||||
Board Color|बोर्ड का रंग
|
||||
Board Width|बोर्ड की चौड़ाई
|
||||
Bobbin 1|बॉबिन 1
|
||||
Bobbin 2|बॉबिन 2
|
||||
Body|शरीर
|
||||
Border|बॉर्डर
|
||||
Border Thickness|बॉर्डर की मोटाई
|
||||
Both|दोनों
|
||||
Both Sides|दोनों तरफ
|
||||
Bottom|नीचे
|
||||
Bottom Left|नीचे बाएं
|
||||
Bottom Right|नीचे दाएं
|
||||
Bracket|ब्रैकेट
|
||||
Bring Forward|आगे लाएं
|
||||
Bring Selection to Front|चयन को सामने लाएं
|
||||
Buffer|बफर
|
||||
Center|केंद्र
|
||||
Center Negative|केंद्र नकारात्मक
|
||||
Center Positive|केंद्र सकारात्मक
|
||||
Center Terminal|केंद्र टर्मिनल
|
||||
Central|केंद्रीय
|
||||
Change Password|पासवर्ड बदलें
|
||||
Channel|चैनल
|
||||
Chassis|चेसिस
|
||||
Check Trace Proximity|ट्रेस निकटता जांचें
|
||||
Circular|गोलाकार
|
||||
Click on a component to highlight area directly or indirectly connected to the area below the cursor. To continue editing, this mode needs to be switched OFF|कर्सर के नीचे के क्षेत्र से सीधे या अप्रत्यक्ष रूप से जुड़े क्षेत्र को हाइलाइट करने के लिए एक घटक पर क्लिक करें। संपादन जारी रखने के लिए, इस मोड को बंद करना होगा
|
||||
Click on the canvas to create a new %s or press %s to cancel|एक नया %s बनाने के लिए कैनवास पर क्लिक करें या रद्द करने के लिए %s दबाएं
|
||||
Click on the canvas to set the %s control point of a new %s or press %s to cancel|एक नए %s के %s कंट्रोल पॉइंट सेट करने के लिए कैनवास पर क्लिक करें या रद्द करने के लिए %s दबाएं
|
||||
Click the lightbulb icon in the bottom-right corner of the window for more info.|अधिक जानकारी के लिए विंडो के निचले दाएं कोने में लाइटबल्ब आइकन पर क्लिक करें।
|
||||
Click to fetch the most recent public announcement|सबसे हाल का सार्वजनिक घोषणा प्राप्त करने के लिए क्लिक करें
|
||||
Click to show recent changes and updates|हाल के परिवर्तन और अपडेट दिखाने के लिए क्लिक करें
|
||||
Click to toggle to the next option|अगले विकल्प पर जाने के लिए क्लिक करें
|
||||
Coil|कुंडली
|
||||
Coil Border|कुंडली बॉर्डर
|
||||
Coil Length|कुंडली की लंबाई
|
||||
Coil Width|कुंडली की चौड़ाई
|
||||
Color|रंग
|
||||
Color 1|रंग 1
|
||||
Color 2|रंग 2
|
||||
Color code|रंग कोड
|
||||
Column Spacing|कॉलम स्पेसिंग
|
||||
Columns|कॉलम
|
||||
Component|घटक
|
||||
Component API|घटक API
|
||||
Components|घटक
|
||||
Config|कॉन्फ़िग
|
||||
Connector|कनेक्टर
|
||||
Connector (Mirrored)|कनेक्टर (मिरर किया गया)
|
||||
Connectivity|कनेक्टिविटी
|
||||
Contacts|संपर्क
|
||||
Continuous Creation|निरंतर निर्माण
|
||||
Coordinate Color|निर्देशांक रंग
|
||||
Coordinate Origin|निर्देशांक मूल
|
||||
Coordinates|निर्देशांक
|
||||
Copy|कॉपी करें
|
||||
Core|कोर
|
||||
Core Border|कोर बॉर्डर
|
||||
Core Thickness|कोर की मोटाई
|
||||
Core Width|कोर की चौड़ाई
|
||||
Could not create a new file. Check the log for details.|नई फ़ाइल नहीं बना सके। विवरण के लिए लॉग जांचें।
|
||||
Could not create component. Check log for details.|घटक नहीं बना सके। विवरण के लिए लॉग जांचें।
|
||||
Could not fetch public announcements.|सार्वजनिक घोषणाएं प्राप्त नहीं कर सके।
|
||||
Could not save the project to file. Check the log for details.|प्रोजेक्ट को फ़ाइल में सहेज नहीं सके। विवरण के लिए लॉग जांचें।
|
||||
Could not set component type slot. Check log for details.|घटक प्रकार स्लॉट सेट नहीं कर सके। विवरण के लिए लॉग जांचें।
|
||||
Cover|कवर
|
||||
Create B.O.M.|B.O.M. बनाएं
|
||||
Create New Account|नया खाता बनाएं
|
||||
Current|वर्तमान
|
||||
Cut|काटें
|
||||
Cut Between Holes|छेदों के बीच काटें
|
||||
Cut Orientation|कट ओरिएंटेशन
|
||||
DIP (Mirrored)|DIP (मिरर किया गया)
|
||||
DP3T (Standard 3-Position Strat)|DP3T (स्टैंडर्ड 3-पोजीशन Strat)
|
||||
DP3T (Standard 5-Position Strat)|DP3T (स्टैंडर्ड 5-पोजीशन Strat)
|
||||
DP4T (4-Position Tele)|DP4T (4-पोजीशन Tele)
|
||||
Dark|डार्क
|
||||
Dashed|डैश किया गया
|
||||
Decimals|दशमलव
|
||||
Default|डिफ़ॉल्ट
|
||||
Default Font|डिफ़ॉल्ट फ़ॉन्ट
|
||||
Default Font Size|डिफ़ॉल्ट फ़ॉन्ट साइज़
|
||||
Delete Selection|चयन हटाएं
|
||||
Description|विवरण
|
||||
Diameter|व्यास
|
||||
Directional|दिशात्मक
|
||||
Directly heated|सीधे गर्म
|
||||
Display|डिस्प्ले
|
||||
Display Pin #s|पिन #s दिखाएं
|
||||
Dog Ear|डॉग ईयर
|
||||
Dot Spacing|डॉट स्पेसिंग
|
||||
Donate|दान करें
|
||||
Dotted|बिंदीदार
|
||||
Drag control point(s) of|कंट्रोल पॉइंट खींचें
|
||||
Drag the mouse over the canvas to place a new|एक नया रखने के लिए कैनवास पर माउस खींचें
|
||||
Dual Rail Humbucker|ड्यूल रेल हम्बकर
|
||||
Dual Rods|ड्यूल रॉड्स
|
||||
Duodecar B12C|Duodecar B12C
|
||||
Duplicate|डुप्लिकेट
|
||||
Edges|किनारे
|
||||
Edit|संपादित करें
|
||||
Edit Project Settings|प्रोजेक्ट सेटिंग्स संपादित करें
|
||||
Edit Selection|चयन संपादित करें
|
||||
Electrode Labels|इलेक्ट्रोड लेबल
|
||||
Electro-Mechanical|इलेक्ट्रो-मैकेनिकल
|
||||
Enable Cache Boost|कैश बूस्ट सक्षम करें
|
||||
End Arrow|अंत तीर
|
||||
Enjoying DIYLC? Click here to buy me a coffee :)|DIYLC का आनंद ले रहे हैं? मुझे कॉफी खरीदने के लिए यहां क्लिक करें :)
|
||||
Error|त्रुटि
|
||||
Error occurred while editing selection. Check the log for details.|चयन संपादित करते समय त्रुटि हुई। विवरण के लिए लॉग जांचें।
|
||||
Exit|बाहर निकलें
|
||||
Expand Selection|चयन विस्तारित करें
|
||||
Explicit Dimensions|स्पष्ट आयाम
|
||||
Explicit Length|स्पष्ट लंबाई
|
||||
Explicit Width|स्पष्ट चौड़ाई
|
||||
Export Building Blocks|बिल्डिंग ब्लॉक्स निर्यात करें
|
||||
Export Grid|ग्रिड निर्यात करें
|
||||
Export Variants|वेरिएंट निर्यात करें
|
||||
Export to PDF|PDF में निर्यात करें
|
||||
Export to PNG|PNG में निर्यात करें
|
||||
Extra Working Area|अतिरिक्त कार्य क्षेत्र
|
||||
Eyelet color|आईलेट रंग
|
||||
FAQ|अक्सर पूछे जाने वाले प्रश्न
|
||||
File|फ़ाइल
|
||||
Filtertron|Filtertron
|
||||
Find|खोजें
|
||||
Five|पांच
|
||||
Flip|फ्लिप करें
|
||||
Folded|तह किया गया
|
||||
Font|फ़ॉन्ट
|
||||
Font Bold|फ़ॉन्ट बोल्ड
|
||||
Font Italic|फ़ॉन्ट इटैलिक
|
||||
Font Size|फ़ॉन्ट साइज़
|
||||
Font Size Override|फ़ॉन्ट साइज़ ओवरराइड
|
||||
Four|चार
|
||||
Full|पूर्ण
|
||||
Fuse|फ्यूज
|
||||
Generate DIYLC Netlist|DIYLC नेटलिस्ट जेनरेट करें
|
||||
Generate Spice Netlist|Spice नेटलिस्ट जेनरेट करें
|
||||
Grid|ग्रिड
|
||||
Grid Spacing|ग्रिड स्पेसिंग
|
||||
Group Selection|चयन समूहित करें
|
||||
Guitar|गिटार
|
||||
Half|आधा
|
||||
Hardware Acceleration|हार्डवेयर एक्सेलेरेशन
|
||||
Heaters|हीटर
|
||||
Height|ऊंचाई
|
||||
Help|मदद
|
||||
Hi-Quality Rendering|उच्च गुणवत्ता रेंडरिंग
|
||||
Highlight Connected Areas|जुड़े क्षेत्र हाइलाइट करें
|
||||
Hole|छेद
|
||||
Hole Size|छेद का आकार
|
||||
Hole Spacing|छेद स्पेसिंग
|
||||
Hole size|छेद का आकार
|
||||
Holes per strip|प्रति स्ट्रिप छेद
|
||||
Horizontal|क्षैतिज
|
||||
Horizontal Alignment|क्षैतिज संरेखण
|
||||
Horizontal Large|क्षैतिज बड़ा
|
||||
Horizontal Medium|क्षैतिज मध्यम
|
||||
Horizontal Small 1|क्षैतिज छोटा 1
|
||||
Horizontal Small 2|क्षैतिज छोटा 2
|
||||
Horizontal X-Small|क्षैतिज एक्स-छोटा
|
||||
Humbucking|हम्बकिंग
|
||||
If this box is checked application will use the current value as a<br>default when creating new components of the same type|यदि यह बॉक्स चेक किया गया है, तो एप्लिकेशन समान प्रकार के नए घटक बनाते समय वर्तमान मान को <br>डिफ़ॉल्ट के रूप में उपयोग करेगा
|
||||
Image|छवि
|
||||
Immediate Only|केवल तत्काल
|
||||
Import|आयात करें
|
||||
Import Building Blocks|बिल्डिंग ब्लॉक्स आयात करें
|
||||
Import Netlist|नेटलिस्ट आयात करें
|
||||
Import Variants|वेरिएंट आयात करें
|
||||
In-Line D-44|इन-लाइन D-44
|
||||
In-line|इन-लाइन
|
||||
Indent|इंडेंट
|
||||
Information|जानकारी
|
||||
Inline|इनलाइन
|
||||
Input error for "%s": %s|"%s" के लिए इनपुट त्रुटि: %s
|
||||
Inside color|अंदर का रंग
|
||||
Integration|एकीकरण
|
||||
Invert polarity|ध्रुवता उलटें
|
||||
Label|लेबल
|
||||
Label Color|लेबल रंग
|
||||
Label Orientation|लेबल ओरिएंटेशन
|
||||
Label Position|लेबल स्थिति
|
||||
Labels|लेबल
|
||||
Language|भाषा
|
||||
Language selection will be applied after the application is restarted.|भाषा चयन एप्लिकेशन रीस्टार्ट होने के बाद लागू होगा।
|
||||
Layer|लेयर
|
||||
Layers|लेयर
|
||||
Lead Color|लीड रंग
|
||||
Lead Count|लीड संख्या
|
||||
Lead Length|लीड लंबाई
|
||||
Lead Spacing|लीड स्पेसिंग
|
||||
Left|बाएं
|
||||
Left-to-Right|बाएं से दाएं
|
||||
Left click to instantiate this component, right click for more options|इस घटक को इंस्टेंट करने के लिए बाएं क्लिक करें, अधिक विकल्पों के लिए दाएं क्लिक करें
|
||||
Legs|पैर
|
||||
Length|लंबाई
|
||||
Letters|अक्षर
|
||||
Light|लाइट
|
||||
Lock|लॉक करें
|
||||
Log In|लॉग इन करें
|
||||
Log Out|लॉग आउट करें
|
||||
Look for|खोजें
|
||||
Lug Size|लग साइज़
|
||||
Lugs|लग्स
|
||||
Make a Donation|दान करें
|
||||
Manage Account|खाता प्रबंधित करें
|
||||
Manage My Uploads|मेरे अपलोड प्रबंधित करें
|
||||
Mark Common Lugs|सामान्य लग्स चिह्नित करें
|
||||
Marker|मार्कर
|
||||
Marker Size|मार्कर साइज़
|
||||
Mini|मिनी
|
||||
Miniature|लघु
|
||||
Mirror Horizontally|क्षैतिज रूप से मिरर करें
|
||||
Mirror Selection|चयन मिरर करें
|
||||
Mirror Vertically|ऊर्ध्वाधर रूप से मिरर करें
|
||||
Mirroring operation will change the circuit. Do you want to continue?|मिररिंग ऑपरेशन सर्किट को बदल देगा। क्या आप जारी रखना चाहते हैं?
|
||||
Misc|विविध
|
||||
Model|मॉडल
|
||||
Mono|मोनो
|
||||
Mount|माउंट
|
||||
Mounting Lugs|माउंटिंग लग्स
|
||||
Mouse Wheel Zoom|माउस व्हील ज़ूम
|
||||
Moveable Label|स्थानांतरणीय लेबल
|
||||
Name|नाम
|
||||
Negative|नकारात्मक
|
||||
New|नया
|
||||
New version available|नया संस्करण उपलब्ध है
|
||||
No new public announcements available.|कोई नई सार्वजनिक घोषणाएं उपलब्ध नहीं हैं।
|
||||
No|नहीं
|
||||
None|कोई नहीं
|
||||
North|उत्तर
|
||||
Noval B9A|Noval B9A
|
||||
Nudge|नज
|
||||
Numbers|संख्या
|
||||
Nut|नट
|
||||
Octal|ऑक्टल
|
||||
Offset|ऑफसेट
|
||||
One Side|एक तरफ
|
||||
Open|खोलें
|
||||
Opposing Points|विपरीत बिंदु
|
||||
Orientation|ओरिएंटेशन
|
||||
Outer Foil|बाहरी फॉइल
|
||||
Outer Foil Mark|बाहरी फॉइल मार्क
|
||||
Outline Mode|आउटलाइन मोड
|
||||
Outside|बाहर
|
||||
Oval horizontal|क्षैतिज अंडाकार
|
||||
Oval vertical|ऊर्ध्वाधर अंडाकार
|
||||
Pad Color|पैड रंग
|
||||
Panel|पैनल
|
||||
Passive|निष्क्रिय
|
||||
Paste|पेस्ट करें
|
||||
Pin Arrangement|पिन व्यवस्था
|
||||
Pin Color|पिन रंग
|
||||
Pin Spacing|पिन स्पेसिंग
|
||||
Pinout|पिनआउट
|
||||
Pins|पिन्स
|
||||
Play Test|टेस्ट प्ले करें
|
||||
Plugin API|प्लगइन API
|
||||
Point Count|बिंदु संख्या
|
||||
Polarity|ध्रुवता
|
||||
Polarized|ध्रुवीकृत
|
||||
Pole Color|पोल रंग
|
||||
Pole Pieces|पोल पीस
|
||||
Pole Pieces 1|पोल पीस 1
|
||||
Pole Pieces 2|पोल पीस 2
|
||||
Positions|स्थितियां
|
||||
Positive|सकारात्मक
|
||||
Power Rating|पावर रेटिंग
|
||||
Power Strip|पावर स्ट्रिप
|
||||
Primary CT|प्राइमरी CT
|
||||
Print...|प्रिंट...
|
||||
Project|प्रोजेक्ट
|
||||
Project Cloud|प्रोजेक्ट क्लाउड
|
||||
Public Announcement|सार्वजनिक घोषणा
|
||||
Radius|त्रिज्या
|
||||
Rail|रेल
|
||||
Recent Files|हाल की फ़ाइलें
|
||||
Recent Updates|हाल के अपडेट
|
||||
Redo|रीडू
|
||||
Renumber On Paste|पेस्ट पर री-नंबर करें
|
||||
Renumber Selection|चयन री-नंबर करें
|
||||
Resistance|प्रतिरोध
|
||||
Reverse (standing)|रिवर्स (खड़ा)
|
||||
Right|दाएं
|
||||
Rim|रिम
|
||||
Rods|रॉड्स
|
||||
Rotate Clockwise|दक्षिणावर्त घुमाएं
|
||||
Rotate Counterclockwise|वामावर्त घुमाएं
|
||||
Rotate Selection|चयन घुमाएं
|
||||
Round|गोल
|
||||
Round WOG A|राउंड WOG A
|
||||
Round WOG B|राउंड WOG B
|
||||
Row Spacing|पंक्ति स्पेसिंग
|
||||
Rows|पंक्तियां
|
||||
Ruler Inch Subdivision...|रूलर इंच सबडिवीजन...
|
||||
Same Type Only|केवल समान प्रकार
|
||||
Save|सहेजें
|
||||
Save As|इस रूप में सहेजें
|
||||
Save as Variant|वेरिएंट के रूप में सहेजें
|
||||
Scale|स्केल
|
||||
Schematic Symbols|स्कीमैटिक प्रतीक
|
||||
Screws|स्क्रू
|
||||
Selection|चयन
|
||||
Selection Size|चयन साइज़
|
||||
Selection is empty.|चयन खाली है।
|
||||
Search The Cloud|क्लाउड खोजें
|
||||
Searchable Tree|खोज योग्य ट्री
|
||||
Secondary CT|सेकेंडरी CT
|
||||
Select All|सभी चुनें
|
||||
Selected component(s) have reached the bottom of their layer. Do you want to force the selection to the back?|चयनित घटक अपनी लेयर के नीचे पहुंच गए हैं। क्या आप चयन को पीछे जबरदस्ती करना चाहते हैं?
|
||||
Selected component(s) have reached the top of their layer. Do you want to force the selection to the top?|चयनित घटक अपनी लेयर के ऊपर पहुंच गए हैं। क्या आप चयन को ऊपर जबरदस्ती करना चाहते हैं?
|
||||
Selection contains components that cannot be mirrored. Do you want to exclude them?|चयन में ऐसे घटक हैं जिन्हें मिरर नहीं किया जा सकता। क्या आप उन्हें बाहर करना चाहते हैं?
|
||||
Selection contains components that cannot be rotated. Do you want to exclude them?|चयन में ऐसे घटक हैं जिन्हें घुमाया नहीं जा सकता। क्या आप उन्हें बाहर करना चाहते हैं?
|
||||
Semiconductors|सेमीकंडक्टर्स
|
||||
Send Backward|पीछे भेजें
|
||||
Send Selection to Back|चयन को पीछे भेजें
|
||||
Seven|सात
|
||||
Shaft Down|शाफ्ट नीचे
|
||||
Shaft Up|शाफ्ट ऊपर
|
||||
Shape|आकार
|
||||
Shapes|आकार
|
||||
Show Bracket|ब्रैकेट दिखाएं
|
||||
Show Grid|ग्रिड दिखाएं
|
||||
Show Rulers|रूलर दिखाएं
|
||||
Shroud|श्राउड
|
||||
Shrouded|श्राउडेड
|
||||
Single Rail|सिंगल रेल
|
||||
Single Rods|सिंगल रॉड्स
|
||||
Size|साइज़
|
||||
Sizing Mode|साइज़िंग मोड
|
||||
Small-button B7G|स्मॉल-बटन B7G
|
||||
Smooth|स्मूथ
|
||||
Snap To|स्नैप टू
|
||||
Soap Bar|सोप बार
|
||||
Solid|ठोस
|
||||
South|दक्षिण
|
||||
Spacing|स्पेसिंग
|
||||
Square|वर्ग
|
||||
Square BR-3|स्क्वायर BR-3
|
||||
Standard|स्टैंडर्ड
|
||||
Start Arrow|शुरुआत तीर
|
||||
Start Recording|रिकॉर्डिंग शुरू करें
|
||||
Stereo|स्टीरियो
|
||||
Sticky Points|स्टिकी पॉइंट्स
|
||||
Stop Recording|रिकॉर्डिंग रोकें
|
||||
Stratocaster|Stratocaster
|
||||
Strip Color|स्ट्रिप रंग
|
||||
Stripe|स्ट्राइप
|
||||
Stripe 1|स्ट्राइप 1
|
||||
Stripe 2|स्ट्राइप 2
|
||||
Stripe Color|स्ट्राइप रंग
|
||||
Stripe Color 1|स्ट्राइप रंग 1
|
||||
Stripe Color 2|स्ट्राइप रंग 2
|
||||
Style|स्टाइल
|
||||
Submit a Bug|बग सबमिट करें
|
||||
Suppressor grid|सप्रेसर ग्रिड
|
||||
Switched|स्विच किया गया
|
||||
Switches|स्विच
|
||||
Tab|टैब
|
||||
Tab Border|टैब बॉर्डर
|
||||
Tabbed Toolbar|टैब्ड टूलबार
|
||||
Taper|टेपर
|
||||
Telecaster|Telecaster
|
||||
Terminal Spacing|टर्मिनल स्पेसिंग
|
||||
Terminals|टर्मिनल
|
||||
Test|टेस्ट
|
||||
Text|टेक्स्ट
|
||||
Text Color|टेक्स्ट रंग
|
||||
Theme|थीम
|
||||
There are unsaved changes. Would you like to save them?|असहेजित परिवर्तन हैं। क्या आप उन्हें सहेजना चाहते हैं?
|
||||
Thickness|मोटाई
|
||||
Three|तीन
|
||||
Through Hole|थ्रू होल
|
||||
Tick|टिक
|
||||
Tick Width|टिक चौड़ाई
|
||||
Ticks|टिक्स
|
||||
Title|शीर्षक
|
||||
Toolbox|टूलबॉक्स
|
||||
Top|ऊपर
|
||||
Top Lead|टॉप लीड
|
||||
Top Left|ऊपर बाएं
|
||||
Top Right|ऊपर दाएं
|
||||
Top-to-Bottom|ऊपर से नीचे
|
||||
Trace|ट्रेस
|
||||
Trace Color|ट्रेस रंग
|
||||
Trace Mask|ट्रेस मास्क
|
||||
Transform Selection|चयन ट्रांसफॉर्म करें
|
||||
Triangle|त्रिभुज
|
||||
Tubular|ट्यूबुलर
|
||||
Tubes|ट्यूब्स
|
||||
Two|दो
|
||||
Type|प्रकार
|
||||
Ultra-miniature|अल्ट्रा-मिनिएचर
|
||||
Underside Pad Color|अंडरसाइड पैड रंग
|
||||
Underside Trace Color|अंडरसाइड ट्रेस रंग
|
||||
Undo|अनडू
|
||||
Ungroup Selection|चयन अनग्रुप करें
|
||||
Unit|यूनिट
|
||||
Upload A Project|एक प्रोजेक्ट अपलोड करें
|
||||
User Manual|उपयोगकर्ता मैनुअल
|
||||
Value|मान
|
||||
Version history is not available.|संस्करण इतिहास उपलब्ध नहीं है।
|
||||
Vertical|ऊर्ध्वाधर
|
||||
Vertical Alignment|ऊर्ध्वाधर संरेखण
|
||||
Vertical Inline|ऊर्ध्वाधर इनलाइन
|
||||
Vertical Offset 1|ऊर्ध्वाधर ऑफसेट 1
|
||||
Vertical Offset 2|ऊर्ध्वाधर ऑफसेट 2
|
||||
View|व्यू
|
||||
Visible|दृश्यमान
|
||||
Voltage|वोल्टेज
|
||||
Wafer|वेफर
|
||||
Warning|चेतावनी
|
||||
Width|चौड़ाई
|
||||
Winding Spacing|वाइंडिंग स्पेसिंग
|
||||
Wiring|वायरिंग
|
||||
X-axis|X-अक्ष
|
||||
Y-axis|Y-अक्ष
|
||||
Zoom|ज़ूम
|
||||
base of 10|10 का आधार
|
||||
base of 2|2 का आधार
|
||||
hold %s and drag to unstick from|%s दबाए रखें और खींचकर अलग करें
|
||||
Add a Curve|एक कर्व जोड़ें
|
||||
Clear|साफ करें
|
||||
Insert Image|छवि सम्मिलित करें
|
||||
Load From File|फ़ाइल से लोड करें
|
||||
Loadline Editor|लोडलाइन एडिटर
|
||||
Max Current (mA)|अधिकतम करंट (mA)
|
||||
Max Dissipation (W)|अधिकतम डिसिपेशन (W)
|
||||
Max Voltage (V)|अधिकतम वोल्टेज (V)
|
||||
Save To File|फ़ाइल में सहेजें
|
||||
Update Axis|अक्ष अपडेट करें
|
||||
Apply Variant|वेरिएंट लागू करें
|
||||
Save as Building Block|बिल्डिंग ब्लॉक के रूप में सहेजें
|
||||
Select|चुनें
|
||||
Unlock|अनलॉक करें
|
||||
Are you sure you want to clear the chat history for this project? This action cannot be undone!|क्या आप वाकई इस प्रोजेक्ट की चैट हिस्ट्री साफ करना चाहते हैं? यह कार्रवाई पूर्ववत नहीं की जा सकती!
|
||||
Component reordering is possible only when Project Explorer is sorted by z-index.|घटक पुन: क्रमबद्धता केवल तभी संभव है जब प्रोजेक्ट एक्सप्लोरर z-index द्वारा क्रमबद्ध हो।
|
||||
Could not apply changes. Check the log for details.|परिवर्तन लागू नहीं कर सके। विवरण के लिए लॉग जांचें।
|
||||
Exporting outline for board %s to file %s|बोर्ड %s का आउटलाइन फ़ाइल %s में निर्यात कर रहे हैं
|
||||
Failed to export the project to gerber. Please check the log for details|प्रोजेक्ट को gerber में निर्यात करने में विफल। कृपया विवरण के लिए लॉग जांचें
|
||||
Forgot Password?|पासवर्ड भूल गए?
|
||||
Gerber Export|Gerber निर्यात
|
||||
Gerber export completed successfully. The following files were created:%s|Gerber निर्यात सफलतापूर्वक पूर्ण हुआ। निम्नलिखित फ़ाइलें बनाई गईं:%s
|
||||
Get Premium|प्रीमियम प्राप्त करें
|
||||
Netlist files|नेटलिस्ट फ़ाइलें
|
||||
No proximity issues detected.|कोई निकटता समस्या का पता नहीं चला।
|
||||
Nothing to export.|निर्यात करने के लिए कुछ नहीं है।
|
||||
Password|पासवर्ड
|
||||
Send|भेजें
|
||||
There are some components that are outside of the bounds of boards.%sThey will be ignored unless you add a board component underneath them.%sDo you want to continue?|कुछ घटक बोर्ड की सीमाओं के बाहर हैं।%sजब तक आप उनके नीचे एक बोर्ड घटक नहीं जोड़ते, तब तक उन्हें अनदेखा किया जाएगा।%sक्या आप जारी रखना चाहते हैं?
|
||||
User Name|उपयोगकर्ता नाम
|
||||
AI Circuit Analyzer|AI सर्किट विश्लेषक
|
||||
Cloud|क्लाउड
|
||||
Compare With...|के साथ तुलना करें...
|
||||
Connect to Patreon|Patreon से कनेक्ट करें
|
||||
Export|निर्यात करें
|
||||
Export to Gerber|Gerber में निर्यात करें
|
||||
Generate DIYLC Netlist (excl. Switches)|DIYLC नेटलिस्ट जेनरेट करें (स्विच के बिना)
|
||||
Generate DIYLC Netlist (incl. Switches)|DIYLC नेटलिस्ट जेनरेट करें (स्विच के साथ)
|
||||
Generate Spice Netlist (excl. Switches)|Spice नेटलिस्ट जेनरेट करें (स्विच के बिना)
|
||||
Generate Spice Netlist (incl. Switches)|Spice नेटलिस्ट जेनरेट करें (स्विच के साथ)
|
||||
Silkscreen|सिल्कस्क्रीन
|
||||
Virtual Multimeter (excl. Switches)|वर्चुअल मल्टीमीटर (स्विच के बिना)
|
||||
Virtual Multimeter (incl. Switches)|वर्चुअल मल्टीमीटर (स्विच के साथ)
|
||||
Become a Patreon and enjoy perks|Patreon बनें और लाभ उठाएं
|
||||
Join Patreon|Patreon में शामिल हों
|
||||
|
||||
@@ -0,0 +1,498 @@
|
||||
#start-internal
|
||||
icon=china
|
||||
#end-internal
|
||||
(Building Blocks)|(构建块)
|
||||
(Favorites)|(收藏)
|
||||
(Recently Used)|(最近使用)
|
||||
180 degrees clockwise|顺时针180度
|
||||
270 degrees clockwise|顺时针270度
|
||||
90 degrees clockwise|顺时针90度
|
||||
A variant with that name already exists. Overwrite?|已存在同名变体。是否覆盖?
|
||||
About|关于
|
||||
Above|上方
|
||||
Access User Files|访问用户文件
|
||||
Add Flexible Leads|添加柔性引线
|
||||
Add Validation Step|添加验证步骤
|
||||
All Connected|全部连接
|
||||
Alpha|透明度
|
||||
Analyze|分析
|
||||
Analyze Guitar Diagrams|分析吉他图表
|
||||
Angle|角度
|
||||
Anti-Aliasing|抗锯齿
|
||||
Arrow Size|箭头大小
|
||||
Author|作者
|
||||
Auto-Create Pads|自动创建焊盘
|
||||
Auto-Edit Mode|自动编辑模式
|
||||
Base|基座
|
||||
Below|下方
|
||||
Blueprint|蓝图
|
||||
Board|电路板
|
||||
Boards|电路板
|
||||
Board Color|电路板颜色
|
||||
Board Width|电路板宽度
|
||||
Bobbin 1|线轴1
|
||||
Bobbin 2|线轴2
|
||||
Body|主体
|
||||
Border|边框
|
||||
Border Thickness|边框厚度
|
||||
Both|两者
|
||||
Both Sides|两侧
|
||||
Bottom|底部
|
||||
Bottom Left|左下
|
||||
Bottom Right|右下
|
||||
Bracket|支架
|
||||
Bring Forward|前移一层
|
||||
Bring Selection to Front|将选择移到最前
|
||||
Buffer|缓冲区
|
||||
Center|中心
|
||||
Center Negative|中心负极
|
||||
Center Positive|中心正极
|
||||
Center Terminal|中心端子
|
||||
Central|中央
|
||||
Change Password|更改密码
|
||||
Channel|通道
|
||||
Chassis|机箱
|
||||
Check Trace Proximity|检查走线间距
|
||||
Circular|圆形
|
||||
Click on a component to highlight area directly or indirectly connected to the area below the cursor. To continue editing, this mode needs to be switched OFF|点击元件以高亮显示与光标下方区域直接或间接连接的区域。要继续编辑,需要关闭此模式
|
||||
Click on the canvas to create a new %s or press %s to cancel|在画布上点击以创建新的%s或按%s取消
|
||||
Click on the canvas to set the %s control point of a new %s or press %s to cancel|在画布上点击以设置新%s的%s控制点或按%s取消
|
||||
Click the lightbulb icon in the bottom-right corner of the window for more info.|点击窗口右下角的灯泡图标以获取更多信息。
|
||||
Click to fetch the most recent public announcement|点击获取最新公告
|
||||
Click to show recent changes and updates|点击显示最近的更改和更新
|
||||
Click to toggle to the next option|点击切换到下一个选项
|
||||
Coil|线圈
|
||||
Coil Border|线圈边框
|
||||
Coil Length|线圈长度
|
||||
Coil Width|线圈宽度
|
||||
Color|颜色
|
||||
Color 1|颜色1
|
||||
Color 2|颜色2
|
||||
Color code|颜色代码
|
||||
Column Spacing|列间距
|
||||
Columns|列
|
||||
Component|元件
|
||||
Component API|元件API
|
||||
Components|元件
|
||||
Config|配置
|
||||
Connector|连接器
|
||||
Connector (Mirrored)|连接器(镜像)
|
||||
Connectivity|连接器
|
||||
Contacts|触点
|
||||
Continuous Creation|连续创建
|
||||
Coordinate Color|坐标颜色
|
||||
Coordinate Origin|坐标原点
|
||||
Coordinates|坐标
|
||||
Copy|复制
|
||||
Core|核心
|
||||
Core Border|核心边框
|
||||
Core Thickness|核心厚度
|
||||
Core Width|核心宽度
|
||||
Could not create a new file. Check the log for details.|无法创建新文件。请查看日志了解详情。
|
||||
Could not create component. Check log for details.|无法创建元件。请查看日志了解详情。
|
||||
Could not fetch public announcements.|无法获取公告。
|
||||
Could not save the project to file. Check the log for details.|无法将项目保存到文件。请查看日志了解详情。
|
||||
Could not set component type slot. Check log for details.|无法设置元件类型插槽。请查看日志了解详情。
|
||||
Cover|盖子
|
||||
Create B.O.M.|创建物料清单
|
||||
Create New Account|创建新账户
|
||||
Current|当前
|
||||
Cut|剪切
|
||||
Cut Between Holes|在孔之间切割
|
||||
Cut Orientation|切割方向
|
||||
DIP (Mirrored)|DIP(镜像)
|
||||
DP3T (Standard 3-Position Strat)|DP3T(标准3档Strat)
|
||||
DP3T (Standard 5-Position Strat)|DP3T(标准5档Strat)
|
||||
DP4T (4-Position Tele)|DP4T(4档Tele)
|
||||
Dark|深色
|
||||
Dashed|虚线
|
||||
Decimals|小数
|
||||
Default|默认
|
||||
Default Font|默认字体
|
||||
Default Font Size|默认字体大小
|
||||
Delete Selection|删除选择
|
||||
Description|描述
|
||||
Diameter|直径
|
||||
Directional|定向
|
||||
Directly heated|直接加热
|
||||
Display|显示
|
||||
Display Pin #s|显示引脚编号
|
||||
Dog Ear|狗耳
|
||||
Dot Spacing|点间距
|
||||
Donate|捐赠
|
||||
Dotted|点线
|
||||
Drag control point(s) of|拖动控制点
|
||||
Drag the mouse over the canvas to place a new|在画布上拖动鼠标以放置新的
|
||||
Dual Rail Humbucker|双轨拾音器
|
||||
Dual Rods|双杆
|
||||
Duodecar B12C|Duodecar B12C
|
||||
Duplicate|复制
|
||||
Edges|边缘
|
||||
Edit|编辑
|
||||
Edit Project Settings|编辑项目设置
|
||||
Edit Selection|编辑选择
|
||||
Electrode Labels|电极标签
|
||||
Electro-Mechanical|机电
|
||||
Enable Cache Boost|启用缓存加速
|
||||
End Arrow|结束箭头
|
||||
Enjoying DIYLC? Click here to buy me a coffee :)|喜欢DIYLC?点击这里请我喝杯咖啡 :)
|
||||
Error|错误
|
||||
Error occurred while editing selection. Check the log for details.|编辑选择时发生错误。请查看日志了解详情。
|
||||
Exit|退出
|
||||
Expand Selection|扩展选择
|
||||
Explicit Dimensions|显式尺寸
|
||||
Explicit Length|显式长度
|
||||
Explicit Width|显式宽度
|
||||
Export Building Blocks|导出构建块
|
||||
Export Grid|导出网格
|
||||
Export Variants|导出变体
|
||||
Export to PDF|导出为PDF
|
||||
Export to PNG|导出为PNG
|
||||
Extra Working Area|额外工作区
|
||||
Eyelet color|孔眼颜色
|
||||
FAQ|常见问题
|
||||
File|文件
|
||||
Filtertron|Filtertron
|
||||
Find|查找
|
||||
Five|五
|
||||
Flip|翻转
|
||||
Folded|折叠
|
||||
Font|字体
|
||||
Font Bold|粗体
|
||||
Font Italic|斜体
|
||||
Font Size|字体大小
|
||||
Font Size Override|字体大小覆盖
|
||||
Four|四
|
||||
Full|完整
|
||||
Fuse|保险丝
|
||||
Generate DIYLC Netlist|生成DIYLC网表
|
||||
Generate Spice Netlist|生成Spice网表
|
||||
Grid|网格
|
||||
Grid Spacing|网格间距
|
||||
Group Selection|组合选择
|
||||
Guitar|吉他
|
||||
Half|一半
|
||||
Hardware Acceleration|硬件加速
|
||||
Heaters|加热器
|
||||
Height|高度
|
||||
Help|帮助
|
||||
Hi-Quality Rendering|高质量渲染
|
||||
Highlight Connected Areas|高亮连接区域
|
||||
Hole|孔
|
||||
Hole Size|孔径
|
||||
Hole Spacing|孔间距
|
||||
Hole size|孔径
|
||||
Holes per strip|每条带孔数
|
||||
Horizontal|水平
|
||||
Horizontal Alignment|水平对齐
|
||||
Horizontal Large|水平大
|
||||
Horizontal Medium|水平中
|
||||
Horizontal Small 1|水平小1
|
||||
Horizontal Small 2|水平小2
|
||||
Horizontal X-Small|水平超小
|
||||
Humbucking|降噪
|
||||
If this box is checked application will use the current value as a<br>default when creating new components of the same type|如果选中此框,应用程序将在创建相同类型的新元件时使用当前值作为<br>默认值
|
||||
Image|图像
|
||||
Immediate Only|仅立即
|
||||
Import|导入
|
||||
Import Building Blocks|导入构建块
|
||||
Import Netlist|导入网表
|
||||
Import Variants|导入变体
|
||||
In-Line D-44|直插D-44
|
||||
In-line|直插
|
||||
Indent|缩进
|
||||
Information|信息
|
||||
Inline|内联
|
||||
Input error for "%s": %s|"%s"的输入错误:%s
|
||||
Inside color|内部颜色
|
||||
Integration|集成
|
||||
Invert polarity|反转极性
|
||||
Label|标签
|
||||
Label Color|标签颜色
|
||||
Label Orientation|标签方向
|
||||
Label Position|标签位置
|
||||
Labels|标签
|
||||
Language|语言
|
||||
Language selection will be applied after the application is restarted.|语言选择将在应用程序重启后生效。
|
||||
Layer|图层
|
||||
Layers|图层
|
||||
Lead Color|引线颜色
|
||||
Lead Count|引线数量
|
||||
Lead Length|引线长度
|
||||
Lead Spacing|引线间距
|
||||
Left|左
|
||||
Left-to-Right|从左到右
|
||||
Left click to instantiate this component, right click for more options|左键点击以实例化此元件,右键点击以获取更多选项
|
||||
Legs|引脚
|
||||
Length|长度
|
||||
Letters|字母
|
||||
Light|浅色
|
||||
Lock|锁定
|
||||
Log In|登录
|
||||
Log Out|登出
|
||||
Look for|查找
|
||||
Lug Size|焊片尺寸
|
||||
Lugs|焊片
|
||||
Make a Donation|捐赠
|
||||
Manage Account|管理账户
|
||||
Manage My Uploads|管理我的上传
|
||||
Mark Common Lugs|标记公共焊片
|
||||
Marker|标记
|
||||
Marker Size|标记大小
|
||||
Mini|迷你
|
||||
Miniature|微型
|
||||
Mirror Horizontally|水平镜像
|
||||
Mirror Selection|镜像选择
|
||||
Mirror Vertically|垂直镜像
|
||||
Mirroring operation will change the circuit. Do you want to continue?|镜像操作将改变电路。是否继续?
|
||||
Misc|杂项
|
||||
Model|型号
|
||||
Mono|单声道
|
||||
Mount|安装
|
||||
Mounting Lugs|安装焊片
|
||||
Mouse Wheel Zoom|鼠标滚轮缩放
|
||||
Moveable Label|可移动标签
|
||||
Name|名称
|
||||
Negative|负
|
||||
New|新建
|
||||
New version available|新版本可用
|
||||
No new public announcements available.|没有新的公告。
|
||||
No|否
|
||||
None|无
|
||||
North|北
|
||||
Noval B9A|Noval B9A
|
||||
Nudge|微调
|
||||
Numbers|数字
|
||||
Nut|螺母
|
||||
Octal|八脚
|
||||
Offset|偏移
|
||||
One Side|一侧
|
||||
Open|打开
|
||||
Opposing Points|相对点
|
||||
Orientation|方向
|
||||
Outer Foil|外层箔
|
||||
Outer Foil Mark|外层箔标记
|
||||
Outline Mode|轮廓模式
|
||||
Outside|外部
|
||||
Oval horizontal|水平椭圆
|
||||
Oval vertical|垂直椭圆
|
||||
Pad Color|焊盘颜色
|
||||
Panel|面板
|
||||
Passive|被动元件
|
||||
Paste|粘贴
|
||||
Pin Arrangement|引脚排列
|
||||
Pin Color|引脚颜色
|
||||
Pin Spacing|引脚间距
|
||||
Pinout|引脚排列
|
||||
Pins|引脚
|
||||
Play Test|播放测试
|
||||
Plugin API|插件API
|
||||
Point Count|点数
|
||||
Polarity|极性
|
||||
Polarized|极性
|
||||
Pole Color|极颜色
|
||||
Pole Pieces|极片
|
||||
Pole Pieces 1|极片1
|
||||
Pole Pieces 2|极片2
|
||||
Positions|位置
|
||||
Positive|正
|
||||
Power Rating|功率
|
||||
Power Strip|电源条
|
||||
Primary CT|初级中心抽头
|
||||
Print...|打印...
|
||||
Project|项目
|
||||
Project Cloud|项目云
|
||||
Public Announcement|公告
|
||||
Radius|半径
|
||||
Rail|轨道
|
||||
Recent Files|最近文件
|
||||
Recent Updates|最近更新
|
||||
Redo|重做
|
||||
Renumber On Paste|粘贴时重新编号
|
||||
Renumber Selection|重新编号选择
|
||||
Resistance|电阻
|
||||
Reverse (standing)|反向(立式)
|
||||
Right|右
|
||||
Rim|边缘
|
||||
Rods|杆
|
||||
Rotate Clockwise|顺时针旋转
|
||||
Rotate Counterclockwise|逆时针旋转
|
||||
Rotate Selection|旋转选择
|
||||
Round|圆形
|
||||
Round WOG A|圆形WOG A
|
||||
Round WOG B|圆形WOG B
|
||||
Row Spacing|行间距
|
||||
Rows|行
|
||||
Ruler Inch Subdivision...|标尺英寸细分...
|
||||
Same Type Only|仅相同类型
|
||||
Save|保存
|
||||
Save As|另存为
|
||||
Save as Variant|另存为变体
|
||||
Scale|比例
|
||||
Schematic Symbols|原理图符号
|
||||
Screws|螺丝
|
||||
Selection|选择
|
||||
Selection Size|选择大小
|
||||
Selection is empty.|选择为空。
|
||||
Search The Cloud|搜索云
|
||||
Searchable Tree|可搜索树
|
||||
Secondary CT|次级中心抽头
|
||||
Select All|全选
|
||||
Selected component(s) have reached the bottom of their layer. Do you want to force the selection to the back?|所选元件已到达其图层的底部。是否强制将选择移到后面?
|
||||
Selected component(s) have reached the top of their layer. Do you want to force the selection to the top?|所选元件已到达其图层的顶部。是否强制将选择移到前面?
|
||||
Selection contains components that cannot be mirrored. Do you want to exclude them?|选择包含无法镜像的元件。是否排除它们?
|
||||
Selection contains components that cannot be rotated. Do you want to exclude them?|选择包含无法旋转的元件。是否排除它们?
|
||||
Semiconductors|半导体
|
||||
Send Backward|后移一层
|
||||
Send Selection to Back|将选择移到后面
|
||||
Seven|七
|
||||
Shaft Down|轴向下
|
||||
Shaft Up|轴向上
|
||||
Shape|形状
|
||||
Shapes|形状
|
||||
Show Bracket|显示支架
|
||||
Show Grid|显示网格
|
||||
Show Rulers|显示标尺
|
||||
Shroud|护罩
|
||||
Shrouded|带护罩
|
||||
Single Rail|单轨
|
||||
Single Rods|单杆
|
||||
Size|大小
|
||||
Sizing Mode|大小模式
|
||||
Small-button B7G|小按钮B7G
|
||||
Smooth|平滑
|
||||
Snap To|对齐到
|
||||
Soap Bar|肥皂条
|
||||
Solid|实线
|
||||
South|南
|
||||
Spacing|间距
|
||||
Square|方形
|
||||
Square BR-3|方形BR-3
|
||||
Standard|标准
|
||||
Start Arrow|开始箭头
|
||||
Start Recording|开始录制
|
||||
Stereo|立体声
|
||||
Sticky Points|吸附点
|
||||
Stop Recording|停止录制
|
||||
Stratocaster|Stratocaster
|
||||
Strip Color|条带颜色
|
||||
Stripe|条纹
|
||||
Stripe 1|条纹1
|
||||
Stripe 2|条纹2
|
||||
Stripe Color|条纹颜色
|
||||
Stripe Color 1|条纹颜色1
|
||||
Stripe Color 2|条纹颜色2
|
||||
Style|样式
|
||||
Submit a Bug|提交错误报告
|
||||
Suppressor grid|抑制栅极
|
||||
Switched|开关
|
||||
Switches|开关
|
||||
Tab|标签
|
||||
Tab Border|标签边框
|
||||
Tabbed Toolbar|标签工具栏
|
||||
Taper|锥度
|
||||
Telecaster|Telecaster
|
||||
Terminal Spacing|端子间距
|
||||
Terminals|端子
|
||||
Test|测试
|
||||
Text|文本
|
||||
Text Color|文本颜色
|
||||
Theme|主题
|
||||
There are unsaved changes. Would you like to save them?|有未保存的更改。是否保存?
|
||||
Thickness|厚度
|
||||
Three|三
|
||||
Through Hole|通孔
|
||||
Tick|刻度
|
||||
Tick Width|刻度宽度
|
||||
Ticks|刻度
|
||||
Title|标题
|
||||
Toolbox|工具箱
|
||||
Top|顶部
|
||||
Top Lead|顶部引线
|
||||
Top Left|左上
|
||||
Top Right|右上
|
||||
Top-to-Bottom|从上到下
|
||||
Trace|走线
|
||||
Trace Color|走线颜色
|
||||
Trace Mask|走线掩膜
|
||||
Transform Selection|变换选择
|
||||
Triangle|三角形
|
||||
Tubular|管状
|
||||
Tubes|电子管
|
||||
Two|二
|
||||
Type|类型
|
||||
Ultra-miniature|超微型
|
||||
Underside Pad Color|底面焊盘颜色
|
||||
Underside Trace Color|底面走线颜色
|
||||
Undo|撤销
|
||||
Ungroup Selection|取消组合
|
||||
Unit|单位
|
||||
Upload A Project|上传项目
|
||||
User Manual|用户手册
|
||||
Value|值
|
||||
Version history is not available.|版本历史不可用。
|
||||
Vertical|垂直
|
||||
Vertical Alignment|垂直对齐
|
||||
Vertical Inline|垂直内联
|
||||
Vertical Offset 1|垂直偏移1
|
||||
Vertical Offset 2|垂直偏移2
|
||||
View|视图
|
||||
Visible|可见
|
||||
Voltage|电压
|
||||
Wafer|晶圆
|
||||
Warning|警告
|
||||
Width|宽度
|
||||
Winding Spacing|绕组间距
|
||||
Wiring|布线
|
||||
X-axis|X轴
|
||||
Y-axis|Y轴
|
||||
Zoom|缩放
|
||||
base of 10|10进制
|
||||
base of 2|2进制
|
||||
hold %s and drag to unstick from|按住%s并拖动以从...脱离
|
||||
Add a Curve|添加曲线
|
||||
Clear|清除
|
||||
Insert Image|插入图像
|
||||
Load From File|从文件加载
|
||||
Loadline Editor|负载线编辑器
|
||||
Max Current (mA)|最大电流(mA)
|
||||
Max Dissipation (W)|最大功耗(W)
|
||||
Max Voltage (V)|最大电压(V)
|
||||
Save To File|保存到文件
|
||||
Update Axis|更新轴
|
||||
Apply Variant|应用变体
|
||||
Save as Building Block|另存为构建块
|
||||
Select|选择
|
||||
Unlock|解锁
|
||||
Are you sure you want to clear the chat history for this project? This action cannot be undone!|您确定要清除此项目的聊天历史记录吗?此操作无法撤销!
|
||||
Component reordering is possible only when Project Explorer is sorted by z-index.|只有在项目资源管理器按z-index排序时才能重新排序元件。
|
||||
Could not apply changes. Check the log for details.|无法应用更改。请查看日志了解详情。
|
||||
Exporting outline for board %s to file %s|正在将电路板%s的轮廓导出到文件%s
|
||||
Failed to export the project to gerber. Please check the log for details|无法将项目导出为gerber格式。请查看日志了解详情
|
||||
Forgot Password?|忘记密码?
|
||||
Gerber Export|Gerber导出
|
||||
Gerber export completed successfully. The following files were created:%s|Gerber导出成功完成。已创建以下文件:%s
|
||||
Get Premium|获取高级版
|
||||
Netlist files|网表文件
|
||||
No proximity issues detected.|未检测到间距问题。
|
||||
Nothing to export.|没有可导出的内容。
|
||||
Password|密码
|
||||
Send|发送
|
||||
There are some components that are outside of the bounds of boards.%sThey will be ignored unless you add a board component underneath them.%sDo you want to continue?|有些元件超出了电路板的边界。%s除非您在它们下方添加电路板元件,否则它们将被忽略。%s是否继续?
|
||||
User Name|用户名
|
||||
AI Circuit Analyzer|AI电路分析器
|
||||
Cloud|云
|
||||
Compare With...|与...比较
|
||||
Connect to Patreon|连接到Patreon
|
||||
Export|导出
|
||||
Export to Gerber|导出为Gerber
|
||||
Generate DIYLC Netlist (excl. Switches)|生成DIYLC网表(不含开关)
|
||||
Generate DIYLC Netlist (incl. Switches)|生成DIYLC网表(含开关)
|
||||
Generate Spice Netlist (excl. Switches)|生成Spice网表(不含开关)
|
||||
Generate Spice Netlist (incl. Switches)|生成Spice网表(含开关)
|
||||
Silkscreen|丝印
|
||||
Virtual Multimeter (excl. Switches)|虚拟万用表(不含开关)
|
||||
Virtual Multimeter (incl. Switches)|虚拟万用表(含开关)
|
||||
Become a Patreon and enjoy perks|成为Patreon支持者,享受特权
|
||||
Join Patreon|加入Patreon
|
||||
|
||||
Reference in New Issue
Block a user