mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-25 13:40:46 +00:00
Timeline view with preview and object hilighting.
Embedded timeline view instead of new window. code formatting
This commit is contained in:
@@ -17,12 +17,14 @@
|
||||
package com.jpexs.decompiler.flash.gui;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.exporters.ShapeExporter;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
|
||||
import com.jpexs.decompiler.flash.gui.player.MediaDisplay;
|
||||
import com.jpexs.decompiler.flash.tags.DefineButtonSoundTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.DrawableTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundTag;
|
||||
import com.jpexs.decompiler.flash.timeline.DepthState;
|
||||
import com.jpexs.decompiler.flash.timeline.Timeline;
|
||||
@@ -85,6 +87,14 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
private final List<SoundTagPlayer> soundPlayers = new ArrayList<>();
|
||||
private final IconPanel iconPanel;
|
||||
private int time = 0;
|
||||
private int selectedDepth = -1;
|
||||
|
||||
public void selectDepth(int depth) {
|
||||
if (depth != selectedDepth) {
|
||||
this.selectedDepth = depth;
|
||||
}
|
||||
hideMouseSelection();
|
||||
}
|
||||
|
||||
private class IconPanel extends JPanel {
|
||||
|
||||
@@ -271,6 +281,26 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
}
|
||||
}
|
||||
|
||||
private void showSelectedName() {
|
||||
if (selectedDepth > -1 && frame > -1) {
|
||||
DepthState ds = timelined.getTimeline().frames.get(frame).layers.get(selectedDepth);
|
||||
if (ds != null) {
|
||||
CharacterTag cht = timelined.getTimeline().swf.characters.get(ds.characterId);
|
||||
if (cht != null) {
|
||||
debugLabel.setText(cht.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void hideMouseSelection() {
|
||||
if (selectedDepth > -1) {
|
||||
showSelectedName();
|
||||
} else {
|
||||
debugLabel.setText(" - ");
|
||||
}
|
||||
}
|
||||
|
||||
public ImagePanel() {
|
||||
super(new BorderLayout());
|
||||
//iconPanel.setHorizontalAlignment(JLabel.CENTER);
|
||||
@@ -301,8 +331,9 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
stateUnderCursor = null;
|
||||
lastMouseEvent = null;
|
||||
drawFrame();
|
||||
debugLabel.setText(" - ");
|
||||
hideMouseSelection();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -489,8 +520,8 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
}
|
||||
}
|
||||
|
||||
private static SerializableImage getFrame(SWF swf, int frame, int time, Timelined drawable, DepthState stateUnderCursor, int mouseButton) {
|
||||
String key = "drawable_" + frame + "_" + drawable.hashCode() + "_" + mouseButton + "_" + (stateUnderCursor == null ? "out" : stateUnderCursor.hashCode());
|
||||
private static SerializableImage getFrame(SWF swf, int frame, int time, Timelined drawable, DepthState stateUnderCursor, int mouseButton, int selectedDepth) {
|
||||
String key = "drawable_" + frame + "_" + drawable.hashCode() + "_" + mouseButton + "_depth" + selectedDepth + "_" + (stateUnderCursor == null ? "out" : stateUnderCursor.hashCode());
|
||||
SerializableImage img = SWF.getFromCache(key);
|
||||
if (img == null) {
|
||||
if (drawable instanceof BoundedTag) {
|
||||
@@ -514,6 +545,30 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
gg.setTransform(AffineTransform.getTranslateInstance(0, 0));
|
||||
List<DepthState> dss = new ArrayList<>();
|
||||
List<Shape> os = new ArrayList<>();
|
||||
DepthState ds = drawable.getTimeline().frames.get(frame).layers.get(selectedDepth);
|
||||
if (ds != null) {
|
||||
CharacterTag cht = swf.characters.get(ds.characterId);
|
||||
if (cht != null) {
|
||||
if (cht instanceof DrawableTag) {
|
||||
DrawableTag dt = (DrawableTag) cht;
|
||||
Shape outline = dt.getOutline(0, ds.time, ds.ratio, stateUnderCursor, mouseButton, new Matrix(ds.matrix));
|
||||
Rectangle bounds = outline.getBounds();
|
||||
bounds.x /= 20;
|
||||
bounds.y /= 20;
|
||||
bounds.width /= 20;
|
||||
bounds.height /= 20;
|
||||
bounds.x -= rect.Xmin / 20;
|
||||
bounds.y -= rect.Ymin / 20;
|
||||
//SHAPERECORD.resizeSHAPE(outline, 1/20)
|
||||
gg.setStroke(new BasicStroke(2.0f,
|
||||
BasicStroke.CAP_BUTT,
|
||||
BasicStroke.JOIN_MITER,
|
||||
10.0f, new float[]{10.0f}, 0.0f));
|
||||
gg.setPaint(Color.red);
|
||||
gg.draw(bounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*drawable.getTimeline().getObjectsOutlines(frame, frame, stateUnderCursor, mouseButton, m, dss, os);
|
||||
|
||||
//gg.setTransform(AffineTransform.getTranslateInstance(0, 0));
|
||||
@@ -544,7 +599,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
mat.translateX = swf.displayRect.Xmin;
|
||||
mat.translateY = swf.displayRect.Ymin;
|
||||
updatePos(lastMouseEvent, false);
|
||||
SerializableImage img = getFrame(swf, frame, time, timelined, stateUnderCursor, mouseButton);
|
||||
SerializableImage img = getFrame(swf, frame, time, timelined, stateUnderCursor, mouseButton, selectedDepth);
|
||||
List<Integer> sounds = new ArrayList<>();
|
||||
List<String> soundClasses = new ArrayList<>();
|
||||
timeline.getSounds(frame, time, stateUnderCursor, mouseButton, sounds, soundClasses);
|
||||
|
||||
@@ -48,6 +48,7 @@ import javax.swing.JDialog;
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JToggleButton;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.pushingpixels.flamingo.api.common.AbstractCommandButton;
|
||||
import org.pushingpixels.flamingo.api.common.CommandButtonDisplayState;
|
||||
@@ -122,6 +123,7 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
|
||||
static final String ACTION_CHECK_RESOURCES = "CHECKRESOURCES";
|
||||
static final String ACTION_VIEWMODE_RESOURCES = "VIEWMODERESOURCES";
|
||||
static final String ACTION_VIEWMODE_HEX = "VIEWMODEHEX";
|
||||
static final String ACTION_VIEWMODE_TIMELINE = "VIEWMODETIMELINE";
|
||||
static final String ACTION_DEOBFUSCATION_MODE_OLD = "DEOBFUSCATIONMODEOLD";
|
||||
static final String ACTION_DEOBFUSCATION_MODE_NEW = "DEOBFUSCATIONMODENEW";
|
||||
|
||||
@@ -153,10 +155,13 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
|
||||
private JCommandButton globalrenameCommandButton;
|
||||
private JCommandButton deobfuscationCommandButton;
|
||||
private JCommandButton searchCommandButton;
|
||||
private JCommandButton timeLineCommandButton;
|
||||
private JCommandToggleButton timeLineToggleButton;
|
||||
private CommandToggleButtonGroup timeLineToggleGroup;
|
||||
private JCommandButton gotoDocumentClassCommandButton;
|
||||
private JCommandButton clearRecentFilesCommandButton;
|
||||
|
||||
private CommandToggleButtonGroup viewModeToggleGroup;
|
||||
|
||||
RibbonApplicationMenuEntryPrimary exportFlaMenu;
|
||||
RibbonApplicationMenuEntryPrimary exportAllMenu;
|
||||
RibbonApplicationMenuEntryPrimary exportSelMenu;
|
||||
@@ -280,7 +285,7 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
|
||||
resizePolicies.add(new BaseRibbonBandResizePolicy<AbstractBandControlPanel>(ribbonBand.getControlPanel()) {
|
||||
@Override
|
||||
public int getPreferredWidth(int i, int i1) {
|
||||
return ribbonBand.getGraphics().getFontMetrics(ribbonBand.getFont()).stringWidth(ribbonBand.getTitle())+20;
|
||||
return ribbonBand.getGraphics().getFontMetrics(ribbonBand.getFont()).stringWidth(ribbonBand.getTitle()) + 20;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -357,7 +362,7 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
|
||||
JRibbonBand viewBand = new JRibbonBand(translate("menu.view"), null);
|
||||
viewBand.setResizePolicies(getResizePolicies(viewBand));
|
||||
|
||||
CommandToggleButtonGroup grpViewMode = new CommandToggleButtonGroup();
|
||||
viewModeToggleGroup = new CommandToggleButtonGroup();
|
||||
|
||||
viewModeResourcesToggleButton = new JCommandToggleButton(fixCommandTitle(translate("menu.file.view.resources")), View.getResizableIcon("viewresources16"));
|
||||
assignListener(viewModeResourcesToggleButton, ACTION_VIEWMODE_RESOURCES);
|
||||
@@ -365,13 +370,13 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
|
||||
viewModeHexToggleButton = new JCommandToggleButton(fixCommandTitle(translate("menu.file.view.hex")), View.getResizableIcon("viewhex16"));
|
||||
assignListener(viewModeHexToggleButton, ACTION_VIEWMODE_HEX);
|
||||
|
||||
grpViewMode.add(viewModeResourcesToggleButton);
|
||||
grpViewMode.add(viewModeHexToggleButton);
|
||||
viewModeToggleGroup.add(viewModeResourcesToggleButton);
|
||||
viewModeToggleGroup.add(viewModeHexToggleButton);
|
||||
|
||||
if (Configuration.dumpView.get()) {
|
||||
grpViewMode.setSelected(viewModeHexToggleButton, true);
|
||||
viewModeToggleGroup.setSelected(viewModeHexToggleButton, true);
|
||||
} else {
|
||||
grpViewMode.setSelected(viewModeResourcesToggleButton, true);
|
||||
viewModeToggleGroup.setSelected(viewModeResourcesToggleButton, true);
|
||||
}
|
||||
|
||||
viewBand.addCommandButton(viewModeResourcesToggleButton, RibbonElementPriority.MEDIUM);
|
||||
@@ -389,8 +394,11 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
|
||||
searchCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.search")), View.getResizableIcon("search32"));
|
||||
assignListener(searchCommandButton, ACTION_SEARCH);
|
||||
|
||||
timeLineCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.timeline")), View.getResizableIcon("timeline32"));
|
||||
assignListener(timeLineCommandButton, ACTION_TIMELINE);
|
||||
timeLineToggleButton = new JCommandToggleButton(fixCommandTitle(translate("menu.tools.timeline")), View.getResizableIcon("timeline32"));
|
||||
assignListener(timeLineToggleButton, ACTION_TIMELINE);
|
||||
|
||||
timeLineToggleGroup = new CommandToggleButtonGroup();
|
||||
timeLineToggleGroup.add(timeLineToggleButton);
|
||||
|
||||
gotoDocumentClassCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.gotodocumentclass")), View.getResizableIcon("gotomainclass32"));
|
||||
assignListener(gotoDocumentClassCommandButton, ACTION_GOTO_DOCUMENT_CLASS);
|
||||
@@ -405,7 +413,7 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
|
||||
assignListener(loadCacheCommandButton, ACTION_LOAD_CACHE);
|
||||
|
||||
toolsBand.addCommandButton(searchCommandButton, RibbonElementPriority.TOP);
|
||||
toolsBand.addCommandButton(timeLineCommandButton, RibbonElementPriority.TOP);
|
||||
toolsBand.addCommandButton(timeLineToggleButton, RibbonElementPriority.TOP);
|
||||
toolsBand.addCommandButton(gotoDocumentClassCommandButton, RibbonElementPriority.TOP);
|
||||
toolsBand.addCommandButton(proxyCommandButton, RibbonElementPriority.MEDIUM);
|
||||
toolsBand.addCommandButton(loadMemoryCommandButton, RibbonElementPriority.MEDIUM);
|
||||
@@ -614,7 +622,7 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
|
||||
globalrenameCommandButton.setEnabled(swfLoaded);
|
||||
deobfuscationCommandButton.setEnabled(swfLoaded);
|
||||
searchCommandButton.setEnabled(swfLoaded);
|
||||
timeLineCommandButton.setEnabled(swfLoaded);
|
||||
timeLineToggleButton.setEnabled(swfLoaded);
|
||||
|
||||
gotoDocumentClassCommandButton.setEnabled(hasAbc);
|
||||
deobfuscationCommandButton.setEnabled(hasAbc);
|
||||
@@ -705,11 +713,13 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
|
||||
|
||||
case ACTION_VIEWMODE_RESOURCES:
|
||||
Configuration.dumpView.set(false);
|
||||
mainFrame.panel.showDumpView(false);
|
||||
mainFrame.panel.showView(MainPanel.VIEW_RESOURCES);
|
||||
timeLineToggleGroup.setSelected(timeLineToggleButton, false);
|
||||
break;
|
||||
case ACTION_VIEWMODE_HEX:
|
||||
Configuration.dumpView.set(true);
|
||||
mainFrame.panel.showDumpView(true);
|
||||
mainFrame.panel.showView(MainPanel.VIEW_DUMP);
|
||||
timeLineToggleGroup.setSelected(timeLineToggleButton, false);
|
||||
break;
|
||||
case ACTION_DEOBFUSCATION_MODE_OLD:
|
||||
Configuration.deobfuscationMode.set(0);
|
||||
@@ -719,15 +729,28 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
|
||||
Configuration.deobfuscationMode.set(1);
|
||||
mainFrame.panel.autoDeobfuscateChanged();
|
||||
break;
|
||||
case ACTION_DUMP_VIEW_SWITCH:
|
||||
Configuration.dumpView.set(miDumpView.isSelected());
|
||||
mainFrame.panel.showDumpView(miDumpView.isSelected());
|
||||
break;
|
||||
case ACTION_SEARCH:
|
||||
mainFrame.panel.searchAs();
|
||||
break;
|
||||
case ACTION_TIMELINE:
|
||||
mainFrame.panel.timeline();
|
||||
timeLineToggleGroup.setSelected(timeLineToggleButton, timeLineToggleGroup.getSelected() == timeLineToggleButton);
|
||||
if (timeLineToggleGroup.getSelected() == timeLineToggleButton) {
|
||||
if (!mainFrame.panel.showView(MainPanel.VIEW_TIMELINE)) {
|
||||
timeLineToggleGroup.setSelected(timeLineToggleButton, false);
|
||||
} else {
|
||||
viewModeToggleGroup.setSelected(viewModeHexToggleButton, false);
|
||||
viewModeToggleGroup.setSelected(viewModeResourcesToggleButton, false);
|
||||
}
|
||||
} else {
|
||||
if (Configuration.dumpView.get()) {
|
||||
viewModeToggleGroup.setSelected(viewModeHexToggleButton, true);
|
||||
mainFrame.panel.showView(MainPanel.VIEW_DUMP);
|
||||
} else {
|
||||
viewModeToggleGroup.setSelected(viewModeResourcesToggleButton, true);
|
||||
mainFrame.panel.showView(MainPanel.VIEW_RESOURCES);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case ACTION_AUTO_DEOBFUSCATE:
|
||||
if (View.showConfirmDialog(mainFrame.panel, translate("message.confirm.autodeobfuscate") + "\r\n" + (miAutoDeobfuscation.isSelected() ? translate("message.confirm.on") : translate("message.confirm.off")), translate("message.confirm"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
|
||||
|
||||
@@ -63,7 +63,8 @@ import com.jpexs.decompiler.flash.gui.dumpview.DumpTree;
|
||||
import com.jpexs.decompiler.flash.gui.dumpview.DumpTreeModel;
|
||||
import com.jpexs.decompiler.flash.gui.dumpview.DumpViewPanel;
|
||||
import com.jpexs.decompiler.flash.gui.player.FlashPlayerPanel;
|
||||
import com.jpexs.decompiler.flash.gui.timeline.TimelineFrame;
|
||||
import com.jpexs.decompiler.flash.gui.timeline.TimelineViewPanel;
|
||||
import com.jpexs.decompiler.flash.gui.timeline.TimelinePanel;
|
||||
import com.jpexs.decompiler.flash.gui.treenodes.SWFBundleNode;
|
||||
import com.jpexs.decompiler.flash.gui.treenodes.SWFNode;
|
||||
import com.jpexs.decompiler.flash.gui.treenodes.StringNode;
|
||||
@@ -219,6 +220,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
private ABCPanel abcPanel;
|
||||
private ActionPanel actionPanel;
|
||||
private final JPanel welcomePanel;
|
||||
private final TimelineViewPanel timelineViewPanel;
|
||||
private final MainFrameStatusPanel statusPanel;
|
||||
private final MainFrameMenu mainMenu;
|
||||
private final JProgressBar progressBar = new JProgressBar(0, 100);
|
||||
@@ -241,6 +243,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
private static final String DETAILCARDEMPTYPANEL = "Empty card";
|
||||
private static final String SPLIT_PANE1 = "SPLITPANE1";
|
||||
private static final String WELCOME_PANEL = "WELCOMEPANEL";
|
||||
private static final String TIMELINE_PANEL = "TIMELINEPANEL";
|
||||
private final JSplitPane splitPane1;
|
||||
private final JSplitPane splitPane2;
|
||||
private boolean splitsInited = false;
|
||||
@@ -560,10 +563,13 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
}
|
||||
});
|
||||
|
||||
timelineViewPanel = new TimelineViewPanel();
|
||||
|
||||
CardLayout cl3 = new CardLayout();
|
||||
contentPanel = new JPanel(cl3);
|
||||
contentPanel.add(welcomePanel, WELCOME_PANEL);
|
||||
contentPanel.add(splitPane1, SPLIT_PANE1);
|
||||
contentPanel.add(timelineViewPanel, TIMELINE_PANEL);
|
||||
add(contentPanel);
|
||||
cl3.show(contentPanel, WELCOME_PANEL);
|
||||
|
||||
@@ -578,7 +584,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
});
|
||||
detailPanel.setVisible(false);
|
||||
|
||||
showDumpView(Configuration.dumpView.get());
|
||||
showView(Configuration.dumpView.get() ? VIEW_DUMP : VIEW_RESOURCES);
|
||||
updateUi();
|
||||
|
||||
//Opening files with drag&drop to main window
|
||||
@@ -2143,19 +2149,52 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
return mainMenu.isInternalFlashViewerSelected();
|
||||
}
|
||||
|
||||
public void showDumpView(boolean show) {
|
||||
treePanel.removeAll();
|
||||
if (show) {
|
||||
treePanel.add(new JScrollPane(dumpTree), BorderLayout.CENTER);
|
||||
treePanelMode = TreePanelMode.DUMP_TREE;
|
||||
showDetail(DETAILCARDEMPTYPANEL);
|
||||
} else {
|
||||
treePanel.add(new JScrollPane(tagTree), BorderLayout.CENTER);
|
||||
treePanel.add(searchPanel, BorderLayout.SOUTH);
|
||||
treePanelMode = TreePanelMode.TAG_TREE;
|
||||
public static final int VIEW_RESOURCES = 0;
|
||||
public static final int VIEW_DUMP = 1;
|
||||
public static final int VIEW_TIMELINE = 2;
|
||||
|
||||
public boolean showView(int view) {
|
||||
|
||||
CardLayout cl = (CardLayout) (contentPanel.getLayout());
|
||||
switch (view) {
|
||||
case VIEW_DUMP:
|
||||
if (!isWelcomeScreen) {
|
||||
cl.show(contentPanel, SPLIT_PANE1);
|
||||
}
|
||||
treePanel.removeAll();
|
||||
treePanel.add(new JScrollPane(dumpTree), BorderLayout.CENTER);
|
||||
treePanelMode = TreePanelMode.DUMP_TREE;
|
||||
showDetail(DETAILCARDEMPTYPANEL);
|
||||
reload(true);
|
||||
treePanel.revalidate();
|
||||
return true;
|
||||
case VIEW_RESOURCES:
|
||||
if (!isWelcomeScreen) {
|
||||
cl.show(contentPanel, SPLIT_PANE1);
|
||||
}
|
||||
treePanel.removeAll();
|
||||
treePanel.add(new JScrollPane(tagTree), BorderLayout.CENTER);
|
||||
treePanel.add(searchPanel, BorderLayout.SOUTH);
|
||||
treePanelMode = TreePanelMode.TAG_TREE;
|
||||
reload(true);
|
||||
treePanel.revalidate();
|
||||
return true;
|
||||
case VIEW_TIMELINE:
|
||||
final SWF swf = getCurrentSwf();
|
||||
if (swf != null) {
|
||||
TreeItem item = tagTree.getCurrentTreeItem();
|
||||
if (item instanceof DefineSpriteTag) {
|
||||
timelineViewPanel.setTimelined((DefineSpriteTag) item);
|
||||
} else {
|
||||
timelineViewPanel.setTimelined(swf);
|
||||
}
|
||||
cl.show(contentPanel, TIMELINE_PANEL);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
reload(true);
|
||||
treePanel.revalidate();
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
private void dumpViewReload(boolean forceReload) {
|
||||
@@ -2499,21 +2538,6 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
statusPanel.setErrorState(errorState);
|
||||
}
|
||||
|
||||
public void timeline() {
|
||||
final SWF swf = getCurrentSwf();
|
||||
if (swf != null) {
|
||||
TreeItem item = tagTree.getCurrentTreeItem();
|
||||
if (item instanceof DefineSpriteTag) {
|
||||
TimelineFrame tf = new TimelineFrame((DefineSpriteTag) item);
|
||||
tf.setVisible(true);
|
||||
return;
|
||||
}
|
||||
|
||||
TimelineFrame tf = new TimelineFrame(swf);
|
||||
tf.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
public static Timelined makeTimelined(final Tag tag) {
|
||||
|
||||
return new Timelined() {
|
||||
|
||||
@@ -141,7 +141,7 @@ public class NewVersionDialog extends AppDialog implements ActionListener {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (e.getActionCommand() == ACTION_OK) {
|
||||
String url;
|
||||
String url;
|
||||
if (latestVersion.updateLink != null) {
|
||||
url = latestVersion.updateLink;
|
||||
} else {
|
||||
|
||||
@@ -537,8 +537,7 @@ public class View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ public class DumpViewPanel extends JPanel {
|
||||
super(new BorderLayout());
|
||||
|
||||
this.dumpTree = dumpTree;
|
||||
|
||||
|
||||
selectedByteInfo = new JLabel();
|
||||
selectedByteInfo.setMinimumSize(new Dimension(100, 20));
|
||||
selectedByteInfo.setText("-");
|
||||
@@ -64,13 +64,13 @@ public class DumpViewPanel extends JPanel {
|
||||
dumpViewHexTable.addListener(new HexViewListener() {
|
||||
|
||||
private int lastAddressUnderCursor = -1;
|
||||
|
||||
|
||||
@Override
|
||||
public void byteValueChanged(int address, byte b) {
|
||||
if (skipValueChange) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (address != -1) {
|
||||
TreeModel model = dumpTree.getModel();
|
||||
DumpInfo di = DumpInfoSwfNode.getSwfNode(selectedDumpInfo);
|
||||
@@ -100,7 +100,7 @@ public class DumpViewPanel extends JPanel {
|
||||
dumpTree.setSelectionPath(tp);
|
||||
dumpTree.scrollPathToVisible(tp);
|
||||
}
|
||||
|
||||
|
||||
byte[] data = dumpViewHexTable.getData();
|
||||
byteMouseMoved(lastAddressUnderCursor, lastAddressUnderCursor == -1 ? 0 : data[lastAddressUnderCursor]);
|
||||
}
|
||||
@@ -115,20 +115,20 @@ public class DumpViewPanel extends JPanel {
|
||||
b = data[address];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (address != -1) {
|
||||
int b2 = b & 0xff;
|
||||
selectedByteInfo.setText("Addr: " + Helper.padZeros(address, 8) +
|
||||
" Hex: " + Helper.padZeros(Integer.toHexString(b2), 2) +
|
||||
" Dec: " + b2 +
|
||||
" Bin: " + Helper.padZeros(Integer.toBinaryString(b2), 8) +
|
||||
" Ascii: " + (char) b2);
|
||||
selectedByteInfo.setText("Addr: " + Helper.padZeros(address, 8)
|
||||
+ " Hex: " + Helper.padZeros(Integer.toHexString(b2), 2)
|
||||
+ " Dec: " + b2
|
||||
+ " Bin: " + Helper.padZeros(Integer.toBinaryString(b2), 8)
|
||||
+ " Ascii: " + (char) b2);
|
||||
} else {
|
||||
selectedByteInfo.setText("-");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
add(new JScrollPane(dumpViewHexTable), BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ public class DumpViewPanel extends JPanel {
|
||||
skipNextScroll = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
this.selectedDumpInfo = dumpInfo;
|
||||
byte[] data = DumpInfoSwfNode.getSwfNode(dumpInfo).getSwf().originalUncompressedData;
|
||||
List<DumpInfo> dumpInfos = new ArrayList<>();
|
||||
|
||||
@@ -50,11 +50,11 @@ public class HexView extends JTable {
|
||||
private final Color bgColorAlternate = Color.decode("#EDEDED");
|
||||
private int mouseOverIdx = -1;
|
||||
private HexViewListener listener;
|
||||
|
||||
|
||||
private class HighlightCellRenderer extends DefaultTableCellRenderer {
|
||||
|
||||
public int byteIndex;
|
||||
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
|
||||
|
||||
@@ -81,7 +81,7 @@ public class HexView extends JTable {
|
||||
foreground = Color.black;
|
||||
background = row % 2 == 0 ? bgColor : bgColorAlternate;
|
||||
}
|
||||
|
||||
|
||||
if (idx != -1 && idx == mouseOverIdx) {
|
||||
foreground = new Color(255 - foreground.getRed(), 255 - foreground.getGreen(), 255 - foreground.getBlue());
|
||||
background = new Color(255 - background.getRed(), 255 - background.getGreen(), 255 - background.getBlue());
|
||||
@@ -92,18 +92,18 @@ public class HexView extends JTable {
|
||||
return l;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class HexViewSelectionListener implements ListSelectionListener {
|
||||
|
||||
private final HexView table;
|
||||
|
||||
|
||||
public HexViewSelectionListener(HexView table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
|
||||
|
||||
int col = table.getSelectedColumn();
|
||||
int row = table.getSelectedRow();
|
||||
|
||||
@@ -118,7 +118,7 @@ public class HexView extends JTable {
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
HexView table = (HexView) e.getSource();
|
||||
HexView table = (HexView) e.getSource();
|
||||
Point point = e.getPoint();
|
||||
int col = table.columnAtPoint(point);
|
||||
int row = table.rowAtPoint(point);
|
||||
@@ -131,17 +131,17 @@ public class HexView extends JTable {
|
||||
}
|
||||
|
||||
private class HexViewMouseMotionAdapter extends MouseMotionAdapter {
|
||||
|
||||
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
HexView table = (HexView) e.getSource();
|
||||
HexView table = (HexView) e.getSource();
|
||||
Point point = e.getPoint();
|
||||
int col = table.columnAtPoint(point);
|
||||
int row = table.rowAtPoint(point);
|
||||
int idx = getIdxByColAndRow(row, col);
|
||||
mouseOverIdx = idx;
|
||||
getModel().fireTableCellUpdated(row, col);
|
||||
|
||||
|
||||
if (listener != null) {
|
||||
listener.byteMouseMoved(idx, idx == -1 ? 0 : getModel().getData()[idx]);
|
||||
}
|
||||
@@ -182,7 +182,7 @@ public class HexView extends JTable {
|
||||
column.setMaxWidth(10);
|
||||
column.setCellRenderer(cellRenderer);
|
||||
}
|
||||
|
||||
|
||||
addMouseListener(new HexViewMouseAdapter());
|
||||
addMouseMotionListener(new HexViewMouseMotionAdapter());
|
||||
ListSelectionModel rowSelModel = getSelectionModel();
|
||||
@@ -195,9 +195,9 @@ public class HexView extends JTable {
|
||||
@Override
|
||||
public HexViewTableModel getModel() {
|
||||
TableModel model = super.getModel();
|
||||
return (HexViewTableModel) model;
|
||||
return (HexViewTableModel) model;
|
||||
}
|
||||
|
||||
|
||||
public void setData(byte[] data, long[] highlightStarts, long[] highlightEnds) {
|
||||
|
||||
if ((highlightStarts == null) ^ (highlightEnds == null)) {
|
||||
@@ -216,7 +216,7 @@ public class HexView extends JTable {
|
||||
public byte[] getData() {
|
||||
return getModel().getData();
|
||||
}
|
||||
|
||||
|
||||
public void scrollToByte(long byteNum) {
|
||||
|
||||
int row = (int) (byteNum / bytesInRow);
|
||||
@@ -237,7 +237,7 @@ public class HexView extends JTable {
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
public int getFocusedByteIdx() {
|
||||
int col = getSelectedColumn();
|
||||
int row = getSelectedRow();
|
||||
@@ -245,7 +245,7 @@ public class HexView extends JTable {
|
||||
int idx = getIdxByColAndRow(row, col);
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
public void scrollToByte(long[] byteNumStarts, long[] byteNumEnds) {
|
||||
for (int i = 0; i < byteNumStarts.length; i++) {
|
||||
scrollToByte(byteNumStarts[i]);
|
||||
@@ -253,7 +253,7 @@ public class HexView extends JTable {
|
||||
scrollToByte(byteNumStarts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void addListener(HexViewListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import javax.swing.table.AbstractTableModel;
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class HexViewTableModel extends AbstractTableModel {
|
||||
|
||||
|
||||
private byte[] data;
|
||||
private final int bytesInRow;
|
||||
|
||||
@@ -79,15 +79,15 @@ public class HexViewTableModel extends AbstractTableModel {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
public void setData(byte[] data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void fireTableCellUpdated(int row, int columnd) {
|
||||
super.fireTableCellUpdated(bytesInRow, bytesInRow);
|
||||
|
||||
@@ -369,9 +369,9 @@ public class ProxyFrame extends AppFrame implements ActionListener, CatchedListe
|
||||
if ((!sniffOSCheckBox.isSelected()) && (contentType.equals("application/octet-stream"))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
byte[] result = null;
|
||||
|
||||
|
||||
if (!listModel.contains(url)) {
|
||||
try {
|
||||
byte[] hdr = new byte[3];
|
||||
@@ -387,16 +387,16 @@ public class ProxyFrame extends AppFrame implements ActionListener, CatchedListe
|
||||
try (FileOutputStream fos = new FileOutputStream(new File(tempFilePath))) {
|
||||
fos.write(dataArray);
|
||||
}
|
||||
|
||||
|
||||
result = SWFDecompilerPlugin.fireProxyFileCatched(dataArray);
|
||||
|
||||
|
||||
Replacement r = new Replacement(url, tempFilePath);
|
||||
r.lastAccess = Calendar.getInstance();
|
||||
listModel.addURL(r);
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,273 +1,311 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.timeline;
|
||||
|
||||
import com.jpexs.decompiler.flash.timeline.DepthState;
|
||||
import com.jpexs.decompiler.flash.timeline.Timeline;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class TimelineBodyPanel extends JPanel implements MouseListener {
|
||||
|
||||
private final Timeline timeLine;
|
||||
|
||||
public static Color frameColor = Color.lightGray;
|
||||
public static Color emptyFrameColor = Color.white;
|
||||
public static Color emptyFrameSecondColor = new Color(0xed, 0xed, 0xed);
|
||||
public static Color borderColor = Color.black;
|
||||
public static Color emptyBorderColor = Color.lightGray;
|
||||
public static Color keyColor = Color.black;
|
||||
public static Color aColor = Color.black;
|
||||
public static Color stopColor = Color.white;
|
||||
public static Color stopBorderColor = Color.black;
|
||||
public static Color borderLinesColor = new Color(0xde, 0xde, 0xde);
|
||||
|
||||
public static Color selectedColor = new Color(113, 174, 235);
|
||||
public static final int borderLinesLength = 2;
|
||||
public static final float fontSize = 10.0f;
|
||||
|
||||
private final List<FrameSelectionListener> listeners = new ArrayList<>();
|
||||
|
||||
public Point cursor = null;
|
||||
|
||||
public void addFrameSelectionListener(FrameSelectionListener l) {
|
||||
listeners.add(l);
|
||||
}
|
||||
|
||||
public void removeFrameSelectionListener(FrameSelectionListener l) {
|
||||
listeners.remove(l);
|
||||
}
|
||||
|
||||
public TimelineBodyPanel(Timeline timeLine) {
|
||||
|
||||
this.timeLine = timeLine;
|
||||
Dimension dim = new Dimension(TimelinePanel.FRAME_WIDTH * timeLine.getFrameCount() + 1, TimelinePanel.FRAME_HEIGHT * timeLine.getMaxDepth());
|
||||
setSize(dim);
|
||||
setPreferredSize(dim);
|
||||
addMouseListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g1) {
|
||||
Graphics2D g = (Graphics2D) g1;
|
||||
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
g.setColor(TimelinePanel.backgroundColor);
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
Rectangle clip = g.getClipBounds();
|
||||
int start_f = clip.x / TimelinePanel.FRAME_WIDTH;
|
||||
int start_d = clip.y / TimelinePanel.FRAME_HEIGHT;
|
||||
int end_f = (clip.x + clip.width) / TimelinePanel.FRAME_WIDTH;
|
||||
int end_d = (clip.y + clip.height) / TimelinePanel.FRAME_HEIGHT;
|
||||
|
||||
int max_d = timeLine.getMaxDepth();
|
||||
if (max_d < end_d) {
|
||||
end_d = max_d;
|
||||
}
|
||||
int max_f = timeLine.getFrameCount() - 1;
|
||||
if (max_f < end_f) {
|
||||
end_f = max_f;
|
||||
}
|
||||
|
||||
if (end_d - start_d + 1 < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean keyfound[] = new boolean[end_d - start_d + 1];
|
||||
|
||||
for (int f = start_f; f <= end_f; f++) {
|
||||
for (int d = start_d; d <= end_d; d++) {
|
||||
DepthState fl = timeLine.frames.get(f).layers.get(d);
|
||||
if (fl == null) {
|
||||
if ((f + 1) % 5 == 0) {
|
||||
g.setColor(emptyFrameSecondColor);
|
||||
} else {
|
||||
g.setColor(emptyFrameColor);
|
||||
}
|
||||
g.fillRect(f * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT, TimelinePanel.FRAME_WIDTH, TimelinePanel.FRAME_HEIGHT);
|
||||
g.setColor(emptyBorderColor);
|
||||
g.drawRect(f * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT, TimelinePanel.FRAME_WIDTH, TimelinePanel.FRAME_HEIGHT);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int f = start_f; f <= end_f; f++) {
|
||||
for (int d = start_d; d <= end_d; d++) {
|
||||
DepthState fl = timeLine.frames.get(f).layers.get(d);
|
||||
DepthState flNext = null;
|
||||
if (f < max_f) {
|
||||
flNext = timeLine.frames.get(f + 1).layers.get(d);
|
||||
}
|
||||
boolean selected = false;
|
||||
if (cursor != null) {
|
||||
if (f == cursor.x && d == cursor.y) {
|
||||
selected = true;
|
||||
}
|
||||
}
|
||||
if (selected) {
|
||||
if (!(fl != null && (flNext == null || flNext.key))) {
|
||||
g.setColor(selectedColor);
|
||||
g.fillRect(f * TimelinePanel.FRAME_WIDTH + 1, d * TimelinePanel.FRAME_HEIGHT + 1, TimelinePanel.FRAME_WIDTH - 1, TimelinePanel.FRAME_HEIGHT - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (fl == null) {
|
||||
|
||||
if (d == 0) {
|
||||
if (timeLine.frames.get(f).action != null) {
|
||||
g.setColor(aColor);
|
||||
g.setFont(getFont().deriveFont(fontSize));
|
||||
int awidth = g.getFontMetrics().stringWidth("a");
|
||||
g.drawString("a", f * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 2 - awidth / 2, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT / 2 + fontSize / 2);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
|
||||
int draw_f = 0;
|
||||
if (fl.key) {
|
||||
draw_f = f;
|
||||
keyfound[d - start_d] = true;
|
||||
} else if (!keyfound[d - start_d]) {
|
||||
for (int k = f - 1; k >= 0; k--) {
|
||||
fl = timeLine.frames.get(k).layers.get(d);
|
||||
if (fl == null) {
|
||||
break;
|
||||
}
|
||||
if (fl.key) {
|
||||
keyfound[d - start_d] = true;
|
||||
draw_f = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
int num_frames = 1;
|
||||
for (int n = draw_f + 1; n < timeLine.getFrameCount(); n++) {
|
||||
fl = timeLine.frames.get(n).layers.get(d);
|
||||
if (fl == null) {
|
||||
break;
|
||||
}
|
||||
if (fl.key) {
|
||||
break;
|
||||
}
|
||||
num_frames++;
|
||||
}
|
||||
g.setColor(frameColor);
|
||||
g.fillRect(draw_f * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT, num_frames * TimelinePanel.FRAME_WIDTH, TimelinePanel.FRAME_HEIGHT);
|
||||
|
||||
if (selected) {
|
||||
g.setColor(selectedColor);
|
||||
g.fillRect(draw_f * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT, TimelinePanel.FRAME_WIDTH, TimelinePanel.FRAME_HEIGHT);
|
||||
}
|
||||
|
||||
g.setColor(borderColor);
|
||||
g.drawRect(draw_f * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT, num_frames * TimelinePanel.FRAME_WIDTH, TimelinePanel.FRAME_HEIGHT);
|
||||
g.setColor(keyColor);
|
||||
g.fillOval(draw_f * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 4, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT * 3 / 4 - TimelinePanel.FRAME_WIDTH / 2 / 2, TimelinePanel.FRAME_WIDTH / 2, TimelinePanel.FRAME_WIDTH / 2);
|
||||
if (num_frames > 1) {
|
||||
if (cursor != null && cursor.y == d && cursor.x == f + num_frames - 1) {
|
||||
g.setColor(selectedColor);
|
||||
g.fillRect((f + num_frames - 1) * TimelinePanel.FRAME_WIDTH + 1, d * TimelinePanel.FRAME_HEIGHT + 1, TimelinePanel.FRAME_WIDTH - 1, TimelinePanel.FRAME_HEIGHT - 1);
|
||||
}
|
||||
g.setColor(stopColor);
|
||||
g.fillRect((draw_f + num_frames - 1) * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 4, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT / 2 - 2, TimelinePanel.FRAME_WIDTH / 2, TimelinePanel.FRAME_HEIGHT / 2);
|
||||
g.setColor(stopBorderColor);
|
||||
g.drawRect((draw_f + num_frames - 1) * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 4, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT / 2 - 2, TimelinePanel.FRAME_WIDTH / 2, TimelinePanel.FRAME_HEIGHT / 2);
|
||||
|
||||
g.setColor(borderLinesColor);
|
||||
for (int n = draw_f + 1; n < draw_f + num_frames; n++) {
|
||||
g.drawLine(n * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT + 1, n * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT + borderLinesLength);
|
||||
g.drawLine(n * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT - 1, n * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT - borderLinesLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cursor != null && cursor.x >= start_f && cursor.x <= end_f) {
|
||||
g.setColor(TimelinePanel.selectedBorderColor);
|
||||
g.drawLine(cursor.x * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 2, 0, cursor.x * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 2, getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
|
||||
}
|
||||
|
||||
public void frameSelect(int frame, int depth) {
|
||||
if (cursor != null && cursor.x == frame && (cursor.y == depth || depth == -1)) {
|
||||
return;
|
||||
}
|
||||
if (depth == -1 && cursor != null) {
|
||||
depth = cursor.y;
|
||||
}
|
||||
cursor = new Point(frame, depth);
|
||||
for (FrameSelectionListener l : listeners) {
|
||||
l.frameSelected(frame, -1);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
Point p = e.getPoint();
|
||||
p.x = p.x / TimelinePanel.FRAME_WIDTH;
|
||||
p.y = p.y / TimelinePanel.FRAME_HEIGHT;
|
||||
if (p.x >= timeLine.getFrameCount()) {
|
||||
p.x = timeLine.getFrameCount() - 1;
|
||||
}
|
||||
int maxDepth = timeLine.getMaxDepth();
|
||||
if (p.y > maxDepth) {
|
||||
p.y = maxDepth;
|
||||
}
|
||||
frameSelect(p.x, p.y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.timeline;
|
||||
|
||||
import com.jpexs.decompiler.flash.timeline.DepthState;
|
||||
import com.jpexs.decompiler.flash.timeline.Timeline;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class TimelineBodyPanel extends JPanel implements MouseListener, KeyListener {
|
||||
|
||||
private final Timeline timeLine;
|
||||
|
||||
public static Color frameColor = new Color(0xbd, 0xd8, 0xfc);
|
||||
public static Color emptyFrameColor = Color.white;
|
||||
public static Color emptyFrameSecondColor = new Color(0xea, 0xf2, 0xfc);
|
||||
public static Color borderColor = Color.black;
|
||||
public static Color emptyBorderColor = new Color(0xbd, 0xd8, 0xfc);
|
||||
public static Color keyColor = Color.black;
|
||||
public static Color aColor = Color.black;
|
||||
public static Color stopColor = Color.white;
|
||||
public static Color stopBorderColor = Color.black;
|
||||
public static Color borderLinesColor = new Color(0xde, 0xde, 0xde);
|
||||
|
||||
public static Color selectedColor = new Color(113, 174, 235);
|
||||
public static final int borderLinesLength = 2;
|
||||
public static final float fontSize = 10.0f;
|
||||
|
||||
private final List<FrameSelectionListener> listeners = new ArrayList<>();
|
||||
|
||||
public Point cursor = null;
|
||||
|
||||
public void addFrameSelectionListener(FrameSelectionListener l) {
|
||||
listeners.add(l);
|
||||
}
|
||||
|
||||
public void removeFrameSelectionListener(FrameSelectionListener l) {
|
||||
listeners.remove(l);
|
||||
}
|
||||
|
||||
public TimelineBodyPanel(Timeline timeLine) {
|
||||
|
||||
this.timeLine = timeLine;
|
||||
Dimension dim = new Dimension(TimelinePanel.FRAME_WIDTH * timeLine.getFrameCount() + 1, TimelinePanel.FRAME_HEIGHT * timeLine.getMaxDepth());
|
||||
setSize(dim);
|
||||
setPreferredSize(dim);
|
||||
addMouseListener(this);
|
||||
addKeyListener(this);
|
||||
setFocusable(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g1) {
|
||||
Graphics2D g = (Graphics2D) g1;
|
||||
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
g.setColor(TimelinePanel.backgroundColor);
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
Rectangle clip = g.getClipBounds();
|
||||
int start_f = clip.x / TimelinePanel.FRAME_WIDTH;
|
||||
int start_d = clip.y / TimelinePanel.FRAME_HEIGHT;
|
||||
int end_f = (clip.x + clip.width) / TimelinePanel.FRAME_WIDTH;
|
||||
int end_d = (clip.y + clip.height) / TimelinePanel.FRAME_HEIGHT;
|
||||
|
||||
int max_d = timeLine.getMaxDepth();
|
||||
if (max_d < end_d) {
|
||||
end_d = max_d;
|
||||
}
|
||||
int max_f = timeLine.getFrameCount() - 1;
|
||||
if (max_f < end_f) {
|
||||
end_f = max_f;
|
||||
}
|
||||
|
||||
if (end_d - start_d + 1 < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean keyfound[] = new boolean[end_d - start_d + 1];
|
||||
|
||||
for (int f = start_f; f <= end_f; f++) {
|
||||
for (int d = start_d; d <= end_d; d++) {
|
||||
DepthState fl = timeLine.frames.get(f).layers.get(d);
|
||||
if (fl == null) {
|
||||
if ((f + 1) % 5 == 0) {
|
||||
g.setColor(emptyFrameSecondColor);
|
||||
} else {
|
||||
g.setColor(emptyFrameColor);
|
||||
}
|
||||
g.fillRect(f * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT, TimelinePanel.FRAME_WIDTH, TimelinePanel.FRAME_HEIGHT);
|
||||
g.setColor(emptyBorderColor);
|
||||
g.drawRect(f * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT, TimelinePanel.FRAME_WIDTH, TimelinePanel.FRAME_HEIGHT);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int f = start_f; f <= end_f; f++) {
|
||||
for (int d = start_d; d <= end_d; d++) {
|
||||
DepthState fl = timeLine.frames.get(f).layers.get(d);
|
||||
DepthState flNext = null;
|
||||
if (f < max_f) {
|
||||
flNext = timeLine.frames.get(f + 1).layers.get(d);
|
||||
}
|
||||
boolean selected = false;
|
||||
if (cursor != null) {
|
||||
if (f == cursor.x && d == cursor.y) {
|
||||
selected = true;
|
||||
}
|
||||
}
|
||||
if (selected) {
|
||||
if (!(fl != null && (flNext == null || flNext.key))) {
|
||||
g.setColor(selectedColor);
|
||||
g.fillRect(f * TimelinePanel.FRAME_WIDTH + 1, d * TimelinePanel.FRAME_HEIGHT + 1, TimelinePanel.FRAME_WIDTH - 1, TimelinePanel.FRAME_HEIGHT - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (fl == null) {
|
||||
|
||||
if (d == 0) {
|
||||
if (timeLine.frames.get(f).action != null) {
|
||||
g.setColor(aColor);
|
||||
g.setFont(getFont().deriveFont(fontSize));
|
||||
int awidth = g.getFontMetrics().stringWidth("a");
|
||||
g.drawString("a", f * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 2 - awidth / 2, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT / 2 + fontSize / 2);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
|
||||
int draw_f = 0;
|
||||
if (fl.key) {
|
||||
draw_f = f;
|
||||
keyfound[d - start_d] = true;
|
||||
} else if (!keyfound[d - start_d]) {
|
||||
for (int k = f - 1; k >= 0; k--) {
|
||||
fl = timeLine.frames.get(k).layers.get(d);
|
||||
if (fl == null) {
|
||||
break;
|
||||
}
|
||||
if (fl.key) {
|
||||
keyfound[d - start_d] = true;
|
||||
draw_f = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
int num_frames = 1;
|
||||
for (int n = draw_f + 1; n < timeLine.getFrameCount(); n++) {
|
||||
fl = timeLine.frames.get(n).layers.get(d);
|
||||
if (fl == null) {
|
||||
break;
|
||||
}
|
||||
if (fl.key) {
|
||||
break;
|
||||
}
|
||||
num_frames++;
|
||||
}
|
||||
g.setColor(frameColor);
|
||||
g.fillRect(draw_f * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT, num_frames * TimelinePanel.FRAME_WIDTH, TimelinePanel.FRAME_HEIGHT);
|
||||
|
||||
if (selected) {
|
||||
g.setColor(selectedColor);
|
||||
g.fillRect(draw_f * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT, TimelinePanel.FRAME_WIDTH, TimelinePanel.FRAME_HEIGHT);
|
||||
}
|
||||
|
||||
g.setColor(borderColor);
|
||||
g.drawRect(draw_f * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT, num_frames * TimelinePanel.FRAME_WIDTH, TimelinePanel.FRAME_HEIGHT);
|
||||
g.setColor(keyColor);
|
||||
g.fillOval(draw_f * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 4, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT * 3 / 4 - TimelinePanel.FRAME_WIDTH / 2 / 2, TimelinePanel.FRAME_WIDTH / 2, TimelinePanel.FRAME_WIDTH / 2);
|
||||
if (num_frames > 1) {
|
||||
if (cursor != null && cursor.y == d && cursor.x == f + num_frames - 1) {
|
||||
g.setColor(selectedColor);
|
||||
g.fillRect((f + num_frames - 1) * TimelinePanel.FRAME_WIDTH + 1, d * TimelinePanel.FRAME_HEIGHT + 1, TimelinePanel.FRAME_WIDTH - 1, TimelinePanel.FRAME_HEIGHT - 1);
|
||||
}
|
||||
g.setColor(stopColor);
|
||||
g.fillRect((draw_f + num_frames - 1) * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 4, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT / 2 - 2, TimelinePanel.FRAME_WIDTH / 2, TimelinePanel.FRAME_HEIGHT / 2);
|
||||
g.setColor(stopBorderColor);
|
||||
g.drawRect((draw_f + num_frames - 1) * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 4, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT / 2 - 2, TimelinePanel.FRAME_WIDTH / 2, TimelinePanel.FRAME_HEIGHT / 2);
|
||||
|
||||
g.setColor(borderLinesColor);
|
||||
for (int n = draw_f + 1; n < draw_f + num_frames; n++) {
|
||||
g.drawLine(n * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT + 1, n * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT + borderLinesLength);
|
||||
g.drawLine(n * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT - 1, n * TimelinePanel.FRAME_WIDTH, d * TimelinePanel.FRAME_HEIGHT + TimelinePanel.FRAME_HEIGHT - borderLinesLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cursor != null && cursor.x >= start_f && cursor.x <= end_f) {
|
||||
g.setColor(TimelinePanel.selectedBorderColor);
|
||||
g.drawLine(cursor.x * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 2, 0, cursor.x * TimelinePanel.FRAME_WIDTH + TimelinePanel.FRAME_WIDTH / 2, getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
|
||||
}
|
||||
|
||||
public void frameSelect(int frame, int depth) {
|
||||
if (cursor != null && cursor.x == frame && (cursor.y == depth || depth == -1)) {
|
||||
return;
|
||||
}
|
||||
if (depth == -1 && cursor != null) {
|
||||
depth = cursor.y;
|
||||
}
|
||||
cursor = new Point(frame, depth);
|
||||
for (FrameSelectionListener l : listeners) {
|
||||
l.frameSelected(frame, depth);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
Point p = e.getPoint();
|
||||
p.x = p.x / TimelinePanel.FRAME_WIDTH;
|
||||
p.y = p.y / TimelinePanel.FRAME_HEIGHT;
|
||||
if (p.x >= timeLine.getFrameCount()) {
|
||||
p.x = timeLine.getFrameCount() - 1;
|
||||
}
|
||||
int maxDepth = timeLine.getMaxDepth();
|
||||
if (p.y > maxDepth) {
|
||||
p.y = maxDepth;
|
||||
}
|
||||
frameSelect(p.x, p.y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
switch (e.getKeyCode()) {
|
||||
case 37: //left
|
||||
if (cursor.x > 0) {
|
||||
frameSelect(cursor.x - 1, cursor.y);
|
||||
}
|
||||
break;
|
||||
case 39: //right
|
||||
if (cursor.x < timeLine.frames.size() - 1) {
|
||||
frameSelect(cursor.x + 1, cursor.y);
|
||||
}
|
||||
break;
|
||||
case 38: //up
|
||||
if (cursor.y > 0) {
|
||||
frameSelect(cursor.x, cursor.y - 1);
|
||||
}
|
||||
break;
|
||||
case 40: //down
|
||||
if (cursor.y < timeLine.getMaxDepth()) {
|
||||
frameSelect(cursor.x, cursor.y + 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.timeline;
|
||||
|
||||
import com.jpexs.decompiler.flash.gui.AppFrame;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import com.jpexs.decompiler.flash.timeline.Timelined;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Container;
|
||||
import java.awt.Image;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class TimelineFrame extends AppFrame {
|
||||
|
||||
public TimelinePanel timeline;
|
||||
|
||||
public TimelineFrame(Timelined timelined) {
|
||||
setSize(800, 600);
|
||||
View.setWindowIcon(this);
|
||||
View.centerScreen(this);
|
||||
setTitle(translate("dialog.title"));
|
||||
Container cnt = getContentPane();
|
||||
cnt.setLayout(new BorderLayout());
|
||||
cnt.add(timeline = new TimelinePanel(timelined), BorderLayout.CENTER);
|
||||
|
||||
List<Image> images = new ArrayList<>();
|
||||
images.add(View.loadImage("timeline16"));
|
||||
images.add(View.loadImage("timeline32"));
|
||||
setIconImages(images);
|
||||
}
|
||||
}
|
||||
@@ -1,106 +1,124 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.timeline;
|
||||
|
||||
import com.jpexs.decompiler.flash.timeline.Timeline;
|
||||
import com.jpexs.decompiler.flash.timeline.Timelined;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.AdjustmentEvent;
|
||||
import java.awt.event.AdjustmentListener;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class TimelinePanel extends JPanel {
|
||||
|
||||
public TimelineBodyPanel timelineBodyPanel;
|
||||
public TimelineTimePanel timePanel;
|
||||
public TimelineDepthPanel depthPanel;
|
||||
public Timeline timeline;
|
||||
|
||||
public static final int FRAME_WIDTH = 8;
|
||||
public static final int FRAME_HEIGHT = 18;
|
||||
|
||||
public static Color selectedColor = new Color(0xff, 0x99, 0x99);
|
||||
public static Color selectedBorderColor = new Color(0xcc, 0, 0);
|
||||
public static Color backgroundColor = new Color(0xee, 0xee, 0xee);
|
||||
|
||||
public TimelinePanel(Timelined timelined) {
|
||||
timeline = timelined.getTimeline();
|
||||
timelineBodyPanel = new TimelineBodyPanel(timeline);
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
JScrollPane sp = new JScrollPane(timelineBodyPanel);
|
||||
|
||||
depthPanel = new TimelineDepthPanel(timeline);
|
||||
|
||||
timePanel = new TimelineTimePanel();
|
||||
|
||||
JPanel row1Panel = new JPanel();
|
||||
row1Panel.setLayout(new BorderLayout());
|
||||
JPanel sepPanel = new JPanel();
|
||||
sepPanel.setBackground(TimelinePanel.backgroundColor);
|
||||
sepPanel.setPreferredSize(new Dimension(depthPanel.getWidth(), timePanel.getHeight()));
|
||||
row1Panel.add(sepPanel, BorderLayout.WEST);
|
||||
row1Panel.add(timePanel, BorderLayout.CENTER);
|
||||
|
||||
JPanel row2Panel = new JPanel();
|
||||
row2Panel.setLayout(new BorderLayout());
|
||||
row2Panel.add(depthPanel, BorderLayout.WEST);
|
||||
row2Panel.add(sp, BorderLayout.CENTER);
|
||||
|
||||
add(row1Panel, BorderLayout.NORTH);
|
||||
add(row2Panel, BorderLayout.CENTER);
|
||||
|
||||
sp.getHorizontalScrollBar().addAdjustmentListener(new AdjustmentListener() {
|
||||
@Override
|
||||
public void adjustmentValueChanged(AdjustmentEvent e) {
|
||||
timePanel.scroll(e.getValue());
|
||||
}
|
||||
});
|
||||
sp.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
|
||||
|
||||
@Override
|
||||
public void adjustmentValueChanged(AdjustmentEvent e) {
|
||||
depthPanel.scroll(e.getValue());
|
||||
}
|
||||
});
|
||||
|
||||
final TimelineTimePanel ftime = timePanel;
|
||||
timelineBodyPanel.addFrameSelectionListener(new FrameSelectionListener() {
|
||||
|
||||
@Override
|
||||
public void frameSelected(int frame, int depth) {
|
||||
ftime.frameSelect(frame);
|
||||
}
|
||||
});
|
||||
final TimelineBodyPanel ftimeline = timelineBodyPanel;
|
||||
timePanel.addFrameSelectionListener(new FrameSelectionListener() {
|
||||
|
||||
@Override
|
||||
public void frameSelected(int frame, int depth) {
|
||||
ftimeline.frameSelect(frame, depth);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.timeline;
|
||||
|
||||
import com.jpexs.decompiler.flash.timeline.Timeline;
|
||||
import com.jpexs.decompiler.flash.timeline.Timelined;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.AdjustmentEvent;
|
||||
import java.awt.event.AdjustmentListener;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class TimelinePanel extends JPanel {
|
||||
|
||||
private TimelineBodyPanel timelineBodyPanel;
|
||||
private TimelineTimePanel timePanel;
|
||||
private TimelineDepthPanel depthPanel;
|
||||
private Timeline timeline;
|
||||
|
||||
public static final int FRAME_WIDTH = 8;
|
||||
public static final int FRAME_HEIGHT = 18;
|
||||
|
||||
public static Color selectedColor = new Color(0xff, 0x99, 0x99);
|
||||
public static Color selectedBorderColor = new Color(0xcc, 0, 0);
|
||||
public static Color backgroundColor = new Color(0xd9, 0xe7, 0xfa);
|
||||
|
||||
public Timeline getTimeline() {
|
||||
return timeline;
|
||||
}
|
||||
|
||||
public void addFrameSelectionListener(FrameSelectionListener l) {
|
||||
timelineBodyPanel.addFrameSelectionListener(l);
|
||||
}
|
||||
|
||||
public void removeFrameSelectionListener(FrameSelectionListener l) {
|
||||
timelineBodyPanel.removeFrameSelectionListener(l);
|
||||
}
|
||||
|
||||
public void setTimelined(Timelined timelined) {
|
||||
this.removeAll();
|
||||
if (timelined == null) {
|
||||
this.revalidate();
|
||||
return;
|
||||
}
|
||||
timeline = timelined.getTimeline();
|
||||
timelineBodyPanel = new TimelineBodyPanel(timeline);
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
JScrollPane sp = new JScrollPane(timelineBodyPanel);
|
||||
|
||||
depthPanel = new TimelineDepthPanel(timeline);
|
||||
|
||||
timePanel = new TimelineTimePanel();
|
||||
|
||||
JPanel row1Panel = new JPanel();
|
||||
row1Panel.setLayout(new BorderLayout());
|
||||
JPanel sepPanel = new JPanel();
|
||||
sepPanel.setBackground(TimelinePanel.backgroundColor);
|
||||
sepPanel.setPreferredSize(new Dimension(depthPanel.getWidth(), timePanel.getHeight()));
|
||||
row1Panel.add(sepPanel, BorderLayout.WEST);
|
||||
row1Panel.add(timePanel, BorderLayout.CENTER);
|
||||
|
||||
JPanel row2Panel = new JPanel();
|
||||
row2Panel.setLayout(new BorderLayout());
|
||||
row2Panel.add(depthPanel, BorderLayout.WEST);
|
||||
row2Panel.add(sp, BorderLayout.CENTER);
|
||||
|
||||
add(row1Panel, BorderLayout.NORTH);
|
||||
add(row2Panel, BorderLayout.CENTER);
|
||||
|
||||
sp.getHorizontalScrollBar().addAdjustmentListener(new AdjustmentListener() {
|
||||
@Override
|
||||
public void adjustmentValueChanged(AdjustmentEvent e) {
|
||||
timePanel.scroll(e.getValue());
|
||||
}
|
||||
});
|
||||
sp.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
|
||||
|
||||
@Override
|
||||
public void adjustmentValueChanged(AdjustmentEvent e) {
|
||||
depthPanel.scroll(e.getValue());
|
||||
}
|
||||
});
|
||||
|
||||
final TimelineTimePanel ftime = timePanel;
|
||||
timelineBodyPanel.addFrameSelectionListener(new FrameSelectionListener() {
|
||||
|
||||
@Override
|
||||
public void frameSelected(int frame, int depth) {
|
||||
ftime.frameSelect(frame);
|
||||
}
|
||||
});
|
||||
final TimelineBodyPanel ftimeline = timelineBodyPanel;
|
||||
timePanel.addFrameSelectionListener(new FrameSelectionListener() {
|
||||
|
||||
@Override
|
||||
public void frameSelected(int frame, int depth) {
|
||||
ftimeline.frameSelect(frame, depth);
|
||||
}
|
||||
});
|
||||
this.revalidate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.timeline;
|
||||
|
||||
import com.jpexs.decompiler.flash.gui.AppFrame;
|
||||
import com.jpexs.decompiler.flash.gui.ImagePanel;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import com.jpexs.decompiler.flash.timeline.Timelined;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Image;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JSplitPane;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class TimelineViewPanel extends JPanel {
|
||||
|
||||
public TimelinePanel timeline;
|
||||
public ImagePanel previewPanel;
|
||||
|
||||
public TimelineViewPanel() {
|
||||
|
||||
}
|
||||
|
||||
public void setTimelined(Timelined timelined) {
|
||||
removeAll();
|
||||
if (timelined == null) {
|
||||
revalidate();
|
||||
return;
|
||||
}
|
||||
setLayout(new BorderLayout());
|
||||
timeline = new TimelinePanel();
|
||||
timeline.setTimelined(timelined);
|
||||
add(new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, timeline, previewPanel = new ImagePanel()));
|
||||
|
||||
previewPanel.setTimelined(timelined, timelined.getTimeline().swf, 0);
|
||||
//previewPanel.setPreferredSize(new Dimension(400,300));
|
||||
previewPanel.pause();
|
||||
previewPanel.gotoFrame(0);
|
||||
timeline.addFrameSelectionListener(new FrameSelectionListener() {
|
||||
|
||||
@Override
|
||||
public void frameSelected(int frame, int depth) {
|
||||
previewPanel.selectDepth(depth);
|
||||
previewPanel.pause();
|
||||
previewPanel.gotoFrame(frame);
|
||||
}
|
||||
});
|
||||
revalidate();
|
||||
}
|
||||
}
|
||||
@@ -390,11 +390,11 @@ public class Win32ProcessTools extends ProcessTools {
|
||||
for (int pg = 0; pg < pages.size(); pg++) {
|
||||
MEMORY_BASIC_INFORMATION mbi = pages.get(pg);
|
||||
if (pageReadable(mbi)) {
|
||||
long addr = pointerToAddress(mbi.baseAddress);
|
||||
long addr = pointerToAddress(mbi.baseAddress);
|
||||
int maxsize = mbi.regionSize.intValue();
|
||||
long pos = 0;
|
||||
long bufSize = 1024*512;
|
||||
do {
|
||||
long bufSize = 1024 * 512;
|
||||
do {
|
||||
NativeLongByReference bytesReadRef = new NativeLongByReference();
|
||||
Memory buf = new Memory(bufSize);
|
||||
boolean ok = Kernel32.INSTANCE.ReadProcessMemory(hOtherProcess, new Pointer(addr + pos), buf, new NativeLong(bufSize), bytesReadRef);
|
||||
@@ -530,7 +530,7 @@ public class Win32ProcessTools extends ProcessTools {
|
||||
private final List<MEMORY_BASIC_INFORMATION> pages;
|
||||
private int currentPage = 0;
|
||||
private long pagePos = 0;
|
||||
private static final int BUFFER_SIZE = 1024*512;
|
||||
private static final int BUFFER_SIZE = 1024 * 512;
|
||||
private byte[] buf;
|
||||
private int bufPos;
|
||||
private final HANDLE hOtherProcess;
|
||||
|
||||
Reference in New Issue
Block a user