aboutsummaryrefslogtreecommitdiffstats
path: root/src/com/vaadin/terminal/gwt/client/ui/ClickEventHandler.java
blob: 84102586c9f8435ed5313e8fe6019f2b6fd7ce8b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
@VaadinApache2LicenseForJavaFiles@
 */
package com.vaadin.terminal.gwt.client.ui;

import java.util.HashMap;
import java.util.Map;

import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.ContextMenuEvent;
import com.google.gwt.event.dom.client.ContextMenuHandler;
import com.google.gwt.event.dom.client.DomEvent;
import com.google.gwt.event.dom.client.DoubleClickEvent;
import com.google.gwt.event.dom.client.DoubleClickHandler;
import com.google.gwt.event.dom.client.MouseUpEvent;
import com.google.gwt.event.dom.client.MouseUpHandler;
import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Element;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.ComponentConnector;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
import com.vaadin.terminal.gwt.client.MouseEventDetailsBuilder;

public abstract class ClickEventHandler implements DoubleClickHandler,
        ContextMenuHandler, MouseUpHandler {

    private HandlerRegistration doubleClickHandlerRegistration;
    private HandlerRegistration mouseUpHandlerRegistration;
    private HandlerRegistration contextMenuHandlerRegistration;

    protected String clickEventIdentifier;
    protected ComponentConnector connector;

    public ClickEventHandler(ComponentConnector connector,
            String clickEventIdentifier) {
        this.connector = connector;
        this.clickEventIdentifier = clickEventIdentifier;
    }

    public void handleEventHandlerRegistration() {
        // Handle registering/unregistering of click handler depending on if
        // server side listeners have been added or removed.
        if (hasEventListener()) {
            if (mouseUpHandlerRegistration == null) {
                mouseUpHandlerRegistration = registerHandler(this,
                        MouseUpEvent.getType());
                contextMenuHandlerRegistration = registerHandler(this,
                        ContextMenuEvent.getType());
                doubleClickHandlerRegistration = registerHandler(this,
                        DoubleClickEvent.getType());
            }
        } else {
            if (mouseUpHandlerRegistration != null) {
                // Remove existing handlers
                doubleClickHandlerRegistration.removeHandler();
                mouseUpHandlerRegistration.removeHandler();
                contextMenuHandlerRegistration.removeHandler();

                contextMenuHandlerRegistration = null;
                mouseUpHandlerRegistration = null;
                doubleClickHandlerRegistration = null;

            }
        }

    }

    protected abstract <H extends EventHandler> HandlerRegistration registerHandler(
            final H handler, DomEvent.Type<H> type);

    protected ApplicationConnection getApplicationConnection() {
        return connector.getConnection();
    }

    public boolean hasEventListener() {
        return connector.hasEventListener(clickEventIdentifier);
    }

    protected void fireClick(NativeEvent event) {
        String pid = connector.getConnectorId();

        MouseEventDetails mouseDetails = MouseEventDetailsBuilder
                .buildMouseEventDetails(event, getRelativeToElement());

        Map<String, Object> parameters = new HashMap<String, Object>();
        parameters.put("mouseDetails", mouseDetails.serialize());
        connector.getConnection().updateVariable(pid, clickEventIdentifier,
                parameters, true);

    }

    public void onContextMenu(ContextMenuEvent event) {
        if (hasEventListener()) {
            // Prevent showing the browser's context menu when there is a right
            // click listener.
            event.preventDefault();
        }

    }

    public void onMouseUp(MouseUpEvent event) {
        // TODO For perfect accuracy we should check that a mousedown has
        // occured on this element before this mouseup and that no mouseup
        // has occured anywhere after that.
        if (hasEventListener()) {
            // "Click" with left, right or middle button
            fireClick(event.getNativeEvent());
        }
    }

    public void onDoubleClick(DoubleClickEvent event) {
        if (hasEventListener()) {
            fireClick(event.getNativeEvent());
        }
    }

    /**
     * Click event calculates and returns coordinates relative to the element
     * returned by this method. Default implementation uses the root element of
     * the widget. Override to provide a different relative element.
     * 
     * @return The Element used for calculating relative coordinates for a click
     *         or null if no relative coordinates can be calculated.
     */
    protected Element getRelativeToElement() {
        return connector.getWidget().getElement();
    }

}