org.sikuli.guide.SxMagnet 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-2019, sikuli.org, sikulix.com - MIT license
*/
package org.sikuli.guide;
import java.awt.Dimension;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import org.sikuli.guide.SxAnchor.AnchorListener;
import org.sikuli.guide.Visual.Layout;
import org.sikuli.basics.Debug;
import org.sikuli.script.Env;
import org.sikuli.script.Location;
import org.sikuli.script.Pattern;
import org.sikuli.script.Region;
public class SxMagnet
implements Transition, GlobalMouseMotionListener {
Guide guide;
GlobalMouseMotionTracker mouseTracker;
private SxClickable lastClickedClickable;
public SxMagnet(Guide guide) {
this.guide = guide;
mouseTracker = GlobalMouseMotionTracker.getInstance();
mouseTracker.addListener(this);
// TOOD: fix this hack
// use this trick to engage clickablewindow
guide.addComponent(new SxClickable(), 0);
}
ArrayList targets = new ArrayList();
ArrayList links = new ArrayList();
// void flyTarget(SxAnchor a){
//
// Location mouseLocation = Env.getMouseLocation();
//
// try {
// Pattern pattern = a.getPattern();
// SxImage img = new SxImage(pattern.getBImage());
// img.setActualLocation(a.getActualLocation());
//
// Dimension currentSize = a.getActualSize();
// Dimension targetSize = new Dimension(currentSize);
// targetSize.width *= 1.5;
// targetSize.height *= 1.5;
//
// img.addResizeAnimation(currentSize, targetSize);
//
//
// Point currentLocation = new Point(a.getActualLocation());
// currentLocation.x += img.getActualWidth();
// currentLocation.y += img.getActualHeight();
//
// int dx = mouseLocation.x - currentLocation.x;
// int dy = mouseLocation.y - currentLocation.y;
//
// int radius = 50;
// double distance = mouseLocation.distance(currentLocation);
// double m = radius / distance;
//
// Point targetLocation = new Point();
// targetLocation.x = (int) (mouseLocation.x - dx*m) - img.getActualWidth()/2;
// targetLocation.y = (int) (mouseLocation.y - dy*m) - img.getActualHeight()/2;
//
//
// Rectangle desiredSpot = new Rectangle(targetLocation, targetSize);
// desiredSpot = getFreeSpot(desiredSpot);
// targetLocation = desiredSpot.getLocation();
//
//
// img.addMoveAnimation(currentLocation, targetLocation);
// guide.addToFront(img);
// img.startAnimation();
//
//
// Region r = new Region(mouseLocation.x-radius,mouseLocation.y-radius,radius*2,radius*2);
// SxCircle c = new SxCircle(r);
// guide.addComponent(c,1);
//
// guide.repaint();
//
//
// } catch (IOException e) {
// e.printStackTrace();
// }
class Link {
SxImage image;
SxAnchor anchor;
}
void attractTarget(SxAnchor a, Point targetLocation) {
try {
Pattern pattern = a.getPattern();
SxImage img = new SxImage(pattern.getBImage());
SxClickable clickable = new SxClickable();
clickable.setLocationRelativeToComponent(img, Layout.OVER);
guide.addToFront(clickable);
clickable.clickPoint = a.getCenter();
Link link = new Link();
link.image = img;
link.anchor = a;
links.add(link);
img.setShadowDefault();
img.setActualLocation(a.getActualLocation());
Dimension currentSize = a.getActualSize();
Dimension targetSize = new Dimension(currentSize);
targetSize.width *= 1.5;
targetSize.height *= 1.5;
img.addResizeAnimation(currentSize, targetSize);
Point currentLocation = new Point(a.getActualLocation());
targetLocation.x -= targetSize.width / 2;
targetLocation.y -= targetSize.height / 2;
img.addMoveAnimation(currentLocation, targetLocation);
guide.addToFront(img);
img.startAnimation();
guide.repaint();
} catch (Exception e) {
e.printStackTrace();
}
}
SxCircle selection;
public void allTargetAnchored() {
double theta = 0;
double dtheta = 2.0f * Math.PI / (double) targets.size();
Location mouseLocation = Env.getMouseLocation();
int x = mouseLocation.x;
int y = mouseLocation.y;
int radius = 50;
Region r = new Region(mouseLocation.x - radius, mouseLocation.y - radius, radius * 2, radius * 2);
SxCircle c = new SxCircle(r);
guide.addToFront(c);
selection = new SxCircle();
guide.addToFront(selection);
// sort targets along x-axis
Collections.sort(targets, new Comparator() {
@Override
public int compare(SxAnchor a, SxAnchor b) {
return b.getX() - a.getX();
}
});
for (SxAnchor target : targets) {
int px = (int) (x + radius * Math.cos(theta));
int py = (int) (y + radius * Math.sin(theta));
theta += dtheta;
attractTarget(target, new Point(px, py));
}
}
int anchoredCount = 0;
public void addTarget(final Pattern pattern) {
final SxAnchor a = new SxAnchor(pattern);
guide.addToFront(a);
targets.add(a);
SxFlag f = new SxFlag("Flag");
f.setLocationRelativeToComponent(a, Layout.LEFT);
guide.addToFront(f);
a.addListener(new AnchorListener() {
@Override
public void anchored() {
Debug.info("[Magnet] pattern anchored");
anchoredCount += 1;
if (anchoredCount == targets.size()) {
allTargetAnchored();
}
}
@Override
public void found(SxAnchor source) {
// TODO Auto-generated method stub
}
});
}
// ArrayList occupiedSpots = new ArrayList();
// Rectangle getFreeSpot(Rectangle desired){
//
// Rectangle freeSpot = new Rectangle(desired);
//
// for (Rectangle occupiedSpot : occupiedSpots){
//
// if (freeSpot.intersects(occupiedSpot)){
// freeSpot.x = occupiedSpot.x + occupiedSpot.width + 10;
// }
//
// }
//
// occupiedSpots.add(freeSpot);
//
// return freeSpot;
// }
TransitionListener token;
@Override
public String waitForTransition(TransitionListener token) {
this.token = token;
mouseTracker.start();
return "Next";
}
@Override
public void globalMouseMoved(int x, int y) {
// Debug.log("[SxMagnet] moved to " + x + "," + y);
Point p = new Point(x, y);
for (Link link : links) {
if (link.image.getActualBounds().contains(p)) {
//Debug.info("[SxMagnet] mouseover on a target");
if (selection != null) {
selection.setMargin(5, 5, 5, 5);
selection.setLocationRelativeToComponent(link.anchor, Layout.OVER);
guide.repaint();
}
}
}
}
@Override
public void globalMouseIdled(int x, int y) {
}
}