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

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

/**
* Sencha GXT 3.0.0 - Sencha for GWT
* Copyright(c) 2007-2012, 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.google.gwt.user.client.Window;
import com.sencha.gxt.cell.core.client.form.FieldCell;
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.Tip;

public class SliderCell extends FieldCell<Integer> {

  public interface HorizontalSliderAppearance extends SliderAppearance {

  }

  public interface SliderAppearance extends FieldAppearance {

    int getClickedValue(Context context, Element parent, NativeEvent event);

    int getSliderLength(XElement parent);

    Element getThumb(Element parent);

    boolean isVertical();

    void onMouseDown(Context context, Element parent, NativeEvent event);

    void onMouseOut(Context context, Element parent, NativeEvent event);

    void onMouseOver(Context context, Element parent, NativeEvent event);

    void onMouseUp(Context context, Element parent, NativeEvent event);

    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 = appearance.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, appearance.getClickedValue(context, p, event.getNativeEvent())));
          valueUpdater.update(v);
          appearance.onMouseUp(context, parent, event.getNativeEvent());
          appearance.onMouseOut(context, parent, event.getNativeEvent());
          tip.hide();
          break;
      }

      return allow;
    }

    private void positionTip(NativeEvent e) {
      Point thumbPosition = appearance.getThumb(parent).<XElement> cast().getPosition(false);

      int x = thumbPosition.getX();
      int y = thumbPosition.getY();

      XElement p = XElement.as(parent);
      int v = setValue(p, reverseValue(p, appearance.getClickedValue(context, p, e)));
      tip.getAppearance().getTextElement(tip.getElement()).setInnerText(onFormatValue(v));

      tip.showAt(-5000, -5000);
      int w = tip.getOffsetWidth();
      int h = tip.getOffsetHeight();

      if (!vertical) {
        boolean top = y > 35;
        if (top) {
          thumbPosition.setX(x - (w / 2) + (thumbWidth / 2));
          thumbPosition.setY(y - h - 5);

        } else {
          thumbPosition.setX(x - (w / 2) + (thumbWidth / 2));
          thumbPosition.setY(y + thumbHeight + 5);
        }
      } else {
        int vleft = Window.getClientWidth();
        boolean right = x < (vleft - 30);
        if (right) {
          thumbPosition.setX(parent.getAbsoluteLeft() + parent.getOffsetWidth() + 5);
          thumbPosition.setY(Math.max(0, y - (h / 2)));
        } else {
          thumbPosition.setX(parent.getAbsoluteLeft() - w - 5);
          thumbPosition.setY(Math.max(0, y - (h / 2)));
        }
      }

      tip.showAt(thumbPosition);
    }

  }

  private SliderAppearance appearance;
  private String message = "{0}";
  private boolean vertical = false;
  private int maxValue = 100;
  private int minValue = 0;
  private final Tip tip = new Tip() {
    protected void onAfterFirstAttach() {
      super.onAfterFirstAttach();
      constrainPosition = false;
    };
  };

  private int increment = 10;

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

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

    vertical = appearance.isVertical();
    tip.setMinWidth(25);

  }

  /**
   * 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;
  }

  @Override
  public void onBrowserEvent(Context context, Element parent, Integer value, NativeEvent event,
      ValueUpdater<Integer> valueUpdater) {
    Element target = event.getEventTarget().cast();
    if (!parent.isOrHasChild(target)) {
      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)) {
      appearance.onMouseOver(context, parent, event);
    } else if ("mouseout".equals(eventType)) {
      appearance.onMouseOut(context, parent, event);
    } 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);
            break;
          }
          case KeyCodes.KEY_RIGHT: {
            int v = setValue(parent, value + increment);
            valueUpdater.update(v);
            break;
          }
        }
      } else {
        switch (key) {
          case KeyCodes.KEY_DOWN: {
            int v = setValue(parent, value - increment);
            valueUpdater.update(v);
            break;
          }
          case KeyCodes.KEY_UP: {
            int v = setValue(parent, value + increment);
            valueUpdater.update(v);
            break;
          }
        }
      }
    }
  }

  @Override
  public void onEmpty(XElement parent, boolean empty) {
    appearance.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);
    }
    appearance.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;
  }

  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;
    if (vertical) {
      int h = appearance.getSliderLength(parent);
      return v == 0 ? h : ((double) h / v);
    } else {
      int w = appearance.getSliderLength(parent);
      return v == 0 ? w : ((double) w / 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 (!appearance.getThumb(parent).isOrHasChild(target)) {
      int value = appearance.getClickedValue(context, parent, event);
      value = reverseValue(parent.<XElement> cast(), value);
      value = normalizeValue(value);

      valueUpdater.update(value);

      int pos = translateValue(parent.<XElement> cast(), value);
      appearance.setThumbPosition(parent, pos);

      return;
    }

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

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

  protected int translateValue(XElement parent, int v) {
    double ratio = getRatio(parent);
    int halfThumb = appearance.getThumb(parent).getOffsetWidth() / 2;
    return (int) ((v * ratio) - (minValue * ratio) - halfThumb);
  }

  private int setValue(Element parent, int value) {
    value = normalizeValue(value);
    int left = translateValue(parent.<XElement> cast(), value);

    appearance.setThumbPosition(parent, left);

    return value;
  }

}
TOP

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

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.