001package gwt.material.design.addins.client.swipeable; 002 003/* 004 * #%L 005 * GwtMaterial 006 * %% 007 * Copyright (C) 2015 - 2016 GwtMaterialDesign 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022 023/* 024 * Copyright 2008 Google Inc. 025 * 026 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 027 * use this file except in compliance with the License. You may obtain a copy of 028 * the License at 029 * 030 * http://www.apache.org/licenses/LICENSE-2.0 031 * 032 * Unless required by applicable law or agreed to in writing, software 033 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 034 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 035 * License for the specific language governing permissions and limitations under 036 * the License. 037 */ 038 039import com.google.gwt.dom.client.Document; 040import com.google.gwt.dom.client.Element; 041import com.google.gwt.event.shared.HandlerRegistration; 042import com.google.gwt.user.client.ui.Widget; 043import gwt.material.design.addins.client.MaterialAddins; 044import gwt.material.design.addins.client.swipeable.base.HasSwipeable; 045import gwt.material.design.addins.client.swipeable.events.SwipeLeftEvent; 046import gwt.material.design.addins.client.swipeable.events.SwipeRightEvent; 047import gwt.material.design.client.MaterialDesignBase; 048import gwt.material.design.client.base.MaterialWidget; 049 050/** 051 * A panel that allows any of its nested children to be swiped away. 052 * 053 * <h3>XML Namespace Declaration</h3> 054 * <pre> 055 * {@code 056 * xmlns:ma='urn:import:gwt.material.design.addins.client' 057 * } 058 * </pre> 059 * 060 * <h3>UiBinder Usage:</h3> 061 * <pre> 062 *{ 063 * @code 064 * <ma:swipeable.MaterialSwipeablePanel ui:field="swipeablePanel" shadow="1" backgroundColor="white" padding="12"> 065 * <m:MaterialLabel text="You can swipe native components. This is a plain label" backgroundColor="yellow" padding="12" /> 066 * <m:MaterialCard> 067 * <m:MaterialCardContent> 068 * <m:MaterialLabel text="This is another Card Component that is swipeable." /> 069 * </m:MaterialCardContent> 070 * </m:MaterialCard> 071 * </ma:swipeable.MaterialSwipeablePanel> 072 * } 073 * </pre> 074 * @see <a href="http://gwtmaterialdesign.github.io/gwt-material-demo/#swipeable">Material Swipeable</a> 075 * @author kevzlou7979 076 * @author Ben Dol 077 */ 078//@formatter:on 079public class MaterialSwipeablePanel extends MaterialWidget implements HasSwipeable<Widget> { 080 081 static { 082 if(MaterialAddins.isDebug()) { 083 MaterialDesignBase.injectCss(MaterialSwipeableDebugClientBundle.INSTANCE.swipeableCssDebug()); 084 } else { 085 MaterialDesignBase.injectCss(MaterialSwipeableClientBundle.INSTANCE.swipeableCss()); 086 } 087 } 088 089 private final String DISABLED = "disabled-swipe"; 090 091 public MaterialSwipeablePanel() { 092 super(Document.get().createDivElement(), "swipeable"); 093 } 094 095 @Override 096 protected void onLoad() { 097 super.onLoad(); 098 for(Widget w : getChildren()) { 099 if(!w.getStyleName().contains(DISABLED)) { 100 initSwipeable(w.getElement(), w); 101 } 102 } 103 } 104 105 106 @Override 107 public void initSwipeable(Element element, Widget target) { 108 initSwipeableElement(element, target); 109 } 110 111 /** 112 * Initialize the swipeable element 113 * @param element 114 * @param target 115 */ 116 protected native void initSwipeableElement(Element element, Widget target) /*-{ 117 var that = this; 118 var swipeLeftToRight; 119 var swipeRightToLeft; 120 // Dismissible Collections 121 $wnd.jQuery(element).each(function() { 122 $wnd.jQuery(this).hammer({ 123 prevent_default: false 124 }).bind('pan', function(e) { 125 if (e.gesture.pointerType === "touch") { 126 var parent = $wnd.jQuery(this); 127 var direction = e.gesture.direction; 128 var x = e.gesture.deltaX; 129 var velocityX = e.gesture.velocityX; 130 131 parent.velocity({ translateX: x 132 }, {duration: 50, queue: false, easing: 'easeOutQuad'}); 133 134 // Swipe Left 135 if (direction === 4 && (x > (parent.innerWidth() / 2) || velocityX < -0.75)) { 136 swipeLeftToRight = true; 137 } 138 139 // Swipe Right 140 if (direction === 2 && (x < (-1 * parent.innerWidth() / 2) || velocityX > 0.75)) { 141 swipeRightToLeft = true; 142 } 143 } 144 }).bind('panend', function(e) { 145 // Reset if collection is moved back into original position 146 if (Math.abs(e.gesture.deltaX) < ($wnd.jQuery(this).innerWidth() / 2)) { 147 swipeRightToLeft = false; 148 swipeLeftToRight = false; 149 } 150 151 if (e.gesture.pointerType === "touch") { 152 var parent = $wnd.jQuery(this); 153 if (swipeLeftToRight || swipeRightToLeft) { 154 var fullWidth; 155 if (swipeLeftToRight) { 156 fullWidth = parent.innerWidth(); 157 that.@gwt.material.design.addins.client.swipeable.MaterialSwipeablePanel::fireSwipeRightEvent(*)(target); 158 } 159 else { 160 fullWidth = -1 * parent.innerWidth(); 161 that.@gwt.material.design.addins.client.swipeable.MaterialSwipeablePanel::fireSwipeLeftEvent(*)(target); 162 } 163 164 parent.velocity({ translateX: fullWidth, 165 }, {duration: 100, queue: false, easing: 'easeOutQuad', complete: 166 function() { 167 parent.css('border', 'none'); 168 parent.velocity({ height: 0, padding: 0, 169 }, {duration: 200, queue: false, easing: 'easeOutQuad', complete: 170 function() { 171 parent.remove(); 172 } 173 }); 174 } 175 }); 176 } 177 else { 178 parent.velocity({ translateX: 0, 179 }, {duration: 100, queue: false, easing: 'easeOutQuad'}); 180 } 181 swipeLeftToRight = false; 182 swipeRightToLeft = false; 183 } 184 }); 185 186 }); 187 }-*/; 188 189 @Override 190 public HandlerRegistration addSwipeLeft(final SwipeLeftEvent.SwipeLeftHandler<Widget> handler) { 191 return addHandler(new SwipeLeftEvent.SwipeLeftHandler<Widget>() { 192 @Override 193 public void onSwipeLeft(SwipeLeftEvent<Widget> event) { 194 if(isEnabled()){ 195 handler.onSwipeLeft(event); 196 } 197 } 198 }, SwipeLeftEvent.getType()); 199 } 200 201 @Override 202 public HandlerRegistration addSwipeRight(final SwipeRightEvent.SwipeRightHandler<Widget> handler) { 203 return addHandler(new SwipeRightEvent.SwipeRightHandler<Widget>() { 204 @Override 205 public void onSwipeRight(SwipeRightEvent<Widget> event) { 206 if(isEnabled()){ 207 handler.onSwipeRight(event); 208 } 209 } 210 }, SwipeRightEvent.getType()); 211 } 212 213 /** 214 * Fire the Swipe left event listener 215 * @param target 216 */ 217 public void fireSwipeLeftEvent(Widget target) { 218 SwipeLeftEvent.fire(MaterialSwipeablePanel.this, target); 219 } 220 221 /** 222 * Fire the Swipe right event listener 223 * @param target 224 */ 225 public void fireSwipeRightEvent(Widget target) { 226 SwipeRightEvent.fire(MaterialSwipeablePanel.this, target); 227 } 228 229 public void setDisable(Widget... widgets) { 230 for(Widget w : widgets){ 231 w.addStyleName(DISABLED); 232 } 233 } 234}