001package gwt.material.design.client.ui; 002 003/* 004 * #%L 005 * GwtMaterial 006 * %% 007 * Copyright (C) 2015 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 023import gwt.material.design.client.base.MaterialWidget; 024import gwt.material.design.client.base.HasDismissable; 025import gwt.material.design.client.base.HasTransition; 026import gwt.material.design.client.base.HasType; 027import gwt.material.design.client.base.mixin.CssTypeMixin; 028import gwt.material.design.client.constants.ModalType; 029 030import com.google.gwt.dom.client.Document; 031import com.google.gwt.dom.client.Element; 032import com.google.gwt.event.logical.shared.CloseEvent; 033import com.google.gwt.event.logical.shared.CloseHandler; 034import com.google.gwt.event.logical.shared.HasCloseHandlers; 035import com.google.gwt.event.shared.HandlerRegistration; 036 037//@formatter:off 038 039/** 040 * Dialogs are content that are not original visible on a page but show up with 041 * extra information if needed. The transitions should make the appearance of 042 * the dialog make sense and not jarring to the user. 043 * 044 * 045 * <p> 046 * <h3>UiBinder Usage:</h3> 047 * 048 * <pre> 049 * {@code 050 * <m:MaterialModal ui:field="modal" type="FIXED_FOOTER" dismissable="true" inDuration="500" outDuration="800"> 051 * <m:MaterialModalContent> 052 * <m:MaterialTitle title="Title" description="Description" /> 053 * </m:MaterialModalContent> 054 * <m:MaterialModalFooter> 055 * <m:MaterialButton text="Close Modal" type="FLAT"/> 056 * </m:MaterialModalFooter> 057 * </m:MaterialModal> 058 * } 059 * </pre> 060 * 061 * * 062 * <h3>Java Usage:</h3> 063 * 064 * <pre> 065 * { 066 * @code 067 * @UiField 068 * MaterialModal modal; 069 * modal.openModal(); 070 * } 071 * </pre> 072 * 073 * </p> 074 * 075 * @author kevzlou7979 076 * @author Ben Dol 077 * @see <a href="http://gwt-material-demo.herokuapp.com/#dialogs">Material 078 * Modals</a> 079 */ 080// @formatter:on 081public class MaterialModal extends MaterialWidget implements HasType<ModalType>, HasTransition, 082 HasDismissable, HasCloseHandlers<MaterialModal> { 083 084 private final CssTypeMixin<ModalType, MaterialModal> typeMixin = new CssTypeMixin<>(this); 085 private int inDuration = 300; 086 private int outDuration = 200; 087 private boolean dismissable = false; 088 private double opacity = 0.5; 089 090 public MaterialModal() { 091 super(Document.get().createDivElement(), "modal"); 092 } 093 094 /** 095 * Open the modal programatically 096 * 097 * <p> 098 * Note: the MaterialModal component must be added to the document before 099 * calling this method. When declaring this modal on a UiBinder file, the 100 * MaterialModal is already added, but if you call it using pure Java, you 101 * must add it to a container before opening the modal. You can do it by 102 * calling, for example: 103 * </p> 104 * 105 * <pre> 106 * MaterialModal modal = new MaterialModal(); 107 * RootPanel.get().add(modal); 108 * </pre> 109 * 110 * @throws IllegalStateException 111 * If the MaterialModal is not added to the document 112 */ 113 public void openModal() { 114 // the modal must be added to the document before opening 115 if (this.getParent() == null) { 116 throw new IllegalStateException( 117 "The MaterialModal must be added to the document before calling openModal()."); 118 } 119 openModal(getElement(), opacity, dismissable, inDuration, outDuration); 120 } 121 122 /** 123 * Open modal with additional properties 124 * 125 * @param e 126 * - Modal Component 127 * @param opacity 128 * - Opacity of modal background 129 * @param dismissable 130 * - Modal can be dismissed by clicking outside of the modal 131 * @param inDuration 132 * - Transition in Duration 133 * @param outDuration 134 * - Transition out Duration 135 */ 136 protected native void openModal(Element e, double opacity, boolean dismissable, int inDuration, int outDuration) /*-{ 137 var obj = this; 138 $wnd.jQuery(e).openModal({ 139 opacity: opacity, 140 dismissible: dismissable, 141 in_duration: inDuration, 142 out_duration: outDuration, 143 complete: function () { obj.@gwt.material.design.client.ui.MaterialModal::onNativeClose(Z)(true); } 144 }); 145 }-*/; 146 147 protected void onNativeClose(boolean autoClosed) { 148 CloseEvent.fire(this, this, autoClosed); 149 } 150 151 /** 152 * Close the modal programatically. It is the same as calling 153 * {@link #closeModal(boolean)} with <code>false</code> as parameter. 154 * <p> 155 * Note: you may need to remove it MaterialModal from the document if you 156 * are not using UiBinder. See {@link #openModal()}. 157 * </p> 158 * 159 */ 160 public void closeModal() { 161 closeModal(false); 162 } 163 164 /** 165 * Close the modal programatically. 166 * <p> 167 * Note: you may need to remove it MaterialModal from the document if you 168 * are not using UiBinder. See {@link #openModal()}. 169 * </p> 170 * 171 * @param autoClosed 172 * Flag indicating if the modal was automatically dismissed 173 * 174 * @see CloseEvent 175 */ 176 public void closeModal(boolean autoClosed) { 177 closeModal(getElement(), autoClosed); 178 } 179 180 protected native void closeModal(Element e, boolean autoClosed) /*-{ 181 var obj = this; 182 $wnd.jQuery(e).closeModal({ 183 complete: function () { obj.@gwt.material.design.client.ui.MaterialModal::onNativeClose(Z)(autoClosed); } 184 }); 185 }-*/; 186 187 @Override 188 public void setType(ModalType type) { 189 typeMixin.setType(type); 190 } 191 192 @Override 193 public ModalType getType() { 194 return typeMixin.getType(); 195 } 196 197 @Override 198 public void setInDuration(int inDuration) { 199 this.inDuration = inDuration; 200 } 201 202 @Override 203 public void setOutDuration(int outDuration) { 204 this.outDuration = outDuration; 205 } 206 207 @Override 208 public void setDismissable(boolean dismissable) { 209 this.dismissable = dismissable; 210 } 211 212 @Override 213 public boolean isDismissable() { 214 return dismissable; 215 } 216 217 @Override 218 public void setOpacity(double opacity) { 219 this.opacity = opacity; 220 } 221 222 @Override 223 public HandlerRegistration addCloseHandler(CloseHandler<MaterialModal> handler) { 224 return this.addHandler(handler, CloseEvent.getType()); 225 } 226 227}