Hi all,
If you want a fancy slider with all the trimmings, use the one here:
http://code.google.com/p/google-web-toolkit-incubator/wiki/SliderBar
If you want a simple one, without needing css, abstract images,
without all the labels, ticks, key handlers, and works in the
UiBinder... Here is the code.
Big thanks to the good folks that did the fancy one (that's where this
code is derived from)
Enjoy.
===============
import java.util.ArrayList;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.Image;
/**
* <p>A widget that allows the user to select a value within a range
of possible
* values using a sliding bar that responds to mouse events.</p>
*
* <p>You need to set the three images, knobNormal, knobDisabled, and
knobSliding</p>
*
* <p>Original code from {...@link
http://code.google.com/p/google-web-toolkit-incubator/wiki/SliderBar}</p>
*
* <p>Modifications:
* <li>Stripped out all key handlers, css, and abstract images.
* <li>Upgraded to use ChangeHandlers
* </p>
*
* <p>
* <h3>Example usage with UIBinder</h3>
* <code>
* <p><ui:UiBinder ... xmlns:m="urn:import:mypackage"></p>
* <p><ui:with field="res" type="MyResources" /></p>
* <p>...</p>
* <p><m:SliderBar
* ui:field="mySlider"
* knobNormal="{res.mySliderNormalImageResource}"
* knobDisabled="{res.mySliderDisabledImageResource}"
* knobSliding="{res.mySliderSlidingImageResource}"/>
* </p>
* </code>
*
* @author Google (original)
* @author Craig Mitchell
* @since 07/01/2011
*/
public class SliderBar extends FocusPanel {
/**
* The change listeners.
*/
private ArrayList<ChangeHandler> changeHandlers = null;
/**
* The current value.
*/
private double curValue;
/**
* The knob that slides across the line.
*/
private Image knobImage;
/**
* The know image resources
*/
private ImageResource knobNormal;
private ImageResource knobDisabled;
private ImageResource knobSliding;
/**
* The line that the knob moves over.
*/
private Element lineElement;
/**
* The offset between the edge of the shell and the line.
*/
private int lineLeftOffset = 0;
/**
* The maximum slider value.
*/
private double maxValue;
/**
* The minimum slider value.
*/
private double minValue;
/**
* A bit indicating whether or not we are currently sliding the
slider bar due
* to mouse events.
*/
private boolean slidingMouse = false;
/**
* A bit indicating whether or not the slider is enabled
*/
private boolean enabled = true;
/**
* The size of the increments between knob positions.
*/
private double stepSize;
/**
* Constructor
*/
public SliderBar() {
super();
// Create the outer shell
DOM.setStyleAttribute(getElement(), "position", "relative");
// Create the line
lineElement = DOM.createDiv();
DOM.appendChild(getElement(), lineElement);
DOM.setStyleAttribute(lineElement, "position", "absolute");
DOM.setStyleAttribute(lineElement, "border", "1px solid black");
DOM.setStyleAttribute(lineElement, "height", "4px");
DOM.setStyleAttribute(lineElement, "width", "90%");
DOM.setStyleAttribute(lineElement, "top", "8px");
DOM.setStyleAttribute(lineElement, "overflow", "hidden");
sinkEvents(Event.MOUSEEVENTS | Event.FOCUSEVENTS);
}
public void setKnobNormal(ImageResource knobNormal) {
this.knobNormal = knobNormal;
// Create the knob
if (knobImage == null) {
knobImage = new Image(knobNormal);
Element knobElement = knobImage.getElement();
DOM.appendChild(getElement(), knobElement);
DOM.setStyleAttribute(knobElement, "position",
"absolute");
DOM.setStyleAttribute(knobElement, "cursor", "pointer");
// Initialise our size
setSize("100%", knobImage.getHeight()+"px");
}
}
public void setKnobDisabled(ImageResource knobDisabled) {
this.knobDisabled = knobDisabled;
}
public void setKnobSliding(ImageResource knobSliding) {
this.knobSliding = knobSliding;
}
/**
* Add a change listener to this SliderBar.
*
* @param listener the listener to add
*/
public void addChangeHandler(ChangeHandler listener) {
if (changeHandlers == null) {
changeHandlers = new ArrayList<ChangeHandler>();
}
changeHandlers.add(listener);
}
/**
* Return the current value.
*
* @return the current value
*/
public double getCurrentValue() {
return curValue;
}
/**
* Return the max value.
*
* @return the max value
*/
public double getMaxValue() {
return maxValue;
}
/**
* Return the minimum value.
*
* @return the minimum value
*/
public double getMinValue() {
return minValue;
}
/**
* Return the step size.
*
* @return the step size
*/
public double getStepSize() {
return stepSize;
}
/**
* Return the total range between the minimum and maximum values.
*
* @return the total range
*/
public double getTotalRange() {
if (minValue > maxValue) {
return 0;
} else {
return maxValue - minValue;
}
}
/**
* @return Gets whether this widget is enabled
*/
public boolean isEnabled() {
return enabled;
}
/**
* Listen for events that will move the knob.
*
* @param event the event that occurred
*/
@Override
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
if (enabled) {
switch (DOM.eventGetType(event)) {
// Unhighlight and cancel keyboard events
case Event.ONBLUR:
if (slidingMouse) {
DOM.releaseCapture(getElement());
slidingMouse = false;
slideKnob(event);
stopSliding(true, true);
}
unhighlight();
break;
// Highlight on focus
case Event.ONFOCUS:
highlight();
break;
// Mousewheel events
case Event.ONMOUSEWHEEL:
int velocityY =
DOM.eventGetMouseWheelVelocityY(event);
DOM.eventPreventDefault(event);
if (velocityY > 0) {
shiftRight(1);
} else {
shiftLeft(1);
}
break;
// Mouse Events
case Event.ONMOUSEDOWN:
setFocus(true);
slidingMouse = true;
DOM.setCapture(getElement());
startSliding(true, true);
DOM.eventPreventDefault(event);
slideKnob(event);
break;
case Event.ONMOUSEUP:
if (slidingMouse) {
DOM.releaseCapture(getElement());
slidingMouse = false;
slideKnob(event);
stopSliding(true, true);
}
break;
case Event.ONMOUSEMOVE:
if (slidingMouse) {
slideKnob(event);
}
break;
}
}
}
/**
* This method is called when the dimensions of the parent element
change.
* Subclasses should override this method as needed.
*
* @param width the new client width of the element
* @param height the new client height of the element
*/
public void onResize(int width, int height) {
// Center the line in the shell
int lineWidth = DOM.getElementPropertyInt(lineElement,
"offsetWidth");
lineLeftOffset = (width / 2) - (lineWidth / 2);
DOM.setStyleAttribute(lineElement, "left", lineLeftOffset +
"px");
// Draw the other components
drawKnob();
}
/**
* Redraw the progress bar when something changes the layout.
*/
public void redraw() {
if (isAttached()) {
int width = DOM.getElementPropertyInt(getElement(),
"clientWidth");
int height = DOM.getElementPropertyInt(getElement(),
"clientHeight");
onResize(width, height);
}
}
/**
* Remove a change listener from this SliderBar.
*
* @param listener the listener to remove
*/
public void removeChangeHandler(ChangeHandler listener) {
if (changeHandlers != null) {
changeHandlers.remove(listener);
}
}
/**
* Set the current value and fire the onValueChange event.
*
* @param curValue the current value
*/
public void setCurrentValue(double curValue) {
setCurrentValue(curValue, true);
}
/**
* Set the current value and optionally fire the onValueChange event.
*
* @param curValue the current value
* @param fireEvent fire the onValue change event if true
*/
public void setCurrentValue(double curValue, boolean fireEvent) {
// Confine the value to the range
this.curValue = Math.max(minValue, Math.min(maxValue,
curValue));
double remainder = (this.curValue - minValue) % stepSize;
this.curValue -= remainder;
// Go to next step if more than halfway there
if ((remainder > (stepSize / 2))
&& ((this.curValue + stepSize) <= maxValue)) {
this.curValue += stepSize;
}
// Redraw the knob
drawKnob();
// Fire the onValueChange event
if (fireEvent && (changeHandlers != null)) {
for (ChangeHandler changeHandler : changeHandlers) {
changeHandler.onChange(null);
}
}
}
/**
* Sets whether this widget is enabled.
*
* @param enabled true to enable the widget, false to disable it
*/
public void setEnabled(boolean enabled) {
this.enabled = enabled;
if (enabled) {
knobImage.setResource(knobNormal);
} else {
knobImage.setResource(knobDisabled);
}
redraw();
}
/**
* Set the max value.
*
* @param maxValue the current value
*/
public void setMaxValue(double maxValue) {
this.maxValue = maxValue;
resetCurrentValue();
}
/**
* Set the minimum value.
*
* @param minValue the current value
*/
public void setMinValue(double minValue) {
this.minValue = minValue;
resetCurrentValue();
}
/**
* Set the step size.
*
* @param stepSize the current value
*/
public void setStepSize(double stepSize) {
this.stepSize = stepSize;
resetCurrentValue();
}
/**
* Shift to the left (smaller value).
*
* @param numSteps the number of steps to shift
*/
public void shiftLeft(int numSteps) {
setCurrentValue(getCurrentValue() - numSteps * stepSize);
}
/**
* Shift to the right (greater value).
*
* @param numSteps the number of steps to shift
*/
public void shiftRight(int numSteps) {
setCurrentValue(getCurrentValue() + numSteps * stepSize);
}
/**
* Get the percentage of the knob's position relative to the size of
the line.
* The return value will be between 0.0 and 1.0.
*
* @return the current percent complete
*/
protected double getKnobPercent() {
// If we have no range
if (maxValue <= minValue) {
return 0;
}
// Calculate the relative progress
double percent = (curValue - minValue) / (maxValue - minValue);
return Math.max(0.0, Math.min(1.0, percent));
}
/**
* This method is called immediately after a widget becomes attached
to the
* browser's document.
*/
@Override
protected void onLoad() {
// Reset the position attribute of the parent element
DOM.setStyleAttribute(getElement(), "position", "relative");
redraw();
}
@Override
protected void onUnload() {
}
/**
* Draw the knob where it is supposed to be relative to the line.
*/
private void drawKnob() {
// Abort if not attached
if (!isAttached()) {
return;
}
// Move the knob to the correct position
Element knobElement = knobImage.getElement();
int lineWidth = DOM.getElementPropertyInt(lineElement,
"offsetWidth");
int knobWidth = DOM.getElementPropertyInt(knobElement,
"offsetWidth");
int knobLeftOffset = (int) (lineLeftOffset + (getKnobPercent() *
lineWidth) - (knobWidth / 2));
knobLeftOffset = Math.min(knobLeftOffset, lineLeftOffset +
lineWidth
- (knobWidth / 2) - 1);
DOM.setStyleAttribute(knobElement, "left", knobLeftOffset +
"px");
}
/**
* Highlight this widget.
*/
private void highlight() {
String styleName = getStylePrimaryName();
DOM.setElementProperty(getElement(), "className", styleName + "
"
+ styleName + "-focused");
}
/**
* Reset the progress to constrain the progress to the current range
and
* redraw the knob as needed.
*/
private void resetCurrentValue() {
setCurrentValue(getCurrentValue());
}
/**
* Slide the knob to a new location.
*
* @param event the mouse event
*/
private void slideKnob(Event event) {
int x = DOM.eventGetClientX(event);
if (x > 0) {
int lineWidth = DOM.getElementPropertyInt(lineElement,
"offsetWidth");
int lineLeft = DOM.getAbsoluteLeft(lineElement);
double percent = (double) (x - lineLeft) / lineWidth *
1.0;
setCurrentValue(getTotalRange() * percent + minValue,
true);
}
}
/**
* Start sliding the knob.
*
* @param highlight true to change the style
* @param fireEvent true to fire the event
*/
private void startSliding(boolean highlight, boolean fireEvent) {
if (highlight) {
DOM.setStyleAttribute(lineElement, "backgroundColor",
"#DDDDDD");
knobImage.setResource(knobSliding);
}
}
/**
* Stop sliding the knob.
*
* @param unhighlight true to change the style
* @param fireEvent true to fire the event
*/
private void stopSliding(boolean unhighlight, boolean fireEvent) {
if (unhighlight) {
DOM.setStyleAttribute(lineElement, "backgroundColor",
"white");
knobImage.setResource(knobNormal);
}
}
/**
* Unhighlight this widget.
*/
private void unhighlight() {
DOM.setElementProperty(getElement(), "className",
getStylePrimaryName());
}
}
--
You received this message because you are subscribed to the Google Groups
"Google Web Toolkit" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-web-toolkit?hl=en.