Package com.positive.charts.widgets

Source Code of com.positive.charts.widgets.TinyScrollbar

package com.positive.charts.widgets;

import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.TypedListener;

import com.positive.colorchecker.StaticColorChecker;

public class TinyScrollbar extends Canvas implements PaintListener {

  private static final int SCROLLBAR_THICKNESS = 4;

  private static final int STATE_MASK = SWT.HORIZONTAL | SWT.VERTICAL;

  /**
   * The direction of the scrollbar, either {@link SWT#HORIZONTAL} or
   * {@link SWT#VERTICAL}.
   */
  private int direction;

  /**
   * Lower bound of the scrollbar range, in domain units.
   */
  protected long minimum = 0;

  /**
   * Upper bound of the scrollbar range, in domain units.
   */
  protected long maximum = 100;

  /**
   * Size of the scrollbar thumb, in domain units.
   */
  protected long thumb = 10;

  /**
   * Currently selected value within scrollbar range, in domain units.
   */
  protected long selection = 0;

  private boolean dragStarted = false;
  private Point dragStartPosition;

  public TinyScrollbar(final Composite parent, final int style) {

    super(parent, style & ~STATE_MASK | SWT.DOUBLE_BUFFERED);

    this.direction = (style & SWT.VERTICAL) != 0 ? SWT.VERTICAL
        : SWT.HORIZONTAL;

    this.addPaintListener(this);

    this.addMouseListener(new MouseAdapter() {
      public void mouseDown(final MouseEvent e) {
        TinyScrollbar.this.handleMouseDown(e);
      }

      public void mouseUp(final MouseEvent e) {
        TinyScrollbar.this.handleMouseUp(e);
      }
    });

    this.addMouseMoveListener(new MouseMoveListener() {
      public void mouseMove(final MouseEvent e) {
        TinyScrollbar.this.handleMouseMove(e);
      }
    });

  }

  /**
   * Adds the listener to the collection of listeners who will be notified
   * when the receiver's value changes, by sending it one of the messages
   * defined in the <code>SelectionListener</code> interface.
   * <p>
   * When <code>widgetSelected</code> is called, the event object detail field
   * contains one of the following values: <code>SWT.NONE</code> - for the end
   * of a drag. <code>SWT.DRAG</code>. <code>SWT.HOME</code>.
   * <code>SWT.END</code>. <code>SWT.ARROW_DOWN</code>.
   * <code>SWT.ARROW_UP</code>. <code>SWT.PAGE_DOWN</code>.
   * <code>SWT.PAGE_UP</code>. <code>widgetDefaultSelected</code> is not
   * called.
   * </p>
   *
   * @param listener
   *            the listener which should be notified
   *
   * @exception IllegalArgumentException
   *                <ul>
   *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
   *                </ul>
   * @exception SWTException
   *                <ul>
   *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
   *                disposed</li>
   *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
   *                thread that created the receiver</li>
   *                </ul>
   *
   * @see SelectionListener
   * @see #removeSelectionListener
   * @see SelectionEvent
   */
  public void addSelectionListener(final SelectionListener listener) {
    this.checkWidget();
    if (listener == null) {
      SWT.error(SWT.ERROR_NULL_ARGUMENT);
    }
    final TypedListener typedListener = new TypedListener(listener);
    this.addListener(SWT.Selection, typedListener);
    this.addListener(SWT.DefaultSelection, typedListener);
  }

  public Rectangle computeTrim(final int x, final int y, final int width,
      final int height) {
    if (this.direction == SWT.HORIZONTAL) {
      return super.computeTrim(x, y, width, SCROLLBAR_THICKNESS);
    }
    return super.computeTrim(x, y, SCROLLBAR_THICKNESS, height);
  }

  public int getDirection() {
    return this.direction;
  }

  public long getMaximum() {
    return this.maximum;
  }

  public long getMinimum() {
    return this.minimum;
  }

  private double getRange() {
    return (double) this.maximum - (double) this.minimum;
  }

  public long getSelection() {
    return this.selection;
  }

  public long getThumb() {
    return this.thumb;
  }

  /**
   * @return
   */
  private Rectangle getThumbRectangle() {
    final double range = this.getRange();
    final double thumbRatio = this.thumb / range;
    final double thumbPosition = (this.selection - this.minimum) / range;

    final Rectangle thumbRect = new Rectangle(0, 0, 0, 0);
    final Rectangle clientArea = this.getClientArea();
    final int width = clientArea.width;
    final int height = clientArea.height;
    if (this.direction == SWT.HORIZONTAL) {
      thumbRect.y = clientArea.y;
      thumbRect.height = clientArea.height;
      thumbRect.width = (int) (width * thumbRatio);
      thumbRect.x = clientArea.x
          + (int) (thumbPosition * (width - thumbRect.width));
    } else {
      thumbRect.x = clientArea.x;
      thumbRect.width = clientArea.width;
      thumbRect.height = (int) (height * thumbRatio);
      thumbRect.y = clientArea.y
          + (int) (thumbPosition * (height - thumbRect.height));
    }
    return thumbRect;
  }

  private void handleMouseDown(final MouseEvent e) {
    final Rectangle thumbRectangle = this.getThumbRectangle();

    if (thumbRectangle.contains(e.x, e.y)) {
      // If clicked within thumb, then it must be a drag...
      this.dragStarted = e.button == 1;
    } else {
      // ...else it is an increment.
      if (this.direction == SWT.HORIZONTAL) {
        if (e.x > thumbRectangle.x + thumbRectangle.width) {
          this.setSelection(this.selection + this.thumb);
        } else {
          this.setSelection(this.selection - this.thumb);
        }
      } else {
        if (e.y > thumbRectangle.y + thumbRectangle.height) {
          this.setSelection(this.selection + this.thumb);
        } else {
          this.setSelection(this.selection - this.thumb);
        }
      }
    }

    if (this.dragStarted) {
      this.dragStartPosition = new Point(e.x, e.y);
    }

    this.handleMouseMove(e);
  }

  protected void handleMouseMove(final MouseEvent e) {
    if (!this.dragStarted) {
      return;
    }
    int positionDelta, length;
    if (this.direction == SWT.HORIZONTAL) {
      positionDelta = e.x - this.dragStartPosition.x;
      this.dragStartPosition.x = e.x;
      length = this.getBounds().width;
    } else {
      positionDelta = e.y - this.dragStartPosition.y;
      this.dragStartPosition.y = e.y;
      length = this.getBounds().height;
    }
    if (positionDelta == 0) {
      return;
    }

    final long selectionDelta = (positionDelta
        * (this.maximum - this.minimum) / length);

    this.setSelection(this.getSelection() + selectionDelta);
  }

  private void handleMouseUp(final MouseEvent e) {
    this.dragStarted &= e.button != 1;
    if (!this.dragStarted) {
      this.dragStartPosition = null;
    }
    this.handleMouseMove(e);
  }

  public void paintControl(final PaintEvent e) {
    final GC gc = e.gc;
    final Rectangle clientArea = this.getClientArea();
    if ((clientArea.width == 0) || (clientArea.height == 0)) {
      return;
    }
    this.paintScrollbar(gc);
  }

  private void paintScrollbar(final GC gc) {
    gc.setBackground(StaticColorChecker
        .dublicateColor(SWT.COLOR_WIDGET_DARK_SHADOW));
    // this.getDisplay().getSystemColor(
    // SWT.COLOR_WIDGET_DARK_SHADOW));
    gc.fillRectangle(this.getClientArea());

    gc.setBackground(StaticColorChecker
        .dublicateColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW));
    // this.getDisplay().getSystemColor(
    // SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW));
    gc.fillRectangle(this.getThumbRectangle());
  }

  /**
   * Removes the listener from the collection of listeners who will be
   * notified when the receiver's value changes.
   *
   * @param listener
   *            the listener which should no longer be notified
   *
   * @exception IllegalArgumentException
   *                <ul>
   *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
   *                </ul>
   * @exception SWTException
   *                <ul>
   *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
   *                disposed</li>
   *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
   *                thread that created the receiver</li>
   *                </ul>
   *
   * @see SelectionListener
   * @see #addSelectionListener
   */
  public void removeSelectionListener(final SelectionListener listener) {
    this.checkWidget();
    if (listener == null) {
      SWT.error(SWT.ERROR_NULL_ARGUMENT);
    }
    this.removeListener(SWT.Selection, listener);
    this.removeListener(SWT.DefaultSelection, listener);
  }

  private void repaint() {
    if (this.isDisposed()) {
      return;
    }

    if (Thread.currentThread() == this.getDisplay().getThread()) {
      this.redraw();
      return;
    }

    this.getDisplay().asyncExec(new Runnable() {
      public void run() {
        TinyScrollbar.this.redraw();
      }
    });
  }

  public void setDirection(final int direction) {
    // assert (direction & STATE_MASK) != 0 :
    // "Direction must be one of SWT.HORIZONTAL or SWT.VERTICAL";
    this.direction = direction;
    this.repaint();
  }

  public void setMaximum(final long max) {
    // assert max > minimum : "Maximum mast be greater than minimum";
    this.maximum = max;
    this.repaint();
  }

  public void setMinimum(final long minimum) {
    // assert minimum < maximum : "Minimum must be less than maximum";
    this.minimum = minimum;
    this.repaint();
  }

  public void setSelection(final long selection) {
    this.checkWidget();
    // assert (selection >= minimum) && (selection <= maximum) : "Selection
    // must lie within minimum and maximum";
    this.selection = Math.max(selection, this.minimum);
    this.selection = Math.min(this.selection, this.maximum);
    this.notifyListeners(SWT.Selection, null);
    this.repaint();
  }

  public void setThumb(final long thumb) {
    // assert thumb > 0 : "Thumb size must be positive";
    this.thumb = thumb;
    this.repaint();
  }

}
TOP

Related Classes of com.positive.charts.widgets.TinyScrollbar

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.