/** * Starts this updater. This method initializes all the necessary resources and puts this {@link * Runnable} on the asynch queue. If this updater is not active or is already running, this * method just returns. */ public void start() { if (!isActive() || isRunning()) return; isRunning = true; setDirty(false); resetTileValues(); if (!targetSize.equals(thumbnailImageSize)) { resetThumbnailImage(); } if (targetSize.isEmpty()) return; thumbnailGC = new GC(thumbnailImage, sourceFigure.isMirrored() ? SWT.RIGHT_TO_LEFT : SWT.NONE); thumbnailGraphics = new ScaledGraphics(new SWTGraphics(thumbnailGC)); thumbnailGraphics.scale(getScaleX()); thumbnailGraphics.translate(getSourceRectangle().getLocation().negate()); Color color = sourceFigure.getForegroundColor(); if (color != null) thumbnailGraphics.setForegroundColor(color); color = sourceFigure.getBackgroundColor(); if (color != null) thumbnailGraphics.setBackgroundColor(color); thumbnailGraphics.setFont(sourceFigure.getFont()); setScales( targetSize.width / (float) getSourceRectangle().width, targetSize.height / (float) getSourceRectangle().height); Display.getCurrent().asyncExec(this); }
/** * Updates the current tile on the Thumbnail. An area of the source Figure is painted to an * {@link Image}. That Image is then drawn on the Thumbnail. Scaling of the source Image is done * inside {@link GC#drawImage(Image, int, int, int, int, int, int, int, int)} since the source * and target sizes are different. The current tile indexes are incremented and if more updating * is necesary, this {@link Runnable} is called again in a {@link Display#timerExec(int, * Runnable)}. If no more updating is required, {@link #stop()} is called. */ public void run() { if (!isActive() || !isRunning()) return; int v = getCurrentVTile(); int sy1 = v * tileSize.height; int sy2 = Math.min((v + 1) * tileSize.height, getSourceRectangle().height); int h = getCurrentHTile(); int sx1 = h * tileSize.width; int sx2 = Math.min((h + 1) * tileSize.width, getSourceRectangle().width); com.architexa.org.eclipse.draw2d.geometry.Point p = getSourceRectangle().getLocation(); Rectangle rect = new Rectangle(sx1 + p.x, sy1 + p.y, sx2 - sx1, sy2 - sy1); thumbnailGraphics.pushState(); thumbnailGraphics.setClip(rect); thumbnailGraphics.fillRectangle(rect); sourceFigure.paint(thumbnailGraphics); thumbnailGraphics.popState(); if (getCurrentHTile() < (hTiles - 1)) setCurrentHTile(getCurrentHTile() + 1); else { setCurrentHTile(0); if (getCurrentVTile() < (vTiles - 1)) setCurrentVTile(getCurrentVTile() + 1); else setCurrentVTile(0); } if (getCurrentHTile() != 0 || getCurrentVTile() != 0) Display.getCurrent().asyncExec(this); else if (isDirty()) { setDirty(false); Display.getCurrent().asyncExec(this); repaint(); } else { stop(); repaint(); } }
/** * Stops this updater. Also disposes of resources (except the thumbnail image which is still * needed for painting). */ public void stop() { isRunning = false; if (thumbnailGC != null) { thumbnailGC.dispose(); thumbnailGC = null; } if (thumbnailGraphics != null) { thumbnailGraphics.dispose(); thumbnailGraphics = null; } // Don't dispose of the thumbnail image since it is needed to paint the // figure when the source is not dirty (i.e. showing/hiding the dock). }