Generic tag editor: Add+Remove item from List/Array, match countField

This commit is contained in:
Jindra Petk
2014-02-16 20:04:29 +01:00
parent 30f2b9dfa3
commit a1dcd67dc6
13 changed files with 418 additions and 71 deletions

View File

@@ -37,22 +37,33 @@ import com.jpexs.decompiler.flash.types.annotations.parser.ConditionEvaluator;
import com.jpexs.decompiler.flash.types.annotations.parser.ParseException;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.SpringLayout;
import javax.swing.SwingUtilities;
/**
*
@@ -72,6 +83,9 @@ public class GenericTagPanel extends JPanel implements ChangeListener {
private Map<String, List<Field>> fieldPaths = new HashMap<>();
private Map<String, List<Integer>> fieldIndices = new HashMap<>();
private HeaderLabel hdr;
private Set<String> addKeys = new HashSet<>();
private Map<String, Component> addButtons = new HashMap<>();
private Map<String, Component> removeButtons = new HashMap<>();
public GenericTagPanel() {
super(new BorderLayout());
@@ -101,6 +115,9 @@ public class GenericTagPanel extends JPanel implements ChangeListener {
labels.clear();
types.clear();
keys.clear();
addKeys.clear();
addButtons.clear();
removeButtons.clear();
genericTagPropertiesEditPanel.removeAll();
genericTagPropertiesEditPanel.setSize(0, 0);
}
@@ -125,21 +142,21 @@ public class GenericTagPanel extends JPanel implements ChangeListener {
for (String key : keys) {
GenericTagEditor ed = editors.get(key);
if (((Component) ed).isVisible()) {
val += key + " : " + ed.getReadOnlyValue()+ "<br>";
val += key + " : " + ed.getReadOnlyValue() + "<br>";
}
}
//HTML for colors:
val = "<html>"+val+"</html>";
val = "<html>" + val + "</html>";
genericTagPropertiesEditorPane.setContentType("text/html");
genericTagPropertiesEditorPane.setText(val);
genericTagPropertiesEditorPane.setCaretPosition(0);
hdr.setText(tag.toString());
hdr.setText(tag.toString());
}
public void generateEditControls(Tag tag, boolean readonly) {
clear();
this.tag = tag;
generateEditControlsRecursive(tag, "", new ArrayList<Field>(),new ArrayList<Integer>(), readonly);
generateEditControlsRecursive(tag, "", new ArrayList<Field>(), new ArrayList<Integer>(), readonly);
change(null);
}
@@ -152,37 +169,81 @@ public class GenericTagPanel extends JPanel implements ChangeListener {
repaint();
}
private int generateEditControlsRecursive(Object obj, String parent, List<Field> parentFields, List<Integer> parentIndices, boolean readonly) {
private int generateEditControlsRecursive(final Object obj, String parent, List<Field> parentFields, List<Integer> parentIndices, boolean readonly) {
if (obj == null) {
return 0;
}
Field[] fields = obj.getClass().getDeclaredFields();
int propCount = 0;
for (Field field : fields) {
for (final Field field : fields) {
try {
if (Modifier.isStatic(field.getModifiers())) {
continue;
}
field.setAccessible(true);
String name = parent + field.getName();
Object value = field.get(obj);
final Object value = field.get(obj);
if (List.class.isAssignableFrom(field.getType())) {
if (value != null) {
int i = 0;
for (Object obj1 : (Iterable) value) {
propCount += addEditor(name + "[" + i + "]", obj, field, i, obj1.getClass(), obj1, parentFields,parentIndices, readonly);
final String subname = name + "[" + i + "]";
propCount += addEditor(subname, obj, field, i, obj1.getClass(), obj1, parentFields, parentIndices, readonly);
final int fi = i;
i++;
JButton removeButton = new JButton(View.getIcon("close16"));
removeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
removeItem(obj, field, fi);
}
});
removeButtons.put(subname, removeButton);
}
}
} else if (field.getType().isArray()) {
if (value != null) {
for (int i = 0; i < Array.getLength(value); i++) {
Object item = Array.get(value, i);
propCount += addEditor(name + "[" + i + "]", obj, field, i, item.getClass(), item, parentFields,parentIndices, readonly);
String subname = name + "[" + i + "]";
propCount += addEditor(subname, obj, field, i, item.getClass(), item, parentFields, parentIndices, readonly);
final int fi = i;
JButton removeButton = new JButton(View.getIcon("close16"));
removeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
removeItem(obj, field, fi);
}
});
removeButtons.put(subname, removeButton);
}
}
} else {
propCount += addEditor(name, obj, field, 0, field.getType(), value, parentFields,parentIndices, readonly);
propCount += addEditor(name, obj, field, 0, field.getType(), value, parentFields, parentIndices, readonly);
}
if (ReflectionTools.needsIndex(field) && !readonly) {
JButton addButton = new JButton(View.getIcon("add16"));
addButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
addItem(obj, field);
}
});
name += "[]";
List<Field> parList = new ArrayList<>(parentFields);
parList.add(field);
fieldPaths.put(name, parList);
List<Integer> parIndices = new ArrayList<>(parentIndices);
parIndices.add(0);
fieldIndices.put(name, parIndices);
addRow(name, addButton, field);
addKeys.add(name);
addButtons.put(name, addButton);
}
} catch (IllegalArgumentException | IllegalAccessException ex) {
Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex);
@@ -191,14 +252,114 @@ public class GenericTagPanel extends JPanel implements ChangeListener {
return propCount;
}
private int addEditor(String name, Object obj, Field field, int index, Class<?> type, Object value, List<Field> parentList,List<Integer> parentIndices, boolean readonly) throws IllegalArgumentException, IllegalAccessException {
private void removeItem(Object obj, Field field, int index) {
final JScrollBar sb = genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar();
final int val = sb.getValue(); //save scroll top
SWFType swfType = field.getAnnotation(SWFType.class);
if (swfType != null && !swfType.countField().equals("")) { //Fields with same countField must be removed from too
Field fields[] = obj.getClass().getDeclaredFields();
for (int f = 0; f < fields.length; f++) {
SWFType fieldSwfType = fields[f].getAnnotation(SWFType.class);
if (fieldSwfType != null && fieldSwfType.countField().equals(swfType.countField())) {
ReflectionTools.removeFromField(obj, fields[f], index);
}
}
try {
//If countField exists, decrement, otherwise do nothing
Field countField = obj.getClass().getDeclaredField(swfType.countField());
if(countField!=null){
int cnt = countField.getInt(obj);
cnt--;
countField.setInt(obj, cnt);
}
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
//ignored
}
} else {
ReflectionTools.removeFromField(obj, field, index);
}
generateEditControls(tag, false);
//Restore scroll top after some time. TODO: Handle this better. I don't know how :-(.
new Thread() {
@Override
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex);
}
View.execInEventDispatch(new Runnable() {
@Override
public void run() {
genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar().setValue(val);
}
});
}
}.start();
}
private void addItem(Object obj, Field field) {
final JScrollBar sb = genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar();
final int val = sb.getValue(); //save scroll top
SWFType swfType = field.getAnnotation(SWFType.class);
if (swfType != null && !swfType.countField().equals("")) { //Fields with same countField must be enlarged too
Field fields[] = obj.getClass().getDeclaredFields();
for (int f = 0; f < fields.length; f++) {
SWFType fieldSwfType = fields[f].getAnnotation(SWFType.class);
if (fieldSwfType != null && fieldSwfType.countField().equals(swfType.countField())) {
ReflectionTools.enlargeField(obj, fields[f], true);
}
}
try {
//If countField exists, increment, otherwise do nothing
Field countField = obj.getClass().getDeclaredField(swfType.countField());
if(countField!=null){
int cnt = countField.getInt(obj);
cnt++;
countField.setInt(obj, cnt);
}
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
//ignored
}
} else {
ReflectionTools.enlargeField(obj, field, true);
}
generateEditControls(tag, false);
//Restore scroll top after some time. TODO: Handle this better. I don't know how :-(.
new Thread() {
@Override
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex);
}
View.execInEventDispatch(new Runnable() {
@Override
public void run() {
genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar().setValue(val);
}
});
}
}.start();
}
private int addEditor(String name, Object obj, Field field, int index, Class<?> type, Object value, List<Field> parentList, List<Integer> parentIndices, boolean readonly) throws IllegalArgumentException, IllegalAccessException {
Calculated calculated = field.getAnnotation(Calculated.class);
if (calculated != null) {
return 0;
}
List<Field> parList = new ArrayList<>(parentList);
parList.add(field);
List<Integer> parIndices = new ArrayList<>(parentIndices);
parIndices.add(index);
Internal inter = field.getAnnotation(Internal.class);
@@ -217,9 +378,9 @@ public class GenericTagPanel extends JPanel implements ChangeListener {
editor = new BooleanEditor(name, obj, field, index, type);
} else if (type.equals(String.class)) {
editor = new StringEditor(name, obj, field, index, type);
} else if (type.equals(RGB.class) || type.equals(RGBA.class) || type.equals(ARGB.class)){
} else if (type.equals(RGB.class) || type.equals(RGBA.class) || type.equals(ARGB.class)) {
editor = new ColorEditor(name, obj, field, index, type);
}else {
} else {
if (value == null) {
if (readonly) {
return 0;
@@ -227,7 +388,7 @@ public class GenericTagPanel extends JPanel implements ChangeListener {
Optional opt = field.getAnnotation(Optional.class);
if (opt == null) {
try {
value = field.getType().newInstance();
value = ReflectionTools.newInstanceOf(field.getType());
field.set(obj, value);
} catch (InstantiationException | IllegalAccessException ex) {
Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex);
@@ -237,28 +398,31 @@ public class GenericTagPanel extends JPanel implements ChangeListener {
return 0;
}
}
return generateEditControlsRecursive(value, name + ".", parList,parIndices, readonly);
return generateEditControlsRecursive(value, name + ".", parList, parIndices, readonly);
}
if (editor instanceof GenericTagEditor) {
GenericTagEditor ce = (GenericTagEditor) editor;
ce.addChangeListener(this);
editors.put(name, ce);
fieldPaths.put(name, parList);
fieldIndices.put(name,parIndices);
fieldIndices.put(name, parIndices);
addRow(name, editor, field);
}
return 1;
}
private void addRow(String name, Component editor, Field field) {
JLabel label = new JLabel(name + ":", JLabel.TRAILING);
label.setVerticalAlignment(JLabel.TOP);
genericTagPropertiesEditPanel.add(label);
label.setLabelFor(editor);
labels.put(name, label);
genericTagPropertiesEditPanel.add(editor);
JLabel typeLabel = new JLabel(swfTypeToString(swfType), JLabel.TRAILING);
JLabel typeLabel = new JLabel(swfTypeToString(field.getAnnotation(SWFType.class)), JLabel.TRAILING);
typeLabel.setVerticalAlignment(JLabel.TOP);
genericTagPropertiesEditPanel.add(typeLabel);
types.put(name, typeLabel);
keys.add(name);
return 1;
}
public String swfTypeToString(SWFType swfType) {
@@ -305,17 +469,17 @@ public class GenericTagPanel extends JPanel implements ChangeListener {
List<Field> path = fieldPaths.get(key);
List<Integer> indices = fieldIndices.get(key);
String p = "";
boolean conditionMet = true;
for (int i=0;i<path.size();i++) {
boolean conditionMet = true;
for (int i = 0; i < path.size(); i++) {
Field f = path.get(i);
int index=indices.get(i);
int index = indices.get(i);
String par = p;
if (!p.equals("")) {
p += ".";
}
p += f.getName();
if(ReflectionTools.needsIndex(f)){
p+="["+index+"]";
if (ReflectionTools.needsIndex(f)) {
p += "[" + index + "]";
}
Conditional cond = f.getAnnotation(Conditional.class);
if (cond != null) {
@@ -359,7 +523,18 @@ public class GenericTagPanel extends JPanel implements ChangeListener {
genericTagPropertiesEditPanel.setSize(0, 0);
int propCount = 0;
for (String key : keys) {
Component dependentEditor = (Component) editors.get(key);
Component dependentEditor = null;
if (addKeys.contains(key)) {
dependentEditor = addButtons.get(key);
} else if (removeButtons.containsKey(key)) { //It's array/list, add remove button
JPanel editRemPanel = new JPanel(new FlowLayout());
editRemPanel.add((Component) editors.get(key));
editRemPanel.add(removeButtons.get(key));
dependentEditor = editRemPanel;
} else {
dependentEditor = (Component) editors.get(key);
}
Component dependentLabel = labels.get(key);
Component dependentTypeLabel = types.get(key);
if (dependentEditor.isVisible()) {
@@ -368,10 +543,10 @@ public class GenericTagPanel extends JPanel implements ChangeListener {
genericTagPropertiesEditPanel.add(dependentTypeLabel);
propCount++;
}
}
}
genericTagPropertiesEditPanel.add(new JPanel());
genericTagPropertiesEditPanel.add(new JPanel());
genericTagPropertiesEditPanel.add(new JPanel());
relayout(propCount+1);
relayout(propCount + 1);
}
}

View File

@@ -18,7 +18,10 @@ package com.jpexs.decompiler.flash.gui.generictageditors;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
@@ -31,35 +34,171 @@ public class ReflectionTools {
if (List.class.isAssignableFrom(field.getType())) {
return ((List) value).get(index);
}
if (field.getType().isArray()) {
return Array.get(value, index);
}
return value;
}
public static boolean needsIndex(Field field){
public static boolean needsIndex(Field field) {
if (List.class.isAssignableFrom(field.getType())) {
return true;
}
else if (field.getType().isArray()) {
} else if (field.getType().isArray()) {
return true;
}
return false;
}
@SuppressWarnings("unchecked")
public static void setValue(Object obj, Field field, int index, Object newValue) throws IllegalArgumentException, IllegalAccessException {
Object value = field.get(obj);
if (List.class.isAssignableFrom(field.getType())) {
((List) value).set(index, newValue);
}
else if (field.getType().isArray()) {
} else if (field.getType().isArray()) {
Array.set(value, index, newValue);
}
else {
} else {
field.set(obj, newValue);
}
}
public static Object newInstanceOf(Class cls) throws InstantiationException, IllegalAccessException {
if (cls == Integer.class || cls == int.class) {
return new Integer(0);
} else if (cls == Float.class || cls == float.class) {
return new Float(0.0f);
} else if (cls == Double.class || cls == double.class ) {
return new Double(0);
} else if(cls == Long.class || cls == long.class){
return new Long(0L);
}
return cls.newInstance();
}
@SuppressWarnings("unchecked")
public static boolean enlargeList(Object object, Field field) {
if (!List.class.isAssignableFrom(field.getType())) {
return false;
}
List list;
try {
list = (List) field.get(object);
} catch (IllegalArgumentException | IllegalAccessException ex) {
Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex);
return false;
}
ParameterizedType listType = (ParameterizedType) field.getGenericType();
Class<?> parameterClass = (Class<?>) listType.getActualTypeArguments()[0];
try {
Object val = newInstanceOf(parameterClass);
list.add(val);
} catch (InstantiationException | IllegalAccessException ex) {
Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex);
return false;
}
return true;
}
public static boolean enlargeArray(Object object, Field field, boolean notnull) {
if (!field.getType().isArray()) {
return false;
}
Object arrValue;
try {
arrValue = field.get(object);
} catch (IllegalArgumentException | IllegalAccessException ex) {
Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex);
return false;
}
Class componentClass = arrValue.getClass().getComponentType();
int originalSize = Array.getLength(arrValue);
Object copy = Array.newInstance(componentClass, originalSize + 1);
for (int i = 0; i < originalSize; i++) {
Array.set(copy, i, Array.get(arrValue, i));
}
if (!componentClass.isPrimitive() && notnull) {
try {
Array.set(copy, originalSize, componentClass.newInstance());
} catch (InstantiationException | IllegalAccessException ex) {
Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex);
return false;
}
}
try {
field.set(object, copy);
} catch (IllegalArgumentException | IllegalAccessException ex) {
Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex);
return false;
}
return true;
}
public static boolean enlargeField(Object object, Field field, boolean notnull) {
if (List.class.isAssignableFrom(field.getType())) {
return enlargeList(object, field);
}
if (field.getType().isArray()) {
return enlargeArray(object, field, notnull);
}
return false;
}
public static boolean removeFromField(Object object, Field field,int index){
if (List.class.isAssignableFrom(field.getType())) {
return removeFromList(object, field,index);
}
if (field.getType().isArray()) {
return removeFromArray(object, field, index);
}
return false;
}
public static boolean removeFromList(Object object, Field field,int index){
List list;
try {
list=(List)field.get(object);
} catch (IllegalArgumentException | IllegalAccessException ex) {
Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex);
return false;
}
if(index<0 || index>=list.size()){
return false;
}
list.remove(index);
return true;
}
public static boolean removeFromArray(Object object, Field field, int index){
Object arrValue;
try {
arrValue = field.get(object);
} catch (IllegalArgumentException | IllegalAccessException ex) {
Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex);
return false;
}
Class componentClass = arrValue.getClass().getComponentType();
int originalSize = Array.getLength(arrValue);
Object copy = Array.newInstance(componentClass, originalSize - 1);
int pos=0;
//copy all before index
for (int i = 0; i < index; i++) {
Array.set(copy, pos, Array.get(arrValue, i));
pos++;
}
//copy all after index
for (int i = index+1; i <originalSize ; i++) {
Array.set(copy, pos, Array.get(arrValue, i));
pos++;
}
try {
field.set(object, copy);
} catch (IllegalArgumentException | IllegalAccessException ex) {
Logger.getLogger(ReflectionTools.class.getName()).log(Level.SEVERE, null, ex);
return false;
}
return true;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

View File

@@ -33,14 +33,15 @@ import java.io.OutputStream;
*/
public class DefineSceneAndFrameLabelDataTag extends Tag {
@SWFType(BasicType.EncodedU32)
@SWFType(value=BasicType.EncodedU32,countField="sceneCount")
public long[] sceneOffsets;
@SWFType(countField="sceneCount")
public String[] sceneNames;
@SWFType(BasicType.EncodedU32)
@SWFType(value=BasicType.EncodedU32,countField="frameLabelCount")
public long[] frameNums;
@SWFType(countField = "frameLabelCount")
public String[] frameNames;
public static final int ID = 86;

View File

@@ -38,15 +38,16 @@ public class ExportAssetsTag extends Tag {
/**
* HashMap with assets
*/
@SWFType(BasicType.UI16)
@SWFType(value = BasicType.UI16,countField = "count")
public List<Integer> tags;
@SWFType(countField = "count")
public List<String> names;
public static final int ID = 56;
public ExportAssetsTag() {
super(null, ID, "ExportAssets", new byte[]{}, 0);
tags = new ArrayList<>();
names = new ArrayList<>();
names = new ArrayList<>();
}
/**

View File

@@ -27,7 +27,10 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Imports characters from another file, v2
@@ -46,7 +49,10 @@ public class ImportAssets2Tag extends Tag implements ImportTag {
/**
* HashMap with assets
*/
public HashMap<Integer, String> assets;
@SWFType(value=BasicType.UI16,countField = "count")
public List<Integer> characterIds;
@SWFType(countField = "count")
public List<String> names;
public static final int ID = 71;
/**
@@ -60,16 +66,18 @@ public class ImportAssets2Tag extends Tag implements ImportTag {
*/
public ImportAssets2Tag(SWF swf, byte[] data, int version, long pos) throws IOException {
super(swf, ID, "ImportAssets2", data, pos);
assets = new HashMap<>();
characterIds = new ArrayList<>();
names = new ArrayList<>();
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
url = sis.readString();
reserved1 = sis.readUI8();//reserved, must be 1
reserved2 = sis.readUI8();//reserved, must be 0
int count = sis.readUI16();
for (int i = 0; i < count; i++) {
int characterId = sis.readUI16();
String name = sis.readString();
assets.put(characterId, name);
int charId = sis.readUI16();
String tagName = sis.readString();
characterIds.add(charId);
names.add(tagName);
}
}
@@ -88,10 +96,10 @@ public class ImportAssets2Tag extends Tag implements ImportTag {
sos.writeString(url);
sos.writeUI8(reserved1);
sos.writeUI8(reserved2);
sos.writeUI16(assets.size());
for (int characterId : assets.keySet()) {
sos.writeUI16(characterId);
sos.writeString(assets.get(characterId));
sos.writeUI16(characterIds.size());
for (int i=0;i<characterIds.size();i++) {
sos.writeUI16(characterIds.get(i));
sos.writeString(names.get(i));
}
} catch (IOException e) {
}
@@ -99,7 +107,11 @@ public class ImportAssets2Tag extends Tag implements ImportTag {
}
@Override
public HashMap<Integer, String> getAssets() {
public Map<Integer, String> getAssets() {
Map<Integer, String> assets = new HashMap<>();
for (int i = 0; i < characterIds.size(); i++) {
assets.put(characterIds.get(i), names.get(i));
}
return assets;
}

View File

@@ -20,11 +20,16 @@ import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.tags.base.ImportTag;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Imports characters from another file
@@ -37,7 +42,10 @@ public class ImportAssetsTag extends Tag implements ImportTag {
/**
* HashMap with assets
*/
public HashMap<Integer, String> assets;
@SWFType(value=BasicType.UI16,countField = "count")
public List<Integer> characterIds;
@SWFType(countField = "count")
public List<String> names;
public static final int ID = 57;
/**
@@ -51,14 +59,16 @@ public class ImportAssetsTag extends Tag implements ImportTag {
*/
public ImportAssetsTag(SWF swf, byte[] data, int version, long pos) throws IOException {
super(swf, ID, "ImportAssets", data, pos);
assets = new HashMap<>();
characterIds = new ArrayList<>();
names = new ArrayList<>();
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
url = sis.readString();
int count = sis.readUI16();
for (int i = 0; i < count; i++) {
int characterId = sis.readUI16();
String name = sis.readString();
assets.put(characterId, name);
int charId = sis.readUI16();
String tagName = sis.readString();
characterIds.add(charId);
names.add(tagName);
}
}
@@ -75,10 +85,10 @@ public class ImportAssetsTag extends Tag implements ImportTag {
SWFOutputStream sos = new SWFOutputStream(os, version);
try {
sos.writeString(url);
sos.writeUI16(assets.size());
for (int characterId : assets.keySet()) {
sos.writeUI16(characterId);
sos.writeString(assets.get(characterId));
sos.writeUI16(characterIds.size());
for (int i = 0; i < characterIds.size(); i++) {
sos.writeUI16(characterIds.get(i));
sos.writeString(names.get(i));
}
} catch (IOException e) {
}
@@ -86,7 +96,11 @@ public class ImportAssetsTag extends Tag implements ImportTag {
}
@Override
public HashMap<Integer, String> getAssets() {
public Map<Integer, String> getAssets() {
Map<Integer, String> assets = new HashMap<>();
for (int i = 0; i < characterIds.size(); i++) {
assets.put(characterIds.get(i), names.get(i));
}
return assets;
}

View File

@@ -28,8 +28,9 @@ import java.io.OutputStream;
public class SymbolClassTag extends Tag {
@SWFType(BasicType.UI16)
@SWFType(value=BasicType.UI16,countField = "numSymbols")
public int[] tagIDs;
@SWFType(countField = "numSymbols")
public String[] classNames;
public static final int ID = 76;

View File

@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash.tags.base;
import java.util.HashMap;
import java.util.Map;
/**
*
@@ -25,6 +26,6 @@ import java.util.HashMap;
public interface ImportTag {
public String getUrl();
public HashMap<Integer, String> getAssets();
public Map<Integer, String> getAssets();
}

View File

@@ -36,5 +36,6 @@ public enum BasicType {
FLOAT16,
FIXED,
FIXED8,
NONE
NONE,
OTHER
}

View File

@@ -32,7 +32,7 @@ import java.lang.annotation.Target;
public @interface SWFType {
/// Type of value
BasicType value();
BasicType value() default BasicType.OTHER;
/// Alternate type when condition is met
BasicType alternateValue() default BasicType.NONE;

View File

@@ -34,11 +34,12 @@ public class GRADIENTBEVELFILTER extends FILTER {
/**
* Gradient colors
*/
@SWFType(countField = "numColors")
public RGBA[] gradientColors = new RGBA[0];
/**
* Gradient ratios
*/
@SWFType(BasicType.UI8)
@SWFType(value=BasicType.UI8,countField = "numColors")
public int[] gradientRatio = new int[0];
/**
* Horizontal blur amount

View File

@@ -34,11 +34,12 @@ public class GRADIENTGLOWFILTER extends FILTER {
/**
* Gradient colors
*/
@SWFType(countField = "numColors")
public RGBA[] gradientColors = new RGBA[0];
/**
* Gradient ratios
*/
@SWFType(BasicType.UI8)
@SWFType(value=BasicType.UI8,countField = "numColors")
public int[] gradientRatio;
/**
* Horizontal blur amount