blob: dd6f4362c357713845ab757f3bd7cff0cf573797 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2002, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
****************************************************************************/
package org.eclipse.gmf.runtime.draw2d.ui.figures;
import org.eclipse.draw2d.Border;
import org.eclipse.draw2d.ChangeEvent;
import org.eclipse.draw2d.ChangeListener;
import org.eclipse.draw2d.Clickable;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.draw2d.MouseEvent;
import org.eclipse.draw2d.Panel;
import org.eclipse.draw2d.ScrollBar;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gmf.runtime.draw2d.ui.mapmode.IMapMode;
import org.eclipse.gmf.runtime.draw2d.ui.mapmode.MapModeUtil;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
/**
* Customizes the look of GEF's ScrollBar
*
* @author sshaw
* @author lgrahek
*/
public class ListScrollBar extends ScrollBar {
/**
* @since 1.4
*/
protected ArrowButton downButtonFigure;
/**
* @since 1.4
*/
protected ArrowButton upButtonFigure;
ThumbFigure thumb;
/**
* @since 1.4
*/
protected static Color fillLightGrey = new Color(null, new RGB(240, 240, 240));
/**
* @since 1.4
*/
protected static Color outlineLightGrey = new Color(null, new RGB(185, 185, 185));
/**
* @since 1.4
*/
protected static Color fillDarkGrey = new Color(null, new RGB(84, 84, 84));
/**
* @since 1.4
*/
protected static Color outlineDarkGrey = new Color(null, new RGB(109, 109, 109));
/**
* @since 1.4
*/
protected static Color arrowFill = new Color(null, new RGB(187, 187, 187));
/**
* @since 1.4
*/
protected int mm_1;
/**
* @since 1.4
*/
protected int mm_2;
/**
* Constructor
*
* @param orientation int that is a define from <code>Orientable</code>
* @param insets the <code>Insets> that represents the white space buffer around the scroll bar in
* logical coordinates.
* @param size the <code>Dimension</code> that is the size of the scroll bar end boxes in
* logical coordinates
* @param stepInc the <code>int</code> space to jump when incrementing the scroll bar one step in
* logical coordinates
* @param pageInc the <code>int</code> space to jump when paging the scroll bar up or down in
* logical coordinates.
*/
public ListScrollBar(int orientation, Insets insets, Dimension size, int stepInc, int pageInc) {
setOrientation(orientation);
Border margin = new MarginBorder(insets.top, insets.left, insets.bottom, insets.right);
setBorder(margin);
setPreferredSize(size.width, size.height);
setStepIncrement(stepInc);
setPageIncrement(pageInc);
if (isHorizontal()) {
downButtonFigure.setDirection(EAST);
upButtonFigure.setDirection(WEST);
} else {
downButtonFigure.setDirection(SOUTH);
upButtonFigure.setDirection(NORTH);
}
IMapMode mm= MapModeUtil.getMapMode();
mm_1 = mm.DPtoLP(1);
mm_2 = mm.DPtoLP(2);
}
/* (non-Javadoc)
* @see org.eclipse.draw2d.ScrollBar#createDefaultDownButton()
*/
protected Clickable createDefaultDownButton() {
downButtonFigure = new ArrowButton();
downButtonFigure.setBorder(new MarginBorder(new Insets(mm_1)));
Clickable button = new Clickable(downButtonFigure) {
@Override
public boolean hasFocus() {
return false;
}
};
button.getModel().addChangeListener(new ChangeListener() {
public void handleStateChanged(ChangeEvent event) {
updateDownColors();
}
});
button.setFiringMethod(Clickable.REPEAT_FIRING);
button.setRolloverEnabled(true);
return button;
}
/* (non-Javadoc)
* @see org.eclipse.draw2d.ScrollBar#createDefaultUpButton()
*/
protected Clickable createDefaultUpButton() {
upButtonFigure = new ArrowButton();
upButtonFigure.setBorder(new MarginBorder(new Insets(mm_1)));
Clickable button = new Clickable(upButtonFigure) {
@Override
public boolean hasFocus() {
return false;
}
};
button.getModel().addChangeListener(new ChangeListener() {
public void handleStateChanged(ChangeEvent event) {
updateUpColors();
}
});
button.setFiringMethod(Clickable.REPEAT_FIRING);
button.setRolloverEnabled(true);
return button;
}
/* (non-Javadoc)
* @see org.eclipse.draw2d.ScrollBar#initialize()
*/
protected void initialize() {
super.initialize();
setPageUp(null);
setPageDown(null);
setOpaque(true);
}
/* (non-Javadoc)
* @see org.eclipse.draw2d.ScrollBar#createDefaultThumb()
*/
protected IFigure createDefaultThumb() {
thumbDragger = new ThumbDraggerColors();
thumb = new ThumbFigure();
thumb.setMinimumSize(new Dimension(6, 6));
return thumb;
}
/**
* Updates colors of down button depending on its state (highlighted,
* pressed, or neither)
* @since 1.4
*/
protected void updateDownColors() {
boolean pressed = false;
boolean highlighted = false;
if (getValue() < (getMaximum() - getExtent())) {
// Arrow is scrollable
if (((Clickable) getButtonDown()).getModel().isPressed()) {
pressed = true;
} else if (((Clickable) getButtonDown()).getModel().isMouseOver()) {
highlighted = true;
}
}
boolean doRepaint = false;
if (downButtonFigure.isHighlighted() != highlighted) {
downButtonFigure.setHighlighted(highlighted);
doRepaint = true;
}
if (downButtonFigure.isPressed() != pressed) {
doRepaint = true;
downButtonFigure.setPressed(pressed);
}
if (doRepaint) {
// Just changing color, no recalculation of arrow position needed
downButtonFigure.setRecalculate(false);
downButtonFigure.repaint();
}
}
/**
* Updates colors of up button depending on its state (highlighted,
* pressed, or neither)
* @since 1.4
*/
protected void updateUpColors() {
boolean pressed = false;
boolean highlighted = false;
if (getValue() > getMinimum()) {
// Arrow is scrollable
if (((Clickable) getButtonUp()).getModel().isPressed()) {
pressed = true;
} else if (((Clickable) getButtonUp()).getModel().isMouseOver()) {
highlighted = true;
}
}
boolean doRepaint = false;
if (upButtonFigure.isHighlighted() != highlighted) {
upButtonFigure.setHighlighted(highlighted);
doRepaint = true;
}
if (upButtonFigure.isPressed() != pressed) {
doRepaint = true;
upButtonFigure.setPressed(pressed);
}
if (doRepaint) {
// Just changing color, no recalculation of arrow position needed
upButtonFigure.setRecalculate(false);
upButtonFigure.repaint();
}
}
/**
* Figure that defines the content for up and down buttons
*
* @author lgrahek
*
* @since 1.4
*/
protected class ArrowButton extends Figure
{
private PointList arrow = new PointList();
private boolean recalculate;
private int direction;
private boolean highlighted;
private boolean pressed;
@Override
protected void paintFigure(Graphics g) {
Rectangle r = getBounds();
// If not pressed, fill with white, so later there will be 1px of
// white left around outline.
g.setAlpha(130);
if (!pressed) {
g.setBackgroundColor(ColorConstants.white);
g.fillRectangle(r);
}
// Draw the outline (none when button is pressed)
if (!pressed) {
g.setLineWidth(mm_1);
if (highlighted) {
g.setForegroundColor(outlineDarkGrey);
} else {
g.setForegroundColor(outlineLightGrey);
}
g.drawRectangle(r);
}
// Fill the interior. If not pressed, leave 1px white between outline and filled area.
if (pressed) {
g.setBackgroundColor(fillDarkGrey);
} else {
g.setBackgroundColor(fillLightGrey);
r = r.getCopy().shrink(mm_2, mm_2);
}
g.fillRectangle(r);
// Draw the arrow
if (pressed) {
r = r.getCopy().shrink(mm_2, mm_2);
}
if (recalculate || arrow.size() == 0) {
int size;
switch (direction) {
case EAST:
case WEST:
size = Math.min(r.height / 2, r.width);
r.x += (r.width - size) / 2;
break;
default: //North or south
size = Math.min(r.height, r.width / 2);
r.y += (r.height - size) / 2;
break;
}
size = Math.max(size, 1); //Size cannot be negative
Point head, p2, p3;
switch (direction) {
case NORTH:
head = new Point(r.x + r.width / 2, r.y);
p2 = new Point (head.x - size, head.y + size);
p3 = new Point (head.x + size, head.y + size);
break;
case SOUTH:
head = new Point (r.x + r.width / 2, r.y + size);
p2 = new Point (head.x - size, head.y - size);
p3 = new Point (head.x + size, head.y - size);
break;
case WEST:
head = new Point (r.x, r.y + r.height / 2);
p2 = new Point (head.x + size, head.y - size);
p3 = new Point (head.x + size, head.y + size);
break;
default:
head = new Point(r.x + size, r.y + r.height / 2);
p2 = new Point(head.x - size, head.y - size);
p3 = new Point(head.x - size, head.y + size);
}
arrow.removeAllPoints();
arrow.addPoint(p2);
arrow.addPoint(head);
arrow.addPoint(p3);
} else {
// Recalculating with every paint unless explicitly told not too
recalculate = true;
}
if (highlighted) {
g.setForegroundColor(fillDarkGrey);
} else if (pressed) {
g.setAlpha(255);
g.setForegroundColor(ColorConstants.white);
} else {
g.setForegroundColor(arrowFill);
}
g.setLineWidth(mm_2);
g.drawPolyline(arrow);
}
/**
* @param value
* one of PositionConstants: EAST, WEST, NORTH, SOUTH that
* determine the arrow direction
*/
public void setDirection(int value) {
direction = value;
}
/**
* @param value
* false if arrow points do no have to be recalculated (e.g.
* when just changing color)
*/
public void setRecalculate(boolean value) {
recalculate = value;
}
/**
* @param value true if highlighted, false if not
*/
public void setHighlighted(boolean value) {
highlighted = value;
}
/**
* @return true if highlighted, false if not
*/
public boolean isHighlighted() {
return highlighted;
}
/**
* @param value true if pressed, false if not
*/
public void setPressed(boolean value) {
pressed = value;
}
/**
* @return true if pressed
*/
public boolean isPressed() {
return pressed;
}
}
/**
* Figure that defines scroll bar thumb.
*
* @author lgrahek
*
* @since 1.4
*/
protected class ThumbFigure extends Panel {
boolean highlighted;
boolean pressed;
@Override
protected void paintFigure(Graphics g) {
g.setAlpha(130);
Rectangle r = getBounds().getCopy();
// Fill with white, so later there will be 1px of
// white left around outline.
g.setBackgroundColor(ColorConstants.white);
g.fillRectangle(getBounds());
// Draw the outline (none when button is pressed)
g.setLineWidth(mm_1);
if (highlighted || pressed) {
g.setForegroundColor(outlineDarkGrey);
} else {
g.setForegroundColor(outlineLightGrey);
}
g.drawRectangle(r);
// Fill the interior, while leaving 1px white between outline and filled area.
r = r.getCopy().shrink(mm_2, mm_2);
if (pressed) {
g.setBackgroundColor(fillDarkGrey);
} else {
g.setBackgroundColor(fillLightGrey);
}
g.fillRectangle(r);
}
/**
* @param value true if highlighted, false if not
*/
public void setHighlighted(boolean value) {
highlighted = value;
}
/**
* @return true if highlighted, false if not
*/
public boolean isHighlighted() {
return highlighted;
}
/**
* @param value true if pressed, false if not
*/
public void setPressed(boolean value) {
pressed = value;
}
/**
* @return true if pressed
*/
public boolean isPressed() {
return pressed;
}
}
/**
* Customizes ThumbDragger to set different colors to thumb depending on its
* state.
*
* @author lgrahek
*
* @since 1.4
*/
protected class ThumbDraggerColors extends ThumbDragger {
/* (non-Javadoc)
* @see org.eclipse.draw2d.MouseMotionListener.Stub#mouseEntered(org.eclipse.draw2d.MouseEvent)
*/
@Override
public void mouseEntered(MouseEvent me) {
// Set up highlight colors
thumb.setHighlighted(true);
thumb.setPressed(false);
thumb.repaint();
super.mouseEntered(me);
}
/* (non-Javadoc)
* @see org.eclipse.draw2d.MouseMotionListener.Stub#mouseExited(org.eclipse.draw2d.MouseEvent)
*/
@Override
public void mouseExited(MouseEvent me) {
// Set up colors: back to no-hover, no-drag colors
thumb.setHighlighted(false);
thumb.setPressed(false);
thumb.repaint();
super.mouseExited(me);
}
/* (non-Javadoc)
* @see org.eclipse.draw2d.ScrollBar.ThumbDragger#mousePressed(org.eclipse.draw2d.MouseEvent)
*/
@Override
public void mousePressed(MouseEvent me) {
// Set up pressed colors
thumb.setHighlighted(false);
thumb.setPressed(true);
thumb.repaint();
super.mousePressed(me);
}
/* (non-Javadoc)
* @see org.eclipse.draw2d.ScrollBar.ThumbDragger#mouseReleased(org.eclipse.draw2d.MouseEvent)
*/
@Override
public void mouseReleased(MouseEvent me) {
// Set up colors: back to hover
thumb.setHighlighted(true);
thumb.setPressed(false);
thumb.repaint();
super.mouseReleased(me);
}
}
}