Added Scenes folder with (readonly) display of scene frames

This commit is contained in:
Jindra Petřík
2023-12-29 18:40:23 +01:00
parent f09d4affa5
commit 85ba45cbb3
15 changed files with 333 additions and 10 deletions

View File

@@ -0,0 +1,92 @@
/*
* Copyright (C) 2010-2023 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.timeline;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.treeitems.Openable;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import java.util.Objects;
/**
*
* @author JPEXS
*/
public class Scene implements TreeItem {
private SWF swf;
public int startFrame;
public int endFrame;
public String name;
public Scene(SWF swf, int startFrame, int endFrame, String name) {
this.swf = swf;
this.startFrame = startFrame;
this.endFrame = endFrame;
this.name = name;
}
public int getSceneFrameCount() {
return endFrame - startFrame + 1;
}
public SceneFrame getSceneFrame(int sceneFrameIndex) {
if (sceneFrameIndex >= getSceneFrameCount()) {
throw new IndexOutOfBoundsException("Invalid sceneframe index");
}
return new SceneFrame(swf, this, startFrame + sceneFrameIndex);
}
@Override
public Openable getOpenable() {
return swf;
}
@Override
public boolean isModified() {
return false; //??
}
@Override
public int hashCode() {
int hash = 7;
hash = 97 * hash + Objects.hashCode(this.swf);
hash = 97 * hash + this.startFrame;
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Scene other = (Scene) obj;
if (this.startFrame != other.startFrame) {
return false;
}
return Objects.equals(this.swf, other.swf);
}
@Override
public String toString() {
return name;
}
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright (C) 2010-2023 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.timeline;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.treeitems.Openable;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import java.util.Objects;
/**
*
* @author JPEXS
*/
public class SceneFrame implements TreeItem {
private final SWF swf;
private final Scene scene;
private final int realFrameIndex;
public SceneFrame(SWF swf, Scene scene, int realFrameIndex) {
this.swf = swf;
this.scene = scene;
this.realFrameIndex = realFrameIndex;
}
public int getSceneFrameIndex() {
return realFrameIndex - scene.startFrame;
}
public Frame getFrame() {
return swf.getTimeline().getFrame(realFrameIndex);
}
@Override
public String toString() {
return "scene frame " + (getSceneFrameIndex() + 1);
}
@Override
public Openable getOpenable() {
return swf;
}
@Override
public boolean isModified() {
return getFrame().isModified();
}
@Override
public int hashCode() {
int hash = 5;
hash = 47 * hash + Objects.hashCode(this.scene);
hash = 47 * hash + this.realFrameIndex;
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final SceneFrame other = (SceneFrame) obj;
if (this.realFrameIndex != other.realFrameIndex) {
return false;
}
return Objects.equals(this.scene, other.scene);
}
}

View File

@@ -128,6 +128,8 @@ public class Timeline {
private boolean initialized = false;
private Map<String, Integer> labelToFrame = new HashMap<>();
private List<Scene> scenes = new ArrayList<>();
public static final int DRAW_MODE_ALL = 0;
public static final int DRAW_MODE_SHAPES = 1;
@@ -282,6 +284,8 @@ public class Timeline {
Frame frame = new Frame(this, frameIdx++);
frame.layersChanged = true;
boolean newFrameNeeded = false;
scenes = new ArrayList<>();
Scene prevScene = null;
for (Tag t : timelined.getTags()) {
newFrameNeeded = true;
boolean isNested = ShowFrameTag.isNestedTagType(t.getId());
@@ -290,6 +294,20 @@ public class Timeline {
}
frame.allInnerTags.add(t);
if (id == 0 && (t instanceof DefineSceneAndFrameLabelDataTag)) {
DefineSceneAndFrameLabelDataTag sceneData = (DefineSceneAndFrameLabelDataTag) t;
scenes = new ArrayList<>();
for (int i = 0; i < sceneData.sceneNames.length; i++) {
int ioffset = (int) sceneData.sceneOffsets[i];
Scene currentScene = new Scene(swf, ioffset, -1, sceneData.sceneNames[i]);
scenes.add(currentScene);
if (prevScene != null) {
prevScene.endFrame = ioffset - 1;
}
prevScene = currentScene;
}
}
if (t instanceof ASMSourceContainer) {
ASMSourceContainer asmSourceContainer = (ASMSourceContainer) t;
if (!asmSourceContainer.getSubItems().isEmpty()) {
@@ -445,6 +463,10 @@ public class Timeline {
if (newFrameNeeded) {
frames.add(frame);
}
if (prevScene != null) {
prevScene.endFrame = frames.size() - 1;
}
maxDepth = getMaxDepthInternal();
@@ -1521,4 +1543,9 @@ public class Timeline {
return false;
}
public List<Scene> getScenes() {
ensureInitialized();
return new ArrayList<>(scenes);
}
}