Added: Link blur X and blur Y

This commit is contained in:
Jindra Petřík
2025-05-14 21:29:49 +02:00
parent 321538e789
commit ecae3cdbb0
6 changed files with 184 additions and 34 deletions
@@ -24,6 +24,7 @@ import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.gui.AppStrings; import com.jpexs.decompiler.flash.gui.AppStrings;
import com.jpexs.decompiler.flash.gui.View; import com.jpexs.decompiler.flash.gui.View;
import com.jpexs.decompiler.flash.gui.generictageditors.BooleanEditor; import com.jpexs.decompiler.flash.gui.generictageditors.BooleanEditor;
import com.jpexs.decompiler.flash.gui.generictageditors.ChangeListener;
import com.jpexs.decompiler.flash.gui.generictageditors.ColorEditor; import com.jpexs.decompiler.flash.gui.generictageditors.ColorEditor;
import com.jpexs.decompiler.flash.gui.generictageditors.FloatEditor; import com.jpexs.decompiler.flash.gui.generictageditors.FloatEditor;
import com.jpexs.decompiler.flash.gui.generictageditors.NumberEditor; import com.jpexs.decompiler.flash.gui.generictageditors.NumberEditor;
@@ -42,6 +43,8 @@ import de.javagl.treetable.TreeTableModel;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.Color; import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable; import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.datatransfer.UnsupportedFlavorException;
@@ -60,6 +63,8 @@ import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DropMode; import javax.swing.DropMode;
import javax.swing.JCheckBox; import javax.swing.JCheckBox;
import javax.swing.JComponent; import javax.swing.JComponent;
@@ -89,6 +94,7 @@ import javax.swing.tree.TreePath;
public class FiltersTreeTable extends JTreeTable { public class FiltersTreeTable extends JTreeTable {
private List<ActionListener> filterChangedListeners = new ArrayList<>(); private List<ActionListener> filterChangedListeners = new ArrayList<>();
private boolean linkEnabled = true;
public FiltersTreeTable() { public FiltersTreeTable() {
super(new FiltersTreeTableModel(null)); super(new FiltersTreeTableModel(null));
@@ -556,7 +562,6 @@ public class FiltersTreeTable extends JTreeTable {
//((BooleanEditor) editor).setRequestFocusEnabled(false); //((BooleanEditor) editor).setRequestFocusEnabled(false);
} else if (realValue.getClass() == Double.class || realValue.getClass() == Float.class) { } else if (realValue.getClass() == Double.class || realValue.getClass() == Float.class) {
editor = new FloatEditor(filterField.toString(), filterField.filter, filterField.field, -1, realValue.getClass()); editor = new FloatEditor(filterField.toString(), filterField.filter, filterField.field, -1, realValue.getClass());
//editor = new NumberEditor(filterField.toString(), filterField.filter, filterField.field, -1, realValue.getClass(), filterField.field.getAnnotation(SWFType.class));
if ("angle".equals(filterField.field.getName())) { if ("angle".equals(filterField.field.getName())) {
((FloatEditor) editor).setValueNormalizer(new ValueNormalizer() { ((FloatEditor) editor).setValueNormalizer(new ValueNormalizer() {
@Override @Override
@@ -570,6 +575,22 @@ public class FiltersTreeTable extends JTreeTable {
} }
}); });
} }
if ("blurX".equals(filterField.field.getName())) {
try {
((FloatEditor) editor).setLinkedField(filterField.filter.getClass().getField("blurY"));
((FloatEditor) editor).setLinkEnabled(filtersTable.linkEnabled);
} catch (NoSuchFieldException | SecurityException ex) {
//ignore
}
}
if ("blurY".equals(filterField.field.getName())) {
try {
((FloatEditor) editor).setLinkedField(filterField.filter.getClass().getField("blurX"));
((FloatEditor) editor).setLinkEnabled(filtersTable.linkEnabled);
} catch (NoSuchFieldException | SecurityException ex) {
//ignore
}
}
} else if (realValue.getClass() == int.class || realValue.getClass() == Integer.class) { } else if (realValue.getClass() == int.class || realValue.getClass() == Integer.class) {
editor = new NumberEditor(filterField.toString(), filterField.filter, filterField.field, -1, realValue.getClass(), filterField.field.getAnnotation(SWFType.class)); editor = new NumberEditor(filterField.toString(), filterField.filter, filterField.field, -1, realValue.getClass(), filterField.field.getAnnotation(SWFType.class));
} else if (realValue.getClass() == RGBA.class) { } else if (realValue.getClass() == RGBA.class) {
@@ -578,12 +599,18 @@ public class FiltersTreeTable extends JTreeTable {
if (editor != null) { if (editor != null) {
/*editor.addChangeListener(new ChangeListener() { editor.addChangeListener(new ChangeListener() {
@Override @Override
public void change(PropertyEditor editor) { public void change(PropertyEditor editor) {
editor.save();
} }
});*/
@Override
public void linkChanged(boolean newValue) {
filtersTable.linkEnabled = newValue;
stopCellEditing();
filtersTable.repaint();
}
});
if (table instanceof JTreeTable) { if (table instanceof JTreeTable) {
JTreeTable treeTable = (JTreeTable) table; JTreeTable treeTable = (JTreeTable) table;
if (treeTable.isRowSelected(row)) { if (treeTable.isRowSelected(row)) {
@@ -672,7 +699,7 @@ public class FiltersTreeTable extends JTreeTable {
private static class FiltersTableCellRenderer extends DefaultTableCellRenderer { private static class FiltersTableCellRenderer extends DefaultTableCellRenderer {
JLabel label = new JLabel(); JLabel label = new JLabel();
@Override @Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
label.setText(value.toString()); label.setText(value.toString());
@@ -740,6 +767,17 @@ public class FiltersTreeTable extends JTreeTable {
component = new ColorEditor(filterValue.filterField.toString(), filterValue.filterField.filter, filterValue.filterField.field, -1, RGBA.class); component = new ColorEditor(filterValue.filterField.toString(), filterValue.filterField.filter, filterValue.filterField.field, -1, RGBA.class);
component.setToolTipText(AppStrings.translate("button.selectcolor.hint")); component.setToolTipText(AppStrings.translate("button.selectcolor.hint"));
} }
if ("blurX".equals(filterValue.filterField.field.getName())
|| "blurY".equals(filterValue.filterField.field.getName())) {
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
JLabel blurLabel = new JLabel(label.getText());
panel.add(blurLabel);
blurLabel.setPreferredSize(new Dimension(50, blurLabel.getPreferredSize().height));
blurLabel.setMaximumSize(blurLabel.getPreferredSize());
JLabel linkLabel = new JLabel(View.getIcon(((FiltersTreeTable) table).linkEnabled ? "link16" : "linkbreak16"));
panel.add(linkLabel);
component = panel;
}
} }
} }
@@ -953,6 +991,7 @@ public class FiltersTreeTable extends JTreeTable {
DefaultMutableTreeNode filterNode = new DefaultMutableTreeNode(new FilterName(filter)); DefaultMutableTreeNode filterNode = new DefaultMutableTreeNode(new FilterName(filter));
root.insert(filterNode, index); root.insert(filterNode, index);
Field[] fields = filter.getClass().getFields(); Field[] fields = filter.getClass().getFields();
LinkedDefaultMutableTreeNode lastLinkedNode = null;
for (Field field : fields) { for (Field field : fields) {
if ("id".equals(field.getName())) { if ("id".equals(field.getName())) {
continue; continue;
@@ -996,7 +1035,19 @@ public class FiltersTreeTable extends JTreeTable {
continue; continue;
} }
FilterField filterField = new FilterField(filter, field); FilterField filterField = new FilterField(filter, field);
DefaultMutableTreeNode fieldNode = new DefaultMutableTreeNode(filterField); DefaultMutableTreeNode fieldNode;
if ("blurX".equals(field.getName())) {
LinkedDefaultMutableTreeNode linkedNode = new LinkedDefaultMutableTreeNode(filterField);
fieldNode = linkedNode;
lastLinkedNode = linkedNode;
} else if ("blurY".equals(field.getName())) {
LinkedDefaultMutableTreeNode linkedNode = new LinkedDefaultMutableTreeNode(filterField);
fieldNode = linkedNode;
linkedNode.setLinkedNode(lastLinkedNode);
lastLinkedNode.setLinkedNode(linkedNode);
} else {
fieldNode = new DefaultMutableTreeNode(filterField);
}
filterNode.add(fieldNode); filterNode.add(fieldNode);
} }
this.filters.add(index, filter); this.filters.add(index, filter);
@@ -1130,5 +1181,23 @@ public class FiltersTreeTable extends JTreeTable {
public void removeTreeModelListener(TreeModelListener l) { public void removeTreeModelListener(TreeModelListener l) {
listeners.remove(l); listeners.remove(l);
} }
} }
private static class LinkedDefaultMutableTreeNode extends DefaultMutableTreeNode {
private LinkedDefaultMutableTreeNode linkedNode;
public LinkedDefaultMutableTreeNode(Object userObject) {
super(userObject);
}
public void setLinkedNode(LinkedDefaultMutableTreeNode linkedNode) {
this.linkedNode = linkedNode;
}
public LinkedDefaultMutableTreeNode getLinkedNode() {
return linkedNode;
}
}
} }
@@ -21,8 +21,9 @@ import com.jpexs.decompiler.flash.easygui.properties.PropertyEditor;
/** /**
* @author JPEXS * @author JPEXS
*/ */
@FunctionalInterface
public interface ChangeListener { public interface ChangeListener {
public void change(PropertyEditor editor); public void change(PropertyEditor editor);
public void linkChanged(boolean newValue);
} }
@@ -18,20 +18,30 @@ package com.jpexs.decompiler.flash.gui.generictageditors;
import com.jpexs.decompiler.flash.easygui.properties.PropertyEditor; import com.jpexs.decompiler.flash.easygui.properties.PropertyEditor;
import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.gui.View;
import com.jpexs.helpers.Helper; import com.jpexs.helpers.Helper;
import com.jpexs.helpers.ReflectionTools; import com.jpexs.helpers.ReflectionTools;
import java.awt.BorderLayout;
import java.awt.Component; import java.awt.Component;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.FocusAdapter; import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent; import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField; import javax.swing.JTextField;
/** /**
* @author JPEXS * @author JPEXS
*/ */
public class FloatEditor extends JTextField implements GenericTagEditor { public class FloatEditor extends JPanel implements GenericTagEditor {
private final Object obj; private final Object obj;
@@ -42,13 +52,17 @@ public class FloatEditor extends JTextField implements GenericTagEditor {
private final Class<?> type; private final Class<?> type;
private String fieldName; private String fieldName;
private ValueNormalizer normalizer; private ValueNormalizer normalizer;
@Override private Field linkedField;
public boolean getScrollableTracksViewportWidth() {
return true; private boolean linkEnabled;
}
private List<ChangeListener> listeners = new ArrayList<>();
private JTextField textField;
private JLabel linkLabel;
@Override @Override
public Dimension getPreferredSize() { public Dimension getPreferredSize() {
@@ -73,7 +87,48 @@ public class FloatEditor extends JTextField implements GenericTagEditor {
this.index = index; this.index = index;
this.type = type; this.type = type;
this.fieldName = fieldName; this.fieldName = fieldName;
reset();
addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
for (ChangeListener l : listeners) {
l.change(FloatEditor.this);
}
}
});
textField = new JTextField() {
@Override
public boolean getScrollableTracksViewportWidth() {
return true;
}
};
textField.setBorder(BorderFactory.createEmptyBorder());
setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
textField.setPreferredSize(new Dimension(50, textField.getPreferredSize().height));
textField.setMaximumSize(textField.getPreferredSize());
add(textField);
linkLabel = new JLabel(View.getIcon("link16"));
add(linkLabel);
linkLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
boolean newValue = !linkEnabled;
setLinkEnabled(newValue);
for (ChangeListener l : listeners) {
l.linkChanged(newValue);
}
repaint();
}
});
linkLabel.setVisible(false);
reset();
} }
@Override @Override
@@ -83,7 +138,7 @@ public class FloatEditor extends JTextField implements GenericTagEditor {
if (normalizer != null) { if (normalizer != null) {
val = normalizer.toViewValue(val); val = normalizer.toViewValue(val);
} }
setText(val == null ? "" : EcmaScript.toString(val)); textField.setText(val == null ? "" : EcmaScript.toString(val));
} catch (IllegalArgumentException | IllegalAccessException ex) { } catch (IllegalArgumentException | IllegalAccessException ex) {
// ignore // ignore
} }
@@ -97,20 +152,38 @@ public class FloatEditor extends JTextField implements GenericTagEditor {
oldFieldValue = normalizer.toViewValue(oldFieldValue); oldFieldValue = normalizer.toViewValue(oldFieldValue);
} }
String oldValue = (String) EcmaScript.toString(oldFieldValue); String oldValue = (String) EcmaScript.toString(oldFieldValue);
String newValue = getText(); String newValue = textField.getText();
if (Objects.equals(oldValue, newValue)) { if (Objects.equals(oldValue, newValue)) {
return false; return false;
} }
Object val; Object val;
if (type.equals(double.class) || type.equals(Double.class)) { if (type.equals(double.class) || type.equals(Double.class)) {
val = Double.valueOf(getText()); val = Double.valueOf(textField.getText());
} else { } else {
val = Float.valueOf(getText()); val = Float.valueOf(textField.getText());
} }
if (normalizer != null) { if (normalizer != null) {
val = normalizer.toFieldValue(val); val = normalizer.toFieldValue(val);
} }
ReflectionTools.setValue(obj, field, index, val); ReflectionTools.setValue(obj, field, index, val);
if (linkedField != null && linkEnabled) {
Object linkedFieldValue = ReflectionTools.getValue(obj, linkedField);
Object newLinkefFieldValue = null;
if (oldFieldValue instanceof Double) {
Double v = (Double) oldFieldValue;
Double v2 = (Double) val;
Double vL = (Double) linkedFieldValue;
newLinkefFieldValue = v == 0.0 ? v2 : v2 * vL / v;
} else if (oldFieldValue instanceof Float) {
Float v = (Float) oldFieldValue;
Float v2 = (Float) val;
Float vL = (Float) linkedFieldValue;
newLinkefFieldValue = v == 0f ? v2 : v2 * vL / v;
}
ReflectionTools.setValue(obj, linkedField, -1, newLinkefFieldValue);
}
} catch (IllegalArgumentException | IllegalAccessException ex) { } catch (IllegalArgumentException | IllegalAccessException ex) {
// ignore // ignore
} }
@@ -119,20 +192,12 @@ public class FloatEditor extends JTextField implements GenericTagEditor {
@Override @Override
public void addChangeListener(final ChangeListener l) { public void addChangeListener(final ChangeListener l) {
final PropertyEditor t = this; listeners.add(l);
addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
l.change(t);
}
});
} }
@Override @Override
public Object getChangedValue() { public Object getChangedValue() {
return getText(); return textField.getText();
} }
@Override @Override
@@ -163,10 +228,24 @@ public class FloatEditor extends JTextField implements GenericTagEditor {
public Object getObject() { public Object getObject() {
return obj; return obj;
} }
@Override @Override
public void setValueNormalizer(ValueNormalizer normalizer) { public void setValueNormalizer(ValueNormalizer normalizer) {
this.normalizer = normalizer; this.normalizer = normalizer;
reset(); reset();
} }
public void setLinkedField(Field linkedField) {
this.linkedField = linkedField;
linkLabel.setVisible(true);
}
public void setLinkEnabled(boolean enabled) {
this.linkEnabled = enabled;
linkLabel.setIcon(View.getIcon(enabled ? "link16" : "linkbreak16"));
}
public boolean isLinkEnabled() {
return linkEnabled;
}
} }
@@ -30,7 +30,6 @@ import javax.swing.JPanel;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import javax.swing.SpinnerModel; import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel; import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.text.DefaultFormatter; import javax.swing.text.DefaultFormatter;
/** /**
Binary file not shown.

After

Width:  |  Height:  |  Size: 804 B

@@ -159,4 +159,6 @@ convolution.highPass = High pass
property.instance.filters.menu.clipboard.copySelected = Copy selected property.instance.filters.menu.clipboard.copySelected = Copy selected
property.instance.filters.menu.clipboard.copyAll = Copy all property.instance.filters.menu.clipboard.copyAll = Copy all
property.instance.filters.menu.clipboard.paste = Paste property.instance.filters.menu.clipboard.paste = Paste
property.linkXY = Link X and Y property values