001/* 002 * #%L 003 * GwtMaterial 004 * %% 005 * Copyright (C) 2015 - 2017 GwtMaterialDesign 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package gwt.material.design.addins.client.overlay; 021 022import com.google.gwt.dom.client.Document; 023import com.google.gwt.dom.client.Element; 024import com.google.gwt.dom.client.Style; 025import com.google.gwt.event.logical.shared.*; 026import com.google.gwt.event.shared.HandlerRegistration; 027import gwt.material.design.addins.client.MaterialAddins; 028import gwt.material.design.addins.client.base.constants.AddinsCssName; 029import gwt.material.design.addins.client.pathanimator.MaterialPathAnimator; 030import gwt.material.design.client.MaterialDesignBase; 031import gwt.material.design.client.base.HasDurationTransition; 032import gwt.material.design.client.base.MaterialWidget; 033import gwt.material.design.client.constants.Color; 034 035import static gwt.material.design.jquery.client.api.JQuery.$; 036 037//@formatter:off 038 039/** 040 * It's an overlay panel layout wherein you can put as many widgets as you want and design it. 041 * You can do advance stuff by implementing Path Animator into the overlay panel container. 042 * <p> 043 * <h3>XML Namespace Declaration</h3> 044 * <pre> 045 * {@code 046 * xmlns:ma='urn:import:gwt.material.design.addins.client' 047 * } 048 * </pre> 049 * <p> 050 * <h3>UiBinder Usage:</h3> 051 * <pre> 052 * {@code 053 * <ma:overlay.MaterialOverlay background="blue"> 054 * <-- Some content here --> 055 * </ma:overlay.MaterialOverlay> 056 * } 057 * </pre> 058 * 059 * @author kevzlou7979 060 */ 061//@formatter:on 062public class MaterialOverlay extends MaterialWidget implements HasOpenHandlers<MaterialOverlay>, 063 HasCloseHandlers<MaterialOverlay>, HasDurationTransition { 064 065 static { 066 if (MaterialAddins.isDebug()) { 067 MaterialDesignBase.injectCss(MaterialOverlayDebugClientBundle.INSTANCE.overlayCssDebug()); 068 } else { 069 MaterialDesignBase.injectCss(MaterialOverlayClientBundle.INSTANCE.overlayCss()); 070 } 071 } 072 073 private Element sourceElement; 074 private MaterialPathAnimator animator = new MaterialPathAnimator(); 075 076 public MaterialOverlay() { 077 super(Document.get().createDivElement(), AddinsCssName.OVERLAY_PANEL); 078 } 079 080 public MaterialOverlay(Color backgroundColor) { 081 this(); 082 setBackgroundColor(backgroundColor); 083 } 084 085 public MaterialOverlay(Color backgroundColor, Style.Visibility visibility, Double opacity) { 086 this(backgroundColor); 087 setVisibility(visibility); 088 setOpacity(opacity); 089 } 090 091 public void open(MaterialWidget source) { 092 open(source.getElement()); 093 } 094 095 /** 096 * Open the Overlay Panel with Path Animator applied 097 */ 098 public void open(Element sourceElement) { 099 this.sourceElement = sourceElement; 100 $("body").attr("style", "overflow: hidden !important"); 101 animator.setSourceElement(sourceElement); 102 animator.setTargetElement(getElement()); 103 animator.animate(); 104 OpenEvent.fire(this, this); 105 } 106 107 /** 108 * Open the Overlay Panel without Path Animator 109 */ 110 public void open() { 111 setVisibility(Style.Visibility.VISIBLE); 112 setOpacity(1); 113 OpenEvent.fire(this, this); 114 } 115 116 /** 117 * Close the Overlay Panel with Path Animator applied 118 */ 119 public void close() { 120 if ($(getElement()).parents(AddinsCssName.OVERLAY_PANEL).length() == 1) { 121 body().attr("style", "overflow: hidden !important"); 122 } else { 123 body().attr("style", "overflow: auto !important"); 124 } 125 if (sourceElement != null) { 126 animator.reverseAnimate(); 127 } 128 CloseEvent.fire(this, this); 129 } 130 131 /** 132 * Get source element for path animator 133 */ 134 public Element getSourceElement() { 135 return sourceElement; 136 } 137 138 /** 139 * Set source element for path animator 140 */ 141 public void setSourceElement(Element sourceElement) { 142 this.sourceElement = sourceElement; 143 } 144 145 @Override 146 public int getDuration() { 147 return animator.getDuration(); 148 } 149 150 @Override 151 public void setDuration(int duration) { 152 animator.setDuration(duration); 153 } 154 155 public int getTargetShowDuration() { 156 return animator.getTargetShowDuration(); 157 } 158 159 /** 160 * Duration (in milliseconds) of targetElement to become visible, if hidden initially. The library will automatically try to figure this out from the element's computed styles. Default is 0 seconds. 161 */ 162 public void setTargetShowDuration(int targetShowDuration) { 163 animator.setTargetShowDuration(targetShowDuration); 164 } 165 166 public int getExtraTransitionDuration() { 167 return animator.getExtraTransitionDuration(); 168 } 169 170 /** 171 * Extra duration (in milliseconds) of targetElement to provide visual continuity between the animation and the rendering of the targetElement. Default is 1 second 172 */ 173 public void setExtraTransitionDuration(int extraTransitionDuration) { 174 animator.setExtraTransitionDuration(extraTransitionDuration); 175 } 176 177 public void setRelativeToWindow(boolean relativeToWindow) { 178 animator.setRelativeToWindow(relativeToWindow); 179 } 180 181 public boolean isRelativeToWindow() { 182 return animator.isRelativeToWindow(); 183 } 184 185 @Override 186 public HandlerRegistration addCloseHandler(CloseHandler<MaterialOverlay> closeHandler) { 187 return addHandler(new CloseHandler<MaterialOverlay>() { 188 @Override 189 public void onClose(CloseEvent<MaterialOverlay> closeEvent) { 190 if (isEnabled()) { 191 closeHandler.onClose(closeEvent); 192 } 193 } 194 }, CloseEvent.getType()); 195 } 196 197 @Override 198 public HandlerRegistration addOpenHandler(OpenHandler<MaterialOverlay> openHandler) { 199 return addHandler(new OpenHandler<MaterialOverlay>() { 200 @Override 201 public void onOpen(OpenEvent<MaterialOverlay> openEvent) { 202 if (isEnabled()) { 203 openHandler.onOpen(openEvent); 204 } 205 } 206 }, OpenEvent.getType()); 207 } 208}