package com.peterhi.ui.stripbar4;
import java.util.concurrent.TimeUnit;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
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.runtime.RT;
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 FOCUS = 1;
public static final int PRESS = 2;
public static final int DRAG = 4;
public static final int OUTSIDE = 8;
public static final int SELECT = 16;
public static RGB getForeground(int state) {
if (RT.isFlagged(state, DRAG, false)) {
return UI.getColor(SWT.COLOR_WIDGET_FOREGROUND).getRGB();
} else if (RT.isFlagged(state, PRESS, false)) {
return UI.getColor(SWT.COLOR_WIDGET_LIGHT_SHADOW).getRGB();
} else if (RT.isFlagged(state, FOCUS, false)) {
if (RT.isFlagged(state, SELECT, false)) {
return UI.getColor(SWT.COLOR_LIST_BACKGROUND).getRGB();
} else {
return UI.getColor(SWT.COLOR_WIDGET_FOREGROUND).getRGB();
}
} else if (RT.isFlagged(state, SELECT, false)) {
return UI.getColor(SWT.COLOR_LIST_BACKGROUND).getRGB();
}
return UI.getColor(SWT.COLOR_WIDGET_FOREGROUND).getRGB();
}
public static RGB getBackground(int state) {
if (RT.isFlagged(state, DRAG, false)) {
return new RGB(65, 105, 225);
} else if (RT.isFlagged(state, PRESS, false)) {
return new RGB(65, 105, 225);
} else if (RT.isFlagged(state, SELECT, false)) {
return new RGB(67, 110, 238);
} else if (RT.isFlagged(state, FOCUS, false)) {
return new RGB(72, 118, 255);
}
return UI.getColor(SWT.COLOR_WIDGET_BACKGROUND).getRGB();
}
private final StripBar parent;
private final Rectangle bounds;
private final RGB foreground;
private final RGB background;
private int state = DEFAULT;
private Animator foregroundAnimator;
private Animator backgroundAnimator;
private Animator boundsAnimator;
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 Rectangle(0, 0, 0, 0);
this.foreground = UI.getColor(SWT.COLOR_WIDGET_FOREGROUND).getRGB();
this.background = UI.getColor(SWT.COLOR_WIDGET_BACKGROUND).getRGB();
addListener(SWT.Dispose, this);
parent.add(index, this);
}
public StripBar getParent() {
return parent;
}
@Override
public void handleEvent(Event event) {
if (equals(event.widget)) {
if (event.type == SWT.Dispose) {
onDispose(event);
}
}
}
public boolean hasText() {
if (getText() == null) {
return false;
}
if (getText().isEmpty()) {
return false;
}
return true;
}
public boolean hasImage() {
return getImage() != null;
}
public Point getTextSize() {
Point size = new Point(0, 0);
if (hasText()) {
GC gc = new GC(parent);
size = gc.stringExtent(getText());
gc.dispose();
}
return size;
}
public Point getImageSize() {
Point size = new Point(0, 0);
if (hasImage()) {
Rectangle imageBounds = getImage().getBounds();
size.x = imageBounds.width;
size.y = imageBounds.height;
}
return size;
}
int getState() {
return state;
}
void setState(int value, boolean animate, TimingTarget listener) {
if (value == state) {
return;
}
state = value;
RGB foreground = getForeground(value);
RGB background = getBackground(value);
setForeground(foreground, animate, listener);
setBackground(background, animate, listener);
}
public boolean isForegroundAnimating() {
return foregroundAnimator != null;
}
public boolean isBackgroundAnimating() {
return backgroundAnimator != null;
}
public boolean isBoundsAnimating() {
return boundsAnimator != null;
}
protected void onDispose(Event event) {
parent.remove(this);
}
Rectangle getBounds() {
return new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height);
}
void setBounds(Rectangle value, boolean animate, TimingTarget listener) {
if (value == null) {
throw new NullPointerException();
}
setBounds(value.x, value.y, value.width, value.height, animate, listener);
}
void setBounds(final int x, final int y, final int width, final int height, boolean animate, final TimingTarget listener) {
if (animate) {
if (isBoundsAnimating()) {
boundsAnimator.cancel();
boundsAnimator = null;
}
if (bounds.x == x && bounds.y == y && bounds.width == width && bounds.height == height) {
return;
}
final Bounds from = Bounds.fromRectangle(getBounds());
final Bounds to = Bounds.fromXYWidthHeight(x, y, width, height);
TimingTarget timingTarget = new TimingTargetAdapter() {
@Override
public void timingEvent(Animator source, double fraction) {
double leftDiff = (to.getLeft() - from.getLeft()) * fraction;
double rightDiff = (to.getRight() - from.getRight()) * fraction;
double topDiff = (to.getTop() - from.getTop()) * fraction;
double bottomDiff = (to.getBottom() - from.getBottom()) * fraction;
int newLeft = (int )Math.round(from.getLeft() + leftDiff);
int newRight = (int )Math.round(from.getRight() + rightDiff);
int newTop = (int )Math.round(from.getTop() + topDiff);
int newBottom = (int )Math.round(from.getBottom() + bottomDiff);
Bounds newBounds = Bounds.fromLeftTopRightBottom(newLeft, newTop, newRight, newBottom);
setBounds(newBounds.getLeft(), newBounds.getTop(), newBounds.getWidth(), newBounds.getHeight(), false, null);
if (listener != null) {
listener.timingEvent(source, fraction);
}
}
@Override
public void end(Animator source) {
setBounds(x, y, width, height, false, null);
if (listener != null) {
listener.end(source);
}
boundsAnimator = null;
}
};
Builder builder = new Builder();
builder.addTarget(timingTarget);
builder.setInterpolator(new AccelerationInterpolator(0.0, 0.9));
builder.setDuration(160, TimeUnit.MILLISECONDS);
boundsAnimator = builder.build();
boundsAnimator.start();
} else {
Rectangle oldBounds = new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height);
bounds.x = x;
bounds.y = y;
bounds.width = width;
bounds.height = height;
redraw(oldBounds);
}
}
RGB getForeground() {
return new RGB(foreground.red, foreground.green, foreground.blue);
}
void setForeground(RGB value, boolean animate, TimingTarget listener) {
if (value == null) {
throw new NullPointerException();
}
setForeground(value.red, value.green, value.blue, animate, listener);
}
void setForeground(final int red, final int green, final int blue, boolean animate, final TimingTarget listener) {
if (animate) {
if (isForegroundAnimating()) {
foregroundAnimator.cancel();
foregroundAnimator = null;
}
if (foreground.red == red && foreground.green == green && foreground.blue == blue) {
return;
}
final RGB from = new RGB(foreground.red, foreground.green, foreground.blue);
TimingTarget timingTarget = new TimingTargetAdapter() {
@Override
public void timingEvent(Animator source, double fraction) {
double redDiff = (red - from.red) * fraction;
double greenDiff = (green - from.green) * fraction;
double blueDiff = (blue - from.blue) * fraction;
int newRed = (int )Math.round(from.red + redDiff);
int newGreen = (int )Math.round(from.green + greenDiff);
int newBlue = (int )Math.round(from.blue + blueDiff);
setForeground(newRed, newGreen, newBlue, false, null);
if (listener != null) {
listener.timingEvent(source, fraction);
}
}
@Override
public void end(Animator source) {
setForeground(red, green, blue, false, null);
if (listener != null) {
listener.end(source);
}
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 {
foreground.red = red;
foreground.green = green;
foreground.blue = blue;
redraw(null);
}
}
RGB getBackground() {
return new RGB(background.red, background.green, background.blue);
}
void setBackground(RGB value, boolean animate, final TimingTarget listener) {
if (value == null) {
throw new NullPointerException();
}
setBackground(value.red, value.green, value.blue, animate, listener);
}
void setBackground(final int red, final int green, final int blue, boolean animate, final TimingTarget listener) {
if (animate) {
if (isBackgroundAnimating()) {
backgroundAnimator.cancel();
backgroundAnimator = null;
}
if (background.red == red && background.green == green && background.blue == blue) {
return;
}
final RGB from = new RGB(background.red, background.green, background.blue);
TimingTarget timingTarget = new TimingTargetAdapter() {
@Override
public void timingEvent(Animator source, double fraction) {
double redDiff = (red - from.red) * fraction;
double greenDiff = (green - from.green) * fraction;
double blueDiff = (blue - from.blue) * fraction;
int newRed = (int )Math.round(from.red + redDiff);
int newGreen = (int )Math.round(from.green + greenDiff);
int newBlue = (int )Math.round(from.blue + blueDiff);
setBackground(newRed, newGreen, newBlue, false, null);
if (listener != null) {
listener.timingEvent(source, fraction);
}
}
@Override
public void end(Animator source) {
setBackground(red, green, blue, false, null);
if (listener != null) {
listener.end(source);
}
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 {
background.red = red;
background.green = green;
background.blue = blue;
redraw(null);
}
}
private void redraw(Rectangle oldBounds) {
Rectangle newBounds = getBounds();
if (oldBounds != null) {
parent.redraw(oldBounds.x, oldBounds.y, oldBounds.width, oldBounds.height, true);
}
parent.redraw(newBounds.x, newBounds.y, newBounds.width, newBounds.height, true);
}
}