diff --git a/assets/plugins/plugin-9patch-0.0.7.jar b/assets/plugins/plugin-9patch-0.0.7.jar index f3541ac6..39dee0e6 100644 Binary files a/assets/plugins/plugin-9patch-0.0.7.jar and b/assets/plugins/plugin-9patch-0.0.7.jar differ diff --git a/assets/plugins/plugin-tiled-0.0.7.jar b/assets/plugins/plugin-tiled-0.0.7.jar index 82eaf069..40d852cd 100644 Binary files a/assets/plugins/plugin-tiled-0.0.7.jar and b/assets/plugins/plugin-tiled-0.0.7.jar differ diff --git a/assets/style/uiskin.json b/assets/style/uiskin.json index a30adcd0..d8ad3efe 100644 --- a/assets/style/uiskin.json +++ b/assets/style/uiskin.json @@ -135,6 +135,9 @@ hScrollKnob: scroll-knob-horizontal } }, + com.kotcrab.vis.ui.util.adapter.SimpleListAdapter$SimpleListAdapterStyle: { + default: {selection: list-selection } + } com.badlogic.gdx.scenes.scene2d.ui.SelectBox$SelectBoxStyle: { default: { font: default-font, diff --git a/h2d-libgdx-spine-extension b/h2d-libgdx-spine-extension index 8e09aab5..f9de1d70 160000 --- a/h2d-libgdx-spine-extension +++ b/h2d-libgdx-spine-extension @@ -1 +1 @@ -Subproject commit 8e09aab5639fd95152e66291b70f8c7a3e942c65 +Subproject commit f9de1d70029721df5c7526158c86fba2b24c018c diff --git a/h2d-libgdx-talos-extension b/h2d-libgdx-talos-extension index 2b43d7b7..94b1d7dc 160000 --- a/h2d-libgdx-talos-extension +++ b/h2d-libgdx-talos-extension @@ -1 +1 @@ -Subproject commit 2b43d7b7cb9eb84d1322782cee692712f9f0f797 +Subproject commit 94b1d7dce75962ee60a38fb405548fe168f21b3b diff --git a/hyperlap2d-common-api b/hyperlap2d-common-api index 32f61ecb..06009aa7 160000 --- a/hyperlap2d-common-api +++ b/hyperlap2d-common-api @@ -1 +1 @@ -Subproject commit 32f61ecbdfb01bd4d3e720791eb8b852e320984a +Subproject commit 06009aa76abb57a83692033d5e97f67d5282200d diff --git a/hyperlap2d-runtime-libgdx b/hyperlap2d-runtime-libgdx index 511e35ce..b1b5e944 160000 --- a/hyperlap2d-runtime-libgdx +++ b/hyperlap2d-runtime-libgdx @@ -1 +1 @@ -Subproject commit 511e35ce512d2ac0ee815823ec48f8cb822d555e +Subproject commit b1b5e9445c33e1474d46b9d805394076f1a1cfb2 diff --git a/plugin-9patch/src/main/java/games/rednblack/editor/plugin/ninepatch/MainPanelMediator.java b/plugin-9patch/src/main/java/games/rednblack/editor/plugin/ninepatch/MainPanelMediator.java index 9860a572..696912d8 100644 --- a/plugin-9patch/src/main/java/games/rednblack/editor/plugin/ninepatch/MainPanelMediator.java +++ b/plugin-9patch/src/main/java/games/rednblack/editor/plugin/ninepatch/MainPanelMediator.java @@ -5,6 +5,7 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.g2d.NinePatch; import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.graphics.g2d.TextureRegion; import games.rednblack.editor.renderer.components.MainItemComponent; import games.rednblack.editor.renderer.components.NinePatchComponent; import games.rednblack.editor.renderer.components.TextureRegionComponent; @@ -148,9 +149,9 @@ public class MainPanelMediator extends Mediator { } private void loadRegion(String name) { - TextureAtlas atlas = plugin.getAPI().getProjectTextureAtlas(); - validateNinePatchTextureRegion(atlas.findRegion(name)); - viewComponent.setTexture(atlas.findRegion(name)); + TextureAtlas.AtlasRegion region = plugin.getAPI().getProjectTextureRegion(name); + validateNinePatchTextureRegion(region); + viewComponent.setTexture(region); viewComponent.setListeners(plugin.getAPI().getUIStage()); } diff --git a/plugin-tiled/src/main/java/games/rednblack/editor/plugin/tiled/manager/ResourcesManager.java b/plugin-tiled/src/main/java/games/rednblack/editor/plugin/tiled/manager/ResourcesManager.java index 2eb06a0a..bf5d7aa6 100644 --- a/plugin-tiled/src/main/java/games/rednblack/editor/plugin/tiled/manager/ResourcesManager.java +++ b/plugin-tiled/src/main/java/games/rednblack/editor/plugin/tiled/manager/ResourcesManager.java @@ -14,7 +14,7 @@ import com.google.common.io.ByteStreams; import games.rednblack.editor.plugin.tiled.TiledPlugin; import games.rednblack.editor.plugin.tiled.view.SpineDrawable; import games.rednblack.editor.renderer.factory.EntityFactory; -import games.rednblack.h2d.extention.spine.PrefixAtlasAttachmentLoader; +import games.rednblack.h2d.extention.spine.ResourceRetrieverAttachmentLoader; import java.io.File; import java.io.FileOutputStream; @@ -96,7 +96,7 @@ public class ResourcesManager { public SpineDrawable getSpineDrawable(String name) { if (spineDrawableCache.get(name) == null) { - PrefixAtlasAttachmentLoader atlasAttachmentLoader = new PrefixAtlasAttachmentLoader(name, tiledPlugin.getAPI().getSceneLoader().getRm().getMainPack()); + ResourceRetrieverAttachmentLoader atlasAttachmentLoader = new ResourceRetrieverAttachmentLoader(name, tiledPlugin.getAPI().getSceneLoader().getRm()); SkeletonJson skeletonJson = new SkeletonJson(atlasAttachmentLoader); SkeletonData skeletonData = skeletonJson.readSkeletonData(tiledPlugin.getAPI().getSceneLoader().getRm().getSkeletonJSON(name)); Skeleton skeleton = new Skeleton(skeletonData); diff --git a/plugin-tiled/src/main/java/games/rednblack/editor/plugin/tiled/tools/drawStrategy/SpineDrawStrategy.java b/plugin-tiled/src/main/java/games/rednblack/editor/plugin/tiled/tools/drawStrategy/SpineDrawStrategy.java index 927a615e..22f51459 100644 --- a/plugin-tiled/src/main/java/games/rednblack/editor/plugin/tiled/tools/drawStrategy/SpineDrawStrategy.java +++ b/plugin-tiled/src/main/java/games/rednblack/editor/plugin/tiled/tools/drawStrategy/SpineDrawStrategy.java @@ -9,7 +9,7 @@ import games.rednblack.editor.renderer.components.SpineDataComponent; import games.rednblack.editor.renderer.utils.ComponentRetriever; import games.rednblack.h2d.common.command.ReplaceSpineCommandBuilder; import games.rednblack.h2d.common.factory.IFactory; -import games.rednblack.h2d.extention.spine.PrefixAtlasAttachmentLoader; +import games.rednblack.h2d.extention.spine.ResourceRetrieverAttachmentLoader; public class SpineDrawStrategy extends BasicDrawStrategy { @@ -45,7 +45,7 @@ public class SpineDrawStrategy extends BasicDrawStrategy { replaceSpineCommandBuilder.begin(entity); String animName = tiledPlugin.getSelectedTileName(); replaceSpineCommandBuilder.setAnimationName(animName); - PrefixAtlasAttachmentLoader atlasAttachmentLoader = new PrefixAtlasAttachmentLoader(animName, tiledPlugin.getAPI().getSceneLoader().getRm().getMainPack()); + ResourceRetrieverAttachmentLoader atlasAttachmentLoader = new ResourceRetrieverAttachmentLoader(animName, tiledPlugin.getAPI().getSceneLoader().getRm()); SkeletonJson skeletonJson = new SkeletonJson(atlasAttachmentLoader); replaceSpineCommandBuilder.setSkeletonJson(skeletonJson); SkeletonData skeletonData = skeletonJson.readSkeletonData((tiledPlugin.getAPI().getSceneLoader().getRm().getSkeletonJSON(animName))); diff --git a/src/main/java/games/rednblack/editor/controller/BootstrapViewCommand.java b/src/main/java/games/rednblack/editor/controller/BootstrapViewCommand.java index 6326a396..a458325e 100644 --- a/src/main/java/games/rednblack/editor/controller/BootstrapViewCommand.java +++ b/src/main/java/games/rednblack/editor/controller/BootstrapViewCommand.java @@ -87,6 +87,8 @@ public class BootstrapViewCommand extends SimpleCommand { facade.registerMediator(new CreatePlaceholderDialogMediator()); facade.registerMediator(new CreateNoiseDialogMediator()); facade.registerMediator(new ConsoleDialogMediator()); + facade.registerMediator(new ImagesPackDialogMediator()); + facade.registerMediator(new AnimationsPackDialogMediator()); facade.registerMediator(new SaveProjectDialogMediator()); } diff --git a/src/main/java/games/rednblack/editor/data/SpineAnimData.java b/src/main/java/games/rednblack/editor/data/SpineAnimData.java index d7299f18..f3f2f965 100644 --- a/src/main/java/games/rednblack/editor/data/SpineAnimData.java +++ b/src/main/java/games/rednblack/editor/data/SpineAnimData.java @@ -25,7 +25,6 @@ import com.badlogic.gdx.graphics.g2d.TextureAtlas; * Created by azakhary on 7/3/2014. */ public class SpineAnimData { - public TextureAtlas atlas; public FileHandle jsonFile; public String animName; } diff --git a/src/main/java/games/rednblack/editor/proxy/PluginManager.java b/src/main/java/games/rednblack/editor/proxy/PluginManager.java index 521c9563..4210a176 100644 --- a/src/main/java/games/rednblack/editor/proxy/PluginManager.java +++ b/src/main/java/games/rednblack/editor/proxy/PluginManager.java @@ -109,9 +109,9 @@ public class PluginManager extends Proxy implements PluginAPI { } @Override - public TextureAtlas getProjectTextureAtlas() { + public TextureAtlas.AtlasRegion getProjectTextureRegion(String regionName) { ResourceManager resourceManager = facade.retrieveProxy(ResourceManager.NAME); - return resourceManager.getTextureAtlas(); + return (TextureAtlas.AtlasRegion) resourceManager.getTextureRegion(regionName); } @Override diff --git a/src/main/java/games/rednblack/editor/proxy/ProjectManager.java b/src/main/java/games/rednblack/editor/proxy/ProjectManager.java index 461da150..f2e80aff 100755 --- a/src/main/java/games/rednblack/editor/proxy/ProjectManager.java +++ b/src/main/java/games/rednblack/editor/proxy/ProjectManager.java @@ -299,12 +299,6 @@ public class ProjectManager extends Proxy { } } - public void reLoadProjectAssets() { - ResolutionManager resolutionManager = facade.retrieveProxy(ResolutionManager.NAME); - ResourceManager resourceManager = facade.retrieveProxy(ResourceManager.NAME); - resourceManager.loadCurrentProjectAssets(currentProjectPath + "/assets/" + resolutionManager.currentResolutionName + "/pack/pack.atlas"); - } - public void loadProjectData(String projectPath) { // All legit loading assets ResolutionManager resolutionManager = facade.retrieveProxy(ResolutionManager.NAME); @@ -405,12 +399,7 @@ public class ProjectManager extends Proxy { newFile.mkdir(); } - // The filename should not be changed because the particle effects contain the name in their - // configuration. Unfortunately though, the texture packer does not support the underscore because - // any underscore in the texture packer is considered an image index. More info here: - // https://github.com/libgdx/libgdx/wiki/Texture-packer#image-indexes - // So, long story short, we MUST remove the underscore. - ImageIO.write(bufferedImage, "png", new File(targetPath + "/" + handle.name().replace("_", ""))); + ImageIO.write(bufferedImage, "png", new File(targetPath + "/" + handle.name())); } catch (IOException e) { e.printStackTrace(); } @@ -450,7 +439,6 @@ public class ProjectManager extends Proxy { if (!currentProjectVO.projectMainExportPath.isEmpty()) { exportFonts(currentProjectVO.projectMainExportPath); } - exportStyles(defaultBuildPath); SceneDataManager sceneDataManager = facade.retrieveProxy(SceneDataManager.NAME); sceneDataManager.buildScenes(defaultBuildPath); if (!currentProjectVO.projectMainExportPath.isEmpty()) { @@ -458,18 +446,6 @@ public class ProjectManager extends Proxy { } } - private void exportStyles(String targetPath) { - String srcPath = currentProjectPath + "/assets/orig"; - FileHandle origDirectoryHandle = Gdx.files.absolute(srcPath); - FileHandle stylesDirectory = origDirectoryHandle.child("styles"); - File fileTarget = new File(targetPath + "/" + stylesDirectory.name()); - try { - FileUtils.copyDirectory(stylesDirectory.file(), fileTarget); - } catch (IOException e) { - e.printStackTrace(); - } - } - private void exportShaders(String targetPath) { String srcPath = currentProjectPath + "/assets"; FileHandle origDirectoryHandle = Gdx.files.absolute(srcPath); @@ -477,8 +453,7 @@ public class ProjectManager extends Proxy { File fileTarget = new File(targetPath + "/" + shadersDirectory.name()); try { FileUtils.copyDirectory(shadersDirectory.file(), fileTarget); - } catch (IOException e) { - e.printStackTrace(); + } catch (IOException ignore) { } } @@ -489,8 +464,7 @@ public class ProjectManager extends Proxy { File fileTarget = new File(targetPath + "/" + particlesDirectory.name()); try { FileUtils.copyDirectory(particlesDirectory.file(), fileTarget); - } catch (IOException e) { - e.printStackTrace(); + } catch (IOException ignore) { } } @@ -501,8 +475,7 @@ public class ProjectManager extends Proxy { File fileTarget = new File(targetPath + "/" + particlesDirectory.name()); try { FileUtils.copyDirectory(particlesDirectory.file(), fileTarget); - } catch (IOException e) { - e.printStackTrace(); + } catch (IOException ignore) { } } @@ -513,8 +486,7 @@ public class ProjectManager extends Proxy { File fileTarget = new File(targetPath + "/" + fontsDirectory.name()); try { FileUtils.copyDirectory(fontsDirectory.file(), fileTarget); - } catch (IOException e) { - e.printStackTrace(); + } catch (IOException ignore) { } } diff --git a/src/main/java/games/rednblack/editor/proxy/ResolutionManager.java b/src/main/java/games/rednblack/editor/proxy/ResolutionManager.java index cd2fd2f1..f943f282 100644 --- a/src/main/java/games/rednblack/editor/proxy/ResolutionManager.java +++ b/src/main/java/games/rednblack/editor/proxy/ResolutionManager.java @@ -29,7 +29,9 @@ import java.util.concurrent.Executors; import javax.imageio.ImageIO; import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.utils.ObjectMap; import com.kotcrab.vis.ui.util.dialog.Dialogs; +import games.rednblack.editor.renderer.data.TexturePackVO; import games.rednblack.h2d.common.MsgAPI; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; @@ -178,8 +180,6 @@ public class ResolutionManager extends Proxy { ProjectManager projectManager = facade.retrieveProxy(ProjectManager.NAME); TexturePacker.Settings settings = projectManager.getTexturePackerSettings(); - TexturePacker tp = new TexturePacker(settings); - String sourcePath = projectManager.getCurrentProjectPath() + "/assets/" + resEntry.name + "/images"; String outputPath = projectManager.getCurrentProjectPath() + "/assets/" + resEntry.name + "/pack"; @@ -193,15 +193,36 @@ public class ResolutionManager extends Proxy { e.printStackTrace(); } + ObjectMap packerMap = new ObjectMap<>(); + ObjectMap regionsReverse = new ObjectMap<>(); + for (TexturePackVO packVO : projectManager.currentProjectInfoVO.imagesPacks.values()) { + String name = packVO.name.equals("main") ? "pack" : packVO.name; + packerMap.put(name, new TexturePacker(settings)); + for (String region : packVO.regions) + regionsReverse.put(region, name); + } + for (TexturePackVO packVO : projectManager.currentProjectInfoVO.animationsPacks.values()) { + String name = packVO.name.equals("main") ? "pack" : packVO.name; + if (packerMap.get(name) == null) + packerMap.put(name, new TexturePacker(settings)); + for (String region : packVO.regions) + regionsReverse.put(region, name); + } + + for (FileHandle entry : sourceDir.list()) { - String filename = entry.file().getName(); - String extension = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase(); - if (extension.equals("png")) { + if (entry.extension().equals("png")) { + String name = regionsReverse.get(entry.nameWithoutExtension().replace(".9", "").replaceAll("_.*", "")); + name = name == null ? "pack" : name; + TexturePacker tp = packerMap.get(name); tp.addImage(entry.file()); } } - tp.pack(outputDir, "pack"); + for (String name : packerMap.keys()) { + TexturePacker tp = packerMap.get(name); + tp.pack(outputDir, name); + } } private int resizeTextures(String path, ResolutionEntryVO resolution) { diff --git a/src/main/java/games/rednblack/editor/proxy/ResourceManager.java b/src/main/java/games/rednblack/editor/proxy/ResourceManager.java index 777b27e2..491382f1 100644 --- a/src/main/java/games/rednblack/editor/proxy/ResourceManager.java +++ b/src/main/java/games/rednblack/editor/proxy/ResourceManager.java @@ -30,6 +30,7 @@ import games.rednblack.editor.renderer.data.*; import games.rednblack.editor.renderer.utils.H2DSkinLoader; import games.rednblack.editor.renderer.utils.ShadedDistanceFieldFont; import games.rednblack.editor.view.ui.widget.actors.basic.WhitePixel; +import games.rednblack.h2d.extension.talos.ResourceRetrieverAssetProvider; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; @@ -58,7 +59,7 @@ public class ResourceManager extends Proxy implements IResourceRetriever { private final HashMap particleEffects = new HashMap<>(1); private final HashMap talosVFXs = new HashMap<>(1); private final HashMap talosVFXsFiles = new HashMap<>(1); - private TextureAtlas currentProjectAtlas; + private HashMap currentProjectAtlas = new HashMap<>(1); private final HashMap spineAnimAtlases = new HashMap<>(); private final HashMap> spriteAnimAtlases = new HashMap<>(); @@ -145,17 +146,17 @@ public class ResourceManager extends Proxy implements IResourceRetriever { @Override public TextureRegion getTextureRegion(String name) { - TextureRegion reg = currentProjectAtlas.findRegion(name); - - if(reg == null) { - reg = defaultRegion; + for (TextureAtlas atlas : currentProjectAtlas.values()) { + TextureRegion region = atlas.findRegion(name); + if (region != null) + return region; } - - return reg; + return defaultRegion; } - public TextureAtlas getTextureAtlas() { - return currentProjectAtlas; + @Override + public TextureAtlas getTextureAtlas(String atlasName) { + return currentProjectAtlas.get(atlasName); } @Override @@ -201,7 +202,11 @@ public class ResourceManager extends Proxy implements IResourceRetriever { @Override public boolean hasTextureRegion(String regionName) { - return currentProjectAtlas.findRegion(regionName) != null; + for (TextureAtlas atlas : currentProjectAtlas.values()) { + if (atlas.findRegion(regionName) != null) + return true; + } + return false; } @Override @@ -223,7 +228,7 @@ public class ResourceManager extends Proxy implements IResourceRetriever { public void loadCurrentProjectData(String projectPath, String curResolution) { packResolutionName = curResolution; - loadCurrentProjectAssets(projectPath + "/assets/" + curResolution + "/pack/pack.atlas"); + loadCurrentProjectAssets(projectPath + "/assets/" + curResolution + "/pack"); loadCurrentProjectParticles(projectPath + "/assets/orig/particles"); loadCurrentProjectTalosVFXs(projectPath + "/assets/orig/talos-vfx"); loadCurrentProjectSpineAnimations(projectPath + "/assets/", curResolution); @@ -241,7 +246,13 @@ public class ResourceManager extends Proxy implements IResourceRetriever { if (file.isDirectory() || filename.endsWith(".DS_Store")) continue; ParticleEffect particleEffect = new ParticleEffect(); - particleEffect.load(Gdx.files.internal(file.getAbsolutePath()), currentProjectAtlas, ""); + particleEffect.loadEmitters(Gdx.files.internal(file.getAbsolutePath())); + for (TextureAtlas atlas : currentProjectAtlas.values()) { + try { + particleEffect.loadEmitterImages(atlas, ""); + break; + } catch (Exception ignore) { } + } particleEffects.put(filename, particleEffect); } } @@ -255,7 +266,7 @@ public class ResourceManager extends Proxy implements IResourceRetriever { String filename = file.getName(); if (file.isDirectory() || filename.endsWith(".DS_Store") || filename.endsWith("shdr") || filename.endsWith(".fga")) continue; - AtlasAssetProvider assetProvider = new AtlasAssetProvider(currentProjectAtlas); + ResourceRetrieverAssetProvider assetProvider = new ResourceRetrieverAssetProvider(this); assetProvider.setAssetHandler(ShaderDescriptor.class, this::findShaderDescriptorOnLoad); assetProvider.setAssetHandler(VectorField.class, this::findVectorFieldDescriptorOnLoad); ParticleEffectDescriptor effectDescriptor = new ParticleEffectDescriptor(); @@ -305,7 +316,6 @@ public class ResourceManager extends Proxy implements IResourceRetriever { String animName = FilenameUtils.removeExtension(entry.file().getName()); FileHandle animJsonFile = Gdx.files.internal(entry.file().getAbsolutePath() + File.separator + animName + ".json"); SpineAnimData data = new SpineAnimData(); - data.atlas = currentProjectAtlas; data.jsonFile = animJsonFile; data.animName = animName; spineAnimAtlases.put(animName, data); @@ -320,16 +330,25 @@ public class ResourceManager extends Proxy implements IResourceRetriever { for (FileHandle entry : sourceDir.list()) { if (entry.file().isDirectory()) { String animName = FilenameUtils.removeExtension(entry.file().getName()); - spriteAnimAtlases.put(animName, currentProjectAtlas.findRegions(animName)); + Array regions = null; + for (TextureAtlas atlas : currentProjectAtlas.values()) { + regions = atlas.findRegions(animName); + if (regions.size > 0) + break; + } + if (regions != null) + spriteAnimAtlases.put(animName, regions); } } } - public void loadCurrentProjectAssets(String packPath) { - try { - currentProjectAtlas = new TextureAtlas(Gdx.files.getFileHandle(packPath, Files.FileType.Internal)); - } catch (Exception e) { - currentProjectAtlas = new TextureAtlas(); + public void loadCurrentProjectAssets(String packFolderPath) { + FileHandle folder = new FileHandle(packFolderPath); + for (FileHandle file : folder.list()) { + if (file.extension().equals("atlas")) { + String name = file.nameWithoutExtension().equals("pack") ? "main" : file.nameWithoutExtension(); + currentProjectAtlas.put(name, new TextureAtlas(file)); + } } } @@ -485,8 +504,8 @@ public class ResourceManager extends Proxy implements IResourceRetriever { return spriteAnimAtlases; } - public TextureAtlas getProjectAssetsList() { - return currentProjectAtlas; + public TextureAtlas getProjectAssetsList(String atlas) { + return currentProjectAtlas.get(atlas); } public HashMap getProjectParticleList() { @@ -513,9 +532,4 @@ public class ResourceManager extends Proxy implements IResourceRetriever { public HashMap getShaders() { return shaderPrograms; } - - @Override - public TextureAtlas getMainPack() { - return currentProjectAtlas; - } } diff --git a/src/main/java/games/rednblack/editor/view/menu/ResourcesMenu.java b/src/main/java/games/rednblack/editor/view/menu/ResourcesMenu.java index 9da2006e..8ff7a6a7 100644 --- a/src/main/java/games/rednblack/editor/view/menu/ResourcesMenu.java +++ b/src/main/java/games/rednblack/editor/view/menu/ResourcesMenu.java @@ -14,6 +14,8 @@ public class ResourcesMenu extends H2DMenu { public static final String IMPORT_TO_LIBRARY = HyperLap2DMenuBar.prefix + ".IMPORT_TO_LIBRARY"; public static final String CREATE_PLACEHOLDER = HyperLap2DMenuBar.prefix + ".CREATE_PLACEHOLDER"; public static final String CREATE_NOISE = HyperLap2DMenuBar.prefix + ".CREATE_NOISE"; + public static final String OPEN_IMAGES_PACK = HyperLap2DMenuBar.prefix + ".OPEN_IMAGES_PACK"; + public static final String OPEN_ANIMATIONS_PACK = HyperLap2DMenuBar.prefix + ".OPEN_ANIMATIONS_PACK"; public ResourcesMenu() { super("Resources"); @@ -21,10 +23,14 @@ public class ResourcesMenu extends H2DMenu { MenuItem placeholders = new MenuItem("Create Placeholder...", new MenuItemListener(CREATE_PLACEHOLDER, null, RESOURCE_MENU)); MenuItem noise = new MenuItem("Create Perlin Noise...", new MenuItemListener(CREATE_NOISE, null, RESOURCE_MENU)); MenuItem repack = new MenuItem("Repack Assets", new MenuItemListener(MsgAPI.ACTION_REPACK, null, RESOURCE_MENU)); + MenuItem imagesPack = new MenuItem("Images Atlases...", new MenuItemListener(OPEN_IMAGES_PACK, null, RESOURCE_MENU)); + MenuItem animationsPack = new MenuItem("Animations Atlases...", new MenuItemListener(OPEN_ANIMATIONS_PACK, null, RESOURCE_MENU)); addItem(importToLibrary); addSeparator(); addItem(repack); + addItem(imagesPack); + addItem(animationsPack); addSeparator(); addItem(placeholders); addItem(noise); diff --git a/src/main/java/games/rednblack/editor/view/ui/box/resourcespanel/UIImagesTabMediator.java b/src/main/java/games/rednblack/editor/view/ui/box/resourcespanel/UIImagesTabMediator.java index 76cd40eb..f35361b1 100644 --- a/src/main/java/games/rednblack/editor/view/ui/box/resourcespanel/UIImagesTabMediator.java +++ b/src/main/java/games/rednblack/editor/view/ui/box/resourcespanel/UIImagesTabMediator.java @@ -71,7 +71,7 @@ public class UIImagesTabMediator extends UIResourcesTabMediator { ProjectManager projectManager = facade.retrieveProxy(ProjectManager.NAME); ProjectInfoVO projectInfoVO = projectManager.getCurrentProjectInfoVO(); - TextureAtlas atlas = resourceManager.getProjectAssetsList(); + TextureAtlas atlas = resourceManager.getProjectAssetsList("main"); Array thumbnailBoxes = new Array<>(); Array atlasRegions = atlas.getRegions(); diff --git a/src/main/java/games/rednblack/editor/view/ui/dialog/AnimationsPackDialogMediator.java b/src/main/java/games/rednblack/editor/view/ui/dialog/AnimationsPackDialogMediator.java new file mode 100644 index 00000000..d4afc349 --- /dev/null +++ b/src/main/java/games/rednblack/editor/view/ui/dialog/AnimationsPackDialogMediator.java @@ -0,0 +1,80 @@ +package games.rednblack.editor.view.ui.dialog; + +import games.rednblack.editor.HyperLap2DFacade; +import games.rednblack.editor.proxy.ProjectManager; +import games.rednblack.editor.renderer.data.TexturePackVO; +import games.rednblack.editor.view.menu.ResourcesMenu; +import games.rednblack.editor.view.stage.Sandbox; +import games.rednblack.editor.view.stage.UIStage; +import org.puremvc.java.interfaces.INotification; +import org.puremvc.java.patterns.mediator.Mediator; + +public class AnimationsPackDialogMediator extends Mediator { + private static final String TAG = AnimationsPackDialogMediator.class.getCanonicalName(); + private static final String NAME = TAG; + + private static final String NEW_IMAGES_PACK = "games.rednblack.editor.view.ui.dialog.AnimationsPackDialogMediator.NEW_IMAGES_PACK"; + private static final String MOVE_REGION_TO_PACK = "games.rednblack.editor.view.ui.dialog.AnimationsPackDialogMediator.MOVE_REGION_TO_PACK"; + private static final String UPDATE_CURRENT_LIST = "games.rednblack.editor.view.ui.dialog.AnimationsPackDialogMediator.UPDATE_CURRENT_LIST"; + + public AnimationsPackDialogMediator() { + super(NAME, new AtlasesPackDialog("Animations Atlases", NEW_IMAGES_PACK, MOVE_REGION_TO_PACK, UPDATE_CURRENT_LIST)); + } + + @Override + public void onRegister() { + super.onRegister(); + facade = HyperLap2DFacade.getInstance(); + } + + @Override + public String[] listNotificationInterests() { + return new String[]{ + ResourcesMenu.OPEN_ANIMATIONS_PACK, + ProjectManager.PROJECT_OPENED, + NEW_IMAGES_PACK, + MOVE_REGION_TO_PACK, + UPDATE_CURRENT_LIST + }; + } + + @Override + public void handleNotification(INotification notification) { + Sandbox sandbox = Sandbox.getInstance(); + UIStage uiStage = sandbox.getUIStage(); + ProjectManager projectManager = facade.retrieveProxy(ProjectManager.NAME); + + switch (notification.getName()) { + case ResourcesMenu.OPEN_ANIMATIONS_PACK: + viewComponent.show(uiStage); + break; + case ProjectManager.PROJECT_OPENED: + viewComponent.initPacks(projectManager.currentProjectInfoVO.animationsPacks.keySet()); + viewComponent.updateMainPack(projectManager.currentProjectInfoVO.animationsPacks.get("main").regions); + break; + case NEW_IMAGES_PACK: + TexturePackVO newVo = new TexturePackVO(); + newVo.name = notification.getBody(); + + projectManager.currentProjectInfoVO.animationsPacks.put(newVo.name, newVo); + + viewComponent.addNewPack(newVo.name); + break; + case UPDATE_CURRENT_LIST: + String currentTab = viewComponent.getSelectedTab(); + viewComponent.updateCurrentPack(projectManager.currentProjectInfoVO.animationsPacks.get(currentTab).regions); + break; + case MOVE_REGION_TO_PACK: + String toPack = viewComponent.getMainSelected() != null ? viewComponent.getSelectedTab() : "main"; + String fromPack = viewComponent.getMainSelected() == null ? viewComponent.getSelectedTab() : "main"; + String region = viewComponent.getMainSelected() != null ? viewComponent.getMainSelected() : viewComponent.getCurrentSelected(); + + projectManager.currentProjectInfoVO.animationsPacks.get(fromPack).regions.remove(region); + projectManager.currentProjectInfoVO.animationsPacks.get(toPack).regions.add(region); + + viewComponent.updateCurrentPack(projectManager.currentProjectInfoVO.animationsPacks.get(viewComponent.getSelectedTab()).regions); + viewComponent.updateMainPack(projectManager.currentProjectInfoVO.animationsPacks.get("main").regions); + break; + } + } +} diff --git a/src/main/java/games/rednblack/editor/view/ui/dialog/AtlasesPackDialog.java b/src/main/java/games/rednblack/editor/view/ui/dialog/AtlasesPackDialog.java new file mode 100644 index 00000000..cdcc0425 --- /dev/null +++ b/src/main/java/games/rednblack/editor/view/ui/dialog/AtlasesPackDialog.java @@ -0,0 +1,248 @@ +package games.rednblack.editor.view.ui.dialog; + +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.utils.Align; +import com.badlogic.gdx.utils.Array; +import com.kotcrab.vis.ui.util.adapter.AbstractListAdapter; +import com.kotcrab.vis.ui.util.adapter.SimpleListAdapter; +import com.kotcrab.vis.ui.widget.*; +import com.kotcrab.vis.ui.widget.tabbedpane.Tab; +import com.kotcrab.vis.ui.widget.tabbedpane.TabbedPane; +import com.kotcrab.vis.ui.widget.tabbedpane.TabbedPaneAdapter; +import games.rednblack.editor.HyperLap2DFacade; +import games.rednblack.editor.view.stage.Sandbox; +import games.rednblack.h2d.common.H2DDialog; +import games.rednblack.h2d.common.view.ui.StandardWidgetsFactory; +import games.rednblack.h2d.common.view.ui.listener.ScrollFocusListener; + +import java.util.Set; + +public class AtlasesPackDialog extends H2DDialog { + + private final TabbedPane tabbedPane; + private final String addNewNotification; + private final String moveRegionNotification, updateCurrentNotification; + private final SimpleListAdapter mainPackAdapter, currentPackAdapter; + private final VisTextButton insertButton, removeButton; + private final VisLabel currentSelectedPackLabel; + + private final HyperLap2DFacade facade = HyperLap2DFacade.getInstance(); + + private final Array mainList = new Array<>(); + private final Array currentList = new Array<>(); + + private String mainSelected = null, currentSelected = null; + + public AtlasesPackDialog(String title, String add, String move, String updateList) { + super(title); + addNewNotification = add; + moveRegionNotification = move; + updateCurrentNotification = updateList; + + addCloseButton(); + getContentTable().top().left(); + + tabbedPane = new TabbedPane(); + tabbedPane.addListener(new TabbedPaneAdapter() { + @Override + public void switchedTab(Tab tab) { + facade.sendNotification(updateCurrentNotification); + updateOpButtons(); + currentSelectedPackLabel.setText(tab.getTabTitle()); + } + }); + + VisTable addNewPackTable = new VisTable(); + VisTextField newPackName = StandardWidgetsFactory.createTextField(); + newPackName.setMessageText("Add new atlas pack"); + VisTextButton newPackButton = StandardWidgetsFactory.createTextButton("Add"); + newPackButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + if (!newPackName.getText().equals("")) + facade.sendNotification(addNewNotification, newPackName.getText()); + newPackName.setText(""); + } + }); + addNewPackTable.add(newPackName).growX(); + addNewPackTable.add(newPackButton).width(80); + + mainPackAdapter = new SimpleListAdapter<>(mainList); + mainPackAdapter.setSelectionMode(AbstractListAdapter.SelectionMode.SINGLE); + mainPackAdapter.getSelectionManager().setProgrammaticChangeEvents(false); + + currentPackAdapter = new SimpleListAdapter<>(currentList); + currentPackAdapter.setSelectionMode(AbstractListAdapter.SelectionMode.SINGLE); + currentPackAdapter.getSelectionManager().setProgrammaticChangeEvents(false); + + ListView mainPackList = new ListView<>(mainPackAdapter); + mainPackList.getScrollPane().addListener(new ScrollFocusListener()); + ListView currentPackList = new ListView<>(currentPackAdapter); + currentPackList.getScrollPane().addListener(new ScrollFocusListener()); + + mainPackList.setItemClickListener(this::selectMainItem); + currentPackList.setItemClickListener(this::selectCurrentItem); + + getContentTable().add(addNewPackTable).growX().row(); + getContentTable().add(tabbedPane.getTable()).height(30).growX().row(); + + insertButton = StandardWidgetsFactory.createTextButton("->"); + insertButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + if (!insertButton.isDisabled()) + facade.sendNotification(moveRegionNotification); + } + }); + removeButton = StandardWidgetsFactory.createTextButton("<-"); + removeButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + if (!removeButton.isDisabled()) + facade.sendNotification(moveRegionNotification); + } + }); + updateOpButtons(); + VisTable opButtonsContainer = new VisTable(); + VisTable opButtons = new VisTable(); + opButtons.add(insertButton).width(80).row(); + opButtons.add(removeButton).width(80).row(); + opButtonsContainer.addSeparator(true); + opButtonsContainer.add(opButtons); + opButtonsContainer.addSeparator(true); + + VisTable opTable = new VisTable(); + opTable.add(new VisLabel("Main Pack", Align.center)).uniformX().growX(); + opTable.add().width(80); + currentSelectedPackLabel = new VisLabel("Select Pack", Align.center); + opTable.add(currentSelectedPackLabel).uniformX().growX().row(); + opTable.addSeparator().colspan(3); + opTable.add(mainPackList.getMainTable()).uniformX().grow(); + opTable.add(opButtonsContainer).growY(); + opTable.add(currentPackList.getMainTable()).uniformX().grow().row(); + + getContentTable().add(opTable).grow().row(); + } + + private void selectCurrentItem(String item) { + mainPackAdapter.getSelectionManager().deselectAll(); + mainSelected = null; + currentSelected = item; + + updateOpButtons(); + } + + private void selectMainItem(String item) { + currentPackAdapter.getSelectionManager().deselectAll(); + currentSelected = null; + mainSelected = item; + + updateOpButtons(); + } + + public void initPacks(Set packs) { + tabbedPane.removeAll(); + + for (String name : packs) { + if (name.equals("main")) continue; + tabbedPane.add(new PackTab(name)); + } + + if (tabbedPane.getTabs().size > 0) tabbedPane.switchTab(0); + } + + public void updateCurrentPack(Set regions) { + String toSelect = null; + if (currentPackAdapter.getSelection().size > 0) { + String selected = currentPackAdapter.getSelection().get(0); + int nextIndex = currentList.indexOf(selected, false); + if (nextIndex + 1 < currentList.size) + toSelect = currentList.get(nextIndex + 1); + + } + currentList.clear(); + for (String item : regions) + currentList.addAll(item); + currentList.sort(); + if (currentPackAdapter.getSelection().size > 0) { + selectCurrentItem(currentList.contains(toSelect, false) ? toSelect : null); + } + + currentPackAdapter.itemsChanged(); + if (toSelect != null && currentList.contains(toSelect, false)) { + currentPackAdapter.getSelectionManager().select(toSelect); + } + } + + public void updateMainPack(Set regions) { + String toSelect = null; + if (mainPackAdapter.getSelection().size > 0) { + String selected = mainPackAdapter.getSelection().get(0); + int nextIndex = mainList.indexOf(selected, false); + if (nextIndex + 1 < mainList.size) + toSelect = mainList.get(nextIndex + 1); + selectMainItem(toSelect); + } + mainList.clear(); + for (String item : regions) + mainList.addAll(item); + mainList.sort(); + + mainPackAdapter.itemsChanged(); + if (toSelect != null) { + mainPackAdapter.getSelectionManager().select(toSelect); + } + } + + public void addNewPack(String name) { + tabbedPane.add(new PackTab(name)); + pack(); + } + + public String getSelectedTab() { + return tabbedPane.getActiveTab().getTabTitle(); + } + + private void updateOpButtons() { + insertButton.setDisabled(tabbedPane.getActiveTab() == null || mainSelected == null); + removeButton.setDisabled(tabbedPane.getActiveTab() == null || currentSelected == null); + } + + public String getCurrentSelected() { + return currentSelected; + } + + public String getMainSelected() { + return mainSelected; + } + + @Override + public float getPrefWidth() { + return Sandbox.getInstance().getUIStage().getWidth() * 0.5f; + } + + @Override + public float getPrefHeight() { + return Sandbox.getInstance().getUIStage().getHeight() * 0.5f; + } + + public static class PackTab extends Tab { + String name; + public PackTab (String name) { + super(false, false); + this.name = name; + } + + @Override + public String getTabTitle() { + return name; + } + + @Override + public Table getContentTable() { + return null; + } + } +} diff --git a/src/main/java/games/rednblack/editor/view/ui/dialog/ImagesPackDialogMediator.java b/src/main/java/games/rednblack/editor/view/ui/dialog/ImagesPackDialogMediator.java new file mode 100644 index 00000000..bce1ff55 --- /dev/null +++ b/src/main/java/games/rednblack/editor/view/ui/dialog/ImagesPackDialogMediator.java @@ -0,0 +1,80 @@ +package games.rednblack.editor.view.ui.dialog; + +import games.rednblack.editor.HyperLap2DFacade; +import games.rednblack.editor.proxy.ProjectManager; +import games.rednblack.editor.renderer.data.TexturePackVO; +import games.rednblack.editor.view.menu.ResourcesMenu; +import games.rednblack.editor.view.stage.Sandbox; +import games.rednblack.editor.view.stage.UIStage; +import org.puremvc.java.interfaces.INotification; +import org.puremvc.java.patterns.mediator.Mediator; + +public class ImagesPackDialogMediator extends Mediator { + private static final String TAG = ImagesPackDialogMediator.class.getCanonicalName(); + private static final String NAME = TAG; + + private static final String NEW_IMAGES_PACK = "games.rednblack.editor.view.ui.dialog.ImagesPackDialogMediator.NEW_IMAGES_PACK"; + private static final String MOVE_REGION_TO_PACK = "games.rednblack.editor.view.ui.dialog.ImagesPackDialogMediator.MOVE_REGION_TO_PACK"; + private static final String UPDATE_CURRENT_LIST = "games.rednblack.editor.view.ui.dialog.ImagesPackDialogMediator.UPDATE_CURRENT_LIST"; + + public ImagesPackDialogMediator() { + super(NAME, new AtlasesPackDialog("Images Atlases", NEW_IMAGES_PACK, MOVE_REGION_TO_PACK, UPDATE_CURRENT_LIST)); + } + + @Override + public void onRegister() { + super.onRegister(); + facade = HyperLap2DFacade.getInstance(); + } + + @Override + public String[] listNotificationInterests() { + return new String[]{ + ResourcesMenu.OPEN_IMAGES_PACK, + ProjectManager.PROJECT_OPENED, + NEW_IMAGES_PACK, + MOVE_REGION_TO_PACK, + UPDATE_CURRENT_LIST + }; + } + + @Override + public void handleNotification(INotification notification) { + Sandbox sandbox = Sandbox.getInstance(); + UIStage uiStage = sandbox.getUIStage(); + ProjectManager projectManager = facade.retrieveProxy(ProjectManager.NAME); + + switch (notification.getName()) { + case ResourcesMenu.OPEN_IMAGES_PACK: + viewComponent.show(uiStage); + break; + case ProjectManager.PROJECT_OPENED: + viewComponent.initPacks(projectManager.currentProjectInfoVO.imagesPacks.keySet()); + viewComponent.updateMainPack(projectManager.currentProjectInfoVO.imagesPacks.get("main").regions); + break; + case NEW_IMAGES_PACK: + TexturePackVO newVo = new TexturePackVO(); + newVo.name = notification.getBody(); + + projectManager.currentProjectInfoVO.imagesPacks.put(newVo.name, newVo); + + viewComponent.addNewPack(newVo.name); + break; + case UPDATE_CURRENT_LIST: + String currentTab = viewComponent.getSelectedTab(); + viewComponent.updateCurrentPack(projectManager.currentProjectInfoVO.imagesPacks.get(currentTab).regions); + break; + case MOVE_REGION_TO_PACK: + String toPack = viewComponent.getMainSelected() != null ? viewComponent.getSelectedTab() : "main"; + String fromPack = viewComponent.getMainSelected() == null ? viewComponent.getSelectedTab() : "main"; + String region = viewComponent.getMainSelected() != null ? viewComponent.getMainSelected() : viewComponent.getCurrentSelected(); + + projectManager.currentProjectInfoVO.imagesPacks.get(fromPack).regions.remove(region); + projectManager.currentProjectInfoVO.imagesPacks.get(toPack).regions.add(region); + + viewComponent.updateCurrentPack(projectManager.currentProjectInfoVO.imagesPacks.get(viewComponent.getSelectedTab()).regions); + viewComponent.updateMainPack(projectManager.currentProjectInfoVO.imagesPacks.get("main").regions); + break; + } + } +} diff --git a/src/main/java/games/rednblack/editor/view/ui/widget/actors/SpineActor.java b/src/main/java/games/rednblack/editor/view/ui/widget/actors/SpineActor.java index 6f5dcdfd..c2fad424 100644 --- a/src/main/java/games/rednblack/editor/view/ui/widget/actors/SpineActor.java +++ b/src/main/java/games/rednblack/editor/view/ui/widget/actors/SpineActor.java @@ -19,7 +19,7 @@ import com.esotericsoftware.spine.attachments.Attachment; import com.esotericsoftware.spine.attachments.MeshAttachment; import com.esotericsoftware.spine.attachments.RegionAttachment; import games.rednblack.editor.renderer.resources.IResourceRetriever; -import games.rednblack.h2d.extention.spine.PrefixAtlasAttachmentLoader; +import games.rednblack.h2d.extention.spine.ResourceRetrieverAttachmentLoader; public class SpineActor extends Actor { @@ -81,7 +81,7 @@ public class SpineActor extends Actor { } private void initSkeletonData() { - skeletonJson = new SkeletonJson(new PrefixAtlasAttachmentLoader(animationName, irr.getMainPack())); + skeletonJson = new SkeletonJson(new ResourceRetrieverAttachmentLoader(animationName, irr)); skeletonData = skeletonJson.readSkeletonData((irr.getSkeletonJSON(animationName))); }