/*******************************************************************************
* 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.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Arrays;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.ui.ImageButton;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.bladecoder.engine.assets.EngineAssetManager;
import com.bladecoder.engine.model.ActorRenderer;
import com.bladecoder.engine.model.AnchorActor;
import com.bladecoder.engine.model.AtlasRenderer;
import com.bladecoder.engine.model.BaseActor;
import com.bladecoder.engine.model.CharacterActor;
import com.bladecoder.engine.model.ImageRenderer;
import com.bladecoder.engine.model.InteractiveActor;
import com.bladecoder.engine.model.ObstacleActor;
import com.bladecoder.engine.model.ParticleRenderer;
import com.bladecoder.engine.model.Scene;
import com.bladecoder.engine.model.Sprite3DRenderer;
import com.bladecoder.engine.model.SpriteActor;
import com.bladecoder.engine.model.TextRenderer;
import com.bladecoder.engine.spine.SpineRenderer;
import com.bladecoder.engineeditor.Ctx;
import com.bladecoder.engineeditor.common.ElementUtils;
import com.bladecoder.engineeditor.model.Project;
import com.bladecoder.engineeditor.ui.panels.CellRenderer;
import com.bladecoder.engineeditor.ui.panels.EditModelDialog;
import com.bladecoder.engineeditor.ui.panels.ModelList;
import com.bladecoder.engineeditor.undo.UndoDeleteActor;
public class ActorList extends ModelList<Scene, BaseActor> {
private ImageButton playerBtn;
public ActorList(Skin skin) {
super(skin, true);
playerBtn = new ImageButton(skin);
toolbar.addToolBarButton(playerBtn, "ic_player_small", "Set player", "Set player");
playerBtn.setDisabled(true);
list.addListener(new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
// EditorLogger.debug("ACTOR LIST ELEMENT SELECTED");
int pos = list.getSelectedIndex();
if (pos == -1) {
Ctx.project.setSelectedActor((BaseActor) null);
} else {
BaseActor a = list.getItems().get(pos);
Ctx.project.setSelectedActor(a);
}
toolbar.disableEdit(pos == -1);
playerBtn.setDisabled(pos == -1);
}
});
playerBtn.addListener(new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
setPlayer();
}
});
list.setCellRenderer(listCellRenderer);
Ctx.project.addPropertyChangeListener(Project.NOTIFY_ACTOR_SELECTED, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent e) {
int pos = list.getSelectedIndex();
// Element newActor = (Element) e.getNewValue();
BaseActor newActor = Ctx.project.getSelectedActor();
if (newActor == null)
return;
if (pos != -1) {
BaseActor oldActor = list.getItems().get(pos);
if (oldActor == newActor) {
return;
}
}
int i = list.getItems().indexOf(newActor, true);
if (i >= 0) {
list.setSelectedIndex(i);
container.getActor().setScrollPercentY(i/(float)list.getItems().size);
}
}
});
Ctx.project.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(Project.NOTIFY_ELEMENT_DELETED)) {
if (evt.getNewValue() instanceof BaseActor) {
addElements(Ctx.project.getSelectedScene(),
Arrays.asList(Ctx.project.getSelectedScene().getActors().values().toArray(new BaseActor[0])));
}
} else if (evt.getPropertyName().equals(Project.NOTIFY_ELEMENT_CREATED)) {
if (evt.getNewValue() instanceof BaseActor && !(evt.getSource() instanceof EditActorDialog)) {
addElements(Ctx.project.getSelectedScene(),
Arrays.asList(Ctx.project.getSelectedScene().getActors().values().toArray(new BaseActor[0])));
}
}
}
});
}
@Override
protected void delete() {
BaseActor a = removeSelected();
parent.removeActor(a);
// delete player attr if the actor to delete is the player
if (parent.getPlayer() == a) {
parent.setPlayer(null);
}
// TRANSLATIONS
Ctx.project.getI18N().putTranslationsInElement(a);
// UNDO
Ctx.project.getUndoStack().add(new UndoDeleteActor(parent, a));
Ctx.project.setModified();
}
@Override
protected EditModelDialog<Scene, BaseActor> getEditElementDialogInstance(BaseActor a) {
return new EditActorDialog(skin, parent, a);
}
@Override
protected void edit() {
BaseActor e = list.getSelected();
if (e == null)
return;
EditModelDialog<Scene, BaseActor> dialog = getEditElementDialogInstance(e);
dialog.show(getStage());
dialog.setListener(new ChangeListener() {
@SuppressWarnings("unchecked")
@Override
public void changed(ChangeEvent event, Actor actor) {
BaseActor e = ((EditModelDialog<Scene, BaseActor>) actor).getElement();
// When the type is changed, a new element is created and it is needed to replace the previous element.
if(e != list.getSelected()) {
int i = list.getSelectedIndex();
getItems().set(i, e);
list.setSelectedIndex(i);
list.invalidateHierarchy();
}
}
});
}
private void setPlayer() {
int pos = list.getSelectedIndex();
if (pos == -1)
return;
BaseActor a = list.getItems().get(pos);
if (a instanceof CharacterActor) {
Ctx.project.getSelectedScene().setPlayer((CharacterActor) a);
Ctx.project.setModified();
}
}
@Override
protected void copy() {
BaseActor e = list.getSelected();
if (e == null)
return;
clipboard = (BaseActor) ElementUtils.cloneElement(e);
toolbar.disablePaste(false);
// TRANSLATIONS
Ctx.project.getI18N().putTranslationsInElement(clipboard);
}
@Override
protected void paste() {
BaseActor newElement = (BaseActor) ElementUtils.cloneElement(clipboard);
newElement.setId(
ElementUtils.getCheckedId(newElement.getId(), parent.getActors().keySet().toArray(new String[0])));
int pos = list.getSelectedIndex() + 1;
list.getItems().insert(pos, newElement);
parent.addActor(newElement);
Ctx.project.getI18N().extractStrings(parent.getId(), newElement);
if(newElement instanceof InteractiveActor) {
InteractiveActor ia = (InteractiveActor) newElement;
ia.loadAssets();
EngineAssetManager.getInstance().finishLoading();
ia.retrieveAssets();
}
list.setSelectedIndex(pos);
list.invalidateHierarchy();
Ctx.project.setModified();
}
// -------------------------------------------------------------------------
// ListCellRenderer
// -------------------------------------------------------------------------
private final CellRenderer<BaseActor> listCellRenderer = new CellRenderer<BaseActor>() {
@Override
protected String getCellTitle(BaseActor e) {
return e.getId();
}
@Override
protected String getCellSubTitle(BaseActor e) {
if (e instanceof InteractiveActor)
return Ctx.project.translate(((InteractiveActor) e).getDesc());
return "";
}
@Override
public TextureRegion getCellImage(BaseActor a) {
boolean isPlayer = (a.getScene().getPlayer() == a);
String u = null;
if (isPlayer) {
u = "ic_player";
} else if (a instanceof CharacterActor) {
u = "ic_character_actor";
} else if (a instanceof SpriteActor) {
ActorRenderer r = ((SpriteActor) a).getRenderer();
if (r instanceof ImageRenderer) {
u = "ic_sprite_actor";
} else if (r instanceof AtlasRenderer) {
u = "ic_sprite_actor";
} else if (r instanceof SpineRenderer) {
u = "ic_spine";
} else if (r instanceof ParticleRenderer) {
u = "ic_particles";
} else if (r instanceof TextRenderer) {
u = "ic_text";
} else if (r instanceof Sprite3DRenderer) {
u = "ic_3d";
}
} else if (a instanceof InteractiveActor) {
u = "ic_base_actor";
} else if (a instanceof ObstacleActor) {
u = "ic_obstacle_actor";
} else if (a instanceof AnchorActor) {
u = "ic_anchor";
}
return Ctx.assetManager.getIcon(u);
}
@Override
protected boolean hasSubtitle() {
return true;
}
@Override
protected boolean hasImage() {
return true;
}
};
}