/*******************************************************************************
* Copyright 2014 Rafael Garcia Moreno.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.bladecoder.engineeditor.ui;
import java.awt.Desktop;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.ui.Container;
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane;
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.utils.Array;
import com.bladecoder.engineeditor.Ctx;
import com.bladecoder.engineeditor.common.EditorLogger;
import com.bladecoder.engineeditor.common.ImageUtils;
import com.bladecoder.engineeditor.common.Message;
import com.bladecoder.engineeditor.common.RunProccess;
import com.bladecoder.engineeditor.model.Project;
import com.bladecoder.engineeditor.ui.panels.CustomList;
import com.bladecoder.engineeditor.ui.panels.EditToolbar;
import com.kotcrab.vis.ui.widget.file.FileChooser;
import com.kotcrab.vis.ui.widget.file.FileChooser.Mode;
import com.kotcrab.vis.ui.widget.file.FileChooser.SelectionMode;
import com.kotcrab.vis.ui.widget.file.FileChooser.ViewMode;
import com.kotcrab.vis.ui.widget.file.FileChooserListener;
import com.kotcrab.vis.ui.widget.file.FileTypeFilter;
public class AssetsList extends Table {
private static final String[] ASSET_TYPES = { "3d models", "atlases", "music", "sounds", "images", "spine", "particles", "voices" };
private SelectBox<String> assetTypes;
protected EditToolbar toolbar;
protected CustomList<String> list;
protected Skin skin;
protected Container<ScrollPane> container;
private File lastDir;
public AssetsList(Skin skin) {
super(skin);
assetTypes = new SelectBox<String>(skin);
assetTypes.setItems(ASSET_TYPES);
this.skin = skin;
list = new CustomList<String>(skin);
Array<String> items = new Array<String>();
list.setItems(items);
ScrollPane scrollPane = new ScrollPane(list, skin);
container = new Container<ScrollPane>(scrollPane);
container.fill();
container.prefHeight(1000);
toolbar = new EditToolbar(skin);
// debug();
add(assetTypes).expandX().fillX();
row();
add(toolbar).expandX().fillX();
row();
add(container).expand().fill();
toolbar.addCreateListener(new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
create();
}
});
toolbar.addEditListener(new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
edit();
}
});
toolbar.addDeleteListener(new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
delete();
}
});
list.addListener(new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
toolbar.disableEdit(false);
}
});
Ctx.project.addPropertyChangeListener(Project.NOTIFY_PROJECT_LOADED, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent arg0) {
toolbar.disableCreate(Ctx.project.getProjectDir() == null);
addAssets();
}
});
assetTypes.addListener(new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
addAssets();
}
});
}
private void addAssets() {
list.getItems().clear();
if (Ctx.project.getProjectDir() != null) {
String type = assetTypes.getSelected();
String dir = getAssetDir(type);
if (type.equals("images") || type.equals("atlases"))
dir += "/1";
String[] files = new File(dir).list(new FilenameFilter() {
@Override
public boolean accept(File arg0, String arg1) {
String type = assetTypes.getSelected();
if (type.equals("atlases") && !arg1.endsWith(".atlas"))
return false;
return true;
}
});
if (files != null)
for (String f : files)
list.getItems().add(f);
if (list.getItems().size > 0) {
list.setSelectedIndex(0);
}
}
toolbar.disableCreate(Ctx.project.getProjectDir() == null);
list.invalidateHierarchy();
}
private String getAssetDir(String type) {
String dir;
if (type.equals("atlases")) {
dir = Ctx.project.getProjectPath() + "/" + Project.ATLASES_PATH;
} else if (type.equals("music")) {
dir = Ctx.project.getProjectPath() + "/" + Project.MUSIC_PATH;
} else if (type.equals("sounds")) {
dir = Ctx.project.getProjectPath() + "/" + Project.SOUND_PATH;
} else if (type.equals("images")) {
dir = Ctx.project.getProjectPath() + "/" + Project.IMAGE_PATH;
} else if (type.equals("3d models")) {
dir = Ctx.project.getProjectPath() + "/" + Project.SPRITE3D_PATH;
} else if (type.equals("spine")) {
dir = Ctx.project.getProjectPath() + "/" + Project.SPINE_PATH;
} else if (type.equals("particles")) {
dir = Ctx.project.getProjectPath() + "/" + Project.PARTICLE_PATH;
} else if (type.equals("voices")) {
dir = Ctx.project.getProjectPath() + "/" + Project.VOICE_PATH;
} else {
dir = Ctx.project.getProjectPath() + Project.ASSETS_PATH;
}
return dir;
}
private void create() {
final String type = assetTypes.getSelected();
if (type.equals("atlases")) {
new CreateAtlasDialog(skin).show(getStage());
// addAssets();
} else if (type.equals("particles")) {
// Open the particle editor
List<String> cp = new ArrayList<String>();
cp.add(System.getProperty("java.class.path"));
try {
RunProccess.runJavaProccess("com.badlogic.gdx.tools.particleeditor.ParticleEditor", cp, null);
} catch (IOException e) {
Message.showMsgDialog(getStage(), "Error", "Error launching Particle Editor.");
EditorLogger.printStackTrace(e);
}
} else {
FileChooser fileChooser = new FileChooser(Mode.OPEN);
fileChooser.setSelectionMode(SelectionMode.FILES);
fileChooser.setMultiSelectionEnabled(true);
fileChooser.setSize(Gdx.graphics.getWidth() * 0.7f, Gdx.graphics.getHeight() * 0.7f);
fileChooser.setViewMode(ViewMode.LIST);
getStage().addActor(fileChooser);
if(lastDir != null)
fileChooser.setDirectory(lastDir);
// chooser.setTitle("Select the '" + type + "' asset files");
FileTypeFilter typeFilter = new FileTypeFilter(true); //allow "All Types" mode where all files are shown
switch (type) {
case "images":
typeFilter.addRule("Images (*.png, *.jpg, *.etc1)", "jpg", "png", "etc1");
break;
case "music":
case "sounds":
case "voices":
typeFilter.addRule("Sound (*.mp3, *.wav, *.ogg)", "wav", "mp3", "ogg");
break;
case "3d models":
typeFilter.addRule("3D Models (*.g3db, *.png)", "g3db", "png");
break;
case "spine":
typeFilter.addRule("Spine (*.skel, *.json)", "skel", "json");
break;
default:
typeFilter.addRule("All", "");
break;
}
fileChooser.setFileTypeFilter(typeFilter);
fileChooser.setListener(new FileChooserListener() {
@Override
public void selected(Array<FileHandle> files) {
try {
String dirName = getAssetDir(type);
lastDir = files.get(0).parent().file();
// Si no existe la carpeta la creamos
File dir = new File(dirName);
if(!dir.exists())
dir.mkdir();
for (FileHandle f : files) {
if (type.equals("images")) {
List<String> res = Ctx.project.getResolutions();
for (String r : res) {
File destFile = new File(dirName + "/" + r + "/" + f.file().getName());
float scale = Float.parseFloat(r);
if (scale != 1.0f) {
ImageUtils.scaleImageFile(f.file(), destFile, scale);
} else {
Files.copy(f.file().toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
}
} else {
File destFile = new File(dir, f.file().getName());
Files.copy(f.file().toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
}
addAssets();
} catch (Exception ex) {
String msg = "Something went wrong while getting the assets.\n\n"
+ ex.getClass().getSimpleName() + " - " + ex.getMessage();
Message.showMsgDialog(getStage(), "Error", msg);
EditorLogger.printStackTrace(ex);
}
}
@Override
public void canceled() {
}
});
}
}
private void edit() {
if (Desktop.isDesktopSupported()) {
String type = assetTypes.getSelected();
String dir = getAssetDir(type);
if (type.equals("images") || type.equals("atlases"))
dir += "/1";
try {
Desktop.getDesktop().open(new File(dir));
} catch (IOException e1) {
String msg = "Something went wrong while opening assets folder.\n\n" + e1.getClass().getSimpleName()
+ " - " + e1.getMessage();
Message.showMsgDialog(getStage(), "Error", msg);
}
}
}
private void delete() {
String type = assetTypes.getSelected();
String dir = getAssetDir(type);
String name = list.getSelected();
try {
if (type.equals("images") || type.equals("atlases")) {
List<String> res = Ctx.project.getResolutions();
for (String r : res) {
File file = new File(dir + "/" + r + "/" + name);
file.delete();
// delete pages on atlases
if (type.equals("atlases")) {
File atlasDir = new File(dir + "/" + r);
File[] files = atlasDir.listFiles();
if (files != null)
for (File f : files) {
String destName = f.getName();
String nameWithoutExt = name.substring(0, name.lastIndexOf('.'));
String destNameWithoutExt = destName.substring(0, destName.lastIndexOf('.'));
if (destNameWithoutExt.length() < nameWithoutExt.length())
continue;
String suffix = destNameWithoutExt.substring(nameWithoutExt.length());
if (!suffix.isEmpty() && !suffix.matches("[0-9]+"))
continue;
if (destName.startsWith(nameWithoutExt) && destName.toLowerCase().endsWith(".png"))
Files.delete(f.toPath());
}
}
}
} else {
File file = new File(dir + "/" + name);
file.delete();
}
addAssets();
} catch (Exception ex) {
String msg = "Something went wrong while deleting the asset.\n\n" + ex.getClass().getSimpleName() + " - "
+ ex.getMessage();
Message.showMsgDialog(getStage(), "Error", msg);
EditorLogger.printStackTrace(ex);
}
}
}