// Copyright 2012 Georg-August-Universität Göttingen, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package de.ugoe.cs.autoquest.eventcore.gui; import java.util.LinkedList; import java.util.List; import de.ugoe.cs.autoquest.eventcore.Event; import de.ugoe.cs.autoquest.eventcore.IEventTarget; /** *

* This class condenses mouse clicks, i.e. it reduces a sequence of mouse button down, mouse button * up and possibly a subsequent mouse click with the same button on the same event target and the * same coordinates to a single mouse click with that button on that target at the coordinates. * The mouse button down and mouse button up events are discarded. For this, it iterates the * provided sequence and identifies any match of the named event sequence pattern. This match is * condensed to the mouse click event. *

* * @version 1.0 * @author Patrick Harms */ public class MouseClickCondenser { /** *

* This method performs the work described in the description of the class. A new list is * instantiated and returned. This list is filled with the events provided by the sequence being * the parameter of the method except for mouse button down and mouse button up events which are * followed by a mouse click event with the same button on the same target. *

* * @param sequence * the event sequence to condense the mouse clicks in * * @return the resulting sequence, in which mouse clicks are condensed to single mouse click * events */ public List condenseMouseClicks(List sequence) { List resultingSequence = new LinkedList(); int index = 0; boolean mouseClickHandled; while (index < sequence.size()) { mouseClickHandled = false; if ((index + 1) < sequence.size()) { Event mbDown = sequence.get(index); Event mbUp = sequence.get(index + 1); if (((index + 2) < sequence.size()) && mouseClickSequenceFound(mbDown, mbUp, sequence.get(index + 2))) { // skip the mouse button down and mouse button up event and add the mouse click index += 2; resultingSequence.add(sequence.get(index)); index++; mouseClickHandled = true; } else if (mouseClickSequenceFound(mbDown, mbUp)) { // skip the mouse button down and mouse button up event and add a mouse click index += 2; resultingSequence.add(createClick(mbDown, mbUp)); mouseClickHandled = true; } else if (mouseDragAndDropSequenceFound(mbDown, mbUp)) { // skip the mouse button down and mouse button up event and add a mouse click index += 2; resultingSequence.add(createDragAndDrop(mbDown, mbUp)); mouseClickHandled = true; } } if (!mouseClickHandled) { resultingSequence.add(sequence.get(index)); index++; } } return resultingSequence; } /** * */ private boolean mouseClickSequenceFound(Event mouseButtonDown, Event mouseButtonUp, Event mouseClick) { if (!mouseClickSequenceFound(mouseButtonDown, mouseButtonUp)) { return false; } // check the third node for validity if (!(mouseClick.getType() instanceof MouseClick)) { return false; } if (!targetsEqual(mouseButtonDown, mouseClick)) { return false; } if (!buttonsEqual(mouseButtonDown, mouseClick)) { return false; } if (!coordinatesEqual(mouseButtonDown, mouseClick)) { return false; } return true; } /** * */ private boolean mouseClickSequenceFound(Event mouseButtonDown, Event mouseButtonUp) { // check the first in a row of three for validity if (!(mouseButtonDown.getType() instanceof MouseButtonDown)) { return false; } // check the second node for validity if (!(mouseButtonUp.getType() instanceof MouseButtonUp)) { return false; } if (!targetsEqual(mouseButtonDown, mouseButtonUp)) { return false; } if (!buttonsEqual(mouseButtonDown, mouseButtonUp)) { return false; } if (!coordinatesEqual(mouseButtonDown, mouseButtonUp)) { return false; } return true; } /** * */ private boolean mouseDragAndDropSequenceFound(Event mouseButtonDown, Event mouseButtonUp) { // check the first in a row of three for validity if (!(mouseButtonDown.getType() instanceof MouseButtonDown)) { return false; } // check the second node for validity if (!(mouseButtonUp.getType() instanceof MouseButtonUp)) { return false; } if (!targetsEqual(mouseButtonDown, mouseButtonUp)) { return false; } MouseButtonInteraction.Button button = ((MouseButtonDown) mouseButtonDown.getType()).getButton(); if (MouseButtonInteraction.Button.LEFT != button) { return false; } if (!buttonsEqual(mouseButtonDown, mouseButtonUp)) { return false; } if (coordinatesEqual(mouseButtonDown, mouseButtonUp)) { return false; } return true; } /** * */ private Event createClick(Event mouseButtonDown, Event mouseButtonUp) { MouseButtonInteraction.Button button = ((MouseButtonDown) mouseButtonDown.getType()).getButton(); int x = ((MouseButtonDown) mouseButtonDown.getType()).getX(); int y = ((MouseButtonDown) mouseButtonDown.getType()).getY(); return new Event(new MouseClick(button, x, y), mouseButtonDown.getTarget()); } /** * */ private Event createDragAndDrop(Event mouseButtonDown, Event mouseButtonUp) { int xStart = ((MouseButtonDown) mouseButtonDown.getType()).getX(); int yStart = ((MouseButtonDown) mouseButtonDown.getType()).getY(); int xEnd = ((MouseButtonUp) mouseButtonUp.getType()).getX(); int yEnd = ((MouseButtonUp) mouseButtonUp.getType()).getY(); return new Event (new MouseDragAndDrop(xStart, yStart, xEnd, yEnd), mouseButtonDown.getTarget()); } /** * */ private boolean targetsEqual(Event event1, Event event2) { IEventTarget target1 = event1.getTarget(); IEventTarget target2 = event2.getTarget(); return target1 == null ? target2 == null : target1.equals(target2); } /** * */ private boolean buttonsEqual(Event event1, Event event2) { MouseButtonInteraction.Button button1 = (event1.getType() instanceof MouseButtonInteraction) ? ((MouseButtonInteraction) event1.getType()).getButton() : null; MouseButtonInteraction.Button button2 = (event2.getType() instanceof MouseButtonInteraction) ? ((MouseButtonInteraction) event2.getType()).getButton() : null; return button1 == null ? button2 == null : button1.equals(button2); } /** * */ private boolean coordinatesEqual(Event event1, Event event2) { int x1 = (event1.getType() instanceof MouseButtonInteraction) ? ((MouseButtonInteraction) event1.getType()).getX() : -1; int x2 = (event2.getType() instanceof MouseButtonInteraction) ? ((MouseButtonInteraction) event2.getType()).getX() : -1; if ((x1 == -1) || (x1 != x2)) { return false; } int y1 = (event1.getType() instanceof MouseButtonInteraction) ? ((MouseButtonInteraction) event1.getType()).getY() : -1; int y2 = (event2.getType() instanceof MouseButtonInteraction) ? ((MouseButtonInteraction) event2.getType()).getY() : -1; return (y1 != -1) && (y1 == y2); } }