package com.peterhi.ui.stripbar6;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
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.graphics.Transform;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Layout;
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.TimingSource;
import org.jdesktop.swt.animation.timing.sources.SWTTimingSource;
import com.peterhi.runtime.RT;
import com.peterhi.ui.UI;
import com.peterhi.ui.UIImageResource;
public class StripBar extends Composite implements Listener {
public static final int BAR_EXTENT_MARGIN = 5;
public static final int BAR_SPAN_MARGIN = 5;
public static final int ITEM_EXTENT_MARGIN = 10;
public static final int ITEM_SPAN_MARGIN = 5;
public static final int ITEM_SPACING = 5;
public static final int ITEM_TEXT_INDENT = 5;
public static final int ITEM_CLOSEBUTTON_INDENT = 10;
public static final int ITEM_ROUND_ARC = 6;
private final List<StripItem> items = new ArrayList<StripItem>();
private boolean imageRotationPreservedInVerticalMode;
private boolean animated;
private StripMouseContext mouseContext;
public StripBar(Composite parent, int style) {
super(parent, style);
addListener(SWT.Modify, this);
addListener(SWT.Dispose, this);
addListener(SWT.Paint, this);
addListener(SWT.PaintItem, 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.Modify) {
onModify(event);
} else if (event.type == SWT.Dispose) {
onDispose(event);
} else if (event.type == SWT.Paint) {
onPaint(event);
} else if (event.type == SWT.PaintItem) {
onPaintItem(event);
} else if (event.type == SWT.MouseEnter) {
processFocus(event.x, event.y);
} else if (event.type == SWT.MouseExit) {
processFocus(event.x, event.y);
} 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 = computeInternalSize().toPoint(isVertical());
Rectangle bounds = computeTrim(0, 0, size.x, size.y);
return new Point(bounds.width, bounds.height);
}
@Override
public void layout(boolean changed) {
for (StripItem item : items) {
item.setBounds(computeBounds(item, items), false, null);
}
}
@Override
public void setLayout(Layout layout) {
throw new UnsupportedOperationException();
}
@Override
public void setLayoutDeferred(boolean defer) {
throw new UnsupportedOperationException();
}
public int indexOf(StripItem item) {
if (item == null) {
throw new NullPointerException();
}
return items.indexOf(item);
}
public boolean contains(StripItem item) {
return indexOf(item) >= 0;
}
public int getItemCount() {
return items.size();
}
public StripItem[] getItems() {
return items.toArray(new StripItem[items.size()]);
}
public StripItem getItem(int index) {
return items.get(index);
}
public StripItem[] getItems(int x, int y) {
List<StripItem> itemsAt = new ArrayList<StripItem>();
for (StripItem item : items) {
if (item.getBounds().getNow().contains(x, y)) {
itemsAt.add(item);
}
}
return itemsAt.toArray(new StripItem[itemsAt.size()]);
}
public StripItem getItem(int x, int y) {
StripItem[] items = getItems(x, y);
if (items.length > 0) {
return items[0];
}
return null;
}
public StripItem[] getItems(int state, boolean exact) {
List<StripItem> itemsWithState = new ArrayList<StripItem>();
for (StripItem item : items) {
if (RT.isFlagged(item.getState(), state, exact)) {
itemsWithState.add(item);
}
}
return itemsWithState.toArray(new StripItem[itemsWithState.size()]);
}
public StripItem getItem(int state, boolean exact) {
StripItem[] items = getItems(state, exact);
if (items.length > 0) {
return items[0];
}
return null;
}
public int getPosition() {
if (RT.isFlagged(getStyle(), SWT.LEFT)) {
return SWT.LEFT;
}
if (RT.isFlagged(getStyle(), SWT.RIGHT)) {
return SWT.RIGHT;
}
return SWT.TOP;
}
public int getAlignment() {
int position = getPosition();
if (position == SWT.LEFT) {
return SWT.VERTICAL;
}
if (position == SWT.RIGHT) {
return SWT.VERTICAL;
}
return SWT.HORIZONTAL;
}
public boolean isVertical() {
return getAlignment() == SWT.VERTICAL;
}
public boolean isImageRotationPreservedInVerticalMode() {
return imageRotationPreservedInVerticalMode;
}
public void setImageRotationPreservedInVerticalMode(boolean value) {
imageRotationPreservedInVerticalMode = value;
}
public boolean isAnimated() {
return animated;
}
public void setAnimated(boolean value) {
animated = value;
}
protected void onModify(Event event) {
if (event.item == null) {
throw new NullPointerException();
}
if (!(event.item instanceof StripItem)) {
throw new ClassCastException();
}
if (event.index < -1 || event.index > items.size()) {
throw new IndexOutOfBoundsException();
}
if (event.index == -1) {
event.index = items.size();
}
StripItem item = (StripItem )event.item;
if (event.detail == SWT.INSERT) {
items.add(event.index, item);
} else if (event.detail == SWT.DEL) {
items.remove(item);
}
}
protected void onDispose(Event event) {
StripItem[] items = getItems();
for (StripItem item : items) {
UI.dispose(item);
}
}
protected void onPaint(Event event) {
List<StripItem> items = getItemsInPaintOrder();
for (StripItem item : items) {
Event redir = new Event();
redir.time = (int )(System.currentTimeMillis() & 0xffffffffL);
redir.widget = item;
redir.gc = event.gc;
item.notifyListeners(SWT.Paint, redir);
}
}
protected void onPaintItem(Event event) {
GC gc = event.gc;
StripItem item = (StripItem )event.item;
if (RT.isFlagged(item.getState(), StripItem.DRAGGED)) {
gc.setAlpha(192);
}
paintBackground(gc, item);
paintImage(gc, item);
paintText(gc, item);
paintCloseButton(gc, item);
paintBorder(gc, item);
gc.setAlpha(255);
}
protected void onMouseDown(Event event) {
if (event.button != 1) {
return;
}
if (mouseContext != null) {
return;
}
StripItem item = getItem(event.x, event.y);
if (item == null) {
return;
}
if (item.isBoundsAnimating()) {
return;
}
int[] statePointer = new int[] { item.getState() };
RT.addFlags(statePointer, StripItem.PRESSED);
item.setState(statePointer[0], false);
Rectangle bounds = item.getBounds().getFuture();
mouseContext = new StripMouseContext(item);
mouseContext.setInitial(event.x, event.y);
mouseContext.setLatest(event.x, event.y);
mouseContext.setOffset(event.x - bounds.x, event.y - bounds.y);
}
protected void onMouseMove(Event event) {
processFocus(event.x, event.y);
if (mouseContext == null) {
return;
}
StripItem item = mouseContext.getTargetItem();
updateDragFlags(item, event.x, event.y);
boolean dragged = RT.isFlagged(item.getState(), StripItem.DRAGGED);
if (dragged) {
Point buffer = new Point(event.x, event.y);
constrainDragRange(item, mouseContext, buffer);
event.x = buffer.x;
event.y = buffer.y;
dragItems(item, event.x, event.y);
}
mouseContext.setLatest(event.x, event.y);
}
protected void onMouseUp(Event event) {
if (event.button == 1) {
if (mouseContext != null) {
StripItem item = mouseContext.getTargetItem();
int[] statePointer = new int[] { item.getState() };
if (RT.removeFlags(statePointer, StripItem.DRAGGED)) {
List<StripItem> arrangedItems = getItemsInBoundsOrder(SWT.NONE);
item.setBounds(computeBounds(item, arrangedItems), true, null);
} else if (RT.removeFlags(statePointer, StripItem.PRESSED)) {
if (RT.isFlagged(getStyle(), SWT.MULTI)) {
RT.flipFlags(statePointer, StripItem.SELECTED);
} else {
if (RT.addFlags(statePointer, StripItem.SELECTED)) {
for (StripItem other : items) {
if (other.equals(item)) {
continue;
}
int[] otherStatePointer = new int[] { other.getState() };
RT.removeFlags(otherStatePointer, StripItem.SELECTED);
other.setState(otherStatePointer[0], true);
}
}
}
}
item.setState(statePointer[0], false);
mouseContext = null;
List<StripItem> itemsInBoundsOrder = getItemsInBoundsOrder(SWT.NONE);
items.clear();
items.addAll(itemsInBoundsOrder);
}
}
}
private void paintBackground(GC gc, StripItem item) {
RGB rgb = item.getBackground().getNow();
Color old = gc.getBackground();
Color neo = UI.newColor(rgb);
gc.setBackground(neo);
{
Rectangle rect = item.getBounds().getNow();
gc.fillRoundRectangle(rect.x, rect.y, rect.width, rect.height, ITEM_ROUND_ARC, ITEM_ROUND_ARC);
}
gc.setBackground(old);
UI.dispose(neo);
}
private void paintImage(GC gc, StripItem item) {
if (!item.hasImage()) {
return;
}
Rectangle bounds = item.getBounds().getNow();
OIPoint imageLocation = computeImageLocation(item, bounds);
OIPoint imageSize = item.getImageSize();
Rectangle imageBounds = OIPoint.makeRect(imageLocation, imageSize, isVertical());
Transform transform = new Transform(getDisplay());
if (isVertical() && !isImageRotationPreservedInVerticalMode()) {
boolean vertLeft = getPosition() == SWT.LEFT;
transform.translate(vertLeft ? 0 : imageBounds.width, vertLeft ? imageBounds.height : 0);
transform.translate(imageBounds.x, imageBounds.y);
transform.rotate(vertLeft ? -90 : 90);
transform.translate(-imageBounds.x, -imageBounds.y);
}
gc.setTransform(transform);
gc.drawImage(item.getImage(), imageBounds.x, imageBounds.y);
gc.setTransform(null);
UI.dispose(transform);
}
private void paintText(GC gc, StripItem item) {
if (!item.hasText()) {
return;
}
Rectangle bounds = item.getBounds().getNow();
OIPoint textLocation = computeTextLocation(item, bounds);
OIPoint textSize = item.getTextSize();
Rectangle textBounds = OIPoint.makeRect(textLocation, textSize, isVertical());
Transform transform = new Transform(getDisplay());
if (isVertical()) {
boolean vertLeft = getPosition() == SWT.LEFT;
transform.translate(vertLeft ? 0 : textBounds.width, vertLeft ? textBounds.height : 0);
transform.translate(textBounds.x, textBounds.y);
transform.rotate(vertLeft ? -90 : 90);
transform.translate(-textBounds.x, -textBounds.y);
gc.setTransform(transform);
}
gc.setTransform(transform);
RGB rgb = item.getForeground().getNow();
Color old = gc.getForeground();
Color neo = UI.newColor(rgb);
gc.setForeground(neo);
{
gc.drawText(item.getText(), textBounds.x, textBounds.y, true);
}
gc.setForeground(old);
UI.dispose(neo);
gc.setTransform(null);
UI.dispose(transform);
}
private void paintCloseButton(GC gc, StripItem item) {
boolean v = isVertical();
Rectangle bounds = item.getBounds().getNow();
OIPoint closeButtonLocation = computeCloseButtonLocation(item, bounds);
gc.drawImage(getCloseButtonImage(), closeButtonLocation.getX(v), closeButtonLocation.getY(v));
}
private void paintBorder(GC gc, StripItem item) {
Rectangle bounds = item.getBounds().getNow();
bounds.width --;
bounds.height --;
Color old = gc.getForeground();
Color neo = UI.getColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
gc.setForeground(neo);
{
gc.drawRoundRectangle(bounds.x, bounds.y, bounds.width, bounds.height, ITEM_ROUND_ARC, ITEM_ROUND_ARC);
}
gc.setForeground(old);
}
private void processFocus(int x, int y) {
if (getItem(StripItem.PRESSED, false) != null) {
return;
}
if (getItem(StripItem.DRAGGED, false) != null) {
return;
}
StripItem oldItem = getItem(StripItem.FOCUSED, false);
StripItem newItem = getItem(x, y);
if (RT.equals(oldItem, newItem)) {
return;
}
if (oldItem != null) {
int[] statePointer = new int[] { oldItem.getState() };
RT.removeFlags(statePointer, StripItem.FOCUSED);
oldItem.setState(statePointer[0], isAnimated());
}
if (newItem != null) {
int[] statePointer = new int[] { newItem.getState() };
RT.addFlags(statePointer, StripItem.FOCUSED);
newItem.setState(statePointer[0], isAnimated());
}
}
private OIPoint computeInternalSize() {
OIPoint size = new OIPoint(0, 0);
for (StripItem item : items) {
OIPoint itemSize = computeSize(item);
size.extend(itemSize.getExtent());
size.maxSpan(itemSize.getSpan());
}
size.extend(ITEM_SPACING * (items.size() - 1));
size.extend(BAR_EXTENT_MARGIN * 2);
size.span(BAR_SPAN_MARGIN * 2);
return size;
}
private OIPoint computeSize(StripItem item) {
OIPoint closeButtonSize = getCloseButtonSize();
OIPoint size = new OIPoint(0, 0);
if (item.hasImage()) {
OIPoint imageSize = item.getImageSize();
if (isImageRotationPreserved()) {
size.extend(imageSize.getSpan());
} else {
size.extend(imageSize.getExtent());
}
}
if (item.hasText()) {
OIPoint textSize = item.getTextSize();
if (item.hasImage()) {
size.extend(ITEM_TEXT_INDENT);
}
size.extend(textSize.getExtent());
}
if (item.hasImage() || item.hasText()) {
size.extend(ITEM_CLOSEBUTTON_INDENT);
}
size.extend(closeButtonSize.getExtent());
size.extend(ITEM_EXTENT_MARGIN * 2);
for (StripItem spanItem : items) {
if (spanItem.hasImage()) {
OIPoint spanSize = spanItem.getImageSize();
if (isImageRotationPreserved()) {
size.maxSpan(spanSize.getExtent());
} else {
size.maxSpan(spanSize.getSpan());
}
}
if (spanItem.hasText()) {
OIPoint textSize = spanItem.getTextSize();
size.maxSpan(textSize.getSpan());
}
size.maxSpan(closeButtonSize.getSpan());
}
size.span(ITEM_SPAN_MARGIN * 2);
return size;
}
private OIPoint computeLocation(StripItem item, List<StripItem> reference) {
OIPoint location = new OIPoint(0, 0);
location.extend(BAR_EXTENT_MARGIN);
location.span(BAR_SPAN_MARGIN);
for (StripItem extentItem : reference) {
OIPoint extentSize = computeSize(extentItem);
if (item.equals(extentItem)) {
break;
}
location.extend(extentSize.getExtent());
location.extend(ITEM_SPACING);
}
return location;
}
private Rectangle computeBounds(StripItem item, List<StripItem> reference) {
OIPoint location = computeLocation(item, reference);
OIPoint size = computeSize(item);
boolean v = isVertical();
return new Rectangle(location.getX(v), location.getY(v), size.getX(v), size.getY(v));
}
private OIPoint computeImageLocation(StripItem item, Rectangle bounds) {
boolean v = isVertical();
OIPoint location = new OIPoint(bounds.x, bounds.y, v);
OIPoint size = new OIPoint(bounds.width, bounds.height, v);
location.extend(ITEM_EXTENT_MARGIN);
location.span(size.getSpan() / 2);
if (item.hasImage()) {
OIPoint imageSize = item.getImageSize();
boolean r = isImageRotationPreserved();
int span = r ? imageSize.getExtent() : imageSize.getSpan();
location.span(-span / 2);
}
return location;
}
private OIPoint computeTextLocation(StripItem item, Rectangle bounds) {
OIPoint location = computeImageLocation(item, bounds);
OIPoint size = item.getImageSize();
if (isImageRotationPreserved()) {
size.changeOrientation();
}
location.extend(size.getExtent());
location.span(size.getSpan() / 2);
if (item.hasText()) {
if (item.hasImage()) {
location.extend(ITEM_TEXT_INDENT);
}
OIPoint textSize = item.getTextSize();
location.span(-textSize.getSpan() / 2);
}
return location;
}
private OIPoint computeCloseButtonLocation(StripItem item, Rectangle bounds) {
OIPoint location = computeTextLocation(item, bounds);
OIPoint size = item.getTextSize();
OIPoint closeButtonSize = getCloseButtonSize();
if (item.hasImage() || item.hasText()) {
location.extend(ITEM_CLOSEBUTTON_INDENT);
}
location.extend(size.getExtent());
location.span(size.getSpan() / 2);
location.span(-closeButtonSize.getSpan() / 2);
return location;
}
private List<StripItem> getItemsInPaintOrder() {
List<StripItem> itemsInPaintOrder = new ArrayList<StripItem>();
for (StripItem item : items) {
int[] statePointer = new int[] { item.getState() };
if (RT.isFlagged(statePointer, StripItem.PRESSED)) {
continue;
}
if (RT.isFlagged(statePointer, StripItem.DRAGGED)) {
continue;
}
itemsInPaintOrder.add(item);
}
StripItem[] pressedItems = getItems(StripItem.PRESSED, false);
itemsInPaintOrder.addAll(Arrays.asList(pressedItems));
StripItem[] draggedItems = getItems(StripItem.DRAGGED, false);
itemsInPaintOrder.addAll(Arrays.asList(draggedItems));
return itemsInPaintOrder;
}
private List<StripItem> getItemsInBoundsOrder(final int compareStyle) {
List<StripItem> itemsInBoundsOrder = new ArrayList<StripItem>(items);
Comparator<StripItem> comparator = new Comparator<StripItem>() {
@Override
public int compare(StripItem item0, StripItem item1) {
boolean v = isVertical();
Rectangle bounds0 = item0.getBounds().getFuture();
Rectangle bounds1 = item1.getBounds().getFuture();
OIPoint loc0 = new OIPoint(bounds0.x, bounds0.y, v);
OIPoint loc1 = new OIPoint(bounds1.x, bounds1.y, v);
OIPoint size0 = new OIPoint(bounds0.width, bounds0.height, v);
OIPoint size1 = new OIPoint(bounds1.width, bounds1.height, v);
if (compareStyle == SWT.MIN) {
return loc0.getExtent() - loc1.getExtent();
} else if (compareStyle == SWT.MAX) {
return (loc0.getExtent() + size0.getExtent()) - (loc1.getExtent() + size1.getExtent());
} else {
return (loc0.getExtent() + size0.getExtent() / 2) - (loc1.getExtent() + size1.getExtent() / 2);
}
}
};
Collections.sort(itemsInBoundsOrder, comparator);
return itemsInBoundsOrder;
}
private List<StripItem> getAffectedItems(StripItem item, int location, int delta, boolean useBoundsCheck) {
List<StripItem> affectedItems = new ArrayList<StripItem>();
if (delta > 0) {
List<StripItem> itemsInBoundsOrder = getItemsInBoundsOrder(SWT.MAX);
int index = itemsInBoundsOrder.indexOf(item);
for (int i = index + 1; i < items.size(); i++) {
StripItem itemAfter = itemsInBoundsOrder.get(i);
Rectangle boundsAfter = itemAfter.getBounds().getFuture();
if (useBoundsCheck) {
Rectangle bounds = item.getBounds().getFuture();
if (isVertical()) {
if (bounds.y < boundsAfter.y + boundsAfter.height / 2 && bounds.y + bounds.height + delta >= boundsAfter.y + boundsAfter.height / 2) {
affectedItems.add(itemAfter);
}
} else {
if (bounds.x < boundsAfter.x + boundsAfter.width / 2 && bounds.x + bounds.width + delta >= boundsAfter.x + boundsAfter.width / 2) {
affectedItems.add(itemAfter);
}
}
} else {
if (location + delta >= (isVertical() ? boundsAfter.y : boundsAfter.x)) {
affectedItems.add(itemAfter);
}
}
}
} else if (delta < 0) {
List<StripItem> itemsInBoundsOrder = getItemsInBoundsOrder(SWT.MIN);
int index = itemsInBoundsOrder.indexOf(item);
for (int i = 0; i < index; i++) {
StripItem itemBefore = itemsInBoundsOrder.get(i);
Rectangle boundsBefore = itemBefore.getBounds().getFuture();
if (useBoundsCheck) {
Rectangle bounds = item.getBounds().getFuture();
if (isVertical()) {
if (bounds.y + bounds.height > boundsBefore.y + boundsBefore.height / 2 && bounds.y + delta <= boundsBefore.y + boundsBefore.height / 2) {
affectedItems.add(itemBefore);
}
} else {
if (bounds.x + bounds.width > boundsBefore.x + boundsBefore.width / 2 && bounds.x + delta <= boundsBefore.x + boundsBefore.width / 2) {
affectedItems.add(itemBefore);
}
}
} else {
if (location + delta <= (isVertical() ? boundsBefore.y + boundsBefore.height : boundsBefore.x + boundsBefore.width)) {
affectedItems.add(itemBefore);
}
}
}
}
return affectedItems;
}
private boolean isImageRotationPreserved() {
if (isVertical()) {
if (isImageRotationPreservedInVerticalMode()) {
return true;
}
}
return false;
}
private OIPoint getCloseButtonSize() {
Image closeButtonImage = getCloseButtonImage();
Rectangle closeButtonImageBounds = closeButtonImage.getBounds();
return new OIPoint(closeButtonImageBounds, false);
}
private Image getCloseButtonImage() {
Image closeButtonImage = UIImageResource.T.closeNormal10();
return closeButtonImage;
}
private Image getHighlightCloseButtonImage() {
Image highlightCloseButtonImage = UIImageResource.T.closeHighlight10();
return highlightCloseButtonImage;
}
private void updateDragFlags(StripItem item, int x, int y) {
int[] statePointer = new int[] { item.getState() };
boolean pressed = RT.isFlagged(statePointer, StripItem.PRESSED);
boolean willDrag = mouseContext.isConsideredDrag(x, y);
if (!pressed) {
return;
}
if (!willDrag) {
return;
}
RT.removeFlags(statePointer, StripItem.PRESSED);
RT.addFlags(statePointer, StripItem.DRAGGED);
item.setState(statePointer[0], false);
}
private void constrainDragRange(StripItem item, StripMouseContext context, Point buffer) {
boolean v = isVertical();
Rectangle bounds = item.getBounds().getFuture();
OIPoint itemSize = new OIPoint(bounds.width, bounds.height, v);
OIPoint offset = new OIPoint(context.getOffset(), v);
OIPoint oiBuffer = new OIPoint(buffer, v);
OIPoint barSize = computeInternalSize();
if (oiBuffer.getExtent() - offset.getExtent() + itemSize.getExtent() > barSize.getExtent() - BAR_EXTENT_MARGIN) {
oiBuffer.setExtent(barSize.getExtent() - BAR_EXTENT_MARGIN + offset.getExtent() - itemSize.getExtent());
}
if (oiBuffer.getExtent() - offset.getExtent() < BAR_EXTENT_MARGIN) {
oiBuffer.setExtent(BAR_EXTENT_MARGIN + offset.getExtent());
}
buffer.x = oiBuffer.getX(v);
buffer.y = oiBuffer.getY(v);
}
private void dragItems(StripItem item, int x, int y) {
int location = isVertical() ? mouseContext.getLast().y : mouseContext.getLast().x;
int delta = isVertical() ? y - mouseContext.getLast().y : x - mouseContext.getLast().x;
List<StripItem> affected = getAffectedItems(item, location, delta, isAnimated());
if (isAnimated()) {
boolean v = isVertical();
Rectangle bounds = item.getBounds().getFuture();
if (isVertical()) {
bounds.y = y - mouseContext.getOffset().y;
} else {
bounds.x = x - mouseContext.getOffset().x;
}
item.setBounds(bounds, false, null);
for (StripItem affectedItem : affected) {
Rectangle boundsToSet = (delta > 0) ? mouseContext.getFront(affectedItem) : mouseContext.getBack(affectedItem);
affectedItem.setBounds(boundsToSet, true, null);
}
} else {
Rectangle bounds = item.getBounds().getFuture();
if (!affected.isEmpty()) {
int direction = delta > 0 ? 1 : -1;
int locationChange = 0;
for (StripItem affectedItem : affected) {
Rectangle affectedBounds = affectedItem.getBounds().getFuture();
if (isVertical()) {
locationChange += affectedBounds.height + ITEM_SPACING;
} else {
locationChange += affectedBounds.width + ITEM_SPACING;
}
if (isVertical()) {
affectedBounds.y += (-direction) * (bounds.height + ITEM_SPACING);
} else {
affectedBounds.x += (-direction) * (bounds.width + ITEM_SPACING);
}
affectedItem.setBounds(affectedBounds, false, null);
}
if (isVertical()) {
bounds.y += direction * locationChange;
} else {
bounds.x += direction * locationChange;
}
item.setBounds(bounds, false, null);
Point mouse = new Point(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2);
mouse = toDisplay(mouse);
getDisplay().setCursorLocation(mouse);
}
}
}
public static void main(String[] args) {
Display display = Display.getDefault();
TimingSource timingSource = new SWTTimingSource(16, TimeUnit.MILLISECONDS, display);
timingSource.init();
Animator.setDefaultTimingSource(timingSource);
Shell shell = new Shell(display);
GridLayout layout = new GridLayout();
layout.horizontalSpacing = 0;
layout.verticalSpacing = 0;
layout.marginWidth = 0;
layout.marginHeight = 0;
shell.setLayout(layout);
StripBar stripBar = new StripBar(shell, SWT.DOUBLE_BUFFERED | SWT.BORDER | SWT.LEFT);
stripBar.setImageRotationPreservedInVerticalMode(false);
stripBar.setAnimated(true);
GridData layoutData = new GridData();
layoutData.horizontalAlignment = SWT.FILL;
layoutData.verticalAlignment = SWT.FILL;
stripBar.setLayoutData(layoutData);
StripItem item0 = new StripItem(stripBar, SWT.NONE);
item0.setText("Item 0");
item0.setImage(UIImageResource.T.about16());
StripItem item2 = new StripItem(stripBar, SWT.NONE);
item2.setImage(UIImageResource.T.addContact16());
StripItem item3 = new StripItem(stripBar, SWT.NONE);
StripItem item1 = new StripItem(stripBar, SWT.NONE, 1);
item1.setText("Item 1");
item1.setImage(UIImageResource.T.foo());
stripBar.layout();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
}