gwt.material.design.addins.client.swipeable.MaterialSwipeablePanel Maven / Gradle / Ivy
/*
* #%L
* GwtMaterial
* %%
* Copyright (C) 2015 - 2017 GwtMaterialDesign
* %%
* 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.
* #L%
*/
package gwt.material.design.addins.client.swipeable;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwt.user.client.ui.Widget;
import gwt.material.design.addins.client.MaterialAddins;
import gwt.material.design.addins.client.base.constants.AddinsCssName;
import gwt.material.design.addins.client.gesture.velocity.js.JsTransitionOptions;
import gwt.material.design.addins.client.gesture.velocity.js.JsVelocity;
import gwt.material.design.addins.client.gesture.velocity.js.JsVelocityOptions;
import gwt.material.design.addins.client.swipeable.base.HasSwipeableHandler;
import gwt.material.design.addins.client.swipeable.events.*;
import gwt.material.design.client.MaterialDesignBase;
import gwt.material.design.client.base.JsLoader;
import gwt.material.design.client.base.MaterialWidget;
import gwt.material.design.client.constants.Color;
import gwt.material.design.jquery.client.api.Functions;
import gwt.material.design.jquery.client.api.JQueryElement;
import static gwt.material.design.addins.client.gesture.hammer.js.JsHammer.$;
/**
* A panel that allows any of its nested children to be swiped away.
*
*
XML Namespace Declaration
*
* {@code
* xmlns:ma='urn:import:gwt.material.design.addins.client'
* }
*
*
*
UiBinder Usage:
*
* {
* @code
*
*
*
*
*
*
*
*
* }
*
*
* @author kevzlou7979
* @author Ben Dol
* @see Material Swipeable
*/
//@formatter:on
public class MaterialSwipeablePanel extends MaterialWidget implements JsLoader, HasSwipeableHandler {
static {
if (MaterialAddins.isDebug()) {
MaterialDesignBase.injectDebugJs(MaterialSwipeableDebugClientBundle.INSTANCE.swipeableJsDebug());
MaterialDesignBase.injectCss(MaterialSwipeableDebugClientBundle.INSTANCE.swipeableCssDebug());
} else {
MaterialDesignBase.injectJs(MaterialSwipeableClientBundle.INSTANCE.swipeableJs());
MaterialDesignBase.injectCss(MaterialSwipeableClientBundle.INSTANCE.swipeableCss());
}
}
public MaterialSwipeablePanel() {
super(Document.get().createDivElement(), AddinsCssName.SWIPEABLE);
}
public MaterialSwipeablePanel(Color backgroundColor) {
this();
setBackgroundColor(backgroundColor);
}
public MaterialSwipeablePanel(Color backgroundColor, Integer shadow) {
this(backgroundColor);
setShadow(shadow);
}
@Override
protected void onLoad() {
super.onLoad();
load();
}
@Override
public void load() {
for (Widget w : getChildren()) {
if (!w.getStyleName().contains(AddinsCssName.IGNORED)) {
load(w.getElement(), w);
}
}
}
protected void load(Element container, Widget target) {
JQueryElement parent = $(container);
parent.each((object, element) -> {
boolean swipeLeftToRight[] = {false};
boolean swipeRightToLeft[] = {false};
$(element).hammer().bind("pan", (result) -> {
int direction = result.gesture.direction;
int x = result.gesture.deltaX;
double velocityX = result.gesture.velocityX;
JsVelocity.$(container).velocity(buildVelocityOption(x), buildTransitionOption(50, false, "easeOutQuad", null));
if (direction == 4 && (x > parent.innerWidth() || velocityX < -0.75)) {
swipeLeftToRight[0] = true;
}
if (direction == 2 && (x < (-1 * parent.innerWidth() / 2) || velocityX > 0.75)) {
swipeRightToLeft[0] = true;
}
}).bind("panend", e -> {
// Reset if collection is moved back into original position
if (Math.abs(e.gesture.deltaX) < ($(element).innerWidth() / 2)) {
swipeLeftToRight[0] = false;
swipeRightToLeft[0] = false;
}
// Sets final position once pan ended
if (swipeLeftToRight[0] || swipeRightToLeft[0]) {
double fullWidth = 0;
if (swipeLeftToRight[0]) {
fullWidth = parent.innerWidth();
SwipeRightEvent.fire(MaterialSwipeablePanel.this, target);
}
if (swipeRightToLeft[0]) {
fullWidth = -1 * parent.innerWidth();
SwipeLeftEvent.fire(MaterialSwipeablePanel.this, target);
}
Functions.Func completeCallback = () -> {
parent.css("border", "none");
JsVelocity.$(parent).velocity(buildVelocityOption(0, 0), buildTransitionOption(200, false, "easeQuadOut", () -> parent.remove()));
};
JsVelocity.$(parent).velocity(buildVelocityOption(fullWidth), buildTransitionOption(100, false, "easeOutQuad", completeCallback));
} else {
JsVelocity.$(parent).velocity(buildVelocityOption(0), buildTransitionOption(100, false, "easeQuad", null));
}
});
});
}
@Override
protected void onUnload() {
super.onUnload();
unload();
}
@Override
public void unload() {
for (Widget widget : getChildren()) {
JQueryElement element = $(widget.getElement());
element.off("pan");
element.off("panend");
}
}
@Override
public void reload() {
unload();
load();
}
protected JsVelocityOptions buildVelocityOption(double translateX) {
JsVelocityOptions option = new JsVelocityOptions();
option.translateX = translateX;
return option;
}
protected JsVelocityOptions buildVelocityOption(double height, double padding) {
JsVelocityOptions option = new JsVelocityOptions();
option.height = 0;
option.padding = 0;
return option;
}
protected JsTransitionOptions buildTransitionOption(int duration, boolean queue, String easing, Functions.Func completeCallback) {
JsTransitionOptions option = new JsTransitionOptions();
option.duration = duration;
option.easing = easing;
option.queue = queue;
if (completeCallback != null) {
option.complete = completeCallback;
}
return option;
}
/**
* Ignore any elements to be swipeable
*/
public void ignore(UIObject object, UIObject... objects) {
object.addStyleName(AddinsCssName.IGNORED);
if (objects != null) {
for (UIObject obj : objects) {
obj.addStyleName(AddinsCssName.IGNORED);
}
}
}
/**
* Remove Ignore property to any ignored elements
*/
public void removeIgnore(UIObject object, UIObject... objects) {
object.removeStyleName(AddinsCssName.IGNORED);
if (objects != null) {
for (UIObject obj : objects) {
obj.removeStyleName(AddinsCssName.IGNORED);
}
}
}
@Override
public HandlerRegistration addSwipeLeftHandler(final SwipeLeftEvent.SwipeLeftHandler handler) {
return addHandler(new SwipeLeftEvent.SwipeLeftHandler() {
@Override
public void onSwipeLeft(SwipeLeftEvent event) {
if (isEnabled()) {
handler.onSwipeLeft(event);
}
}
}, SwipeLeftEvent.getType());
}
@Override
public HandlerRegistration addSwipeRightHandler(final SwipeRightEvent.SwipeRightHandler handler) {
return addHandler(new SwipeRightEvent.SwipeRightHandler() {
@Override
public void onSwipeRight(SwipeRightEvent event) {
if (isEnabled()) {
handler.onSwipeRight(event);
}
}
}, SwipeRightEvent.getType());
}
@Override
public HandlerRegistration addOnStartSwipeLeftHandler(OnStartSwipeLeftEvent.OnStartSwipeLeftHandler handler) {
return addHandler(handler, OnStartSwipeLeftEvent.getType());
}
@Override
public HandlerRegistration addOnStartSwipeRightHandler(OnStartSwipeRightEvent.OnStartSwipeRightHandler handler) {
return addHandler(handler, OnStartSwipeRightEvent.getType());
}
@Override
public HandlerRegistration addOnEndSwipeLeftHandler(OnEndSwipeLeftEvent.OnEndSwipeLeftHandler handler) {
return addHandler(handler, OnEndSwipeLeftEvent.getType());
}
@Override
public HandlerRegistration addOnEndSwipeRightHandler(OnEndSwipeRightEvent.OnEndSwipeRightHandler handler) {
return addHandler(handler, OnEndSwipeRightEvent.getType());
}
}