Java tutorial
/* * #%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.signature; import com.google.gwt.dom.client.CanvasElement; import com.google.gwt.dom.client.Document; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.shared.HandlerRegistration; import gwt.material.design.addins.client.MaterialAddins; import gwt.material.design.addins.client.base.constants.AddinsCssName; import gwt.material.design.addins.client.signature.events.HasSignatureHandlers; import gwt.material.design.addins.client.signature.events.SignatureClearEvent; import gwt.material.design.addins.client.signature.events.SignatureEndEvent; import gwt.material.design.addins.client.signature.events.SignatureStartEvent; import gwt.material.design.addins.client.signature.js.JsSignaturePadOptions; import gwt.material.design.addins.client.signature.js.SignaturePad; import gwt.material.design.client.MaterialDesignBase; import gwt.material.design.client.base.AbstractValueWidget; import gwt.material.design.client.base.JsLoader; import gwt.material.design.client.base.viewport.ViewPort; import gwt.material.design.client.base.viewport.WidthBoundary; import gwt.material.design.client.js.Window; //@formatter:off /** * HTML5 canvas based smooth signature drawing * <h3>XML Namespace Declaration</h3> * <pre> * {@code xmlns:ma='urn:import:gwt.material.design.addins.client'} * </pre> * <p> * <h3>UiBinder Usage:</h3> * <pre> * {@code <ma:signature.MaterialSignaturePad dotSize="5" lineMinWidth="5" lineMaxWidth="10" />} * * @author kevzlou7979 * @see <a href="http://gwtmaterialdesign.github.io/gwt-material-demo/#signaturePad">Material Signature Pad</a> * @see <a href="https://github.com/szimek/signature_pad">LiveStamp SignaturePad 2.3.0</a> */ //@formatter:on public class MaterialSignaturePad extends AbstractValueWidget<String> implements JsLoader, HasSignaturePadOptions, HasSignatureHandlers { static { if (MaterialAddins.isDebug()) { MaterialDesignBase.injectDebugJs(MaterialSignaturePadDebugClientBundle.INSTANCE.signaturePadDebugJs()); } else { MaterialDesignBase.injectJs(MaterialSignaturePadClientBundle.INSTANCE.signaturePadJs()); } } public MaterialSignaturePad() { super(Document.get().createCanvasElement(), AddinsCssName.SIGNATURE_PAD); } private SignaturePad signaturePad; private JsSignaturePadOptions options = JsSignaturePadOptions.create(); @Override protected void onLoad() { super.onLoad(); resizeCanvas(); load(); } /** * <b>Handling high DPI screens</b> * <p> * To correctly handle canvas on low and high DPI screens one has to take devicePixelRatio into account and scale * the canvas accordingly. </p> * * @see <a href="https://github.com/szimek/signature_pad#handling-high-dpi-screens">More info</a> */ protected void resizeCanvas() { applyResize(); ViewPort.when(new WidthBoundary(0, 5120)).then(param1 -> applyResize()); } protected void applyResize() { CanvasElement element = getElement().cast(); double ratio = getRatio(); element.setWidth((int) (getOffsetWidth() * ratio)); element.setHeight((int) (getOffsetHeight() * ratio)); element.getContext2d().scale(ratio, ratio); getSignaturePad().clear(); } @Override public void load() { getSignaturePad().on(); } @Override protected void onUnload() { super.onUnload(); unload(); } @Override public void unload() { getSignaturePad().off(); } @Override public void reload() { unload(); load(); } @Override public void clear() { super.clear(); reset(); } public void reset() { resizeCanvas(); SignatureClearEvent.fire(this); } @Override public boolean isEmpty() { return getSignaturePad().isEmpty(); } @Override public void fromDataUrl(String url) { getSignaturePad().fromDataURL(url); } @Override public String toDataUrl() { return getSignaturePad().toDataURL(); } public SignaturePad getSignaturePad() { if (signaturePad == null) { options.onBegin = () -> SignatureStartEvent.fire(this); options.onEnd = () -> { SignatureEndEvent.fire(this); ValueChangeEvent.fire(this, getSignaturePad().toDataURL()); }; signaturePad = new SignaturePad(getElement(), options); } return signaturePad; } public void setSignaturePad(SignaturePad signaturePad) { this.signaturePad = signaturePad; } @Override public double getDotSize() { return options.dotSize; } @Override public void setDotSize(double dotSize) { options.dotSize = dotSize; if (signaturePad != null) { signaturePad.dotSize = dotSize; } } @Override public double getLineMinWidth() { return options.minWidth; } @Override public void setLineMinWidth(double lineMinWidth) { options.minWidth = lineMinWidth; if (signaturePad != null) { signaturePad.minWidth = lineMinWidth; } } @Override public double getLineMaxWidth() { return options.maxWidth; } @Override public void setLineMaxWidth(double lineMaxWidth) { options.maxWidth = lineMaxWidth; if (signaturePad != null) { signaturePad.maxWidth = lineMaxWidth; } } @Override public int getThrottle() { return options.throttle; } @Override public void setThrottle(int throttle) { options.throttle = throttle; if (signaturePad != null) { signaturePad.throttle = throttle; } } @Override public String getPenColor() { return options.penColor; } @Override public void setPenColor(String penColor) { options.penColor = penColor; if (signaturePad != null) { signaturePad.penColor = penColor; } } @Override public double getVelocityFilterWeight() { return options.velocityFilterWeight; } @Override public void setVelocityFilterWeight(double velocityFilterWeight) { options.velocityFilterWeight = velocityFilterWeight; if (signaturePad != null) { signaturePad.velocityFilterWeight = velocityFilterWeight; } } public static native double getRatio() /*-{ return Math.max(window.devicePixelRatio || 1, 1); }-*/; @Override public HandlerRegistration addSignatureClearHandler(SignatureClearEvent.SignatureClearHandler handler) { return addHandler(handler, SignatureClearEvent.TYPE); } @Override public HandlerRegistration addSignatureStartHandler(SignatureStartEvent.SignatureStartHandler handler) { return addHandler(handler, SignatureStartEvent.TYPE); } @Override public HandlerRegistration addSignatureEndHandler(SignatureEndEvent.SignatureEndHandler handler) { return addHandler(handler, SignatureEndEvent.TYPE); } @Override public String getValue() { return getSignaturePad().toDataURL(); } @Override public void setValue(String value, boolean fireEvents) { super.setValue(value, fireEvents); // Will set the value internally from signaturepad component fromDataUrl(value); } }