Package com.sencha.gxt.cell.core.client

Source Code of com.sencha.gxt.cell.core.client.SliderCell$ToolTipExt

/**
* Sencha GXT 3.1.0-beta - Sencha for GWT
* Copyright(c) 2007-2014, Sencha, Inc.
* licensing@sencha.com
*
* http://www.sencha.com/products/gxt/license/
*/
package com.sencha.gxt.cell.core.client;

import com.google.gwt.cell.client.ValueUpdater;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Event.NativePreviewEvent;
import com.sencha.gxt.cell.core.client.form.FieldCell;
import com.sencha.gxt.core.client.Style.Side;
import com.sencha.gxt.core.client.dom.XElement;
import com.sencha.gxt.core.client.util.BaseEventPreview;
import com.sencha.gxt.core.client.util.Format;
import com.sencha.gxt.core.client.util.Point;
import com.sencha.gxt.core.client.util.Util;
import com.sencha.gxt.widget.core.client.tips.ToolTip;
import com.sencha.gxt.widget.core.client.tips.ToolTipConfig;

public class SliderCell extends FieldCell<Integer> {

  public interface HorizontalSliderAppearance extends SliderAppearance {
  }

  public interface SliderAppearance extends FieldAppearance {

    int getClickedValue(Context context, Element parent, Point location);

    int getSliderLength(XElement parent);

    Element getThumb(Element parent);

    boolean isVertical();

    void onMouseDown(Context context, Element parent);

    void onMouseOut(Context context, Element parent);

    void onMouseOver(Context context, Element parent);

    void onMouseUp(Context context, Element parent);

    void render(double fractionalValue, int width, int height, SafeHtmlBuilder sb);

    void setThumbPosition(Element parent, int left);

  }

  public interface VerticalSliderAppearance extends SliderAppearance {
  }

  protected class DragPreview extends BaseEventPreview {

    private final Context context;
    private final Element parent;
    private int thumbWidth;
    private int thumbHeight;

    private final ValueUpdater<Integer> valueUpdater;

    public DragPreview(Context context, Element parent, ValueUpdater<Integer> valueUpdater, NativeEvent e) {
      super();
      this.context = context;
      this.parent = parent;
      this.valueUpdater = valueUpdater;

      XElement t = getAppearance().getThumb(parent).cast();
      thumbWidth = t.getOffsetWidth();
      thumbHeight = t.getOffsetHeight();

      positionTip(e);
    }

    @Override
    protected boolean onPreview(NativePreviewEvent event) {
      boolean allow = super.onPreview(event);

      switch (event.getTypeInt()) {
        case Event.ONMOUSEMOVE:
          positionTip(event.getNativeEvent());
          break;
        case Event.ONMOUSEUP:
          this.remove();
          XElement p = XElement.as(parent);
          int v = setValue(p, reverseValue(p, getAppearance().getClickedValue(context, p, new Point(event.getNativeEvent().getClientX(), event.getNativeEvent().getClientY()))));
          valueUpdater.update(v);
          getAppearance().onMouseUp(context, parent);
          getAppearance().onMouseOut(context, parent);
          tip.hide();
          break;
      }

      return allow;
    }

    private void positionTip(NativeEvent event) {
      if (!showMessage) {
        return;
      }

      XElement p = XElement.as(parent);
      int v = setValue(p, reverseValue(p, getAppearance().getClickedValue(context, p, new Point(event.getClientX(), event.getClientY()))));
      Element thumb = getAppearance().getThumb(parent);
      tip.setToolTipConfig(toolTipConfig);
      tip.setText(onFormatValue(v));

      if (!tip.isAttached()) {
        tip.onMouseMove(thumbWidth, thumbHeight, thumb);
      }
      tip.onMouseMove(thumbWidth, thumbHeight, thumb);
    }

  }

  private class ToolTipExt extends ToolTip {
    public ToolTipExt(ToolTipConfig config) {
      super(config);
    }

    public void setText(String text) {
      bodyHtml = text;
    }

    public void onMouseMove(int thumbWidth, int thumbHeight, Element target) {
      this.target = target;
      Side origAnchor = toolTipConfig.getAnchor();
      Point p = getTargetXY(0);
      p.setX(p.getX() - (thumbWidth / 2));
      p.setY(p.getY() - (thumbHeight / 2));
      super.showAt(p.getX(), p.getY());
      toolTipConfig.setAnchor(origAnchor);
    }
  }

  private String message = "{0}";
  private boolean showMessage = true;
  private boolean vertical = false;
  private int maxValue = 100;
  private int minValue = 0;
  private ToolTipExt tip;
  private ToolTipConfig toolTipConfig;
  private int increment = 10;

  public SliderCell() {
    this(GWT.<SliderAppearance>create(SliderAppearance.class));
  }

  public SliderCell(SliderAppearance appearance) {
    super(appearance, "mousedown", "mouseover", "mouseout", "keydown");

    vertical = appearance.isVertical();

    toolTipConfig = new ToolTipConfig();
    toolTipConfig.setAnchorArrow(false);
    toolTipConfig.setMaxWidth(25);
    toolTipConfig.setDismissDelay(1000);
    if (vertical) {
      toolTipConfig.setAnchor(Side.LEFT);
      toolTipConfig.setMouseOffsetX(25);
      toolTipConfig.setMouseOffsetY(0);
    } else {
      toolTipConfig.setAnchor(Side.TOP);
      toolTipConfig.setMouseOffsetX(0);
      toolTipConfig.setMouseOffsetY(25);
    }

    tip = new ToolTipExt(toolTipConfig);
  }

  @Override
  public SliderAppearance getAppearance() {
    return (SliderAppearance) super.getAppearance();
  }

  /**
   * Returns the increment.
   *
   * @return the increment
   */
  public int getIncrement() {
    return increment;
  }

  /**
   * Returns the max value (defaults to 100).
   *
   * @return the max value
   */
  public int getMaxValue() {
    return maxValue;
  }

  /**
   * Returns the tool tip message.
   *
   * @return the tool tip message
   */
  public String getMessage() {
    return message;
  }

  /**
   * Returns the minimum value (defaults to 0).
   *
   * @return the minimum value
   */
  public int getMinValue() {
    return minValue;
  }

  /**
   * Returns true if the tool tip message is shown
   *
   * @return the showMessage state
   */
  public boolean isShowMessage() {
    return showMessage;
  }

  @Override
  public void onBrowserEvent(Context context, Element parent, Integer value, NativeEvent event,
      ValueUpdater<Integer> valueUpdater) {
    Element target = event.getEventTarget().cast();
    if (!parent.isOrHasChild(target) || isDisabled()) {
      return;
    }
    super.onBrowserEvent(context, parent, value, event, valueUpdater);

    String eventType = event.getType();

    if ("mousedown".equals(eventType)) {
      onMouseDown(context, parent, event, valueUpdater);
    } else if ("mouseover".equals(eventType)) {
      getAppearance().onMouseOver(context, parent);
    } else if ("mouseout".equals(eventType)) {
      getAppearance().onMouseOut(context, parent);
    } else if ("keydown".equals(eventType)) {
      int key = event.getKeyCode();
      if (!vertical) {
        switch (key) {
          case KeyCodes.KEY_LEFT:
            int v = setValue(parent, value - increment);
            valueUpdater.update(v);
            positionTip(parent, v);
            break;
          case KeyCodes.KEY_RIGHT:
            v = setValue(parent, value + increment);
            valueUpdater.update(v);
            positionTip(parent, v);
            break;
        }
      } else {
        switch (key) {
          case KeyCodes.KEY_DOWN:
            int v = setValue(parent, value - increment);
            valueUpdater.update(v);
            positionTip(parent, v);
            break;
          case KeyCodes.KEY_UP:
            v = setValue(parent, value + increment);
            valueUpdater.update(v);
            positionTip(parent, v);
            break;
        }
      }
    }
  }

  private void positionTip(Element parent, int v) {
    if (!showMessage) {
      return;
    }
    Element thumb = getAppearance().getThumb(parent);

    XElement t = thumb.cast();
    int thumbWidth = t.getOffsetWidth();
    int thumbHeight = t.getOffsetHeight();

    toolTipConfig.setAutoHide(true);
    tip.setToolTipConfig(toolTipConfig);
    tip.setText(onFormatValue(v));

    if (!tip.isAttached()) {
      tip.onMouseMove(thumbWidth, thumbHeight, thumb);
    }
    tip.onMouseMove(thumbWidth, thumbHeight, thumb);
  }

  @Override
  public void onEmpty(XElement parent, boolean empty) {
    getAppearance().onEmpty(parent, empty);
  }

  @Override
  public boolean redrawOnResize() {
    return true;
  }

  @Override
  public void render(Context context, Integer value, SafeHtmlBuilder sb) {
    double fractionalValue;
    if (value == null) {
      fractionalValue = 0.5;
    } else {
      fractionalValue = 1.0 * (value - minValue) / (maxValue - minValue);
    }
    getAppearance().render(fractionalValue, getWidth(), getHeight(), sb);
  }

  /**
   * How many units to change the slider when adjusting by drag and drop. Use this option to enable 'snapping' (default
   * to 10).
   *
   * @param increment the increment
   */
  public void setIncrement(int increment) {
    this.increment = increment;
  }

  /**
   * Sets the max value (defaults to 100).
   *
   * @param maxValue the max value
   */
  public void setMaxValue(int maxValue) {
    this.maxValue = maxValue;
  }

  /**
   * Sets the tool tip message (defaults to '{0}'). "{0} will be substituted with the current slider value.
   *
   * @param message the tool tip message
   */
  public void setMessage(String message) {
    this.message = message;
  }

  /**
   * Sets the minimum value (defaults to 0).
   *
   * @param minValue the minimum value
   */
  public void setMinValue(int minValue) {
    this.minValue = minValue;
  }

  /**
   * Sets if the tool tip message should be displayed (defaults to true, pre-render).
   *
   * @param showMessage true to show tool tip message
   */
  public void setShowMessage(boolean showMessage) {
    this.showMessage = showMessage;
  }

  /**
   * Set the tooltip config. This is the tooltip for the message configuration. Set {@link #setShowMessage(boolean)} to
   * true to use this feature.
   * <p/>
   * {@link ToolTipConfig#setAnchor(com.sencha.gxt.core.client.Style.Side)} is a required setting for toolTipConfig.
   *
   * @param toolTipConfig is the tooltip configuration.
   */
  public void setToolTipConfig(ToolTipConfig toolTipConfig) {
    assert toolTipConfig != null : "The toolTipConfig parameter is null and it is required.";
    assert toolTipConfig.getAnchor() != null : "The toolTipConfig must have an anchor Side set. "
        + "Like toolTipConfig.setAnchor(Side.RIGHT);";
    this.toolTipConfig = toolTipConfig;
  }

  protected int constrain(int value) {
    return Util.constrain(value, minValue, maxValue);
  }

  protected int doSnap(int v) {
    if (increment == 1) {
      return v;
    }
    int m = v % increment;
    if (m != 0) {
      v -= m;
      if (m * 2 > increment) {
        v += increment;
      } else if (m * 2 < -increment) {
        v -= increment;
      }
    }
    return v;
  }

  protected double getRatio(XElement parent) {
    int v = maxValue - minValue;
    int length = getAppearance().getSliderLength(parent);
    return v == 0 ? length : ((double) length / v);
  }

  protected int normalizeValue(int value) {
    value = doSnap(value);
    value = constrain(value);
    return value;
  }

  protected String onFormatValue(int value) {
    return Format.substitute(getMessage(), value);
  }

  protected void onMouseDown(final Context context, final Element parent, NativeEvent event,
      final ValueUpdater<Integer> valueUpdater) {
    Element target = Element.as(event.getEventTarget());
    if (!getAppearance().getThumb(parent).isOrHasChild(target)) {
      int value = getAppearance().getClickedValue(context, parent, new Point(event.getClientX(), event.getClientY()));
      value = reverseValue(parent.<XElement> cast(), value);
      value = normalizeValue(value);
      valueUpdater.update(value);
      return;
    }

    BaseEventPreview preview = new DragPreview(context, parent, valueUpdater, event);
    getAppearance().onMouseDown(context, parent);
    preview.add();
  }

  protected int reverseValue(XElement parent, int pos) {
    double ratio = getRatio(parent);
    if (vertical) {
      int length = getAppearance().getSliderLength(parent);
      return (int) (((minValue * ratio) + length - pos) / ratio);
    } else {
      int halfThumb = getAppearance().getThumb(parent).getOffsetWidth() / 2;
      return (int) ((pos + halfThumb + (minValue * ratio)) / ratio);
    }
  }

  protected int translateValue(XElement parent, int v) {
    int halfThumb;
    if (vertical) {
      halfThumb = getAppearance().getThumb(parent).getOffsetHeight() / 2;
    } else {
      halfThumb = getAppearance().getThumb(parent).getOffsetWidth() / 2;
    }

    double ratio = getRatio(parent);

    return (int) ((v * ratio) - (minValue * ratio) - halfThumb);
  }

  private int setValue(Element parent, int value) {
    value = normalizeValue(value);

    // move thumb
    int pos = translateValue(parent.<XElement> cast(), value);
    getAppearance().setThumbPosition(parent, pos);

    return value;
  }

}
TOP

Related Classes of com.sencha.gxt.cell.core.client.SliderCell$ToolTipExt

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.