Package org.gephi.visualization.events

Source Code of org.gephi.visualization.events.StandardVizEventManager$VizEventTypeHandler

/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org

This file is part of Gephi.

Gephi is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

Gephi is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with Gephi.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.gephi.visualization.events;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.gephi.graph.api.Node;
import org.gephi.graph.api.NodeData;
import org.gephi.visualization.VizController;
import org.gephi.visualization.apiimpl.GraphIO;
import org.gephi.visualization.apiimpl.ModelImpl;
import org.gephi.visualization.apiimpl.VizEvent;
import org.gephi.visualization.apiimpl.VizEventListener;
import org.gephi.visualization.apiimpl.VizEventManager;
import org.gephi.visualization.opengl.AbstractEngine;

/**
*
* @author Mathieu Bastian
*/
public class StandardVizEventManager implements VizEventManager {

    //Architecture
    private AbstractEngine engine;
    private GraphIO graphIO;
    //
    private ThreadPoolExecutor pool;
    private VizEventTypeHandler[] handlers;

    public StandardVizEventManager() {
        pool = new ThreadPoolExecutor(0, 1, 60L, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>(10));
    }

    public void initArchitecture() {
        engine = VizController.getInstance().getEngine();
        graphIO = VizController.getInstance().getGraphIO();

        //Set handlers
        ArrayList<VizEventTypeHandler> handlersList = new ArrayList<VizEventTypeHandler>();
        handlersList.add(new VizEventTypeHandler(VizEvent.Type.MOUSE_LEFT_CLICK, false));
        handlersList.add(new VizEventTypeHandler(VizEvent.Type.MOUSE_LEFT_PRESS, false));
        handlersList.add(new VizEventTypeHandler(VizEvent.Type.MOUSE_MIDDLE_CLICK, false));
        handlersList.add(new VizEventTypeHandler(VizEvent.Type.MOUSE_MIDDLE_PRESS, false));
        handlersList.add(new VizEventTypeHandler(VizEvent.Type.MOUSE_RIGHT_CLICK, false));
        handlersList.add(new VizEventTypeHandler(VizEvent.Type.MOUSE_RIGHT_PRESS, false));
        handlersList.add(new VizEventTypeHandler(VizEvent.Type.MOUSE_MOVE, true));
        handlersList.add(new VizEventTypeHandler(VizEvent.Type.START_DRAG, false));
        handlersList.add(new VizEventTypeHandler(VizEvent.Type.DRAG, true));
        handlersList.add(new VizEventTypeHandler(VizEvent.Type.STOP_DRAG, false));
        handlersList.add(new VizEventTypeHandler(VizEvent.Type.NODE_LEFT_CLICK, false));
        handlersList.add(new VizEventTypeHandler(VizEvent.Type.MOUSE_LEFT_PRESSING, false));
        handlersList.add(new VizEventTypeHandler(VizEvent.Type.MOUSE_RELEASED, false));
        handlersList.add(new VizEventTypeHandler(VizEvent.Type.NODE_LEFT_PRESS, false));
        handlersList.add(new VizEventTypeHandler(VizEvent.Type.NODE_LEFT_PRESSING, false));
        Collections.sort(handlersList, new Comparator() {

            public int compare(Object o1, Object o2) {
                VizEvent.Type t1 = ((VizEventTypeHandler) o1).type;
                VizEvent.Type t2 = ((VizEventTypeHandler) o2).type;
                return t1.compareTo(t2);
            }
        });
        handlers = handlersList.toArray(new VizEventTypeHandler[0]);
    }

    public void mouseLeftClick() {
        //Node Left click
        VizEventTypeHandler nodeLeftHandler = handlers[VizEvent.Type.NODE_LEFT_CLICK.ordinal()];
        if (nodeLeftHandler.hasListeners() && VizController.getInstance().getVizConfig().isSelectionEnable()) {
            //Check if some node are selected
            ModelImpl[] modelArray = engine.getSelectedObjects(AbstractEngine.CLASS_NODE);
            if (modelArray.length > 0) {
                Node[] nodeArray = new Node[modelArray.length];
                for (int i = 0; i < modelArray.length; i++) {
                    nodeArray[i] = ((NodeData) modelArray[i].getObj()).getRootNode();
                }
                nodeLeftHandler.dispatch(nodeArray);
            }
        }

        //Mouse left click
        VizEventTypeHandler mouseLeftHandler = handlers[VizEvent.Type.MOUSE_LEFT_CLICK.ordinal()];
        if (mouseLeftHandler.hasListeners()) {
            ModelImpl[] modelArray = engine.getSelectedObjects(AbstractEngine.CLASS_NODE);
            if (modelArray.length == 0 || !VizController.getInstance().getVizConfig().isSelectionEnable()) {
                float[] mousePositionViewport = graphIO.getMousePosition();
                float[] mousePosition3d = graphIO.getMousePosition3d();
                float[] mousePos = new float[]{mousePositionViewport[0], mousePositionViewport[1], mousePosition3d[0], mousePosition3d[1]};
                handlers[VizEvent.Type.MOUSE_LEFT_CLICK.ordinal()].dispatch(mousePos);
            }
        }
    }

    public void mouseLeftPress() {
        handlers[VizEvent.Type.MOUSE_LEFT_PRESS.ordinal()].dispatch();
        pressingTick = PRESSING_FREQUENCY;
        VizEventTypeHandler pressHandler = handlers[VizEvent.Type.NODE_LEFT_PRESS.ordinal()];
        if (pressHandler.hasListeners()) {
            //Check if some node are selected
            ModelImpl[] modelArray = engine.getSelectedObjects(AbstractEngine.CLASS_NODE);
            if (modelArray.length > 0) {
                Node[] nodeArray = new Node[modelArray.length];
                for (int i = 0; i < modelArray.length; i++) {
                    nodeArray[i] = ((NodeData) modelArray[i].getObj()).getRootNode();
                }
                pressHandler.dispatch(nodeArray);
            }
        }
    }

    public void mouseMiddleClick() {
        handlers[VizEvent.Type.MOUSE_MIDDLE_CLICK.ordinal()].dispatch();
    }

    public void mouseMiddlePress() {
        handlers[VizEvent.Type.MOUSE_LEFT_PRESS.ordinal()].dispatch();
    }

    public void mouseMove() {
        handlers[VizEvent.Type.MOUSE_MOVE.ordinal()].dispatch();
    }

    public void mouseRightClick() {
        handlers[VizEvent.Type.MOUSE_RIGHT_CLICK.ordinal()].dispatch();
    }

    public void mouseRightPress() {
        handlers[VizEvent.Type.MOUSE_RIGHT_PRESS.ordinal()].dispatch();
    }
    private static final int PRESSING_FREQUENCY = 5;
    private int pressingTick = 0;

    public void mouseLeftPressing() {
        if (pressingTick++ >= PRESSING_FREQUENCY) {
            pressingTick = 0;
            VizEventTypeHandler nodeHandler = handlers[VizEvent.Type.NODE_LEFT_PRESSING.ordinal()];
            if (nodeHandler.hasListeners()) {
                //Check if some node are selected
                ModelImpl[] modelArray = engine.getSelectedObjects(AbstractEngine.CLASS_NODE);
                if (modelArray.length > 0) {
                    Node[] nodeArray = new Node[modelArray.length];
                    for (int i = 0; i < modelArray.length; i++) {
                        nodeArray[i] = ((NodeData) modelArray[i].getObj()).getRootNode();
                    }
                    nodeHandler.dispatch(nodeArray);
                }
            }
        }
    }

    public void startDrag() {
        handlers[VizEvent.Type.START_DRAG.ordinal()].dispatch();
    }

    public void stopDrag() {
        handlers[VizEvent.Type.STOP_DRAG.ordinal()].dispatch();
    }
    private static final int DRAGGING_FREQUENCY = 5;
    private int draggingTick = 0;

    public void drag() {
        if (draggingTick++ >= DRAGGING_FREQUENCY) {
            draggingTick = 0;
            VizEventTypeHandler handler = handlers[VizEvent.Type.DRAG.ordinal()];
            if (handler.hasListeners()) {
                float[] mouseDrag = Arrays.copyOf(graphIO.getMouseDrag(), 4);
                mouseDrag[2] = graphIO.getMouseDrag3d()[0];
                mouseDrag[3] = graphIO.getMouseDrag3d()[1];
                handler.dispatch(mouseDrag);
            }
        }
    }

    public void mouseReleased() {
        handlers[VizEvent.Type.MOUSE_RELEASED.ordinal()].dispatch();
    }

    //Listeners
    public boolean hasListeners(VizEvent.Type type) {
        return handlers[type.ordinal()].hasListeners();
    }

    public void addListener(VizEventListener listener) {
        handlers[listener.getType().ordinal()].addListener(listener);
    }

    public void removeListener(VizEventListener listener) {
        handlers[listener.getType().ordinal()].removeListener(listener);
    }

    public void addListener(VizEventListener[] listeners) {
        for (int i = 0; i < listeners.length; i++) {
            handlers[listeners[i].getType().ordinal()].addListener(listeners[i]);
        }
    }

    public void removeListener(VizEventListener[] listeners) {
        for (int i = 0; i < listeners.length; i++) {
            handlers[listeners[i].getType().ordinal()].removeListener(listeners[i]);
        }
    }

    private class VizEventTypeHandler {

        //Settings
        private final boolean limitRunning;
        //Data
        protected List<WeakReference<VizEventListener>> listeners;
        protected final VizEvent.Type type;
        protected Runnable runnable;
        //States
        protected boolean running;

        public VizEventTypeHandler(VizEvent.Type type, boolean limitRunning) {
            this.limitRunning = limitRunning;
            this.type = type;
            this.listeners = new ArrayList<WeakReference<VizEventListener>>();
            runnable = new Runnable() {

                public void run() {
                    fireVizEvent(null);
                    running = false;
                }
            };
        }

        protected synchronized void addListener(VizEventListener listener) {
            WeakReference<VizEventListener> weakListener = new WeakReference<VizEventListener>(listener);
            listeners.add(weakListener);
        }

        protected synchronized void removeListener(VizEventListener listener) {
            for (Iterator<WeakReference<VizEventListener>> itr = listeners.iterator(); itr.hasNext();) {
                WeakReference<VizEventListener> li = itr.next();
                if (li.get() == listener) {
                    itr.remove();
                }
            }
        }

        protected void dispatch() {
            if (limitRunning && running) {
                return;
            }
            if (listeners.size() > 0) {
                running = true;
                pool.submit(runnable);
            }
        }

        protected void dispatch(final Object data) {
            if (limitRunning && running) {
                return;
            }
            if (listeners.size() > 0) {
                running = true;
                pool.submit(new Runnable() {

                    public void run() {
                        fireVizEvent(data);
                        running = false;
                    }
                });
            }
        }

        protected boolean isRunning() {
            return running;
        }

        private synchronized void fireVizEvent(Object data) {
            VizEvent event = new VizEvent(this, type, data);
            for (int i = 0; i < listeners.size(); i++) {
                WeakReference<VizEventListener> weakListener = listeners.get(i);
                VizEventListener v = weakListener.get();
                v.handleEvent(event);
            }
        }

        public boolean hasListeners() {
            return listeners.size() > 0;
        }

        protected int getIndex() {
            return type.ordinal();
        }
    }
}
TOP

Related Classes of org.gephi.visualization.events.StandardVizEventManager$VizEventTypeHandler

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.