org.sikuli.guide.SxBeam Maven / Gradle / Ivy
/*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.guide;
import org.sikuli.script.Region;
import org.sikuli.util.OverlayTransparentWindow;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import org.sikuli.util.EventObserver;
import org.sikuli.util.EventSubject;
import org.sikuli.basics.Settings;
import org.sikuli.natives.SysUtil;
public class SxBeam extends OverlayTransparentWindow
implements Transition, GlobalMouseMotionListener, EventObserver {
Guide guide;
public SxBeam(Guide guide, Region target) {
super(new Color(1f, 0f, 0f, 0.7f), null);
super.addObserver(this);
this.guide = guide;
this.target = target;
/*
setBackground(null);
// when opaque is set to false, the content seems to get cleared properly
// this is tested on both Windows and Mac
SysUtil.getOSUtil().setWindowOpaque(this, false);
setOpacity(0.7f);
*/
}
public Point current = null;
public Point to = null;
Region target;
@Override
public void update(EventSubject es) {
Graphics2D g = ((OverlayTransparentWindow) es).getJPanelGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
drawRayPolygon(g, current, target.getRect());
}
/*
public void paint(Graphics g){
Graphics2D g2d = (Graphics2D)g;
super.paint(g);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
drawRayPolygon(g, current, target.getRect());
}
*/
public void drawRayPolygon(Graphics g, Point p, Rectangle rect) {
if (p == null || rect == null) {
return;
}
Graphics2D g2d = (Graphics2D) g;
Rectangle r = rect;
Ellipse2D.Double ellipse =
new Ellipse2D.Double(r.x, r.y, r.width - 1, r.height - 1);
g2d.setColor(Color.red);
g2d.fill(ellipse);
//g2d.drawRect(rect.x,rect.y,rect.width,rect.height);
// compute tangent points
g2d.translate(rect.x + rect.width / 2, rect.y + rect.height / 2);
float a0 = r.width / 2;
float b0 = r.height / 2;
float a = a0 * a0;
float b = b0 * b0;
float m = p.x - rect.x - rect.width / 2;
float n = p.y - rect.y - rect.height / 2;
float t1 = (1f + (a * n * n) / (b * m * m));
float t2 = -2f * a * n / (m * m);
float t3 = (b * a) / (m * m) - b;
float s = (float) Math.sqrt(t2 * t2 - 4 * t1 * t3);
float y1 = (-t2 + s) / (2 * t1);
float y2 = (-t2 - s) / (2 * t1);
float x1 = a / m - y1 * (a * n) / (b * m);
float x2 = a / m - y2 * (a * n) / (b * m);
// g2d.drawLine((int)m,(int)n,(int)x1,(int)y1);
// g2d.drawLine((int)m,(int)n,(int)x2,(int)y2);
//
//
// g2d.setColor(Color.black);
// g2d.drawLine(0,0,(int)a0,(int)b0);
//
//
//
GeneralPath flagShape = new GeneralPath();
flagShape.moveTo(m, n);
flagShape.lineTo(x1, y1);
flagShape.lineTo(x2, y2);
flagShape.closePath();
g2d.fill(flagShape);
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 1.0f));
//Rectangle smaller = new Rectangle(rect);
ellipse =
new Ellipse2D.Double(-r.width / 2 + 3, -r.height / 2 + 3, r.width - 6, r.height - 6);
g2d.fill(ellipse);
}
public void drawRayPolygon1(Graphics g, Point p, Rectangle rect) {
if (p == null || rect == null) {
return;
}
Graphics2D g2d = (Graphics2D) g;
Rectangle r = rect;
// corners of the target rectangle
int cxs[] = {r.x, r.x, r.x + r.width, r.x + r.width};
int cys[] = {r.y, r.y + r.height, r.y + r.height, r.height};
ArrayList corners = new ArrayList();
corners.add(new Point(r.x, r.y));
corners.add(new Point(r.x + r.width, r.y + r.height));
corners.add(new Point(r.x + r.width, r.y));
corners.add(new Point(r.x, r.y + r.height));
Collections.sort(corners, new Comparator() {
@Override
public int compare(Object arg0, Object arg1) {
return (int) (current.distance((Point) arg0) - current.distance((Point) arg1));
}
});
int[] xs;
int[] ys;
int d = 5;
if (p.x > rect.getMinX() - 5 && p.x < rect.getMaxX() + 5
|| p.y > rect.getMinY() - 5 && p.y < rect.getMaxY() + 5) {
xs = new int[3];
ys = new int[3];
xs[0] = (int) p.x;
xs[1] = (int) corners.get(0).x;
xs[2] = (int) corners.get(1).x;
ys[0] = (int) p.y;
ys[1] = (int) corners.get(0).y;
ys[2] = (int) corners.get(1).y;
} else {
xs = new int[4];
ys = new int[4];
xs[0] = (int) p.x;
xs[1] = (int) corners.get(2).x;
xs[2] = (int) corners.get(0).x;
xs[3] = (int) corners.get(1).x;
ys[0] = (int) p.y;
ys[1] = (int) corners.get(2).y;
ys[2] = (int) corners.get(0).y;
ys[3] = (int) corners.get(1).y;
}
Polygon shape = new Polygon(xs, ys, xs.length);
Stroke pen = new BasicStroke(3.0F);
g2d.setStroke(pen);
g2d.setColor(Color.black);
//g2d.drawPolygon(pointing_triangle);
//g2d.drawRect(x,y,w,h);
g2d.setColor(Color.red);
g2d.fillPolygon(shape);
g2d.drawRect(rect.x, rect.y, rect.width, rect.height);
}
@Override
public void toFront() {
if ( Settings.isMac() || Settings.isWindows() ) {
// this call is necessary to allow clicks to go through the window (ignoreMouse == true)
if (Settings.JavaVersion < 7) {
SysUtil.getOSUtil().bringWindowToFront(this, true);
} else {
}
}
super.toFront();
}
GlobalMouseMotionTracker mouseTracker;
TransitionListener listener;
@Override
public String waitForTransition(TransitionListener listener) {
this.listener = listener;
mouseTracker = GlobalMouseMotionTracker.getInstance();
mouseTracker.addListener(this);
mouseTracker.start();
setBounds(guide.getRegion().getRect());
setVisible(true);
toFront();
// repaint();
// Cursor handCursor = new Cursor(Cursor.HAND_CURSOR);
// Cursor defaultCursor = new Cursor(Cursor.DEFAULT_CURSOR);
// Cursor currentCursor = null;
//
// boolean running = true;
// while (running){
//
// Rectangle target_rect = target.getRect();
// Location m = Region.atMouse();
//
// current = new Point(m.x,m.y);
//
// Cursor cursor = null;
// if (target_rect.contains(current)){
// running = false;
// cursor = handCursor;
//
// setVisible(false);
// dispose();
//// synchronized(guide){
//// guide.notify();
//// dispose();
//// return "Next";
//// }
// token.transitionOccurred(this);
// return "Next";
//
// }else{
// cursor = defaultCursor;
// repaint();
// }
//
//
// if (cursor != currentCursor){
// setCursor(cursor);
// currentCursor = cursor;
// }
//
// }
return "Next";
}
@Override
public void globalMouseIdled(int x, int y) {
}
@Override
public void globalMouseMoved(int x, int y) {
current = new Point(x, y);
repaint();
if (target.getRect().contains(current)) {
setVisible(false);
dispose();
listener.transitionOccurred(this);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy