/*******************************************************************************
* 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.runtime.swt.internal.effects;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import com.windowtester.runtime.swt.internal.preferences.ColorManager;
import com.windowtester.runtime.swt.internal.preferences.PlaybackSettings;
import com.windowtester.runtime.swt.internal.selector.HighlightingDriver;
/**
* An abstract highlighter that drwas a highlighted bounding box around a control target. To account
* for clipping issues (due to shading, shadowing and other effects), a fudge factor can be set by implementing
* getPixelBuffer().
*
* @author Phil Quitslund
*/
public abstract class AbstractControlHighlighter implements IHighlighter {
/** The color of the highlight -- to be moved to configurable settings */
//private static final int HIGHLIGHT_COLOR = SWT.COLOR_RED;
/** The control to highlight */
protected final Control _widget;
/** The active display */
protected final Display _display;
/** The painter for drawing the highlight */
protected final Painter _painter;
/** Settings for playback */
private final PlaybackSettings _settings;
/**
* Create an instance.
* @param label
*/
public AbstractControlHighlighter(Control control, PlaybackSettings settings) {
_widget = control;
_settings = settings;
_display = control.getDisplay();
_painter = new Painter();
}
/**
* Get the number of pixels to buffer the highlighting bounding box to avoid clipping.
* @return - the number of pixels
*/
protected abstract int getPixelBuffer();
/**
* Get playback settings.
* @return the current playback settings.
*/
protected PlaybackSettings getSettings() {
return _settings;
}
/**
* @see com.windowtester.runtime.swt.internal.effects.IHighlighter#doPaint(com.windowtester.runtime.swt.internal.selector.HighlightingDriver)
*/
public void doPaint(HighlightingDriver driver) {
paint();
driver.highlightPause();
unPaint();
}
/* (non-Javadoc)
* @see com.windowtester.runtime.swt.internal.effects.IHighlighter#paint()
*/
public void paint() {
//System.out.println("<calling highlight>");
//needs to happen in the UI thread
_display.syncExec(new Runnable() {
public void run() {
addPaintListener();
update();
}
});
}
/* (non-Javadoc)
* @see com.windowtester.runtime.swt.internal.effects.IHighlighter#unPaint()
*/
public void unPaint() {
//System.out.println("<calling un-highlight>");
//needs to happen in the UI thread
_display.syncExec( new Runnable() {
public void run() {
removePaintListener();
update();
}
});
}
/**
* Add our custom paint listener to the highlighted control.
*/
protected void addPaintListener() {
_widget.addPaintListener(_painter);
}
/**
* Remove our custom paint listener from the highlighted control.
*/
protected void removePaintListener() {
_widget.removePaintListener(_painter);
}
/**
* Tell the control to update, so out highlighting effect gets drawn.
*/
protected void update() {
_widget.redraw();
_widget.update();
}
/**
* @return
*/
protected Rectangle calculateBoundingBox() {
Rectangle r = _widget.getBounds();
return new Rectangle(0,0,r.width-getPixelBuffer(), r.height-getPixelBuffer()); //need to subtract a few pixels, else bottom and right clip
}
/**
* Action performed before drawing the outline.
*/
public void preOutline() {
//default is a no-op
}
/**
* Action performed after drawing the outline.
*/
public void postOutline() {
//default is a no-op
}
/**
* A custom paint listener that draws a rectangle highlight around the target control.
*/
class Painter implements PaintListener {
/* (non-Javadoc)
* @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent)
*/
public void paintControl(PaintEvent e) {
preOutline();
//System.out.println("<painting highlight>");
//Rectangle r = _widget.getBounds();
e.gc.setForeground(getColor());
Rectangle outlineBounds = calculateBoundingBox();
e.gc.drawRectangle(outlineBounds);
postOutline();
}
private Color getColor() {
Color color = ColorManager.getDefault().getColor(_settings.getHighlightColor());
return color;
}
}
}