Package com.peterhi.ui.stripbar6

Source Code of com.peterhi.ui.stripbar6.StripBar

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();
      }
    }
  }
 
}
TOP

Related Classes of com.peterhi.ui.stripbar6.StripBar

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.