Package org.eclipse.nebula.widgets.nattable.ui.mode

Source Code of org.eclipse.nebula.widgets.nattable.ui.mode.MouseModeEventHandler

/*******************************************************************************
* Copyright (c) 2012, 2013, 2014 Original authors and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     Original authors and others - initial API and implementation
******************************************************************************/
package org.eclipse.nebula.widgets.nattable.ui.mode;

import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.nebula.widgets.nattable.ui.NatEventData;
import org.eclipse.nebula.widgets.nattable.ui.action.DragModeEventHandler;
import org.eclipse.nebula.widgets.nattable.ui.action.IDragMode;
import org.eclipse.nebula.widgets.nattable.ui.action.IMouseAction;
import org.eclipse.nebula.widgets.nattable.ui.action.IMouseClickAction;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseEvent;

public class MouseModeEventHandler extends AbstractModeEventHandler {

    private MouseEvent initialMouseDownEvent;

    private IMouseAction singleClickAction;

    private IMouseAction doubleClickAction;

    private boolean mouseDown;

    private IDragMode dragMode;

    private boolean doubleClick;

    private boolean skipProcessing = false;

    public MouseModeEventHandler(ModeSupport modeSupport, NatTable natTable,
            MouseEvent initialMouseDownEvent, IMouseAction singleClickAction,
            IMouseAction doubleClickAction, IDragMode dragMode) {
        super(modeSupport, natTable);

        this.mouseDown = true;

        this.initialMouseDownEvent = initialMouseDownEvent;

        this.singleClickAction = singleClickAction;
        this.doubleClickAction = doubleClickAction;
        this.dragMode = dragMode;
    }

    @Override
    public void mouseUp(final MouseEvent event) {
        mouseDown = false;
        doubleClick = false;

        if (singleClickAction != null) {
            // convert/validate/commit/close possible open editor
            // needed in case of conversion/validation errors to cancel any
            // action
            if (natTable.commitAndCloseActiveCellEditor()) {
                if (doubleClickAction != null
                        && (isActionExclusive(singleClickAction) || isActionExclusive(doubleClickAction))) {
                    // If a doubleClick action is registered and either the
                    // single click or the double
                    // click action is exclusive, wait to see if this mouseUp is
                    // part of a doubleClick or not.
                    event.display.timerExec(event.display.getDoubleClickTime(),
                            new Runnable() {
                                @Override
                                public void run() {
                                    if (!doubleClick && !skipProcessing) {
                                        executeClickAction(singleClickAction,
                                                event);
                                    }
                                }
                            });
                } else {
                    executeClickAction(singleClickAction, event);
                }
            }
        } else if (doubleClickAction == null) {
            // No single or double click action registered when mouseUp
            // detected. Switch back to normal mode.
            switchMode(Mode.NORMAL_MODE);
        }
    }

    @Override
    public void mouseDown(MouseEvent event) {
        // another mouse click was performed than initial
        // This handling is necessary to react correctly e.g. if an action is
        // registered
        // for left double click and an action for right single click.
        // Performing a left
        // and right click in short sequence, nothing will happen without this
        // handling.
        // This is also true in case a click is performed without modifier key
        // pressed
        // and performing a mouse click with modifier key pressed shortly after.
        if ((event.button != this.initialMouseDownEvent.button)
                || (event.stateMask != this.initialMouseDownEvent.stateMask)) {
            // ensure the double click runnable is not executed and process
            // single click immediately
            this.skipProcessing = true;
            executeClickAction(singleClickAction, this.initialMouseDownEvent);

            // reset to the parent mode
            switchMode(Mode.NORMAL_MODE);
            // start the mouse event processing for the new button
            getModeSupport().mouseDown(event);
        }
    }

    @Override
    public void keyPressed(KeyEvent event) {
        // ensure the double click runnable is not executed and process single
        // click immediately
        this.skipProcessing = true;
        executeClickAction(singleClickAction, this.initialMouseDownEvent);

        // reset to the parent mode
        switchMode(Mode.NORMAL_MODE);
        // start the key event processing
        getModeSupport().keyPressed(event);
    }

    @Override
    public void mouseDoubleClick(MouseEvent event) {
        // double click event is fired after second mouse up event, so it needs
        // to be set to true here
        // this way the exclusive single click action knows that it should not
        // execute as a double click was performed
        doubleClick = true;

        executeClickAction(doubleClickAction, event);
    }

    @Override
    public synchronized void mouseMove(MouseEvent event) {
        if (mouseDown && dragMode != null) {
            if (natTable.commitAndCloseActiveCellEditor()) {
                dragMode.mouseDown(natTable, initialMouseDownEvent);
                switchMode(new DragModeEventHandler(getModeSupport(), natTable,
                        dragMode, this, initialMouseDownEvent));
            } else {
                switchMode(Mode.NORMAL_MODE);
            }
        } else {
            if (!(mouseDown && eventOnSameCell(initialMouseDownEvent, event))) {
                // ensure the double click runnable is not executed and process
                // single click immediately
                this.skipProcessing = true;
                executeClickAction(singleClickAction,
                        this.initialMouseDownEvent);

                // Bug 436770
                // do not switch back to normal mode in case a click is
                // processed
                // No drag mode registered when mouseMove detected. Switch back
                // to normal mode.
                switchMode(Mode.NORMAL_MODE);
            }
        }
    }

    /**
     * Executes the given IMouseAction and switches the DisplayMode back to
     * normal.
     *
     * @param action
     *            The IMouseAction that should be executed.
     * @param event
     *            The MouseEvent that triggers the action
     */
    private void executeClickAction(IMouseAction action, MouseEvent event) {
        // convert/validate/commit/close possible open editor
        // needed in case of conversion/validation errors to cancel any action
        if (natTable.commitAndCloseActiveCellEditor()) {
            if (action != null && event != null) {
                event.data = NatEventData.createInstanceFromEvent(event);
                action.run(natTable, event);
                // Single click action complete. Switch back to normal mode.
                switchMode(Mode.NORMAL_MODE);
            }
        }
    }

    /**
     * Checks whether the given IMouseAction should be performed exclusive or
     * not. If there is a single and a double click action configured, by
     * default both the single and the double click will be performed. This
     * behaviour can be modified if the given action is of type
     * IMouseClickAction and configured to be exclusive. In this case the single
     * or the double click action will be performed.
     *
     * @param action
     *            The IMouseAction to check
     * @return <code>true</code> if the given IMouseAction should be called
     *         exclusively, <code>false</code> if not.
     */
    private boolean isActionExclusive(IMouseAction action) {
        if (action instanceof IMouseClickAction) {
            return ((IMouseClickAction) action).isExclusive();
        }
        return false;
    }

}
TOP

Related Classes of org.eclipse.nebula.widgets.nattable.ui.mode.MouseModeEventHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.