mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-10-02 10:12:20 +00:00
Add to stage tag order fix.
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2024 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash;
|
||||
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.VideoFrameTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.RemoveTag;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* This class fixes SWF that all CharacterTags (and attached CharacterIdTags)
|
||||
* are placed before their usage.
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineBeforeUsageFixer {
|
||||
|
||||
public boolean fixDefineBeforeUsage(SWF swf) {
|
||||
ReadOnlyTagList tags = swf.getTags();
|
||||
Set<Integer> walkedCharacters = new HashSet<>();
|
||||
boolean changed = false;
|
||||
for (int i = 0; i < tags.size(); i++) {
|
||||
Tag t = tags.get(i);
|
||||
Set<Integer> needed = new LinkedHashSet<>();
|
||||
t.getNeededCharactersDeep(needed);
|
||||
for (int chId : needed) {
|
||||
if (walkedCharacters.contains(chId)) {
|
||||
continue;
|
||||
}
|
||||
walkedCharacters.add(chId);
|
||||
CharacterTag ch = swf.getCharacter(chId);
|
||||
if (ch != null) {
|
||||
int defineIndex = tags.indexOf(ch);
|
||||
int usageIndex = i;
|
||||
if (usageIndex < defineIndex) {
|
||||
i += moveCharacter(swf, i, chId);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
private int moveCharacter(SWF swf, int usageIndex, int characterId) {
|
||||
int i = 0;
|
||||
for (int j = 0; j < swf.getTags().size(); j++) {
|
||||
Tag t2 = swf.getTags().get(j);
|
||||
if ((t2 instanceof CharacterIdTag)
|
||||
&& !(t2 instanceof PlaceObjectTypeTag)
|
||||
&& !(t2 instanceof RemoveTag)
|
||||
&& !(t2 instanceof VideoFrameTag)) {
|
||||
CharacterIdTag chit = (CharacterIdTag) t2;
|
||||
if (chit.getCharacterId() == characterId) {
|
||||
swf.removeTag(j);
|
||||
swf.addTag(usageIndex + i, (Tag) chit);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -1613,7 +1613,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
* @param characters Map of characterId to CharacterTag
|
||||
* @param characterIdTags Map of characterId to list of CharacterIdTags
|
||||
*/
|
||||
private void parseCharacters(Iterable<Tag> list, Map<Integer, DefineExternalImage2> externalImages2, Map<Integer, CharacterTag> characters, Map<Integer, List<CharacterIdTag>> characterIdTags) {
|
||||
private synchronized void parseCharacters(Iterable<Tag> list, Map<Integer, DefineExternalImage2> externalImages2, Map<Integer, CharacterTag> characters, Map<Integer, List<CharacterIdTag>> characterIdTags) {
|
||||
Iterator<Tag> iterator = list.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Tag t = iterator.next();
|
||||
@@ -5068,7 +5068,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
* @param removeDependencies Remove dependencies?
|
||||
* @param listener Listener to call after removing each of character.
|
||||
*/
|
||||
public void removeTags(Collection<Tag> tags, boolean removeDependencies, TagRemoveListener listener) {
|
||||
public synchronized void removeTags(Collection<Tag> tags, boolean removeDependencies, TagRemoveListener listener) {
|
||||
Set<Timelined> timelineds = new HashSet<>();
|
||||
for (Tag tag : tags) {
|
||||
Timelined timelined = tag.getTimelined();
|
||||
@@ -5091,7 +5091,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
* @param index Index of tag
|
||||
*/
|
||||
@Override
|
||||
public void removeTag(int index) {
|
||||
public synchronized void removeTag(int index) {
|
||||
setModified(true);
|
||||
tags.remove(index);
|
||||
updateCharacters();
|
||||
@@ -5103,10 +5103,11 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
* @param tag Tag
|
||||
*/
|
||||
@Override
|
||||
public void removeTag(Tag tag) {
|
||||
public synchronized void removeTag(Tag tag) {
|
||||
setModified(true);
|
||||
tags.remove(tag);
|
||||
updateCharacters();
|
||||
readOnlyTags = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5116,13 +5117,14 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
* @param removeDependencies Remove dependencies?
|
||||
* @param listener Listener to call after removing each of character.
|
||||
*/
|
||||
public void removeTag(Tag tag, boolean removeDependencies, TagRemoveListener listener) {
|
||||
public synchronized void removeTag(Tag tag, boolean removeDependencies, TagRemoveListener listener) {
|
||||
Timelined timelined = tag.getTimelined();
|
||||
removeTagInternal(timelined, tag, removeDependencies, listener);
|
||||
resetTimelines(timelined);
|
||||
updateCharacters();
|
||||
clearImageCache();
|
||||
clearShapeCache();
|
||||
readOnlyTags = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5161,7 +5163,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
* @return Tags
|
||||
*/
|
||||
@Override
|
||||
public ReadOnlyTagList getTags() {
|
||||
public synchronized ReadOnlyTagList getTags() {
|
||||
if (readOnlyTags == null) {
|
||||
readOnlyTags = new ReadOnlyTagList(tags);
|
||||
}
|
||||
@@ -5175,10 +5177,11 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
* @param tag Tag
|
||||
*/
|
||||
@Override
|
||||
public void addTag(Tag tag) {
|
||||
public synchronized void addTag(Tag tag) {
|
||||
setModified(true);
|
||||
tags.add(tag);
|
||||
updateCharacters();
|
||||
readOnlyTags = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5188,10 +5191,11 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
* @param tag Tag
|
||||
*/
|
||||
@Override
|
||||
public void addTag(int index, Tag tag) {
|
||||
public synchronized void addTag(int index, Tag tag) {
|
||||
setModified(true);
|
||||
tags.add(index, tag);
|
||||
updateCharacters();
|
||||
readOnlyTags = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5201,7 +5205,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
* @return Index or -1 when not found
|
||||
*/
|
||||
@Override
|
||||
public int indexOfTag(Tag tag) {
|
||||
public synchronized int indexOfTag(Tag tag) {
|
||||
return tags.indexOf(tag);
|
||||
}
|
||||
|
||||
|
||||
@@ -326,7 +326,7 @@ public class DefineSpriteTag extends DrawableTag implements Timelined {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyTagList getTags() {
|
||||
public synchronized ReadOnlyTagList getTags() {
|
||||
if (readOnlyTags == null) {
|
||||
readOnlyTags = new ReadOnlyTagList(subTags);
|
||||
}
|
||||
@@ -335,31 +335,31 @@ public class DefineSpriteTag extends DrawableTag implements Timelined {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTag(int index) {
|
||||
public synchronized void removeTag(int index) {
|
||||
setModified(true);
|
||||
subTags.remove(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTag(Tag tag) {
|
||||
public synchronized void removeTag(Tag tag) {
|
||||
setModified(true);
|
||||
subTags.remove(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTag(Tag tag) {
|
||||
public synchronized void addTag(Tag tag) {
|
||||
setModified(true);
|
||||
subTags.add(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTag(int index, Tag tag) {
|
||||
public synchronized void addTag(int index, Tag tag) {
|
||||
setModified(true);
|
||||
subTags.add(index, tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOfTag(Tag tag) {
|
||||
public synchronized int indexOfTag(Tag tag) {
|
||||
return subTags.indexOf(tag);
|
||||
}
|
||||
|
||||
|
||||
@@ -486,7 +486,7 @@ public class DefineVideoStreamTag extends DrawableTag implements BoundedTag, Tim
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyTagList getTags() {
|
||||
public synchronized ReadOnlyTagList getTags() {
|
||||
initTimeline();
|
||||
return tags;
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ public abstract class ButtonTag extends DrawableTag implements Timelined {
|
||||
protected abstract void initTimeline(Timeline timeline);
|
||||
|
||||
@Override
|
||||
public ReadOnlyTagList getTags() {
|
||||
public synchronized ReadOnlyTagList getTags() {
|
||||
return ReadOnlyTagList.EMPTY;
|
||||
}
|
||||
|
||||
|
||||
@@ -449,7 +449,8 @@ public class Timeline {
|
||||
boolean newFrameNeeded = false;
|
||||
scenes = new ArrayList<>();
|
||||
Scene prevScene = null;
|
||||
for (Tag t : timelined.getTags()) {
|
||||
List<Tag> tagList = timelined.getTags().toArrayList();
|
||||
for (Tag t : tagList) {
|
||||
newFrameNeeded = true;
|
||||
boolean isNested = ShowFrameTag.isNestedTagType(t.getId());
|
||||
if (isNested) {
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.easygui;
|
||||
|
||||
import com.jpexs.decompiler.flash.DefineBeforeUsageFixer;
|
||||
import com.jpexs.decompiler.flash.ReadOnlyTagList;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.gui.ImagePanel;
|
||||
import com.jpexs.decompiler.flash.gui.RegistrationPointPosition;
|
||||
@@ -47,6 +49,7 @@ import java.awt.geom.Point2D;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
@@ -183,14 +186,18 @@ public class MainFrame extends JFrame {
|
||||
|
||||
private PlaceObject2Tag place;
|
||||
private RemoveObject2Tag remove;
|
||||
private List<Tag> tags;
|
||||
private int frame = stagePanel.getFrame();
|
||||
private int depth = stagePanel.getSelectedDepth();
|
||||
|
||||
@Override
|
||||
public void doOperation() {
|
||||
timelinePanel.setFrame(frame, depth);
|
||||
CharacterTag ch = (CharacterTag) tag;
|
||||
int maxDepth = stagePanel.getTimelined().getTimeline().getMaxDepth();
|
||||
int newDepth = maxDepth + 1;
|
||||
Timelined timelined = stagePanel.getTimelined();
|
||||
ShowFrameTag showFrameTag = timelined.getTimeline().getFrame(stagePanel.getFrame()).showFrameTag;
|
||||
ShowFrameTag showFrameTag = timelined.getTimeline().getFrame(frame).showFrameTag;
|
||||
place = new PlaceObject2Tag(timelined.getSwf());
|
||||
place.depth = newDepth;
|
||||
place.placeFlagHasCharacter = true;
|
||||
@@ -207,6 +214,14 @@ public class MainFrame extends JFrame {
|
||||
remove.depth = newDepth;
|
||||
timelined.addTag(timelined.indexOfTag(showFrameTag) + 1, remove);
|
||||
}
|
||||
|
||||
tags = timelined.getSwf().getTags().toArrayList();
|
||||
DefineBeforeUsageFixer fixer = new DefineBeforeUsageFixer();
|
||||
boolean tagOrderChanged = fixer.fixDefineBeforeUsage(timelined.getSwf());
|
||||
if (!tagOrderChanged) {
|
||||
tags = null;
|
||||
}
|
||||
|
||||
timelined.resetTimeline();
|
||||
stagePanel.repaint();
|
||||
timelinePanel.refresh();
|
||||
@@ -221,8 +236,27 @@ public class MainFrame extends JFrame {
|
||||
timelined.removeTag(remove);
|
||||
}
|
||||
timelined.resetTimeline();
|
||||
|
||||
//Tag order changed, put the original tags back
|
||||
if (tags != null) {
|
||||
SWF swf = timelined.getSwf();
|
||||
ReadOnlyTagList newTags = swf.getTags();
|
||||
int size = newTags.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
swf.removeTag(0);
|
||||
}
|
||||
for (int i = 0; i < tags.size(); i++) {
|
||||
if (tags.get(i) == place) {
|
||||
continue;
|
||||
}
|
||||
swf.addTag(tags.get(i));
|
||||
}
|
||||
swf.resetTimeline();
|
||||
}
|
||||
|
||||
stagePanel.repaint();
|
||||
timelinePanel.refresh();
|
||||
timelinePanel.setFrame(frame, depth);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1144,13 +1144,14 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
|
||||
if (altDown || selectionMode) {
|
||||
if (depthStateUnderCursor != null) {
|
||||
if (transformSelectionMode) {
|
||||
if (freeTransformDepth != depthStateUnderCursor.depth) {
|
||||
if (freeTransformDepth != depthStateUnderCursor.depth && mode == Cursor.DEFAULT_CURSOR) {
|
||||
freeTransformDepth(depthStateUnderCursor.depth);
|
||||
firePlaceObjectSelected();
|
||||
}
|
||||
} else if (selectionMode) {
|
||||
selectDepth(depthStateUnderCursor.depth);
|
||||
}
|
||||
firePlaceObjectSelected();
|
||||
firePlaceObjectSelected();
|
||||
}
|
||||
}
|
||||
if (!selectionMode) {
|
||||
return;
|
||||
|
||||
@@ -91,6 +91,7 @@ import com.jpexs.decompiler.flash.tags.SymbolClassTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.TagTypeInfo;
|
||||
import com.jpexs.decompiler.flash.tags.UnknownTag;
|
||||
import com.jpexs.decompiler.flash.tags.VideoFrameTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.flash.tags.base.BinaryDataInterface;
|
||||
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
|
||||
@@ -5281,7 +5282,8 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
Tag t2 = swf.getTags().get(j);
|
||||
if ((t2 instanceof CharacterIdTag)
|
||||
&& !(t2 instanceof PlaceObjectTypeTag)
|
||||
&& !(t2 instanceof RemoveTag)) {
|
||||
&& !(t2 instanceof RemoveTag)
|
||||
&& !(t2 instanceof VideoFrameTag)) {
|
||||
CharacterIdTag chit = (CharacterIdTag) t2;
|
||||
if (chit.getCharacterId() == characterId) {
|
||||
swf.removeTag(j);
|
||||
|
||||
Reference in New Issue
Block a user