boolean constrainViewport = alignment.isConstrainViewport();
String p1 = alignment.getAlign() == null ? "tl" : alignment.getAlign().value();
String p2 = alignment.getTargetAlign() == null ? "bl" : alignment.getTargetAlign().value();
// Subtract the aligned el's internal xy from the target's offset xy
// plus custom offset to get the aligned el's new offset xy
Point a1 = getAnchorXY(alignment.getAlign(), true);
Point a2 = el.getAnchorXY(alignment.getTargetAlign(), false);
int x = a2.getX() - a1.getX() + ox;
int y = a2.getY() - a1.getY() + oy;
if (constrainViewport) {
// constrain the aligned el to viewport if necessary
int w = getOffsetWidth();
int h = getOffsetHeight();
Region r = el.getRegion();
// 5px of margin for ie
int dw = XDOM.getViewWidth(false) - 10;
int dh = XDOM.getViewHeight(false) - 10;
// If we are at a viewport boundary and the aligned el is anchored on a
// target border that is
// perpendicular to the vp border, allow the aligned el to slide on that
// border,
// otherwise swap the aligned el to the opposite border of the target.
char p1y = p1.charAt(0), p1x = p1.charAt(p1.length() - 1);
char p2y = p2.charAt(0), p2x = p2.charAt(p2.length() - 1);
boolean swapY = ((p1y == 't' && p2y == 'b') || (p1y == 'b' && p2y == 't'));
boolean swapX = ((p1x == 'r' && p2x == 'l') || (p1x == 'l' && p2x == 'r'));
// EXTGWT-1730 only applying 5 when there is scrolling. 5 may be able to
// be removed
// but not sure why this was added in first place. it exists in 2.0
int scrollX = XDOM.getBodyScrollLeft();
if (scrollX > 0) {
scrollX += 5;
}
int scrollY = XDOM.getBodyScrollTop();
if (scrollY > 0) {
scrollY += 5;
}
if ((x + w) > dw + scrollX) {
x = swapX ? r.getLeft() - w : dw + scrollX - w;
}
if (x < scrollX) {
x = swapX ? r.getRight() : scrollX;
}
if ((y + h) > (dh + scrollY)) {
y = swapY ? r.getTop() - h : dh + scrollY - h;
}
if (y < scrollY) {
y = swapY ? r.getBottom() : scrollY;
}
}
return new Point(x, y);
}