mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-08-02 15:51:16 +00:00
Added Changing tag position
This commit is contained in:
@@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file.
|
||||
- data-characterId and data-characterName tags to SVG export
|
||||
- [#1731] Image viewer zoom support
|
||||
- Cloning of tags and frames
|
||||
- Changing tag position
|
||||
|
||||
### Fixed
|
||||
- [#1834] PlaceObject4 tags appear as Unresolved inside of DefineSprite
|
||||
|
||||
@@ -131,12 +131,12 @@ public class Timeline {
|
||||
}
|
||||
}
|
||||
|
||||
public List<Frame> getFrames() {
|
||||
public synchronized List<Frame> getFrames() {
|
||||
ensureInitialized();
|
||||
return frames;
|
||||
}
|
||||
|
||||
public Frame getFrame(int index) {
|
||||
public synchronized Frame getFrame(int index) {
|
||||
ensureInitialized();
|
||||
if (index >= frames.size()) {
|
||||
return null;
|
||||
@@ -144,7 +144,7 @@ public class Timeline {
|
||||
return frames.get(index);
|
||||
}
|
||||
|
||||
public void addFrame(Frame frame) {
|
||||
public synchronized void addFrame(Frame frame) {
|
||||
ensureInitialized();
|
||||
frames.add(frame);
|
||||
maxDepth = getMaxDepthInternal();
|
||||
@@ -174,7 +174,7 @@ public class Timeline {
|
||||
reset(swf, swf, 0, swf.displayRect);
|
||||
}
|
||||
|
||||
public void reset(SWF swf, Timelined timelined, int id, RECT displayRect) {
|
||||
public synchronized void reset(SWF swf, Timelined timelined, int id, RECT displayRect) {
|
||||
initialized = false;
|
||||
frames.clear();
|
||||
depthMaxFrame.clear();
|
||||
@@ -196,7 +196,7 @@ public class Timeline {
|
||||
return maxDepth;
|
||||
}
|
||||
|
||||
private int getMaxDepthInternal() {
|
||||
private synchronized int getMaxDepthInternal() {
|
||||
int max_depth = 0;
|
||||
for (Frame f : frames) {
|
||||
for (int depth : f.layers.keySet()) {
|
||||
@@ -212,12 +212,12 @@ public class Timeline {
|
||||
return max_depth;
|
||||
}
|
||||
|
||||
public int getFrameCount() {
|
||||
public synchronized int getFrameCount() {
|
||||
ensureInitialized();
|
||||
return frames.size();
|
||||
}
|
||||
|
||||
public int getRealFrameCount() {
|
||||
public synchronized int getRealFrameCount() {
|
||||
ensureInitialized();
|
||||
|
||||
int cnt = 1;
|
||||
@@ -263,7 +263,7 @@ public class Timeline {
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
private synchronized void initialize() {
|
||||
int frameIdx = 0;
|
||||
Frame frame = new Frame(this, frameIdx++);
|
||||
frame.layersChanged = true;
|
||||
@@ -418,7 +418,7 @@ public class Timeline {
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
private void detectTweens() {
|
||||
private synchronized void detectTweens() {
|
||||
for (int d = 1; d <= maxDepth; d++) {
|
||||
int characterId = -1;
|
||||
int len = 0;
|
||||
@@ -455,7 +455,7 @@ public class Timeline {
|
||||
}
|
||||
}
|
||||
|
||||
private void calculateMaxDepthFrames() {
|
||||
private synchronized void calculateMaxDepthFrames() {
|
||||
depthMaxFrame.clear();
|
||||
for (int d = 1; d <= maxDepth; d++) {
|
||||
for (int f = frames.size() - 1; f >= 0; f--) {
|
||||
|
||||
@@ -3391,9 +3391,30 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
t = di.getTag();
|
||||
}
|
||||
|
||||
showPreview(t, dumpPreviewPanel);
|
||||
showPreview(t, dumpPreviewPanel, getFrameForTreeItem(t), getTimelinedForTreeItem(treeItem));
|
||||
}
|
||||
}
|
||||
|
||||
private int getFrameForTreeItem(TreeItem treeItem) {
|
||||
TreePath path = tagTree.getModel().getTreePath(treeItem);
|
||||
for (int i = path.getPathCount() - 1; i >= 0; i--) {
|
||||
if (path.getPathComponent(i) instanceof Frame) {
|
||||
Frame frame = (Frame)path.getPathComponent(i);
|
||||
return frame.frame;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private Timelined getTimelinedForTreeItem(TreeItem treeItem) {
|
||||
TreePath path = tagTree.getModel().getTreePath(treeItem);
|
||||
for (int i = path.getPathCount() - 1; i >= 0; i--) {
|
||||
if (path.getPathComponent(i) instanceof Timelined) {
|
||||
return (Timelined)path.getPathComponent(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void unloadFlashPlayer() {
|
||||
if (flashPanel != null) {
|
||||
@@ -3436,7 +3457,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAdobeFlashPlayerEnabled() {
|
||||
public static boolean isAdobeFlashPlayerEnabled() {
|
||||
return Configuration.useAdobeFlashPlayerForPreviews.get();
|
||||
}
|
||||
|
||||
@@ -3614,7 +3635,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
previewPanel.closeTag();
|
||||
}
|
||||
|
||||
public void showPreview(TreeItem treeItem, PreviewPanel previewPanel) {
|
||||
public static void showPreview(TreeItem treeItem, PreviewPanel previewPanel, int frame, Timelined timelinedContainer) {
|
||||
previewPanel.clear();
|
||||
if (treeItem == null) {
|
||||
previewPanel.showEmpty();
|
||||
@@ -3633,10 +3654,10 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
|
||||
//}
|
||||
}
|
||||
} else if ((treeItem instanceof PlaceObjectTypeTag) && (previewPanel != dumpPreviewPanel)) {
|
||||
TreePath path = tagTree.getModel().getTreePath(treeItem);
|
||||
Frame frame = (Frame) path.getParentPath().getLastPathComponent();
|
||||
previewPanel.showPlaceTagPanel((PlaceObjectTypeTag) treeItem, frame.frame);
|
||||
} else if ((treeItem instanceof PlaceObjectTypeTag)) {// && (previewPanel != dumpPreviewPanel)) {
|
||||
//TreePath path = tagTree.getModel().getTreePath(treeItem);
|
||||
//Frame frame = (Frame) path.getParentPath().getLastPathComponent();
|
||||
previewPanel.showPlaceTagPanel((PlaceObjectTypeTag) treeItem, frame);
|
||||
} else if (treeItem instanceof MetadataTag) {
|
||||
MetadataTag metadataTag = (MetadataTag) treeItem;
|
||||
previewPanel.showMetaDataPanel(metadataTag);
|
||||
@@ -3668,6 +3689,14 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
Frame fn = (Frame) treeItem;
|
||||
SWF swf = fn.getSwf();
|
||||
previewPanel.showImagePanel(fn.timeline.timelined, swf, fn.frame, true);
|
||||
} else if (treeItem instanceof ShowFrameTag) {
|
||||
SWF swf;
|
||||
if (timelinedContainer instanceof DefineSpriteTag) {
|
||||
swf = ((DefineSpriteTag)timelinedContainer).getSwf();
|
||||
} else {
|
||||
swf = (SWF)timelinedContainer;
|
||||
}
|
||||
previewPanel.showImagePanel(timelinedContainer, swf, frame, true);
|
||||
} else if ((treeItem instanceof SoundTag)) { //&& isInternalFlashViewerSelected() && (Arrays.asList("mp3", "wav").contains(((SoundTag) tagObj).getExportFormat())))) {
|
||||
previewPanel.showImagePanel(new SerializableImage(View.loadImage("sound32")));
|
||||
previewPanel.setImageReplaceButtonVisible(((Tag) treeItem).isReadOnly() && (treeItem instanceof DefineSoundTag), false);
|
||||
@@ -3804,44 +3833,44 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
} else if (treeItem instanceof FolderItem) {
|
||||
showFolderPreview((FolderItem) treeItem);
|
||||
} else if (treeItem instanceof SWF) {
|
||||
showPreview(treeItem, previewPanel);
|
||||
showPreview(treeItem, previewPanel, -1, null);
|
||||
showCard(CARDPREVIEWPANEL);
|
||||
} else if (treeItem instanceof MetadataTag) {
|
||||
showPreview(treeItem, previewPanel);
|
||||
showPreview(treeItem, previewPanel, -1, null);
|
||||
showCard(CARDPREVIEWPANEL);
|
||||
} else if (treeItem instanceof DefineBinaryDataTag) {
|
||||
showPreview(treeItem, previewPanel);
|
||||
showPreview(treeItem, previewPanel, -1, null);
|
||||
showCard(CARDPREVIEWPANEL);
|
||||
} else if (treeItem instanceof UnknownTag) {
|
||||
showPreview(treeItem, previewPanel);
|
||||
showPreview(treeItem, previewPanel, -1, null);
|
||||
showCard(CARDPREVIEWPANEL);
|
||||
} else if (treeItem instanceof ASMSource && (!(treeItem instanceof DrawableTag) || preferScript)) {
|
||||
getActionPanel().setSource((ASMSource) treeItem, !forceReload);
|
||||
showCard(CARDACTIONSCRIPTPANEL);
|
||||
} else if (treeItem instanceof ImageTag) {
|
||||
showPreview(treeItem, previewPanel);
|
||||
showPreview(treeItem, previewPanel, -1, null);
|
||||
showCard(CARDPREVIEWPANEL);
|
||||
} else if ((treeItem instanceof DrawableTag) && (!(treeItem instanceof TextTag)) && (!(treeItem instanceof FontTag)) && internalViewer) {
|
||||
showPreview(treeItem, previewPanel);
|
||||
showPreview(treeItem, previewPanel, -1, null);
|
||||
showCard(CARDPREVIEWPANEL);
|
||||
} else if ((treeItem instanceof FontTag) && internalViewer) {
|
||||
showPreview(treeItem, previewPanel);
|
||||
showPreview(treeItem, previewPanel, -1, null);
|
||||
showCard(CARDPREVIEWPANEL);
|
||||
} else if ((treeItem instanceof TextTag) && internalViewer) {
|
||||
showPreview(treeItem, previewPanel);
|
||||
showPreview(treeItem, previewPanel, -1, null);
|
||||
showCard(CARDPREVIEWPANEL);
|
||||
} else if (treeItem instanceof Frame && internalViewer) {
|
||||
showPreview(treeItem, previewPanel);
|
||||
showPreview(treeItem, previewPanel, -1, null);
|
||||
showCard(CARDPREVIEWPANEL);
|
||||
} else if ((treeItem instanceof SoundTag)) { //&& isInternalFlashViewerSelected() && (Arrays.asList("mp3", "wav").contains(((SoundTag) tagObj).getExportFormat())))) {
|
||||
showPreview(treeItem, previewPanel);
|
||||
showPreview(treeItem, previewPanel, -1, null);
|
||||
showCard(CARDPREVIEWPANEL);
|
||||
} else if ((treeItem instanceof Frame) || (treeItem instanceof CharacterTag) || (treeItem instanceof FontTag) || (treeItem instanceof SoundStreamHeadTypeTag)) {
|
||||
showPreview(treeItem, previewPanel);
|
||||
showPreview(treeItem, previewPanel, -1, null);
|
||||
|
||||
showCard(CARDPREVIEWPANEL);
|
||||
} else if (treeItem instanceof PlaceObjectTypeTag) {
|
||||
showPreview(treeItem, previewPanel);
|
||||
showPreview(treeItem, previewPanel, getFrameForTreeItem(treeItem), null);
|
||||
showCard(CARDPREVIEWPANEL);
|
||||
} else if (treeItem instanceof Tag) {
|
||||
showGenericTag((Tag) treeItem);
|
||||
|
||||
@@ -712,17 +712,18 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
showCardLeft(PLACE_TAG_CARD);
|
||||
placeTag = tag;
|
||||
oldMatrix = tag.getMatrix();
|
||||
placeSplitPane.setDividerLocation((int) (0.6 * this.getWidth()));
|
||||
placeSplitPane.setDividerLocation((int) (0.6 * this.getWidth()));
|
||||
placeGenericPanel.setVisible(!readOnly);
|
||||
placeGenericPanel.setEditMode(false, tag);
|
||||
placeImagePanel.selectDepth(-1);
|
||||
placeImagePanel.setTimelined(((Tag) tag).getTimelined(), ((Tag) tag).getSwf(), frame, true);
|
||||
placeImagePanel.selectDepth(tag.getDepth());
|
||||
parametersPanel.setVisible(false);
|
||||
placeEditButton.setVisible(!tag.isReadOnly());
|
||||
placeEditButton.setVisible(!tag.isReadOnly() && !readOnly);
|
||||
placeEditButton.setEnabled(true);
|
||||
placeSaveButton.setVisible(false);
|
||||
placeCancelButton.setVisible(false);
|
||||
placeFreeTransformButton.setVisible(true);
|
||||
placeFreeTransformButton.setVisible(!readOnly);
|
||||
}
|
||||
|
||||
public void setImageReplaceButtonVisible(boolean show, boolean showAlpha) {
|
||||
|
||||
544
src/com/jpexs/decompiler/flash/gui/SelectTagPositionDialog.java
Normal file
544
src/com/jpexs/decompiler/flash/gui/SelectTagPositionDialog.java
Normal file
@@ -0,0 +1,544 @@
|
||||
/*
|
||||
* Copyright (C) 2022 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.gui;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import static com.jpexs.decompiler.flash.gui.AppDialog.CANCEL_OPTION;
|
||||
import com.jpexs.decompiler.flash.gui.tagtree.TagTree;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineSoundTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineSpriteTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineVideoStreamTag;
|
||||
import com.jpexs.decompiler.flash.tags.DoABC2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.DoABCTag;
|
||||
import com.jpexs.decompiler.flash.tags.DoActionTag;
|
||||
import com.jpexs.decompiler.flash.tags.DoInitActionTag;
|
||||
import com.jpexs.decompiler.flash.tags.FileAttributesTag;
|
||||
import com.jpexs.decompiler.flash.tags.MetadataTag;
|
||||
import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag;
|
||||
import com.jpexs.decompiler.flash.tags.ShowFrameTag;
|
||||
import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.FontTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.MorphShapeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.RemoveTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.TextTag;
|
||||
import com.jpexs.decompiler.flash.timeline.Timelined;
|
||||
import com.jpexs.decompiler.flash.treeitems.TreeItem;
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.geom.GeneralPath;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.event.TreeSelectionEvent;
|
||||
import javax.swing.plaf.basic.BasicLabelUI;
|
||||
import javax.swing.plaf.basic.BasicTreeUI;
|
||||
import javax.swing.tree.DefaultTreeCellRenderer;
|
||||
import javax.swing.tree.TreeNode;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class SelectTagPositionDialog extends AppDialog {
|
||||
|
||||
private final JButton okButton = new JButton(translate("button.ok"));
|
||||
|
||||
private final JButton cancelButton = new JButton(translate("button.cancel"));
|
||||
|
||||
private JTree positionTree;
|
||||
|
||||
private PreviewPanel previewPanel;
|
||||
|
||||
private final SWF swf;
|
||||
|
||||
private int result = ERROR_OPTION;
|
||||
|
||||
private Tag selectedTag = null;
|
||||
private Timelined selectedTimelined = null;
|
||||
|
||||
private static class MyTreeNode implements TreeNode {
|
||||
|
||||
private final List<TreeNode> children = new ArrayList<>();
|
||||
private TreeNode parent;
|
||||
private Object data;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (data instanceof DoInitActionTag) {
|
||||
DoInitActionTag doinit = (DoInitActionTag) data;
|
||||
String exportName = doinit.getSwf().getExportName(doinit.spriteId);
|
||||
if (exportName != null && !exportName.isEmpty()) {
|
||||
return DoInitActionTag.NAME + " (" + doinit.spriteId + ") : " + exportName;
|
||||
}
|
||||
}
|
||||
return data.toString();
|
||||
}
|
||||
|
||||
public void setData(Object data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public Object getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void addChild(TreeNode node) {
|
||||
children.add(node);
|
||||
}
|
||||
|
||||
public void setParent(TreeNode parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TreeNode getChildAt(int childIndex) {
|
||||
return children.get(childIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildCount() {
|
||||
return children.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TreeNode getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndex(TreeNode node) {
|
||||
return children.indexOf(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAllowsChildren() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeaf() {
|
||||
return children.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration<? extends TreeNode> children() {
|
||||
return Collections.enumeration(children);
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyTimelineEnd {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return AppDialog.translateForDialog("timeline.end", SelectTagPositionDialog.class);
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyFrame {
|
||||
|
||||
private final int frame;
|
||||
private boolean invalid;
|
||||
|
||||
public MyFrame(int frame) {
|
||||
this.frame = frame;
|
||||
}
|
||||
|
||||
public int getFrame() {
|
||||
return frame;
|
||||
}
|
||||
|
||||
public void setInvalid(boolean invalid) {
|
||||
this.invalid = invalid;
|
||||
}
|
||||
|
||||
public boolean isInvalid() {
|
||||
return invalid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "frame " + frame;
|
||||
}
|
||||
}
|
||||
|
||||
private void populateNodes(MyTreeNode root, Timelined tim, int currentFrame) {
|
||||
int f = 1;
|
||||
|
||||
MyTreeNode frameNode = new MyTreeNode();
|
||||
frameNode.setData(new MyFrame(1));
|
||||
frameNode.setParent(root);
|
||||
root.addChild(frameNode);
|
||||
|
||||
for (Tag t : tim.getTags()) {
|
||||
MyTreeNode node = new MyTreeNode();
|
||||
node.setData(t);
|
||||
frameNode.addChild(node);
|
||||
|
||||
if (t instanceof DefineSpriteTag) {
|
||||
populateNodes(node, (DefineSpriteTag) t, 1);
|
||||
}
|
||||
if (t instanceof ShowFrameTag) {
|
||||
f++;
|
||||
frameNode = new MyTreeNode();
|
||||
frameNode.setData(new MyFrame(f));
|
||||
frameNode.setParent(root);
|
||||
root.addChild(frameNode);
|
||||
}
|
||||
}
|
||||
if (frameNode.isLeaf()) {
|
||||
root.children.remove(root.children.size() - 1);
|
||||
}
|
||||
MyTimelineEnd end = new MyTimelineEnd();
|
||||
MyTreeNode endNode = new MyTreeNode();
|
||||
endNode.setData(end);
|
||||
root.addChild(endNode);
|
||||
}
|
||||
|
||||
private void selectCurrent(MyTreeNode root, Timelined timelined, List<Object> path) {
|
||||
|
||||
for (int i = 0; i < root.getChildCount(); i++) {
|
||||
MyTreeNode node = (MyTreeNode) root.getChildAt(i);
|
||||
|
||||
List<Object> subPath = new ArrayList<>(path);
|
||||
subPath.add(node);
|
||||
|
||||
if (node.getData() == selectedTag && timelined == selectedTimelined) {
|
||||
Object[] pathArray = subPath.toArray(new Object[subPath.size()]);
|
||||
TreePath tpath = new TreePath(pathArray);
|
||||
positionTree.setSelectionPath(tpath);
|
||||
positionTree.scrollPathToVisible(tpath);
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.getData() instanceof DefineSpriteTag) {
|
||||
selectCurrent(node, (DefineSpriteTag) node.getData(), subPath);
|
||||
} else {
|
||||
selectCurrent(node, timelined, subPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SelectTagPositionDialog(Window parent, SWF swf) {
|
||||
this(parent, swf, null, null);
|
||||
}
|
||||
|
||||
private static class PositionTreeCellRenderer extends DefaultTreeCellRenderer {
|
||||
|
||||
private boolean selected;
|
||||
|
||||
public PositionTreeCellRenderer() {
|
||||
if (View.isOceanic()) {
|
||||
setUI(new BasicLabelUI());
|
||||
setOpaque(false);
|
||||
setBackgroundNonSelectionColor(Color.white);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
|
||||
Component renderer = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
|
||||
this.selected = sel;
|
||||
if (renderer instanceof JLabel) {
|
||||
JLabel lab = (JLabel) renderer;
|
||||
|
||||
Object subValue = value;
|
||||
if (value instanceof MyTreeNode) {
|
||||
subValue = ((MyTreeNode) value).getData();
|
||||
}
|
||||
TreeNodeType nodeType;
|
||||
if (subValue instanceof MyFrame) {
|
||||
nodeType = TreeNodeType.FRAME;
|
||||
} else if (subValue instanceof FontTag) {
|
||||
nodeType = TreeNodeType.FONT;
|
||||
} else if (subValue instanceof TextTag) {
|
||||
nodeType = TreeNodeType.TEXT;
|
||||
} else if (subValue instanceof ImageTag) {
|
||||
nodeType = TreeNodeType.IMAGE;
|
||||
} else if (subValue instanceof ShapeTag) {
|
||||
nodeType = TreeNodeType.SHAPE;
|
||||
} else if (subValue instanceof MorphShapeTag) {
|
||||
nodeType = TreeNodeType.MORPH_SHAPE;
|
||||
} else if (subValue instanceof DefineSpriteTag) {
|
||||
nodeType = TreeNodeType.SPRITE;
|
||||
} else if (subValue instanceof ButtonTag) {
|
||||
nodeType = TreeNodeType.BUTTON;
|
||||
} else if (subValue instanceof DefineVideoStreamTag) {
|
||||
nodeType = TreeNodeType.MOVIE;
|
||||
} else if ((subValue instanceof DefineSoundTag) || (subValue instanceof SoundStreamHeadTypeTag) || (subValue instanceof SoundStreamBlockTag)) {
|
||||
nodeType = TreeNodeType.SOUND;
|
||||
} else if (subValue instanceof DefineBinaryDataTag) {
|
||||
nodeType = TreeNodeType.BINARY_DATA;
|
||||
} else if ((subValue instanceof DoActionTag)
|
||||
|| (subValue instanceof DoInitActionTag)
|
||||
|| (subValue instanceof DoABCTag)
|
||||
|| (subValue instanceof DoABC2Tag)) {
|
||||
nodeType = TreeNodeType.AS;
|
||||
} else if (subValue instanceof ShowFrameTag) {
|
||||
nodeType = TreeNodeType.FRAME;
|
||||
} else if (subValue instanceof SetBackgroundColorTag) {
|
||||
nodeType = TreeNodeType.SET_BACKGROUNDCOLOR;
|
||||
} else if (subValue instanceof FileAttributesTag) {
|
||||
nodeType = TreeNodeType.FILE_ATTRIBUTES;
|
||||
} else if (subValue instanceof MetadataTag) {
|
||||
nodeType = TreeNodeType.METADATA;
|
||||
} else if (subValue instanceof PlaceObjectTypeTag) {
|
||||
nodeType = TreeNodeType.PLACE_OBJECT;
|
||||
} else if (subValue instanceof RemoveTag) {
|
||||
nodeType = TreeNodeType.REMOVE_OBJECT;
|
||||
} else if (subValue instanceof MyTimelineEnd) {
|
||||
nodeType = null;
|
||||
} else {
|
||||
nodeType = TreeNodeType.OTHER_TAG;
|
||||
}
|
||||
if (nodeType == null) {
|
||||
//nothing
|
||||
} else {
|
||||
lab.setIcon(TagTree.getIconForType(nodeType));
|
||||
}
|
||||
}
|
||||
return renderer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public SelectTagPositionDialog(Window parent, SWF swf, Tag selectedTag, Timelined selectedTimelined) {
|
||||
super(parent);
|
||||
this.swf = swf;
|
||||
this.selectedTag = selectedTag;
|
||||
this.selectedTimelined = selectedTimelined;
|
||||
setTitle(translate("dialog.title"));
|
||||
setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
|
||||
Container cnt = getContentPane();
|
||||
cnt.setLayout(new BorderLayout());
|
||||
|
||||
JPanel buttonsPanel = new JPanel(new FlowLayout());
|
||||
|
||||
okButton.addActionListener(this::okButtonActionPerformed);
|
||||
cancelButton.addActionListener(this::cancelButtonActionPerformed);
|
||||
|
||||
buttonsPanel.add(okButton);
|
||||
buttonsPanel.add(cancelButton);
|
||||
cnt.add(buttonsPanel, BorderLayout.SOUTH);
|
||||
|
||||
MyTreeNode root = new MyTreeNode();
|
||||
root.setData("root");
|
||||
|
||||
populateNodes(root, swf, 1);
|
||||
|
||||
positionTree = new JTree(root) {
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
int rows[] = getSelectionRows();
|
||||
if (rows.length == 1) {
|
||||
int row = rows[0];
|
||||
|
||||
Object selection = getLastSelectedPathComponent();
|
||||
boolean onFrame = false;
|
||||
if (selection != null && (((MyTreeNode)selection).getData() instanceof MyFrame)) { // && !isCollapsed(row)) {
|
||||
onFrame = true;
|
||||
return;
|
||||
}
|
||||
Rectangle rect = this.getRowBounds(row);
|
||||
int sideWidth = 6;
|
||||
int sideHeight = 6;
|
||||
int offsetX = -5;
|
||||
|
||||
|
||||
int lineStartX = offsetX + rect.x;
|
||||
int backStartX = getWidth() + offsetX;
|
||||
if (onFrame) {
|
||||
g.fillRect(lineStartX, rect.y + rect.height - 1, getWidth() - lineStartX, 1);
|
||||
} else {
|
||||
g.fillRect(lineStartX, rect.y, getWidth() - lineStartX, 1);
|
||||
}
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
g2d.setPaint(getForeground());
|
||||
GeneralPath path = new GeneralPath();
|
||||
|
||||
if (onFrame) {
|
||||
path.moveTo(backStartX - 6, rect.y + rect.height - 1 - 6);
|
||||
path.lineTo(backStartX, rect.y + rect.height - 1);
|
||||
path.lineTo(backStartX + 6, rect.y + rect.height - 1 - 6);
|
||||
} else {
|
||||
path.moveTo(lineStartX - 6, rect.y + 6);
|
||||
path.lineTo(lineStartX, rect.y);
|
||||
path.lineTo(lineStartX + 6, rect.y + 6);
|
||||
}
|
||||
path.closePath();
|
||||
g2d.fill(path);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
if (View.isOceanic()) {
|
||||
positionTree.setBackground(Color.white);
|
||||
positionTree.setUI(new BasicTreeUI() {
|
||||
{
|
||||
setHashColor(Color.gray);
|
||||
}
|
||||
});
|
||||
}
|
||||
positionTree.setCellRenderer(new PositionTreeCellRenderer());
|
||||
positionTree.setRootVisible(false);
|
||||
positionTree.setShowsRootHandles(true);
|
||||
positionTree.addTreeSelectionListener(this::spriteValueChanged);
|
||||
|
||||
previewPanel = new PreviewPanel(Main.getMainFrame().getPanel(), null);
|
||||
previewPanel.setReadOnly(true);
|
||||
previewPanel.setPreferredSize(new Dimension(300, 1));
|
||||
previewPanel.showEmpty();
|
||||
previewPanel.setParametersPanelVisible(false);
|
||||
|
||||
JScrollPane positionTreeScrollPane = new FasterScrollPane(positionTree);
|
||||
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, positionTreeScrollPane, previewPanel);
|
||||
//splitPane.setDividerLocation(600);
|
||||
cnt.add(splitPane, BorderLayout.CENTER);
|
||||
|
||||
List<Object> path = new ArrayList<>();
|
||||
path.add(root);
|
||||
selectCurrent(root, swf, path);
|
||||
|
||||
setSize(1024, 600);
|
||||
setModal(true);
|
||||
setResizable(true);
|
||||
View.centerScreen(this);
|
||||
View.setWindowIcon(this);
|
||||
}
|
||||
|
||||
private int getCurrentSelectedFrame() {
|
||||
TreePath path = positionTree.getSelectionPath();
|
||||
for (int i = path.getPathCount() - 1; i >= 0; i--) {
|
||||
MyTreeNode node = (MyTreeNode) path.getPathComponent(i);
|
||||
if (node.getData() instanceof MyFrame) {
|
||||
MyFrame frame = (MyFrame) node.getData();
|
||||
return frame.frame;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private Timelined getCurrentSelectedTimelined() {
|
||||
TreePath path = positionTree.getSelectionPath();
|
||||
for (int i = path.getPathCount() - 1; i >= 0; i--) {
|
||||
MyTreeNode node = (MyTreeNode) path.getPathComponent(i);
|
||||
if ("root".equals(node.getData())) {
|
||||
return swf;
|
||||
}
|
||||
if (node.getData() instanceof DefineSpriteTag) {
|
||||
return (Timelined) node.getData();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void spriteValueChanged(TreeSelectionEvent e) {
|
||||
|
||||
TreePath selection = positionTree.getSelectionPath();
|
||||
if (selection == null) {
|
||||
previewPanel.showEmpty();
|
||||
return;
|
||||
}
|
||||
MyTreeNode tnode = (MyTreeNode) selection.getLastPathComponent();
|
||||
if (tnode.getData() instanceof Tag) {
|
||||
MainPanel.showPreview((TreeItem) tnode.getData(), previewPanel, getCurrentSelectedFrame() - 1, getCurrentSelectedTimelined());
|
||||
} else if (tnode.getData() instanceof MyFrame) {
|
||||
int f = ((MyFrame) tnode.getData()).frame;
|
||||
Object parent = ((MyTreeNode) tnode.getParent()).getData();
|
||||
if (parent instanceof DefineSpriteTag) {
|
||||
previewPanel.showImagePanel((DefineSpriteTag) parent, swf, f - 1, true);
|
||||
} else {
|
||||
previewPanel.showImagePanel(swf, swf, f - 1, true);
|
||||
}
|
||||
} else {
|
||||
previewPanel.showEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelButtonActionPerformed(ActionEvent evt) {
|
||||
result = CANCEL_OPTION;
|
||||
previewPanel.clear();
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
private void okButtonActionPerformed(ActionEvent evt) {
|
||||
MyTreeNode node = (MyTreeNode)positionTree.getLastSelectedPathComponent();
|
||||
if (node.getData() instanceof MyFrame) {
|
||||
return;
|
||||
}
|
||||
if (node.getData() instanceof MyTimelineEnd) {
|
||||
selectedTag = null;
|
||||
} else {
|
||||
selectedTag = (Tag) node.getData();
|
||||
}
|
||||
|
||||
selectedTimelined = getCurrentSelectedTimelined();
|
||||
|
||||
result = OK_OPTION;
|
||||
previewPanel.clear();
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
public int showDialog() {
|
||||
setVisible(true);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets current selected tag to determine position. null = end of timeline position
|
||||
* @return
|
||||
*/
|
||||
public Tag getSelectedTag() {
|
||||
return selectedTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets selected timelined
|
||||
* @return
|
||||
*/
|
||||
public Timelined getSelectedTimelined() {
|
||||
return selectedTimelined;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -268,111 +268,115 @@ public class SoundTagPlayer implements MediaDisplay {
|
||||
}
|
||||
|
||||
private void playLoop() {
|
||||
final byte[] data = new byte[16];
|
||||
|
||||
setPausedFlag(false);
|
||||
setActiveFlag(true);
|
||||
long posBytes = 0;
|
||||
try {
|
||||
int numReadBytes = 0;
|
||||
while (numReadBytes != -1) {
|
||||
loop: while (true) {
|
||||
|
||||
final byte[] data = new byte[16];
|
||||
|
||||
setPausedFlag(false);
|
||||
setActiveFlag(true);
|
||||
long posBytes = 0;
|
||||
try {
|
||||
int numReadBytes = 0;
|
||||
while (numReadBytes != -1) {
|
||||
|
||||
if (getClosedFlag()) {
|
||||
break;
|
||||
}
|
||||
if (!getPausedFlag()) {
|
||||
if (newPositionMicrosec != null) {
|
||||
long newPosBytes = (long) (newPositionMicrosec / microsecPerByte);
|
||||
audioStream.close();
|
||||
reloadAudioStream();
|
||||
audioStream.skip(newPosBytes);
|
||||
newPositionMicrosec = null;
|
||||
posBytes = newPosBytes;
|
||||
}
|
||||
|
||||
numReadBytes = audioStream.read(data, 0, data.length);
|
||||
if (numReadBytes != -1) {
|
||||
posBytes += numReadBytes;
|
||||
if (sourceLine.isControlSupported(FloatControl.Type.MASTER_GAIN)) {
|
||||
//((FloatControl) sourceLine.getControl(FloatControl.Type.MASTER_GAIN)).setValue(volume_dB);
|
||||
}
|
||||
sourceLine.write(data, 0, numReadBytes);
|
||||
synchronized (playLock) {
|
||||
positionMicrosec = microsecPerByte * posBytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (getPausedFlag()) {
|
||||
synchronized (thread) {
|
||||
try {
|
||||
thread.wait(1000);
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (getClosedFlag()) {
|
||||
break;
|
||||
}
|
||||
if (!getPausedFlag()) {
|
||||
if (newPositionMicrosec != null) {
|
||||
long newPosBytes = (long) (newPositionMicrosec / microsecPerByte);
|
||||
audioStream.close();
|
||||
reloadAudioStream();
|
||||
audioStream.skip(newPosBytes);
|
||||
newPositionMicrosec = null;
|
||||
posBytes = newPosBytes;
|
||||
}
|
||||
|
||||
numReadBytes = audioStream.read(data, 0, data.length);
|
||||
if (numReadBytes != -1) {
|
||||
posBytes += numReadBytes;
|
||||
if (sourceLine.isControlSupported(FloatControl.Type.MASTER_GAIN)) {
|
||||
//((FloatControl) sourceLine.getControl(FloatControl.Type.MASTER_GAIN)).setValue(volume_dB);
|
||||
}
|
||||
sourceLine.write(data, 0, numReadBytes);
|
||||
synchronized (playLock) {
|
||||
positionMicrosec = microsecPerByte * posBytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (getPausedFlag()) {
|
||||
synchronized (thread) {
|
||||
try {
|
||||
thread.wait(1000);
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
sourceLine.drain();
|
||||
sourceLine.stop();
|
||||
sourceLine.close();
|
||||
}
|
||||
audioStream.close();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (UnsupportedAudioFileException ex) {
|
||||
Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
if (getClosedFlag()) {
|
||||
sourceLine.drain();
|
||||
sourceLine.stop();
|
||||
sourceLine.close();
|
||||
}
|
||||
audioStream.close();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (UnsupportedAudioFileException ex) {
|
||||
Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
if (!getClosedFlag()) {
|
||||
decreaseLoopCount();
|
||||
|
||||
if (!getClosedFlag()) {
|
||||
decreaseLoopCount();
|
||||
|
||||
int currentLoopCount;
|
||||
synchronized (playLock) {
|
||||
currentLoopCount = loopCount;
|
||||
}
|
||||
|
||||
if (currentLoopCount > 0) {
|
||||
try {
|
||||
reloadAudioStream();
|
||||
playLoop();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (UnsupportedAudioFileException ex) {
|
||||
Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex);
|
||||
int currentLoopCount;
|
||||
synchronized (playLock) {
|
||||
currentLoopCount = loopCount;
|
||||
}
|
||||
} else {
|
||||
setActiveFlag(false);
|
||||
firePlayingFinished();
|
||||
|
||||
if (getClosedFlag()) {
|
||||
return;
|
||||
}
|
||||
synchronized (thread) {
|
||||
if (currentLoopCount > 0) {
|
||||
try {
|
||||
thread.wait();
|
||||
} catch (InterruptedException ex) {
|
||||
reloadAudioStream();
|
||||
continue loop;
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (UnsupportedAudioFileException ex) {
|
||||
Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
} else {
|
||||
setActiveFlag(false);
|
||||
firePlayingFinished();
|
||||
|
||||
if (getClosedFlag()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
synchronized (thread) {
|
||||
try {
|
||||
thread.wait();
|
||||
} catch (InterruptedException ex) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (getClosedFlag()) {
|
||||
return;
|
||||
}
|
||||
setActiveFlag(true);
|
||||
if (getClosedFlag()) {
|
||||
return;
|
||||
}
|
||||
setActiveFlag(true);
|
||||
|
||||
try {
|
||||
reloadAudioStream();
|
||||
playLoop();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (UnsupportedAudioFileException ex) {
|
||||
Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex);
|
||||
try {
|
||||
reloadAudioStream();
|
||||
continue loop;
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (UnsupportedAudioFileException ex) {
|
||||
Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ import com.jpexs.decompiler.flash.tags.RemoveObject2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.RemoveObjectTag;
|
||||
import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag;
|
||||
import com.jpexs.decompiler.flash.tags.ShowFrameTag;
|
||||
import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag;
|
||||
import com.jpexs.decompiler.flash.tags.SoundStreamHead2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.SoundStreamHeadTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
@@ -183,6 +184,7 @@ public class DumpTree extends JTree {
|
||||
case DefineSoundTag.NAME:
|
||||
case SoundStreamHeadTag.NAME:
|
||||
case SoundStreamHead2Tag.NAME:
|
||||
case SoundStreamBlockTag.NAME:
|
||||
nodeType = TreeNodeType.SOUND;
|
||||
break;
|
||||
case DefineBinaryDataTag.NAME:
|
||||
|
||||
@@ -859,4 +859,6 @@ work.generating_swd = Generating SWD file
|
||||
|
||||
button.replaceRefs = Replace references with other character ID
|
||||
|
||||
contextmenu.cloneTag = Clone tag
|
||||
contextmenu.cloneTag = Clone tag
|
||||
|
||||
contextmenu.setTagPosition = Set tag position
|
||||
@@ -0,0 +1,19 @@
|
||||
# Copyright (C) 2022 JPEXS
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
dialog.title = Select tag position
|
||||
button.ok = OK
|
||||
button.cancel = Cancel
|
||||
timeline.end = end of timeline
|
||||
@@ -27,6 +27,7 @@ import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.parser.ActionParseException;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.ActionScript2Parser;
|
||||
import com.jpexs.decompiler.flash.gui.AppDialog;
|
||||
import com.jpexs.decompiler.flash.gui.SelectTagPositionDialog;
|
||||
import com.jpexs.decompiler.flash.gui.Main;
|
||||
import com.jpexs.decompiler.flash.gui.MainPanel;
|
||||
import com.jpexs.decompiler.flash.gui.ReplaceCharacterDialog;
|
||||
@@ -157,6 +158,8 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
private JMenuItem addAs3ClassMenuItem;
|
||||
|
||||
private JMenuItem textSearchMenuItem;
|
||||
|
||||
private JMenuItem setTagPositionMenuItem;
|
||||
|
||||
public TagTreeContextMenu(final TagTree tagTree, MainPanel mainPanel) {
|
||||
this.mainPanel = mainPanel;
|
||||
@@ -226,6 +229,10 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
importSwfXmlMenuItem.addActionListener(mainPanel::importSwfXmlActionPerformed);
|
||||
add(importSwfXmlMenuItem);
|
||||
|
||||
setTagPositionMenuItem = new JMenuItem(mainPanel.translate("contextmenu.setTagPosition"));
|
||||
setTagPositionMenuItem.addActionListener(this::setTagPositionActionPerformed);
|
||||
add(setTagPositionMenuItem);
|
||||
|
||||
addTagMenu = new JMenu(mainPanel.translate("contextmenu.addTag"));
|
||||
add(addTagMenu);
|
||||
|
||||
@@ -233,7 +240,7 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
add(moveTagMenu);
|
||||
|
||||
copyTagMenu = new JMenu(mainPanel.translate("contextmenu.copyTag"));
|
||||
add(copyTagMenu);
|
||||
add(copyTagMenu);
|
||||
|
||||
copyTagWithDependenciesMenu = new JMenu(mainPanel.translate("contextmenu.copyTagWithDependencies"));
|
||||
add(copyTagWithDependenciesMenu);
|
||||
@@ -485,6 +492,7 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
addAs12ScriptMenuItem.setVisible(false);
|
||||
addAs3ClassMenuItem.setVisible(false);
|
||||
textSearchMenuItem.setVisible(hasScripts || hasTexts);
|
||||
setTagPositionMenuItem.setVisible(items.size() == 1 && (items.get(0) instanceof Tag));
|
||||
|
||||
if (allSelectedIsTag) {
|
||||
boolean canUndo = false;
|
||||
@@ -688,7 +696,7 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
}
|
||||
}
|
||||
|
||||
private int chechUniqueCharacterId(Tag tag) {
|
||||
private int checkUniqueCharacterId(Tag tag) {
|
||||
if (tag instanceof CharacterTag) {
|
||||
CharacterTag characterTag = (CharacterTag) tag;
|
||||
int characterId = characterTag.getCharacterId();
|
||||
@@ -713,7 +721,7 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
sourceSwf.removeTag(tag);
|
||||
tag.setSwf(targetSwf, true);
|
||||
targetSwf.addTag(tag);
|
||||
chechUniqueCharacterId(tag);
|
||||
checkUniqueCharacterId(tag);
|
||||
targetSwf.updateCharacters();
|
||||
tag.setModified(true);
|
||||
}
|
||||
@@ -738,7 +746,7 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
Tag copyTag = tag.cloneTag();
|
||||
copyTag.setSwf(targetSwf, true);
|
||||
targetSwf.addTag(copyTag);
|
||||
chechUniqueCharacterId(copyTag);
|
||||
checkUniqueCharacterId(copyTag);
|
||||
targetSwf.updateCharacters();
|
||||
copyTag.setModified(true);
|
||||
}
|
||||
@@ -780,7 +788,7 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
copyTag.setSwf(targetSwf, true);
|
||||
targetSwf.addTag(copyTag);
|
||||
int oldCharacterId = neededTag.getCharacterId();
|
||||
int newCharacterId = chechUniqueCharacterId(copyTag);
|
||||
int newCharacterId = checkUniqueCharacterId(copyTag);
|
||||
changedCharacterIds.put(oldCharacterId, newCharacterId);
|
||||
|
||||
targetSwf.updateCharacters();
|
||||
@@ -797,7 +805,7 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
if (tag instanceof CharacterTag) {
|
||||
CharacterTag characterTag = (CharacterTag) copyTag;
|
||||
int oldCharacterId = characterTag.getCharacterId();
|
||||
int newCharacterId = chechUniqueCharacterId(copyTag);
|
||||
int newCharacterId = checkUniqueCharacterId(copyTag);
|
||||
changedCharacterIds.put(oldCharacterId, newCharacterId);
|
||||
}
|
||||
|
||||
@@ -1764,7 +1772,7 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
timelined.addTag(idx + 1, copyTag);
|
||||
copyTag.setTimelined(timelined);
|
||||
|
||||
chechUniqueCharacterId(copyTag);
|
||||
checkUniqueCharacterId(copyTag);
|
||||
copyTag.setModified(true);
|
||||
|
||||
timelined.resetTimeline();
|
||||
@@ -1792,7 +1800,7 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
timelined.addTag(++i, copyTag);
|
||||
copyTag.setTimelined(timelined);
|
||||
|
||||
chechUniqueCharacterId(copyTag);
|
||||
checkUniqueCharacterId(copyTag);
|
||||
copyTag.setModified(true);
|
||||
}
|
||||
|
||||
@@ -1818,4 +1826,40 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
logger.log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void setTagPositionActionPerformed(ActionEvent evt) {
|
||||
List<TreeItem> items = tagTree.getSelected();
|
||||
Tag t = (Tag)items.get(0);
|
||||
TreePath path = tagTree.getSelectionPath();
|
||||
Timelined timelined = null;
|
||||
for (int i = path.getPathCount()-1; i >= 0; i--) {
|
||||
if ((path.getPathComponent(i) instanceof DefineSpriteTag)||(path.getPathComponent(i) instanceof SWF)) {
|
||||
timelined = (Timelined)path.getPathComponent(i);
|
||||
}
|
||||
}
|
||||
if (timelined == null) { //should not happen
|
||||
return;
|
||||
}
|
||||
|
||||
SelectTagPositionDialog dialog = new SelectTagPositionDialog(Main.getDefaultDialogsOwner(), t.getSwf(), t, timelined);
|
||||
if (dialog.showDialog() == AppDialog.OK_OPTION){
|
||||
Tag selectedTag = dialog.getSelectedTag();
|
||||
Timelined selectedTimelined = dialog.getSelectedTimelined();
|
||||
|
||||
if (selectedTag == t && selectedTimelined == timelined) {
|
||||
return;
|
||||
}
|
||||
timelined.removeTag(t);
|
||||
if (selectedTag == null) {
|
||||
selectedTimelined.addTag(t);
|
||||
} else {
|
||||
selectedTimelined.addTag(selectedTimelined.indexOfTag(selectedTag), t);
|
||||
}
|
||||
timelined.resetTimeline();
|
||||
if (timelined != selectedTimelined) {
|
||||
selectedTimelined.resetTimeline();
|
||||
}
|
||||
mainPanel.refreshTree(t.getSwf());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user