org.sikuli.guide.SxCallout Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sikulixapi Show documentation
Show all versions of sikulixapi Show documentation
... for visual testing and automation
/*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
/**
*
*/
package org.sikuli.guide;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.RoundRectangle2D;
import org.sikuli.script.Region;
public class SxCallout extends Visual {
static final int TRIANGLE_SIZE = 20;
static int defMaxWidth = 400;
static int defFontSize = 14;
static String defFont = "Verdana";
HTMLTextPane textArea;
RoundedBox rbox;
Triangle triangle;
int dx = 0;
int dy = 0;
public SxCallout(String text) {
super();
init(text);
}
void init(String text) {
layout = Layout.RIGHT;
maxWidth = defMaxWidth;
fontName = defFont;
fontSize = defFontSize;
this.text = text;
textArea = new HTMLTextPane(this);
rbox = new RoundedBox(textArea.getBounds());
add(textArea);
add(rbox);
triangle = new Triangle();
add(triangle);
targetRegion = null;
setColors(null, Color.YELLOW, Color.YELLOW, null, null);
makeComponent();
}
@Override
public void updateComponent() {
textArea.setText(text);
textArea.setLocation(PADDING_X, PADDING_Y);
Rectangle rect = textArea.getBounds();
rect.grow(PADDING_X, PADDING_Y);
rbox.setBounds(rect);
makeComponent();
triangle.setForeground(colorBack);
rbox.setForeground(colorBack);
if (targetRegion != null) {
super.setLocationRelativeToRegion(targetRegion, layout);
}
}
@Override
public Visual setLocationRelativeToRegion(Region region, Layout side) {
if (side != layout) {
layout = side;
updateComponent();
}
targetRegion = region;
return super.setLocationRelativeToRegion(targetRegion, side);
}
private void makeComponent() {
if (layout == Layout.TOP) {
triangle.rotate(0);
dx = 0; dy = 0;
triangle.setLocationRelativeToComponent(rbox, Layout.BOTTOM);
} else if (layout == Layout.BOTTOM) {
dx = 0; dy = TRIANGLE_SIZE;
triangle.rotate(Math.PI);
triangle.setLocationRelativeToComponent(rbox, Layout.TOP);
} else if (layout == Layout.LEFT) {
dx = 0; dy = 0;
triangle.rotate(-Math.PI / 2);
triangle.setLocationRelativeToComponent(rbox, Layout.RIGHT);
} else if (layout == Layout.RIGHT) {
dx = TRIANGLE_SIZE; dy = 0;
triangle.rotate(Math.PI / 2);
triangle.setLocationRelativeToComponent(rbox, Layout.LEFT);
}
Rectangle bounds = rbox.getBounds();
bounds.add(triangle.getBounds());
setActualBounds(bounds);
}
@Override
public void paintComponent(Graphics g) {
g.translate(dx, dy);
super.paintComponent(g);
}
class Triangle extends Visual {
GeneralPath gp;
public Triangle() {
super();
init();
}
private void init() {
gp = new GeneralPath();
gp.moveTo(TRIANGLE_SIZE * 0.45, 0);
gp.lineTo(TRIANGLE_SIZE * 0.5, TRIANGLE_SIZE);
gp.lineTo(TRIANGLE_SIZE * 0.85, 0);
gp.closePath();
setActualSize(new Dimension(TRIANGLE_SIZE, TRIANGLE_SIZE));
}
public void rotate(double radius) {
init();
AffineTransform rat = new AffineTransform();
rat.rotate(radius, TRIANGLE_SIZE / 2, TRIANGLE_SIZE / 2);
gp.transform(rat);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.fill(gp);
}
}
class RoundedBox extends Visual {
public RoundedBox(Rectangle rect) {
super();
setActualBounds(rect);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
RoundRectangle2D roundedRectangle = new RoundRectangle2D.Float(0, 0, getWidth(), getHeight(), 15, 15);
g2d.fill(roundedRectangle);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy