Package com.peterhi.ui.tempbars

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

package com.peterhi.ui.tempbars;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
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.Layout;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;

import com.peterhi.ui.UIImageResource;

public final class StripBar extends Canvas implements Listener {

  private final List<StripItemController> itemControllers = new ArrayList<StripItemController>();

  static final int barMarginLeft = 5;
  static final int barMarginRight = 5;
  static final int barMarginTop = 5;
  static final int barMarginBottom = 5;

  static final int itemSpacing = 5;

  static final int itemMarginLeft = 8;
  static final int itemMarginRight = 8;
  static final int itemMarginTop = 5;
  static final int itemMarginBottom = 5;

  static final int itemTextExtraSpaceBefore = 5;
  static final int itemCloseButtonExtraSpaceBefore = 10;

  static final int itemArcSize = 6;

  public StripBar(Composite parent, int style) {
    super(parent, style);
    addListener(SWT.SetData, this);
    addListener(SWT.Paint, this);
    addListener(SWT.Dispose, this);
  }

  @Override
  public void handleEvent(Event event) {
    if (equals(event.widget)) {
      if (event.type == SWT.SetData) {
        onSetData(event);
      } else if (event.type == SWT.Paint) {
        onPaint(event);
      } else if (event.type == SWT.Dispose) {
        onDispose(event);
      }
    }
  }

  @Override
  public Point computeSize(int wHint, int hHint, boolean changed) {
    Point clientAreaSize = calculateClientAreaSize();
    Rectangle boundsWithTrim = computeTrim(0, 0, clientAreaSize.x,
        clientAreaSize.y);
    return new Point(boundsWithTrim.width, boundsWithTrim.height);
  }

  @Override
  public void layout(boolean changed) {
    for (StripItemController itemController : itemControllers) {
      itemController.setBounds(calculateItemBounds(itemController
          .getItem()));
    }
  }

  @Override
  public void setLayout(Layout layout) {
    throw new UnsupportedOperationException();
  }

  @Override
  public void setLayoutDeferred(boolean defer) {
    throw new UnsupportedOperationException();
  }

  public int getItemCount() {
    return itemControllers.size();
  }

  public StripItem[] getItems() {
    List<StripItem> items = new ArrayList<StripItem>();

    for (StripItemController itemController : itemControllers) {
      items.add(itemController.getItem());
    }

    return items.toArray(new StripItem[items.size()]);
  }

  public int indexOf(StripItem item) {
    if (item == null) {
      throw new NullPointerException();
    }

    StripItemController itemController = getItemController(item);

    if (itemController == null) {
      return -1;
    }

    return itemControllers.indexOf(itemController);
  }

  public boolean contains(StripItem item) {
    return indexOf(item) != -1;
  }

  protected void onSetData(Event event) {
    StripItem item = (StripItem) event.item;

    if (event.detail == SWT.INSERT) {
      if (event.index < 0 || event.index > itemControllers.size()) {
        event.index = itemControllers.size();
      }

      itemControllers.add(event.index, new StripItemController(item));
    } else if (event.detail == SWT.DEL) {
      StripItemController itemController = getItemController(item);

      itemControllers.remove(itemController);
    }
  }

  protected void onPaint(Event event) {
    for (StripItemController itemController : itemControllers) {
      drawItem(event.gc, itemController);
    }
  }

  protected void onDispose(Event event) {
    StripItem[] items = getItems();

    for (StripItem item : items) {
      item.dispose();
    }
  }

  protected StripItemController getItemController(StripItem item) {
    for (StripItemController itemController : itemControllers) {
      if (itemController.getItem().equals(item)) {
        return itemController;
      }
    }

    return null;
  }

  protected Point calculateItemSize(StripItem item) {
    if (!contains(item)) {
      throw new IllegalArgumentException();
    }

    Point size = new Point(0, 0);

    GC gc = new GC(this);
    {
      for (StripItemController itemController : itemControllers) {
        if (itemController.getItem().getImage() != null) {
          size.y = Math.max(size.y, itemController.getItem()
              .getImage().getBounds().height);
        }

        if (itemController.getItem().getText() != null
            && !itemController.getItem().getText().isEmpty()) {
          size.y = Math
              .max(size.y, gc.stringExtent(itemController
                  .getItem().getText()).y);
        }

        size.y = Math.max(size.y, UIImageResource.T
            .closeNormal10().getBounds().height);
      }

      if (item.getImage() != null) {
        size.x += item.getImage().getBounds().width;
      }

      if (item.getText() != null && !item.getText().isEmpty()) {
        if (item.getImage() != null) {
          size.x += itemTextExtraSpaceBefore;
        }

        size.x += gc.stringExtent(item.getText()).x;
      }

      if ((item.getImage() != null)
          || (item.getText() != null && !item.getText().isEmpty())) {
        size.x += itemCloseButtonExtraSpaceBefore;
      }

      size.x += UIImageResource.T.closeNormal10().getBounds().width;

      size.x += itemMarginLeft;
      size.x += itemMarginRight;
      size.y += itemMarginTop;
      size.y += itemMarginBottom;
    }
    gc.dispose();

    return size;
  }

  protected Point calculateClientAreaSize() {
    Point clientAreaSize = new Point(0, 0);

    for (StripItemController itemController : itemControllers) {
      Point itemSize = calculateItemSize(itemController.getItem());
      clientAreaSize.x += itemSize.x;
      clientAreaSize.y = Math.max(clientAreaSize.y, itemSize.y);
    }

    clientAreaSize.x += itemSpacing * (itemControllers.size() - 1);

    clientAreaSize.x += barMarginLeft;
    clientAreaSize.x += barMarginRight;
    clientAreaSize.y += barMarginTop;
    clientAreaSize.y += barMarginBottom;

    return clientAreaSize;
  }

  protected Rectangle calculateItemBounds(StripItem item) {
    if (!contains(item)) {
      throw new IllegalArgumentException();
    }

    Rectangle bounds = new Rectangle(0, 0, 0, 0);

    bounds.x += barMarginLeft;
    bounds.y += barMarginTop;

    for (StripItemController itemController : itemControllers) {
      Point itemSize = calculateItemSize(itemController.getItem());
      bounds.height = Math.max(bounds.height, itemSize.y);
    }

    for (StripItemController itemController : itemControllers) {
      Point itemSize = calculateItemSize(itemController.getItem());

      if (itemController.getItem().equals(item)) {
        bounds.width = itemSize.x;
        break;
      } else {
        bounds.x += itemSize.x;
        bounds.x += itemSpacing;
      }
    }

    return bounds;
  }

  protected Rectangle calculateItemImageBounds(StripItem item,
      Rectangle itemBounds) {
    if (!contains(item)) {
      throw new IllegalArgumentException();
    }

    Rectangle bounds = new Rectangle(itemBounds.x, itemBounds.y,
        itemBounds.width, itemBounds.height);

    bounds.x += itemMarginLeft;
    bounds.y += itemBounds.height / 2;
    bounds.width = 0;
    bounds.height = 0;

    if (item.getImage() != null) {
      Rectangle imageBounds = item.getImage().getBounds();
      bounds.y -= imageBounds.height / 2;
      bounds.width = imageBounds.width;
      bounds.height = imageBounds.height;
    }

    return bounds;
  }

  protected Rectangle calculateItemTextBounds(StripItem item,
      Rectangle itemBounds) {
    if (!contains(item)) {
      throw new IllegalArgumentException();
    }

    Rectangle bounds = calculateItemImageBounds(item, itemBounds);

    bounds.x += bounds.width;
    bounds.y += bounds.height / 2;
    bounds.width = 0;
    bounds.height = 0;

    if (item.getText() != null && !item.getText().isEmpty()) {
      if (item.getImage() != null) {
        bounds.x += itemTextExtraSpaceBefore;
      }

      GC gc = new GC(this);
      {
        Point textSize = gc.stringExtent(item.getText());
        bounds.y -= textSize.y / 2;
        bounds.width = textSize.x;
        bounds.height = textSize.y;
      }
      gc.dispose();
    }

    return bounds;
  }

  protected Rectangle calculateItemCloseButtonBounds(StripItem item,
      Rectangle itemBounds) {
    if (!contains(item)) {
      throw new IllegalArgumentException();
    }

    Rectangle bounds = calculateItemTextBounds(item, itemBounds);

    bounds.x += bounds.width;
    bounds.y += bounds.height / 2;
    bounds.width = 0;
    bounds.height = 0;

    if ((item.getImage() != null)
        || (item.getText() != null && !item.getText().isEmpty())) {
      bounds.x += itemCloseButtonExtraSpaceBefore;
    }

    Rectangle closeButtonImageBounds = UIImageResource.T
        .closeNormal10().getBounds();
    bounds.y -= closeButtonImageBounds.height / 2;
    bounds.width = closeButtonImageBounds.width;
    bounds.height = closeButtonImageBounds.height;

    return bounds;
  }

  protected void drawItem(GC gc, StripItemController itemController) {
    drawItemBackground(gc, itemController);
    drawItemImage(gc, itemController);
    drawItemText(gc, itemController);
    drawItemCloseButton(gc, itemController);
    drawItemFrame(gc, itemController);
  }

  protected void drawItemBackground(GC gc, StripItemController itemController) {
    Display display = getDisplay();

    Color oldBackground = gc.getBackground();
    Color newBackground = new Color(display, itemController.getBackground());
    gc.setBackground(newBackground);
    {
      Rectangle bounds = itemController.getBounds();
      gc.fillRoundRectangle(bounds.x, bounds.y, bounds.width - 1,
          bounds.height - 1, itemArcSize, itemArcSize);
    }
    gc.setBackground(oldBackground);
    newBackground.dispose();
  }

  protected void drawItemImage(GC gc, StripItemController itemController) {
    if (itemController.getItem().getImage() == null) {
      return;
    }

    Rectangle bounds = calculateItemImageBounds(itemController.getItem(),
        itemController.getBounds());
    gc.drawImage(itemController.getItem().getImage(), bounds.x, bounds.y);
  }

  protected void drawItemText(GC gc, StripItemController itemController) {
    if (itemController.getItem().getText() == null
        || itemController.getItem().getText().isEmpty()) {
      return;
    }

    Rectangle bounds = calculateItemTextBounds(itemController.getItem(),
        itemController.getBounds());
    gc.drawText(itemController.getItem().getText(), bounds.x, bounds.y);
  }

  protected void drawItemCloseButton(GC gc, StripItemController itemController) {
    Rectangle bounds = calculateItemCloseButtonBounds(
        itemController.getItem(), itemController.getBounds());
    gc.drawImage(UIImageResource.T.closeNormal10(), bounds.x,
        bounds.y);
  }

  protected void drawItemFrame(GC gc, StripItemController itemController) {
    Display display = getDisplay();

    Color oldForeground = gc.getForeground();
    Color newForeground = display
        .getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
    gc.setForeground(newForeground);
    {
      Rectangle bounds = itemController.getBounds();
      gc.drawRoundRectangle(bounds.x, bounds.y, bounds.width - 1,
          bounds.height - 1, itemArcSize, itemArcSize);
    }
    gc.setForeground(oldForeground);
  }

  public static void main(String[] args) {
    Display display = Display.getDefault();

    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 bar = new StripBar(shell, SWT.DOUBLE_BUFFERED | SWT.BORDER);
    {
      GridData data = new GridData();
      data.horizontalAlignment = SWT.FILL;
      data.verticalAlignment = SWT.FILL;
      data.grabExcessHorizontalSpace = true;
      bar.setLayoutData(data);
    }

    {
      StripItem item1 = new StripItem(bar, SWT.NONE);
      item1.setText("Item 1");

      StripItem item2 = new StripItem(bar, SWT.NONE);
      item2.setImage(UIImageResource.T.addContact16());

      StripItem item3 = new StripItem(bar, SWT.NONE);

      StripItem item0 = new StripItem(bar, SWT.NONE, 0);
      item0.setText("Item 0");
      item0.setImage(UIImageResource.T.about16());
    }

    bar.layout();
    shell.open();

    while (!shell.isDisposed()) {
      if (!display.readAndDispatch()) {
        display.sleep();
      }
    }
  }

}
TOP

Related Classes of com.peterhi.ui.tempbars.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.