/* * Copyright (c) 2014 Paul Scherrer Institute. All rights reserved. */ package ch.psi.mxsc; import ch.psi.pshell.device.Device; import ch.psi.pshell.device.DeviceBase; import ch.psi.pshell.imaging.DimensionDouble; import ch.psi.pshell.imaging.PointDouble; import ch.psi.utils.swing.MainFrame; import ch.psi.utils.swing.SwingUtils; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Rectangle; import java.util.ArrayList; /** * */ public class Puck extends DeviceBase { final static PointDouble[] samplesPosition = new PointDouble[]{ new PointDouble(0, 24.24), new PointDouble(23.05360995, 7.490571944), new PointDouble(14.24791452, -19.61057194), new PointDouble(-14.24791452, -19.61057194), new PointDouble(-23.05360995, 7.490571944), new PointDouble(0, 52.52), new PointDouble(28.39445573, 44.18263554), new PointDouble(47.7738724, 21.81759648), new PointDouble(51.98542213, -7.474375306), new PointDouble(39.69196765, -34.39328575), new PointDouble(14.79659389, -50.39257097), new PointDouble(-14.79659389, -50.39257097), new PointDouble(-39.69196765, -34.39328575), new PointDouble(-51.98542213, -7.474375306), new PointDouble(-47.7738724, 21.81759648), new PointDouble(-28.39445573, 44.18263554) }; static final Character[] SEGMENTS = new Character[]{'A', 'A', 'F', 'F', 'F', 'F', 'F', 'E', 'E', 'E', 'E', 'E', 'D', 'D', 'D', 'D', 'D', 'C', 'C', 'C', 'C', 'C', 'B', 'B', 'B', 'B', 'B', 'A', 'A', 'A'}; static final int[] NUMBERS = new int[]{1, 2, 5, 4, 3, 1, 2, 5, 4, 3, 1, 2, 5, 4, 3, 1, 2, 5, 4, 3, 1, 2, 5, 4, 3, 1, 2, 5, 4, 3}; static final int[] ADDRESSES = new int[]{6, 7, 5, 4, 3, 1, 2, 20, 19, 18, 16, 17, 15, 14, 13, 11, 12, 30, 29, 28, 26, 27, 25, 24, 23, 21, 22, 10, 9, 8}; static final double[] ANGLES = new double[]{ 0.00, 0.00, 19.11, 40.89, 30.00, 60.00, 60.00, 79.11, 100.89, 90.00, 120.00, 120.00, 139.11, 160.89, 150.00, 180.00, 180.00, 199.11, 220.89, 210.00, 240.00, 240.00, 259.11, 280.89, 270.00, 300.00, 300.00, 319.11, 340.89, 330.00}; final static PointDouble referencePosition = new PointDouble(0.0, -66.9 - 0.2); final static Double referenceSize = 6.2 + 0.2; final static PointDouble ledUnipuckPosition = new PointDouble(0.0, 0.0); final static PointDouble ledMinispinePosition = new PointDouble(0.0, -36.0); final static Double unipuckLedSize = 10.0; final static Double minispineLedSize = 8.0; final static PointDouble labelPositionWithImage = new PointDouble(0.0, 36.0); PuckType puckType = PuckType.Unknown; public PuckType getPuckType(){ return puckType; } public void setPuckType(PuckType value){ puckType = value; } public enum PuckType{ Empty, Minispine, Unipuck, Error, Unknown; public boolean isDefined(){ return (this==Minispine) || (this==Unipuck); } } public String getStatus(){ if ((detection==Detection.Present) && puckType.isDefined()) { return puckType.toString(); } return detection.toString(); } public double getAngle() { return ANGLES[index]; } final int numberOfSamples = samplesPosition.length; final int index; Character segment; final int address; final int number; final double angle; Puck(BasePlate basePlate, int index) { //super(String.valueOf(index+1)); super(SEGMENTS[index] + "" + NUMBERS[index]); this.setParent(basePlate); this.index = index; this.segment = SEGMENTS[index]; this.number = NUMBERS[index]; this.address = ADDRESSES[index]; this.angle = getAngle(); for (int i = 0; i < numberOfSamples; i++) { new Sample(this, i); } } public BasePlate getBasePlate() { return (BasePlate) getParent(); } DimensionDouble getSize() { return new DimensionDouble(67.0, 67.0); } public Sample[] getSamples() { ArrayList ret = new ArrayList<>(); for (Device d : getChildren()) { ret.add((Sample) d); } return ret.toArray(new Sample[0]); } public PointDouble getRotatedPosition(PointDouble ref) { double rotation = - angle * Math.PI / 180.0; double x = ref.x * Math.cos(rotation) - ref.y * Math.sin(rotation); double y = ref.y * Math.cos(rotation) + ref.x * Math.sin(rotation); return new PointDouble(x,y ); } public PointDouble getSamplePosition(Sample sample) { //PointDouble ref = samplesPosition[sample.index]; //return getRotatedPosition(ref); return samplesPosition[sample.index]; } public Point getDrawUnipuckLedPosition(){ PointDouble ref = ledUnipuckPosition; return getDrawPosition(ref); } public Point getDrawMinispineLedPosition(){ PointDouble ref = ledMinispinePosition; return getDrawPosition(ref); } int getUnipuckLedSize() { return getDrawSize(unipuckLedSize) ; } int getMinispineLedSize() { return getDrawSize(minispineLedSize) ; } int getDrawSize(double refSize) { return (int) ((refSize / getSize().getWidth()) * getDrawSize()) ; } Point getDrawPosition(PointDouble refPosition) { Point puckCenter = getDrawPosition(); int puckDrawSize = getDrawSize(); DimensionDouble puckSize = getSize(); PointDouble pos = getRotatedPosition(refPosition); return new Point( (int) ((pos.x / puckSize.getWidth())* puckDrawSize/2 + puckCenter.x) , (int) ((pos.y / puckSize.getHeight())* puckDrawSize/2 + puckCenter.y) ); } public boolean isSegmentSelected() { /* switch(Integer.valueOf(Controller.getInstance().getHexaposiPosition())){ case 1: return getSegment()=='A'; case 2: return getSegment()=='B'; case 3: return getSegment()=='C'; case 4: return getSegment()=='D'; case 5: return getSegment()=='E'; case 6: return getSegment()=='F'; } } catch(Exception ex){ } return false; */ return ("" + getSegment()).equalsIgnoreCase(Controller.getInstance().getHexiposiPosition()); } public boolean isHighlithted() { return isSelected() || isSegmentSelected(); } public int getIndex() { return index; } String id; public String getId() { //return "XXX000" + index; return id; } public void setId(String value) { id = value; } public char getSegment() { return segment; } public int getNumber() { return number; } public int getAddress() { return address; } boolean enabled; public boolean isEnabled() { return enabled; } public void setEnabled(boolean value) { enabled = value; } public enum Detection { Empty, Present, Offline, Error } Detection detection = Detection.Error; public Detection getDetection() { return detection; } boolean detectionError; public boolean isDetectionError() { return detectionError; } private boolean selected; public boolean isSelected() { return selected && getBasePlate().isSelectable(); } public void toggleSelected(boolean value) { setSelected(!selected); } public void setSelected(boolean value) { if (value != selected) { if (value == true) { for (Device d : getParent().getChildren()) { if (d instanceof Puck) { ((Puck) d).selected = false; for (Sample sample : ((Puck) d).getSamples()) { sample.selected = false; } } } } for (Sample sample : getSamples()) { sample.selected = false; } selected = value; getBasePlate().onSelectionChanged(); } } public int getNumberOfSamples() { return numberOfSamples; } Color getColor() { Color ret = Color.LIGHT_GRAY; switch (detection) { case Empty: //ret = isHighlithted() ? new Color(224, 224, 224) : Color.LIGHT_GRAY; ret = isHighlithted() ? new Color(212, 212, 212) : Color.LIGHT_GRAY; break; case Present: if ((puckType != null) && (puckType != PuckType.Unknown)){ switch (puckType){ case Minispine: ret = isHighlithted() ? new Color(0, 200, 80) : new Color(128, 232, 152); break; case Unipuck: ret = isHighlithted() ? new Color(0, 140, 140) : new Color(128, 192, 192); break; case Empty: case Error: ret = isHighlithted() ? new Color(192, 10, 10) : new Color(192, 128, 128); break; } } else { ret = isHighlithted() ? new Color(0, 140, 140) : new Color(128, 192, 192); } break; case Error: ret = isHighlithted() ? new Color(192, 10, 10) : new Color(192, 128, 128); break; case Offline: ret = isHighlithted() ? new Color(250, 255, 48) : new Color(253, 194, 41); //ret = isHighlithted() ? new Color(230, 142, 40) : new Color(216, 159, 93); break; } return ret; } int getDrawSize() { //Single puck plot if (plotRect != null) { return Math.min(plotRect.width, plotRect.height); } //All pucks Rectangle plotRect = getBasePlate().getBoundingBox(); int ret = Math.min( (int) ((getSize().getWidth() / getBasePlate().getSize().getWidth()) * plotRect.width), (int) ((getSize().getHeight() / getBasePlate().getSize().getHeight()) * plotRect.height) ); if (isSelected()) { ret += 2; } return ret; } Point getDrawPosition() { //Single puck plot if (plotRect != null) { return new Point((int) plotRect.getCenterX(), (int) plotRect.getCenterY()); } //All pucks Rectangle plotRect = getBasePlate().getBoundingBox(); DimensionDouble plateSize = getBasePlate().getSize(); PointDouble pos = getBasePlate().getPuckPosition(this); return new Point((int) ((pos.x / plateSize.getWidth()) * plotRect.width + plotRect.getCenterX()), (int) ((pos.y / plateSize.getHeight()) * plotRect.height + plotRect.getCenterY()) ); } Color getLabelColor(boolean drawBackground) { return drawBackground ? (isHighlithted() ? Color.BLACK : new Color(92, 92, 92)) : (isHighlithted() ? new Color(0, 255, 0) : new Color(0, 162, 0)); } Font getLabelFont() { /* if (plotRect != null) { return new Font("Times New Roman", Font.BOLD, 18); } return new Font("Times New Roman", Font.BOLD, 10); */ if (plotRect != null) { return new Font("Segoe UI", Font.BOLD, 18); } return new Font("Segoe UI", Font.BOLD, 12); } Font getIdFont() { if (plotRect != null) { return new Font("Times New Roman", Font.PLAIN, 12); } return new Font("Times New Roman", Font.PLAIN, 9); } Point getLabelDrawPosition(String text, Graphics g, boolean drawBackground) { Point pos = drawBackground ? getDrawPosition() : getDrawPosition(labelPositionWithImage); Dimension textSize = SwingUtils.getTextSize(text, g.getFontMetrics()); return new Point(pos.x - textSize.width / 2 , pos.y + (g.getFontMetrics().getAscent() / 2)); } Color getBorderColor(boolean drawBackground) { if (drawBackground) { /*if (!isEnabled()){ return Color.GRAY; } else */ if (isHighlithted()) { return new Color(0, 0, 0); } return Color.GRAY; } return isHighlithted() ? new Color(0, 208, 0) : new Color(0, 128, 0); } int getBorderWidth(boolean drawBackground) { return drawBackground ? isSegmentSelected() ? 2 : 1 : isSegmentSelected() ? 2 : 1; } int getReferenceDrawSize() { return getDrawSize(referenceSize) ; } Point getReferenceDrawPosition() { return getDrawPosition(new PointDouble(0, -67.0)); } Rectangle plotRect; void draw(Graphics2D g, Rectangle plotRect, boolean drawSamples, boolean drawId, boolean drawBackground, BasePlate enclosingPlate) { this.plotRect = plotRect; Point position = getDrawPosition(); int size = getDrawSize(); if (drawBackground) { g.setColor(getColor()); g.fillOval(position.x - size / 2, position.y - size / 2, size, size); } g.setColor(getBorderColor(drawBackground)); g.setStroke(new BasicStroke(getBorderWidth(drawBackground))); g.drawOval(position.x - size / 2, position.y - size / 2, size, size); g.setStroke(new BasicStroke(1f)); if (drawSamples) { //Draw samples for (Sample sample : getSamples()) { sample.draw(g, drawBackground); } } //Draw reference Color refColor = MainFrame.isDark() ? Color.DARK_GRAY : new Color(214, 217, 223); if ((enclosingPlate != null) && enclosingPlate.drawContour) { refColor = enclosingPlate.getColor(); } if (drawBackground){ g.setColor(refColor); position = getReferenceDrawPosition(); size = getReferenceDrawSize(); //size+=1; g.fillArc(position.x - size / 2, position.y - size / 2 , size, size, (int) (180 + angle), 180); g.setColor(getBorderColor(drawBackground)); g.drawArc(position.x - size / 2, position.y - size / 2 , size, size, (int) (180 + angle), 180); } else { Point pu = getDrawUnipuckLedPosition(); Point pm = getDrawMinispineLedPosition(); int unipuckSize = getUnipuckLedSize(); int minispineSize = getMinispineLedSize(); g.setColor(getBorderColor(drawBackground)); g.drawOval(pu.x - unipuckSize / 2, pu.y - unipuckSize / 2, unipuckSize, unipuckSize); g.drawOval(pm.x - minispineSize / 2, pm.y - minispineSize / 2, minispineSize, minispineSize); } //Draw text String text = getName(); //String.valueOf(getIndex() + 1); g.setColor(getLabelColor(drawBackground)); g.setFont(getLabelFont()); Point labelPosition = getLabelDrawPosition(text, g, drawBackground); g.drawString(text, labelPosition.x, labelPosition.y); if (drawId) { String id = getId(); if (id != null) { labelPosition.setLocation(labelPosition.x, labelPosition.y - 6); g.setFont(getIdFont()); Dimension textSize = SwingUtils.getTextSize(id, g.getFontMetrics()); g.drawString(id, getDrawPosition().x - textSize.width/2 , getDrawPosition().y + 10 ); } } } }