org.adamtacy.client.ui.effects.impl.Resize.java Source code

Java tutorial

Introduction

Here is the source code for org.adamtacy.client.ui.effects.impl.Resize.java

Source

/*
 * Copyright 2008-2009 Adam Tacy <adam.tacy AT gmail.com>
 * 
 * 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.
 */
/*
 * Copyright 2011 Vancouver Ywebb Consulting 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 org.adamtacy.client.ui.effects.impl;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;

import org.adamtacy.client.ui.effects.NEffect;
import org.adamtacy.client.ui.effects.RequiresDimensions;
import org.adamtacy.client.ui.effects.core.ChangeInterface;
import org.adamtacy.client.ui.effects.core.NChangeScalarAction;
import org.adamtacy.client.ui.effects.impl.css.StyleImplementation;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Node;
import com.google.gwt.dom.client.NodeList;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HasHorizontalAlignment.HorizontalAlignmentConstant;
import com.google.gwt.user.client.ui.HasVerticalAlignment.VerticalAlignmentConstant;

public class Resize extends NEffect implements RequiresDimensions {

    static Vector<String> triggerDOM = new Vector<String>();

    static public void addToTriggerDOM(String newName) {
        triggerDOM.add(newName);
    }

    static public void addToTriggerDOM(Vector<String> newNames) {
        triggerDOM.addAll(newNames);
    }

    static public void setTriggerDOM(Vector<String> names) {
        triggerDOM = names;
    }

    HashMap<Element, Vector<ChangeInterface>> determinedEffects;

    Element effectElement;

    int endX = 0;

    double endXRatio;

    int endY = 0;

    double endYRatio;

    Vector<String> fontSizes = new Vector<String>();

    double fontSizeScalingFactor = 1.2;

    HorizontalAlignmentConstant horizAlign = HasHorizontalAlignment.ALIGN_LEFT;

    int standardFontSize = 14;
    String standardFontUnit = "px";
    int standardIndex = 4;
    int startX = 100;

    double startXRatio;

    int startY = 100;

    double startYRatio;

    VerticalAlignmentConstant vertAlign = HasVerticalAlignment.ALIGN_TOP;

    /**
     * Initialise effect and set up the basic set of DOM elements that resizing
     * will be applied to If more elements are needed to be included, use the
     * addToTriggerDOM(Vector<String> arg) method, or you can replace completely
     * using the setTriggerDOM(Vector<String> arg) method.
     */
    public Resize() {
        super();
        triggerDOM.add("IMG");
        triggerDOM.add("TABLE");
        triggerDOM.add("DIV");
    }

    public Resize(Element el) {
        this();
        addEffectElement(el);
    }

    public Resize(Element el, int start, int end) {
        this(start, end);
        addEffectElement(el);
    }

    public Resize(int start, int end) {
        this();
        startX = start;
        startY = start;
        endX = end;
        endY = end;
    }

    private void createInternalEffectsPerElement(Element currEl) {

        NodeList<Node> nodes = currEl.getChildNodes();
        if (nodes != null) {
            for (int i = 0; i < nodes.getLength(); i++) {
                Node n = nodes.getItem(i);
                if (n.getNodeType() == Node.ELEMENT_NODE) {
                    createInternalEffectsPerElement((Element) nodes.getItem(i));
                }
            }
        }

        Vector<ChangeInterface> temp = new Vector<ChangeInterface>();

        String name = currEl.getNodeName();
        if (triggerDOM.contains(name)) {
            GWT.log("Resize Effect is Processing: " + name, null);

            int startVal;
            int endVal;
            // Deal with Widths
            startVal = getStartWidth(currEl);
            endVal = getEndWidth(currEl);
            if (startVal != endVal) {
                NChangeScalarAction theWidthChange = new NChangeScalarAction(startVal + "px", endVal + "px");
                temp.add(theWidthChange);
                theWidthChange.setUp(currEl, "width", 0);
            }

            // Deal with Heights
            startVal = getStartHeight(currEl);
            endVal = getEndHeight(currEl);
            if (startVal != endVal) {
                NChangeScalarAction theHeightChange = new NChangeScalarAction(startVal + "px", endVal + "px");
                temp.add(theHeightChange);
                theHeightChange.setUp(currEl, "height", 0);
            }

            // Deal with Fonts
            String res = StyleImplementation.getComputedStyle(currEl, "fontSize");

            if (res != null) {
                // We have a font to play with
                String unit = StyleImplementation.getUnits(res);
                double value = -1;
                if (unit == null || unit.equals("")) {
                    // Assume we're dealing with a named font-size, as there are no units
                    // so, find where this name is in our vector of font size names
                    int scale = fontSizes.indexOf(res);
                    // If we found it, calculate the font size
                    if (scale > -1) {
                        value = (double) Math
                                .round(Math.pow(fontSizeScalingFactor, (scale - standardIndex)) * standardFontSize);
                        unit = standardFontUnit;
                    }
                } else {
                    // Not a named font-size, so get the value
                    value = (new Double(StyleImplementation.getValue(res, unit))).doubleValue();
                }
                if (value > -1) {
                    NChangeScalarAction theFontChange = new NChangeScalarAction((int) (value * startXRatio) + unit,
                            (int) (value * endXRatio) + unit);
                    theFontChange.setUp(currEl, "fontSize", 0);
                    temp.add(theFontChange);
                } else {
                    GWT.log("Don't know what to do with this font-size definition: " + res, null);
                }
            }

            // Do we need to manage bounding box aspects, e.g. margin etc?
            if (managesMargin)
                temp.addAll(getBoxChanges("margin", currEl));
            if (managesBorder)
                temp.addAll(getBoxChanges("border", currEl));
            if (managesPadding)
                temp.addAll(getBoxChanges("padding", currEl));

            // Put all ChangeInterfaces together into the determinedEffects object for future management
            determinedEffects.put(currEl, temp);

        } else {
            GWT.log("Resize Effect is Not Processing: " + name, null);
        }
        temp = null;
    }

    protected Vector<NChangeScalarAction> getBoxChanges(String boxAspect, Element currEl) {
        Vector<NChangeScalarAction> temp2 = new Vector<NChangeScalarAction>();
        String end = "";

        if (boxAspect.equals("border"))
            end = "Width";

        int startVal;
        int endVal;

        startVal = getStartBoxHoriz(boxAspect + "Left" + end, currEl);
        endVal = getEndBoxHoriz(boxAspect + "Left" + end, currEl);
        if (startVal != endVal) {
            NChangeScalarAction marginLeft = new NChangeScalarAction(startVal + "px", endVal + "px");
            marginLeft.setUp(currEl, boxAspect + "Left" + end, 0);
            temp2.add(marginLeft);
        }

        startVal = getStartBoxVert(boxAspect + "Bottom" + end, currEl);
        endVal = getEndBoxVert(boxAspect + "Bottom" + end, currEl);
        if (startVal != endVal) {
            NChangeScalarAction marginBottom = new NChangeScalarAction(startVal + "px", endVal + "px");
            marginBottom.setUp(currEl, boxAspect + "Bottom" + end, 0);
            temp2.add(marginBottom);
        }

        startVal = getStartBoxHoriz(boxAspect + "Right" + end, currEl);
        endVal = getEndBoxHoriz(boxAspect + "Right" + end, currEl);
        if (startVal != endVal) {
            NChangeScalarAction marginRight = new NChangeScalarAction(startVal + "px", endVal + "px");
            marginRight.setUp(currEl, boxAspect + "Right" + end, 0);
            temp2.add(marginRight);
        }

        startVal = getStartBoxVert(boxAspect + "Top" + end, currEl);
        endVal = getEndBoxVert(boxAspect + "Top" + end, currEl);
        if (startVal != endVal) {
            NChangeScalarAction marginTop = new NChangeScalarAction(startVal + "px", endVal + "px");
            marginTop.setUp(currEl, boxAspect + "Top" + end, 0);
            temp2.add(marginTop);
        }
        return temp2;
    }

    // Do not manage margin, padding etc by default.
    boolean managesMargin = false;

    public boolean isManagesMargin() {
        return managesMargin;
    }

    public void setManagesMargin(boolean managesMargin) {
        this.managesMargin = managesMargin;
    }

    public boolean isManagesBorder() {
        return managesBorder;
    }

    public void setManagesBorder(boolean managesBorder) {
        this.managesBorder = managesBorder;
    }

    public boolean isManagesPadding() {
        return managesPadding;
    }

    public void setManagesPadding(boolean managesPadding) {
        this.managesPadding = managesPadding;
    }

    boolean managesBorder = false;
    boolean managesPadding = false;

    protected int getBoxSizeVert() {
        return 0;
    }

    protected int getBoxSizeHoriz() {
        return 0;
    }

    protected int getEndHeight(Element theWidget) {
        //int val = (int) ((theWidget.getOffsetHeight() - (2*getBoxSizeVert())) * endYRatio);
        int val = (int) (Double.parseDouble(
                StyleImplementation.getValue(StyleImplementation.getComputedStyle(theWidget, "height")))
                * endYRatio);
        return val;
    }

    protected int getEndBoxHoriz(String css, Element theWidget) {
        String val = StyleImplementation.getComputedStyle(theWidget, css);
        if (!val.equals("auto") && !val.equals("undefined")) {
            double dVal = Double.parseDouble(StyleImplementation.getValue(val));
            return (int) (dVal * endXRatio);
        } else {
            GWT.log("Unable to calculate style " + css + " for widget", null);
            return -1;
        }
    }

    protected int getStartBoxHoriz(String css, Element theWidget) {
        String val = StyleImplementation.getComputedStyle(theWidget, css);
        if (!val.equals("auto") && !val.equals("undefined")) {
            double dVal = Double.parseDouble(StyleImplementation.getValue(val));
            return (int) (dVal * startXRatio);
        } else {
            GWT.log("Unable to calculate style " + css + " for widget", null);
            return -1;
        }
    }

    protected int getEndBoxVert(String css, Element theWidget) {
        String val = StyleImplementation.getComputedStyle(theWidget, css);
        if (!val.equals("auto") && !val.equals("undefined")) {
            double dVal = Double.parseDouble(StyleImplementation.getValue(val));
            return (int) (dVal * endYRatio);
        } else {
            GWT.log("Unable to calculate style " + css + " for widget", null);
            return -1;
        }
    }

    protected int getStartBoxVert(String css, Element theWidget) {
        String val = StyleImplementation.getComputedStyle(theWidget, css);
        if (!val.equals("auto") && !val.equals("undefined")) {
            double dVal = Double.parseDouble(StyleImplementation.getValue(val));
            return (int) (dVal * startYRatio);
        } else {
            GWT.log("Unable to calculate style " + css + " for widget", null);
            return -1;
        }
    }

    protected int getEndLeft(Element theWidget) {
        if (horizAlign == HasHorizontalAlignment.ALIGN_RIGHT) {
            return (int) (((double) theWidget.getOffsetWidth() / 2 - theWidget.getOffsetWidth() * endXRatio) / 2);
        } else {
            return (int) ((theWidget.getOffsetWidth() - theWidget.getOffsetWidth() * endXRatio) / 4);
        }
    }

    protected int getEndTop(Element theWidget) {
        if (vertAlign == HasVerticalAlignment.ALIGN_BOTTOM) {
            return (int) ((double) theWidget.getOffsetHeight() / 2)
                    - (int) (theWidget.getOffsetHeight() * endYRatio / 2);
        } else {
            return (int) ((double) theWidget.getOffsetHeight() / 4)
                    - (int) (theWidget.getOffsetHeight() * endYRatio / 4);
        }
    }

    protected int getEndWidth(Element theWidget) {
        //int val = (int) ((theWidget.getOffsetWidth()  - (2*getBoxSizeHoriz())) * endYRatio);
        int val = (int) (Double
                .parseDouble(StyleImplementation.getValue(StyleImplementation.getComputedStyle(theWidget, "width")))
                * endXRatio);
        return val;
    }

    protected int getStartHeight(Element theWidget) {
        //int val = (int) ((theWidget.getOffsetHeight()  - (2*getBoxSizeVert())) * startYRatio);
        int val = (int) (Double.parseDouble(
                StyleImplementation.getValue(StyleImplementation.getComputedStyle(theWidget, "height")))
                * startYRatio);
        return val;
    }

    protected int getStartLeft(Element theWidget) {
        if (horizAlign == HasHorizontalAlignment.ALIGN_RIGHT) {
            return (int) ((theWidget.getOffsetWidth() - theWidget.getOffsetWidth() * startXRatio) / 2);
        } else {
            return (int) ((theWidget.getOffsetWidth() - theWidget.getOffsetWidth() * startXRatio) / 4);
        }
    }

    protected int getStartTop(Element theWidget) {
        if (vertAlign == HasVerticalAlignment.ALIGN_BOTTOM) {
            return (int) ((double) theWidget.getOffsetHeight() / 2)
                    - (int) (theWidget.getOffsetHeight() * startYRatio / 2);
        } else {
            return (int) ((double) theWidget.getOffsetHeight() / 4)
                    - (int) (theWidget.getOffsetHeight() * startYRatio / 4);
        }
    }

    protected int getStartWidth(Element theWidget) {
        //int val = (int) ((theWidget.getOffsetWidth()  - (2*getBoxSizeHoriz())) * startYRatio);
        int val = (int) (Double
                .parseDouble(StyleImplementation.getValue(StyleImplementation.getComputedStyle(theWidget, "width")))
                * startXRatio);
        return val;

    }

    @Override
    protected void onUpdate(double progress) {
        super.onUpdate(progress);
        for (Iterator<Element> it = determinedEffects.keySet().iterator(); it.hasNext();) {
            Element theChange = it.next();
            Vector<ChangeInterface> currChange = determinedEffects.get(theChange);
            for (int loop = 0; loop < currChange.size(); loop++) {
                currChange.get(loop).performStep(theChange, "", progress);
            }
        }
    }

    /**
     * Set the ending height for the resize.
     * 
     * @param percentage Ending height in percentage.
     */
    public void setEndHeightPercentage(int percentage) {
        assert (percentage >= 0);
        endY = percentage;
    }

    /**
     * Set Ending percentage for width and height
     * 
     * @param percentage
     */
    public void setEndPercentage(int percentage) {
        setEndHeightPercentage(percentage);
        setEndWidthPercentage(percentage);
    }

    /**
     * Set the ending width for the resize.
     * 
     * @param percentage Ending width in percentage.
     */
    public void setEndWidthPercentage(int percentage) {
        assert (percentage >= 0);
        endX = percentage;
    }

    public void setHorizAlignment(HorizontalAlignmentConstant newHorizAlign) {
        horizAlign = newHorizAlign;
    }

    /**
     * Set the starting height for the resize.
     * 
     * @param percentage Starting height in percentage.
     */
    public void setStartHeightPercentage(int percentage) {
        assert (percentage >= 0);
        startY = percentage;
    }

    /**
     * Set Starting percentage for width and height;
     * 
     * @param percentage
     */
    public void setStartPercentage(int percentage) {
        setStartHeightPercentage(percentage);
        setStartWidthPercentage(percentage);
    }

    /**
     * Set the starting width for the resize.
     * 
     * @param percentage Starting width in percentage.
     */
    public void setStartWidthPercentage(int percentage) {
        assert (percentage >= 0);
        startX = percentage;
    }

    @Override
    public void setUpEffect() {
        registerEffectElement();
        if (effectElement == null)
            effectElement = (Element) effectElements.get(0);

        startXRatio = (double) startX / 100;
        startYRatio = (double) startY / 100;
        endXRatio = (double) endX / 100;
        endYRatio = (double) endY / 100;

        if (determinedEffects == null)
            determinedEffects = new HashMap<Element, Vector<ChangeInterface>>();
        else
            determinedEffects.clear();

        Vector<ChangeInterface> temp2 = null;

        // Deal with top if not default to align_top
        if (vertAlign != HasVerticalAlignment.ALIGN_TOP) {
            if (temp2 == null)
                temp2 = new Vector<ChangeInterface>();
            NChangeScalarAction theTopChange = new NChangeScalarAction(getStartTop((Element) effectElement) + "px",
                    getEndTop((Element) effectElement) + "px");
            theTopChange.setUp(effectElement, "top", 0);
            temp2.add(theTopChange);
        }
        if (horizAlign != HasHorizontalAlignment.ALIGN_LEFT) {
            if (temp2 == null)
                temp2 = new Vector<ChangeInterface>();
            NChangeScalarAction theLeftChange = new NChangeScalarAction(
                    getStartLeft((Element) effectElement) + "px", getEndLeft((Element) effectElement) + "px");
            theLeftChange.setUp(effectElement, "left", 0);
            temp2.add(theLeftChange);
        }
        if (temp2 != null)
            determinedEffects.put((Element) effectElement, temp2);

        createInternalEffectsPerElement((Element) effectElement);

        GWT.log("Number of Determined Effects: " + determinedEffects.size(), null);

        // Set up the font-size name list
        fontSizes.add("xx-small");
        fontSizes.add("x-small");
        fontSizes.add("small");
        fontSizes.add("medium");
        fontSizes.add("large");
        fontSizes.add("x-large");
        fontSizes.add("xx-large");

        this.isInitialised = true;
    }

    public void setVertAlignment(VerticalAlignmentConstant newVertAlign) {
        vertAlign = newVertAlign;
    }

    @Override
    public void tearDownEffect() {
        for (Iterator<Element> it = determinedEffects.keySet().iterator(); it.hasNext();) {
            Element theChange = it.next();
            Vector<ChangeInterface> currChange = determinedEffects.get(theChange);
            for (int loop = 0; loop < currChange.size(); loop++) {
                currChange.get(loop).performStep(theChange, "", 0);
            }
        }
        determinedEffects = null;
    }

    public String toString() {
        String toRet = "";
        for (Iterator<Element> it = determinedEffects.keySet().iterator(); it.hasNext();) {
            Element theChange = it.next();
            Vector<ChangeInterface> currChange = determinedEffects.get(theChange);
            for (int loop = 0; loop < currChange.size(); loop++) {
                toRet += currChange.get(loop).toString() + "; ";
            }
        }
        return toRet;
    }
}