Position and size properties

This commit is contained in:
Jindra Petřík
2024-10-13 18:43:27 +02:00
parent 4e063491e7
commit 87c6b403a7
7 changed files with 215 additions and 69 deletions

View File

@@ -57,6 +57,11 @@ public class DepthState {
* Matrix
*/
public MATRIX matrix;
/**
* Temporary matrix
*/
public MATRIX temporaryMatrix;
/**
* Instance name
@@ -376,4 +381,12 @@ public class DepthState {
}
return Arrays.equals(this.amfData, other.amfData);
}
public MATRIX getDrawingMatrix() {
MATRIX temp = temporaryMatrix;
if (temp != null) {
return temp;
}
return matrix;
}
}

View File

@@ -1394,7 +1394,7 @@ public class Timeline {
if (character == null) {
continue;
}
Matrix layerMatrix = new Matrix(layer.matrix);
Matrix layerMatrix = new Matrix(layer.getDrawingMatrix());
Matrix mat = transformation.concatenate(layerMatrix);
Matrix absMat = absoluteTransformation.concatenate(layerMatrix);
@@ -1726,7 +1726,7 @@ public class Timeline {
CharacterTag character = layer.getCharacter();
if (character instanceof DrawableTag) {
DrawableTag drawable = (DrawableTag) character;
Matrix m = transformation.concatenate(new Matrix(layer.matrix));
Matrix m = transformation.concatenate(new Matrix(layer.getDrawingMatrix()));
int drawableFrameCount = drawable.getNumFrames();
if (drawableFrameCount == 0) {

View File

@@ -175,6 +175,8 @@ public class EasySwfPanel extends JPanel {
stagePanel.setRegistrationPointPosition(regPointPos);
}
transformPanel.setVisible(true);
} else {
stagePanel.selectDepths(depths);
}
}
@@ -196,6 +198,8 @@ public class EasySwfPanel extends JPanel {
if (transformEnabled()) {
stagePanel.freeTransformDepths(depths);
transformPanel.setVisible(true);
} else {
stagePanel.selectDepths(depths);
}
}

View File

@@ -61,6 +61,7 @@ public abstract class AbstractPropertyField<E> extends JPanel {
private AWTEventListener aeListener;
private boolean undetermined = false;
private boolean editing = false;
public void addValidation(PropertyValidationInteface<E> validation) {
validations.add(validation);
@@ -97,12 +98,13 @@ public abstract class AbstractPropertyField<E> extends JPanel {
readLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 1) {
if (e.getClickCount() == 1) {
((CardLayout)AbstractPropertyField.this.getLayout()).show(AbstractPropertyField.this, CARD_WRITE);
writeField.requestFocus();
writeField.selectAll();
Toolkit.getDefaultToolkit().addAWTEventListener(aeListener, AWTEvent.MOUSE_EVENT_MASK);
editing = true;
}
}
});
@@ -147,7 +149,10 @@ public abstract class AbstractPropertyField<E> extends JPanel {
protected abstract E textToValue(String text);
protected abstract String valueToText(E value);
private void finishEdit() {
private synchronized void finishEdit() {
if (!editing) {
return;
}
String textBefore = readLabel.getText();
String textAfter = writeField.getText();
@@ -179,10 +184,14 @@ public abstract class AbstractPropertyField<E> extends JPanel {
undetermined = false;
readLabel.setText(valueToText(value));
((CardLayout)AbstractPropertyField.this.getLayout()).show(AbstractPropertyField.this, CARD_READ);
editing = false;
fireChange();
}
private void cancelEdit() {
if (!editing) {
return;
}
Toolkit.getDefaultToolkit().removeAWTEventListener(aeListener);
if (undetermined) {
writeField.setText("");
@@ -190,6 +199,7 @@ public abstract class AbstractPropertyField<E> extends JPanel {
writeField.setText(readLabel.getText());
}
((CardLayout)AbstractPropertyField.this.getLayout()).show(AbstractPropertyField.this, CARD_READ);
editing = false;
}
public E getValue() {
@@ -200,25 +210,36 @@ public abstract class AbstractPropertyField<E> extends JPanel {
}
public void setValue(Set<E> value) {
setValue(value, false);
}
public void setValue(Set<E> value, boolean silent) {
if (value.size() != 1) {
setValue((E) null);
setValue((E) null, silent);
} else {
setValue(value.iterator().next());
setValue(value.iterator().next(), silent);
}
}
public void setValue(E value) {
setValue(value, false);
}
public void setValue(E value, boolean silent) {
if (value == null) {
readLabel.setText("-");
writeField.setText("");
undetermined = true;
fireChange();
if (!silent) {
fireChange();
}
return;
}
String text = valueToText(value);
readLabel.setText(text);
writeField.setText(text);
fireChange();
if (!silent) {
fireChange();
}
}
}

View File

@@ -20,9 +20,14 @@ import com.jpexs.decompiler.flash.easygui.ChangeDoableOperation;
import com.jpexs.decompiler.flash.easygui.EasyStrings;
import com.jpexs.decompiler.flash.easygui.EasySwfPanel;
import com.jpexs.decompiler.flash.easygui.UndoManager;
import com.jpexs.decompiler.flash.easygui.properties.FloatPropertyField;
import com.jpexs.decompiler.flash.easygui.properties.IntegerPropertyField;
import com.jpexs.decompiler.flash.easygui.properties.PropertyValidationInteface;
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
import com.jpexs.decompiler.flash.gui.AppStrings;
import com.jpexs.decompiler.flash.gui.BoundsChangeListener;
import com.jpexs.decompiler.flash.gui.ImagePanel;
import com.jpexs.decompiler.flash.gui.RegistrationPointPosition;
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
import com.jpexs.decompiler.flash.tags.converters.PlaceObjectTypeConverter;
import com.jpexs.decompiler.flash.timeline.DepthState;
@@ -33,6 +38,8 @@ import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -49,6 +56,11 @@ import javax.swing.event.ChangeListener;
*/
public class GeneralPropertiesPanel extends AbstractPropertiesPanel {
private final FloatPropertyField xPropertyField = new FloatPropertyField(0, -8192, 8192);
private final FloatPropertyField yPropertyField = new FloatPropertyField(0, -8192, 8192);
private final FloatPropertyField wPropertyField = new FloatPropertyField(0, -8192, 8192);
private final FloatPropertyField hPropertyField = new FloatPropertyField(0, -8192, 8192);
private final IntegerPropertyField alphaPercentPropertyField = new IntegerPropertyField(100, -100, 100);
private final IntegerPropertyField redPercentPropertyField = new IntegerPropertyField(100, -100, 100);
private final IntegerPropertyField greenPercentPropertyField = new IntegerPropertyField(100, -100, 100);
@@ -61,17 +73,59 @@ public class GeneralPropertiesPanel extends AbstractPropertiesPanel {
private final JPanel propertiesPanel;
private boolean updating = false;
private Rectangle2D lastBounds = null;
public GeneralPropertiesPanel(EasySwfPanel swfPanel, UndoManager undoManager) {
super("general");
JPanel colorEffectPanel = new JPanel();
GridBagLayout gridBag = new GridBagLayout();
GridBagLayout gridBag;
GridBagConstraints gbc;
JPanel positionSizePanel = new JPanel();
gridBag = new GridBagLayout();
positionSizePanel.setLayout(gridBag);
gbc = new GridBagConstraints();
gbc.weightx = 0;
gbc.insets = new Insets(3, 3, 3, 3);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.EAST;
positionSizePanel.add(new JLabel(formatPropertyName("positionSize.x")), gbc);
gbc.gridx++;
gbc.anchor = GridBagConstraints.WEST;
positionSizePanel.add(xPropertyField, gbc);
gbc.gridx++;
gbc.anchor = GridBagConstraints.EAST;
positionSizePanel.add(new JLabel(formatPropertyName("positionSize.y")), gbc);
gbc.gridx++;
gbc.anchor = GridBagConstraints.WEST;
positionSizePanel.add(yPropertyField, gbc);
gbc.gridy++;
gbc.gridx = 0;
gbc.anchor = GridBagConstraints.EAST;
positionSizePanel.add(new JLabel(formatPropertyName("positionSize.width")), gbc);
gbc.gridx++;
gbc.anchor = GridBagConstraints.WEST;
positionSizePanel.add(wPropertyField, gbc);
gbc.gridx++;
gbc.anchor = GridBagConstraints.EAST;
positionSizePanel.add(new JLabel(formatPropertyName("positionSize.height")), gbc);
gbc.gridx++;
gbc.anchor = GridBagConstraints.WEST;
positionSizePanel.add(hPropertyField, gbc);
gbc.gridx++;
gbc.gridy = 0;
gbc.gridheight = 2;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
positionSizePanel.add(new JPanel(), gbc);
JPanel colorEffectPanel = new JPanel();
gridBag = new GridBagLayout();
colorEffectPanel.setLayout(gridBag);
GridBagConstraints gbc = new GridBagConstraints();
gbc = new GridBagConstraints();
gbc.weightx = 0;
gbc.insets = new Insets(3, 3, 3, 3);
gbc.gridx = 0;
@@ -133,15 +187,13 @@ public class GeneralPropertiesPanel extends AbstractPropertiesPanel {
propertiesPanel = new JPanel();
propertiesPanel.setLayout(new BoxLayout(propertiesPanel, BoxLayout.Y_AXIS));
propertiesPanel.add(makeCard("positionSize", null, positionSizePanel));
propertiesPanel.add(makeCard("colorEffect", null, colorEffectPanel));
this.swfPanel = swfPanel;
alphaPercentPropertyField.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (updating) {
return;
}
undoManager.doOperation(new ColorEffectChangeDoableOperation() {
int value = alphaPercentPropertyField.getValue();
@Override
@@ -155,9 +207,6 @@ public class GeneralPropertiesPanel extends AbstractPropertiesPanel {
alphaAddPropertyField.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (updating) {
return;
}
undoManager.doOperation(new ColorEffectChangeDoableOperation() {
int value = alphaAddPropertyField.getValue();
@Override
@@ -172,9 +221,6 @@ public class GeneralPropertiesPanel extends AbstractPropertiesPanel {
redPercentPropertyField.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (updating) {
return;
}
undoManager.doOperation(new ColorEffectChangeDoableOperation() {
int value = redPercentPropertyField.getValue();
@Override
@@ -188,9 +234,6 @@ public class GeneralPropertiesPanel extends AbstractPropertiesPanel {
redAddPropertyField.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (updating) {
return;
}
undoManager.doOperation(new ColorEffectChangeDoableOperation() {
int value = redAddPropertyField.getValue();
@Override
@@ -205,9 +248,6 @@ public class GeneralPropertiesPanel extends AbstractPropertiesPanel {
greenPercentPropertyField.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (updating) {
return;
}
undoManager.doOperation(new ColorEffectChangeDoableOperation() {
int value = greenPercentPropertyField.getValue();
@Override
@@ -221,9 +261,6 @@ public class GeneralPropertiesPanel extends AbstractPropertiesPanel {
greenAddPropertyField.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (updating) {
return;
}
undoManager.doOperation(new ColorEffectChangeDoableOperation() {
int value = greenAddPropertyField.getValue();
@Override
@@ -238,9 +275,6 @@ public class GeneralPropertiesPanel extends AbstractPropertiesPanel {
bluePercentPropertyField.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (updating) {
return;
}
undoManager.doOperation(new ColorEffectChangeDoableOperation() {
int value = bluePercentPropertyField.getValue();
@Override
@@ -254,9 +288,6 @@ public class GeneralPropertiesPanel extends AbstractPropertiesPanel {
blueAddPropertyField.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (updating) {
return;
}
undoManager.doOperation(new ColorEffectChangeDoableOperation() {
int value = blueAddPropertyField.getValue();
@Override
@@ -268,18 +299,101 @@ public class GeneralPropertiesPanel extends AbstractPropertiesPanel {
}
});
add(propertiesPanel, BorderLayout.CENTER);;
xPropertyField.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
double xBefore = lastBounds.getX();
double xAfter = xPropertyField.getValue() * 20;
double xDelta = Math.round(xAfter - xBefore);
swfPanel.getStagePanel().applyTransformMatrix(Matrix.getTranslateInstance(xDelta, 0));
}
});
yPropertyField.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
double yBefore = lastBounds.getY();
double yAfter = yPropertyField.getValue() * 20;
double yDelta = Math.round(yAfter - yBefore);
swfPanel.getStagePanel().applyTransformMatrix(Matrix.getTranslateInstance(0, yDelta));
}
});
PropertyValidationInteface<Float> nonZeroFloatValidation = new PropertyValidationInteface<Float>() {
@Override
public boolean validate(Float value) {
return value != 0f;
}
};
wPropertyField.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
double wBefore = lastBounds.getWidth();
if (wBefore == 0) {
return;
}
double wAfter = wPropertyField.getValue() * 20;
double wScale = wAfter / wBefore;
Matrix m = new Matrix();
m.translate(Math.round(lastBounds.getX()), Math.round(lastBounds.getY()));
m.scale(wScale, 1);
m.translate(-Math.round(lastBounds.getX()), -Math.round(lastBounds.getY()));
swfPanel.getStagePanel().applyTransformMatrix(m);
}
});
wPropertyField.addValidation(nonZeroFloatValidation);
hPropertyField.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
double hBefore = lastBounds.getHeight();
if (hBefore == 0) {
return;
}
double hAfter = hPropertyField.getValue() * 20;
double hScale = hAfter / hBefore;
Matrix m = new Matrix();
m.translate(Math.round(lastBounds.getX()), Math.round(lastBounds.getY()));
m.scale(1, hScale);
m.translate(-Math.round(lastBounds.getX()), -Math.round(lastBounds.getY()));
swfPanel.getStagePanel().applyTransformMatrix(m);
}
});
hPropertyField.addValidation(nonZeroFloatValidation);
add(propertiesPanel, BorderLayout.CENTER);
swfPanel.getStagePanel().addBoundsChangeListener(new BoundsChangeListener() {
@Override
public void boundsChanged(Rectangle2D newBounds, Point2D registrationPoint, RegistrationPointPosition registrationPointPosition) {
lastBounds = newBounds;
xPropertyField.setValue(twipToPixelValue(newBounds.getX()), true);
yPropertyField.setValue(twipToPixelValue(newBounds.getY()), true);
wPropertyField.setValue(twipToPixelValue(newBounds.getWidth()), true);
hPropertyField.setValue(twipToPixelValue(newBounds.getHeight()), true);
}
});
}
private static float twipToPixelValue(double val) {
float ret = (float) val;
ret = Math.round(ret);
ret = ret / 20;
return ret;
}
public void update() {
updating = true;
List<DepthState> dss = swfPanel.getSelectedDepthStates();
if (dss == null || dss.isEmpty()) {
propertiesPanel.setVisible(false);
return;
}
propertiesPanel.setVisible(true);
//swfPanel.getStagePanel().gett
Set<Integer> alphaPercent = new HashSet<>();
Set<Integer> alphaAdd = new HashSet<>();
Set<Integer> redPercent = new HashSet<>();
@@ -316,16 +430,14 @@ public class GeneralPropertiesPanel extends AbstractPropertiesPanel {
}
alphaPercentPropertyField.setValue(alphaPercent);
alphaAddPropertyField.setValue(alphaAdd);
redPercentPropertyField.setValue(redPercent);
redAddPropertyField.setValue(redAdd);
greenPercentPropertyField.setValue(greenPercent);
greenAddPropertyField.setValue(greenAdd);
bluePercentPropertyField.setValue(bluePercent);
blueAddPropertyField.setValue(blueAdd);
updating = false;
alphaPercentPropertyField.setValue(alphaPercent, true);
alphaAddPropertyField.setValue(alphaAdd, true);
redPercentPropertyField.setValue(redPercent, true);
redAddPropertyField.setValue(redAdd, true);
greenPercentPropertyField.setValue(greenPercent, true);
greenAddPropertyField.setValue(greenAdd, true);
bluePercentPropertyField.setValue(bluePercent, true);
blueAddPropertyField.setValue(blueAdd, true);
}
abstract class PlaceChangeDoableOperation extends ChangeDoableOperation {

View File

@@ -1402,7 +1402,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
repaint();
}
if (selectionMode && !doFreeTransform) {
transform = null;
//transform = null;
}
mode = Cursor.DEFAULT_CURSOR;
}
@@ -3170,19 +3170,12 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
Matrix fullM = m.clone();
List<MATRIX> oldMatrices = new ArrayList<>();
for (int i = 0; i < selectedDepths.size(); i++) {
if (newMatrix != null) {
DepthState ds = timeline.getFrame(frame).layers.get(selectedDepths.get(i));
if (ds != null) {
oldMatrices.add(ds.matrix);
timeline.getFrame(frame).layers.get(selectedDepths.get(i)).matrix = newMatrix.concatenate(new Matrix(ds.matrix)).toMATRIX();
} else {
oldMatrices.add(null);
}
} else {
oldMatrices.add(null);
ds.temporaryMatrix = newMatrix.concatenate(new Matrix(ds.matrix)).toMATRIX();
}
}
}
@@ -3262,15 +3255,13 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
Matrix transform2 = transform;
if (oldMatrices != null) {
transform2 = transform2.concatenate(new Matrix(oldMatrices.get(i)));
}
transform2 = transform2.concatenate(new Matrix(ds.matrix));
Shape outline = dt.getOutline(true, dframe, time, ds.ratio, renderContext, transform2, true, viewRect, zoom);
if (temporaryMatrix != null) {
Matrix tMatrix = temporaryMatrix;
tMatrix = tMatrix.concatenate(new Matrix(ds.matrix));
tMatrix = tMatrix.concatenate(new Matrix(ds.temporaryMatrix));
Shape tempOutline = dt.getOutline(true, dframe, time, ds.ratio, renderContext, tMatrix, true, viewRect, zoom);
gg.setStroke(new BasicStroke(1));
gg.setPaint(Color.black);
@@ -3305,13 +3296,13 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
drawRegistrationPoint(gg, regPoint);
}
if (doFreeTransform && oldMatrices != null && timeline != null && timeline.getFrameCount() > frame) {
if (timeline != null && timeline.getFrameCount() > frame) {
for (int i = 0; i < selectedDepths.size(); i++) {
int selectedDepth = selectedDepths.get(i);
MATRIX oldMatrix = oldMatrices.get(i);
if (oldMatrix != null) {
timeline.getFrame(frame).layers.get(selectedDepth).matrix = oldMatrix;
}
DepthState ds = timeline.getDepthState(frame, selectedDepth);
if (ds != null) {
ds.temporaryMatrix = null;
}
}
}
img = image;

View File

@@ -75,6 +75,7 @@ properties = Properties
properties.document = Document
properties.general = General
properties.general.header.positionSize = Position and size
properties.general.header.colorEffect = Color effect
property.label = %item%:
@@ -84,5 +85,9 @@ property.general.colorEffect.alpha = Alpha
property.general.colorEffect.red = Red
property.general.colorEffect.green = Green
property.general.colorEffect.blue = Blue
property.general.positionSize.x = X
property.general.positionSize.y = Y
property.general.positionSize.width = W
property.general.positionSize.height = H