001package org.gwtbootstrap3.extras.slider.client.ui.base;
002
003/*
004 * #%L
005 * GwtBootstrap3
006 * %%
007 * Copyright (C) 2013 - 2015 GwtBootstrap3
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 * 
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 * 
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import java.util.ArrayList;
024import java.util.Collections;
025import java.util.List;
026
027import org.gwtbootstrap3.client.ui.base.HasId;
028import org.gwtbootstrap3.client.ui.base.HasResponsiveness;
029import org.gwtbootstrap3.client.ui.base.helper.StyleHelper;
030import org.gwtbootstrap3.client.ui.base.mixin.AttributeMixin;
031import org.gwtbootstrap3.client.ui.constants.DeviceSize;
032import org.gwtbootstrap3.extras.slider.client.ui.base.constants.HandleType;
033import org.gwtbootstrap3.extras.slider.client.ui.base.constants.OrientationType;
034import org.gwtbootstrap3.extras.slider.client.ui.base.constants.ScaleType;
035import org.gwtbootstrap3.extras.slider.client.ui.base.constants.SelectionType;
036import org.gwtbootstrap3.extras.slider.client.ui.base.constants.TooltipPosition;
037import org.gwtbootstrap3.extras.slider.client.ui.base.constants.TooltipType;
038import org.gwtbootstrap3.extras.slider.client.ui.base.event.HasAllSlideHandlers;
039import org.gwtbootstrap3.extras.slider.client.ui.base.event.SlideDisabledEvent;
040import org.gwtbootstrap3.extras.slider.client.ui.base.event.SlideDisabledHandler;
041import org.gwtbootstrap3.extras.slider.client.ui.base.event.SlideEnabledEvent;
042import org.gwtbootstrap3.extras.slider.client.ui.base.event.SlideEnabledHandler;
043import org.gwtbootstrap3.extras.slider.client.ui.base.event.SlideEvent;
044import org.gwtbootstrap3.extras.slider.client.ui.base.event.SlideHandler;
045import org.gwtbootstrap3.extras.slider.client.ui.base.event.SlideStartEvent;
046import org.gwtbootstrap3.extras.slider.client.ui.base.event.SlideStartHandler;
047import org.gwtbootstrap3.extras.slider.client.ui.base.event.SlideStopEvent;
048import org.gwtbootstrap3.extras.slider.client.ui.base.event.SlideStopHandler;
049
050import com.google.gwt.core.client.JavaScriptObject;
051import com.google.gwt.core.client.JsArrayNumber;
052import com.google.gwt.core.client.JsArrayString;
053import com.google.gwt.core.client.JsonUtils;
054import com.google.gwt.dom.client.Document;
055import com.google.gwt.dom.client.Element;
056import com.google.gwt.editor.client.IsEditor;
057import com.google.gwt.editor.client.LeafValueEditor;
058import com.google.gwt.editor.client.adapters.TakesValueEditor;
059import com.google.gwt.event.logical.shared.ValueChangeEvent;
060import com.google.gwt.event.logical.shared.ValueChangeHandler;
061import com.google.gwt.event.shared.HandlerRegistration;
062import com.google.gwt.user.client.Event;
063import com.google.gwt.user.client.ui.HasEnabled;
064import com.google.gwt.user.client.ui.HasValue;
065import com.google.gwt.user.client.ui.Widget;
066
067/**
068 *
069 *
070 * @param <T> slider value type
071 *
072 * @see https://github.com/seiyria/bootstrap-slider
073 * @author Xiaodong Sun
074 */
075public abstract class SliderBase<T> extends Widget implements
076        HasValue<T>, IsEditor<LeafValueEditor<T>>, HasEnabled, HasId,
077        HasResponsiveness, HasAllSlideHandlers<T> {
078
079    private FormatterCallback<T> formatterCallback;
080    private LeafValueEditor<T> editor;
081    private boolean sliderNamespaceAvailable = true;
082
083    private final AttributeMixin<SliderBase<T>> attributeMixin = new AttributeMixin<SliderBase<T>>(this);
084
085    protected SliderBase() {
086        setElement(Document.get().createTextInputElement());
087    }
088
089    @Override
090    protected void onLoad() {
091        super.onLoad();
092        final JavaScriptObject options = JavaScriptObject.createObject();
093        if (formatterCallback != null) {
094            setFormatterOption(options);
095        }
096        sliderNamespaceAvailable = isSliderNamespaceAvailable();
097        initSlider(getElement(), options);
098        bindSliderEvents(getElement());
099    }
100
101    /**
102     * Sets formatter option if defined when attaching to the DOM.
103     *
104     * @param options
105     */
106    protected abstract void setFormatterOption(JavaScriptObject options);
107
108    @Override
109    protected void onUnload() {
110        super.onUnload();
111        unbindSliderEvents(getElement());
112        sliderCommand(getElement(), SliderCommand.DESTROY);
113    }
114
115    /**
116     * Sets the id of the slider element when it's created.
117     */
118    @Override
119    public void setId(final String id) {
120        updateSlider(SliderOption.ID, id);
121    }
122
123    @Override
124    public String getId() {
125        return getStringAttribute(SliderOption.ID);
126    }
127
128    public double getMin() {
129        return getDoubleAttribute(SliderOption.MIN, 0);
130    }
131
132    /**
133     * Sets the minimum possible value.
134     *
135     * @param min
136     */
137    public void setMin(final double min) {
138        updateSlider(SliderOption.MIN, min);
139    }
140
141    public double getMax() {
142        return getDoubleAttribute(SliderOption.MAX, 10);
143    }
144
145    /**
146     * Sets the maximum possible value.
147     *
148     * @param max
149     */
150    public void setMax(final double max) {
151        updateSlider(SliderOption.MAX, max);
152    }
153
154    public double getStep() {
155        return getDoubleAttribute(SliderOption.STEP, 1);
156    }
157
158    /**
159     * Sets the increment step.
160     *
161     * @param step
162     */
163    public void setStep(final double step) {
164        updateSlider(SliderOption.STEP, step);
165    }
166
167    public double getPrecision() {
168        return getDoubleAttribute(SliderOption.PRECISION, 0);
169    }
170
171    /**
172     * Sets the number of digits shown after the decimal.<br>
173     * <br>
174     * Defaults to the number of digits after the decimal of step value.
175     *
176     * @param precision
177     */
178    public void setPrecision(final double precision) {
179        updateSlider(SliderOption.PRECISION, precision);
180    }
181
182    public OrientationType getOrientation() {
183        return getEnumAttribute(SliderOption.ORIENTATION, OrientationType.class, OrientationType.HORIZONTAL);
184    }
185
186    /**
187     * Sets the orientation.
188     *
189     * @param orientation
190     * @see OrientationType
191     */
192    public void setOrientation(final OrientationType orientation) {
193        updateSlider(SliderOption.ORIENTATION, orientation.getType());
194    }
195
196    protected boolean isRange() {
197        return getBooleanAttribute(SliderOption.RANGE, false);
198    }
199
200    /**
201     * Make range slider if set to <code>true</code>. If initial value is scalar,
202     * max will be used for second value.
203     *
204     * @param range
205     */
206    protected void setRange(final boolean range) {
207        updateSlider(SliderOption.RANGE, range);
208    }
209
210    public SelectionType getSelection() {
211        return getEnumAttribute(SliderOption.SELECTION, SelectionType.class, SelectionType.BEFORE);
212    }
213
214    /**
215     * Sets the selection type.
216     *
217     * @param selection
218     * @see SelectionType
219     */
220    public void setSelection(final SelectionType selection) {
221        updateSlider(SliderOption.SELECTION, selection.getType());
222    }
223
224    public TooltipType getTooltip() {
225        return getEnumAttribute(SliderOption.TOOLTIP, TooltipType.class, TooltipType.SHOW);
226    }
227
228    /**
229     * Sets the tool-tip type.
230     *
231     * @param tooltip
232     * @see TooltipType
233     */
234    public void setTooltip(final TooltipType tooltip) {
235        updateSlider(SliderOption.TOOLTIP, tooltip.getType());
236    }
237
238    public boolean isTooltipSplit() {
239        return getBooleanAttribute(SliderOption.TOOLTIP_SPLIT, false);
240    }
241
242    /**
243     * Show one too-tip if set to <code>false</code>, otherwise
244     * show two tool-tips one for each handler.
245     *
246     * @param tooltipSplit
247     */
248    public void setTooltipSplit(final boolean tooltipSplit) {
249        updateSlider(SliderOption.TOOLTIP_SPLIT, tooltipSplit);
250    }
251
252    public TooltipPosition getTooltipPosition() {
253        TooltipPosition defaultPosition = getOrientation() == OrientationType.HORIZONTAL ?
254                TooltipPosition.TOP : TooltipPosition.RIGHT;
255        return getEnumAttribute(SliderOption.TOOLTIP_POSITION, TooltipPosition.class, defaultPosition);
256    }
257
258    /**
259     * Sets the tool-tip position.
260     *
261     * @param position
262     * @see TooltipPosition
263     */
264    public void setTooltipPosition(final TooltipPosition position) {
265        updateSlider(SliderOption.TOOLTIP_POSITION, position.getPosition());
266    }
267
268    public HandleType getHandle() {
269        return getEnumAttribute(SliderOption.HANDLE, HandleType.class, HandleType.ROUND);
270    }
271
272    /**
273     * Sets the handle shape.
274     *
275     * @param handle
276     * @see HandleType
277     */
278    public void setHandle(final HandleType handle) {
279        updateSlider(SliderOption.HANDLE, handle.getType());
280    }
281
282    public boolean isReversed() {
283        return getBooleanAttribute(SliderOption.REVERSED, false);
284    }
285
286    /**
287     * Sets whether or not the slider should be reversed.
288     *
289     * @param reversed
290     */
291    public void setReversed(final boolean reversed) {
292        updateSlider(SliderOption.REVERSED, reversed);
293    }
294
295    @Override
296    public boolean isEnabled() {
297        if (isAttached()) {
298            return isEnabled(getElement());
299        }
300        return getBooleanAttribute(SliderOption.ENABLED, true);
301    }
302
303    @Override
304    public void setEnabled(final boolean enabled) {
305        if (isAttached()) {
306            if (enabled) {
307                sliderCommand(getElement(), SliderCommand.ENABLE);
308            } else {
309                sliderCommand(getElement(), SliderCommand.DISABLE);
310            }
311        } else {
312            updateSlider(SliderOption.ENABLED, enabled);
313        }
314    }
315
316    /**
317     * Sets the formatter callback.
318     *
319     * @param formatterCallback
320     */
321    public void setFormatter(final FormatterCallback<T> formatterCallback) {
322        this.formatterCallback = formatterCallback;
323        if (isAttached()) {
324            setFormatter(getElement());
325            refresh();
326        }
327    }
328
329    /**
330     * Sets the callback function of the {@link SliderOption#FORMATTER} attribute.
331     *
332     * @param element
333     */
334    protected abstract void setFormatter(Element element);
335
336    protected String formatTooltip(final T value) {
337        if (formatterCallback != null)
338            return formatterCallback.formatTooltip(value);
339        return format(value);
340    }
341
342    /**
343     * Formats the slider value to string value to be displayed
344     * as tool-tip text.
345     *
346     * @param value
347     * @return
348     */
349    protected abstract String format(final T value);
350
351    public boolean isNaturalArrowKeys() {
352        return getBooleanAttribute(SliderOption.NATURAL_ARROW_KEYS, false);
353    }
354
355    /**
356     * The natural order is used for the arrow keys. Arrow up select the
357     * upper slider value for vertical sliders, arrow right the righter
358     * slider value for a horizontal slider ; no matter if the slider
359     * was reversed or not.<br>
360     * <br>
361     * By default the arrow keys are oriented by arrow up/right to the
362     * higher slider value, arrow down/left to the lower slider value.
363     *
364     * @param naturalArrowKeys
365     */
366    public void setNaturalArrowKeys(final boolean naturalArrowKeys) {
367        updateSlider(SliderOption.NATURAL_ARROW_KEYS, naturalArrowKeys);
368    }
369
370    public List<Double> getTicks() {
371        return getNumberArrayAttribute(SliderOption.TICKS, Collections.<Double>emptyList());
372    }
373
374    /**
375     * Sets the values of ticks. Tick marks are indicators to denote
376     * special values in the range.<br>
377     * <br>
378     * This option overwrites min and max options.
379     *
380     * @param ticks
381     */
382    public void setTicks(final List<Double> ticks) {
383        updateSliderForNumberArray(SliderOption.TICKS, ticks);
384    }
385
386    public List<Double> getTicksPositions() {
387        return getNumberArrayAttribute(SliderOption.TICKS_POSITIONS, Collections.<Double>emptyList());
388    }
389
390    /**
391     * Defines the positions of the tick values in percentages.<br>
392     * The first value should always be 0, the last value should always be 100 percent.
393     *
394     * @param ticksPositions
395     */
396    public void setTicksPositions(final List<Double> ticksPositions) {
397        updateSliderForNumberArray(SliderOption.TICKS_POSITIONS, ticksPositions);
398    }
399
400    public List<String> getTicksLabels() {
401        return getStringArrayAttribute(SliderOption.TICKS_LABELS, Collections.<String>emptyList());
402    }
403
404    /**
405     * Sets the labels below the tick marks.<br>
406     * <br>
407     * Accepts HTML input.
408     *
409     * @param ticksLabels
410     */
411    public void setTicksLabels(final List<String> ticksLabels) {
412        updateSliderForStringArray(SliderOption.TICKS_LABELS, ticksLabels);
413    }
414
415    public double getTicksSnapBounds() {
416        return getDoubleAttribute(SliderOption.TICKS_SNAP_BOUNDS, 0);
417    }
418
419    /**
420     * Sets the snap bounds of a tick. Snaps to the tick if value
421     * is within these bounds.
422     *
423     * @param ticksSnapBounds
424     */
425    public void setTicksSnapBounds(final double ticksSnapBounds) {
426        updateSlider(SliderOption.TICKS_SNAP_BOUNDS, ticksSnapBounds);
427    }
428
429    public ScaleType getScale() {
430        return getEnumAttribute(SliderOption.SCALE, ScaleType.class, ScaleType.LINEAR);
431    }
432
433    /**
434     * Focus the appropriate slider handle after a value change.
435     * Defaults to false.
436     *
437     * @param focus
438     */
439    public void setFocusHandle(final boolean focus) {
440        updateSlider(SliderOption.FOCUS, focus);
441    }
442
443    public boolean getFocusHandle() {
444        return getBooleanAttribute(SliderOption.FOCUS, false);
445    }
446
447    /**
448     * Sets the slider scale type.
449     *
450     * @param scale
451     * @see ScaleType
452     */
453    public void setScale(final ScaleType scale) {
454        updateSlider(SliderOption.SCALE, scale.getType());
455    }
456
457    @Override
458    public void setVisible(final boolean visible) {
459        if (isAttached()) {
460            setVisible(getElement(getElement()), visible);
461        } else {
462            super.setVisible(visible);
463        }
464    }
465
466    @Override
467    public boolean isVisible() {
468        if (isAttached()) {
469            return isVisible(getElement(getElement()));
470        }
471        return isVisible();
472    }
473
474    @Override
475    public void setVisibleOn(final DeviceSize deviceSize) {
476        StyleHelper.setVisibleOn(this, deviceSize);
477    }
478
479    @Override
480    public void setHiddenOn(final DeviceSize deviceSize) {
481        StyleHelper.setHiddenOn(this, deviceSize);
482    }
483
484    @Override
485    public void setValue(final T value) {
486        setValue(value, false);
487    }
488
489    @Override
490    public void setValue(final T value, final boolean fireEvents) {
491
492        T oldValue = fireEvents ? getValue() : null;
493
494        if (isAttached()) {
495            setValue(getElement(), value);
496        } else {
497            String attrVal = (value == null) ? null : value.toString();
498            attributeMixin.setAttribute(SliderOption.VALUE.getDataAttribute(), attrVal);
499        }
500
501        if (fireEvents) {
502            T newValue = getValue();
503            ValueChangeEvent.fireIfNotEqual(this, oldValue, newValue);
504        }
505    }
506
507    /**
508     * Sets the given value to the slider. This method is only relevant if the
509     * slider has been initialized and it will NOT fire the <b>slide</b> event.
510     *
511     * @param e
512     * @param value
513     */
514    protected abstract void setValue(Element e, T value);
515
516    @Override
517    public T getValue() {
518        if (isAttached()) {
519            return getValue(getElement());
520        }
521        String attrVal = attributeMixin.getAttribute(SliderOption.VALUE.getDataAttribute());
522        return convertValue(attrVal);
523    }
524
525    /**
526     * Returns the value by invoking the JSNI <strong>getValue</strong> command.
527     *
528     * @param e
529     * @return
530     */
531    protected abstract T getValue(Element e);
532
533    /**
534     * Converts the value of the {@link SliderOption#VALUE} attribute to the
535     * slider value.
536     *
537     * @param value
538     * @return
539     */
540    protected abstract T convertValue(String value);
541
542    @SuppressWarnings("deprecation")
543    @Override
544    public com.google.gwt.user.client.Element getStyleElement() {
545        if (isAttached()) {
546            return (com.google.gwt.user.client.Element) getElement(getElement());
547        }
548        return super.getStyleElement();
549    }
550
551    /**
552     * Toggles the slider between enabled and disabled.
553     */
554    public void toggle() {
555        if (isAttached()) {
556            sliderCommand(getElement(), SliderCommand.TOGGLE);
557        } else {
558            setEnabled(!isEnabled());
559        }
560    }
561
562    /**
563     * Refreshes the current slider. This method does nothing if the slider has
564     * not been initialized.
565     */
566    public void refresh() {
567        if (isAttached()) {
568            sliderCommand(getElement(), SliderCommand.REFEESH);
569        }
570    }
571
572    /**
573     * Renders the tool-tip again, after initialization. Useful in situations
574     * when the slider and tool-tip are initially hidden.
575     */
576    public void relayout() {
577        if (isAttached()) {
578            sliderCommand(getElement(), SliderCommand.RELAYOUT);
579        }
580    }
581
582    @Override
583    public LeafValueEditor<T> asEditor() {
584        if (editor == null) {
585            editor = TakesValueEditor.of(this);
586        }
587        return editor;
588    }
589
590    @Override
591    public HandlerRegistration addValueChangeHandler(final ValueChangeHandler<T> handler) {
592        return addHandler(handler, ValueChangeEvent.getType());
593    }
594
595    @Override
596    public HandlerRegistration addSlideHandler(final SlideHandler<T> handler) {
597        return addHandler(handler, SlideEvent.getType());
598    }
599
600    @Override
601    public HandlerRegistration addSlideStartHandler(final SlideStartHandler<T> handler) {
602        return addHandler(handler, SlideStartEvent.getType());
603    }
604
605    @Override
606    public HandlerRegistration addSlideStopHandler(final SlideStopHandler<T> handler) {
607        return addHandler(handler, SlideStopEvent.getType());
608    }
609
610    @Override
611    public HandlerRegistration addSlideEnabledHandler(final SlideEnabledHandler handler) {
612        return addHandler(handler, SlideEnabledEvent.getType());
613    }
614
615    @Override
616    public HandlerRegistration addSlideDisabledHandler(final SlideDisabledHandler handler) {
617        return addHandler(handler, SlideDisabledEvent.getType());
618    }
619
620    private void updateSlider(SliderOption option, String value) {
621        if (isAttached()) {
622            setAttribute(getElement(), option.getName(), value);
623            refresh();
624        } else {
625            attributeMixin.setAttribute(option.getDataAttribute(), value);
626        }
627    }
628
629    private void updateSlider(SliderOption option, boolean value) {
630        if (isAttached()) {
631            setAttribute(getElement(), option.getName(), value);
632            refresh();
633        } else {
634            attributeMixin.setAttribute(option.getDataAttribute(), Boolean.toString(value));
635        }
636    }
637
638    private void updateSlider(SliderOption option, double value) {
639        if (isAttached()) {
640            setAttribute(getElement(), option.getName(), value);
641            refresh();
642        } else {
643            attributeMixin.setAttribute(option.getDataAttribute(), Double.toString(value));
644        }
645    }
646
647    private void updateSliderForNumberArray(SliderOption option, List<Double> value) {
648        JsArrayNumber array = JavaScriptObject.createArray().cast();
649        for (Double val : value) {
650            array.push(val);
651        }
652        if (isAttached()) {
653            setAttribute(getElement(), option.getName(), array);
654            refresh();
655        } else {
656            String arrayStr = JsonUtils.stringify(array);
657            attributeMixin.setAttribute(option.getDataAttribute(), arrayStr);
658        }
659    }
660
661    private void updateSliderForStringArray(SliderOption option, List<String> value) {
662        JsArrayString array = JavaScriptObject.createArray().cast();
663        for (String val : value) {
664            array.push(val);
665        }
666        if (isAttached()) {
667            setAttribute(getElement(), option.getName(), array);
668            refresh();
669        } else {
670            String arrayStr = JsonUtils.stringify(array);
671            attributeMixin.setAttribute(option.getDataAttribute(), arrayStr);
672        }
673    }
674
675    private String getStringAttribute(SliderOption option) {
676        if (isAttached()) {
677            return getStringAttribute(getElement(), option.getName());
678        }
679        return attributeMixin.getAttribute(option.getDataAttribute());
680    }
681
682    private boolean getBooleanAttribute(SliderOption option, boolean defaultValue) {
683        if (isAttached()) {
684            return getBooleanAttribute(getElement(), option.getName());
685        }
686        String value = attributeMixin.getAttribute(option.getDataAttribute());
687        if (value != null && !value.isEmpty()) {
688            return Boolean.valueOf(value);
689        }
690        return defaultValue;
691    }
692
693    private double getDoubleAttribute(SliderOption option, double defaultValue) {
694        if (isAttached()) {
695            return getDoubleAttribute(getElement(), option.getName());
696        }
697        String value = attributeMixin.getAttribute(option.getDataAttribute());
698        if (value != null && !value.isEmpty()) {
699            return Double.valueOf(value);
700        }
701        return defaultValue;
702    }
703
704    private <E extends Enum<E>> E getEnumAttribute(SliderOption option, Class<E> clazz, E defaultValue) {
705        String value;
706        if (isAttached()) {
707            value = getStringAttribute(getElement(), option.getName());
708        } else {
709            value = attributeMixin.getAttribute(option.getDataAttribute());
710        }
711        try {
712            return Enum.valueOf(clazz, value);
713        } catch (Throwable e) {
714            return defaultValue;
715        }
716    }
717
718    private List<Double> getNumberArrayAttribute(SliderOption option, List<Double> defaultValue) {
719
720        // Get array attribute
721        JsArrayNumber array = null;
722        if (isAttached()) {
723            array = getNumberArrayAttribute(getElement(), option.getName());
724        } else {
725            String value = attributeMixin.getAttribute(option.getDataAttribute());
726            if (value != null && !value.isEmpty()) {
727                array = JsonUtils.safeEval(value);
728            }
729        }
730
731        // Attribute not set
732        if (array == null) {
733            return defaultValue;
734        }
735
736        // Put array to list
737        List<Double> list = new ArrayList<Double>(array.length());
738        for (int i = 0; i < array.length(); i++) {
739            list.add(array.get(i));
740        }
741        return list;
742    }
743
744    private List<String> getStringArrayAttribute(SliderOption option, List<String> defaultValue) {
745
746        // Get array attribute
747        JsArrayString array = null;
748        if (isAttached()) {
749            array = getStringArrayAttribute(getElement(), option.getName());
750        } else {
751            String value = attributeMixin.getAttribute(option.getDataAttribute());
752            if (value != null && !value.isEmpty()) {
753                array = JsonUtils.safeEval(value);
754            }
755        }
756
757        // Attribute not set
758        if (array == null) {
759            return defaultValue;
760        }
761
762        // Put array to list
763        List<String> list = new ArrayList<String>(array.length());
764        for (int i = 0; i < array.length(); i++) {
765            list.add(array.get(i));
766        }
767        return list;
768    }
769
770    protected boolean isSliderNamespaceAvailable() {
771        return sliderNamespaceAvailable;
772    }
773
774    private native boolean isSliderNamespaceBound() /*-{
775        return ($wnd.jQuery.fn.slider === 'undefined');
776    }-*/;
777
778    private native void initSlider(Element e, JavaScriptObject options) /*-{
779        if (this.@org.gwtbootstrap3.extras.slider.client.ui.base.SliderBase::isSliderNamespaceAvailable()())
780            $wnd.jQuery(e).slider(options);
781        else
782            $wnd.jQuery(e).bootstrapSlider(options);
783    }-*/;
784
785    /**
786     * Called when a {@link SlideEvent} is fired.
787     *
788     * @param event the native event
789     */
790    protected abstract void onSlide(final Event event);
791
792    /**
793     * Fires a {@link SlideEvent} event.
794     *
795     * @param value the new slide value
796     */
797    protected void fireSlideEvent(final T value) {
798        SlideEvent.fire(this, value);
799    }
800
801    /**
802     * Called when a {@link SlideStartEvent} is fired.
803     *
804     * @param event the native event
805     */
806    protected abstract void onSlideStart(final Event event);
807
808    /**
809     * Fires a {@link SlideStartEvent} event.
810     *
811     * @param value the new slide value
812     */
813    protected void fireSlideStartEvent(final T value) {
814        SlideStartEvent.fire(this, value);
815    }
816
817    /**
818     * Called when a {@link SlideStopEvent} is fired.
819     *
820     * @param event the native event
821     */
822    protected abstract void onSlideStop(final Event event);
823
824    /**
825     * Fires a {@link SlideStopEvent} event.
826     *
827     * @param value the new slide value
828     */
829    protected void fireSlideStopEvent(final T value) {
830        SlideStopEvent.fire(this, value);
831    }
832
833    /**
834     * Called when a {@link ValueChangeEvent} is fired.
835     *
836     * @param event the native event
837     */
838    protected abstract void onSlideChange(final Event event);
839
840    /**
841     * Fires a {@link ValueChangeEvent} event.
842     *
843     * @param value the new slide value
844     */
845    protected void fireChangeEvent(final T value) {
846        ValueChangeEvent.fire(this, value);
847    }
848
849    /**
850     * Binds the slider events.
851     *
852     * @param e
853     */
854    private native void bindSliderEvents(Element e) /*-{
855        var slider = this;
856        $wnd.jQuery(e).on(@org.gwtbootstrap3.extras.slider.client.ui.base.event.HasAllSlideHandlers::SLIDE_EVENT, function(event) {
857            slider.@org.gwtbootstrap3.extras.slider.client.ui.base.SliderBase::onSlide(Lcom/google/gwt/user/client/Event;)(event);
858        });
859        $wnd.jQuery(e).on(@org.gwtbootstrap3.extras.slider.client.ui.base.event.HasAllSlideHandlers::SLIDE_START_EVENT, function(event) {
860            slider.@org.gwtbootstrap3.extras.slider.client.ui.base.SliderBase::onSlideStart(Lcom/google/gwt/user/client/Event;)(event);
861        });
862        $wnd.jQuery(e).on(@org.gwtbootstrap3.extras.slider.client.ui.base.event.HasAllSlideHandlers::SLIDE_STOP_EVENT, function(event) {
863            slider.@org.gwtbootstrap3.extras.slider.client.ui.base.SliderBase::onSlideStop(Lcom/google/gwt/user/client/Event;)(event);
864        });
865        $wnd.jQuery(e).on(@org.gwtbootstrap3.extras.slider.client.ui.base.event.HasAllSlideHandlers::SLIDE_CHANGE_EVENT, function(event) {
866            slider.@org.gwtbootstrap3.extras.slider.client.ui.base.SliderBase::onSlideChange(Lcom/google/gwt/user/client/Event;)(event);
867        });
868        $wnd.jQuery(e).on(@org.gwtbootstrap3.extras.slider.client.ui.base.event.HasAllSlideHandlers::SLIDE_ENABLED_EVENT, function(event) {
869            @org.gwtbootstrap3.extras.slider.client.ui.base.event.SlideEnabledEvent::fire(Lorg/gwtbootstrap3/extras/slider/client/ui/base/event/HasSlideEnabledHandlers;)(slider);
870        });
871        $wnd.jQuery(e).on(@org.gwtbootstrap3.extras.slider.client.ui.base.event.HasAllSlideHandlers::SLIDE_DISABLED_EVENT, function(event) {
872            @org.gwtbootstrap3.extras.slider.client.ui.base.event.SlideDisabledEvent::fire(Lorg/gwtbootstrap3/extras/slider/client/ui/base/event/HasSlideDisabledHandlers;)(slider);
873        });
874    }-*/;
875
876    /**
877     * Unbinds the slider events.
878     *
879     * @param e
880     */
881    private native void unbindSliderEvents(Element e) /*-{
882        $wnd.jQuery(e).off(@org.gwtbootstrap3.extras.slider.client.ui.base.event.HasAllSlideHandlers::SLIDE_EVENT);
883        $wnd.jQuery(e).off(@org.gwtbootstrap3.extras.slider.client.ui.base.event.HasAllSlideHandlers::SLIDE_START_EVENT);
884        $wnd.jQuery(e).off(@org.gwtbootstrap3.extras.slider.client.ui.base.event.HasAllSlideHandlers::SLIDE_STOP_EVENT);
885        $wnd.jQuery(e).off(@org.gwtbootstrap3.extras.slider.client.ui.base.event.HasAllSlideHandlers::SLIDE_CHANGE_EVENT);
886        $wnd.jQuery(e).off(@org.gwtbootstrap3.extras.slider.client.ui.base.event.HasAllSlideHandlers::SLIDE_ENABLED_EVENT);
887        $wnd.jQuery(e).off(@org.gwtbootstrap3.extras.slider.client.ui.base.event.HasAllSlideHandlers::SLIDE_DISABLED_EVENT);
888    }-*/;
889
890    private native boolean isEnabled(Element e) /*-{
891        if (this.@org.gwtbootstrap3.extras.slider.client.ui.base.SliderBase::isSliderNamespaceAvailable()())
892            return $wnd.jQuery(e).slider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::IS_ENABLED);
893        return $wnd.jQuery(e).bootstrapSlider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::IS_ENABLED);
894    }-*/;
895
896    private native void sliderCommand(Element e, String cmd) /*-{
897        if (this.@org.gwtbootstrap3.extras.slider.client.ui.base.SliderBase::isSliderNamespaceAvailable()())
898            $wnd.jQuery(e).slider(cmd);
899        else
900            $wnd.jQuery(e).bootstrapSlider(cmd);
901    }-*/;
902
903    private native Element getElement(Element e) /*-{
904        if (this.@org.gwtbootstrap3.extras.slider.client.ui.base.SliderBase::isSliderNamespaceAvailable()())
905            return $wnd.jQuery(e).slider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::GET_ELEMENT);
906        return $wnd.jQuery(e).bootstrapSlider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::GET_ELEMENT);
907    }-*/;
908
909    private native void setAttribute(Element e, String attr, String value) /*-{
910        if (this.@org.gwtbootstrap3.extras.slider.client.ui.base.SliderBase::isSliderNamespaceAvailable()())
911            $wnd.jQuery(e).slider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::SET_ATTRIBUTE, attr, value);
912        else
913            $wnd.jQuery(e).bootstrapSlider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::SET_ATTRIBUTE, attr, value);
914    }-*/;
915
916    private native void setAttribute(Element e, String attr, boolean value) /*-{
917        if (this.@org.gwtbootstrap3.extras.slider.client.ui.base.SliderBase::isSliderNamespaceAvailable()())
918            $wnd.jQuery(e).slider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::SET_ATTRIBUTE, attr, value);
919        else
920            $wnd.jQuery(e).bootstrapSlider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::SET_ATTRIBUTE, attr, value);
921    }-*/;
922
923    private native void setAttribute(Element e, String attr, double value) /*-{
924        if (this.@org.gwtbootstrap3.extras.slider.client.ui.base.SliderBase::isSliderNamespaceAvailable()())
925            $wnd.jQuery(e).slider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::SET_ATTRIBUTE, attr, value);
926        else
927            $wnd.jQuery(e).bootstrapSlider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::SET_ATTRIBUTE, attr, value);
928    }-*/;
929
930    private native void setAttribute(Element e, String attr, JsArrayNumber value) /*-{
931        if (this.@org.gwtbootstrap3.extras.slider.client.ui.base.SliderBase::isSliderNamespaceAvailable()())
932            $wnd.jQuery(e).slider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::SET_ATTRIBUTE, attr, value);
933        else
934            $wnd.jQuery(e).bootstrapSlider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::SET_ATTRIBUTE, attr, value);
935    }-*/;
936
937    private native void setAttribute(Element e, String attr, JsArrayString value) /*-{
938        if (this.@org.gwtbootstrap3.extras.slider.client.ui.base.SliderBase::isSliderNamespaceAvailable()())
939            $wnd.jQuery(e).slider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::SET_ATTRIBUTE, attr, value);
940        else
941            $wnd.jQuery(e).bootstrapSlider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::SET_ATTRIBUTE, attr, value);
942    }-*/;
943
944    private native String getStringAttribute(Element e, String attr) /*-{
945        if (this.@org.gwtbootstrap3.extras.slider.client.ui.base.SliderBase::isSliderNamespaceAvailable()())
946            return $wnd.jQuery(e).slider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::GET_ATTRIBUTE, attr);
947        return $wnd.jQuery(e).bootstrapSlider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::GET_ATTRIBUTE, attr);
948    }-*/;
949
950    private native boolean getBooleanAttribute(Element e, String attr) /*-{
951        if (this.@org.gwtbootstrap3.extras.slider.client.ui.base.SliderBase::isSliderNamespaceAvailable()())
952            return $wnd.jQuery(e).slider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::GET_ATTRIBUTE, attr);
953        return $wnd.jQuery(e).bootstrapSlider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::GET_ATTRIBUTE, attr);
954    }-*/;
955
956    private native double getDoubleAttribute(Element e, String attr) /*-{
957        if (this.@org.gwtbootstrap3.extras.slider.client.ui.base.SliderBase::isSliderNamespaceAvailable()())
958            return $wnd.jQuery(e).slider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::GET_ATTRIBUTE, attr);
959        return $wnd.jQuery(e).bootstrapSlider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::GET_ATTRIBUTE, attr);
960    }-*/;
961
962    private native JsArrayNumber getNumberArrayAttribute(Element e, String attr) /*-{
963        if (this.@org.gwtbootstrap3.extras.slider.client.ui.base.SliderBase::isSliderNamespaceAvailable()())
964            return $wnd.jQuery(e).slider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::GET_ATTRIBUTE, attr);
965        return $wnd.jQuery(e).bootstrapSlider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::GET_ATTRIBUTE, attr);
966    }-*/;
967
968    private native JsArrayString getStringArrayAttribute(Element e, String attr) /*-{
969        if (this.@org.gwtbootstrap3.extras.slider.client.ui.base.SliderBase::isSliderNamespaceAvailable()())
970            return $wnd.jQuery(e).slider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::GET_ATTRIBUTE, attr);
971        return $wnd.jQuery(e).bootstrapSlider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::GET_ATTRIBUTE, attr);
972    }-*/;
973
974}