Package ru.batrdmi.svnplugin

Source Code of ru.batrdmi.svnplugin.KeyboardNavigator$LinkedRevisionsByDistance

package ru.batrdmi.svnplugin;

import com.mxgraph.model.mxGeometry;
import ru.batrdmi.svnplugin.logic.Revision;

import java.awt.event.KeyEvent;
import java.util.*;

public class KeyboardNavigator {
    private static final double PRECISION = 1e-3;

    private final SVNRevisionGraph graph;
    private final Map<Integer, KeyProcessor> processors = new HashMap<Integer, KeyProcessor>();

    interface KeyProcessor {
        Revision moveFrom(RevisionGraphModel.Node r);
    }

    public KeyboardNavigator(SVNRevisionGraph graph) {
        this.graph = graph;
        processors.put(KeyEvent.VK_UP, new KeyProcessor() {
             @Override
             public Revision moveFrom(RevisionGraphModel.Node r) {
                 return moveUp(r);
             }
         });
        processors.put(KeyEvent.VK_DOWN, new KeyProcessor() {
             @Override
             public Revision moveFrom(RevisionGraphModel.Node r) {
                 return moveDown(r);
             }
         });
        processors.put(KeyEvent.VK_LEFT, new KeyProcessor() {
             @Override
             public Revision moveFrom(RevisionGraphModel.Node r) {
                 return moveLeft(r);
             }
         });
        processors.put(KeyEvent.VK_RIGHT, new KeyProcessor() {
             @Override
             public Revision moveFrom(RevisionGraphModel.Node r) {
                 return moveRight(r);
             }
         });
    }

    public boolean processEvent(KeyEvent e){
        KeyProcessor kp = processors.get(e.getKeyCode());
        if (kp == null) {
            return false;
        }
        List<RevisionGraphModel.Node> selectedRevs = graph.getModel().getSelectedNodes();
        if (selectedRevs.size() != 1) {
            return false;
        }
        Revision targetRevision = kp.moveFrom(selectedRevs.get(0));
        if (targetRevision != null) {
            graph.selectAndShowRevision(targetRevision);
        }
        return true;
    }

    private Revision moveUp(RevisionGraphModel.Node currentNode) {
        Revision current = currentNode.revisions.get(0);
        RevisionGraphModel model = graph.getModel();
        Set<Revision> linkedRevs = model.getLinkedRevisions(current);
        if (linkedRevs.isEmpty()) {
            graph.moveUpRange();
            return null;
        }
        Revision result = null;
        double currY = model.getCellForRevision(current).getGeometry().getY();
        Comparator<Revision> comparator = new LinkedRevisionsByDistance(current, false);
        for (Revision r : linkedRevs) {
            if ((model.getCellForRevision(r).getGeometry().getY() - currY < PRECISION)
                    && (result == null || comparator.compare(result, r) > 0)) {
                result = r;
            }
        }
        return result;
    }

    private Revision moveDown(RevisionGraphModel.Node currentNode) {
        Revision current = currentNode.revisions.get(0);
        RevisionGraphModel model = graph.getModel();
        Set<Revision> linkedRevs = model.getLinkedRevisions(current);
        if (linkedRevs.isEmpty()) {
            graph.moveDownRange();
            return null;
        }
        Revision result = null;
        double currY = model.getCellForRevision(current).getGeometry().getY();
        Comparator<Revision> comparator = new LinkedRevisionsByDistance(current, true);
        for (Revision r : linkedRevs) {
            if ((model.getCellForRevision(r).getGeometry().getY() - currY > PRECISION)
                    && (result == null || comparator.compare(result, r) > 0)) {
                result = r;
            }
        }
        return (result == null) ? current : result;
    }

    private Revision moveLeft(RevisionGraphModel.Node currentNode) {
        Revision current = currentNode.revisions.get(0);
        List<Revision> revsOnPath = graph.getModel().getRevisionsForPath(current.getRelPath());
        ListIterator<Revision> it = revsOnPath.listIterator(revsOnPath.size());
        while (it.hasPrevious()) {
            Revision r = it.previous();
            if (r.equals(current) && it.hasPrevious()) {
                return it.previous();
            }
        }
        return null;
    }

    private Revision moveRight(RevisionGraphModel.Node currentNode) {
        Revision current = currentNode.revisions.get(currentNode.revisions.size() - 1);
        List<Revision> revsOnPath = graph.getModel().getRevisionsForPath(current.getRelPath());
        Iterator<Revision> it = revsOnPath.iterator();
        while (it.hasNext()) {
            Revision r = it.next();
            if (r.equals(current) && it.hasNext()) {
                return it.next();
            }
        }
        return null;
    }

    private class LinkedRevisionsByDistance implements Comparator<Revision> {
        private final Revision reference;
        private final boolean latestIsCloser;

        public LinkedRevisionsByDistance(Revision reference, boolean latestIsCloser) {
            this.reference = reference;
            this.latestIsCloser = latestIsCloser;
        }

        @Override
        public int compare(Revision r1, Revision r2) {
            RevisionGraphModel model = graph.getModel();
            mxGeometry g = model.getCellForRevision(reference).getGeometry();
            mxGeometry g1 = model.getCellForRevision(r1).getGeometry();
            mxGeometry g2 = model.getCellForRevision(r2).getGeometry();
            double diffX = Math.abs(g1.getX() - g.getX()) - Math.abs(g2.getX() - g.getX());
            if (Math.abs(diffX) > PRECISION) {
                return (diffX > 0) ? 1 : -1;
            }
            double diffY = Math.abs(g1.getY() - g.getY()) - Math.abs(g2.getY() - g.getY());
            if (Math.abs(diffY) > PRECISION) {
                return (diffY > 0) ? 1 : -1;
            }
            return (latestIsCloser ^ (r1.getRevisionNumber() > reference.getRevisionNumber())) ? 1 : -1;
        }
    }
}
TOP

Related Classes of ru.batrdmi.svnplugin.KeyboardNavigator$LinkedRevisionsByDistance

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.