mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-29 07:15:39 +00:00
Added: Simple editor - add/remove frames in buttons
This commit is contained in:
@@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file.
|
||||
### Added
|
||||
- "Starting Flash content debugger" in status bar when debugging starts
|
||||
- Simple editor - edit parameters of items inside buttons
|
||||
- Simple editor - add/remove frames in buttons
|
||||
|
||||
### Fixed
|
||||
- Resize export dialogs labels to match localized strings
|
||||
|
||||
@@ -270,7 +270,7 @@ public class DefineButton2Tag extends ButtonTag implements ASMSourceContainer {
|
||||
layer.filters = r.filterList;
|
||||
layer.matrix = r.placeMatrix;
|
||||
layer.characterId = r.characterId;
|
||||
layer.depth = r.placeDepth;
|
||||
layer.depth = r.placeDepth;
|
||||
|
||||
if (r.placeDepth > maxDepth) {
|
||||
maxDepth = r.placeDepth;
|
||||
@@ -278,15 +278,28 @@ public class DefineButton2Tag extends ButtonTag implements ASMSourceContainer {
|
||||
|
||||
if (r.buttonStateUp) {
|
||||
frameUp.layers.put(r.placeDepth, new DepthState(layer, frameUp, frameUp, false));
|
||||
frameUp.layers.get(r.placeDepth).key = true;
|
||||
}
|
||||
if (r.buttonStateDown) {
|
||||
frameDown.layers.put(r.placeDepth, new DepthState(layer, frameDown, frameDown, false));
|
||||
}
|
||||
|
||||
if (r.buttonStateOver) {
|
||||
frameOver.layers.put(r.placeDepth, new DepthState(layer, frameOver, frameOver, false));
|
||||
if (!r.buttonStateUp) {
|
||||
frameOver.layers.get(r.placeDepth).key = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (r.buttonStateDown) {
|
||||
frameDown.layers.put(r.placeDepth, new DepthState(layer, frameDown, frameDown, false));
|
||||
if (!r.buttonStateOver) {
|
||||
frameDown.layers.get(r.placeDepth).key = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (r.buttonStateHitTest) {
|
||||
frameHit.layers.put(r.placeDepth, new DepthState(layer, frameHit, frameHit, false));
|
||||
if (!r.buttonStateDown) {
|
||||
frameHit.layers.get(r.placeDepth).key = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -264,14 +264,23 @@ public class DefineButtonTag extends ButtonTag implements ASMSourceContainer {
|
||||
if (r.buttonStateUp) {
|
||||
frameUp.layers.put(r.placeDepth, new DepthState(layer, frameUp, frameUp, false));
|
||||
}
|
||||
if (r.buttonStateDown) {
|
||||
frameDown.layers.put(r.placeDepth, new DepthState(layer, frameDown, frameDown, false));
|
||||
}
|
||||
if (r.buttonStateOver) {
|
||||
frameOver.layers.put(r.placeDepth, new DepthState(layer, frameOver, frameOver, false));
|
||||
if (!r.buttonStateUp) {
|
||||
frameOver.layers.get(r.placeDepth).key = true;
|
||||
}
|
||||
}
|
||||
if (r.buttonStateDown) {
|
||||
frameDown.layers.put(r.placeDepth, new DepthState(layer, frameDown, frameDown, false));
|
||||
if (!r.buttonStateOver) {
|
||||
frameDown.layers.get(r.placeDepth).key = true;
|
||||
}
|
||||
}
|
||||
if (r.buttonStateHitTest) {
|
||||
frameHit.layers.put(r.placeDepth, new DepthState(layer, frameHit, frameHit, false));
|
||||
if (!r.buttonStateDown) {
|
||||
frameDown.layers.get(r.placeDepth).key = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -278,7 +279,7 @@ public abstract class ButtonTag extends DrawableTag implements Timelined {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (addIfNotExists) {
|
||||
BUTTONRECORD newRecord = new BUTTONRECORD(swf, this);
|
||||
switch (frame) {
|
||||
@@ -295,12 +296,52 @@ public abstract class ButtonTag extends DrawableTag implements Timelined {
|
||||
newRecord.buttonStateHitTest = true;
|
||||
break;
|
||||
}
|
||||
newRecord.placeDepth = depth;
|
||||
getRecords().add(newRecord);
|
||||
return newRecord;
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void packRecords() {
|
||||
List<BUTTONRECORD> records = new ArrayList<>();
|
||||
for (int i = records.size() - 1; i >= 0; i--) {
|
||||
BUTTONRECORD rec = records.get(i);
|
||||
if (rec.isEmpty()) {
|
||||
records.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Set<Integer> getEmptyFrames() {
|
||||
Set<Integer> ret = new LinkedHashSet<>();
|
||||
ret.add(FRAME_UP);
|
||||
ret.add(FRAME_OVER);
|
||||
ret.add(FRAME_DOWN);
|
||||
ret.add(FRAME_HITTEST);
|
||||
for (BUTTONRECORD rec : getRecords()) {
|
||||
if (rec.buttonStateUp) {
|
||||
ret.remove(FRAME_UP);
|
||||
}
|
||||
if (rec.buttonStateOver) {
|
||||
ret.remove(FRAME_OVER);
|
||||
}
|
||||
if (rec.buttonStateDown) {
|
||||
ret.remove(FRAME_DOWN);
|
||||
}
|
||||
if (rec.buttonStateHitTest) {
|
||||
ret.remove(FRAME_HITTEST);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
public boolean isFrameEmpty(int frame) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setRecordFromPlaceObject(int frame, PlaceObjectTypeTag placeTag) {
|
||||
BUTTONRECORD selectedRecord = null;
|
||||
|
||||
@@ -84,6 +84,7 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -144,6 +145,11 @@ public class Timeline {
|
||||
* Map of depth to maximum frame.
|
||||
*/
|
||||
private final Map<Integer, Integer> depthMaxFrame = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Map of depth to maximum frame including buttons
|
||||
*/
|
||||
private final Map<Integer, Integer> depthMaxFrameButtons = new HashMap<>();
|
||||
|
||||
/**
|
||||
* List of all ASMSources.
|
||||
@@ -283,6 +289,16 @@ public class Timeline {
|
||||
ensureInitialized();
|
||||
return depthMaxFrame;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets map of depth to max frame including buttons
|
||||
*
|
||||
* @return Map of depth to max frame
|
||||
*/
|
||||
public Map<Integer, Integer> getDepthMaxFrameButtons() {
|
||||
ensureInitialized();
|
||||
return depthMaxFrameButtons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets map of soundStream id to SoundStreamFrameRanges.
|
||||
@@ -325,6 +341,7 @@ public class Timeline {
|
||||
initialized = false;
|
||||
frames.clear();
|
||||
depthMaxFrame.clear();
|
||||
depthMaxFrameButtons.clear();
|
||||
asmSources.clear();
|
||||
asmSourceContainers.clear();
|
||||
actionFrames.clear();
|
||||
@@ -725,14 +742,31 @@ public class Timeline {
|
||||
*/
|
||||
private synchronized void calculateMaxDepthFrames() {
|
||||
depthMaxFrame.clear();
|
||||
depthMaxFrameButtons.clear();
|
||||
for (int d = 0; d <= maxDepth; d++) {
|
||||
for (int f = frames.size() - 1; f >= 0; f--) {
|
||||
if (frames.get(f).layers.get(d) != null) {
|
||||
depthMaxFrame.put(d, f);
|
||||
depthMaxFrame.put(d, f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (timelined instanceof ButtonTag) {
|
||||
ButtonTag button = (ButtonTag) timelined;
|
||||
Set<Integer> emptyFrames = button.getEmptyFrames();
|
||||
|
||||
for (int d = 0; d <= maxDepth; d++) {
|
||||
for (int f = frames.size() - 1; f >= 0; f--) {
|
||||
if (frames.get(f).layers.get(d) != null) {
|
||||
if (!emptyFrames.contains(f)) {
|
||||
depthMaxFrameButtons.put(d, f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,6 +33,7 @@ import com.jpexs.decompiler.flash.types.annotations.Reserved;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFArray;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.filters.FILTER;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
@@ -52,12 +53,14 @@ public class BUTTONRECORD implements Serializable, TreeItem, HasSwfAndTag, HasCh
|
||||
|
||||
/**
|
||||
* Has blend mode?
|
||||
*
|
||||
* @since SWF 8
|
||||
*/
|
||||
public boolean buttonHasBlendMode;
|
||||
|
||||
/**
|
||||
* Has filter list?
|
||||
*
|
||||
* @since SWF 8
|
||||
*/
|
||||
public boolean buttonHasFilterList;
|
||||
@@ -146,6 +149,7 @@ public class BUTTONRECORD implements Serializable, TreeItem, HasSwfAndTag, HasCh
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param swf SWF
|
||||
* @param tag Button tag
|
||||
*/
|
||||
@@ -154,6 +158,26 @@ public class BUTTONRECORD implements Serializable, TreeItem, HasSwfAndTag, HasCh
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public BUTTONRECORD(BUTTONRECORD source) {
|
||||
this.buttonHasBlendMode = source.buttonHasBlendMode;
|
||||
this.buttonHasFilterList = source.buttonHasFilterList;
|
||||
this.buttonStateHitTest =source. buttonStateHitTest;
|
||||
this.buttonStateDown = source.buttonStateDown;
|
||||
this.buttonStateOver = source.buttonStateOver;
|
||||
this.buttonStateUp = source.buttonStateUp;
|
||||
this.characterId = source.characterId;
|
||||
this.placeDepth = source.placeDepth;
|
||||
this.placeMatrix = new MATRIX(source.placeMatrix);
|
||||
this.colorTransform = source.colorTransform == null ? null : new CXFORMWITHALPHA(source.colorTransform);
|
||||
this.filterList = Helper.deepCopy(source.filterList);
|
||||
this.blendMode = source.blendMode;
|
||||
this.swf = source.swf;
|
||||
this.tag = source.tag;
|
||||
this.modified = source.modified;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
@@ -179,6 +203,7 @@ public class BUTTONRECORD implements Serializable, TreeItem, HasSwfAndTag, HasCh
|
||||
|
||||
/**
|
||||
* Sets the modified flag.
|
||||
*
|
||||
* @param value Modified flag
|
||||
*/
|
||||
public void setModified(boolean value) {
|
||||
@@ -211,20 +236,69 @@ public class BUTTONRECORD implements Serializable, TreeItem, HasSwfAndTag, HasCh
|
||||
this.characterId = characterId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables/disables specific frame
|
||||
*
|
||||
* @param frame Frame
|
||||
* @param value Value
|
||||
*/
|
||||
public void setFrame(int frame, boolean value) {
|
||||
switch (frame) {
|
||||
case ButtonTag.FRAME_UP:
|
||||
buttonStateUp = value;
|
||||
break;
|
||||
case ButtonTag.FRAME_OVER:
|
||||
buttonStateOver = value;
|
||||
break;
|
||||
case ButtonTag.FRAME_DOWN:
|
||||
buttonStateDown = value;
|
||||
break;
|
||||
case ButtonTag.FRAME_HITTEST:
|
||||
buttonStateHitTest = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Has frame
|
||||
*
|
||||
* @param frame Frame
|
||||
* @return True if has
|
||||
*/
|
||||
public boolean hasFrame(int frame) {
|
||||
switch (frame) {
|
||||
case ButtonTag.FRAME_UP:
|
||||
return buttonStateUp;
|
||||
case ButtonTag.FRAME_OVER:
|
||||
return buttonStateOver;
|
||||
case ButtonTag.FRAME_DOWN:
|
||||
return buttonStateDown;
|
||||
case ButtonTag.FRAME_HITTEST:
|
||||
return buttonStateHitTest;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports placeObject to this BUTTONRECORD
|
||||
*
|
||||
* @param placeObject Place tag
|
||||
*/
|
||||
public void fromPlaceObject(PlaceObjectTypeTag placeObject) {
|
||||
placeDepth = placeObject.getDepth();
|
||||
characterId = placeObject.getCharacterId();
|
||||
ColorTransform importedColorTrans = placeObject.getColorTransform();
|
||||
colorTransform = importedColorTrans == null ? null : new CXFORMWITHALPHA(placeObject.getColorTransform());
|
||||
ColorTransform importedColorTrans = placeObject.getColorTransform();
|
||||
colorTransform = importedColorTrans == null ? new CXFORMWITHALPHA() : new CXFORMWITHALPHA(placeObject.getColorTransform());
|
||||
placeMatrix = placeObject.getMatrix();
|
||||
blendMode = placeObject.getBlendMode();
|
||||
buttonHasBlendMode = blendMode > 0;
|
||||
filterList = placeObject.getFilters();
|
||||
buttonHasFilterList = filterList != null && !filterList.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts this BUTTONRECORD to a place tag.
|
||||
*
|
||||
* @return Place tag
|
||||
*/
|
||||
public PlaceObject3Tag toPlaceObject() {
|
||||
@@ -260,4 +334,20 @@ public class BUTTONRECORD implements Serializable, TreeItem, HasSwfAndTag, HasCh
|
||||
}
|
||||
return placeTag;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
if (buttonStateUp) {
|
||||
return false;
|
||||
}
|
||||
if (buttonStateOver) {
|
||||
return false;
|
||||
}
|
||||
if (buttonStateDown) {
|
||||
return false;
|
||||
}
|
||||
if (buttonStateHitTest) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,15 +298,21 @@ public class EasySwfPanel extends JPanel {
|
||||
place.matrix = new MATRIX();
|
||||
place.placeFlagHasMatrix = true;
|
||||
place.setTimelined(timelined);
|
||||
if (showFrameTag == null) {
|
||||
timelined.addTag(place);
|
||||
|
||||
if (timelined instanceof ButtonTag) {
|
||||
ButtonTag button = (ButtonTag) timelined;
|
||||
button.getButtonRecordAt(fframe, newDepth, true).fromPlaceObject(place);
|
||||
} else {
|
||||
timelined.addTag(timelined.indexOfTag(showFrameTag), place);
|
||||
if (showFrameTag == null) {
|
||||
timelined.addTag(place);
|
||||
} else {
|
||||
timelined.addTag(timelined.indexOfTag(showFrameTag), place);
|
||||
|
||||
if (fframe < timelined.getFrameCount() - 1) {
|
||||
RemoveObject2Tag remove = new RemoveObject2Tag(timelined.getSwf());
|
||||
remove.depth = newDepth;
|
||||
timelined.addTag(timelined.indexOfTag(showFrameTag) + 1, remove);
|
||||
if (fframe < timelined.getFrameCount() - 1) {
|
||||
RemoveObject2Tag remove = new RemoveObject2Tag(timelined.getSwf());
|
||||
remove.depth = newDepth;
|
||||
timelined.addTag(timelined.indexOfTag(showFrameTag) + 1, remove);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.tags.RemoveObject2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.ShowFrameTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.MorphShapeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
|
||||
@@ -29,6 +30,8 @@ import com.jpexs.decompiler.flash.timeline.DepthState;
|
||||
import com.jpexs.decompiler.flash.timeline.Frame;
|
||||
import com.jpexs.decompiler.flash.timeline.Timeline;
|
||||
import com.jpexs.decompiler.flash.timeline.Timelined;
|
||||
import com.jpexs.decompiler.flash.types.BUTTONRECORD;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
@@ -229,10 +232,16 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe
|
||||
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
g.setColor(getBackgroundColor());
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
|
||||
if (timeline == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<Integer> emptyFrames = new LinkedHashSet<>();
|
||||
if (timeline.timelined instanceof ButtonTag) {
|
||||
emptyFrames = ((ButtonTag) timeline.timelined).getEmptyFrames();
|
||||
}
|
||||
Rectangle clip = g.getClipBounds();
|
||||
int frameWidth = FRAME_WIDTH;
|
||||
int frameHeight = FRAME_HEIGHT;
|
||||
@@ -291,7 +300,7 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe
|
||||
}
|
||||
}
|
||||
|
||||
Map<Integer, Integer> depthMaxFrames = timeline.getDepthMaxFrame();
|
||||
Map<Integer, Integer> depthMaxFrames = timeline.getDepthMaxFrameButtons();
|
||||
for (int d = start_d; d <= end_d; d++) {
|
||||
int maxFrame = depthMaxFrames.containsKey(d) ? depthMaxFrames.get(d) : -1;
|
||||
if (maxFrame < 0) {
|
||||
@@ -313,6 +322,11 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe
|
||||
|
||||
for (int f = start_f2; f <= end_f2; f++) {
|
||||
DepthState fl = timeline.getFrame(f).layers.get(d);
|
||||
|
||||
if (emptyFrames.contains(f)) {
|
||||
fl = null;
|
||||
}
|
||||
|
||||
boolean motionTween = fl == null ? false : fl.motionTween;
|
||||
|
||||
DepthState flNext = f < max_f ? timeline.getFrame(f + 1).layers.get(d) : null;
|
||||
@@ -608,7 +622,11 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe
|
||||
|
||||
Frame fr = timeline.getFrame(frame);
|
||||
DepthState ds = fr == null ? null : fr.layers.get(depth);
|
||||
boolean thisEmpty = ds == null || ds.getCharacter() == null;
|
||||
Set<Integer> emptyFrames = new LinkedHashSet<>();
|
||||
if (timeline.timelined instanceof ButtonTag) {
|
||||
emptyFrames = ((ButtonTag) timeline.timelined).getEmptyFrames();
|
||||
}
|
||||
boolean thisEmpty = emptyFrames.contains(frame) || ds == null || ds.getCharacter() == null;
|
||||
boolean previousEmpty = true;
|
||||
boolean emptyDepth = true;
|
||||
boolean somethingBefore = false;
|
||||
@@ -621,7 +639,7 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe
|
||||
for (int f = frame - 1; f >= 0; f--) {
|
||||
fr = timeline.getFrame(f);
|
||||
ds = fr == null ? null : fr.layers.get(depth);
|
||||
boolean empty = ds == null || ds.getCharacter() == null;
|
||||
boolean empty = emptyFrames.contains(f) || ds == null || ds.getCharacter() == null;
|
||||
if (!empty) {
|
||||
somethingBefore = true;
|
||||
break;
|
||||
@@ -630,7 +648,7 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe
|
||||
for (int f = frame + 1; f < timeline.getFrameCount(); f++) {
|
||||
fr = timeline.getFrame(f);
|
||||
ds = fr == null ? null : fr.layers.get(depth);
|
||||
boolean empty = ds == null || ds.getCharacter() == null;
|
||||
boolean empty = emptyFrames.contains(f) || ds == null || ds.getCharacter() == null;
|
||||
if (!empty) {
|
||||
somethingAfter = true;
|
||||
break;
|
||||
@@ -700,103 +718,108 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe
|
||||
int nf = p.x;
|
||||
int nd = p.y;
|
||||
|
||||
int f = timelined.getFrameCount();
|
||||
List<Tag> lastFrameDepthTags = new ArrayList<>();
|
||||
DepthState ds = timeline.getFrame(nf).layers.get(nd);
|
||||
if (ds != null && ds.key) {
|
||||
PlaceObjectTypeTag po = ds.placeObjectTag;
|
||||
ShowFrameTag sf = timeline.getFrame(nf).showFrameTag;
|
||||
int pos = sf == null ? tags.size() : timelined.indexOfTag(sf);
|
||||
for (int i = pos + 1; i < tags.size(); i++) {
|
||||
if (timelined instanceof ButtonTag) {
|
||||
ButtonTag button = (ButtonTag) timelined;
|
||||
BUTTONRECORD rec = button.getButtonRecordAt(nf, nd, false);
|
||||
if (rec != null) {
|
||||
rec.setFrame(nf, false);
|
||||
}
|
||||
for(int i = nf + 1; i < button.getFrameCount(); i++) {
|
||||
rec = button.getButtonRecordAt(i, nd, false);
|
||||
if (rec != null) {
|
||||
rec.setFrame(i - 1, true);
|
||||
rec.setFrame(i, false);
|
||||
}
|
||||
}
|
||||
button.packRecords();
|
||||
} else {
|
||||
|
||||
int f = timelined.getFrameCount();
|
||||
List<Tag> lastFrameDepthTags = new ArrayList<>();
|
||||
DepthState ds = timeline.getFrame(nf).layers.get(nd);
|
||||
if (ds != null && ds.key) {
|
||||
PlaceObjectTypeTag po = ds.placeObjectTag;
|
||||
ShowFrameTag sf = timeline.getFrame(nf).showFrameTag;
|
||||
int pos = sf == null ? tags.size() : timelined.indexOfTag(sf);
|
||||
for (int i = pos + 1; i < tags.size(); i++) {
|
||||
Tag t = tags.get(i);
|
||||
if (t instanceof RemoveObject2Tag) {
|
||||
RemoveObject2Tag rt = (RemoveObject2Tag) t;
|
||||
if (rt.depth == nd) {
|
||||
timelined.removeTag(po);
|
||||
timelined.removeTag(rt);
|
||||
i--;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
if (t instanceof ShowFrameTag) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean endsWithRemove = false;
|
||||
for (int i = tags.size() - 1; i >= 0; i--) {
|
||||
Tag t = tags.get(i);
|
||||
if (t instanceof RemoveObject2Tag) {
|
||||
RemoveObject2Tag rt = (RemoveObject2Tag) t;
|
||||
if (rt.depth == nd) {
|
||||
timelined.removeTag(po);
|
||||
timelined.removeTag(rt);
|
||||
i--;
|
||||
i--;
|
||||
if (t instanceof PlaceObjectTypeTag) {
|
||||
PlaceObjectTypeTag pt = (PlaceObjectTypeTag) t;
|
||||
if (pt.getDepth() == nd) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (t instanceof RemoveTag) {
|
||||
RemoveTag rt = (RemoveTag) t;
|
||||
if (rt.getDepth() == nd) {
|
||||
endsWithRemove = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = tags.size() - 1; i >= 0; i--) {
|
||||
Tag t = tags.get(i);
|
||||
if (t instanceof PlaceObjectTypeTag) {
|
||||
PlaceObjectTypeTag pt = (PlaceObjectTypeTag) t;
|
||||
if (pt.getDepth() == nd) {
|
||||
lastFrameDepthTags.add(pt);
|
||||
timelined.removeTag(i);
|
||||
}
|
||||
}
|
||||
if (t instanceof RemoveTag) {
|
||||
RemoveTag rt = (RemoveTag) t;
|
||||
if (rt.getDepth() == nd) {
|
||||
lastFrameDepthTags.add(rt);
|
||||
timelined.removeTag(i);
|
||||
}
|
||||
}
|
||||
if (t instanceof ShowFrameTag) {
|
||||
break;
|
||||
for (Tag lt : lastFrameDepthTags) {
|
||||
timelined.addTag(i, lt);
|
||||
}
|
||||
lastFrameDepthTags.clear();
|
||||
f--;
|
||||
if (f == nf) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean endsWithRemove = false;
|
||||
for (int i = tags.size() - 1; i >= 0; i--) {
|
||||
Tag t = tags.get(i);
|
||||
if (t instanceof PlaceObjectTypeTag) {
|
||||
PlaceObjectTypeTag pt = (PlaceObjectTypeTag) t;
|
||||
if (pt.getDepth() == nd) {
|
||||
break;
|
||||
if (!endsWithRemove) {
|
||||
RemoveTag rt = new RemoveObject2Tag(timelined.getSwf());
|
||||
rt.setTimelined(timelined);
|
||||
rt.setDepth(nd);
|
||||
Tag lt = tags.get(tags.size() - 1);
|
||||
if (lt instanceof ShowFrameTag) {
|
||||
timelined.addTag(tags.size() - 1, rt);
|
||||
} else {
|
||||
timelined.addTag(lt);
|
||||
}
|
||||
}
|
||||
if (t instanceof RemoveTag) {
|
||||
RemoveTag rt = (RemoveTag) t;
|
||||
if (rt.getDepth() == nd) {
|
||||
endsWithRemove = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = tags.size() - 1; i >= 0; i--) {
|
||||
Tag t = tags.get(i);
|
||||
if (t instanceof PlaceObjectTypeTag) {
|
||||
PlaceObjectTypeTag pt = (PlaceObjectTypeTag) t;
|
||||
if (pt.getDepth() == nd) {
|
||||
lastFrameDepthTags.add(pt);
|
||||
timelined.removeTag(i);
|
||||
}
|
||||
}
|
||||
if (t instanceof RemoveTag) {
|
||||
RemoveTag rt = (RemoveTag) t;
|
||||
if (rt.getDepth() == nd) {
|
||||
lastFrameDepthTags.add(rt);
|
||||
timelined.removeTag(i);
|
||||
}
|
||||
}
|
||||
if (t instanceof ShowFrameTag) {
|
||||
for (Tag lt : lastFrameDepthTags) {
|
||||
timelined.addTag(i, lt);
|
||||
}
|
||||
lastFrameDepthTags.clear();
|
||||
f--;
|
||||
if (f == nf) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!endsWithRemove) {
|
||||
RemoveTag rt = new RemoveObject2Tag(timelined.getSwf());
|
||||
rt.setTimelined(timelined);
|
||||
rt.setDepth(nd);
|
||||
Tag lt = tags.get(tags.size() - 1);
|
||||
if (lt instanceof ShowFrameTag) {
|
||||
timelined.addTag(tags.size() - 1, rt);
|
||||
} else {
|
||||
timelined.addTag(lt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
timelined.resetTimeline();
|
||||
|
||||
/*System.err.println("=====AFTER=======");
|
||||
f = 0;
|
||||
int i = 0;
|
||||
for (Tag t : timelined.getTags()) {
|
||||
if (t instanceof ShowFrameTag) {
|
||||
System.err.println("" + i + ": frame " + f);
|
||||
f++;
|
||||
} else {
|
||||
System.err.println("" + i + ": " + t);
|
||||
}
|
||||
i++;
|
||||
}*/
|
||||
Point firstCursor = orderedCursor.iterator().next();
|
||||
frameSelect(firstCursor.x, firstCursor.y);
|
||||
timeline = timelined.getTimeline();
|
||||
@@ -851,9 +874,22 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe
|
||||
continue;
|
||||
}
|
||||
ds.key = true;
|
||||
/*RemoveTag rm = new RemoveObject2Tag(timelined.getSwf());
|
||||
rm.setDepth(depth);
|
||||
rm.setTimelined(timelined);*/
|
||||
|
||||
if (timelined instanceof ButtonTag) {
|
||||
ButtonTag button = (ButtonTag) timelined;
|
||||
BUTTONRECORD rec = button.getButtonRecordAt(nf, nd, false);
|
||||
if (rec != null) {
|
||||
BUTTONRECORD rec2 = new BUTTONRECORD(rec.getSwf(), rec.getTag());
|
||||
rec2.fromPlaceObject(rec.toPlaceObject());
|
||||
|
||||
for(int i = nf; i < button.getFrameCount(); i++) {
|
||||
rec2.setFrame(i, rec.hasFrame(i));
|
||||
rec.setFrame(i, false);
|
||||
}
|
||||
button.getRecords().add(rec2);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
PlaceObjectTypeTag place;
|
||||
try {
|
||||
place = (PlaceObjectTypeTag) ds.placeObjectTag.cloneTag();
|
||||
@@ -870,8 +906,6 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe
|
||||
} else {
|
||||
pos = timelined.getTags().size();
|
||||
}
|
||||
//timelined.addTag(pos++, rm);
|
||||
|
||||
timelined.addTag(pos++, place);
|
||||
}
|
||||
|
||||
@@ -910,7 +944,10 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe
|
||||
|
||||
DepthState ds = null;
|
||||
|
||||
if (fframe >= timelined.getFrameCount()) {
|
||||
if (!(timelined instanceof ButtonTag) && fframe >= timelined.getFrameCount()) {
|
||||
if (timelined instanceof ButtonTag) {
|
||||
|
||||
}
|
||||
int lastFrame = timelined.getFrameCount() - 1;
|
||||
for (int d = 1; d <= timeline.maxDepth; d++) {
|
||||
ds = timeline.getDepthState(lastFrame, d);
|
||||
@@ -931,30 +968,41 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe
|
||||
timelined.resetTimeline();
|
||||
}
|
||||
|
||||
int nonEmptyFrame = -1;
|
||||
for (int f = fframe - 1; f >= 0; f--) {
|
||||
ds = timeline.getDepthState(f, fdepth);
|
||||
if (ds != null && ds.getCharacter() != null) {
|
||||
nonEmptyFrame = f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PlaceObjectTypeTag place;
|
||||
try {
|
||||
place = (PlaceObjectTypeTag) ds.placeObjectTag.cloneTag();
|
||||
} catch (InterruptedException | IOException ex) {
|
||||
//should not happen
|
||||
return;
|
||||
if (timelined instanceof ButtonTag) {
|
||||
ButtonTag button = (ButtonTag) timelined;
|
||||
BUTTONRECORD rec = button.getButtonRecordAt(nonEmptyFrame, fdepth, false);
|
||||
BUTTONRECORD rec2 = new BUTTONRECORD(rec.getSwf(), rec.getTag());
|
||||
rec2.fromPlaceObject(rec.toPlaceObject());
|
||||
rec2.setFrame(fframe, true);
|
||||
button.getRecords().add(rec2);
|
||||
|
||||
} else {
|
||||
PlaceObjectTypeTag place;
|
||||
try {
|
||||
place = (PlaceObjectTypeTag) ds.placeObjectTag.cloneTag();
|
||||
} catch (InterruptedException | IOException ex) {
|
||||
//should not happen
|
||||
return;
|
||||
}
|
||||
place.setTimelined(timelined);
|
||||
place.setPlaceFlagMove(false);
|
||||
ShowFrameTag sf = timeline.getFrame(fframe).showFrameTag;
|
||||
int pos;
|
||||
if (sf != null) {
|
||||
pos = timelined.indexOfTag(sf);
|
||||
} else {
|
||||
pos = timelined.getTags().size();
|
||||
}
|
||||
timelined.addTag(pos++, place);
|
||||
}
|
||||
place.setTimelined(timelined);
|
||||
place.setPlaceFlagMove(false);
|
||||
ShowFrameTag sf = timeline.getFrame(fframe).showFrameTag;
|
||||
int pos;
|
||||
if (sf != null) {
|
||||
pos = timelined.indexOfTag(sf);
|
||||
} else {
|
||||
pos = timelined.getTags().size();
|
||||
}
|
||||
timelined.addTag(pos++, place);
|
||||
|
||||
timelined.resetTimeline();
|
||||
timeline = timelined.getTimeline();
|
||||
@@ -990,14 +1038,17 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe
|
||||
DepthState ds;
|
||||
Timelined timelined = timeline.timelined;
|
||||
|
||||
//for (int nf = 0; nf < fendFrame - fframe + 1; nf++) {
|
||||
// for (int nd = fdepth; nd <= fendDepth; nd++)
|
||||
for (Point p : orderedCursor) {
|
||||
int nf = p.x;
|
||||
int nd = p.y;
|
||||
|
||||
|
||||
if (nf >= timelined.getFrameCount()) {
|
||||
|
||||
if (timelined instanceof ButtonTag) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ReadOnlyTagList tags = timelined.getTags();
|
||||
for (int i = tags.size() - 1; i >= 0; i--) {
|
||||
Tag t = tags.get(i);
|
||||
@@ -1042,9 +1093,13 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe
|
||||
}
|
||||
|
||||
boolean somethingAfter = false;
|
||||
Set<Integer> emptyFrames = new LinkedHashSet<>();
|
||||
if (timelined instanceof ButtonTag) {
|
||||
emptyFrames = ((ButtonTag) timelined).getEmptyFrames();
|
||||
}
|
||||
for (int f = nf + 1; f < timeline.getFrameCount(); f++) {
|
||||
ds = timeline.getDepthState(f, nd);
|
||||
boolean empty = ds == null || ds.getCharacter() == null;
|
||||
boolean empty = emptyFrames.contains(f) || ds == null || ds.getCharacter() == null;
|
||||
if (!empty) {
|
||||
somethingAfter = true;
|
||||
break;
|
||||
@@ -1053,10 +1108,29 @@ public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListe
|
||||
|
||||
for (int f = nf; f >= 0; f--) {
|
||||
ds = timeline.getDepthState(f, nd);
|
||||
boolean empty = ds == null || ds.getCharacter() == null;
|
||||
boolean empty = emptyFrames.contains(f) || ds == null || ds.getCharacter() == null;
|
||||
if (!empty || somethingAfter) {
|
||||
int moveFrameCount = somethingAfter ? 1 : nf - f;
|
||||
for (int mf = 0; mf < moveFrameCount; mf++) {
|
||||
|
||||
if (timelined instanceof ButtonTag) {
|
||||
ButtonTag button = (ButtonTag) timelined;
|
||||
if (!somethingAfter) {
|
||||
BUTTONRECORD rec = button.getButtonRecordAt(f, nd, true);
|
||||
rec.setFrame(nf - mf, true);
|
||||
} else {
|
||||
for (int fx = button.getFrameCount() - 1; fx >= nf; fx--) {
|
||||
BUTTONRECORD rec = button.getButtonRecordAt(fx, nd, false);
|
||||
if (rec != null) {
|
||||
rec.setFrame(fx, false);
|
||||
rec.setFrame(fx + 1, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
button.packRecords();
|
||||
continue;
|
||||
}
|
||||
|
||||
int pos = timelined.indexOfTag(timeline.getFrame(f).showFrameTag);
|
||||
ReadOnlyTagList tags = timelined.getTags();
|
||||
List<Tag> lastFrameDepthTags = new ArrayList<>();
|
||||
|
||||
@@ -18,7 +18,10 @@ package com.jpexs.decompiler.flash.easygui;
|
||||
|
||||
import com.jpexs.decompiler.flash.ReadOnlyTagList;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
|
||||
import com.jpexs.decompiler.flash.timeline.Timelined;
|
||||
import com.jpexs.decompiler.flash.types.BUTTONRECORD;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -31,6 +34,7 @@ public abstract class TimelinedTagListDoableOperation implements DoableOperation
|
||||
|
||||
private final Timelined timelined;
|
||||
protected List<Tag> tags;
|
||||
protected List<BUTTONRECORD> buttonRecords;
|
||||
protected boolean wasModified = false;
|
||||
protected int fframe;
|
||||
protected List<Integer> fdepths;
|
||||
@@ -53,10 +57,26 @@ public abstract class TimelinedTagListDoableOperation implements DoableOperation
|
||||
}
|
||||
|
||||
protected void saveTagList() {
|
||||
tags = timelined.getTags().toArrayList();
|
||||
if (timelined instanceof ButtonTag) {
|
||||
List<BUTTONRECORD> recordsCopy = new ArrayList<>();
|
||||
for (BUTTONRECORD rec :((ButtonTag) timelined).getRecords()) {
|
||||
recordsCopy.add(new BUTTONRECORD(rec));
|
||||
}
|
||||
buttonRecords = recordsCopy;
|
||||
} else {
|
||||
tags = timelined.getTags().toArrayList();
|
||||
}
|
||||
}
|
||||
|
||||
protected void restoreTagList() {
|
||||
protected void restoreTagList() {
|
||||
if (buttonRecords != null) {
|
||||
if (timelined instanceof ButtonTag) {
|
||||
ButtonTag button = (ButtonTag) timelined;
|
||||
button.getRecords().clear();
|
||||
button.getRecords().addAll(buttonRecords);
|
||||
}
|
||||
timelined.resetTimeline();
|
||||
}
|
||||
if (tags != null) {
|
||||
ReadOnlyTagList newTags = timelined.getTags();
|
||||
int size = newTags.size();
|
||||
|
||||
@@ -3454,6 +3454,9 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
|
||||
|
||||
BoundedTag bounded = (BoundedTag) timelined;
|
||||
RECT rect = bounded.getRect();
|
||||
if (rect == null) {
|
||||
return;
|
||||
}
|
||||
int width = rect.getWidth();
|
||||
double scale = 1.0;
|
||||
/*if (width > swf.displayRect.getWidth()) {
|
||||
@@ -4140,6 +4143,10 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
|
||||
return;
|
||||
}
|
||||
RECT timRect = timelined.getRect();
|
||||
|
||||
if (timRect == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
int h_value = horizontalScrollBar.getValue();
|
||||
@@ -4813,6 +4820,9 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
|
||||
Matrix parentMatrix = new Matrix();
|
||||
for (int i = 0; i < parentTimelineds.size(); i++) {
|
||||
DepthState parentDepthState = parentTimelineds.get(i).getTimeline().getDepthState(parentFrames.get(i), parentDepths.get(i));
|
||||
if (parentDepthState == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
parentMatrix = parentMatrix.concatenate(new Matrix(parentDepthState.matrix));
|
||||
}
|
||||
@@ -4851,7 +4861,11 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
|
||||
|
||||
for (int i = 0; i < selectedDepths.size(); i++) {
|
||||
if (newMatrix != null) {
|
||||
DepthState ds = timeline.getFrame(frame).layers.get(selectedDepths.get(i));
|
||||
Frame fr = timeline.getFrame(frame);
|
||||
if (fr == null) {
|
||||
continue;
|
||||
}
|
||||
DepthState ds = fr.layers.get(selectedDepths.get(i));
|
||||
if (ds != null) {
|
||||
ds.temporaryMatrix = newMatrix.concatenate(new Matrix(ds.matrix)).toMATRIX();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user