Package org.erlide.wrangler.refactoring.codeinspection.view

Source Code of org.erlide.wrangler.refactoring.codeinspection.view.SWTImageCanvas

/*******************************************************************************
* Copyright (c) 2004 Chengdong Li : cdli@ccs.uky.edu
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*******************************************************************************/
package org.erlide.wrangler.refactoring.codeinspection.view;

import java.awt.geom.AffineTransform;

import org.eclipse.core.runtime.Path;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.ScrollBar;

/**
* A scrollable image canvas that extends org.eclipse.swt.graphics.Canvas.
* <p/>
* It requires Eclipse (version >= 2.1) on Win32/win32; Linux/gtk;
* MacOSX/carbon.
* <p/>
* This implementation using the pure SWT, no UI AWT package is used. For
* convenience, I put everything into one class. However, the best way to
* implement this is to use inheritance to create multiple hierarchies.
*
* @author Chengdong Li: cli4@uky.edu
*/
public class SWTImageCanvas extends Canvas {
    /* zooming rates in x and y direction are equal. */
    final float ZOOMIN_RATE = 1.1f; /* zoomin rate */
    final float ZOOMOUT_RATE = 0.9f; /* zoomout rate */
    private Image sourceImage; /* original image */
    Image screenImage; /* screen image */
    private AffineTransform transform = new AffineTransform();

    private String currentDir = ""; /* remembering file open directory */

    public SWTImageCanvas(final Composite parent) {
        this(parent, SWT.NULL);
    }

    /**
     * Constructor for ScrollableCanvas.
     *
     * @param parent
     *            the parent of this control.
     * @param style
     *            the style of this control.
     */
    public SWTImageCanvas(final Composite parent, final int style) {
        super(parent, style | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL
                | SWT.NO_BACKGROUND);
        addControlListener(new ControlAdapter() { /* resize listener. */
            @Override
            public void controlResized(final ControlEvent event) {
                syncScrollBars();
            }
        });
        addPaintListener(new PaintListener() { /* paint listener. */
            @Override
            public void paintControl(final PaintEvent event) {
                paint(event.gc);
            }
        });
        initScrollBars();
    }

    /**
     * Dispose the garbage here
     */
    @Override
    public void dispose() {
        if (sourceImage != null && !sourceImage.isDisposed()) {
            sourceImage.dispose();
        }
        if (screenImage != null && !screenImage.isDisposed()) {
            screenImage.dispose();
        }
    }

    /* Paint function */
    private void paint(final GC gc) {
        final Rectangle clientRect = getClientArea(); /* Canvas' painting area */
        if (sourceImage != null) {
            Rectangle imageRect = SWT2Dutil.inverseTransformRect(transform, clientRect);
            final int gap = 2; /* find a better start point to render */
            imageRect.x -= gap;
            imageRect.y -= gap;
            imageRect.width += 2 * gap;
            imageRect.height += 2 * gap;

            final Rectangle imageBound = sourceImage.getBounds();
            imageRect = imageRect.intersection(imageBound);
            final Rectangle destRect = SWT2Dutil.transformRect(transform, imageRect);

            if (screenImage != null) {
                screenImage.dispose();
            }
            screenImage = new Image(getDisplay(), clientRect.width, clientRect.height);
            final GC newGC = new GC(screenImage);
            newGC.setClipping(clientRect);
            newGC.drawImage(sourceImage, imageRect.x, imageRect.y, imageRect.width,
                    imageRect.height, destRect.x, destRect.y, destRect.width,
                    destRect.height);
            newGC.dispose();

            gc.drawImage(screenImage, 0, 0);
        } else {
            gc.setClipping(clientRect);
            gc.fillRectangle(clientRect);
            initScrollBars();
        }
    }

    /* Initalize the scrollbar and register listeners. */
    private void initScrollBars() {
        final ScrollBar horizontal = getHorizontalBar();
        horizontal.setEnabled(false);
        horizontal.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent event) {
                scrollHorizontally((ScrollBar) event.widget);
            }
        });
        final ScrollBar vertical = getVerticalBar();
        vertical.setEnabled(false);
        vertical.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent event) {
                scrollVertically((ScrollBar) event.widget);
            }
        });
    }

    /* Scroll horizontally */
    private void scrollHorizontally(final ScrollBar scrollBar) {
        if (sourceImage == null) {
            return;
        }

        final AffineTransform af = transform;
        final double tx = af.getTranslateX();
        final double select = -scrollBar.getSelection();
        af.preConcatenate(AffineTransform.getTranslateInstance(select - tx, 0));
        transform = af;
        syncScrollBars();
    }

    /* Scroll vertically */
    private void scrollVertically(final ScrollBar scrollBar) {
        if (sourceImage == null) {
            return;
        }

        final AffineTransform af = transform;
        final double ty = af.getTranslateY();
        final double select = -scrollBar.getSelection();
        af.preConcatenate(AffineTransform.getTranslateInstance(0, select - ty));
        transform = af;
        syncScrollBars();
    }

    /**
     * Source image getter.
     *
     * @return sourceImage.
     */
    public Image getSourceImage() {
        return sourceImage;
    }

    /**
     * Synchronize the scrollbar with the image. If the transform is out of
     * range, it will correct it. This function considers only following factors
     * :<b> transform, image size, client area</b>.
     */
    public void syncScrollBars() {
        if (sourceImage == null) {
            redraw();
            return;
        }

        AffineTransform af = transform;
        final double sx = af.getScaleX(), sy = af.getScaleY();
        double tx = af.getTranslateX(), ty = af.getTranslateY();
        if (tx > 0) {
            tx = 0;
        }
        if (ty > 0) {
            ty = 0;
        }

        final ScrollBar horizontal = getHorizontalBar();
        horizontal.setIncrement(getClientArea().width / 100);
        horizontal.setPageIncrement(getClientArea().width);
        final Rectangle imageBound = sourceImage.getBounds();
        final int cw = getClientArea().width, ch = getClientArea().height;
        if (imageBound.width * sx > cw) { /* image is wider than client area */
            horizontal.setMaximum((int) (imageBound.width * sx));
            horizontal.setEnabled(true);
            if ((int) -tx > horizontal.getMaximum() - cw) {
                tx = -horizontal.getMaximum() + cw;
            }
        } else { /* image is narrower than client area */
            horizontal.setEnabled(false);
            tx = (cw - imageBound.width * sx) / 2; // center if too small.
        }
        horizontal.setSelection((int) -tx);
        horizontal.setThumb(getClientArea().width);

        final ScrollBar vertical = getVerticalBar();
        vertical.setIncrement(getClientArea().height / 100);
        vertical.setPageIncrement(getClientArea().height);
        if (imageBound.height * sy > ch) { /* image is higher than client area */
            vertical.setMaximum((int) (imageBound.height * sy));
            vertical.setEnabled(true);
            if ((int) -ty > vertical.getMaximum() - ch) {
                ty = -vertical.getMaximum() + ch;
            }
        } else { /* image is less higher than client area */
            vertical.setEnabled(false);
            ty = (ch - imageBound.height * sy) / 2; // center if too small.
        }
        vertical.setSelection((int) -ty);
        vertical.setThumb(getClientArea().height);

        /* update transform. */
        af = AffineTransform.getScaleInstance(sx, sy);
        af.preConcatenate(AffineTransform.getTranslateInstance(tx, ty));
        transform = af;

        redraw();
    }

    /**
     * Reload image from a file
     *
     * @param filename
     *            image file
     * @return swt image created from image file
     */
    public Image loadImage(final String filename) {
        if (sourceImage != null && !sourceImage.isDisposed()) {
            sourceImage.dispose();
            sourceImage = null;
        }
        sourceImage = new Image(getDisplay(), filename);
        showOriginal();
        return sourceImage;
    }

    /**
     * Load image
     *
     * @param img
     *            image object
     */
    public void setImage(final Image img) {
        sourceImage = img;
        showOriginal();
    }

    /**
     * Save image to a file
     */
    public void onFileSave() {
        final FileDialog fileChooser = new FileDialog(getShell(), SWT.SAVE);
        fileChooser.setText("Save image file");
        fileChooser.setFilterPath(currentDir);
        fileChooser.setFilterExtensions(new String[] { "*.jpg;*.png" });
        fileChooser.setFilterNames(new String[] { "Image file " + " (jpeg, png)" });
        final String filename = fileChooser.open();
        if (filename != null) {
            final ImageLoader imageLoader = new ImageLoader();
            imageLoader.data = new ImageData[] { sourceImage.getImageData() };
            final Path p = new Path(filename);
            if (p.getFileExtension() == "jpg") {
                imageLoader.save(filename, SWT.IMAGE_JPEG);
            } else {
                imageLoader.save(filename, SWT.IMAGE_PNG);
            }

        }

    }

    /**
     * Call back funtion of button "open". Will open a file dialog, and choose
     * the image file. It supports image formats supported by Eclipse.
     */
    public void onFileOpen() {
        final FileDialog fileChooser = new FileDialog(getShell(), SWT.OPEN);
        fileChooser.setText("Open image file");
        fileChooser.setFilterPath(currentDir);
        fileChooser
                .setFilterExtensions(new String[] { "*.gif; *.jpg; *.png; *.ico; *.bmp" });
        fileChooser.setFilterNames(new String[] { "SWT image"
                + " (gif, jpeg, png, ico, bmp)" });
        final String filename = fileChooser.open();
        if (filename != null) {
            loadImage(filename);
            currentDir = fileChooser.getFilterPath();
        }
    }

    /**
     * Get the image data. (for future use only)
     *
     * @return image data of canvas
     */
    public ImageData getImageData() {
        return sourceImage.getImageData();
    }

    /**
     * Reset the image data and update the image
     *
     * @param data
     *            image data to be set
     */
    public void setImageData(final ImageData data) {
        if (sourceImage != null) {
            sourceImage.dispose();
        }
        if (data != null) {
            sourceImage = new Image(getDisplay(), data);
        }
        syncScrollBars();
    }

    /**
     * Fit the image onto the canvas
     */
    public void fitCanvas() {
        if (sourceImage == null) {
            return;
        }
        final Rectangle imageBound = sourceImage.getBounds();
        final Rectangle destRect = getClientArea();
        final double sx = (double) destRect.width / (double) imageBound.width;
        final double sy = (double) destRect.height / (double) imageBound.height;
        final double s = Math.min(sx, sy);
        final double dx = 0.5 * destRect.width;
        final double dy = 0.5 * destRect.height;
        centerZoom(dx, dy, s, new AffineTransform());
    }

    /**
     * Show the image with the original size
     */
    public void showOriginal() {
        if (sourceImage == null) {
            return;
        }
        transform = new AffineTransform();
        syncScrollBars();
    }

    /**
     * Perform a zooming operation centered on the given point (dx, dy) and
     * using the given scale factor. The given AffineTransform instance is
     * preconcatenated.
     *
     * @param dx
     *            center x
     * @param dy
     *            center y
     * @param scale
     *            zoom rate
     * @param af
     *            original affinetransform
     */
    public void centerZoom(final double dx, final double dy, final double scale,
            final AffineTransform af) {
        af.preConcatenate(AffineTransform.getTranslateInstance(-dx, -dy));
        af.preConcatenate(AffineTransform.getScaleInstance(scale, scale));
        af.preConcatenate(AffineTransform.getTranslateInstance(dx, dy));
        transform = af;
        syncScrollBars();
    }

    /**
     * Zoom in around the center of client Area.
     */
    public void zoomIn() {
        if (sourceImage == null) {
            return;
        }
        final Rectangle rect = getClientArea();
        final int w = rect.width, h = rect.height;
        final double dx = (double) w / 2;
        final double dy = (double) h / 2;
        centerZoom(dx, dy, ZOOMIN_RATE, transform);
    }

    /**
     * Zoom out around the center of client Area.
     */
    public void zoomOut() {
        if (sourceImage == null) {
            return;
        }
        final Rectangle rect = getClientArea();
        final int w = rect.width, h = rect.height;
        final double dx = (double) w / 2;
        final double dy = (double) h / 2;
        centerZoom(dx, dy, ZOOMOUT_RATE, transform);
    }
}
TOP

Related Classes of org.erlide.wrangler.refactoring.codeinspection.view.SWTImageCanvas

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.