/*******************************************************************************
* 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.text.MessageFormat;
import java.util.Arrays;
import java.util.List;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.bladecoder.engine.model.BaseActor;
import com.bladecoder.engine.model.InteractiveActor;
import com.bladecoder.engine.model.Verb;
import com.bladecoder.engine.model.VerbManager;
import com.bladecoder.engine.model.World;
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.ui.panels.ScopePanel;
import com.bladecoder.engineeditor.undo.UndoDeleteVerb;
public class VerbList extends ModelList<VerbManager, Verb> {
public static final String VERBS[] = { "lookat", "pickup", "talkto", "use", "leave", "enter", "exit", "init",
"test", "custom" };
private ActionList actionList;
private ScopePanel scopePanel;
public VerbList(Skin skin) {
super(skin, true);
clearChildren();
scopePanel = new ScopePanel(skin) {
@Override
public void scopeChanged(String scope) {
if (WORLD_SCOPE.equals(scope)) {
addElements(World.getInstance().getVerbManager(), Arrays.asList(World.getInstance()
.getVerbManager().getVerbs().values().toArray(new Verb[0])));
} else if (SCENE_SCOPE.equals(scope)) {
if (Ctx.project.getSelectedScene() != null)
addElements(
Ctx.project.getSelectedScene().getVerbManager(),
Arrays.asList(Ctx.project.getSelectedScene().getVerbManager().getVerbs().values()
.toArray(new Verb[0])));
else
addElements(null, null);
} else if (ACTOR_SCOPE.equals(scope)) {
BaseActor a = Ctx.project.getSelectedActor();
if (a instanceof InteractiveActor) {
addElements(
((InteractiveActor) a).getVerbManager(),
Arrays.asList(((InteractiveActor) a).getVerbManager().getVerbs().values()
.toArray(new Verb[0])));
} else {
addElements(null, null);
}
}
}
};
add(scopePanel).expandX().fillX();
row();
add(toolbar).expandX().fillX();
row().fill();
add(container).expandY().fill();
actionList = new ActionList(skin);
row();
add(actionList).expand().fill();
list.addListener(new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
addActions();
}
});
list.setCellRenderer(listCellRenderer);
listCellRenderer.layout(list.getStyle());
container.minHeight(listCellRenderer.getItemHeight() * 5);
container.maxHeight(listCellRenderer.getItemHeight() * 5);
Ctx.project.addPropertyChangeListener(Project.NOTIFY_ELEMENT_CREATED, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getNewValue() instanceof Verb && !(evt.getSource() instanceof EditVerbDialog)) {
if (ScopePanel.WORLD_SCOPE.equals(scopePanel.getScope())) {
addElements(
World.getInstance().getVerbManager(),
Arrays.asList(World.getInstance().getVerbManager().getVerbs().values()
.toArray(new Verb[0])));
} else if (ScopePanel.SCENE_SCOPE.equals(scopePanel.getScope())) {
addElements(
Ctx.project.getSelectedScene().getVerbManager(),
Arrays.asList(Ctx.project.getSelectedScene().getVerbManager().getVerbs().values()
.toArray(new Verb[0])));
} else if (ScopePanel.ACTOR_SCOPE.equals(scopePanel.getScope())) {
BaseActor a = Ctx.project.getSelectedActor();
if (a instanceof InteractiveActor) {
addElements(
((InteractiveActor) a).getVerbManager(),
Arrays.asList(((InteractiveActor) a).getVerbManager().getVerbs().values()
.toArray(new Verb[0])));
} else {
addElements(null, null);
}
}
}
}
});
}
public void changeActor() {
scopePanel.scopeChanged(scopePanel.getScope());
}
@Override
protected EditModelDialog<VerbManager, Verb> getEditElementDialogInstance(Verb e) {
return new EditVerbDialog(skin, scopePanel.getScope(), parent, e);
}
@Override
public void addElements(VerbManager vm, List<Verb> elements) {
super.addElements(vm, elements);
addActions();
}
@Override
protected void delete() {
Verb v = removeSelected();
parent.getVerbs().remove(v.getHashKey());
// TRANSLATIONS
if (scopePanel.getScope().equals(ScopePanel.WORLD_SCOPE))
Ctx.project.getI18N().putTranslationsInElement(v, true);
else
Ctx.project.getI18N().putTranslationsInElement(v, false);
// UNDO
Ctx.project.getUndoStack().add(new UndoDeleteVerb(parent, v));
// Clear actions here because change event doesn't call when deleting
// the last element
if (list.getSelectedIndex() == -1)
addActions();
Ctx.project.setModified();
}
@Override
protected void copy() {
Verb e = list.getSelected();
if (e == null)
return;
clipboard = (Verb) ElementUtils.cloneElement(e);
toolbar.disablePaste(false);
// TRANSLATIONS
if (scopePanel.getScope().equals(ScopePanel.WORLD_SCOPE))
Ctx.project.getI18N().putTranslationsInElement(clipboard, true);
else
Ctx.project.getI18N().putTranslationsInElement(clipboard, false);
}
@Override
protected void paste() {
Verb newElement = (Verb) ElementUtils.cloneElement(clipboard);
// Check for id duplicates
String[] keys = new String[parent.getVerbs().size()];
Verb[] values = parent.getVerbs().values().toArray(new Verb[0]);
for (int i = 0; i < keys.length; i++) {
keys[i] = values[i].getId();
}
newElement.setId(ElementUtils.getCheckedId(newElement.getId(), keys));
int pos = list.getSelectedIndex() + 1;
list.getItems().insert(pos, newElement);
parent.addVerb(newElement);
if (scopePanel.getScope().equals(ScopePanel.WORLD_SCOPE))
Ctx.project.getI18N().extractStrings(null, null, newElement);
else if (scopePanel.getScope().equals(ScopePanel.SCENE_SCOPE))
Ctx.project.getI18N().extractStrings(Ctx.project.getSelectedScene().getId(), null, newElement);
else
Ctx.project.getI18N().extractStrings(Ctx.project.getSelectedScene().getId(),
Ctx.project.getSelectedActor().getId(), newElement);
list.setSelectedIndex(pos);
list.invalidateHierarchy();
Ctx.project.setModified();
}
private void addActions() {
int pos = list.getSelectedIndex();
Verb v = null;
if (pos != -1) {
v = list.getItems().get(pos);
actionList.setScope(scopePanel.getScope());
actionList.addElements(v, v.getActions());
} else {
actionList.addElements(null, null);
actionList.setScope(null);
}
}
// -------------------------------------------------------------------------
// ListCellRenderer
// -------------------------------------------------------------------------
private final CellRenderer<Verb> listCellRenderer = new CellRenderer<Verb>() {
@Override
protected String getCellTitle(Verb e) {
return e.getId();
}
@Override
protected String getCellSubTitle(Verb e) {
String state = e.getState();
String target = e.getTarget();
StringBuilder sb = new StringBuilder(e.getId());
if (state != null)
sb.append(" when ").append(state);
if (target != null)
sb.append(" with target '").append(target).append("'");
return sb.toString();
}
@Override
public TextureRegion getCellImage(Verb e) {
boolean custom = true;
String verbName = e.getId();
for (String v : VERBS) {
if (v.equals(verbName)) {
custom = false;
break;
}
}
String iconName = MessageFormat.format("ic_{0}", e.getId());
TextureRegion image = null;
if (!custom)
image = Ctx.assetManager.getIcon(iconName);
else
image = Ctx.assetManager.getIcon("ic_custom");
return image;
}
@Override
protected boolean hasSubtitle() {
return true;
}
@Override
protected boolean hasImage() {
return true;
}
};
}