com.totsp.gwittir.client.fx.ui.SoftScrollArea.java Source code

Java tutorial

Introduction

Here is the source code for com.totsp.gwittir.client.fx.ui.SoftScrollArea.java

Source

/* SoftScrollPanel.java
*
* Created on August 16, 2007, 9:11 AM
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/
package com.totsp.gwittir.client.fx.ui;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.MouseListener;
import com.google.gwt.user.client.ui.MouseListenerAdapter;
import com.google.gwt.user.client.ui.ScrollListener;
import com.google.gwt.user.client.ui.ScrollListenerCollection;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.SourcesMouseEvents;
import com.google.gwt.user.client.ui.SourcesScrollEvents;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwt.user.client.ui.Widget;
import com.totsp.gwittir.client.beans.Introspectable;
import com.totsp.gwittir.client.fx.AnimationFinishedCallback;
import com.totsp.gwittir.client.fx.MutationStrategy;
import com.totsp.gwittir.client.fx.PositionWrapper;
import com.totsp.gwittir.client.fx.PropertyAnimator;
import com.totsp.gwittir.client.log.Level;
import com.totsp.gwittir.client.log.Logger;
import com.totsp.gwittir.client.ui.HasWidget;
import com.totsp.gwittir.client.util.UnitsParser;

/**
 *
 * @author <a href="mailto:cooper@screaming-penguin.com">Robert "kebernet" Cooper</a>
 */
public class SoftScrollArea extends Composite
        implements HasWidget, Introspectable, SourcesScrollEvents, SourcesMouseEvents {
    private PositionWrapper position;
    PropertyAnimator horizontalAnimator;
    PropertyAnimator scrollAnimator;
    private ScrollListenerCollection listeners = new ScrollListenerCollection();
    private FocusPanel fp = new FocusPanel();
    private SimplePanel base = new SimplePanel();
    private Widget widget;
    private boolean limit = true;
    private int defaultAnimationDuration = 500;
    private int horizOverride = Integer.MIN_VALUE;
    private int scrollOverride = Integer.MIN_VALUE;

    /** Creates a new instance of SoftScrollPanel */
    public SoftScrollArea() {
        DOM.setStyleAttribute(base.getElement(), "overflow", "hidden");
        fp.setWidget(base);
        super.initWidget(fp);
        this.setStyleName("gwittir-SoftScrollArea");
    }

    public SoftScrollArea(boolean limit) {
        this();
        this.limit = limit;
    }

    public void addScrollListener(ScrollListener listener) {
        this.listeners.add(listener);
    }

    public void animateToHorizontalScrollPosition(int newPosition, MutationStrategy integerStrategy, int duration) {
        int max = widget.getOffsetWidth() - base.getOffsetWidth();

        if (limit & (newPosition > max)) {
            newPosition = max;
        }

        if (limit & (newPosition < 0)) {
            newPosition = 0;
        }

        if (this.horizontalAnimator != null) {
            this.horizontalAnimator.cancel();
        }

        horizontalAnimator = new PropertyAnimator(this, "horizontalScrollPosition", new Integer(newPosition),
                integerStrategy, duration, new AnimationFinishedCallback() {
                    public void onFinish(PropertyAnimator animator) {
                        horizOverride = Integer.MIN_VALUE;
                        horizontalAnimator = null;
                    }

                    public void onFailure(PropertyAnimator animator, Exception e) {
                        horizOverride = Integer.MIN_VALUE;
                        horizontalAnimator = null;
                    }
                });
        horizOverride = newPosition;
        this.horizontalAnimator.start();
    }

    public void animateToHorizontalScrollPosition(int newPosition) {
        this.animateToHorizontalScrollPosition(newPosition, MutationStrategy.INTEGER_SINOIDAL,
                this.getDefaultAnimationDuration());
    }

    public void animateToScrollPosition(int newPosition, MutationStrategy integerStrategy, int duration) {
        int max = widget.getOffsetHeight() - base.getOffsetHeight();

        if (limit & (newPosition > max)) {
            newPosition = max;
        }

        if (limit & (newPosition < 0)) {
            newPosition = 0;
        }

        if (this.scrollAnimator != null) {
            scrollAnimator.cancel();
        }

        this.scrollAnimator = new PropertyAnimator(this, "scrollPosition", new Integer(newPosition),
                integerStrategy, duration, new AnimationFinishedCallback() {
                    public void onFinish(PropertyAnimator animator) {
                        scrollOverride = Integer.MIN_VALUE;
                        scrollAnimator = null;
                    }

                    public void onFailure(PropertyAnimator animator, Exception e) {
                        scrollOverride = Integer.MIN_VALUE;
                        scrollAnimator = null;
                    }
                });
        this.scrollOverride = newPosition;
        this.scrollAnimator.start();
    }

    public void animateToScrollPosition(int newPosition) {
        this.animateToScrollPosition(newPosition, MutationStrategy.INTEGER_SINOIDAL,
                this.getDefaultAnimationDuration());
    }

    public void ensureVisible(UIObject uiobject) {
        int scroll = this.ensureVisiblePosition(widget.getElement(), uiobject.getElement());
        int horiz = this.ensureVisibleHortizontalPosition(widget.getElement(), uiobject.getElement());
        this.setScrollPosition(scroll);
        this.setHorizontalScrollPosition(horiz);
    }

    public void ensureVisibleAnimated(UIObject uiobject) {
        int scroll = this.ensureVisiblePosition(widget.getElement(), uiobject.getElement());
        int horiz = this.ensureVisibleHortizontalPosition(widget.getElement(), uiobject.getElement());
        this.animateToScrollPosition(scroll);
        this.animateToHorizontalScrollPosition(horiz);
    }

    private native int ensureVisibleHortizontalPosition(Element position, Element e) /*-{
                                                                                     if (!e)
                                                                                     return;
                                                                                         
                                                                                     var item = e;
                                                                                     var realOffset = 0;
                                                                                     while (item && (item != position)) {
                                                                                     realOffset += item.offsetLeft;
                                                                                     item = item.offsetParent;
                                                                                     }
                                                                                     return realOffset + position.offsetWidth/2;
                                                                                     }-*/;

    private native int ensureVisiblePosition(Element position, Element e) /*-{
                                                                          if (!e)
                                                                          return;
                                                                              
                                                                          var item = e;
                                                                          var realOffset = 0;
                                                                          while (item && (item != position)) {
                                                                          realOffset += item.offsetTop;
                                                                          item = item.offsetParent;
                                                                          }                                                                      
                                                                          return  (realOffset - position.offsetHeight/2 ) + e.offsetHeight ;
                                                                          }-*/;

    public int getDefaultAnimationDuration() {
        return defaultAnimationDuration;
    }

    public int getHorizontalScrollPosition() {
        return (this.horizOverride == Integer.MIN_VALUE) ? (-1 * UnitsParser.parse(position.getLeft()).value)
                : this.horizOverride;
    }

    public int getMaxHorizontalScrollPosition() {
        int max = limit ? (widget.getOffsetWidth() - base.getOffsetWidth()) : Integer.MAX_VALUE;

        return (max < 0) ? 0 : max;
    }

    public int getMaxScrollPosition() {
        int max = limit ? (widget.getOffsetHeight() - base.getOffsetHeight()) : Integer.MAX_VALUE;

        return (max < 0) ? 0 : max;
    }

    public int getScrollPosition() {
        return (this.scrollOverride == Integer.MIN_VALUE) ? (-1 * UnitsParser.parse(position.getTop()).value)
                : this.scrollOverride;
    }

    public Widget getWidget() {
        return widget;
    }

    protected void onAttach() {
        super.onAttach();
        this.setScrollPosition(this.getScrollPosition());
    }

    public void pageDown() {
        this.setScrollPosition(this.getScrollPosition() + this.base.getOffsetHeight());
    }

    public void pageDownAnimated() {
        this.animateToScrollPosition(this.getScrollPosition() + this.base.getOffsetHeight());
    }

    public void pageLeft() {
        this.setHorizontalScrollPosition(this.getHorizontalScrollPosition() - this.base.getOffsetWidth());
    }

    public void pageLeftAnimated() {
        this.animateToHorizontalScrollPosition(this.getHorizontalScrollPosition() - this.base.getOffsetWidth());
    }

    public void pageRight() {
        this.setHorizontalScrollPosition(this.getHorizontalScrollPosition() + this.base.getOffsetWidth());
    }

    public void pageRightAnimated() {
        this.animateToHorizontalScrollPosition(this.getHorizontalScrollPosition() + this.base.getOffsetWidth());
    }

    public void pageUp() {
        this.setScrollPosition(this.getScrollPosition() - this.base.getOffsetHeight());
    }

    public void pageUpAnimated() {
        this.animateToScrollPosition(this.getScrollPosition() - this.base.getOffsetHeight());
    }

    public void removeScrollListener(ScrollListener listener) {
        this.listeners.add(listener);
    }

    public void setDefaultAnimationDuration(int defaultAnimationDuration) {
        this.defaultAnimationDuration = defaultAnimationDuration;
    }

    public void setHorizontalScrollPosition(int position) {
        int max = widget.getOffsetWidth() - base.getOffsetWidth();

        if (limit & (position > max)) {
            position = max;
        }

        if (limit & (position < 0)) {
            position = 0;
        }

        this.position.setLeft((-1 * position) + "px");
        this.listeners.fireScroll(this, this.getHorizontalScrollPosition(), this.getScrollPosition());
    }

    public void setScrollPosition(int position) {
        int max = widget.getOffsetHeight() - base.getOffsetHeight();

        if (limit & (position > max)) {
            position = max;
        }

        if (limit & (position < 0)) {
            position = 0;
        }

        this.position.setTop((-1 * position) + "px");
        this.listeners.fireScroll(this, this.getHorizontalScrollPosition(), this.getScrollPosition());
    }

    public void setWidget(Widget widget) {
        this.widget = widget;
        this.position = new PositionWrapper(widget);
        this.position.setPosition("relative");
        this.position.setTop("0px");
        this.position.setLeft("0px");
        this.base.setWidget(widget);
    }

    public void addMouseListener(MouseListener listener) {
        this.fp.addMouseListener(listener);
    }

    public void removeMouseListener(MouseListener listener) {
        this.fp.removeMouseListener(listener);
    }

    public void setHeight(String height) {
        this.fp.setHeight(height);
        this.base.setHeight(height);
    }

    public void setWidth(String width) {
        this.fp.setWidth(width);
        this.base.setWidth(width);
    }

    public void setPixelSize(int width, int height) {
        this.fp.setPixelSize(width, height);
        this.base.setPixelSize(width, height);
    }

    public void setSize(String width, String height) {
        this.fp.setSize(width, height);
        this.base.setSize(width, height);
    }

    public final MouseListener MOUSE_MOVE_SCROLL_LISTENER = new MouseListenerAdapter() {

        public void onMouseMove(Widget sender, int x, int y) {
            Logger.getAnonymousLogger().log(Level.SPAM, x + " " + y, null);
            int baseX = getOffsetWidth();
            int baseY = getOffsetHeight();
            double percentX = (double) x / (double) baseX;
            double percentY = (double) y / (double) baseY;
            Integer currentX = (Integer) MutationStrategy.INTEGER_SINOIDAL.mutateValue(new Integer(0),
                    new Integer(getMaxHorizontalScrollPosition()), percentX);
            Integer currentY = (Integer) MutationStrategy.INTEGER_SINOIDAL.mutateValue(new Integer(0),
                    new Integer(getMaxScrollPosition()), percentY);
            setHorizontalScrollPosition(currentX.intValue());
            setScrollPosition(currentY.intValue());
        }
    };

}