com.gwtm.ui.client.widgets.FlipSwitch.java Source code

Java tutorial

Introduction

Here is the source code for com.gwtm.ui.client.widgets.FlipSwitch.java

Source

/*
 * Copyright (c) 2010 Zhihua (Dennis) Jiang
 * 
 * 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.gwtm.ui.client.widgets;

import java.beans.Beans;

import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.HasValueChangeHandlers;
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.ui.HTML;
import com.gwtm.ui.client.core.InputController;
import com.gwtm.ui.client.core.Utils;
import com.gwtm.ui.client.events.DraggingEvent;
import com.gwtm.ui.client.events.DraggingHandler;
import com.gwtm.ui.client.themes.ThemeConstants;
import com.gwtm.ui.client.themes.ThemeManager;

public class FlipSwitch extends HTML implements DraggingHandler, ClickHandler, HasValueChangeHandlers<Boolean> {

    private final static String HTML_CONTENT = "<div class='fs-left'></div><div class='fs-middle'></div><div class='fs-right'><div><div class='fs-left'>ON</div><div class='fs-middle'></div><div class='fs-right'>OFF</div></div></div>";
    protected boolean enabled = true;
    protected boolean value = true;
    protected boolean showText = true;

    public FlipSwitch() {
        super(HTML_CONTENT);
        Utils.Widgets.setPrimaryCssClass(this, ThemeManager.getTheme().flipswitch());
        addClickHandler(this);
    }

    @Override
    public String getHTML() {
        if (Beans.isDesignTime())
            return "DO NOT EDIT";
        return super.getHTML();
    }

    @Override
    public void onLoad() {
        super.onLoad();
        InputController.get().addDraggingHandler(this);
        if (!value) {
            updateFlipPosition(0);
        }
    }

    @Override
    public void onUnload() {
        InputController.get().removeDraggingHandler(this);
    }

    @Override
    public void onDraggingStart(DraggingEvent e) {
        if (!enabled) {
            return;
        }
        e.stopPropagation();
        InputController.get().captureDraggingEvent(this);
        Utils.Fx.setTransitionDuration(getFilpElement(), 0);
    }

    @Override
    public void onDraggingMove(DraggingEvent e) {
        if (!enabled) {
            return;
        }
        e.stopPropagation();
        Element flip = getFilpElement();
        int x = Utils.Fx.getTranslateX(flip);
        int newX = (int) (x + e.getOffsetX());
        int onPosition = getOnPosition();
        int offPosition = getOffPosition();
        if (newX > onPosition) {
            newX = onPosition;
        } else if (newX < offPosition) {
            newX = offPosition;
        }
        if (newX != x) {
            Utils.Fx.setTranslateX(flip, newX);
        }
    }

    @Override
    public void onDraggingEnd(DraggingEvent e) {
        if (!enabled) {
            return;
        }
        InputController.get().releaseDraggingEvent(this);
        Element flip = getFilpElement();
        int x = Utils.Fx.getTranslateX(flip);
        int onPosition = getOnPosition();
        int offPosition = getOffPosition();
        if (x == onPosition) {
            setValue(true, false, 0, true);
        } else if (x == offPosition) {
            setValue(false, false, 0, true);
        } else {
            float ratio = (float) x / (float) (offPosition - onPosition);
            boolean newValue = ratio < 0.5;
            int duration = (int) ((0.5 - Math.abs(ratio - 0.5)) * 200);
            //Utils.Console("ratio " + ratio + " duration " + duration);
            setValue(newValue, true, duration, true);
        }
    }

    public void setValue(boolean value) {
        setValue(value, false, 200, true);
    }

    public void setValue(boolean value, boolean fireEvent) {
        setValue(value, false, 200, fireEvent);
    }

    private void setValue(boolean value, boolean forceUpdateFlipPosition, int duration, boolean fireEvent) {
        if (this.value != value) {
            this.value = value;
            updateFlipPosition(duration);
            if (fireEvent) {
                ValueChangeEvent.fire(this, value);
            }
        } else if (forceUpdateFlipPosition || Beans.isDesignTime()) {
            updateFlipPosition(duration);
        }
    }

    public boolean getValue() {
        return value;
    }

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        if (this.enabled == enabled)
            return;

        if (enabled)
            Utils.Widgets.removeExtensionCssClass(this, ThemeConstants.Extension.disabled);
        else
            Utils.Widgets.setExtensionCssClass(this, ThemeConstants.Extension.disabled);

        this.enabled = enabled;
    }

    @Override
    public void onClick(ClickEvent event) {
        if (enabled) {
            setValue(!value);
        }
    }

    private void updateFlipPosition(int duration) {
        Utils.Fx.setTransitionDuration(getFilpElement(), duration);
        Element flip = getFilpElement();

        // make the value be visible during design time
        if (Beans.isDesignTime()) {
            Element flipDiv = (Element) flip.getChild(1);
            if (value) {
                flipDiv.removeAttribute("style");
            } else {
                flipDiv.setAttribute("style", "position:absolute; left:0; height:2em; margin-left:.5px;");
            }
        } else {
            if (value) {
                Utils.Fx.setTranslateX(flip, getOnPosition());
            } else {
                Utils.Fx.setTranslateX(flip, getOffPosition());
            }
        }
    }

    private Element getFilpElement() {
        return (Element) getElement().getChild(2).getChild(0);
    }

    private int getOnPosition() {
        return 0;
    }

    private int getOffPosition() {
        Element flip = getFilpElement();
        Element parent = flip.getParentElement();
        int flipWidth = flip.getScrollWidth();
        int parentWidth = parent.getClientWidth();
        return parentWidth - flipWidth;
    }

    public boolean isShowText() {
        return showText;
    }

    public void setShowText(boolean showText) {

        if (this.showText != showText) {
            setHTML(HTML_CONTENT.replaceAll("ON", "").replaceAll("OFF", ""));
        }

        this.showText = showText;

    }

    @Override
    public HandlerRegistration addValueChangeHandler(ValueChangeHandler<Boolean> handler) {
        return this.addHandler(handler, ValueChangeEvent.getType());
    }

}