Package org.gudy.azureus2.ui.swt

Source Code of org.gudy.azureus2.ui.swt.TwistieLabel

/**
*
*/
package org.gudy.azureus2.ui.swt;

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

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;

/**
* A Label with a twistie graphic at the beginning; every time this label is clicked the
* twistie graphic toggles between pointing to the right and pointing down.
*
* @author knguyen
*
*/
public class TwistieLabel
  extends Composite
  implements ITwistieConstants
{

  private int style = NONE;

  /**
   * An array of points for a triangle pointing downward
   */
  static final int[] points_for_expanded = {
    0,
    2,
    8,
    2,
    4,
    6
  };

  /**
   * An array of points for a triangle pointing to the right
   *
   */
  static final int[] points_for_collapsed = {
    2,
    -1,
    2,
    8,
    6,
    4
  };

  /**
   * <code>Label</code> to display the text for this twistie
   */
  private Label titleLabel = null;

  /**
   * The <code>Color</code> to use for the twistie graphic itself;
   * defaults to the same as the foreground color of the titleLabel
   */
  private Color twistieColor = null;

  /**
   * The state of the control; callers can check this state by calling {@link #isCollapsed()}
   */
  private boolean isCollapsed = true;

  /**
   * An optional Label to display the description
   */
  private Label descriptionLabel = null;

  private List listeners = new ArrayList();

  /**
   * Create a twistie Label with the given style bit.
   * <p>Style bit can be one or more of:</p>
   * <ul>
   * <li> TwistieLabel.NONE</li> -- The default; does not show description and separator, and is collapsed
   * <li> TwistieLabel.SHOW_DESCRIPTION</li> -- Show the description below the separator (or title if separator s not shown)
   * <li> TwistieLabel.SHOW_SEPARATOR</li> -- Show a separator below the title
   * <li> TwistieLabel.SHOW_EXPANDED</li> -- Show a separator below the title
   * </ul>
   *
   * @param parent
   * @param style
   */
  public TwistieLabel(Composite parent, int style) {
    super(parent, SWT.NONE);
    setBackgroundMode(SWT.INHERIT_FORCE);
    this.style = style;

    GridLayout gLayout = new GridLayout();
    gLayout.marginHeight = 0;
    gLayout.marginWidth = 0;
    gLayout.verticalSpacing = 0;
    gLayout.horizontalSpacing = 0;
    setLayout(gLayout);

    titleLabel = new Label(this, SWT.NONE);

    if ((this.style & SHOW_SEPARATOR) != 0) {
      Label separator = new Label(this, SWT.SEPARATOR | SWT.HORIZONTAL);
      GridData labelData = new GridData(SWT.FILL, SWT.CENTER, true, false);
      labelData.horizontalIndent = 10;
      separator.setLayoutData(labelData);
    }

    if ((this.style & SHOW_DESCRIPTION) != 0) {
      descriptionLabel = new Label(this, SWT.WRAP);
      GridData labelData = new GridData(SWT.FILL, SWT.FILL, true, false);
      labelData.horizontalIndent = 10;
      descriptionLabel.setLayoutData(labelData);

      /*
       * Change the font to be italic for the description
       */
      Font initialFont = descriptionLabel.getFont();
      FontData[] fontData = initialFont.getFontData();
      for (int i = 0; i < fontData.length; i++) {
        fontData[i].setStyle(fontData[i].getStyle() | SWT.ITALIC);
      }
      descriptionLabel.setFont(new Font(getDisplay(), fontData));

    }

    if ((this.style & SHOW_EXPANDED) != 0) {
      isCollapsed = false;
    }

    /*
     * Leaving a little margin on the left; this is where we draw the twistie graphic
     */
    GridData labelData = new GridData(SWT.FILL, SWT.CENTER, true, false);
    labelData.horizontalIndent = 10;
    titleLabel.setLayoutData(labelData);

    /*
     * Add our mouse interceptor to the control and the title label
     */
    MouseInterceptor interceptor = new MouseInterceptor();
    super.addMouseListener(interceptor);
    titleLabel.addMouseListener(interceptor);

    /*
     * Listens to the paint event and do the drawing here
     */
    addPaintListener(new PaintListener() {
      public void paintControl(PaintEvent e) {

        /*
         * The graphic is drawn to the left of the titleLabel so define the offset from the titleLabel
         */
        int offsetX = titleLabel.getBounds().x - 10;
        int offsetY = titleLabel.getBounds().y + 3;

        if (null != twistieColor) {
          e.gc.setBackground(twistieColor);
        } else {
          e.gc.setBackground(getForeground());
        }

        if (true == isCollapsed) {
          e.gc.fillPolygon(translate(points_for_collapsed, offsetX, offsetY));
        } else {
          e.gc.fillPolygon(translate(points_for_expanded, offsetX, offsetY));
        }
      }
    });
  }

  /**
   * Translates the twistie points array to compensate for the given x and y offset
   * @param data
   * @param x
   * @param y
   * @return
   */
  private int[] translate(int[] data, int x, int y) {

    int[] target = new int[data.length];
    for (int i = 0; i < data.length; i += 2) {
      target[i] = data[i] + x;
    }
    for (int i = 1; i < data.length; i += 2) {
      target[i] = data[i] + y;
    }
    return target;
  }

  /**
   * Add a mouse listener to the control and also the <code>titleLabel</code>
   */
  public void addMouseListener(MouseListener listener) {
    if (null != titleLabel) {
      titleLabel.addMouseListener(listener);
    }
    super.addMouseListener(listener);
  }

  /**
   * Remove the mouse listener from the control and also the <code>titleLabel</code>
   */
  public void removeMouseListener(MouseListener listener) {
    if (null != titleLabel) {
      titleLabel.removeMouseListener(listener);
    }
    super.removeMouseListener(listener);
  }

  /**
   * Sets the color to be used for drawing the twistie graphic
   * @param color
   */
  public void setTwistieForeground(Color color) {
    twistieColor = color;
  }

  /**
   * Sets the foreground color for the control and also all the text-base children
   */
  public void setForeground(Color color) {
    if (null != titleLabel && false == titleLabel.isDisposed()) {
      titleLabel.setForeground(color);
    }
    if (null != descriptionLabel && false == descriptionLabel.isDisposed()) {
      descriptionLabel.setForeground(color);
    }

    if (null == twistieColor) {
      twistieColor = color;
    }

    super.setForeground(color);
  }

  /**
   * Sets the background color for the control and also all the text-base children
   */
  public void setBackground(Color color) {
    if (null != titleLabel) {
      titleLabel.setBackground(color);
    }
    if (null != descriptionLabel) {
      descriptionLabel.setBackground(color);
    }

    super.setBackground(color);
  }

  /**
   * Sets the text to display as the title
   * @param string
   */
  public void setTitle(String string) {
    if (null != titleLabel) {
      titleLabel.setText(string);
    }
  }

  /**
   * Sets the text to display as the description; this is not in effect unless the {@link #SHOW_DESCRIPTION} flag is also set
   * @param string
   */
  public void setDescription(String string) {
    if (null != descriptionLabel) {
      descriptionLabel.setText(string);
    }
  }

  /**
   * Sets the tooltip for the control and also all the text-base children
   */
  public void setToolTipText(String string) {
    if (null != titleLabel) {
      titleLabel.setToolTipText(string);
    }

    if (null != descriptionLabel) {
      descriptionLabel.setToolTipText(string);
    }

    super.setToolTipText(string);
  }

  /**
   * Sets the enablement for the control and also all the text-base children
   */
  public void setEnabled(boolean enabled) {
    if (null != titleLabel) {
      titleLabel.setEnabled(enabled);
    }

    super.setEnabled(enabled);
  }

  /**
   * Returns whether this control is in a collapsed state
   * @return
   */
  public boolean isCollapsed() {
    return isCollapsed;
  }

  /**
   * Add a listener to be notified whenever this control is collapsed or expanded; listeners
   * can check the collapsed/expanded state on the control and perform layout changes if need be.
   * @param listener
   */
  public void addTwistieListener(ITwistieListener listener) {
    listeners.add(listener);
  }

  public void removeTwistieListener(ITwistieListener listener) {
    listeners.remove(listener);
  }

  private void notifyTwistieListeners() {
    for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
      ((ITwistieListener) iterator.next()).isCollapsed(isCollapsed());

    }
  }

  /**
   * A listener that intercepts mouseDown events from the control and the title label so we can
   * fire a single event to the listener to signal that the control has been collapsed or expanded.
   *
   *
   * @author knguyen
   *
   */
  private class MouseInterceptor
    extends MouseAdapter
  {

    /*
     * Listens to the mouse click and toggle the isCollapsed flag then force a redraw to update the control
     */
    public void mouseDown(MouseEvent e) {
      isCollapsed = !isCollapsed;
      redraw();
      notifyTwistieListeners();
    }

  }
}
TOP

Related Classes of org.gudy.azureus2.ui.swt.TwistieLabel

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.