mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-24 10:25:39 +00:00
Added Show button records in the tree, preview them
This commit is contained in:
@@ -16,6 +16,7 @@ All notable changes to this project will be documented in this file.
|
||||
- Moving tags up and down in the taglist view (context menuitem + ALT up/down shortcut)
|
||||
- [#1701] Setting charset for SWF files with version 5 or lower (GUI, commandline)
|
||||
- [#1864] Commandline: Allow to set special value "/dev/stdin" for input files to read from stdin (even on Windows)
|
||||
- Show button records in the tree, preview them
|
||||
|
||||
### Fixed
|
||||
- Exception when bundle selected
|
||||
|
||||
@@ -202,6 +202,7 @@ import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.TagStub;
|
||||
import com.jpexs.decompiler.flash.tags.UnknownTag;
|
||||
import com.jpexs.decompiler.flash.tags.VideoFrameTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
|
||||
import com.jpexs.decompiler.flash.tags.gfx.DefineCompactedFont;
|
||||
import com.jpexs.decompiler.flash.tags.gfx.DefineExternalGradient;
|
||||
import com.jpexs.decompiler.flash.tags.gfx.DefineExternalImage;
|
||||
@@ -2457,17 +2458,17 @@ public class SWFInputStream implements AutoCloseable {
|
||||
/**
|
||||
* Reads list of BUTTONRECORD values from the stream
|
||||
*
|
||||
* @param inDefineButton2 Whether read from inside of DefineButton2Tag or
|
||||
* not
|
||||
* @param swf
|
||||
* @param buttonTag
|
||||
* @param name
|
||||
* @return List of BUTTONRECORD values
|
||||
* @throws IOException
|
||||
*/
|
||||
public List<BUTTONRECORD> readBUTTONRECORDList(boolean inDefineButton2, String name) throws IOException {
|
||||
public List<BUTTONRECORD> readBUTTONRECORDList(SWF swf, ButtonTag buttonTag, String name) throws IOException {
|
||||
List<BUTTONRECORD> ret = new ArrayList<>();
|
||||
newDumpLevel(name, "BUTTONRECORDList");
|
||||
BUTTONRECORD br;
|
||||
while ((br = readBUTTONRECORD(inDefineButton2, "record")) != null) {
|
||||
while ((br = readBUTTONRECORD(swf, buttonTag, "record")) != null) {
|
||||
ret.add(br);
|
||||
}
|
||||
endDumpLevel();
|
||||
@@ -2477,13 +2478,14 @@ public class SWFInputStream implements AutoCloseable {
|
||||
/**
|
||||
* Reads one BUTTONRECORD value from the stream
|
||||
*
|
||||
* @param inDefineButton2 True when in DefineButton2
|
||||
* @param swf
|
||||
* @param tag
|
||||
* @param name
|
||||
* @return BUTTONRECORD value
|
||||
* @throws IOException
|
||||
*/
|
||||
public BUTTONRECORD readBUTTONRECORD(boolean inDefineButton2, String name) throws IOException {
|
||||
BUTTONRECORD ret = new BUTTONRECORD();
|
||||
public BUTTONRECORD readBUTTONRECORD(SWF swf, ButtonTag tag, String name) throws IOException {
|
||||
BUTTONRECORD ret = new BUTTONRECORD(swf, tag);
|
||||
newDumpLevel(name, "BUTTONRECORD");
|
||||
ret.reserved = (int) readUB(2, "reserved");
|
||||
ret.buttonHasBlendMode = readUB(1, "buttonHasBlendMode") == 1;
|
||||
@@ -2503,7 +2505,7 @@ public class SWFInputStream implements AutoCloseable {
|
||||
ret.characterId = readUI16("characterId");
|
||||
ret.placeDepth = readUI16("placeDepth");
|
||||
ret.placeMatrix = readMatrix("placeMatrix");
|
||||
if (inDefineButton2) {
|
||||
if (tag instanceof DefineButton2Tag) {
|
||||
ret.colorTransform = readCXFORMWITHALPHA("colorTransform");
|
||||
if (ret.buttonHasFilterList) {
|
||||
ret.filterList = readFILTERLIST("filterList");
|
||||
|
||||
@@ -109,7 +109,7 @@ public class DefineButton2Tag extends ButtonTag implements ASMSourceContainer {
|
||||
reserved = (int) sis.readUB(7, "reserved");
|
||||
trackAsMenu = sis.readUB(1, "trackAsMenu") == 1;
|
||||
int actionOffset = sis.readUI16("actionOffset");
|
||||
characters = sis.readBUTTONRECORDList(true, "characters");
|
||||
characters = sis.readBUTTONRECORDList(swf, this, "characters");
|
||||
if (actionOffset > 0) {
|
||||
actions = sis.readBUTTONCONDACTIONList(swf, this, "actions");
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ public class DefineButtonTag extends ButtonTag implements ASMSourceContainer {
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
buttonId = sis.readUI16("buttonId");
|
||||
characters = sis.readBUTTONRECORDList(false, "characters");
|
||||
characters = sis.readBUTTONRECORDList(swf, this, "characters");
|
||||
actionBytes = sis.readByteRangeEx(sis.available(), "actionBytes", DumpInfoSpecialType.ACTION_BYTES, sis.getPos());
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,13 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.types;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.tags.DefineButton2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
|
||||
import com.jpexs.decompiler.flash.treeitems.TreeItem;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Conditional;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFArray;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
@@ -30,7 +35,7 @@ import java.util.List;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class BUTTONRECORD implements Serializable {
|
||||
public class BUTTONRECORD implements Serializable, TreeItem {
|
||||
|
||||
@Reserved
|
||||
@SWFType(value = BasicType.UB, count = 2)
|
||||
@@ -104,8 +109,47 @@ public class BUTTONRECORD implements Serializable {
|
||||
@Conditional(value = {"buttonHasBlendMode"}, tags = {DefineButton2Tag.ID})
|
||||
public int blendMode;
|
||||
|
||||
@Internal
|
||||
private SWF swf;
|
||||
|
||||
@Internal
|
||||
private ButtonTag tag;
|
||||
|
||||
public BUTTONRECORD(SWF swf, ButtonTag tag) {
|
||||
this.swf = swf;
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public BUTTONRECORD() {
|
||||
swf = null;
|
||||
tag = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[BUTTONRECORD character:" + characterId + ", depth:" + placeDepth + ", state:" + ((buttonStateDown ? "down " : "") + (buttonStateHitTest ? "hit " : "") + (buttonStateOver ? "over " : "") + (buttonStateUp ? "up " : "")) + "]";
|
||||
return "BUTTONRECORD (" + characterId + ") Depth:" + placeDepth + " State:" + ((buttonStateDown ? "down " : "") + (buttonStateHitTest ? "hit " : "") + (buttonStateOver ? "over " : "") + (buttonStateUp ? "up " : ""));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SWF getSwf() {
|
||||
return swf;
|
||||
}
|
||||
|
||||
public void setModified() {
|
||||
if (tag != null) {
|
||||
tag.setModified(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModified() {
|
||||
if (tag != null) {
|
||||
return tag.isModified();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public ButtonTag getTag() {
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +133,9 @@ import com.jpexs.decompiler.flash.tags.EndTag;
|
||||
import com.jpexs.decompiler.flash.tags.FileAttributesTag;
|
||||
import com.jpexs.decompiler.flash.tags.JPEGTablesTag;
|
||||
import com.jpexs.decompiler.flash.tags.MetadataTag;
|
||||
import com.jpexs.decompiler.flash.tags.PlaceObject2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.PlaceObjectTag;
|
||||
import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag;
|
||||
import com.jpexs.decompiler.flash.tags.ShowFrameTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.TagInfo;
|
||||
@@ -164,6 +166,7 @@ import com.jpexs.decompiler.flash.treeitems.FolderItem;
|
||||
import com.jpexs.decompiler.flash.treeitems.HeaderItem;
|
||||
import com.jpexs.decompiler.flash.treeitems.SWFList;
|
||||
import com.jpexs.decompiler.flash.treeitems.TreeItem;
|
||||
import com.jpexs.decompiler.flash.types.BUTTONRECORD;
|
||||
import com.jpexs.decompiler.flash.types.FILLSTYLE;
|
||||
import static com.jpexs.decompiler.flash.types.FILLSTYLE.CLIPPED_BITMAP;
|
||||
import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY;
|
||||
@@ -4324,6 +4327,44 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
} else {
|
||||
previewPanel.setParametersPanelVisible(false);
|
||||
}
|
||||
} else if (treeItem instanceof BUTTONRECORD) {
|
||||
BUTTONRECORD buttonRecord = (BUTTONRECORD) treeItem;
|
||||
previewPanel.setParametersPanelVisible(false);
|
||||
SWF swf = new SWF(buttonRecord.getSwf().getCharset());
|
||||
swf.frameCount = 1;
|
||||
swf.frameRate = buttonRecord.getSwf().frameRate;
|
||||
swf.displayRect = buttonRecord.getTag().getRect();
|
||||
if (swf.getBackgroundColor() != null) {
|
||||
SetBackgroundColorTag setBackgroundColorTag = new SetBackgroundColorTag(swf, swf.getBackgroundColor().backgroundColor);
|
||||
swf.addTag(setBackgroundColorTag);
|
||||
setBackgroundColorTag.setTimelined(swf);
|
||||
}
|
||||
CharacterTag character = buttonRecord.getSwf().getCharacter(buttonRecord.characterId);
|
||||
Set<Integer> needed = new LinkedHashSet<>();
|
||||
character.getNeededCharactersDeep(needed);
|
||||
needed.remove(buttonRecord.characterId);
|
||||
needed.add(buttonRecord.characterId);
|
||||
|
||||
for (int n : needed) {
|
||||
CharacterTag neededCharacter;
|
||||
try {
|
||||
neededCharacter = (CharacterTag) buttonRecord.getSwf().getCharacter(n).cloneTag();
|
||||
} catch (InterruptedException | IOException ex) {
|
||||
Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return;
|
||||
}
|
||||
neededCharacter.setSwf(swf);
|
||||
neededCharacter.setTimelined(swf);
|
||||
swf.addTag(neededCharacter);
|
||||
}
|
||||
|
||||
PlaceObject2Tag placeTag = new PlaceObject2Tag(swf, false, 1, buttonRecord.characterId, buttonRecord.placeMatrix, buttonRecord.colorTransform, 0, null, -1, null);
|
||||
swf.addTag(placeTag);
|
||||
placeTag.setTimelined(swf);
|
||||
ShowFrameTag showFrameTag = new ShowFrameTag(swf);
|
||||
swf.addTag(showFrameTag);
|
||||
showFrameTag.setTimelined(swf);
|
||||
previewPanel.showImagePanel(swf, swf, 0, true, true);
|
||||
} else {
|
||||
previewPanel.showEmpty();
|
||||
}
|
||||
@@ -4493,6 +4534,9 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
showCard(CARDPREVIEWPANEL);
|
||||
} else if (treeItem instanceof Tag) {
|
||||
showGenericTag((Tag) treeItem);
|
||||
} else if (treeItem instanceof BUTTONRECORD) {
|
||||
showPreview(treeItem, previewPanel, -1, null);
|
||||
showCard(CARDPREVIEWPANEL);
|
||||
} else {
|
||||
showCard(CARDEMPTYPANEL);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ public enum TreeNodeType {
|
||||
MORPH_SHAPE,
|
||||
SPRITE,
|
||||
BUTTON,
|
||||
BUTTON_RECORD,
|
||||
AS,
|
||||
AS_CLASS,
|
||||
AS_INTERFACE,
|
||||
|
||||
BIN
src/com/jpexs/decompiler/flash/gui/graphics/buttonrecord16.png
Normal file
BIN
src/com/jpexs/decompiler/flash/gui/graphics/buttonrecord16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 733 B |
@@ -24,6 +24,8 @@ import com.jpexs.decompiler.flash.gui.tagtree.AbstractTagTreeModel;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineSpriteTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSourceContainer;
|
||||
import com.jpexs.decompiler.flash.tags.base.ButtonAction;
|
||||
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
|
||||
import com.jpexs.decompiler.flash.timeline.Frame;
|
||||
import com.jpexs.decompiler.flash.timeline.Timelined;
|
||||
import com.jpexs.decompiler.flash.treeitems.HeaderItem;
|
||||
@@ -97,9 +99,18 @@ public class TagListTreeModel extends AbstractTagTreeModel {
|
||||
return ((Frame) parentNode).allInnerTags.get(index);
|
||||
} else if (parentNode instanceof DefineBinaryDataTag) {
|
||||
return ((DefineBinaryDataTag) parentNode).innerSwf;
|
||||
} else if (parentNode instanceof ASMSourceContainer) {
|
||||
}
|
||||
|
||||
if (parentNode instanceof ButtonTag) {
|
||||
if (index < ((ButtonTag) parentNode).getRecords().size()) {
|
||||
return ((ButtonTag) parentNode).getRecords().get(index);
|
||||
}
|
||||
index -= ((ButtonTag) parentNode).getRecords().size();
|
||||
}
|
||||
if (parentNode instanceof ASMSourceContainer) {
|
||||
return ((ASMSourceContainer)parentNode).getSubItems().get(index);
|
||||
}
|
||||
|
||||
throw new Error("Unsupported parent type: " + parentNode.getClass().getName());
|
||||
}
|
||||
|
||||
@@ -107,7 +118,7 @@ public class TagListTreeModel extends AbstractTagTreeModel {
|
||||
public int getChildCount(Object parent) {
|
||||
TreeItem parentNode = (TreeItem) parent;
|
||||
if (parentNode == root) {
|
||||
return swfs.size();
|
||||
return swfs.size();
|
||||
} else if (parentNode instanceof SWFList) {
|
||||
return ((SWFList) parentNode).swfs.size();
|
||||
} else if (parentNode instanceof SWF) {
|
||||
@@ -120,11 +131,17 @@ public class TagListTreeModel extends AbstractTagTreeModel {
|
||||
return ((DefineSpriteTag) parentNode).getTimeline().getFrameCount();
|
||||
} else if (parentNode instanceof DefineBinaryDataTag) {
|
||||
return (((DefineBinaryDataTag) parentNode).innerSwf == null ? 0 : 1);
|
||||
} else if (parentNode instanceof ASMSourceContainer) {
|
||||
return ((ASMSourceContainer)parentNode).getSubItems().size();
|
||||
}
|
||||
int size = 0;
|
||||
if (parentNode instanceof ButtonTag) {
|
||||
size += ((ButtonTag) parentNode).getRecords().size();
|
||||
}
|
||||
if (parentNode instanceof ASMSourceContainer) {
|
||||
size += ((ASMSourceContainer)parentNode).getSubItems().size();
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -165,9 +182,23 @@ public class TagListTreeModel extends AbstractTagTreeModel {
|
||||
return ((Frame) parentNode).allInnerTags.indexOf(child);
|
||||
} else if (parentNode instanceof DefineBinaryDataTag) {
|
||||
return ((DefineBinaryDataTag) parentNode).innerSwf == child ? 0 : -1;
|
||||
} else if (parentNode instanceof ASMSourceContainer) {
|
||||
return ((ASMSourceContainer)parentNode).getSubItems().indexOf(child);
|
||||
}
|
||||
int base = 0;
|
||||
if (parentNode instanceof ButtonTag) {
|
||||
int index = ((ButtonTag) parentNode).getRecords().indexOf(child);
|
||||
if (index > -1) {
|
||||
return index;
|
||||
}
|
||||
base = ((ButtonTag) parentNode).getRecords().size();
|
||||
}
|
||||
if (parentNode instanceof ASMSourceContainer) {
|
||||
int index = ((ASMSourceContainer)parentNode).getSubItems().indexOf(child);
|
||||
if (index == -1) {
|
||||
return -1;
|
||||
}
|
||||
return base + index;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -270,11 +301,16 @@ public class TagListTreeModel extends AbstractTagTreeModel {
|
||||
} else {
|
||||
return new ArrayList<>(0);
|
||||
}
|
||||
} else if (parentNode instanceof ASMSourceContainer) {
|
||||
return ((ASMSourceContainer)parentNode).getSubItems();
|
||||
}
|
||||
List<TreeItem> ret = new ArrayList<>();
|
||||
if (parentNode instanceof ButtonTag) {
|
||||
ret.addAll(((ButtonTag) parentNode).getRecords());
|
||||
}
|
||||
if (parentNode instanceof ASMSourceContainer) {
|
||||
ret.addAll(((ASMSourceContainer)parentNode).getSubItems());
|
||||
}
|
||||
|
||||
return new ArrayList<>();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -95,6 +95,7 @@ import com.jpexs.decompiler.flash.treeitems.HeaderItem;
|
||||
import com.jpexs.decompiler.flash.treeitems.SWFList;
|
||||
import com.jpexs.decompiler.flash.treeitems.TreeItem;
|
||||
import com.jpexs.decompiler.flash.types.BUTTONCONDACTION;
|
||||
import com.jpexs.decompiler.flash.types.BUTTONRECORD;
|
||||
import com.jpexs.decompiler.flash.types.CLIPACTIONRECORD;
|
||||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
@@ -217,6 +218,10 @@ public abstract class AbstractTagTree extends JTree {
|
||||
if (t instanceof ButtonTag) {
|
||||
return TreeNodeType.BUTTON;
|
||||
}
|
||||
|
||||
if (t instanceof BUTTONRECORD) {
|
||||
return TreeNodeType.BUTTON_RECORD;
|
||||
}
|
||||
|
||||
if (t instanceof DefineVideoStreamTag) {
|
||||
return TreeNodeType.MOVIE;
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSourceContainer;
|
||||
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
|
||||
@@ -44,6 +45,7 @@ import com.jpexs.decompiler.flash.treeitems.FolderItem;
|
||||
import com.jpexs.decompiler.flash.treeitems.HeaderItem;
|
||||
import com.jpexs.decompiler.flash.treeitems.SWFList;
|
||||
import com.jpexs.decompiler.flash.treeitems.TreeItem;
|
||||
import com.jpexs.decompiler.flash.types.BUTTONRECORD;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -541,6 +543,8 @@ public class TagTreeModel extends AbstractTagTreeModel {
|
||||
} else {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
} else if (parentNode instanceof ButtonTag) {
|
||||
return ((ButtonTag) parentNode).getRecords();
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -614,6 +618,8 @@ public class TagTreeModel extends AbstractTagTreeModel {
|
||||
return clt.getChild(clt.getRoot(), index);
|
||||
} else if (parentNode instanceof AS3ClassTreeItem) {
|
||||
return ((AS3Package) parentNode).getChild(index);
|
||||
} else if (parentNode instanceof ButtonTag) {
|
||||
return ((ButtonTag) parentNode).getRecords().get(index);
|
||||
}
|
||||
|
||||
throw new Error("Unsupported parent type: " + parentNode.getClass().getName());
|
||||
@@ -654,6 +660,8 @@ public class TagTreeModel extends AbstractTagTreeModel {
|
||||
return mappedSize + clt.getChildCount(clt.getRoot());
|
||||
} else if (parentNode instanceof AS3Package) {
|
||||
return mappedSize + ((AS3Package) parentNode).getChildCount();
|
||||
} else if (parentNode instanceof ButtonTag) {
|
||||
return mappedSize + ((ButtonTag) parentNode).getRecords().size();
|
||||
} else if (parentNode instanceof CharacterTag) {
|
||||
return mappedSize;
|
||||
}
|
||||
@@ -723,6 +731,8 @@ public class TagTreeModel extends AbstractTagTreeModel {
|
||||
return indexOfAdd(baseIndex, clt.getIndexOfChild(clt.getRoot(), childNode));
|
||||
} else if (parentNode instanceof AS3ClassTreeItem) {
|
||||
return indexOfAdd(baseIndex, ((AS3Package) parentNode).getIndexOfChild((AS3ClassTreeItem) childNode));
|
||||
} else if (parentNode instanceof ButtonTag) {
|
||||
return indexOfAdd(baseIndex, ((ButtonTag) parentNode).getRecords().indexOf(childNode));
|
||||
} else if (parentNode instanceof CharacterTag) {
|
||||
return indexOfAdd(baseIndex, getMappedCharacters(((CharacterTag) parentNode).getSwf(), (CharacterTag) parentNode).indexOf(childNode));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user