/******************************************************************************* * Copyright (c) 2012 Google, Inc. * 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: * Google, Inc. - initial API and implementation *******************************************************************************/ package com.windowtester.eclipse.ui.inspector; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import com.windowtester.eclipse.ui.inspector.InspectorPopup.PopupClosedCallback; import com.windowtester.recorder.event.user.IWidgetDescription; import com.windowtester.runtime.swt.internal.display.DisplayExec; import com.windowtester.runtime.swt.internal.display.RunnableWithResult; /** * Manage the inspector popup. */ public class Inspector { protected static final long POPUP_DELAY = 1000; private static InspectorPopup inspector; private static Shell parentShell; //sanity: ensure we don't inspect multiple times for the same request private static IWidgetDescription lastEvent; private static Point cursorLocation; public static void openPopup(IWidgetDescription event, PopupClosedCallback callback) { if (eventIsInvalid(event)) return; if (eventIsSeen(event)) return; if (mouseIsOverOpenInspector()) return; doOpen(event, callback); } public static void openPopup(IWidgetDescription event) { openPopup(event, null); } private static void doOpen(IWidgetDescription event, PopupClosedCallback callback) { cacheEvent(event); closeLastInspector(); openNewInspectorForEvent(event, callback); } private static boolean mouseIsOverOpenInspector() { if (inspector == null) return false; Point cursorLocation = Display.getDefault().getCursorLocation(); if (cursorLocation == null) return false; return inspector.contains(cursorLocation); } private static boolean eventIsInvalid(IWidgetDescription event) { if (event == null) return true; //for now we just ignore events with no locators -- in the future we may want to allow //users to debug them... return event.getLocator() == null; } private static void cacheEvent(IWidgetDescription event) { lastEvent = event; } private static boolean eventIsSeen(IWidgetDescription event) { return (event == lastEvent || event.isSame(lastEvent)); } private static void openNewInspectorForEvent(final IWidgetDescription event, PopupClosedCallback callback) { // cacheCursorPosition(); // // Runnable runnable = new Runnable() { // public void run() { // try { // Thread.sleep(POPUP_DELAY); // } catch (InterruptedException e) { // } // if (mouseMoved()) { // return; // } // inspector = new InspectorPopup(getParent(), event, callback); inspector.open(); // } // }; // Thread t = new Thread(runnable); // t.start(); } protected static boolean mouseMoved() { System.out.println(cursorLocation); System.out.println(getCurrentCursorLocation()); //if either is null we just say true (shouldn't happen but playing safe) Point currentCursorLocation = getCurrentCursorLocation(); if (currentCursorLocation == null || cursorLocation == null) return true; return !currentCursorLocation.equals(cursorLocation); // return cursorLocation != getCurrentCursorLocation(); } // private static void cacheCursorPosition() { // cursorLocation = getCurrentCursorLocation(); // } private static Point getCurrentCursorLocation() { try { return (Point) DisplayExec.sync(new RunnableWithResult() { public Object runWithResult() { return getParent().getDisplay().getCursorLocation(); } }); } catch(Throwable e) { //just null out the location return null; } } private static void closeLastInspector() { if (inspector != null) inspector.close(); } private static Shell getParent() { if (parentShell == null) parentShell = new Shell(SWT.ON_TOP); return parentShell; } }