com.laex.cg2d.entityeditor.ui.ImportSpritesComposite.java Source code

Java tutorial

Introduction

Here is the source code for com.laex.cg2d.entityeditor.ui.ImportSpritesComposite.java

Source

/*
 * Copyright (c) 2012, 2013 Hemanta Sapkota.
 * 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:
 * Hemanta Sapkota (laex.pearl@gmail.com)
 */
package com.laex.cg2d.entityeditor.ui;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.draw2d.FigureCanvas;
import org.eclipse.draw2d.FreeformLayeredPane;
import org.eclipse.draw2d.FreeformLayout;
import org.eclipse.draw2d.ImageFigure;
import org.eclipse.draw2d.RectangleFigure;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.ui.dialogs.FilteredResourcesSelectionDialog;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;

import swing2swt.layout.BorderLayout;

import com.laex.cg2d.model.ICGCProject;
import com.laex.cg2d.model.adapter.RectAdapter;
import com.laex.cg2d.model.model.EntitySpritesheetItem;
import com.laex.cg2d.model.model.JsonSprite;
import com.laex.cg2d.model.model.ResourceFile;
import com.laex.cg2d.model.resources.ResourceManager;

/**
 * The Class ImportSpritesComposite.
 */
public class ImportSpritesComposite extends Composite {

    /** The spritesheet image file. */
    private ResourceFile spritesheetImageFile = ResourceFile.EMPTY;

    /** The spritesheet json mapper file. */
    private ResourceFile spritesheetJsonMapperFile = ResourceFile.EMPTY;

    /** The selected image. */
    private Image selectedImage;

    /** The flp. */
    private FreeformLayeredPane flp = new FreeformLayeredPane();

    /** The toolkit. */
    private final FormToolkit toolkit = new FormToolkit(Display.getCurrent());

    /** The txt rows. */
    private Spinner txtRows;

    /** The txt tile width. */
    private Spinner txtTileWidth;

    /** The spritesheet items. */
    protected ArrayList<EntitySpritesheetItem> spritesheetItems = new ArrayList<EntitySpritesheetItem>();

    /** The extracted images. */
    private Queue<Image> extractedImages = new LinkedList<Image>();

    /** The txt cols. */
    private Spinner txtCols;

    /** The txt tile height. */
    private Spinner txtTileHeight;

    /** The figure canvas. */
    private FigureCanvas figureCanvas;

    /** The delegate. */
    private ImportSpriteCompositeDelegate delegate;

    /**
     * The listener interface for receiving extractionDataModify events.
     * The class that is interested in processing a extractionDataModify
     * event implements this interface, and the object created
     * with that class is registered with a component using the
     * component's <code>addExtractionDataModifyListener<code> method. When
     * the extractionDataModify event occurs, that object's appropriate
     * method is invoked.
     *
     * @see ExtractionDataModifyEvent
     */
    class ExtractionDataModifyListener implements ModifyListener {

        /*
         * (non-Javadoc)
         * 
         * @see
         * org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events
         * .ModifyEvent)
         */
        @Override
        public void modifyText(ModifyEvent e) {
            flp.removeAll();

            setSelectedImageToCanvas();
            updateOutline();
        }

    }

    /** The edm. */
    private ExtractionDataModifyListener edm = new ExtractionDataModifyListener();

    /** The resource container. */
    private IResource resourceContainer;

    /** The btn enable extract. */
    private Button btnEnableExtract;

    /** The lbl count. */
    private Label lblCount;

    /**
     * Sets the delegate.
     *
     * @param delegate the new delegate
     */
    public void setDelegate(ImportSpriteCompositeDelegate delegate) {
        this.delegate = delegate;
    }

    /**
     * Sets the selected image to canvas.
     */
    private void setSelectedImageToCanvas() {
        flp.removeAll();
        selectedImage = ResourceManager.getImageOfRelativePath(spritesheetImageFile.getResourceFile());

        ImageFigure iff = new ImageFigure(selectedImage);
        iff.setBounds(new Rectangle(0, 0, selectedImage.getBounds().width, selectedImage.getBounds().height));
        flp.add(iff);

        figureCanvas.setBounds(0, 0, selectedImage.getBounds().width, selectedImage.getBounds().height);

    }

    /**
     * Update outline.
     */
    private void updateOutline() {
        int cols = txtCols.getSelection();
        int rows = txtRows.getSelection();
        int imgWidth = selectedImage.getBounds().width;
        int imgHeight = selectedImage.getBounds().height;

        if (cols == 0)
            cols = 1;
        if (rows == 0)
            rows = 1;

        int tileWidth = imgWidth / cols;
        int tileHeight = imgHeight / rows;

        txtTileWidth.setSelection(tileWidth);
        txtTileHeight.setSelection(tileHeight);

        extractedImages.clear();

        List<JsonSprite> lst = new ArrayList<JsonSprite>();

        for (int y = 0; y < imgHeight; y += tileHeight) {
            for (int x = 0; x < imgWidth; x += tileWidth) {
                RectangleFigure rf = createBlockFigure(x, y, tileWidth, tileHeight);
                flp.add(rf);

                JsonSprite js = new JsonSprite("", x, y, tileWidth, tileHeight, 0, 0);
                lst.add(js);
            }
        }

        /* Only extract if selected by user */
        if (btnEnableExtract.getSelection()) {
            extractFromJSON(lst);
        }

        figureCanvas.setContents(flp);
    }

    /**
     * Creates the block figure.
     *
     * @param x the x
     * @param y the y
     * @param tileWidth the tile width
     * @param tileHeight the tile height
     * @return the rectangle figure
     */
    private RectangleFigure createBlockFigure(int x, int y, int tileWidth, int tileHeight) {
        RectangleFigure rf = new RectangleFigure();
        rf.setAlpha(120);
        rf.setBounds(new Rectangle(x, y, tileWidth, tileHeight));
        return rf;
    }

    /**
     * Gets the spritesheet items.
     *
     * @return the spritesheet items
     */
    public ArrayList<EntitySpritesheetItem> getSpritesheetItems() {
        return spritesheetItems;
    }

    /**
     * Clear outline.
     */
    private void clearOutline() {
        flp.removeAll();
        figureCanvas.setContents(null);
    }

    /**
     * Open json file opener.
     *
     * @return the list
     */
    protected List<JsonSprite> openJsonFileOpener() {
        List<JsonSprite> list = new ArrayList<JsonSprite>();

        FilteredResourcesSelectionDialog frsd = openResourceLoader("*.json");
        int resp = frsd.open();

        if (resp == FilteredResourcesSelectionDialog.CANCEL) {
            return list;
        }

        IFile selectedFile = (IFile) frsd.getFirstResult();

        String spritesheetJsonFile = selectedFile.getFullPath().toOSString();
        String spritesheetJsonAbs = selectedFile.getLocation().makeAbsolute().toOSString();

        spritesheetJsonMapperFile = ResourceFile.create(spritesheetJsonFile, spritesheetJsonAbs);

        //    JsonReader jr = new JsonReader();
        //    try {
        //      JsonValue json = jr.parse(selectedFile.getContents());
        //
        //      Entries entries = json.entries();
        //
        //      while (entries.hasNext()) {
        //        Entry e = entries.next();
        //
        //        if (e.key.equals("image") || e.key.equals("spriteCount")) {
        //          continue;
        //        }
        //
        //        OrderedMap sprite = (OrderedMap) e.value;
        //
        //        String spriteName = (String) sprite.get("id");
        //        int x = (int) Float.parseFloat(sprite.get("x").toString());
        //        int y = (int) Float.parseFloat(sprite.get("y").toString());
        //        int width = (int) Float.parseFloat(sprite.get("width").toString());
        //        int height = (int) Float.parseFloat(sprite.get("height").toString());
        //
        //        JsonSprite js = new JsonSprite(spriteName, x, y, width, height, 0, 0);
        //        list.add(js);
        //      }
        //
        //    } catch (CoreException e) {
        //      Activator.log(e);
        //    }

        return list;
    }

    /**
     * Extract from json.
     *
     * @param lst the lst
     */
    private void extractFromJSON(final List<JsonSprite> lst) {
        spritesheetItems = new ArrayList<EntitySpritesheetItem>();

        clearOutline();
        setSelectedImageToCanvas();

        ProgressMonitorDialog pmd = new ProgressMonitorDialog(getShell());
        try {

            pmd.run(false, false, new IRunnableWithProgress() {

                @Override
                public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {

                    int index = 0;

                    for (JsonSprite js : lst) {
                        Rectangle r = new Rectangle(js.getX(), js.getY(), js.getWidth(), js.getHeight());

                        EntitySpritesheetItem esi = new EntitySpritesheetItem();
                        esi.setExtractBounds(RectAdapter.gdxRect(r));
                        esi.setFrameIndex(index++);
                        spritesheetItems.add(esi);

                        final RectangleFigure rf = createBlockFigure(r.x, r.y, r.width, r.height);
                        flp.add(rf);

                        final ImageData id = ResourceManager.extractImageFromBounds(selectedImage.getImageData(),
                                RectAdapter.swtRect(rf.getBounds()));
                        extractedImages.add(ResourceManager.getImage(id));
                    }

                    lblCount.setText("#" + String.valueOf(extractedImages.size()));

                    if (delegate != null) {
                        delegate.spriteExtractionComplete(spritesheetImageFile, spritesheetJsonMapperFile,
                                spritesheetItems, extractedImages);
                    }
                }

            });

        } catch (InvocationTargetException e1) {
            e1.printStackTrace();
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }

        figureCanvas.setContents(flp);
    }

    /**
     * Open resource loader.
     *
     * @param pattern the pattern
     * @return the filtered resources selection dialog
     */
    private FilteredResourcesSelectionDialog openResourceLoader(String pattern) {
        IFolder texFlder = resourceContainer.getProject().getFolder(ICGCProject.TEXTURES_FOLDER);

        FilteredResourcesSelectionDialog frsd = new FilteredResourcesSelectionDialog(getShell(), false, texFlder,
                IResource.FILE);
        frsd.setTitle("Select a image. All the images have been listed from the textures folder");
        frsd.setInitialPattern(pattern);
        return frsd;
    }

    /**
     * Choose image.
     */
    protected void chooseImage() {
        FilteredResourcesSelectionDialog frsd = openResourceLoader("*.png");
        int resp = frsd.open();

        if (resp == FilteredResourcesSelectionDialog.CANCEL) {
            return;
        }

        IFile selectedFile = (IFile) frsd.getFirstResult();
        String resourceFile = selectedFile.getFullPath().toOSString();
        String resourceFileAbsolute = selectedFile.getLocation().makeAbsolute().toOSString();

        spritesheetImageFile = ResourceFile.create(resourceFile, resourceFileAbsolute);

        // set the image to figure canvas
        setSelectedImageToCanvas();
        updateOutline();
    }

    /**
     * Toggle extract items.
     */
    private void toggleExtractItems() {
        if (!btnEnableExtract.getSelection()) {
            txtRows.setEnabled(false);
            txtCols.setEnabled(false);
            txtTileHeight.setEnabled(false);
            txtTileWidth.setEnabled(false);
        } else {
            txtRows.setEnabled(true);
            txtCols.setEnabled(true);
            txtTileWidth.setEnabled(false);
            txtTileHeight.setEnabled(false);
        }
    }

    /**
     * Create the composite.
     *
     * @param parent the parent
     * @param style the style
     */
    public ImportSpritesComposite(Composite parent, int style) {
        this(null, parent, style);
    }

    /**
     * Instantiates a new import sprites composite.
     *
     * @param container the container
     * @param parent the parent
     * @param style the style
     */
    public ImportSpritesComposite(IResource container, Composite parent, int style) {
        super(parent, style);

        this.resourceContainer = container;

        addDisposeListener(new DisposeListener() {
            public void widgetDisposed(DisposeEvent e) {
                toolkit.dispose();
            }
        });
        toolkit.adapt(this);
        toolkit.paintBordersFor(this);
        setLayout(new FillLayout(SWT.HORIZONTAL));

        Composite composite = toolkit.createComposite(this, SWT.NONE);
        toolkit.paintBordersFor(composite);
        composite.setLayout(new BorderLayout(0, 0));

        Button btnChooseImage = toolkit.createButton(composite, "Choose Spritesheet", SWT.NONE);
        btnChooseImage.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                chooseImage();
            }
        });
        btnChooseImage.setLayoutData(BorderLayout.NORTH);

        Section sctnExtract = toolkit.createSection(composite, Section.EXPANDED | Section.TITLE_BAR);
        sctnExtract.setLayoutData(BorderLayout.WEST);
        toolkit.paintBordersFor(sctnExtract);
        sctnExtract.setText("Extract");
        sctnExtract.setExpanded(true);

        Composite composite_1 = toolkit.createComposite(sctnExtract, SWT.NONE);
        toolkit.paintBordersFor(composite_1);
        sctnExtract.setClient(composite_1);
        composite_1.setLayout(new RowLayout(SWT.VERTICAL));

        Label lblColumns = toolkit.createLabel(composite_1, "Columns", SWT.NONE);

        txtCols = new Spinner(composite_1, SWT.BORDER);
        txtCols.setSelection(8);
        txtCols.addModifyListener(edm);
        toolkit.adapt(txtCols);
        toolkit.paintBordersFor(txtCols);

        Label lblRows = toolkit.createLabel(composite_1, "Rows", SWT.NONE);

        txtRows = new Spinner(composite_1, SWT.BORDER);
        txtRows.setSelection(1);
        txtRows.addModifyListener(edm);

        Label lblWidth = new Label(composite_1, SWT.NONE);
        toolkit.adapt(lblWidth, true, true);
        lblWidth.setText("Tile Width");

        txtTileWidth = new Spinner(composite_1, SWT.BORDER);
        txtTileWidth.setEnabled(false);
        //    txtTileWidth.addModifyListener(edm);

        Label lblTileHeight = toolkit.createLabel(composite_1, "Tile Height", SWT.NONE);

        txtTileHeight = new Spinner(composite_1, SWT.BORDER);
        txtTileHeight.setEnabled(false);
        //    txtTileHeight.addModifyListener(edm);
        toolkit.adapt(txtTileHeight);
        toolkit.paintBordersFor(txtTileHeight);

        Label label = toolkit.createSeparator(composite_1, SWT.HORIZONTAL);

        Button btnJSON = toolkit.createButton(composite_1, "JSON", SWT.NONE);

        Label label_1 = toolkit.createSeparator(composite_1, SWT.HORIZONTAL);

        lblCount = toolkit.createLabel(composite_1, "#", SWT.NONE);

        btnEnableExtract = new Button(sctnExtract, SWT.CHECK);
        btnEnableExtract.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                toggleExtractItems();
            }
        });
        toolkit.adapt(btnEnableExtract, true, true);
        btnEnableExtract.setBackground(null);
        sctnExtract.setTextClient(btnEnableExtract);
        btnJSON.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                final List<JsonSprite> lst = openJsonFileOpener();
                extractFromJSON(lst);
            }
        });

        ScrolledComposite spriteComposite = new ScrolledComposite(composite,
                SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
        spriteComposite.setLayoutData(BorderLayout.CENTER);
        toolkit.adapt(spriteComposite);
        toolkit.paintBordersFor(spriteComposite);
        spriteComposite.setExpandHorizontal(true);
        spriteComposite.setExpandVertical(true);
        flp.setLayoutManager(new FreeformLayout());

        toolkit.adapt(spriteComposite);
        toolkit.paintBordersFor(spriteComposite);

        figureCanvas = new FigureCanvas(spriteComposite);
        flp.setLayoutManager(new FreeformLayout());

        toolkit.adapt(figureCanvas);
        toolkit.paintBordersFor(figureCanvas);
        spriteComposite.setContent(figureCanvas);
        spriteComposite.setMinSize(figureCanvas.computeSize(SWT.DEFAULT, SWT.DEFAULT));

        toggleExtractItems();

    }
}