package com.peterhi.ui.stripbar6;
import java.util.concurrent.TimeUnit;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Listener;
import org.jdesktop.core.animation.timing.Animator;
import org.jdesktop.core.animation.timing.Animator.Builder;
import org.jdesktop.core.animation.timing.TimingTarget;
import org.jdesktop.core.animation.timing.TimingTargetAdapter;
import org.jdesktop.core.animation.timing.interpolators.AccelerationInterpolator;
import com.peterhi.ui.UI;
import com.peterhi.ui.obsolete.Bounds;
public class StripItem extends Item implements Listener {
public static final int DEFAULT = 0;
public static final int FOCUSED = 1;
public static final int PRESSED = 2;
public static final int SELECTED = 4;
public static final int DRAGGED = 8;
private final StripBar parent;
private final RectNowFuture bounds;
private final RGBNowFuture foreground;
private final RGBNowFuture background;
private int state;
private Animator boundsAnimator;
private Animator foregroundAnimator;
private Animator backgroundAnimator;
public StripItem(StripBar parent, int style) {
this(parent, style, -1);
}
public StripItem(StripBar parent, int style, int index) {
super(parent, style, index);
this.parent = parent;
this.bounds = new RectNowFuture();
this.foreground = new RGBNowFuture(UI.getRGB(SWT.COLOR_WIDGET_FOREGROUND));
this.background = new RGBNowFuture(UI.getRGB(SWT.COLOR_WIDGET_BACKGROUND));
addListener(SWT.Dispose, this);
addListener(SWT.Paint, this);
Event redir = new Event();
redir.time = (int )(System.currentTimeMillis() & 0xffffffffL);
redir.widget = parent;
redir.item = this;
redir.detail = SWT.INSERT;
redir.index = index;
parent.notifyListeners(SWT.Modify, redir);
}
public StripBar getParent() {
return parent;
}
public void handleEvent(Event event) {
if (equals(event.widget)) {
if (event.type == SWT.Dispose) {
onDispose(event);
} else if (event.type == SWT.Paint) {
onPaint(event);
}
}
}
public boolean hasImage() {
if (getImage() == null) {
return false;
} else {
return true;
}
}
public boolean hasText() {
if (getText() == null) {
return false;
} else if (getText().isEmpty()) {
return false;
} else {
return true;
}
}
public OIPoint getImageSize() {
OIPoint size = new OIPoint(0, 0);
if (hasImage()) {
Image image = getImage();
Rectangle bounds = image.getBounds();
size.setValues(bounds, false);
}
return size;
}
public OIPoint getTextSize() {
OIPoint size = new OIPoint(0, 0);
if (hasText()) {
String text = getText();
GC gc = new GC(parent);
size.setValues(gc.stringExtent(text), false);
UI.dispose(gc);
}
return size;
}
protected void onDispose(Event event) {
Event redir = new Event();
redir.time = (int )(System.currentTimeMillis() & 0xffffffffL);
redir.widget = parent;
redir.item = this;
redir.detail = SWT.DEL;
parent.notifyListeners(SWT.Modify, redir);
}
protected void onPaint(Event event) {
Event redir = new Event();
redir.time = (int )(System.currentTimeMillis() & 0xffffffffL);
redir.widget = parent;
redir.item = this;
redir.gc = event.gc;
parent.notifyListeners(SWT.PaintItem, redir);
}
int getState() {
return state;
}
void setState(int value, boolean animate) {
if (state == value) {
return;
}
state = value;
setForeground(getForeground(state), animate, null);
setBackground(getBackground(state), animate, null);
}
boolean isBoundsAnimating() {
return boundsAnimator != null;
}
boolean isForegroundAnimating() {
return foregroundAnimator != null;
}
boolean isBackgroundAnimating() {
return backgroundAnimator != null;
}
RectNowFuture getBounds() {
return bounds;
}
void setBounds(Rectangle value, boolean animate, final TimingTarget callback) {
if (value == null) {
throw new NullPointerException();
}
setBounds(value.x, value.y, value.width, value.height, animate, callback);
}
void setBounds(int x, int y, int width, int height, boolean animate, final TimingTarget callback) {
Rectangle oldFuture = bounds.getFuture();
if (oldFuture.x == x && oldFuture.y == y && oldFuture.width == width && oldFuture.height == height) {
return;
}
bounds.setFuture(x, y, width, height);
if (animate) {
if (isBoundsAnimating()) {
boundsAnimator.cancel();
boundsAnimator = null;
}
Rectangle now = bounds.getNow();
final Bounds from = Bounds.fromRectangle(now);
final Bounds to = Bounds.fromXYWidthHeight(x, y, width, height);
TimingTarget timingTarget = new TimingTargetAdapter() {
@Override
public void timingEvent(Animator source, double fraction) {
int left = (int )Math.round(from.getLeft() + (to.getLeft() - from.getLeft()) * fraction);
int right = (int )Math.round(from.getRight() + (to.getRight() - from.getRight()) * fraction);
int top = (int )Math.round(from.getTop() + (to.getTop() - from.getTop()) * fraction);
int bottom = (int )Math.round(from.getBottom() + (to.getBottom() - from.getBottom()) * fraction);
updateBounds(Bounds.fromLeftTopRightBottom(left, top, right, bottom).toRectangle());
}
@Override
public void end(Animator source) {
updateBounds(to.toRectangle());
boundsAnimator = null;
}
};
Builder builder = new Builder();
builder.addTarget(timingTarget);
builder.setInterpolator(new AccelerationInterpolator(0.0, 0.9));
builder.setDuration(150, TimeUnit.MILLISECONDS);
boundsAnimator = builder.build();
boundsAnimator.start();
} else {
updateBounds(x, y, width, height);
}
}
RGBNowFuture getForeground() {
return foreground;
}
void setForeground(RGB value, boolean animate, TimingTarget callback) {
if (value == null) {
throw new NullPointerException();
}
setForeground(value.red, value.green, value.blue, animate, callback);
}
void setForeground(int red, int green, int blue, boolean animate, final TimingTarget callback) {
RGB oldFuture = foreground.getFuture();
if (oldFuture.red == red && oldFuture.green == green && oldFuture.blue == blue) {
return;
}
foreground.setFuture(red, green, blue);
if (animate) {
if (isForegroundAnimating()) {
foregroundAnimator.cancel();
foregroundAnimator = null;
}
final RGB from = foreground.getNow();
final RGB to = new RGB(red, green, blue);
TimingTarget timingTarget = new TimingTargetAdapter() {
@Override
public void timingEvent(Animator source, double fraction) {
int red = (int )Math.round(from.red + (to.red - from.red) * fraction);
int green = (int )Math.round(from.green + (to.green - from.green) * fraction);
int blue = (int )Math.round(from.blue + (to.blue - from.blue) * fraction);
updateForeground(red, green, blue);
}
@Override
public void end(Animator source) {
updateForeground(to);
foregroundAnimator = null;
}
};
Builder builder = new Builder();
builder.addTarget(timingTarget);
builder.setInterpolator(new AccelerationInterpolator(0.0, 0.9));
builder.setDuration(160, TimeUnit.MILLISECONDS);
foregroundAnimator = builder.build();
foregroundAnimator.start();
} else {
updateForeground(red, green, blue);
}
}
RGBNowFuture getBackground() {
return background;
}
void setBackground(RGB value, boolean animate, TimingTarget callback) {
if (value == null) {
throw new NullPointerException();
}
setBackground(value.red, value.green, value.blue, animate, callback);
}
void setBackground(int red, int green, int blue, boolean animate, final TimingTarget callback) {
RGB oldFuture = background.getFuture();
if (oldFuture.red == red && oldFuture.green == green && oldFuture.blue == blue) {
return;
}
background.setFuture(red, green, blue);
if (animate) {
if (isBackgroundAnimating()) {
backgroundAnimator.cancel();
backgroundAnimator = null;
}
final RGB from = background.getNow();
final RGB to = new RGB(red, green, blue);
TimingTarget timingTarget = new TimingTargetAdapter() {
@Override
public void timingEvent(Animator source, double fraction) {
int red = (int )Math.round(from.red + (to.red - from.red) * fraction);
int green = (int )Math.round(from.green + (to.green - from.green) * fraction);
int blue = (int )Math.round(from.blue + (to.blue - from.blue) * fraction);
updateBackground(red, green, blue);
}
@Override
public void end(Animator source) {
updateBackground(to);
backgroundAnimator = null;
}
};
Builder builder = new Builder();
builder.addTarget(timingTarget);
builder.setInterpolator(new AccelerationInterpolator(0.0, 0.9));
builder.setDuration(160, TimeUnit.MILLISECONDS);
backgroundAnimator = builder.build();
backgroundAnimator.start();
} else {
updateBackground(red, green, blue);
}
}
private void updateBounds(Rectangle value) {
if (value == null) {
throw new NullPointerException();
}
updateBounds(value.x, value.y, value.width, value.height);
}
private void updateBounds(int x, int y, int width, int height) {
Rectangle oldNow = bounds.getNow();
bounds.setNow(x, y, width, height);
update(oldNow);
}
private void updateForeground(RGB value) {
if (value == null) {
throw new NullPointerException();
}
updateForeground(value.red, value.green, value.blue);
}
private void updateForeground(int red, int green, int blue) {
foreground.setNow(red, green, blue);
update(null);
}
private void updateBackground(RGB value) {
if (value == null) {
throw new NullPointerException();
}
updateBackground(value.red, value.green, value.blue);
}
private void updateBackground(int red, int green, int blue) {
background.setNow(red, green, blue);
update(null);
}
private void update(Rectangle oldBounds) {
update(oldBounds, bounds.getNow());
}
private void update(Rectangle oldBounds, Rectangle newBounds) {
if (newBounds == null) {
throw new NullPointerException();
}
if (oldBounds != null && !oldBounds.equals(newBounds)) {
parent.redraw(oldBounds.x, oldBounds.y, oldBounds.width, oldBounds.height, true);
}
parent.redraw(newBounds.x, newBounds.y, newBounds.width, newBounds.height, true);
}
private RGB getForeground(int state) {
if ((state & DRAGGED) == DRAGGED) {
return UI.getRGB(SWT.COLOR_WIDGET_LIGHT_SHADOW);
}
if ((state & PRESSED) == PRESSED) {
return UI.getRGB(SWT.COLOR_WIDGET_LIGHT_SHADOW);
}
if ((state & SELECTED) == SELECTED) {
return UI.getRGB(SWT.COLOR_LIST_BACKGROUND);
}
return UI.getRGB(SWT.COLOR_WIDGET_FOREGROUND);
}
private RGB getBackground(int state) {
if ((state & DRAGGED) == DRAGGED) {
return new RGB(65, 105, 225);
}
if ((state & PRESSED) == PRESSED) {
return new RGB(65, 105, 225);
}
if ((state & SELECTED) == SELECTED) {
return new RGB(67, 110, 238);
}
if ((state & FOCUSED) == FOCUSED) {
return new RGB(72, 118, 255);
}
return UI.getRGB(SWT.COLOR_WIDGET_BACKGROUND);
}
}