<commit_before>/*
 * Copyright 2011 Vaadin Ltd.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
//
package com.vaadin.client.ui;

import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Overflow;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.dom.client.Style.Visibility;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Command;
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.Window;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasValue;
import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.BrowserInfo;
import com.vaadin.client.ContainerResizedListener;
import com.vaadin.client.Util;
import com.vaadin.client.VConsole;
import com.vaadin.shared.ui.slider.SliderOrientation;

public class VSlider extends SimpleFocusablePanel implements Field,
        ContainerResizedListener, HasValue<Double> {

    public static final String CLASSNAME = "v-slider";

    /**
     * Minimum size (width or height, depending on orientation) of the slider
     * base.
     */
    private static final int MIN_SIZE = 50;

    protected ApplicationConnection client;

    protected String id;

    protected boolean immediate;
    protected boolean disabled;
    protected boolean readonly;

    private int acceleration = 1;
    protected double min;
    protected double max;
    protected int resolution;
    protected Double value;
    protected SliderOrientation orientation = SliderOrientation.HORIZONTAL;

    private final HTML feedback = new HTML("", false);
    private final VOverlay feedbackPopup = new VOverlay(true, false, true) {
        {
            setOwner(VSlider.this);
        }

        @Override
        public void show() {
            super.show();
            updateFeedbackPosition();
        }
    };

    /* DOM element for slider's base */
    private final Element base;
    private final int BASE_BORDER_WIDTH = 1;

    /* DOM element for slider's handle */
    private final Element handle;

    /* DOM element for decrement arrow */
    private final Element smaller;

    /* DOM element for increment arrow */
    private final Element bigger;

    /* Temporary dragging/animation variables */
    private boolean dragging = false;

    private VLazyExecutor delayedValueUpdater = new VLazyExecutor(100,
            new ScheduledCommand() {

                @Override
                public void execute() {
                    fireValueChanged();
                    acceleration = 1;
                }
            });

    public VSlider() {
        super();

        base = DOM.createDiv();
        handle = DOM.createDiv();
        smaller = DOM.createDiv();
        bigger = DOM.createDiv();

        setStyleName(CLASSNAME);

        getElement().appendChild(bigger);
        getElement().appendChild(smaller);
        getElement().appendChild(base);
        base.appendChild(handle);

        // Hide initially
        smaller.getStyle().setDisplay(Display.NONE);
        bigger.getStyle().setDisplay(Display.NONE);
        handle.getStyle().setVisibility(Visibility.HIDDEN);

        sinkEvents(Event.MOUSEEVENTS | Event.ONMOUSEWHEEL | Event.KEYEVENTS
                | Event.FOCUSEVENTS | Event.TOUCHEVENTS);

        feedbackPopup.setWidget(feedback);
    }

    @Override
    public void setStyleName(String style) {
        updateStyleNames(style, false);
    }

    @Override
    public void setStylePrimaryName(String style) {
        updateStyleNames(style, true);
    }

    protected void updateStyleNames(String styleName, boolean isPrimaryStyleName) {

        feedbackPopup.removeStyleName(getStylePrimaryName() + "-feedback");
        removeStyleName(getStylePrimaryName() + "-vertical");

        if (isPrimaryStyleName) {
            super.setStylePrimaryName(styleName);
        } else {
            super.setStyleName(styleName);
        }

        feedbackPopup.addStyleName(getStylePrimaryName() + "-feedback");
        base.setClassName(getStylePrimaryName() + "-base");
        handle.setClassName(getStylePrimaryName() + "-handle");
        smaller.setClassName(getStylePrimaryName() + "-smaller");
        bigger.setClassName(getStylePrimaryName() + "-bigger");

        if (isVertical()) {
            addStyleName(getStylePrimaryName() + "-vertical");
        }
    }

    public void setFeedbackValue(double value) {
        String currentValue = "" + value;
        if (resolution == 0) {
            currentValue = "" + new Double(value).intValue();
        }
        feedback.setText(currentValue);
    }

    private void updateFeedbackPosition() {
        if (isVertical()) {
            feedbackPopup.setPopupPosition(
                    handle.getAbsoluteLeft() + handle.getOffsetWidth(),
                    handle.getAbsoluteTop() + handle.getOffsetHeight() / 2
                            - feedbackPopup.getOffsetHeight() / 2);
        } else {
            feedbackPopup.setPopupPosition(
                    handle.getAbsoluteLeft() + handle.getOffsetWidth() / 2
                            - feedbackPopup.getOffsetWidth() / 2,
                    handle.getAbsoluteTop() - feedbackPopup.getOffsetHeight());
        }
    }

    /** For internal use only. May be removed or replaced in the future. */
    public void buildBase() {
        final String styleAttribute = isVertical() ? "height" : "width";
        final String oppositeStyleAttribute = isVertical() ? "width" : "height";
        final String domProperty = isVertical() ? "offsetHeight"
                : "offsetWidth";

        // clear unnecessary opposite style attribute
        base.getStyle().clearProperty(oppositeStyleAttribute);

        final Element p = getElement().getParentElement().cast();
        if (p.getPropertyInt(domProperty) > 50) {
            if (isVertical()) {
                setHeight();
            } else {
                base.getStyle().clearProperty(styleAttribute);
            }
        } else {
            // Set minimum size and adjust after all components have
            // (supposedly) been drawn completely.
            base.getStyle().setPropertyPx(styleAttribute, MIN_SIZE);<commit_msg>Fixed NPE in Slider (#9740)<commit_after>/*
 * Copyright 2011 Vaadin Ltd.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
//
package com.vaadin.client.ui;

import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Overflow;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.dom.client.Style.Visibility;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Command;
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.Window;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasValue;
import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.BrowserInfo;
import com.vaadin.client.ContainerResizedListener;
import com.vaadin.client.Util;
import com.vaadin.client.VConsole;
import com.vaadin.shared.ui.slider.SliderOrientation;

public class VSlider extends SimpleFocusablePanel implements Field,
        ContainerResizedListener, HasValue<Double> {

    public static final String CLASSNAME = "v-slider";

    /**
     * Minimum size (width or height, depending on orientation) of the slider
     * base.
     */
    private static final int MIN_SIZE = 50;

    protected ApplicationConnection client;

    protected String id;

    protected boolean immediate;
    protected boolean disabled;
    protected boolean readonly;

    private int acceleration = 1;
    protected double min;
    protected double max;
    protected int resolution;
    protected Double value;
    protected SliderOrientation orientation = SliderOrientation.HORIZONTAL;

    private final HTML feedback = new HTML("", false);
    private final VOverlay feedbackPopup = new VOverlay(true, false, true) {
        {
            setOwner(VSlider.this);
        }

        @Override
        public void show() {
            super.show();
            updateFeedbackPosition();
        }
    };

    /* DOM element for slider's base */
    private final Element base;
    private final int BASE_BORDER_WIDTH = 1;

    /* DOM element for slider's handle */
    private final Element handle;

    /* DOM element for decrement arrow */
    private final Element smaller;

    /* DOM element for increment arrow */
    private final Element bigger;

    /* Temporary dragging/animation variables */
    private boolean dragging = false;

    private VLazyExecutor delayedValueUpdater = new VLazyExecutor(100,
            new ScheduledCommand() {

                @Override
                public void execute() {
                    fireValueChanged();
                    acceleration = 1;
                }
            });

    public VSlider() {
        super();

        base = DOM.createDiv();
        handle = DOM.createDiv();
        smaller = DOM.createDiv();
        bigger = DOM.createDiv();

        setStyleName(CLASSNAME);

        getElement().appendChild(bigger);
        getElement().appendChild(smaller);
        getElement().appendChild(base);
        base.appendChild(handle);

        // Hide initially
        smaller.getStyle().setDisplay(Display.NONE);
        bigger.getStyle().setDisplay(Display.NONE);
        handle.getStyle().setVisibility(Visibility.HIDDEN);

        sinkEvents(Event.MOUSEEVENTS | Event.ONMOUSEWHEEL | Event.KEYEVENTS
                | Event.FOCUSEVENTS | Event.TOUCHEVENTS);

        feedbackPopup.setWidget(feedback);
    }

    @Override
    public void setStyleName(String style) {
        updateStyleNames(style, false);
    }

    @Override
    public void setStylePrimaryName(String style) {
        updateStyleNames(style, true);
    }

    protected void updateStyleNames(String styleName, boolean isPrimaryStyleName) {

        feedbackPopup.removeStyleName(getStylePrimaryName() + "-feedback");
        removeStyleName(getStylePrimaryName() + "-vertical");

        if (isPrimaryStyleName) {
            super.setStylePrimaryName(styleName);
        } else {
            super.setStyleName(styleName);
        }

        feedbackPopup.addStyleName(getStylePrimaryName() + "-feedback");
        base.setClassName(getStylePrimaryName() + "-base");
        handle.setClassName(getStylePrimaryName() + "-handle");
        smaller.setClassName(getStylePrimaryName() + "-smaller");
        bigger.setClassName(getStylePrimaryName() + "-bigger");

        if (isVertical()) {
            addStyleName(getStylePrimaryName() + "-vertical");
        }
    }

    public void setFeedbackValue(double value) {
        String currentValue = "" + value;
        if (resolution == 0) {
            currentValue = "" + new Double(value).intValue();
        }
        feedback.setText(currentValue);
    }

    private void updateFeedbackPosition() {
        if (isVertical()) {
            feedbackPopup.setPopupPosition(
                    handle.getAbsoluteLeft() + handle.getOffsetWidth(),
                    handle.getAbsoluteTop() + handle.getOffsetHeight() / 2
                            - feedbackPopup.getOffsetHeight() / 2);
        } else {
            feedbackPopup.setPopupPosition(
                    handle.getAbsoluteLeft() + handle.getOffsetWidth() / 2
                            - feedbackPopup.getOffsetWidth() / 2,
                    handle.getAbsoluteTop() - feedbackPopup.getOffsetHeight());
        }
    }

    /** For internal use only. May be removed or replaced in the future. */
    public void buildBase() {
        final String styleAttribute = isVertical() ? "height" : "width";
        final String oppositeStyleAttribute = isVertical() ? "width" : "height";
        final String domProperty = isVertical() ? "offsetHeight"
                : "offsetWidth";

        // clear unnecessary opposite style attribute
        base.getStyle().clearProperty(oppositeStyleAttribute);

        if (!getElement().hasParentElement()) {
            return;
        }

        final Element p = getElement().getParentElement().cast();
        if (p.getPropertyInt(domProperty) > 50) {
            if (isVertical()) {
                setHeight();
            } else {
                base.getStyle().clearProperty(styleAttribute);
            }
        } else {
            // Set minimum size and adjust after all components have
            // (supposedly) been drawn completely.
            base.getStyle().setPropertyPx(styleAttribute, MIN_SIZE);
{'fraction_non_alphanumeric': 0.10098470563586842, 'fraction_numerical': 0.003491863956980236, 'mean_word_length': 2.5979899497487438, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7579360', 'n_tokens_mistral': 3858, 'n_tokens_neox': 3704, 'n_words': 918}