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.client.base.helper;
021
022import com.google.gwt.event.dom.client.*;
023import com.google.gwt.user.client.Event;
024import com.google.gwt.user.client.Window;
025import com.google.gwt.user.client.ui.Widget;
026import gwt.material.design.client.events.DefaultHandlerRegistry;
027
028/**
029 * This static helper class is supposed to collect common methods used for multiple kind of UI classes.
030 * It is defined as abstract to prohibit
031 */
032public final class UiHelper {
033
034    private static DefaultHandlerRegistry handlerRegistry;
035
036    private static String PRESSED_CSS_STYLE_NAME = "pressed";
037
038    /**
039     * Adds a mouse pressed handler to a widget. Adds a CSS style ('pressed',
040     * {@link #PRESSED_CSS_STYLE_NAME}) to the widget as long as the mouse is
041     * pressed (or the user touches the widget). See
042     * {@link #addMousePressedHandlers(Widget, String)}.
043     *
044     * @param widget The widget to which the "pressed" style musst be applied
045     */
046    public static void addMousePressedHandlers(final Widget widget) {
047        addMousePressedHandlers(widget, PRESSED_CSS_STYLE_NAME);
048    }
049
050    /**
051     * Adds a mouse pressed handler to a widget. Adds a CSS style to the widget
052     * as long as the mouse is pressed (or the user touches the widget on mobile browser).
053     *
054     * @param widget       The widget to which the style must be applied for mouse/touch event
055     * @param cssStyleName CSS style name to be applied
056     */
057    public static void addMousePressedHandlers(final Widget widget, final String cssStyleName) {
058        widget.sinkEvents(Event.ONMOUSEDOWN);
059        widget.sinkEvents(Event.ONMOUSEUP);
060        widget.sinkEvents(Event.ONMOUSEOUT);
061        widget.sinkEvents(Event.TOUCHEVENTS);
062
063        handlerRegistry = new DefaultHandlerRegistry(widget);
064        handlerRegistry.registerHandler(widget.addHandler(event -> widget.addStyleName(cssStyleName), MouseDownEvent.getType()));
065        handlerRegistry.registerHandler(widget.addHandler(event -> widget.removeStyleName(cssStyleName), MouseUpEvent.getType()));
066        handlerRegistry.registerHandler(widget.addHandler(event -> widget.removeStyleName(cssStyleName), MouseOutEvent.getType()));
067
068        // Touch Events
069        handlerRegistry.registerHandler(widget.addHandler(event -> widget.addStyleName(cssStyleName), TouchStartEvent.getType()));
070        handlerRegistry.registerHandler(widget.addHandler(event -> widget.removeStyleName(cssStyleName), TouchEndEvent.getType()));
071        handlerRegistry.registerHandler(widget.addHandler(event -> widget.removeStyleName(cssStyleName), TouchCancelEvent.getType()));
072    }
073
074    public static int calculateSpaceToBottom(Widget widget) {
075        return Window.getClientHeight() - widget.getAbsoluteTop() - widget.getOffsetHeight();
076    }
077
078    public static native boolean isTouchScreenDevice() /*-{
079        return 'ontouchstart' in document.documentElement;
080    }-*/;
081}