Added #1465 Configuration option to disable SWF preview autoplay

This commit is contained in:
Jindra Petřík
2022-11-07 23:32:17 +01:00
parent 9267c0dcea
commit 90e01246cd
10 changed files with 129 additions and 38 deletions

View File

@@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
- [#1755] Copy tags to tag clipboard and paste them elsewhere
- [#1460] Bulk importing images
- Bulk importing scripts/text/images added to SWF context menu
- [#1465] Configuration option to disable SWF preview autoplay
### Fixed
- FLA export printing xxx string on exporting character with id 320
@@ -2520,6 +2521,7 @@ All notable changes to this project will be documented in this file.
[#1414]: https://www.free-decompiler.com/flash/issues/1414
[#1755]: https://www.free-decompiler.com/flash/issues/1755
[#1460]: https://www.free-decompiler.com/flash/issues/1460
[#1465]: https://www.free-decompiler.com/flash/issues/1465
[#1862]: https://www.free-decompiler.com/flash/issues/1862
[#1459]: https://www.free-decompiler.com/flash/issues/1459
[#1832]: https://www.free-decompiler.com/flash/issues/1832

View File

@@ -759,7 +759,11 @@ public final class Configuration {
@ConfigurationDefaultBoolean(true)
@ConfigurationCategory("ui")
public static ConfigurationItem<Boolean> showImportImageInfo = null;
@ConfigurationDefaultBoolean(true)
@ConfigurationCategory("display")
public static ConfigurationItem<Boolean> autoPlaySwfs = null;
private enum OSId {
WINDOWS, OSX, UNIX
}

View File

@@ -68,6 +68,7 @@ import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.SystemColor;
import java.awt.Toolkit;
import java.awt.Transparency;
import java.awt.event.ComponentAdapter;
@@ -82,6 +83,7 @@ import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
@@ -89,8 +91,10 @@ import java.awt.image.VolatileImage;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
@@ -101,6 +105,14 @@ import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.event.MouseInputAdapter;
import org.pushingpixels.substance.api.ColorSchemeAssociationKind;
import org.pushingpixels.substance.api.ComponentState;
import org.pushingpixels.substance.api.DecorationAreaType;
import org.pushingpixels.substance.api.SubstanceConstants;
import org.pushingpixels.substance.api.SubstanceLookAndFeel;
import org.pushingpixels.substance.api.SubstanceSkin;
import org.pushingpixels.substance.api.painter.border.StandardBorderPainter;
import org.pushingpixels.substance.internal.utils.SubstanceOutlineUtilities;
/**
*
@@ -222,15 +234,59 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
private ExportRectangle _viewRect = new ExportRectangle(0, 0, 1, 1);
private boolean playing = false;
private boolean playing = false;
private boolean autoPlayed = false;
private static Cursor loadCursor(String name, int x, int y) throws IOException {
Toolkit toolkit = Toolkit.getDefaultToolkit();
Image image = ImageIO.read(MainPanel.class.getResource("/com/jpexs/decompiler/flash/gui/graphics/cursors/" + name + ".png"));
return toolkit.createCustomCursor(image, new Point(x, y), name);
}
private SerializableImage imgPlay = null;
private SerializableImage getImagePlay() {
if (imgPlay != null) {
return imgPlay;
}
Color bgColor;
if (Configuration.useRibbonInterface.get()) {
SubstanceSkin skin = SubstanceLookAndFeel.getCurrentSkin();
bgColor = (skin.getColorScheme(DecorationAreaType.HEADER, ColorSchemeAssociationKind.FILL, ComponentState.ENABLED).getBackgroundFillColor());
} else {
bgColor = SystemColor.control;
}
Color fgColor;
if (Configuration.useRibbonInterface.get()) {
SubstanceSkin skin = SubstanceLookAndFeel.getCurrentSkin();
fgColor = (skin.getColorScheme(DecorationAreaType.HEADER, ColorSchemeAssociationKind.FILL, ComponentState.ENABLED).getForegroundColor());
} else {
fgColor = SystemColor.controlText;
}
int size = 200;
imgPlay = new SerializableImage(size,size,BufferedImage.TYPE_INT_ARGB_PRE);
imgPlay.fillTransparent();
Graphics2D g2d = (Graphics2D) imgPlay.getGraphics();
g2d.setStroke(new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
GeneralPath path = new GeneralPath();
path.moveTo(0, 0);
path.lineTo(size, size/2);
path.lineTo(0, size);
path.closePath();
g2d.setComposite(AlphaComposite.SrcOver);
g2d.setPaint(new Color(fgColor.getRed(), fgColor.getGreen(), fgColor.getBlue(), fgColor.getAlpha() / 2));
g2d.fill(path);
g2d.setPaint(fgColor);
g2d.draw(path);
return imgPlay;
}
static {
static {
try {
moveCursor = loadCursor("move", 0, 0);
moveRegPointCursor = loadCursor("move_regpoint", 0, 0);
@@ -474,6 +530,11 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
if (e.getButton() == MouseEvent.BUTTON1) {
mouseMoved(e); //to correctly calculate mode, because moseMoved event is not called during dragging
setDragStart(e.getPoint());
if (!autoPlayed) {
autoPlayed = true;
play();
}
}
requestFocusInWindow();
}
@@ -1536,7 +1597,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
return zoomAvailable;
}
public void setTimelined(final Timelined drawable, final SWF swf, int frame, boolean showObjectsUnderCursor) {
public void setTimelined(final Timelined drawable, final SWF swf, int frame, boolean showObjectsUnderCursor, boolean autoPlay) {
Stage stage = new Stage(drawable) {
@Override
public void callFrame(int frame) {
@@ -1623,8 +1684,11 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
time = 0;
drawReady = false;
autoPlayed = autoPlay;
redraw();
play();
if (autoPlay) {
play();
}
}
synchronized (delayObject) {
@@ -2098,13 +2162,13 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
int mouseButton;
int selectedDepth;
Zoom zoom;
SWF swf;
SWF swf;
synchronized (ImagePanel.this) {
timelined = this.timelined;
lastMouseEvent = this.lastMouseEvent;
}
boolean shownAgain = false;
synchronized (ImagePanel.this) {
@@ -2170,7 +2234,20 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
Reference<Rectangle2D> boundsRef = new Reference<>(bounds);
_viewRect = getViewRect();
if (_viewRect.getHeight() < 0 || _viewRect.getWidth() < 0) {
if (!autoPlayed) {
img = new SerializableImage(
(int) (_viewRect.getWidth() / SWF.unitDivisor),
(int) (_viewRect.getHeight() / SWF.unitDivisor),
BufferedImage.TYPE_4BYTE_ABGR);
SerializableImage imgPlay = getImagePlay();
Graphics g = img.getGraphics();
int x = (int) (_viewRect.getWidth() / SWF.unitDivisor / 2 - imgPlay.getWidth() / 2);
int y = (int) (_viewRect.getHeight() / SWF.unitDivisor / 2 - imgPlay.getHeight() / 2);
g.drawImage(imgPlay.getBufferedImage(),
x,
y,
null);
} else if (_viewRect.getHeight() < 0 || _viewRect.getWidth() < 0) {
img = new SerializableImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR);
} else {
img = getFrame(_viewRect, swf, frame, time, timelined, renderContext, selectedDepth, freeTransformDepth, zoomDouble, registrationPointRef, boundsRef, transform, transformUpdated == null ? null : new Matrix(transformUpdated));
@@ -2192,7 +2269,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
}
}
if (!shownAgain) {
if (!shownAgain && !autoPlayed) {
List<Integer> sounds = new ArrayList<>();
List<String> soundClasses = new ArrayList<>();
List<SOUNDINFO> soundInfos = new ArrayList<>();
@@ -2232,16 +2309,16 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
StringBuilder ret = new StringBuilder();
if (cursorPosition != null) {
if (cursorPosition != null && !autoPlayed) {
ret.append(" [").append(cursorPosition.x).append(",").append(cursorPosition.y).append("]");
if (showObjectsUnderCursor) {
ret.append(" : ");
}
}
boolean handCursor = renderContext.mouseOverButton != null;
boolean handCursor = renderContext.mouseOverButton != null || !autoPlayed;
if (showObjectsUnderCursor) {
if (showObjectsUnderCursor && !autoPlayed) {
boolean first = true;
for (int i = renderContext.stateUnderCursor.size() - 1; i >= 0; i--) {
@@ -2376,6 +2453,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
@Override
public synchronized void play() {
this.autoPlayed = true;
stopInternal();
if (timelined != null) {
Timeline timeline = timelined.getTimeline();
@@ -2601,6 +2679,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
return;
}
this.autoPlayed = true;
this.frame = frame - 1;
this.prevFrame = -1;
stopInternal();

View File

@@ -4048,7 +4048,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
if (treeItem instanceof SWF) {
SWF swf = (SWF) treeItem;
if (internalViewer) {
previewPanel.showImagePanel(swf, swf, -1, true);
previewPanel.showImagePanel(swf, swf, -1, true, Configuration.autoPlaySwfs.get());
} else {
previewPanel.setParametersPanelVisible(false);
//if (flashPanel != null) { //same for flashPanel2
@@ -4072,7 +4072,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
ImageTag imageTag = (ImageTag) treeItem;
previewPanel.setImageReplaceButtonVisible(!((Tag) imageTag).isReadOnly() && imageTag.importSupported(), imageTag instanceof DefineBitsJPEG3Tag || imageTag instanceof DefineBitsJPEG4Tag, false, false);
SWF imageSWF = makeTimelinedImage(imageTag);
previewPanel.showImagePanel(imageSWF, imageSWF, 0, false);
previewPanel.showImagePanel(imageSWF, imageSWF, 0, false, true);
} else if ((treeItem instanceof DrawableTag) && (!(treeItem instanceof TextTag)) && (!(treeItem instanceof FontTag)) && internalViewer) {
final Tag tag = (Tag) treeItem;
@@ -4088,11 +4088,11 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
if (treeItem instanceof ShapeTag) {
previewPanel.setImageReplaceButtonVisible(false, false, !((Tag) treeItem).isReadOnly(), false);
}
previewPanel.showImagePanel(timelined, tag.getSwf(), -1, true);
previewPanel.showImagePanel(timelined, tag.getSwf(), -1, true, true);
} else if (treeItem instanceof Frame && internalViewer) {
Frame fn = (Frame) treeItem;
SWF swf = fn.getSwf();
previewPanel.showImagePanel(fn.timeline.timelined, swf, fn.frame, true);
previewPanel.showImagePanel(fn.timeline.timelined, swf, fn.frame, true, true);
} else if (treeItem instanceof ShowFrameTag) {
SWF swf;
if (timelinedContainer instanceof DefineSpriteTag) {
@@ -4100,7 +4100,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
} else {
swf = (SWF) timelinedContainer;
}
previewPanel.showImagePanel(timelinedContainer, swf, frame, true);
previewPanel.showImagePanel(timelinedContainer, swf, frame, true, true);
} else if ((treeItem instanceof SoundTag)) { //&& isInternalFlashViewerSelected() && (Arrays.asList("mp3", "wav").contains(((SoundTag) tagObj).getExportFormat())))) {
previewPanel.showImagePanel(new SerializableImage(View.loadImage("sound32")));
previewPanel.setImageReplaceButtonVisible(false, false, false, !((Tag) treeItem).isReadOnly() && (treeItem instanceof DefineSoundTag));

View File

@@ -581,11 +581,11 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
showCardLeft(FLASH_VIEWER_CARD);
}
public void showImagePanel(Timelined timelined, SWF swf, int frame, boolean showObjectsUnderCursor) {
public void showImagePanel(Timelined timelined, SWF swf, int frame, boolean showObjectsUnderCursor, boolean autoPlay) {
showCardLeft(DRAW_PREVIEW_CARD);
parametersPanel.setVisible(false);
imagePlayControls.setMedia(imagePanel);
imagePanel.setTimelined(timelined, swf, frame, showObjectsUnderCursor);
imagePanel.setTimelined(timelined, swf, frame, showObjectsUnderCursor, autoPlay);
}
public void showImagePanel(SerializableImage image) {
@@ -623,7 +623,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
private void showFontPage(FontTag fontTag) {
if (!mainPanel.isAdobeFlashPlayerEnabled() /*|| ft instanceof GFxDefineCompactedFont*/) {
showImagePanel(MainPanel.makeTimelined(fontTag), fontTag.getSwf(), fontPageNum, true);
showImagePanel(MainPanel.makeTimelined(fontTag), fontTag.getSwf(), fontPageNum, true, true);
}
}
@@ -641,7 +641,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
public void showTextPanel(TextTag textTag) {
if (!mainPanel.isAdobeFlashPlayerEnabled() /*|| ft instanceof GFxDefineCompactedFont*/) {
showImagePanel(MainPanel.makeTimelined(textTag), textTag.getSwf(), 0, true);
showImagePanel(MainPanel.makeTimelined(textTag), textTag.getSwf(), 0, true, true);
}
showCardRight(CARDTEXTPANEL);
@@ -741,7 +741,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
placeGenericPanel.setVisible(!readOnly);
placeGenericPanel.setEditMode(false, tag);
placeImagePanel.selectDepth(-1);
placeImagePanel.setTimelined(((Tag) tag).getTimelined(), ((Tag) tag).getSwf(), frame, true);
placeImagePanel.setTimelined(((Tag) tag).getTimelined(), ((Tag) tag).getSwf(), frame, true, true);
placeImagePanel.selectDepth(tag.getDepth());
parametersPanel.setVisible(false);
placeEditButton.setVisible(!tag.isReadOnly() && !readOnly);
@@ -1034,7 +1034,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
int pageCount = getFontPageCount(fontTag);
fontPageNum = (fontPageNum + pageCount - 1) % pageCount;
if (!mainPanel.isAdobeFlashPlayerEnabled() /*|| ft instanceof GFxDefineCompactedFont*/) {
imagePanel.setTimelined(MainPanel.makeTimelined(fontTag, fontPageNum), fontTag.getSwf(), 0, true);
imagePanel.setTimelined(MainPanel.makeTimelined(fontTag, fontPageNum), fontTag.getSwf(), 0, true, true);
}
}
@@ -1043,7 +1043,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
int pageCount = getFontPageCount(fontTag);
fontPageNum = (fontPageNum + 1) % pageCount;
if (!mainPanel.isAdobeFlashPlayerEnabled() /*|| ft instanceof GFxDefineCompactedFont*/) {
imagePanel.setTimelined(MainPanel.makeTimelined(fontTag, fontPageNum), fontTag.getSwf(), 0, true);
imagePanel.setTimelined(MainPanel.makeTimelined(fontTag, fontPageNum), fontTag.getSwf(), 0, true, true);
}
}

View File

@@ -477,9 +477,9 @@ public class SelectTagPositionDialog extends AppDialog {
int f = ((MyFrame) tnode.getData()).frame;
Object parent = ((MyTreeNode) tnode.getParent()).getData();
if (parent instanceof DefineSpriteTag) {
previewPanel.showImagePanel((DefineSpriteTag) parent, swf, f - 1, true);
previewPanel.showImagePanel((DefineSpriteTag) parent, swf, f - 1, true, true);
} else {
previewPanel.showImagePanel(swf, swf, f - 1, true);
previewPanel.showImagePanel(swf, swf, f - 1, true, true);
}
} else {
previewPanel.showEmpty();

View File

@@ -729,22 +729,22 @@ public class AddScriptDialog extends AppDialog {
int f = ((MyFrame) ((MyTreeNode) tnode.getParent()).getData()).frame;
Object parent = ((MyTreeNode) tnode.getParent().getParent()).getData();
if (parent instanceof DefineSpriteTag) {
instancePreviewPanel.showImagePanel((DefineSpriteTag) parent, swf, f - 1, true);
instancePreviewPanel.showImagePanel((DefineSpriteTag) parent, swf, f - 1, true, true);
} else {
instancePreviewPanel.showImagePanel(swf, swf, f - 1, true);
instancePreviewPanel.showImagePanel(swf, swf, f - 1, true, true);
}
} else if (tnode.getData() instanceof DefineSpriteTag) {
instancePreviewPanel.selectImageDepth(-1);
instancePreviewPanel.showImagePanel((DefineSpriteTag) tnode.getData(), swf, -1, true);
instancePreviewPanel.showImagePanel((DefineSpriteTag) tnode.getData(), swf, -1, true, true);
} else if (tnode.getData() instanceof MyFrame) {
instancePreviewPanel.selectImageDepth(-1);
int f = ((MyFrame) tnode.getData()).frame;
Object parent = ((MyTreeNode) tnode.getParent()).getData();
if (parent instanceof DefineSpriteTag) {
instancePreviewPanel.showImagePanel((DefineSpriteTag) parent, swf, f - 1, true);
instancePreviewPanel.showImagePanel((DefineSpriteTag) parent, swf, f - 1, true, true);
} else {
instancePreviewPanel.showImagePanel(swf, swf, f - 1, true);
instancePreviewPanel.showImagePanel(swf, swf, f - 1, true, true);
}
}
checkEnabled();
@@ -758,7 +758,7 @@ public class AddScriptDialog extends AppDialog {
checkEnabled();
return;
}
spriteInitPreviewPanel.showImagePanel(spriteInitList.getSelectedValue(), swf, -1, true);
spriteInitPreviewPanel.showImagePanel(spriteInitList.getSelectedValue(), swf, -1, true, true);
checkEnabled();
}
@@ -770,7 +770,7 @@ public class AddScriptDialog extends AppDialog {
checkEnabled();
return;
}
framePreviewPanel.showImagePanel(swf, swf, selectedIndex, true);
framePreviewPanel.showImagePanel(swf, swf, selectedIndex, true, true);
int f = selectedIndex + 1;
if (!frameTextField.getText().equals("" + f)) {
@@ -782,7 +782,7 @@ public class AddScriptDialog extends AppDialog {
private void buttonValueChanged(ListSelectionEvent e) {
buttonPreviewPanel.showEmpty();
if (buttonList.getSelectedIndex() >= 0) {
buttonPreviewPanel.showImagePanel(MainPanel.makeTimelined(buttonList.getSelectedValue()), swf, -1, true);
buttonPreviewPanel.showImagePanel(MainPanel.makeTimelined(buttonList.getSelectedValue()), swf, -1, true, true);
}
checkEnabled();
@@ -798,14 +798,14 @@ public class AddScriptDialog extends AppDialog {
}
MyTreeNode tnode = (MyTreeNode) selection.getLastPathComponent();
if (tnode.getData() instanceof DefineSpriteTag) {
spriteFramePreviewPanel.showImagePanel((DefineSpriteTag) tnode.getData(), swf, -1, true);
spriteFramePreviewPanel.showImagePanel((DefineSpriteTag) tnode.getData(), swf, -1, true, true);
} else if (tnode.getData() instanceof MyFrame) {
int f = ((MyFrame) tnode.getData()).frame;
Object parent = ((MyTreeNode) tnode.getParent()).getData();
if (parent instanceof DefineSpriteTag) {
spriteFramePreviewPanel.showImagePanel((DefineSpriteTag) parent, swf, f - 1, true);
spriteFramePreviewPanel.showImagePanel((DefineSpriteTag) parent, swf, f - 1, true, true);
} else {
spriteFramePreviewPanel.showImagePanel(swf, swf, f - 1, true);
spriteFramePreviewPanel.showImagePanel(swf, swf, f - 1, true, true);
}
if (!spriteFrameTextField.getText().equals("" + f)) {
spriteFrameTextField.setText("" + f);

View File

@@ -578,3 +578,6 @@ config.description.warningOpeningReadOnly = Show warning when opening SWF from r
config.name.showImportImageInfo = Show information before importing images
config.description.showImportImageInfo = Displays some info about how importing images works after clicking Import images in the menu.
config.name.autoPlaySwfs = Autoplay SWF previews
config.description.autoPlaySwfs = Automatically play SWF preview on SWF node selection.

View File

@@ -564,3 +564,6 @@ config.description.warningOpeningReadOnly = Zobrazovat varov\u00e1n\u00ed p\u015
# after 16.1.0
config.name.showImportImageInfo = Zobrazit informaci p\u0159ed importem obr\u00e1zk\u016f
config.description.showImportImageInfo = Zobraz\u00ed n\u011bjak\u00e9 informace o tom jak import obr\u00e1zk\u016f funguje po kliku na import obr\u00e1zk\u016f v menu.
config.name.autoPlaySwfs = Automaticky p\u0159ehr\u00e1vat n\u00e1hledy SWF
config.description.autoPlaySwfs = Automaticicky p\u0159ehr\u00e1vat n\u00e1hled SWF p\u0159i v\u00fdb\u011bru SWF polo\u017eky.

View File

@@ -49,7 +49,7 @@ public class TimelineViewPanel extends JPanel {
timeline.setTimelined(timelined);
add(new JPersistentSplitPane(JSplitPane.HORIZONTAL_SPLIT, timeline, previewPanel = new ImagePanel(), Configuration.guiTimeLineSplitPaneDividerLocationPercent));
previewPanel.setTimelined(timelined, timelined.getTimeline().swf, 0, true);
previewPanel.setTimelined(timelined, timelined.getTimeline().swf, 0, true, true);
//previewPanel.setPreferredSize(new Dimension(400,300));
previewPanel.pause();
previewPanel.gotoFrame(0);