blob: cf505015c1982bf70f44203508f095a5770a1a2d [file] [log] [blame]
package org.eclipse.swt.widgets;
/*
* Copyright (c) 2000, 2002 IBM Corp. All rights reserved.
* This file is made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*/
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
public class Tracker extends Widget {
Control parent;
Display display;
boolean tracking, stippled;
Rectangle [] rectangles, proportions;
int cursorOrientation = SWT.NONE;
public Tracker (Composite parent, int style) {
super (parent, checkStyle (style));
this.parent = parent;
display = parent.getDisplay ();
}
public Tracker (Display display, int style) {
if (display == null) display = Display.getCurrent ();
if (display == null) display = Display.getDefault ();
if (!display.isValidThread ()) {
error (SWT.ERROR_THREAD_INVALID_ACCESS);
}
this.style = checkStyle (style);
this.display = display;
}
public void addControlListener (ControlListener listener) {
checkWidget ();
if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
TypedListener typedListener = new TypedListener (listener);
addListener (SWT.Move,typedListener);
}
Point adjustMoveCursor (int xDisplay, int xWindow) {
return new Point (0, 0);
}
Point adjustResizeCursor (int xDisplay, int xWindow) {
return new Point (0, 0);
}
static int checkStyle (int style) {
if ((style & (SWT.LEFT | SWT.RIGHT | SWT.UP | SWT.DOWN)) == 0) {
style |= SWT.LEFT | SWT.RIGHT | SWT.UP | SWT.DOWN;
}
return style;
}
public void close () {
checkWidget ();
tracking = false;
}
Rectangle computeBounds () {
int xMin = rectangles [0].x;
int yMin = rectangles [0].y;
int xMax = rectangles [0].x + rectangles [0].width;
int yMax = rectangles [0].y + rectangles [0].height;
for (int i = 1; i < rectangles.length; i++) {
if (rectangles [i].x < xMin) xMin = rectangles [i].x;
if (rectangles [i].y < yMin) yMin = rectangles [i].y;
int rectRight = rectangles [i].x + rectangles [i].width;
if (rectRight > xMax) xMax = rectRight;
int rectBottom = rectangles [i].y + rectangles [i].height;
if (rectBottom > yMax) yMax = rectBottom;
}
return new Rectangle (xMin, yMin, xMax - xMin, yMax - yMin);
}
Rectangle [] computeProportions (Rectangle [] rects) {
Rectangle [] result = new Rectangle [rects.length];
Rectangle bounds = computeBounds ();
for (int i = 0; i < rects.length; i++) {
result[i] = new Rectangle (
(rects[i].x - bounds.x) * 100 / bounds.width,
(rects[i].y - bounds.y) * 100 / bounds.height,
rects[i].width * 100 / bounds.width,
rects[i].height * 100 / bounds.height);
}
return result;
}
void drawRectangles () {
if (parent != null) {
if (parent.isDisposed ()) return;
parent.getShell ().update ();
} else {
display.update ();
}
}
public Display getDisplay () {
return display;
}
public Rectangle [] getRectangles () {
checkWidget ();
return rectangles;
}
public boolean getStippled () {
checkWidget ();
return stippled;
}
void moveRectangles (int xChange, int yChange) {
if (xChange < 0 && ((style & SWT.LEFT) == 0)) return;
if (xChange > 0 && ((style & SWT.RIGHT) == 0)) return;
if (yChange < 0 && ((style & SWT.UP) == 0)) return;
if (yChange > 0 && ((style & SWT.DOWN) == 0)) return;
for (int i = 0; i < rectangles.length; i++) {
rectangles [i].x += xChange;
rectangles [i].y += yChange;
}
}
public boolean open () {
checkWidget ();
if (rectangles == null) return false;
return false;
}
public void removeControlListener (ControlListener listener) {
checkWidget ();
if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
if (eventTable == null) return;
eventTable.unhook (SWT.Move, listener);
}
void resizeRectangles (int xChange, int yChange) {
/*
* If the cursor orientation has not been set in the orientation of
* this change then try to set it here.
*/
if (xChange < 0 && ((style & SWT.LEFT) != 0) && ((cursorOrientation & SWT.RIGHT) == 0)) {
cursorOrientation |= SWT.LEFT;
} else if (xChange > 0 && ((style & SWT.RIGHT) != 0) && ((cursorOrientation & SWT.LEFT) == 0)) {
cursorOrientation |= SWT.RIGHT;
} else if (yChange < 0 && ((style & SWT.UP) != 0) && ((cursorOrientation & SWT.DOWN) == 0)) {
cursorOrientation |= SWT.UP;
} else if (yChange > 0 && ((style & SWT.DOWN) != 0) && ((cursorOrientation & SWT.UP) == 0)) {
cursorOrientation |= SWT.DOWN;
}
Rectangle bounds = computeBounds ();
if ((cursorOrientation & SWT.LEFT) != 0) {
bounds.x += xChange;
bounds.width -= xChange;
} else if ((cursorOrientation & SWT.RIGHT) != 0) {
bounds.width += xChange;
}
if ((cursorOrientation & SWT.UP) != 0) {
bounds.y += yChange;
bounds.height -= yChange;
} else if ((cursorOrientation & SWT.DOWN) != 0) {
bounds.height += yChange;
}
/*
* The following are conditions under which the resize should not be applied
*/
if (bounds.width < 0 || bounds.height < 0) return;
Rectangle [] newRects = new Rectangle [rectangles.length];
for (int i = 0; i < rectangles.length; i++) {
Rectangle proportion = proportions[i];
newRects[i] = new Rectangle (
proportion.x * bounds.width / 100 + bounds.x,
proportion.y * bounds.height / 100 + bounds.y,
proportion.width * bounds.width / 100,
proportion.height * bounds.height / 100);
}
rectangles = newRects;
}
public void setCursor (Cursor value) {
checkWidget ();
}
public void setRectangles (Rectangle [] rectangles) {
checkWidget ();
this.rectangles = rectangles;
proportions = computeProportions (rectangles);
}
public void setStippled (boolean stippled) {
checkWidget ();
this.stippled = stippled;
}
}