CI Server publishes no file-format documentation, so real .qli exports and a
real HMI deployment are the only specification the .qli and display generators
were written against. Kept the parts that carry that knowledge:
ciserver-qli-exports/ 10 exports - the .qli format
ciserver-hmi-deployment/ components, layouts, thresholds, locales
+ 6 of 84 displays
Dropped symbols/ (107 MB - CI Server's own installed library, already on
cicore1), the colour-variant displays, editor lock/autosave artefacts, and the
stock OpenPLC sample projects.
203 lines
6.9 KiB
Java
203 lines
6.9 KiB
Java
/*-
|
|
* @(#)ExtendedJBorder.java
|
|
*
|
|
* Copyright: Yokogawa, All rights reserved.
|
|
* YOKOGAWA PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
|
*
|
|
* Author: C. Horevoorts
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
* Changes ....
|
|
* ----------------------------------------------------------------------------
|
|
* Who When Change What
|
|
* ----------------------------------------------------------------------------
|
|
* HVS Feb-08 e9435 First version documented
|
|
* BNL Apr-09 i10199 Correct hit detection for border top, bottom and text
|
|
* BNL Mar-11 e10468 732 Correct hit detection for empty border with text
|
|
* HVS Jun-20 e12272 Port to JViews 2017.2
|
|
*
|
|
*/
|
|
|
|
package fasttools.jwui.ilv.graphic;
|
|
|
|
import fasttools.jwui.common.property.JBorderType;
|
|
import fasttools.jwui.ilv.swing.INonRectangularJComponent;
|
|
import fasttools.jwui.ilv.swing.IJComponentTagger;
|
|
import ilog.views.IlvPoint;
|
|
|
|
import javax.swing.*;
|
|
import javax.swing.border.Border;
|
|
import javax.swing.border.LineBorder;
|
|
import javax.swing.border.TitledBorder;
|
|
import java.awt.*;
|
|
import java.awt.font.FontRenderContext;
|
|
import java.awt.font.TextLayout;
|
|
import java.awt.geom.AffineTransform;
|
|
import java.awt.geom.Path2D;
|
|
import java.awt.geom.Point2D;
|
|
import java.awt.geom.Rectangle2D;
|
|
|
|
/**
|
|
* Extends the ExtendedJBorder to be usable in the {@link ExtendedJComponent} container.
|
|
*/
|
|
public class ExtendedJBorder extends JPanel implements IJComponentTagger, INonRectangularJComponent {
|
|
private String cLabel = "";
|
|
private Border cBorder = JBorderType.NATIVE_BORDER;
|
|
|
|
public ExtendedJBorder() {
|
|
setOpaque(false);
|
|
setBorder(cBorder);
|
|
}
|
|
|
|
/**
|
|
* Sets the label.
|
|
*
|
|
* @param label The label
|
|
*/
|
|
public void setLabelText(String label) {
|
|
if (label == null) {
|
|
label = "";
|
|
}
|
|
|
|
if (!cLabel.equals(label)) {
|
|
cLabel = label;
|
|
createBorder();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the label.
|
|
*
|
|
* @return The label
|
|
*/
|
|
public String getLabelText() {
|
|
return cLabel;
|
|
}
|
|
|
|
/**
|
|
* Sets the border type.
|
|
*
|
|
* @param borderType The border type
|
|
*/
|
|
public void setBorderType(JBorderType borderType) {
|
|
Border mBorder = borderType.getBorder();
|
|
if (mBorder != cBorder) {
|
|
cBorder = mBorder;
|
|
createBorder();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the border type.
|
|
*
|
|
* @return The border type
|
|
*/
|
|
public JBorderType getBorderType() {
|
|
return new JBorderType(cBorder);
|
|
}
|
|
|
|
/**
|
|
* Override to update the border.
|
|
*
|
|
* @param color The color
|
|
*/
|
|
public void setForeground(Color color) {
|
|
super.setForeground(color);
|
|
createBorder();
|
|
}
|
|
|
|
/**
|
|
* Override to update the border.
|
|
*
|
|
* @param font The font
|
|
*/
|
|
public void setFont(Font font) {
|
|
super.setFont(font);
|
|
createBorder();
|
|
}
|
|
|
|
/**
|
|
* Recreate the border.
|
|
*/
|
|
private void createBorder() {
|
|
if (cLabel != null) {
|
|
Border mBorder = cBorder;
|
|
if (mBorder instanceof LineBorder) {
|
|
mBorder = new LineBorder(getForeground());
|
|
}
|
|
if (cLabel.length() > 0) {
|
|
mBorder = new TitledBorder(mBorder, cLabel, TitledBorder.LEADING, TitledBorder.TOP, getFont(), getForeground());
|
|
}
|
|
setBorder(mBorder);
|
|
}
|
|
}
|
|
|
|
public boolean contains(Point2D p, AffineTransform t, GraphicHelper graphicHelper, float zoomFactor, boolean zoomEnabled) {
|
|
// TODO: Shearing is not taken into consideration, so sheared borders won't hit-detect correctly.
|
|
Shape mShape = graphicHelper.getShape();
|
|
if (isOpaque()) {
|
|
return mShape.contains(p);
|
|
}
|
|
if (!mShape.contains(p)) {
|
|
return false;
|
|
}
|
|
Point2D mTopLeft = graphicHelper.getXYNull();
|
|
Point2D mTopRight = graphicHelper.getXYWidth();
|
|
double mRotation = GraphicHelper.getRotationAngleInDegrees((IlvPoint) mTopLeft, (IlvPoint) mTopRight);
|
|
|
|
String mLabel = getLabelText();
|
|
if (mLabel != null && !mLabel.equals("")) {
|
|
Graphics2D g = (Graphics2D) getGraphics();
|
|
FontRenderContext mFontRenderingContext = g.getFontRenderContext();
|
|
Font mFont = getFont();
|
|
TextLayout mActualText = new TextLayout(mLabel, mFont, mFontRenderingContext);
|
|
TextLayout mHeightText = new TextLayout("abcdefghijklmnopqrstuvwxyz", mFont, mFontRenderingContext);
|
|
Rectangle2D mBounds = mActualText.getBounds();
|
|
Rectangle2D mHeightBounds = mHeightText.getBounds();
|
|
double mZoomFactor = zoomFactor / (zoomEnabled ? 1.0 : t.getScaleX());
|
|
double mTextHeight = mHeightBounds.getHeight() * mZoomFactor;
|
|
// NOTE: The width in mBounds is too long for reasons that I've given up trying to figure out. Multiplying by 0.75 gives us a value that's good enough for now.
|
|
double mTextWidth = mBounds.getWidth() * mZoomFactor * 0.75;
|
|
double mLeftInset = 5.0 * mZoomFactor;
|
|
Point2D mTextTopLeft = getPointFrom((IlvPoint) mTopLeft, mLeftInset, mRotation);
|
|
Point2D mTextTopRight = getPointFrom((IlvPoint) mTextTopLeft, mTextWidth, mRotation);
|
|
Point2D mTextBottomLeft = getPointFrom((IlvPoint) mTextTopLeft, mTextHeight, mRotation + 90.0);
|
|
Point2D mTextBottomRight = getPointFrom((IlvPoint) mTextBottomLeft, mTextWidth, mRotation);
|
|
Path2D.Double mTextShapeRectangle = new Path2D.Double(Path2D.WIND_NON_ZERO, 4);
|
|
mTextShapeRectangle.moveTo(mTextTopLeft.getX(), mTextTopLeft.getY());
|
|
mTextShapeRectangle.lineTo(mTextTopRight.getX(), mTextTopRight.getY());
|
|
mTextShapeRectangle.lineTo(mTextBottomRight.getX(), mTextBottomRight.getY());
|
|
mTextShapeRectangle.lineTo(mTextBottomLeft.getX(), mTextBottomLeft.getY());
|
|
if (mTextShapeRectangle.contains(p)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (!getBorderType().equals(new JBorderType(JBorderType.EMPTY))) {
|
|
double mBorderWidth = 6.0 * zoomFactor;
|
|
if (!zoomEnabled && t != null) {
|
|
mBorderWidth /= t.getScaleX();
|
|
}
|
|
Point2D mBottomLeft = graphicHelper.getXYHeight();
|
|
Point2D mBottomRight = graphicHelper.getXYWidthHeight();
|
|
mTopLeft = getPointFrom((IlvPoint) mTopLeft, mBorderWidth, mRotation + 45.0);
|
|
mTopRight = getPointFrom((IlvPoint) mTopRight, mBorderWidth, mRotation + 135.0);
|
|
mBottomRight = getPointFrom((IlvPoint) mBottomRight, mBorderWidth, mRotation + 225.0);
|
|
mBottomLeft = getPointFrom((IlvPoint) mBottomLeft, mBorderWidth, mRotation + 315.0);
|
|
Path2D.Double mInsideShape = new Path2D.Double(Path2D.WIND_NON_ZERO, 4);
|
|
mInsideShape.moveTo(mTopLeft.getX(), mTopLeft.getY());
|
|
mInsideShape.lineTo(mTopRight.getX(), mTopRight.getY());
|
|
mInsideShape.lineTo(mBottomRight.getX(), mBottomRight.getY());
|
|
mInsideShape.lineTo(mBottomLeft.getX(), mBottomLeft.getY());
|
|
if (!mInsideShape.contains(p)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private Point2D getPointFrom(IlvPoint point, double distance, double angle) {
|
|
IlvPoint mMidPoint = GraphicHelper.getPointRotatedFrom(point, angle - 45.0, distance);
|
|
return GraphicHelper.getPointRotatedFrom(mMidPoint, angle + 45.0, distance);
|
|
}
|
|
}
|