org.sikuli.guide.Visual 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
/**
*
*/
package org.sikuli.guide;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
import javax.swing.JComponent;
import org.sikuli.basics.Debug;
import org.sikuli.script.Pattern;
import org.sikuli.script.Region;
public class Visual extends JComponent
implements Cloneable {
public enum Layout {
TOP,
BOTTOM,
LEFT,
RIGHT,
FOLLOWERS,
INSIDE,
OVER,
ORIGIN,
CENTER,
AROUND
};
public boolean hasChanged = false;
public int PADDING_X = 4;
public int PADDING_Y = 4;
//
Region targetRegion = null;
Visual targetComponent = null;
Pattern targetPattern = null;
Guide currentGuide = null;
public void setGuide(Guide g) {
currentGuide = g;
}
public Region getTarget() {
if (targetRegion != null) {
return targetRegion;
}
return getRegion();
}
public Visual setScale(float scale) {
return this;
}
public Layout layout = Layout.OVER;
public Layout currentLayout = layout;
public Visual setLayout(Layout lo) {
currentLayout = layout;
layout = lo;
setLocationRelative(lo);
updateComponent();
return this;
}
public static Color defColor = Color.RED;
Color color;
public static Color defColorFront = Color.MAGENTA;
Color colorFront;
public static Color defColorBack = Color.RED;
Color colorBack;
public static Color defColorFrame = Color.WHITE;
Color colorFrame;
public static Color defColorText = Color.BLACK;
Color colorText;
/**
* set a Java Color for the component
* not all components have all color options
* @param all sets the color for all options (which have to be null in this case)
* @param front sets the foreground color
* @param back sets the background color
* @param frame sets the color of the frame
* @param text sets the color of the text
* @return the component itself for dot-chaining
*/
public Visual setColors(Color all, Color front, Color back, Color frame, Color text) {
if (all != null) {
color = all;
}
if (front != null) {
colorFront = front;
setForeground(colorFront);
}
if (back != null) {
colorBack = back;
setBackground(colorBack);
}
if (frame != null) {
colorFrame = frame;
}
if (text != null) {
colorText = text;
}
updateComponent();
return this;
}
/**
* mainly for Jython layer: colors given as (r, g, b) integer array
*
* @param front sets the foreground color
* @param back sets the background color
* @param frame sets the color of the frame
* @param text sets the color of the text
* @return the component itself for dot-chaining
*/
public Visual setColors(int[] front, int[] back, int[] frame, int[] text) {
Color cf = null;
Color cb = null;
Color cr = null;
Color ct = null;
if (front != null) {
cf = new Color(front[0], front[1], front[2]);
}
if (back != null) {
cb = new Color(back[0], back[1], back[2]);
}
if (frame != null) {
cr = new Color(frame[0], frame[1], frame[2]);
}
if (text != null) {
ct = new Color(text[0], text[1], text[2]);
}
setColors(null, cf, cb, cr, ct);
updateComponent();
return this;
}
/**
* set the front and back color
* @param color
* @return the component itself
*/
public Visual setColor(Color color) {
setColors(null, color, color, null, null);
return this;
}
/**
* set the front and back color as (r, g, b) integer array
* @return the component itself
*/
public Visual setColor(int r, int g, int b) {
setColor(new Color(r, g, b));
return this;
}
/**
* set the text color
* @param color
* @return the component itself
*/
public Visual setTextColor(Color color) {
setColors(null, null, null, null, color);
return this;
}
/**
* set text color as (r, g, b) integer array
* @return the component itself
*/
public Visual setTextColor(int r, int g, int b) {
setTextColor(new Color(r, g, b));
return this;
}
public static String getColorHex(Color col) {
String rgb = Integer.toHexString(col.getRGB());
return rgb.substring(2, rgb.length()).toUpperCase();
}
public static int defStroke = 3;
int stroke;
public Visual setStroke(int stk) {
stroke = stk;
return this;
}
public static String defFont = "";
String fontName = "";
public static int defFontSize = 0;
int fontSize = 0;
public Visual setFont(String font, int fontSize) {
if (font != null && !this.fontName.isEmpty()) {
this.fontName = font;
hasChanged = true;
}
if (fontSize > 0 && this.fontSize > 0) {
this.fontSize = fontSize;
hasChanged = true;
}
if (hasChanged) {
hasChanged = false;
updateComponent();
}
return this;
}
public Visual setFontSize(int i) {
setFont(null, i);
return this;
}
String getStyleString() {
String s = "font-size:" + fontSize + "px;color:#" + getColorHex(colorText)
+ ";background-color:#" + getColorHex(colorBack) + ";padding:3px";
if (!fontName.isEmpty()) {
s = "font:" + fontName + ";" + s;
}
return s;
}
static int defMaxWidth = 300;
int maxWidth;
public Visual setMaxWidth(int w) {
maxWidth = w;
return this;
}
String text = "";
public String getText() {
return text;
}
public Visual setText(String text) {
if (!this.text.isEmpty()) {
this.text = text;
updateComponent();
}
return this;
}
//
public Visual() {
super();
init();
}
private void init() {
cm = new ComponentMover();
setMovable(false);
setActualLocation(0, 0);
setActualSize(new Dimension(0, 0));
color = defColor;
colorFront = defColorFront;
colorBack = defColorBack;
colorFrame = defColorFrame;
colorText = defColorText;
stroke = defStroke;
fontName = defFont;
fontSize = defFontSize;
maxWidth = defMaxWidth;
}
//
private boolean autoLayoutEnabled = false;
private boolean autoResizeEnabled = false;
private boolean autoMoveEnabled = false;
private boolean autoVisibilityEnabled = false;
public void setAutoLayoutEnabled(boolean autoLayoutEnabled) {
this.autoLayoutEnabled = autoLayoutEnabled;
}
public boolean isAutoLayoutEnabled() {
return autoLayoutEnabled;
}
public void setAutoResizeEnabled(boolean autoResizeEnabled) {
this.autoResizeEnabled = autoResizeEnabled;
}
public boolean isAutoResizeEnabled() {
return autoResizeEnabled;
}
public void setAutoMoveEnabled(boolean autoMoveEnabled) {
this.autoMoveEnabled = autoMoveEnabled;
}
public boolean isAutoMoveEnabled() {
return autoMoveEnabled;
}
public void setAutoVisibilityEnabled(boolean autoVisibilityEnabled) {
this.autoVisibilityEnabled = autoVisibilityEnabled;
}
public boolean isAutoVisibilityEnabled() {
return autoVisibilityEnabled;
}
//
//
private Rectangle actualBounds = new Rectangle();
public Rectangle getActualBounds() {
return actualBounds;
}
public Region getRegion() {
return Region.create(getBounds());
}
public void setActualBounds(Rectangle actualBounds) {
this.actualBounds = (Rectangle) actualBounds.clone();
Rectangle paintBounds = (Rectangle) actualBounds.clone();
if (hasShadow()) {
paintBounds.x -= (shadowSize - shadowOffset);
paintBounds.y -= (shadowSize - shadowOffset);
paintBounds.width += (2 * shadowSize);
paintBounds.height += (2 * shadowSize);
}
super.setBounds(paintBounds);
updateAllFollowers();
}
public Point getCenter() {
Point loc = new Point(getActualLocation());
Dimension size = getActualSize();
loc.x += size.width / 2;
loc.y += size.height / 2;
return loc;
}
public Dimension getActualSize() {
return new Dimension(getActualWidth(), getActualHeight());
}
public void setActualSize(int width, int height) {
if (height == 0) {
setActualSize(new Dimension(width, getActualHeight()));
} else if (width == 0) {
setActualSize(new Dimension(getActualWidth(), height));
} else {
setActualSize(new Dimension(width, height));
}
}
public void setActualSize(Dimension actualSize) {
actualBounds.setSize(actualSize);
Dimension paintSize = (Dimension) actualSize.clone();
if (hasShadow()) {
paintSize.width += (2 * shadowSize);
paintSize.height += (2 * shadowSize);
}
super.setSize(paintSize);
updateAllFollowers();
}
public int getActualWidth() {
return getActualBounds().width;
}
public int getActualHeight() {
return getActualBounds().height;
}
public Point getActualLocation() {
return actualBounds.getLocation();
}
public void offsetLocation(int x, int y) {
setActualLocation(getActualLocation().x + x, getActualLocation().y + y);
}
public void setActualLocation(Point location) {
setActualLocation(location.x, location.y);
}
public void setActualLocation(int x, int y) {
int paintX = x;
int paintY = y;
actualBounds.setLocation(x, y);
if (hasShadow()) {
paintX -= (shadowSize - shadowOffset);
paintY -= (shadowSize - shadowOffset);
}
super.setLocation(paintX, paintY);
updateAllFollowers();
}
class Margin {
int top;
int left;
int bottom;
int right;
}
Margin margin = null;
public void setMargin(int top, int left, int bottom, int right) {
margin = new Margin();
margin.top = top;
margin.left = left;
margin.bottom = bottom;
margin.right = right;
}
int offsetx = 0;
int offsety = 0;
public void setOffset(int offsetx, int offsety) {
this.offsetx = offsetx;
this.offsety = offsety;
offsetLocation(offsetx, offsety);
}
// TODO: fix this
float zoomLevel = 1.0f;
public void setZoomLevel(float zoomLevel) {
if (true) {
return;
}
this.zoomLevel = zoomLevel;
for (Visual sklComp : getFollowers()) {
if (sklComp.autolayout != null) {
sklComp.setZoomLevel(zoomLevel);
}
}
Debug.info("[setZoomLevel] Component:" + this);
// Debug.info("Actual bounds:" + actualBounds);
Rectangle bounds = new Rectangle(getActualBounds());
bounds.x *= zoomLevel;
bounds.y *= zoomLevel;
bounds.width *= zoomLevel;
bounds.height *= zoomLevel;
//super.setBounds(bounds);
super.setBounds(bounds);
for (Visual sklComp : getFollowers()) {
if (sklComp.autolayout != null) {
Debug.info("Updaing by offset:" + sklComp.autolayout);
Debug.info("Updaing child:" + sklComp);
if (sklComp.autolayout instanceof AutoLayoutByMovement) {
((AutoLayoutByMovement) sklComp.autolayout).x = bounds.x;
((AutoLayoutByMovement) sklComp.autolayout).y = bounds.y;
} else if (sklComp.autolayout instanceof AutoLayoutByOffset) {
// ((AutoLayoutByOffset) sklComp.autolayout).offsetx *= zoomLevel;
// ((AutoLayoutByOffset) sklComp.autolayout).offsety *= zoomLevel;
// sklComp.zoomLevel = zoomLevel;
sklComp.autolayout.update();
} else {
sklComp.autolayout.update();
}
}
}
}
// this allows the component to be dragged to another location on the screen
ComponentMover cm;
public void setMovable(boolean movable) {
if (movable) {
cm.registerComponent(this);
} else {
cm.deregisterComponent(this);
}
}
float opacity = 1.0f;
//
//
public void setOpacity(float opacity) {
if (opacity > 0) {
setVisible(true);
} else {
setVisible(false);
}
this.opacity = opacity;
for (Visual sklComp : getFollowers()) {
sklComp.setOpacity(opacity);
}
// if (shadowRenderer != null){
// shadowRenderer.createShadowImage();
// }
Rectangle r = getBounds();
if (getTopLevelAncestor() != null) //getTopLevelAncestor().repaint(r.x,r.y,r.width,r.height);
// for some reason the whole thing needs to be repainted otherwise the
// shadow of other compoments looks weird
{
getTopLevelAncestor().repaint();
}
// public void changeOpacityTo(float targetOpacity){
// OpacityAnimator anim = new OpacityAnimator(this, opacity,targetOpacity);
// anim.start();
// }
}
public void updateComponent() {
}
public void paintPlain(Graphics g) {
super.paint(g);
}
@Override
public void paint(Graphics g) {
BufferedImage image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = image.createGraphics();
if (shadowRenderer != null) {
shadowRenderer.paintComponent(g2);
g2.translate((shadowSize - shadowOffset), (shadowSize - shadowOffset));
}
super.paint(g2);
Graphics2D g2d = (Graphics2D) g;
((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity));
g2d.drawImage(image, 0, 0, null, null);
}
//
//
ShadowRenderer shadowRenderer;
private int defShadowSize = 10;
int shadowSize = 0;
private int defShadowOffset = 2;
int shadowOffset = 0;
public void setShadowDefault() {
setShadow(defShadowSize, defShadowOffset);
}
public void setShadow(int shadowSize, int shadowOffset) {
this.shadowSize = shadowSize;
this.shadowOffset = shadowOffset;
shadowRenderer = new ShadowRenderer(this, shadowSize);
super.setSize(getActualWidth() + 2 * shadowSize, getActualHeight() + 2 * shadowSize);
Point p = getActualLocation();
p.x = p.x - shadowSize + shadowOffset;
p.y = p.y - shadowSize + shadowOffset;
super.setLocation(p.x, p.y);
}
boolean hasShadow() {
return shadowRenderer != null;
}
//
//
boolean animationRunning = false;
class AnimationSequence {
Queue queue = new LinkedBlockingQueue();
private void startNextAnimation() {
if (queue.peek() != null) {
NewAnimator anim = queue.remove();
anim.start();
anim.setListener(new AnimationListener() {
@Override
public void animationCompleted() {
startNextAnimation();
}
});
}
}
public void add(NewAnimator animator) {
queue.add(animator);
}
public void start() {
startNextAnimation();
}
}
AnimationSequence animationSequence = new AnimationSequence();
AnimationFactory getAnimationFactory() {
return new AnimationFactory();
}
public void addAnimation(NewAnimator anim) {
animationSequence.add(anim);
}
public void addMoveAnimation(Point source, Point destination) {
animationSequence.add(AnimationFactory.createMoveAnimation(this, source, destination));
}
public void addResizeAnimation(Dimension currentSize, Dimension targetSize) {
animationSequence.add(AnimationFactory.createResizeAnimation(this, currentSize, targetSize));
}
public void addCircleAnimation(Point origin, float radius) {
animationSequence.add(AnimationFactory.createCircleAnimation(this, origin, radius));
}
public void addFadeinAnimation() {
if (opacity < 1f) {
animationSequence.add(AnimationFactory.createOpacityAnimation(this, opacity, 1f));
}
}
public void addFadeoutAnimation() {
if (opacity > 0f) {
animationSequence.add(AnimationFactory.createOpacityAnimation(this, opacity, 0f));
}
}
public void addSlideAnimation(Point destination, Layout side) {
Point p0 = new Point(destination);
Point p1 = new Point(destination);
if (side == Layout.RIGHT) {
p0.x += 20;
} else if (side == Layout.BOTTOM) {
p0.y += 20;
} else if (side == Layout.TOP) {
p0.y -= 20;
} else if (side == Layout.LEFT) {
p0.x -= 20;
}
setActualLocation(p0);
addMoveAnimation(p0, p1);
}
public void startAnimation() {
animationSequence.start();
}
public void stopAnimation() {
if (emphasis_anim != null) {
emphasis_anim.stop();
}
if (entrance_anim != null) {
entrance_anim.stop();
}
}
public Animator createSlidingAnimator(int offset_x, int offset_y) {
Point dest = getActualLocation();
Point src = new Point(dest.x + offset_x, dest.y + offset_y);
return new MoveAnimator(this, src, dest);
}
public Animator createMoveAnimator(int dest_x, int dest_y) {
Point src = getActualLocation();
Point dest = new Point(dest_x, dest_y);
return new MoveAnimator(this, src, dest);
}
public void resizeTo(Dimension targetSize) {
//ResizeAnimator anim = new ResizeAnimator(this, getActualSize(),targetSize);
//anim.start();
}
public void moveTo(Point targetLocation) {
NewAnimator anim = AnimationFactory.createCenteredMoveAnimation(this, getActualLocation(), targetLocation);
anim.start();
}
public void moveTo(Point targetLocation, AnimationListener listener) {
NewAnimator anim = AnimationFactory.createCenteredMoveAnimation(this, getActualLocation(), targetLocation);
anim.setListener(listener);
anim.start();
}
public void popin() {
Dimension targetSize = new Dimension(getActualSize());
targetSize.width /= 1.2;
targetSize.height /= 1.2;
NewAnimator anim = AnimationFactory.createCenteredResizeToAnimation(this, targetSize);
anim.start();
}
public void popout() {
setShadowDefault();
Dimension targetSize = new Dimension(getActualSize());
targetSize.width *= 1.2;
targetSize.height *= 1.2;
NewAnimator anim = AnimationFactory.createCenteredResizeToAnimation(this, targetSize);
anim.start();
}
Animator entrance_anim;
Animator emphasis_anim;
public void setEntranceAnimation(Animator anim) {
if (entrance_anim != null) {
entrance_anim.stop();
} else {
entrance_anim = anim;
}
}
public void setEmphasisAnimation(Animator anim) {
if (emphasis_anim != null) {
emphasis_anim.stop();
}
if (entrance_anim != null) {
entrance_anim.stop();
}
emphasis_anim = anim;
}
AnimationListener animationListener;
public void addAnimationListener(AnimationListener listener) {
animationListener = listener;
}
public void animationCompleted() {
if (animationListener != null) {
animationListener.animationCompleted();
}
}
//
//
public Visual left() {
left(0);
return this;
}
public Visual left(int x) {
setLayout(Layout.LEFT);
if (x != 0) {
setOffset(-x, 0);
}
return this;
}
public Visual right() {
return right(0);
}
public Visual right(int x) {
setLayout(Layout.RIGHT);
if (x != 0) {
setOffset(x, 0);
}
return this;
}
public Visual above() {
return above(0);
}
public Visual above(int y) {
setLayout(Layout.TOP);
if (y != 0) {
setOffset(0, -y);
}
return this;
}
public Visual below() {
return below(0);
}
public Visual below(int y) {
setLayout(Layout.BOTTOM);
if (y != 0) {
setOffset(0, y);
}
return this;
}
//
//
AutoLayout autolayout = null;
class AutoLayout implements ComponentListener {
private Visual targetComponent;
AutoLayout(Visual targetComponent) {
this.setTargetComponent(targetComponent);
//targetComponent.addComponentListener(this);
}
public void setTargetComponent(Visual targetComponent) {
this.targetComponent = targetComponent;
}
public Visual getTargetComponent() {
return targetComponent;
}
void update() {
//Debug.info("Update caused by leader:" + this);
// TODO calculate necesary region to udpate
// if (getParent()!=null){
//
// if (getParent().getParent()!=null){
// getParent().getParent().repaint();
// }else{
// getParent().repaint();
// }
// }
}
void stop() {
// targetComponent.removeComponentListener(this);
}
@Override
public void componentHidden(ComponentEvent e) {
// if (isAutoVisibilityEnabled()){
// setVisible(false);
// update();
// }
}
@Override
public void componentMoved(ComponentEvent e) {
// if (isAutoMoveEnabled())
// update();
}
@Override
public void componentResized(ComponentEvent e) {
// if (isAutoResizeEnabled())
// update();
}
@Override
public void componentShown(ComponentEvent e) {
// if (isAutoVisibilityEnabled()){
// setVisible(true);
// update();
// }
}
}
class AutoLayoutBySide extends AutoLayout {
Layout side;
AutoLayoutBySide(Visual targetComponent, Layout side) {
super(targetComponent);
this.side = side;
}
@Override
void update() {
if (side == Layout.FOLLOWERS) {
// set to the total bounds of the other followers
// first set its bounds to be equal to the targets, so that
// its current bounds won't have effect on the calculation
// of the total bounds
setBounds(getTargetComponent().getBounds());
// then this call will gives us the total bounds of the
// rest of the followers
Rectangle totalBounds = getTargetComponent().getFollowerBounds();
totalBounds.grow(5, 5);
setBounds(totalBounds);
} else {
setLocationRelativeToRegion(getTargetComponent().getRegion(), side);
}
super.update();
}
}
class AutoLayoutByMovement extends AutoLayout {
// previous known location of the target this component follows
int x;
int y;
Point targetLocation;
AutoLayoutByMovement(Visual targetComponent) {
super(targetComponent);
targetLocation = new Point(targetComponent.getActualLocation());
this.x = targetComponent.getX();
this.y = targetComponent.getY();
}
@Override
public void update() {
//Debug.info("auto moved by leader");
Point newTargetLocation = getTargetComponent().getActualLocation();
int dx = newTargetLocation.x - targetLocation.x;
int dy = newTargetLocation.y - targetLocation.y;
targetLocation = newTargetLocation;
Point actualLocation = getActualLocation();
actualLocation.x += dx;
actualLocation.y += dy;
setActualLocation(actualLocation.x, actualLocation.y);
}
}
class AutoLayoutByOffset extends AutoLayout {
int offsetx;
int offsety;
AutoLayoutByOffset(Visual targetComponent, int offsetx, int offsety) {
super(targetComponent);
this.offsetx = offsetx;
this.offsety = offsety;
}
@Override
void update() {
setOffset(offsetx, offsety);
Region region = new Region(leader.getBounds());
setLocationRelativeToRegion(region, Layout.ORIGIN);
super.update();
}
}
class AutoLayoutByRatio extends AutoLayout {
float x, y;
AutoLayoutByRatio(Visual targetComponent, float x, float y) {
super(targetComponent);
this.x = x;
this.y = y;
}
@Override
void update() {
Region region = new Region(getTargetComponent().getBounds());
setHorizontalAlignmentWithRegion(region, x);
setVerticalAlignmentWithRegion(region, y);
super.update();
}
}
//
//
public Visual setTarget(RCPS target) {
if (target instanceof Region) {
targetRegion = (Region) target;
} else if (target instanceof Visual) {
targetComponent = (Visual) target;
} else if (target instanceof Pattern) {
targetPattern = (Pattern) target;
} else if (target instanceof String) {
targetPattern = new Pattern((String) target);
}
if (targetPattern != null) {
targetComponent = new SxAnchor(targetPattern);
currentGuide.addToFront(targetComponent);
setLayout(layout);
}
updateComponent();
return this;
}
public Visual setLocationRelative(Layout side) {
if (targetRegion != null) {
setLocationRelativeToRegion(targetRegion, side);
} else if (targetComponent != null) {
setLocationRelativeToComponent(targetComponent, side);
}
return this;
}
public void setLocationRelativeToComponent(Visual comp, Layout side) {
if (autolayout != null) {
autolayout.stop();
}
comp.addFollower(this);
autolayout = new AutoLayoutBySide(comp, side);
autolayout.update();
}
public void setLocationRelativeToComponent(Visual comp, int offsetx, int offsety) {
if (autolayout != null) {
autolayout.stop();
}
comp.addFollower(this);
autolayout = new AutoLayoutByOffset(comp, offsetx, offsety);
autolayout.update();
}
public void setLocationRelativeToComponent(Visual comp, float relativeX, float relativeY) {
if (autolayout != null) {
autolayout.stop();
}
autolayout = new AutoLayoutByRatio(comp, relativeX, relativeY);
autolayout.update();
}
public void setLocationRelativeToComponent(Visual leader) {
if (autolayout != null) {
autolayout.stop();
}
leader.addFollower(this);
autolayout = new AutoLayoutByMovement(leader);
autolayout.update();
}
public void setLocationRelativeToPoint(Point point, Layout side) {
Rectangle bounds = getActualBounds();
// TODO implement other positioning parameters
if (side == Layout.CENTER) {
setActualLocation(point.x - bounds.width / 2, point.y - bounds.height / 2);
}
}
public Visual setLocationRelativeToRegion(Region region, Layout side) {
if (margin != null) {
Region rectWithSpacing = new Region(region);
rectWithSpacing.x -= margin.left;
rectWithSpacing.y -= margin.top;
rectWithSpacing.w += (margin.left + margin.right);
rectWithSpacing.h += (margin.top + margin.bottom);
region = rectWithSpacing;
}
region.x += offsetx;
region.y += offsety;
targetRegion = region;
layout = side;
int height = getActualHeight();
int width = getActualWidth();
if (side == Layout.TOP) {
setActualLocation(region.x + region.w / 2 - width / 2, region.y - height);
} else if (side == Layout.BOTTOM) {
setActualLocation(region.x + region.w / 2 - width / 2, region.y + region.h);
} else if (side == Layout.LEFT) {
setActualLocation(region.x - width, region.y + region.h / 2 - height / 2);
} else if (side == Layout.RIGHT) {
setActualLocation(region.x + region.w, region.y + region.h / 2 - height / 2);
} else if (side == Layout.INSIDE) {
setActualLocation(region.x + region.w / 2 - width / 2, region.y + region.h / 2 - height / 2);
} else if (side == Layout.OVER) {
setActualBounds(region.getRect());
} else if (side == Layout.ORIGIN) {
setActualLocation(region.x, region.y);
}
return this;
}
public void setHorizontalAlignmentWithRegion(Region region, float f) {
int x0 = region.x;
int x1 = region.x + region.w - getActualWidth();
int x = (int) (x0 + (x1 - x0) * f);
setActualLocation(x, getActualLocation().y);
}
public void setVerticalAlignmentWithRegion(Region region, float f) {
int y0 = region.y;
int y1 = region.y + region.h - getActualHeight();
int y = (int) (y0 + (y1 - y0) * f);
setActualLocation(getActualLocation().x, y);
}
//
//
private ArrayList followers = new ArrayList();
Visual leader;
public void removeFromLeader() {
if (leader != null) {
leader.removeFollower(this);
}
leader = null;
}
public void addFollower(Visual sklComp) {
// force the follower to have the same visibility
sklComp.setVisible(isVisible());
sklComp.setOpacity(opacity);
if (followers.indexOf(sklComp) < 0) {
// if this component is not already a follower
// add it to the list of follower
followers.add(sklComp);
// remove its previous leader
sklComp.removeFromLeader();
// set its new leader to self
sklComp.leader = this;
}
}
private void updateAllFollowers() {
for (Visual sklComp : getFollowers()) {
if (sklComp.autolayout != null) {
sklComp.autolayout.update();
}
}
}
@Override
public void setVisible(boolean visible) {
for (Visual follower : getFollowers()) {
follower.setVisible(visible);
}
super.setVisible(visible);
}
//
// @Override
// public void setLocation(Point location){
// setLocation(location.x, location.y);
// }
// @Override
// public void setLocation(int x, int y){
//
//// if (shadowRenderer != null){
//// x -= 8;
//// y -= 8;
//// }
//
// getActualBounds().x = (int) (x/zoomLevel);
// getActualBounds().y = (int) (y/zoomLevel);
//
// super.setLocation(x,y);
// updateAllFollowers();
// }
//
// @Override
// public void setBounds(int x, int y, int w, int h){
//
// Rectangle bounds = new Rectangle(x,y,w,h);
//
// actualBounds = new Rectangle(bounds);
// actualBounds.x /= zoomLevel;
// actualBounds.y /= zoomLevel;
// actualBounds.width /= zoomLevel;
// actualBounds.height /= zoomLevel;
//
// for (Visual sklComp : getFollowers()){
// if (sklComp.autolayout != null){
// sklComp.autolayout.update();
// }
// }
// super.setBounds(x,y,w,h);
// }
// @Override
// public void setBounds(Rectangle bounds){
//
// setActualBounds(new Rectangle(bounds));
// getActualBounds().x /= zoomLevel;
// getActualBounds().y /= zoomLevel;
// getActualBounds().width /= zoomLevel;
// getActualBounds().height /= zoomLevel;
//
// super.setBounds(bounds);
// updateAllFollowers();
// }
// @Override
// public void setSize(int width, int height){
// getActualBounds().width = (int) (width/zoomLevel);
// getActualBounds().height = (int) (height/zoomLevel);
//
// if (hasShadow()){
// width += 20;
// height += 20;
// }
//
// super.setSize(width, height);
//// updateAllFollowers();
// }
//
// @Override
// public void setSize(Dimension size){
//// getActualBounds().width = (int) (size.width/zoomLevel);
//// getActualBounds().height = (int) (size.height/zoomLevel);
//
//// if (hasShadow()){
//// size.width += 20;
//// size.height += 20;
//// }
//
// super.setSize(size);
//// updateAllFollowers();
// }
//
public ArrayList getFollowers() {
return followers;
}
public Visual getLeader() {
return leader;
}
public void removeFollower(Visual comp) {
followers.remove(comp);
}
public Rectangle getFollowerBounds() {
// find the total bounds of all the components
Rectangle bounds = new Rectangle(getBounds());
for (Visual sklComp : getFollowers()) {
bounds.add(sklComp.getBounds());
}
return bounds;
}
//
public void removeFrom(Container container) {
for (Visual follower : getFollowers()) {
follower.removeFrom(container);
}
container.remove(this);
}
@Override
public String toString() {
return "" + getClass() + " " + "[actualBounds=" + getActualBounds() + "]";
}
@Override
public Object clone() {
Visual clone;
try {
clone = (Visual) super.clone();
// do not clone references to other components
clone.followers = new ArrayList();
clone.removeFromLeader();
clone.actualBounds = new Rectangle(actualBounds);
clone.autolayout = null;
//clone.connectors = new ArrayList();
return clone;
} catch (CloneNotSupportedException e) {
throw new InternalError(e.toString());
}
}
}