diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b64219cd..429797e01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ All notable changes to this project will be documented in this file. - [#1564], [#1676], [#1697], [#1893] Display of DefineVideoStream tags with VLC player - List of treenode subitems on otherwise empty panel (with 32x32 icons) - DefineVideoStream codecId and videoFlagsDeblocking handled as enums in raw editation +- Option to mute frame sounds ### Fixed - [#1897] Close menu button without selecting specific item diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java index a779a8222..87770cb7d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java @@ -823,6 +823,10 @@ public final class Configuration { @ConfigurationCategory("display") public static ConfigurationItem warningVideoVlc = null; + @ConfigurationDefaultBoolean(true) + @ConfigurationCategory("display") + public static ConfigurationItem playFrameSounds = null; + private enum OSId { WINDOWS, OSX, UNIX } diff --git a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java index 9fa369e45..9bc40ef1d 100644 --- a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java +++ b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java @@ -231,12 +231,16 @@ 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 boolean frozen = false; - + + private boolean muted = false; + + private boolean mutable = false; + private boolean alwaysDisplay = false; private static Cursor loadCursor(String name, int x, int y) throws IOException { @@ -244,15 +248,14 @@ public final class ImagePanel extends JPanel implements MediaDisplay { 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(); @@ -261,33 +264,33 @@ public final class ImagePanel extends JPanel implements MediaDisplay { bgColor = SystemColor.control; } Color fgColor; - if (Configuration.useRibbonInterface.get()) { + 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 = 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(size, size / 2); path.lineTo(0, size); - path.closePath(); + 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.setPaint(fgColor); g2d.draw(path); - + return imgPlay; } - static { + static { try { moveCursor = loadCursor("move", 0, 0); moveRegPointCursor = loadCursor("move_regpoint", 0, 0); @@ -422,7 +425,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay { public void setFrozen(boolean value) { this.frozen = value; } - + @Override public boolean isDisplayed() { return autoPlayed; @@ -432,8 +435,16 @@ public final class ImagePanel extends JPanel implements MediaDisplay { public boolean alwaysDisplay() { return alwaysDisplay; } - - + + @Override + public void setMuted(boolean value) { + this.muted = value; + if (value) { + stopAllSounds(); + } else { + prevFrame = -1; //initiate refreshing frame to play sounds again + } + } private class IconPanel extends JPanel { @@ -554,7 +565,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay { if (SwingUtilities.isLeftMouseButton(e)) { mouseMoved(e); //to correctly calculate mode, because moseMoved event is not called during dragging setDragStart(e.getPoint()); - + if (!autoPlayed) { Configuration.autoPlayPreviews.set(true); autoPlayed = true; @@ -1253,21 +1264,21 @@ public final class ImagePanel extends JPanel implements MediaDisplay { } } - private Rectangle calcRect(Zoom z) { + private Rectangle calcRect(Zoom z) { synchronized (ImagePanel.this) { - if (_img != null || timelined != null) { + if (_img != null || timelined != null) { //int w1 = (int) (_img.getWidth() * (lowQuality ? LQ_FACTOR : 1)); //int h1 = (int) (_img.getHeight() * (lowQuality ? LQ_FACTOR : 1)); double zoomDouble = z.fit ? getZoomToFit() : z.value; int w1; int h1; - if (timelined == null || (!autoPlayed && _img != null)) { + if (timelined == null || (!autoPlayed && _img != null)) { w1 = (int) (_img.getWidth() * (lowQuality ? LQ_FACTOR : 1)); - h1 = (int) (_img.getHeight() * (lowQuality ? LQ_FACTOR : 1)); + h1 = (int) (_img.getHeight() * (lowQuality ? LQ_FACTOR : 1)); } else { w1 = (int) (timelined.getRectWithStrokes().getWidth() * zoomDouble / SWF.unitDivisor); h1 = (int) (timelined.getRectWithStrokes().getHeight() * zoomDouble / SWF.unitDivisor); - } + } int w2 = getWidth(); int h2 = getHeight(); @@ -1443,7 +1454,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay { ButtonTag button = iconPanel.mouseOverButton; if (button != null && freeTransformDepth == -1) { DefineButtonSoundTag sounds = button.getSounds(); - if (sounds != null && sounds.buttonSoundChar2 != 0) { // OverUpToOverDown + if (!muted && sounds != null && sounds.buttonSoundChar2 != 0) { // OverUpToOverDown playSound((SoundTag) swf.getCharacter(sounds.buttonSoundChar2), sounds.buttonSoundInfo2, timer); } List actions = new ArrayList<>(); @@ -1483,7 +1494,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay { lastMouseEvent = e; redraw(); ButtonTag button = iconPanel.mouseOverButton; - if (button != null && freeTransformDepth == -1) { + if (!muted && button != null && freeTransformDepth == -1) { DefineButtonSoundTag sounds = button.getSounds(); if (sounds != null && sounds.buttonSoundChar3 != 0) { // OverDownToOverUp playSound((SoundTag) swf.getCharacter(sounds.buttonSoundChar3), sounds.buttonSoundInfo3, timer); @@ -1624,7 +1635,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay { return zoomAvailable; } - public void setTimelined(final Timelined drawable, final SWF swf, int frame, boolean showObjectsUnderCursor, boolean autoPlay, boolean frozen, boolean alwaysDisplay) { + public void setTimelined(final Timelined drawable, final SWF swf, int frame, boolean showObjectsUnderCursor, boolean autoPlay, boolean frozen, boolean alwaysDisplay, boolean muted, boolean mutable) { Stage stage = new Stage(drawable) { @Override public void callFrame(int frame) { @@ -1714,11 +1725,13 @@ public final class ImagePanel extends JPanel implements MediaDisplay { autoPlayed = autoPlay; this.alwaysDisplay = alwaysDisplay; this.frozen = frozen; + this.muted = muted; + this.mutable = mutable; this.showObjectsUnderCursor = showObjectsUnderCursor; redraw(); - if (autoPlay) { + if (autoPlay) { play(); - } + } } synchronized (delayObject) { @@ -1734,7 +1747,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay { clearImagePanel(); } } - + fireMediaDisplayStateChanged(); } @@ -1884,7 +1897,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay { fireMediaDisplayStateChanged(); } - private static SerializableImage getFrame(ExportRectangle viewRect, SWF swf, int frame, int time, Timelined drawable, RenderContext renderContext, int selectedDepth, int freeTransformDepth, double zoom, Reference registrationPointRef, Reference boundsRef, Matrix transform, Matrix temporaryMatrix) { + private static SerializableImage getFrame(ExportRectangle viewRect, SWF swf, int frame, int time, Timelined drawable, RenderContext renderContext, int selectedDepth, int freeTransformDepth, double zoom, Reference registrationPointRef, Reference boundsRef, Matrix transform, Matrix temporaryMatrix) { Timeline timeline = drawable.getTimeline(); SerializableImage img; RECT rect = drawable.getRect(); @@ -2183,13 +2196,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) { @@ -2255,8 +2268,9 @@ public final class ImagePanel extends JPanel implements MediaDisplay { Reference boundsRef = new Reference<>(bounds); _viewRect = getViewRect(); - if (!autoPlayed) { - img = getImagePlay(); /*new SerializableImage( + if (!autoPlayed) { + img = getImagePlay(); + /*new SerializableImage( (int) (_viewRect.getWidth() / SWF.unitDivisor), (int) (_viewRect.getHeight() / SWF.unitDivisor), BufferedImage.TYPE_4BYTE_ABGR); @@ -2291,34 +2305,36 @@ public final class ImagePanel extends JPanel implements MediaDisplay { } if (!shownAgain && autoPlayed) { - List sounds = new ArrayList<>(); - List soundClasses = new ArrayList<>(); - List soundInfos = new ArrayList<>(); - timeline.getSounds(frame, time, renderContext.mouseOverButton, mouseButton, sounds, soundClasses, soundInfos); - for (int cid : swf.getCharacters().keySet()) { - CharacterTag c = swf.getCharacter(cid); - for (int k = 0; k < soundClasses.size(); k++) { - String cls = soundClasses.get(k); - if (cls == null) { + if (!muted) { + List sounds = new ArrayList<>(); + List soundClasses = new ArrayList<>(); + List soundInfos = new ArrayList<>(); + timeline.getSounds(frame, time, renderContext.mouseOverButton, mouseButton, sounds, soundClasses, soundInfos); + for (int cid : swf.getCharacters().keySet()) { + CharacterTag c = swf.getCharacter(cid); + for (int k = 0; k < soundClasses.size(); k++) { + String cls = soundClasses.get(k); + if (cls == null) { + continue; + } + if (cls.equals(c.getClassName())) { + sounds.set(k, cid); + } + } + } + + for (int s = 0; s < sounds.size(); s++) { + int sndId = sounds.get(s); + if (sndId == -1) { continue; } - if (cls.equals(c.getClassName())) { - sounds.set(k, cid); + CharacterTag c = swf.getCharacter(sndId); + if (c instanceof SoundTag) { + SoundTag st = (SoundTag) c; + playSound(st, soundInfos.get(s), thisTimer); } } } - - for (int s = 0; s < sounds.size(); s++) { - int sndId = sounds.get(s); - if (sndId == -1) { - continue; - } - CharacterTag c = swf.getCharacter(sndId); - if (c instanceof SoundTag) { - SoundTag st = (SoundTag) c; - playSound(st, soundInfos.get(s), thisTimer); - } - } executeFrame(frame); } } catch (Throwable ex) { @@ -2396,22 +2412,24 @@ public final class ImagePanel extends JPanel implements MediaDisplay { } ); - if (lastMouseOverButton != renderContext.mouseOverButton) { - ButtonTag b = renderContext.mouseOverButton; - if (b != null && freeTransformDepth == -1) { - // New mouse entered - DefineButtonSoundTag sounds = b.getSounds(); - if (sounds != null && sounds.buttonSoundChar1 != 0) { // IdleToOverUp - playSound((SoundTag) swf.getCharacter(sounds.buttonSoundChar1), sounds.buttonSoundInfo1, timer); + if (!muted) { + if (lastMouseOverButton != renderContext.mouseOverButton) { + ButtonTag b = renderContext.mouseOverButton; + if (b != null && freeTransformDepth == -1) { + // New mouse entered + DefineButtonSoundTag sounds = b.getSounds(); + if (sounds != null && sounds.buttonSoundChar1 != 0) { // IdleToOverUp + playSound((SoundTag) swf.getCharacter(sounds.buttonSoundChar1), sounds.buttonSoundInfo1, timer); + } } - } - b = lastMouseOverButton; - if (b != null && freeTransformDepth == -1) { - // Old mouse leave - DefineButtonSoundTag sounds = b.getSounds(); - if (sounds != null && sounds.buttonSoundChar0 != 0) { // OverUpToIdle - playSound((SoundTag) swf.getCharacter(sounds.buttonSoundChar0), sounds.buttonSoundInfo0, timer); + b = lastMouseOverButton; + if (b != null && freeTransformDepth == -1) { + // Old mouse leave + DefineButtonSoundTag sounds = b.getSounds(); + if (sounds != null && sounds.buttonSoundChar0 != 0) { // OverUpToIdle + playSound((SoundTag) swf.getCharacter(sounds.buttonSoundChar0), sounds.buttonSoundInfo0, timer); + } } } } @@ -2467,7 +2485,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay { timelined = null; swf = null; lda = null; - showObjectsUnderCursor = false; + showObjectsUnderCursor = false; fireMediaDisplayStateChanged(); } @@ -2806,4 +2824,9 @@ public final class ImagePanel extends JPanel implements MediaDisplay { } zoom(newZoom); } + + @Override + public boolean isMutable() { + return mutable; + } } diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index 7728a279b..a382023ae 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -4631,7 +4631,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, Configuration.autoPlaySwfs.get() && Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false); + previewPanel.showImagePanel(swf, swf, -1, true, Configuration.autoPlaySwfs.get() && Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false, !Configuration.playFrameSounds.get(), true); } else { previewPanel.setParametersPanelVisible(false); //if (flashPanel != null) { //same for flashPanel2 @@ -4658,7 +4658,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, true, true, true); + previewPanel.showImagePanel(imageSWF, imageSWF, 0, false, true, true, true, true, false); } else if (!isVideoButNotDrawable && (treeItem instanceof DrawableTag) && (!(treeItem instanceof TextTag)) && (!(treeItem instanceof FontTag)) && internalViewer) { final Tag tag = (Tag) treeItem; @@ -4674,11 +4674,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, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), treeItem instanceof ShapeTag); + previewPanel.showImagePanel(timelined, tag.getSwf(), -1, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), treeItem instanceof ShapeTag, !Configuration.playFrameSounds.get(), (treeItem instanceof DefineSpriteTag)||(treeItem instanceof ButtonTag)); } else if (treeItem instanceof Frame && internalViewer) { Frame fn = (Frame) treeItem; SWF swf = (SWF) fn.getOpenable(); - previewPanel.showImagePanel(fn.timeline.timelined, swf, fn.frame, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false); + previewPanel.showImagePanel(fn.timeline.timelined, swf, fn.frame, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false, !Configuration.playFrameSounds.get(), true); } else if (treeItem instanceof ShowFrameTag) { SWF swf; if (timelinedContainer instanceof DefineSpriteTag) { @@ -4686,7 +4686,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } else { swf = (SWF) timelinedContainer; } - previewPanel.showImagePanel(timelinedContainer, swf, frame, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false); + previewPanel.showImagePanel(timelinedContainer, swf, frame, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false, !Configuration.playFrameSounds.get(), 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)); @@ -4776,7 +4776,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se ShowFrameTag showFrameTag = new ShowFrameTag(swf); swf.addTag(showFrameTag); showFrameTag.setTimelined(swf); - previewPanel.showImagePanel(swf, swf, 0, true, true, !Configuration.animateSubsprites.get(), false); + previewPanel.showImagePanel(swf, swf, 0, true, true, !Configuration.animateSubsprites.get(), false, !Configuration.playFrameSounds.get(), true); } else { previewPanel.showEmpty(); } diff --git a/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java b/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java index 4a29beb34..10b9667d2 100644 --- a/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java @@ -686,11 +686,11 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel showCardLeft(FLASH_VIEWER_CARD); } - public void showImagePanel(Timelined timelined, SWF swf, int frame, boolean showObjectsUnderCursor, boolean autoPlay, boolean frozen, boolean alwaysDisplay) { + public void showImagePanel(Timelined timelined, SWF swf, int frame, boolean showObjectsUnderCursor, boolean autoPlay, boolean frozen, boolean alwaysDisplay, boolean muted, boolean mutable) { showCardLeft(DRAW_PREVIEW_CARD); parametersPanel.setVisible(false); imagePlayControls.setMedia(imagePanel); - imagePanel.setTimelined(timelined, swf, frame, showObjectsUnderCursor, autoPlay, frozen, alwaysDisplay); + imagePanel.setTimelined(timelined, swf, frame, showObjectsUnderCursor, autoPlay, frozen, alwaysDisplay, muted, mutable); } public void showImagePanel(SerializableImage image) { @@ -728,7 +728,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, true, true, true); + showImagePanel(MainPanel.makeTimelined(fontTag), fontTag.getSwf(), fontPageNum, true, true, true, true, true, false); } } @@ -746,7 +746,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, true, true, true); + showImagePanel(MainPanel.makeTimelined(textTag), textTag.getSwf(), 0, true, true, true, true, true, false); } showCardRight(CARDTEXTPANEL); @@ -891,7 +891,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, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false); + placeImagePanel.setTimelined(((Tag) tag).getTimelined(), ((Tag) tag).getSwf(), frame, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false, !Configuration.playFrameSounds.get(), true); placeImagePanel.selectDepth(tag.getDepth()); parametersPanel.setVisible(false); placeEditButton.setVisible(!tag.isReadOnly() && !readOnly); @@ -1189,7 +1189,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, true, true, true); + imagePanel.setTimelined(MainPanel.makeTimelined(fontTag, fontPageNum), fontTag.getSwf(), 0, true, true, true, true, true, false); } } @@ -1198,7 +1198,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, true, true, true); + imagePanel.setTimelined(MainPanel.makeTimelined(fontTag, fontPageNum), fontTag.getSwf(), 0, true, true, true, true, true, false); } } diff --git a/src/com/jpexs/decompiler/flash/gui/SelectTagPositionDialog.java b/src/com/jpexs/decompiler/flash/gui/SelectTagPositionDialog.java index 2cc61fbc2..19543fc2c 100644 --- a/src/com/jpexs/decompiler/flash/gui/SelectTagPositionDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/SelectTagPositionDialog.java @@ -478,9 +478,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, true, !Configuration.animateSubsprites.get(), false); + previewPanel.showImagePanel((DefineSpriteTag) parent, swf, f - 1, true, true, !Configuration.animateSubsprites.get(), false, !Configuration.playFrameSounds.get(), true); } else { - previewPanel.showImagePanel(swf, swf, f - 1, true, true, !Configuration.animateSubsprites.get(), false); + previewPanel.showImagePanel(swf, swf, f - 1, true, true, !Configuration.animateSubsprites.get(), false, !Configuration.playFrameSounds.get(), true); } } else { previewPanel.showEmpty(); diff --git a/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java b/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java index 2e742d17e..c20f9178d 100644 --- a/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java +++ b/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java @@ -514,6 +514,14 @@ public class SoundTagPlayer implements MediaDisplay { public boolean alwaysDisplay() { return true; } - - + + @Override + public void setMuted(boolean value) { + + } + + @Override + public boolean isMutable() { + return true; + } } diff --git a/src/com/jpexs/decompiler/flash/gui/action/AddScriptDialog.java b/src/com/jpexs/decompiler/flash/gui/action/AddScriptDialog.java index 1658496f7..9ae56a307 100644 --- a/src/com/jpexs/decompiler/flash/gui/action/AddScriptDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/action/AddScriptDialog.java @@ -730,22 +730,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, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false); + instancePreviewPanel.showImagePanel((DefineSpriteTag) parent, swf, f - 1, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false, !Configuration.playFrameSounds.get(), true); } else { - instancePreviewPanel.showImagePanel(swf, swf, f - 1, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false); + instancePreviewPanel.showImagePanel(swf, swf, f - 1, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false, !Configuration.playFrameSounds.get(), true); } } else if (tnode.getData() instanceof DefineSpriteTag) { instancePreviewPanel.selectImageDepth(-1); - instancePreviewPanel.showImagePanel((DefineSpriteTag) tnode.getData(), swf, -1, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false); + instancePreviewPanel.showImagePanel((DefineSpriteTag) tnode.getData(), swf, -1, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false, !Configuration.playFrameSounds.get(), 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, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false); + instancePreviewPanel.showImagePanel((DefineSpriteTag) parent, swf, f - 1, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false, !Configuration.playFrameSounds.get(), true); } else { - instancePreviewPanel.showImagePanel(swf, swf, f - 1, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false); + instancePreviewPanel.showImagePanel(swf, swf, f - 1, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false, !Configuration.playFrameSounds.get(), true); } } checkEnabled(); @@ -759,7 +759,7 @@ public class AddScriptDialog extends AppDialog { checkEnabled(); return; } - spriteInitPreviewPanel.showImagePanel(spriteInitList.getSelectedValue(), swf, -1, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false); + spriteInitPreviewPanel.showImagePanel(spriteInitList.getSelectedValue(), swf, -1, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false, !Configuration.playFrameSounds.get(), true); checkEnabled(); } @@ -771,7 +771,7 @@ public class AddScriptDialog extends AppDialog { checkEnabled(); return; } - framePreviewPanel.showImagePanel(swf, swf, selectedIndex, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false); + framePreviewPanel.showImagePanel(swf, swf, selectedIndex, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false, !Configuration.playFrameSounds.get(), true); int f = selectedIndex + 1; if (!frameTextField.getText().equals("" + f)) { @@ -783,7 +783,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, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false); + buttonPreviewPanel.showImagePanel(MainPanel.makeTimelined(buttonList.getSelectedValue()), swf, -1, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false, !Configuration.playFrameSounds.get(), true); } checkEnabled(); @@ -799,14 +799,14 @@ public class AddScriptDialog extends AppDialog { } MyTreeNode tnode = (MyTreeNode) selection.getLastPathComponent(); if (tnode.getData() instanceof DefineSpriteTag) { - spriteFramePreviewPanel.showImagePanel((DefineSpriteTag) tnode.getData(), swf, -1, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false); + spriteFramePreviewPanel.showImagePanel((DefineSpriteTag) tnode.getData(), swf, -1, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false, !Configuration.playFrameSounds.get(), 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, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false); + spriteFramePreviewPanel.showImagePanel((DefineSpriteTag) parent, swf, f - 1, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false, !Configuration.playFrameSounds.get(), true); } else { - spriteFramePreviewPanel.showImagePanel(swf, swf, f - 1, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false); + spriteFramePreviewPanel.showImagePanel(swf, swf, f - 1, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), false, !Configuration.playFrameSounds.get(), true); } if (!spriteFrameTextField.getText().equals("" + f)) { spriteFrameTextField.setText("" + f); diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/soundmute16.png b/src/com/jpexs/decompiler/flash/gui/graphics/soundmute16.png new file mode 100644 index 000000000..b652d2a71 Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/soundmute16.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties index 69c78cdda..4c3e4fd74 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties @@ -626,3 +626,6 @@ config.description.gui.scale = Scaling factor of graphics interface. Set this to config.name.warning.video.vlc = Warn on missing VLC config.description.warning.video.vlc = Show warning about VLC media player required when opening SWFs with DefineVideoStream tags when VLC is not available. + +config.name.playFrameSounds = Play frame sounds +config.description.playFrameSounds = Play sounds on displaying frames. diff --git a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties index ed0bca034..eca1ddf3a 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties @@ -616,3 +616,6 @@ config.description.gui.scale = Zv\u011bt\u0161ovac\u00ed faktor grafick\u00e9ho config.name.warning.video.vlc = Varovat p\u0159i chyb\u011bj\u00edc\u00edm VLC config.description.warning.video.vlc = Zobrazovat varov\u00e1n\u00ed o vy\u017eadovan\u00e9m VLC media playeru p\u0159i otev\u00edr\u00e1n\u00ed SWF s DefineVideoStream tagy kdy\u017e je VLC nedostupn\u00fd. + +config.name.playFrameSounds = P\u0159ehr\u00e1vat sn\u00edmkov\u00e9 zvuky +config.description.playFrameSounds = P\u0159ehr\u00e1vat zvuky p\u0159i zobrazov\u00e1n\u00ed sn\u00edmk\u016f. \ No newline at end of file diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties index 9fc66ae75..07dcd0ece 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties @@ -998,4 +998,6 @@ productinfo.compileDate = Compilation date: message.video.installvlc = The file "%file%" contains video tags (DefineVideoStream).\r\n\ To properly display them in the decompiler, VLC media player installed is required (minimum version 3.0.0).\r\n\ - You can however still export the videos to FLV file format without it. \ No newline at end of file + You can however still export the videos to FLV file format without it. + +button.mute = Mute frame sounds \ No newline at end of file diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties index 1c18e3cc2..40c80b689 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties @@ -983,4 +983,6 @@ productinfo.compileDate = Datum kompilace: message.video.installvlc = Soubor "%file%" obsahuje video tagy (DefineVideoStream).\r\n\ Pro korektn\u00ed zobrazen\u00ed v dekompil\u00e1toru je vy\u017eadov\u00e1n nainstalovan\u00fd VLC media player (v minim\u00e1ln\u00ed verzi 3.0.0).\r\n\ - St\u00e1le nicm\u00e9n\u011b m\u016f\u017eete exportovat videa do FLV form\u00e1tu i bez toho. \ No newline at end of file + St\u00e1le nicm\u00e9n\u011b m\u016f\u017eete exportovat videa do FLV form\u00e1tu i bez toho. + +button.mute = Ztlumit sn\u00edmkov\u00e9 zvuky \ No newline at end of file diff --git a/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java b/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java index fb0a2676e..2f68d111e 100644 --- a/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java @@ -465,4 +465,14 @@ public final class FlashPlayerPanel extends Panel implements Closeable, MediaDis public boolean alwaysDisplay() { return true; } + + @Override + public void setMuted(boolean value) { + + } + + @Override + public boolean isMutable() { + return false; + } } diff --git a/src/com/jpexs/decompiler/flash/gui/player/MediaDisplay.java b/src/com/jpexs/decompiler/flash/gui/player/MediaDisplay.java index efd433c91..248a8f462 100644 --- a/src/com/jpexs/decompiler/flash/gui/player/MediaDisplay.java +++ b/src/com/jpexs/decompiler/flash/gui/player/MediaDisplay.java @@ -77,4 +77,8 @@ public interface MediaDisplay extends Closeable { public void setFrozen(boolean value); public boolean alwaysDisplay(); + + public void setMuted(boolean value); + + public boolean isMutable(); } diff --git a/src/com/jpexs/decompiler/flash/gui/player/PlayerControls.java b/src/com/jpexs/decompiler/flash/gui/player/PlayerControls.java index 0d8176f3a..5558d24dc 100644 --- a/src/com/jpexs/decompiler/flash/gui/player/PlayerControls.java +++ b/src/com/jpexs/decompiler/flash/gui/player/PlayerControls.java @@ -92,7 +92,7 @@ public class PlayerControls extends JPanel implements MediaDisplayListener { private static final Icon loopIcon = View.getIcon("loopon16"); private static final Icon noLoopIcon = View.getIcon("loopoff16"); - + private final JLabel percentLabel = new JLabel("100%"); private final JPanel zoomPanel; @@ -114,6 +114,8 @@ public class PlayerControls extends JPanel implements MediaDisplayListener { private final JToggleButton showButton; private final JToggleButton freezeButton; + + private final JToggleButton muteButton; public static final int ZOOM_DECADE_STEPS = 10; @@ -195,8 +197,16 @@ public class PlayerControls extends JPanel implements MediaDisplayListener { freezeButton.setVisible(false); freezeButton.setSelected(!Configuration.animateSubsprites.get()); + muteButton = new JToggleButton(View.getIcon("soundmute16")); + muteButton.addActionListener(this::muteButtonActionPerformed); + muteButton.setToolTipText(AppStrings.translate("button.mute")); + muteButton.setVisible(false); + muteButton.setSelected(!Configuration.playFrameSounds.get()); + + displayButtonsPanel.add(showButton); displayButtonsPanel.add(freezeButton); + displayButtonsPanel.add(muteButton); graphicControls.add(displayButtonsPanel, BorderLayout.WEST); graphicControls.add(graphicButtonsPanel, BorderLayout.EAST); @@ -358,7 +368,7 @@ public class PlayerControls extends JPanel implements MediaDisplayListener { } View.execInEventDispatchLater(() -> { - //updateZoom(); + muteButton.setVisible(display.isMutable()); int totalFrames = display.getTotalFrames(); int currentFrame = display.getCurrentFrame(); if (currentFrame > totalFrames) { @@ -590,6 +600,11 @@ public class PlayerControls extends JPanel implements MediaDisplayListener { display.setFrozen(freezeButton.isSelected()); Configuration.animateSubsprites.set(!freezeButton.isSelected()); } + + private void muteButtonActionPerformed(ActionEvent evt) { + display.setMuted(muteButton.isSelected()); + Configuration.playFrameSounds.set(!muteButton.isSelected()); + } private double getRealZoom() { if (zoomToFit) { diff --git a/src/com/jpexs/decompiler/flash/gui/timeline/TimelineViewPanel.java b/src/com/jpexs/decompiler/flash/gui/timeline/TimelineViewPanel.java index d415eea7f..06709e6db 100644 --- a/src/com/jpexs/decompiler/flash/gui/timeline/TimelineViewPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/timeline/TimelineViewPanel.java @@ -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, true, !Configuration.animateSubsprites.get(), true); + previewPanel.setTimelined(timelined, timelined.getTimeline().swf, 0, true, true, !Configuration.animateSubsprites.get(), true, !Configuration.playFrameSounds.get(), true); //previewPanel.setPreferredSize(new Dimension(400,300)); previewPanel.pause(); previewPanel.gotoFrame(0);