button standardization

This commit is contained in:
Bane Stojkovic
2026-08-27 16:01:27 +02:00
parent 5e0377867b
commit 4e331ad61b
8 changed files with 86 additions and 93 deletions
@@ -76,6 +76,9 @@ public abstract class AbstractMakerBoard extends AbstractTransparentComponent<Vo
public static Color ANTENNA_COLOR = Color.decode("#DAA520");
public static Color ANTENNA_BG_COLOR = Color.decode("#1E1E1E");
public static Color PAD_COLOR = Color.decode("#DAA520");
public static Color BUTTON_BODY_COLOR = Color.decode("#383838");
public static Color BUTTON_BORDER_COLOR = Color.decode("#666666");
public static Color BUTTON_ACTUATOR_COLOR = Color.decode("#A0A0A0");
public static Size PIN_SIZE = new Size(0.04d, SizeUnit.in);
public static Size PIN_SPACING = new Size(0.1d, SizeUnit.in);
@@ -83,6 +86,8 @@ public abstract class AbstractMakerBoard extends AbstractTransparentComponent<Vo
public static Size HOLE_SIZE = new Size(0.035d, SizeUnit.in);
public static Size ANTENNA_WIDTH = new Size(15.0d, SizeUnit.mm);
public static Size ANTENNA_LENGTH = new Size(7.0d, SizeUnit.mm);
public static Size BUTTON_WIDTH = new Size(3.5d, SizeUnit.mm);
public static Size BUTTON_LENGTH = new Size(3.0d, SizeUnit.mm);
// Standard USB Port Dimensions
public static Size USB_MICRO_WIDTH = new Size(7.5d, SizeUnit.mm);
@@ -905,6 +910,38 @@ public abstract class AbstractMakerBoard extends AbstractTransparentComponent<Vo
drawPcbAntenna(g2d, x, y, ANTENNA_WIDTH.convertToPixels(), ANTENNA_LENGTH.convertToPixels());
}
/**
* Helper to draw a standard SMD tactile push button (housing + circular actuator).
*
* @param g2d Graphics2D context
* @param x Top-left X coordinate of the button body
* @param y Top-left Y coordinate of the button body
* @param w Width of the button body
* @param h Height of the button body
*/
protected void drawButton(Graphics2D g2d, double x, double y, double w, double h) {
g2d.setColor(BUTTON_BODY_COLOR);
g2d.fill(new RoundRectangle2D.Double(x, y, w, h, 2, 2));
g2d.setColor(BUTTON_BORDER_COLOR);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.draw(new RoundRectangle2D.Double(x, y, w, h, 2, 2));
double actuatorD = Math.min(w, h) * 0.55;
g2d.setColor(BUTTON_ACTUATOR_COLOR);
g2d.fill(new Ellipse2D.Double(x + (w - actuatorD) / 2.0, y + (h - actuatorD) / 2.0, actuatorD, actuatorD));
}
/**
* Helper to draw a standard SMD tactile push button with default 3.5mm x 3.0mm dimensions.
*
* @param g2d Graphics2D context
* @param x Top-left X coordinate of the button body
* @param y Top-left Y coordinate of the button body
*/
protected void drawButton(Graphics2D g2d, double x, double y) {
drawButton(g2d, x, y, BUTTON_WIDTH.convertToPixels(), BUTTON_LENGTH.convertToPixels());
}
/**
* Helper to get outline border color.
*/
@@ -59,7 +59,6 @@ public class ArduinoMega extends AbstractMakerBoard {
private static final long serialVersionUID = 1L;
public static Color ARDUINO_BLUE = Color.decode("#00878F");
public static Color RESET_BTN_COLOR = Color.decode("#CC3333");
public static Color SILK_COLOR = Color.WHITE;
public static Size BOARD_WIDTH = new Size(101.6d, SizeUnit.mm);
@@ -286,14 +285,16 @@ public class ArduinoMega extends AbstractMakerBoard {
new Size(0.4d, SizeUnit.in).convertToPixels(), "ATmega2560");
// Reset Button near USB
double rstBtnSize = new Size(0.09d, SizeUnit.in).convertToPixels();
g2d.setColor(RESET_BTN_COLOR);
g2d.fill(new Ellipse2D.Double(boardX + new Size(0.19d, SizeUnit.in).convertToPixels(),
boardY + new Size(0.1d, SizeUnit.in).convertToPixels(), rstBtnSize, rstBtnSize));
double btnW = BUTTON_WIDTH.convertToPixels();
double btnH = BUTTON_LENGTH.convertToPixels();
double btnX = boardX + new Size(0.235d, SizeUnit.in).convertToPixels() - btnW / 2.0;
double btnY = boardY + new Size(0.1d, SizeUnit.in).convertToPixels();
drawButton(g2d, btnX, btnY, btnW, btnH);
g2d.setColor(SILK_COLOR);
g2d.setFont(SILK_FONT_SMALL);
StringUtils.drawCenteredText(g2d, "RST", boardX + new Size(0.235d, SizeUnit.in).convertToPixels(),
boardY + new Size(0.24d, SizeUnit.in).convertToPixels(), HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
StringUtils.drawCenteredText(g2d, "RST", btnX + btnW / 2.0,
btnY + btnH + new Size(1.0d, SizeUnit.mm).convertToPixels(), HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
// Arduino Infinity Logo
drawArduinoLogo(g2d, boardX + new Size(1.2d, SizeUnit.in).convertToPixels(),
@@ -60,7 +60,6 @@ public class ArduinoNano extends AbstractMakerBoard {
private static final long serialVersionUID = 1L;
public static Color ARDUINO_BLUE = Color.decode("#00878F");
public static Color RESET_BTN_COLOR = Color.decode("#CC3333");
public static Color SILK_COLOR = Color.WHITE;
public static Size BOARD_WIDTH = new Size(0.73d, SizeUnit.in);
@@ -247,13 +246,15 @@ public class ArduinoNano extends AbstractMakerBoard {
g2d.setTransform(oldChipTx);
// Reset Button
double rstW = new Size(0.12d, SizeUnit.in).convertToPixels();
double rstH = new Size(0.10d, SizeUnit.in).convertToPixels();
g2d.setColor(RESET_BTN_COLOR);
g2d.fill(new RoundRectangle2D.Double(boardX + (boardW - rstW) / 2.0, boardY + new Size(0.68d, SizeUnit.in).convertToPixels(), rstW, rstH, 3, 3));
double btnW = BUTTON_WIDTH.convertToPixels();
double btnH = BUTTON_LENGTH.convertToPixels();
double btnX = boardX + (boardW - btnW) / 2.0;
double btnY = boardY + new Size(0.68d, SizeUnit.in).convertToPixels();
drawButton(g2d, btnX, btnY, btnW, btnH);
g2d.setColor(SILK_COLOR);
g2d.setFont(SILK_FONT_SMALL);
StringUtils.drawCenteredText(g2d, "RST", boardX + boardW / 2.0, boardY + new Size(0.73d, SizeUnit.in).convertToPixels(), HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
StringUtils.drawCenteredText(g2d, "RST", boardX + boardW / 2.0, btnY - 8, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
// Silkscreen
g2d.setFont(SILK_FONT);
@@ -60,7 +60,6 @@ public class ArduinoUno extends AbstractMakerBoard {
private static final long serialVersionUID = 1L;
public static Color ARDUINO_BLUE = Color.decode("#00878F");
public static Color RESET_BTN_COLOR = Color.decode("#CC3333");
public static Color SILK_COLOR = Color.WHITE;
public static Size BOARD_WIDTH = new Size(68.6d, SizeUnit.mm);
@@ -256,14 +255,16 @@ public class ArduinoUno extends AbstractMakerBoard {
new Size(0.22d, SizeUnit.in).convertToPixels(), "ATmega328P");
// Reset Button near USB
double rstBtnSize = new Size(0.09d, SizeUnit.in).convertToPixels();
g2d.setColor(RESET_BTN_COLOR);
g2d.fill(new Ellipse2D.Double(boardX + new Size(0.19d, SizeUnit.in).convertToPixels(),
boardY + new Size(0.1d, SizeUnit.in).convertToPixels(), rstBtnSize, rstBtnSize));
double btnW = BUTTON_WIDTH.convertToPixels();
double btnH = BUTTON_LENGTH.convertToPixels();
double btnX = boardX + new Size(0.235d, SizeUnit.in).convertToPixels() - btnW / 2.0;
double btnY = boardY + new Size(0.1d, SizeUnit.in).convertToPixels();
drawButton(g2d, btnX, btnY, btnW, btnH);
g2d.setColor(SILK_COLOR);
g2d.setFont(SILK_FONT_SMALL);
StringUtils.drawCenteredText(g2d, "RST", boardX + new Size(0.235d, SizeUnit.in).convertToPixels(),
boardY + new Size(0.24d, SizeUnit.in).convertToPixels(), HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
StringUtils.drawCenteredText(g2d, "RST", btnX + btnW / 2.0,
btnY + btnH + new Size(1.0d, SizeUnit.mm).convertToPixels(), HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
// Arduino Infinity Logo
drawArduinoLogo(g2d, boardX + new Size(1.26d, SizeUnit.in).convertToPixels(),
@@ -79,9 +79,6 @@ public class ESP32DevKit extends AbstractMakerBoard {
public static Color ESP_BLACK = Color.decode("#3E3E3E");
public static Color ANTENNA_BG_COLOR = Color.decode("#1E1E1E");
public static Color BUTTON_BODY_COLOR = Color.decode("#383838");
public static Color BUTTON_BORDER_COLOR = Color.decode("#666666");
public static Color BUTTON_ACTUATOR_COLOR = Color.decode("#A0A0A0");
public static Color SILK_COLOR = Color.WHITE;
public static Size BOARD_WIDTH_30 = new Size(28.33d, SizeUnit.mm);
@@ -369,10 +366,10 @@ public class ESP32DevKit extends AbstractMakerBoard {
if (!outlineMode) {
double shift1mm = new Size(1.0d, SizeUnit.mm).convertToPixels();
double btnW = 20;
double btnH = 20;
if (version == DevKitVersion.DevKit_V1_30Pin) {
double btnW = BUTTON_LENGTH.convertToPixels();
double btnH = BUTTON_WIDTH.convertToPixels();
double rowSpacing = ROW_SPACING.convertToPixels();
double boardW = BOARD_WIDTH_30.convertToPixels();
double boardH = BOARD_LENGTH_30.convertToPixels();
@@ -418,9 +415,9 @@ public class ESP32DevKit extends AbstractMakerBoard {
drawMicroUsb(g2d, usbX, usbY, usbW, usbH, "USB");
// EN & BOOT tactile buttons at bottom (flanking the Micro-USB port)
double btnY = boardY + boardH - 25 - shift1mm;
double btnLeftX = leftHoleX + 14 + shift1mm;
double btnRightX = rightHoleX - 14 - shift1mm - btnW;
double btnY = boardY + boardH - 25 - 1.5 * shift1mm;
double btnLeftX = leftHoleX + 14 + 0.5 * shift1mm;
double btnRightX = rightHoleX - 14 - 0.5 * shift1mm - btnW;
drawButtons(g2d, btnLeftX, btnRightX, btnY, btnW, btnH, "EN", "BOOT");
// Silkscreen
@@ -429,6 +426,8 @@ public class ESP32DevKit extends AbstractMakerBoard {
StringUtils.drawCenteredText(g2d, "ESP32 DevKit V1", centerX, shieldY + shieldH + 45, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
} else if (version == DevKitVersion.ESP32_S3_DevKitC_44Pin) {
double btnW = BUTTON_WIDTH.convertToPixels();
double btnH = BUTTON_LENGTH.convertToPixels();
double boardW = BOARD_WIDTH_S3.convertToPixels();
double boardH = BOARD_LENGTH_S3.convertToPixels();
double topMargin = TOP_MARGIN_S3.convertToPixels();
@@ -475,6 +474,8 @@ public class ESP32DevKit extends AbstractMakerBoard {
} else {
// 38-Pin (DevKitC V4)
double btnW = BUTTON_LENGTH.convertToPixels();
double btnH = BUTTON_WIDTH.convertToPixels();
double rowSpacing = ROW_SPACING.convertToPixels();
double mainW = BOARD_WIDTH_38.convertToPixels();
double mainH = MAIN_BODY_LENGTH_38.convertToPixels();
@@ -505,7 +506,7 @@ public class ESP32DevKit extends AbstractMakerBoard {
drawMicroUsb(g2d, usbX, usbY, usbW, usbH, "USB");
// EN & BOOT tactile buttons at bottom
double btnY = mainY + mainH - 25;
double btnY = mainY + mainH - 25 - new Size(2.0d, SizeUnit.mm).convertToPixels();
double btnLeftX = mainX + 38;
double btnRightX = mainX + mainW - 38 - btnW;
drawButtons(g2d, btnLeftX, btnRightX, btnY, btnW, btnH, "EN", "BOOT");
@@ -533,17 +534,8 @@ public class ESP32DevKit extends AbstractMakerBoard {
*/
private void drawButtons(Graphics2D g2d, double btnLeftX, double btnRightX, double btnY, double btnW, double btnH,
String leftLabel, String rightLabel) {
g2d.setColor(BUTTON_BODY_COLOR);
g2d.fill(new RoundRectangle2D.Double(btnLeftX, btnY, btnW, btnH, 3, 3));
g2d.fill(new RoundRectangle2D.Double(btnRightX, btnY, btnW, btnH, 3, 3));
g2d.setColor(BUTTON_BORDER_COLOR);
g2d.draw(new RoundRectangle2D.Double(btnLeftX, btnY, btnW, btnH, 3, 3));
g2d.draw(new RoundRectangle2D.Double(btnRightX, btnY, btnW, btnH, 3, 3));
// Button actuators
g2d.setColor(BUTTON_ACTUATOR_COLOR);
g2d.fillOval((int) (btnLeftX + btnW / 2.0 - 4), (int) (btnY + btnH / 2.0 - 4), 8, 8);
g2d.fillOval((int) (btnRightX + btnW / 2.0 - 4), (int) (btnY + btnH / 2.0 - 4), 8, 8);
drawButton(g2d, btnLeftX, btnY, btnW, btnH);
drawButton(g2d, btnRightX, btnY, btnW, btnH);
g2d.setColor(SILK_COLOR);
g2d.setFont(SILK_FONT_SMALL);
@@ -62,9 +62,6 @@ public class ESP8266NodeMCU extends AbstractMakerBoard {
public static Color NODEMCU_BLACK = Color.decode("#3E3E3E");
public static Color ANTENNA_COLOR = Color.decode("#DAA520");
public static Color ANTENNA_BG_COLOR = Color.decode("#1E1E1E");
public static Color BUTTON_BODY_COLOR = Color.decode("#383838");
public static Color BUTTON_BORDER_COLOR = Color.decode("#666666");
public static Color BUTTON_ACTUATOR_COLOR = Color.decode("#A0A0A0");
public static Color SILK_COLOR = Color.WHITE;
public static Size BOARD_WIDTH = new Size(25.7d, SizeUnit.mm);
public static Size BOARD_LENGTH = new Size(48.0d, SizeUnit.mm);
@@ -220,24 +217,15 @@ public class ESP8266NodeMCU extends AbstractMakerBoard {
drawMicroUsb(g2d, usbX, usbY, usbW, usbH, "USB");
// RST & FLASH tactile buttons at bottom (flanking the Micro-USB port)
double btnW = 18;
double btnH = 18;
double btnY = boardY + boardH - 25;
double btnW = BUTTON_LENGTH.convertToPixels();
double btnH = BUTTON_WIDTH.convertToPixels();
double btnY = boardY + boardH - 25 - new Size(2.0d, SizeUnit.mm).convertToPixels();
double shift1mm = new Size(1.0d, SizeUnit.mm).convertToPixels();
double btnLeftX = leftHoleX + 10 + shift1mm;
double btnRightX = rightHoleX - 10 - shift1mm - btnW;
g2d.setColor(BUTTON_BODY_COLOR);
g2d.fill(new RoundRectangle2D.Double(btnLeftX, btnY, btnW, btnH, 3, 3));
g2d.fill(new RoundRectangle2D.Double(btnRightX, btnY, btnW, btnH, 3, 3));
g2d.setColor(BUTTON_BORDER_COLOR);
g2d.draw(new RoundRectangle2D.Double(btnLeftX, btnY, btnW, btnH, 3, 3));
g2d.draw(new RoundRectangle2D.Double(btnRightX, btnY, btnW, btnH, 3, 3));
// Button actuators
g2d.setColor(BUTTON_ACTUATOR_COLOR);
g2d.fillOval((int) (btnLeftX + btnW / 2.0 - 3.5), (int) (btnY + btnH / 2.0 - 3.5), 7, 7);
g2d.fillOval((int) (btnRightX + btnW / 2.0 - 3.5), (int) (btnY + btnH / 2.0 - 3.5), 7, 7);
drawButton(g2d, btnLeftX, btnY, btnW, btnH);
drawButton(g2d, btnRightX, btnY, btnW, btnH);
g2d.setColor(SILK_COLOR);
g2d.setFont(SILK_FONT_SMALL);
@@ -264,14 +264,15 @@ public class RaspberryPiPico extends AbstractMakerBoard {
drawMicroUsb(g2d, boardX + (boardW - usbW) / 2.0, boardY - usbOverhang, usbW, usbH, "USB");
// BOOTSEL button
double btnW = new Size(3.8d, SizeUnit.mm).convertToPixels();
double btnH = new Size(3.0d, SizeUnit.mm).convertToPixels();
double btnW = BUTTON_WIDTH.convertToPixels();
double btnH = BUTTON_LENGTH.convertToPixels();
double btnX = boardX + (boardW - btnW) / 2.0;
double btnY = boardY + new Size(11.5d, SizeUnit.mm).convertToPixels();
drawButton(g2d, btnX, btnY, btnW, btnH);
g2d.setColor(Color.WHITE);
g2d.fill(new RoundRectangle2D.Double(boardX + (boardW - btnW) / 2.0, btnY, btnW, btnH, 2, 2));
g2d.setColor(Color.DARK_GRAY);
g2d.setFont(SILK_FONT_SMALL);
StringUtils.drawCenteredText(g2d, "BOOT", boardX + boardW / 2.0, btnY + btnH / 2.0, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
StringUtils.drawCenteredText(g2d, "BOOTSEL", boardX + boardW / 2.0, btnY - 7, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
// RP2040 chip
double chipSize = new Size(7.0d, SizeUnit.mm).convertToPixels();
@@ -76,9 +76,6 @@ public class Teensy extends AbstractMakerBoard {
// Board color matches standard green PCB (like Pi Zero)
public static Color TEENSY_GREEN = Color.decode("#1B5E20");
public static Color BUTTON_BODY_COLOR = Color.decode("#383838");
public static Color BUTTON_BORDER_COLOR = Color.decode("#666666");
public static Color BUTTON_ACTUATOR_COLOR = Color.decode("#A0A0A0");
public static Color SILK_COLOR = Color.WHITE;
public static Color PAD_COLOR = GOLD_COLOR;
@@ -353,18 +350,13 @@ public class Teensy extends AbstractMakerBoard {
drawChip(g2d, chipX, chipY, chipW, chipH, "iMXRT1062");
// Pushbutton (Program button)
double btnW = new Size(3.5d, SizeUnit.mm).convertToPixels();
double btnH = new Size(3.0d, SizeUnit.mm).convertToPixels();
double btnW = BUTTON_WIDTH.convertToPixels();
double btnH = BUTTON_LENGTH.convertToPixels();
double btnX = centerX - btnW / 2.0;
double btnY = (version == TeensyVersion.Teensy_4_0)
? boardY + PIN1_OFFSET_Y.convertToPixels() + 11.5 * PIN_SPACING.convertToPixels() - btnH / 2.0
: boardY + new Size(35.5d, SizeUnit.mm).convertToPixels() + new Size(0.25d, SizeUnit.in).convertToPixels();
g2d.setColor(BUTTON_BODY_COLOR);
g2d.fill(new RoundRectangle2D.Double(btnX, btnY, btnW, btnH, 2, 2));
g2d.setColor(BUTTON_BORDER_COLOR);
g2d.draw(new RoundRectangle2D.Double(btnX, btnY, btnW, btnH, 2, 2));
g2d.setColor(BUTTON_ACTUATOR_COLOR);
g2d.fillOval((int) (btnX + btnW / 2.0 - 2.5), (int) (btnY + btnH / 2.0 - 2.5), 5, 5);
drawButton(g2d, btnX, btnY, btnW, btnH);
// Teensy 4.1 extras: Ethernet PHY + SD card slot
if (version == TeensyVersion.Teensy_4_1) {
@@ -376,26 +368,6 @@ public class Teensy extends AbstractMakerBoard {
drawMetalConnector(g2d, sdX, sdY, sdW, sdH, "SD");
}
// Silkscreen white outline boxes around outer pins
g2d.setColor(Color.WHITE);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
int outerRowCount = (version == TeensyVersion.Teensy_4_0) ? 14 : 24;
double padBoxMargin = new Size(0.9d, SizeUnit.mm).convertToPixels();
// Left row silkscreen box
Point2D pLeftFirst = controlPoints[0];
Point2D pLeftLast = controlPoints[outerRowCount - 1];
g2d.draw(new Rectangle2D.Double(
pLeftFirst.getX() - padBoxMargin, pLeftFirst.getY() - padBoxMargin,
padBoxMargin * 2, (pLeftLast.getY() - pLeftFirst.getY()) + padBoxMargin * 2));
// Right row silkscreen box
Point2D pRightFirst = controlPoints[outerRowCount];
Point2D pRightLast = controlPoints[outerRowCount * 2 - 1];
g2d.draw(new Rectangle2D.Double(
pRightFirst.getX() - padBoxMargin, pRightFirst.getY() - padBoxMargin,
padBoxMargin * 2, (pRightLast.getY() - pRightFirst.getY()) + padBoxMargin * 2));
// Silkscreen "TEENSY" label
g2d.setColor(SILK_COLOR);
g2d.setFont(SILK_FONT);