package com.peterhi.ui.stripbar3;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
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.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.jdesktop.core.animation.timing.Animator;
import org.jdesktop.core.animation.timing.Interpolator;
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.UIImageResource;
import com.peterhi.ui.obsolete.Bounds;
public final class StripBar extends Canvas implements Listener {
public static final class StripItem {
private final String id;
private String text;
private Image image;
public StripItem(String id) {
this.id = id;
}
public String getId() {
return id;
}
public String getText() {
return text;
}
public void setText(String value) {
this.text = value;
}
public Image getImage() {
return image;
}
public void setImage(Image value) {
this.image = value;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
StripItem other = (StripItem) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
@Override
public String toString() {
return MessageFormat.format("{0} ({1})", id, text);
}
}
static final class StripItemController {
private final StripItem item;
private RGB foreground;
private RGB background;
private Animator backgroundAnimator;
private Animator offsetAnimator;
private int offset;
private Rectangle oldBounds;
public StripItemController(StripItem item) {
this.item = item;
}
public StripItem getItem() {
return item;
}
public boolean hasForeground() {
return foreground != null;
}
public RGB getForeground() {
return foreground;
}
public void setForeground(RGB value) {
foreground = value;
}
public boolean hasBackground() {
return background != null;
}
public RGB getBackground() {
return background;
}
public void setBackground(RGB value) {
background = value;
}
public boolean hasBackgroundAnimator() {
return backgroundAnimator != null;
}
public Animator getBackgroundAnimator() {
return backgroundAnimator;
}
public void setBackgroundAnimator(Animator value) {
backgroundAnimator = value;
}
public boolean hasOffsetAnimator() {
return offsetAnimator != null;
}
public Animator getOffsetAnimator() {
return offsetAnimator;
}
public void setOffsetAnimator(Animator value) {
offsetAnimator = value;
}
public int getOffset() {
return offset;
}
public void setOffset(int value) {
offset = value;
}
public Rectangle getOldBounds() {
return oldBounds;
}
public void setOldBounds(Rectangle value) {
oldBounds = value;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((item == null) ? 0 : item.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
StripItemController other = (StripItemController) obj;
if (item == null) {
if (other.item != null)
return false;
} else if (!item.equals(other.item))
return false;
return true;
}
}
public static final int SPACE = 5;
public static final int NONE = 0;
public static final int HOVERED = 1;
public static final int PRESSED = 2;
public static final int SELECTED = 3;
public static final RGB[] FOREGROUNDS;
public static final RGB[] BACKGROUNDS;
static {
Display display = Display.getDefault();
FOREGROUNDS = new RGB[4];
BACKGROUNDS = new RGB[4];
Color color = display.getSystemColor(SWT.COLOR_WIDGET_FOREGROUND);
RGB rgb = color.getRGB();
FOREGROUNDS[0] = rgb;
FOREGROUNDS[1] = rgb;
FOREGROUNDS[2] = rgb;
color = display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
rgb = color.getRGB();
FOREGROUNDS[3] = rgb;
color = display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
rgb = color.getRGB();
BACKGROUNDS[0] = rgb;
rgb = new RGB(72, 118, 255);
BACKGROUNDS[1] = rgb;
rgb = new RGB(65, 105, 225);
BACKGROUNDS[2] = rgb;
rgb = new RGB(67, 110, 238);
BACKGROUNDS[3] = rgb;
}
private final List<StripItemController> controllers = new ArrayList<StripItemController>();
private StripItemController hovered;
private StripItemController pressed;
private StripItemController dragged;
private final Set<StripItemController> selected = new HashSet<StripItemController>();
private Point mouseDownLocation;
private Point mouseDownOffset;
private Point mouseMoveLocation;
private List<StripItemController> temp;
public StripBar(Composite parent, int style) {
super(parent, style);
addListener(SWT.Paint, this);
addListener(SWT.MouseEnter, this);
addListener(SWT.MouseExit, this);
addListener(SWT.MouseDown, this);
addListener(SWT.MouseMove, this);
addListener(SWT.MouseUp, this);
}
@Override
public void handleEvent(Event event) {
if (equals(event.widget)) {
if (event.type == SWT.Paint) {
onPaint(event);
} else if (event.type == SWT.MouseEnter) {
onMouseEnter(event);
} else if (event.type == SWT.MouseExit) {
onMouseExit(event);
} else if (event.type == SWT.MouseDown) {
onMouseDown(event);
} else if (event.type == SWT.MouseMove) {
onMouseMove(event);
} else if (event.type == SWT.MouseUp) {
onMouseUp(event);
}
}
}
@Override
public Point computeSize(int wHint, int hHint, boolean changed) {
Point size = new Point(0, 0);
for (StripItemController controller : controllers) {
Rectangle bounds = getItemBounds(controller.getItem());
size.x += bounds.width;
size.y = Math.max(size.y, bounds.height);
}
size.x += SPACE * (getItemCount() - 1);
size.y += SPACE * 2;
Rectangle boundsWithTrim = computeTrim(0, 0, size.x, size.y);
size.x = boundsWithTrim.width;
size.y = boundsWithTrim.height;
return size;
}
public boolean isMultiSelection() {
int style = getStyle();
boolean multi = (style & SWT.MULTI) == SWT.MULTI;
return multi;
}
public int getItemCount() {
return controllers.size();
}
public boolean addItem(StripItem item) {
return insertItem(item, getItemCount());
}
public boolean insertItem(StripItem item, int index) {
if (item == null) {
throw new NullPointerException();
}
if (containsItem(item)) {
return false;
}
controllers.add(index, new StripItemController(item));
return true;
}
public boolean removeItem(StripItem item) {
return removeItem(indexOfItem(item)) != null;
}
public StripItem removeItem(int index) {
StripItemController controller = controllers.remove(index);
if (controller == null) {
return null;
}
if (controller.equals(hovered)) {
hovered = null;
}
if (controller.equals(pressed)) {
pressed = null;
}
if (selected.contains(controller)) {
selected.remove(controller);
}
return controller.getItem();
}
public StripItem getItem(int index) {
StripItemController controller = controllers.get(index);
if (controller == null) {
return null;
}
return controller.getItem();
}
public StripItem getItem(int x, int y) {
StripItemController controller = getController(x, y);
if (controller == null) {
return null;
}
return controller.getItem();
}
public int indexOfItem(StripItem item) {
if (item == null) {
throw new NullPointerException();
}
for (int i = 0; i < controllers.size(); i++) {
StripItemController controller = controllers.get(i);
if (controller.getItem().equals(item)) {
return i;
}
}
return -1;
}
public boolean containsItem(StripItem item) {
return indexOfItem(item) >= 0;
}
public StripItem[] getItems() {
List<StripItem> items = new ArrayList<StripItem>();
for (StripItemController controller : controllers) {
items.add(controller.getItem());
}
return items.toArray(new StripItem[items.size()]);
}
public boolean hasItemText(StripItem item) {
checkItem(item);
String text = item.getText();
return text != null && !text.isEmpty();
}
public boolean hasItemImage(StripItem item) {
checkItem(item);
Image image = item.getImage();
return image != null;
}
public Point getItemTextSize(StripItem item) {
checkItem(item);
Point size = new Point(0, 0);
if (hasItemText(item)) {
String text = item.getText();
GC gc = new GC(this);
size = gc.stringExtent(text);
gc.dispose();
}
return size;
}
public Point getItemImageSize(StripItem item) {
checkItem(item);
Point size = new Point(0, 0);
if (hasItemImage(item)) {
Image image = item.getImage();
Rectangle bounds = image.getBounds();
size.x = bounds.width;
size.y = bounds.height;
}
return size;
}
public Image getItemCloseButtonImage() {
return UIImageResource.T.closeNormal10();
}
public Point getItemCloseButtonSize() {
Point size = new Point(0, 0);
Image image = getItemCloseButtonImage();
Rectangle bounds = image.getBounds();
size.x = bounds.width;
size.y = bounds.height;
return size;
}
public Rectangle getItemBounds(StripItem item) {
checkItem(item);
return getItemBounds(controllers, item);
}
private Rectangle getItemBounds(List<StripItemController> controllers, StripItem item) {
Rectangle bounds = new Rectangle(SPACE, SPACE, 0, 0);
for (StripItemController controller : controllers) {
if (hasItemImage(controller.getItem())) {
Point imageSize = getItemImageSize(controller.getItem());
bounds.height = Math.max(bounds.height, imageSize.y);
}
if (hasItemText(controller.getItem())) {
Point textSize = getItemTextSize(controller.getItem());
bounds.height = Math.max(bounds.height, textSize.y);
}
Point closeButtonSize = getItemCloseButtonSize();
bounds.height = Math.max(bounds.height, closeButtonSize.y);
}
bounds.height += SPACE * 2;
for (StripItemController controller : controllers) {
int extent = SPACE;
if (hasItemImage(controller.getItem())) {
Point imageSize = getItemImageSize(controller.getItem());
extent += imageSize.x;
extent += SPACE;
}
if (hasItemText(controller.getItem())) {
Point textSize = getItemTextSize(controller.getItem());
extent += textSize.x;
extent += SPACE;
}
Point closeButtonSize = getItemCloseButtonSize();
extent += closeButtonSize.x;
extent += SPACE;
if (controller.getItem().equals(item)) {
bounds.width = extent;
break;
} else {
bounds.x += extent;
bounds.x += SPACE;
}
}
return bounds;
}
public Rectangle getItemImageBounds(StripItem item) {
checkItem(item);
Rectangle bounds = getItemBounds(item);
bounds.y += bounds.height / 2;
bounds.width = 0;
bounds.height = 0;
if (hasItemImage(item)) {
Point imageSize = getItemImageSize(item);
bounds.x += SPACE;
bounds.y -= imageSize.y / 2;
bounds.width = imageSize.x;
bounds.height = imageSize.y;
}
return bounds;
}
public Rectangle getItemTextBounds(StripItem item) {
checkItem(item);
Rectangle bounds = getItemImageBounds(item);
bounds.x += bounds.width;
bounds.y += bounds.height / 2;
bounds.width = 0;
bounds.height = 0;
if (hasItemText(item)) {
Point textSize = getItemTextSize(item);
bounds.x += SPACE;
bounds.y -= textSize.y / 2;
bounds.width = textSize.x;
bounds.height = textSize.y;
}
return bounds;
}
public Rectangle getItemCloseButtonBounds(StripItem item) {
checkItem(item);
Point closeButtonSize = getItemCloseButtonSize();
Rectangle bounds = getItemTextBounds(item);
bounds.x += bounds.width + SPACE;
bounds.y += bounds.height / 2 - closeButtonSize.y / 2;
bounds.width = closeButtonSize.x;
bounds.height = closeButtonSize.y;
return bounds;
}
public void redrawItem(StripItem item) {
checkItem(item);
StripItemController controller = getController(item);
Rectangle newBounds = getItemBounds(item);
newBounds.x += controller.getOffset();
Rectangle oldBounds = controller.getOldBounds();
if (oldBounds != null && !oldBounds.equals(newBounds)) {
redraw(oldBounds.x, oldBounds.y, oldBounds.width, oldBounds.height, true);
}
redraw(newBounds.x, newBounds.y, newBounds.width, newBounds.height, true);
controller.setOldBounds(newBounds);
}
public StripItem getHoveredItem() {
if (hovered == null) {
return null;
}
return hovered.getItem();
}
public boolean isItemHovered(StripItem item) {
checkItem(item);
return item.equals(getHoveredItem());
}
public StripItem getPressedItem() {
if (pressed == null) {
return null;
}
return pressed.getItem();
}
public boolean isItemPressed(StripItem item) {
checkItem(item);
return item.equals(getPressedItem());
}
public StripItem getDraggedItem() {
if (dragged == null) {
return null;
}
return dragged.getItem();
}
public boolean isItemDragged(StripItem item) {
checkItem(item);
return item.equals(getDraggedItem());
}
public StripItem[] getSelectedItems() {
List<StripItem> items = new ArrayList<StripItem>();
for (StripItemController controller : selected) {
items.add(controller.getItem());
}
return items.toArray(new StripItem[items.size()]);
}
public boolean isItemSelected(StripItem item) {
checkItem(item);
for (StripItemController controller : selected) {
if (controller.getItem().equals(item)) {
return true;
}
}
return false;
}
public void setItemSelected(StripItem item, boolean value) {
setItemSelected(item, value, true);
}
public void checkItem(StripItem item) {
if (item == null) {
throw new NullPointerException();
}
if (!containsItem(item)) {
throw new IllegalArgumentException();
}
}
public StripItem getItemBelowMouseCursor() {
Point location = getDisplay().getCursorLocation();
location = toControl(location);
return getItem(location.x, location.y);
}
private Rectangle getItemOffsetBounds(StripItem item) {
checkItem(item);
return getItemOffsetBounds(controllers, getController(item));
}
private Rectangle getItemOffsetBounds(List<StripItemController> controllers, StripItemController controller) {
Rectangle bounds = getItemBounds(controllers, controller.getItem());
bounds.x += controller.getOffset();
return bounds;
}
private void setItemSelected(StripItem item, boolean value, boolean affectOthers) {
checkItem(item);
StripItemController controller = getController(item);
StripItem[] othersSelected = getSelectedItems();
if (value) {
if (!isItemSelected(item)) {
controller.setForeground(FOREGROUNDS[SELECTED]);
if (isItemHovered(item)) {
controller.setBackground(BACKGROUNDS[SELECTED]);
redrawItem(item);
} else {
RGB from;
RGB to = BACKGROUNDS[SELECTED];
if (controller.hasBackground()) {
from = controller.getBackground();
} else {
from = BACKGROUNDS[NONE];
}
animateBackground(controller, from, to);
}
selected.add(controller);
}
} else {
if (isItemSelected(item)) {
controller.setForeground(FOREGROUNDS[NONE]);
if (isItemHovered(item)) {
controller.setBackground(BACKGROUNDS[HOVERED]);
redrawItem(item);
} else {
RGB from;
RGB to = BACKGROUNDS[NONE];
if (controller.hasBackground()) {
from = controller.getBackground();
} else {
from = BACKGROUNDS[SELECTED];
}
animateBackground(controller, from, to);
}
selected.remove(controller);
}
}
if (affectOthers && !isMultiSelection()) {
for (StripItem otherSelected : othersSelected) {
setItemSelected(otherSelected, false, false);
}
}
}
private void animateMoveTo(final StripItemController controller, final int location) {
if (controller.hasOffsetAnimator()) {
controller.getOffsetAnimator().cancel();
controller.setOffsetAnimator(null);
return;
}
TimingTarget timingTarget = new TimingTargetAdapter() {
private int srcOffset;
private int destOffset;
@Override
public void begin(Animator source) {
srcOffset = controller.getOffset();
destOffset = location - getItemBounds(controller.getItem()).x;
}
@Override
public void timingEvent(Animator source, double fraction) {
Rectangle oldOffsetBounds = getItemOffsetBounds(controller.getItem());
controller.setOffset((int )(srcOffset + (destOffset - srcOffset) * fraction));
redraw(oldOffsetBounds.x, oldOffsetBounds.y, oldOffsetBounds.width, oldOffsetBounds.height, true);
redrawItem(controller.getItem());
}
@Override
public void end(Animator source) {
Rectangle bounds = getItemBounds(controller.getItem());
int diff = location - bounds.x;
controller.setOffset(diff);
redrawItem(controller.getItem());
controller.setOffsetAnimator(null);
}
};
Interpolator interpol = new AccelerationInterpolator(0.0, 0.1);
Animator animator = new Animator.Builder().addTarget(timingTarget).setInterpolator(interpol).setDuration(250, TimeUnit.MILLISECONDS).build();
controller.setOffsetAnimator(animator);
animator.start();
System.out.println("Started: " + System.currentTimeMillis());
}
private void animateBackground(final StripItemController controller, final RGB from, final RGB to) {
if (controller.hasBackgroundAnimator()) {
controller.getBackgroundAnimator().cancel();
controller.setBackgroundAnimator(null);
}
TimingTarget timingTarget = new TimingTargetAdapter() {
@Override
public void timingEvent(Animator source, double fraction) {
double r = to.red - from.red;
double g = to.green - from.green;
double b = to.blue - from.blue;
r *= fraction;
g *= fraction;
b *= fraction;
r += from.red;
g += from.green;
b += from.blue;
controller.setBackground(new RGB((int )r, (int )g, (int )b));
redrawItem(controller.getItem());
}
@Override
public void end(Animator source) {
controller.setBackground(to);
redrawItem(controller.getItem());
controller.setBackgroundAnimator(null);
}
};
Interpolator interpol = new AccelerationInterpolator(0.0, 0.1);
Animator animator = new Animator.Builder().addTarget(timingTarget).setInterpolator(interpol).setDuration(100, TimeUnit.MILLISECONDS).build();
controller.setBackgroundAnimator(animator);
animator.start();
}
protected void onPaint(Event event) {
for (StripItemController controller : controllers) {
if (controller.equals(dragged)) {
continue;
}
paintItem(event.gc, controller);
}
if (dragged != null) {
paintItem(event.gc, dragged);
}
}
protected void onMouseEnter(Event event) {
processHover(event.x, event.y);
}
protected void onMouseExit(Event event) {
processHover(event.x, event.y);
}
protected void onMouseDown(Event event) {
if (event.button != 1) {
return;
}
StripItemController controller = getController(event.x, event.y);
if (controller != null) {
Rectangle bounds = getItemBounds(controller.getItem());
controller.setBackground(BACKGROUNDS[PRESSED]);
redrawItem(controller.getItem());
mouseDownLocation = new Point(event.x, event.y);
mouseDownOffset = new Point(event.x - bounds.x, event.y - bounds.y);
mouseMoveLocation = new Point(event.x, event.y);
}
pressed = controller;
}
protected void onMouseMove(Event event) {
processHover(event.x, event.y);
if (pressed != null) {
if (Math.abs(event.x - mouseDownLocation.x) > 5) {
dragged = pressed;
temp = new ArrayList<StripItemController>(controllers);
pressed = null;
}
}
if (dragged != null) {
int offset = dragged.getOffset();
offset += (event.x - mouseMoveLocation.x);
StripItemController[] affected = null;
if (event.x - mouseMoveLocation.x > 0) {
// right to left
affected = getControllersAfter(dragged, event.x - mouseMoveLocation.x);
}
if (event.x - mouseMoveLocation.x < 0) {
// left to right
affected = getControllersBefore(dragged, mouseMoveLocation.x - event.x);
}
dragged.setOffset(offset);
redrawItem(dragged.getItem());
if (event.x - mouseMoveLocation.x > 0) {
StripItemController last = null;
for (StripItemController item : affected) {
if (last == null) {
last = item;
} else {
Rectangle bounds0 = getItemBounds(last.getItem());
Rectangle bounds1 = getItemBounds(item.getItem());
if (bounds1.x > bounds0.x) {
last = item;
}
}
}
if (last != null) {
temp.remove(dragged);
temp.add(temp.indexOf(last) + 1, dragged);
}
for (StripItemController item : affected) {
Rectangle bounds = getItemBounds(temp, item.getItem());
Rectangle offsetBounds = getItemOffsetBounds(item.getItem());
if (!bounds.equals(offsetBounds)) {
animateMoveTo(item, bounds.x);
}
}
}
if (event.x - mouseMoveLocation.x < 0) {
StripItemController first = null;
for (StripItemController item : affected) {
if (first == null) {
first = item;
} else {
Rectangle bounds0 = getItemBounds(first.getItem());
Rectangle bounds1 = getItemBounds(item.getItem());
if (bounds1.x < bounds0.x) {
first = item;
}
}
}
if (first != null) {
temp.remove(dragged);
temp.add(temp.indexOf(first), dragged);
}
for (StripItemController item : affected) {
Rectangle bounds = getItemBounds(temp, item.getItem());
Rectangle offsetBounds = getItemOffsetBounds(item.getItem());
if (!bounds.equals(offsetBounds)) {
animateMoveTo(item, bounds.x);
}
}
}
mouseMoveLocation.x = event.x;
mouseMoveLocation.y = event.y;
}
}
protected void onMouseUp(Event event) {
if (pressed != null) {
boolean wasSelected = isItemSelected(pressed.getItem());
if (wasSelected && !isMultiSelection()) {
pressed.setBackground(BACKGROUNDS[SELECTED]);
redrawItem(pressed.getItem());
} else {
setItemSelected(pressed.getItem(), !wasSelected);
}
}
if (dragged != null) {
temp = null;
Rectangle bounds = getItemBounds(dragged.getItem());
animateMoveTo(dragged, bounds.x);
StripItem itemBelow = getItemBelowMouseCursor();
StripItemController controllerBelow = getController(itemBelow);
if (dragged.equals(controllerBelow)) {
dragged.setBackground(BACKGROUNDS[HOVERED]);
redrawItem(dragged.getItem());
} else {
if (isItemSelected(dragged.getItem())) {
dragged.setBackground(BACKGROUNDS[SELECTED]);
redrawItem(dragged.getItem());
} else {
animateBackground(dragged, BACKGROUNDS[PRESSED], BACKGROUNDS[NONE]);
}
if (controllerBelow != null) {
if (!isItemPressed(controllerBelow.getItem())) {
if (!isItemDragged(controllerBelow.getItem())) {
animateBackground(controllerBelow, BACKGROUNDS[NONE], BACKGROUNDS[HOVERED]);
}
}
}
}
}
pressed = null;
dragged = null;
mouseDownLocation = null;
mouseDownOffset = null;
mouseMoveLocation = null;
}
private void processHover(int x, int y) {
StripItemController oldController = hovered;
StripItemController newController = getController(x, y);
if (RT.equals(oldController, newController)) {
return;
}
if (oldController != null) {
if (!isItemSelected(oldController.getItem())) {
if (pressed == null && dragged == null) {
RGB from;
RGB to = BACKGROUNDS[NONE];
if (oldController.hasBackground()) {
from = oldController.getBackground();
} else {
from = BACKGROUNDS[HOVERED];
}
animateBackground(oldController, from, to);
}
}
}
if (newController != null) {
if (!isItemSelected(newController.getItem())) {
if (pressed == null && dragged == null) {
RGB from;
RGB to = BACKGROUNDS[HOVERED];
if (newController.hasBackground()) {
from = newController.getBackground();
} else {
from = BACKGROUNDS[NONE];
}
animateBackground(newController, from, to);
}
}
}
hovered = newController;
}
private StripItemController getController(StripItem item) {
for (StripItemController controller : controllers) {
if (controller.getItem().equals(item)) {
return controller;
}
}
return null;
}
private StripItemController getController(int x, int y) {
for (StripItemController controller : controllers) {
StripItem item = controller.getItem();
Rectangle bounds = getItemBounds(item);
if (bounds.contains(x, y)) {
return controller;
}
}
return null;
}
private void paintItem(GC gc, StripItemController controller) {
paintItemBackground(gc, controller);
paintItemImage(gc, controller);
paintItemText(gc, controller);
paintItemCloseButton(gc, controller);
paintItemFrame(gc, controller);
}
private void paintItemBackground(GC gc, StripItemController controller) {
if (!controller.hasBackground()) {
return;
}
Color oldColor = gc.getBackground();
Color newColor = newColor(controller.getBackground());
gc.setBackground(newColor);
Rectangle bounds = getItemBounds(controller.getItem());
bounds.x += controller.getOffset();
gc.fillRectangle(bounds);
gc.setBackground(oldColor);
newColor.dispose();
}
private void paintItemImage(GC gc, StripItemController controller) {
if (!hasItemImage(controller.getItem())) {
return;
}
Rectangle imageBounds = getItemImageBounds(controller.getItem());
imageBounds.x += controller.getOffset();
gc.drawImage(controller.getItem().getImage(), imageBounds.x, imageBounds.y);
}
private void paintItemText(GC gc, StripItemController controller) {
if (!hasItemText(controller.getItem())) {
return;
}
Color oldColor = gc.getForeground();
Color newColor = null;
if (controller.hasForeground()) {
newColor = newColor(controller.getForeground());
gc.setForeground(newColor);
}
Rectangle textBounds = getItemTextBounds(controller.getItem());
textBounds.x += controller.getOffset();
gc.drawText(controller.getItem().getText(), textBounds.x, textBounds.y, true);
gc.setForeground(oldColor);
if (newColor != null) {
newColor.dispose();
}
}
private void paintItemCloseButton(GC gc, StripItemController controller) {
Rectangle closeButtonBounds = getItemCloseButtonBounds(controller.getItem());
closeButtonBounds.x += controller.getOffset();
gc.drawImage(getItemCloseButtonImage(), closeButtonBounds.x, closeButtonBounds.y);
}
private void paintItemFrame(GC gc, StripItemController controller) {
Rectangle bounds = getItemBounds(controller.getItem());
bounds.x += controller.getOffset();
Color oldColor = gc.getForeground();
Color newColor = getColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
gc.setForeground(newColor);
gc.drawRectangle(bounds.x, bounds.y, bounds.width - 1, bounds.height - 1);
gc.setForeground(oldColor);
}
private Color newColor(RGB rgb) {
Display display = getDisplay();
return new Color(display, rgb);
}
private Color getColor(int id) {
Display display = getDisplay();
return display.getSystemColor(id);
}
private StripItemController[] getControllersBefore(StripItemController controller, int moved) {
Set<StripItemController> before = new HashSet<StripItemController>();
Bounds offsetBounds = Bounds.fromRectangle(getItemOffsetBounds(controller.getItem()));
for (StripItemController otherController : controllers) {
if (otherController.equals(controller)) {
continue;
}
Bounds otherOffsetBounds = Bounds.fromRectangle(getItemOffsetBounds(otherController.getItem()));
if (offsetBounds.getRight() > otherOffsetBounds.getRight() && (offsetBounds.getLeft() - moved) < otherOffsetBounds.getCenterX()) {
before.add(otherController);
}
}
return before.toArray(new StripItemController[before.size()]);
}
private StripItemController[] getControllersAfter(StripItemController controller, int moved) {
Set<StripItemController> after = new HashSet<StripItemController>();
Bounds offsetBounds = Bounds.fromRectangle(getItemOffsetBounds(controller.getItem()));
for (StripItemController otherController : controllers) {
if (otherController.equals(controller)) {
continue;
}
Bounds otherOffsetBounds = Bounds.fromRectangle(getItemOffsetBounds(otherController.getItem()));
if (offsetBounds.getLeft() < otherOffsetBounds.getLeft() && (offsetBounds.getRight() + moved) > otherOffsetBounds.getCenterX()) {
after.add(otherController);
}
}
return after.toArray(new StripItemController[after.size()]);
}
public static void main(String[] args) {
UI.initialize();
Display display = Display.getDefault();
Shell shell = new Shell(display);
StripBar bar = new StripBar(shell, SWT.DOUBLE_BUFFERED);
GridLayout layout = new GridLayout();
layout.horizontalSpacing = 0;
layout.verticalSpacing = 0;
layout.marginWidth = 0;
layout.marginHeight = 0;
shell.setLayout(layout);
GridData data = new GridData();
data.horizontalAlignment = SWT.FILL;
data.verticalAlignment = SWT.FILL;
data.grabExcessHorizontalSpace = true;
bar.setLayoutData(data);
StripItem item0 = new StripItem("item0");
StripItem item1 = new StripItem("item1");
StripItem item2 = new StripItem("item2");
StripItem item3 = new StripItem("item3");
item0.setText("Item 0");
item1.setText("Item 1");
item0.setImage(UIImageResource.T.about16());
item2.setImage(UIImageResource.T.addContact16());
bar.addItem(item0);
bar.addItem(item1);
bar.addItem(item2);
bar.addItem(item3);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
UI.destroy();
}
}