org.sikuli.guide.ClickableWindow 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-2020, sikuli.org, sikulix.com - MIT license
*/
package org.sikuli.guide;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import javax.swing.JPanel;
import org.sikuli.guide.Visual.Layout;
import org.sikuli.basics.Debug;
import org.sikuli.util.OverlayTransparentWindow;
import org.sikuli.script.Region;
import org.sikuli.basics.Settings;
import org.sikuli.natives.SysUtil;
// TODO: Automatically move mouse cursor to the click target. The current implementation
// is problematic for non-rectangular clickable widgets, for instance, a round buttone.
// Since the highlighted region is always rectangular and is larger than the area that
// is actually cliable, users may click on the edge of the region and dismiss the window
// errorneously. This needs to be fixed.
public class ClickableWindow extends OverlayTransparentWindow
implements MouseListener, Transition, GlobalMouseMotionListener {
Guide guide;
JPanel jp = null;
ArrayList clickables = new ArrayList();
private SxClickable lastClicked;
private Rectangle maxR;
Point clickLocation;
GlobalMouseMotionTracker mouseTracker;
TransitionListener token;
Cursor handCursor = new Cursor(Cursor.HAND_CURSOR);
Cursor defaultCursor = new Cursor(Cursor.DEFAULT_CURSOR);
Cursor hourglassCursor = new Cursor(Cursor.WAIT_CURSOR);
Cursor currentCursor = null;
public ClickableWindow(Guide guide) {
super(new Color(0.1f, 0f, 0f, 0.005f), null);
this.guide = guide;
jp = getJPanel();
mouseTracker = GlobalMouseMotionTracker.getInstance();
mouseTracker.addListener(this);
setVisible(false);
setFocusableWindowState(false);
addMouseListener(this);
addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
// stop the global mouse tracker's timer thread
mouseTracker.stop();
}
});
}
@Override
public void toFront() {
// if (Settings.isMac()) {
// // this call is necessary to allow clicks to go through the window (ignoreMouse == true)
// if (Guide.JavaVersion < 7) {
// SysUtil.getOSUtil().bringWindowToFront(this, true);
// } else {
// }
// }
super.toFront();
}
public void addClickable(SxClickable c) {
clickables.add(c);
SxClickable c1 = new SxClickable(null);
c1.setLocationRelativeToComponent(c, Layout.OVER);
jp.add(c1);
}
public void addClickableRegion(Region region, String name) {
SxClickable c = new SxClickable(region);
c.setName(name);
addClickable(c);
}
@Override
public void mouseClicked(MouseEvent e) {
Debug.log("[ClickableWindow] clicked on " + e.getX() + "," + e.getY());
Point p = e.getPoint();
lastClicked = null;
for (SxClickable c : clickables) {
if (c.getActualBounds().contains(p)) {
lastClicked = c;
p.x -= c.getX();
p.y -= c.getY();
c.globalMouseClicked(p);
}
}
if (lastClicked != null) {
if (token != null) {
setVisible(false);
token.transitionOccurred(this);
}
}
}
//
@Override
public void mouseEntered(MouseEvent arg0) {
}
@Override
public void mouseExited(MouseEvent arg0) {
}
@Override
public void mousePressed(MouseEvent arg0) {
}
@Override
public void mouseReleased(MouseEvent arg0) {
}
//
@Override
public String waitForTransition(TransitionListener token) {
this.token = token;
maxR = clickables.get(0).getBounds();
if (clickables.size() > 1) {
for (SxClickable c : clickables.subList(1, clickables.size())) {
maxR = maxR.union(c.getActualBounds());
}
}
setBounds(maxR);
setVisible(true);
mouseTracker.start();
return "Next";
}
@Override
public void globalMouseMoved(int x, int y) {
Point p = new Point(x, y);
SxClickable cc = null;
for (SxClickable c : clickables) {
if (c.getBounds().contains(p)) {
c.setMouseOver(true);
cc = c;
} else {
c.setMouseOver(false);
}
}
//TODO keep moving to (0,0) to nullify the dragged move bug
if (cc != null) {
setLocation(0, 0);
setSize(cc.getActualLocation().x+cc.getActualWidth(), cc.getActualLocation().y+cc.getActualHeight());
} else {
setBounds(maxR);
}
}
@Override
public void globalMouseIdled(int x, int y) {
}
public SxClickable getLastClicked() {
return lastClicked;
}
public ArrayList getClickables() {
return clickables;
}
public void clear() {
clickables.clear();
getContentPane().removeAll();
}
}