Simple editor - filters (editing only existing, without gradients)

This commit is contained in:
Jindra Petřík
2025-05-10 13:13:17 +02:00
parent c1007fae70
commit 3133d7b6d0
21 changed files with 605 additions and 134 deletions
@@ -5262,7 +5262,11 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
Reference<Rectangle2D> boundsRef = new Reference<>(null);
RECT rect = getTopTimelined().getRect();
Timelined t = getTopTimelined();
if (t == null) {
return;
}
RECT rect = t.getRect();
synchronized (ImagePanel.this) {
synchronized (lock) {
@@ -276,6 +276,9 @@ public class MainFrameClassicMenu extends MainFrameMenu {
if (selected != null) {
selected = mapping(selected);
}
if (menuGroups == null) {
return;
}
for (String path : menuGroups.get(group)) {
setMenuChecked(path, selected == null ? false : path.equals(selected));
}
@@ -264,4 +264,9 @@ public class Amf3ValueEditor extends JPanel implements GenericTagEditor, FullSiz
public Object getObject() {
return obj;
}
@Override
public void setValueNormalizer(ValueNormalizer normalizer) {
}
}
@@ -199,4 +199,9 @@ public class BinaryDataEditor extends JPanel implements GenericTagEditor {
public Object getObject() {
return obj;
}
@Override
public void setValueNormalizer(ValueNormalizer normalizer) {
}
}
@@ -17,15 +17,18 @@
package com.jpexs.decompiler.flash.gui.generictageditors;
import com.jpexs.helpers.ReflectionTools;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Field;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
/**
* @author JPEXS
*/
public class BooleanEditor extends JCheckBox implements GenericTagEditor {
public class BooleanEditor extends JPanel implements GenericTagEditor {
private final Object obj;
@@ -36,6 +39,8 @@ public class BooleanEditor extends JCheckBox implements GenericTagEditor {
private final Class<?> type;
private final String fieldName;
private final JCheckBox checkBox;
@Override
public void added() {
@@ -49,7 +54,13 @@ public class BooleanEditor extends JCheckBox implements GenericTagEditor {
this.index = index;
this.type = type;
this.fieldName = fieldName;
reset();
checkBox = new JCheckBox();
checkBox.setOpaque(false);
checkBox.setRequestFocusEnabled(false);
setLayout(new BorderLayout());
add(checkBox, BorderLayout.CENTER);
setOpaque(false);
reset();
}
@Override
@@ -59,7 +70,7 @@ public class BooleanEditor extends JCheckBox implements GenericTagEditor {
@Override
public void reset() {
try {
setSelected((boolean) ReflectionTools.getValue(obj, field, index));
checkBox.setSelected((boolean) ReflectionTools.getValue(obj, field, index));
} catch (IllegalArgumentException | IllegalAccessException ex) {
// ignore
}
@@ -69,13 +80,13 @@ public class BooleanEditor extends JCheckBox implements GenericTagEditor {
public boolean save() {
try {
boolean oldValue = (boolean) ReflectionTools.getValue(obj, field, index);
boolean newValue = isSelected();
boolean newValue = checkBox.isSelected();
if (oldValue == newValue) {
return false;
}
ReflectionTools.setValue(obj, field, index, isSelected());
ReflectionTools.setValue(obj, field, index, checkBox.isSelected());
} catch (IllegalArgumentException | IllegalAccessException ex) {
// ignore
}
@@ -85,7 +96,7 @@ public class BooleanEditor extends JCheckBox implements GenericTagEditor {
@Override
public void addChangeListener(final ChangeListener l) {
final GenericTagEditor t = this;
addActionListener(new ActionListener() {
checkBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
@@ -96,7 +107,7 @@ public class BooleanEditor extends JCheckBox implements GenericTagEditor {
@Override
public Object getChangedValue() {
return isSelected();
return checkBox.isSelected();
}
@Override
@@ -118,4 +129,9 @@ public class BooleanEditor extends JCheckBox implements GenericTagEditor {
public Object getObject() {
return obj;
}
@Override
public void setValueNormalizer(ValueNormalizer normalizer) {
}
}
@@ -17,12 +17,14 @@
package com.jpexs.decompiler.flash.gui.generictageditors;
import com.jpexs.decompiler.flash.gui.AppStrings;
import com.jpexs.decompiler.flash.gui.FocusablePanel;
import com.jpexs.decompiler.flash.gui.ViewMessages;
import com.jpexs.decompiler.flash.types.ARGB;
import com.jpexs.decompiler.flash.types.RGB;
import com.jpexs.decompiler.flash.types.RGBA;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.ReflectionTools;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
@@ -36,6 +38,8 @@ import java.awt.event.FocusEvent;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import javax.swing.BorderFactory;
import javax.swing.JButton;
@@ -50,7 +54,7 @@ import javax.swing.colorchooser.AbstractColorChooserPanel;
/**
* @author JPEXS
*/
public class ColorEditor extends JPanel implements GenericTagEditor, ActionListener {
public class ColorEditor extends FocusablePanel implements GenericTagEditor, ActionListener {
private final Object obj;
@@ -74,6 +78,8 @@ public class ColorEditor extends JPanel implements GenericTagEditor, ActionListe
private final JButton buttonChange;
private final List<ChangeListener> changeListeners = new ArrayList<>();
public int getColorType() {
return colorType;
}
@@ -90,7 +96,7 @@ public class ColorEditor extends JPanel implements GenericTagEditor, ActionListe
this.type = type;
this.fieldName = fieldName;
setLayout(new FlowLayout());
setLayout(new BorderLayout());
buttonChange = new JButton("") {
@@ -111,7 +117,7 @@ public class ColorEditor extends JPanel implements GenericTagEditor, ActionListe
Dimension colorDim = new Dimension(16, 16);
buttonChange.setSize(colorDim);
buttonChange.setPreferredSize(colorDim);
add(buttonChange);
add(buttonChange, BorderLayout.WEST);
reset();
}
@@ -163,15 +169,7 @@ public class ColorEditor extends JPanel implements GenericTagEditor, ActionListe
@Override
public void addChangeListener(final ChangeListener l) {
final GenericTagEditor t = this;
addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
l.change(t);
}
});
changeListeners.add(l);
}
@Override
@@ -256,15 +254,15 @@ public class ColorEditor extends JPanel implements GenericTagEditor, ActionListe
}
JDialog chooserDialog = null;
private void colorCancelPerformed(ActionEvent e) {
chooserDialog.setVisible(false);
}
private void colorOkPerformed(ActionEvent e) {
chooserDialog.setVisible(false);
}
@Override
public void actionPerformed(ActionEvent e) {
@@ -283,6 +281,10 @@ public class ColorEditor extends JPanel implements GenericTagEditor, ActionListe
color = newColor;
buttonChange.setBackground(color);
repaint();
List<ChangeListener> listeners2 = new ArrayList<>(changeListeners);
for (ChangeListener l : listeners2) {
l.change(this);
}
}
}
@@ -296,4 +298,9 @@ public class ColorEditor extends JPanel implements GenericTagEditor, ActionListe
public Object getObject() {
return obj;
}
@Override
public void setValueNormalizer(ValueNormalizer normalizer) {
}
}
@@ -159,4 +159,9 @@ public class EnumEditor extends JComboBox<ComboBoxItem<Integer>> implements Gene
public Object getObject() {
return obj;
}
@Override
public void setValueNormalizer(ValueNormalizer normalizer) {
}
}
@@ -24,6 +24,8 @@ import java.awt.Dimension;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import javax.swing.JTextField;
@@ -41,7 +43,9 @@ public class FloatEditor extends JTextField implements GenericTagEditor {
private final Class<?> type;
private String fieldName;
private ValueNormalizer normalizer;
@Override
public boolean getScrollableTracksViewportWidth() {
return true;
@@ -77,7 +81,10 @@ public class FloatEditor extends JTextField implements GenericTagEditor {
public void reset() {
try {
Object val = ReflectionTools.getValue(obj, field, index);
setText(val == null ? "" : val.toString());
if (normalizer != null) {
val = normalizer.toViewValue(val);
}
setText(val == null ? "" : EcmaScript.toString(val));
} catch (IllegalArgumentException | IllegalAccessException ex) {
// ignore
}
@@ -86,7 +93,11 @@ public class FloatEditor extends JTextField implements GenericTagEditor {
@Override
public boolean save() {
try {
String oldValue = (String) EcmaScript.toString(ReflectionTools.getValue(obj, field, index));
Object oldFieldValue = ReflectionTools.getValue(obj, field, index);
if (normalizer != null) {
oldFieldValue = normalizer.toViewValue(oldFieldValue);
}
String oldValue = (String) EcmaScript.toString(oldFieldValue);
String newValue = getText();
if (Objects.equals(oldValue, newValue)) {
return false;
@@ -97,6 +108,9 @@ public class FloatEditor extends JTextField implements GenericTagEditor {
} else {
val = Float.valueOf(getText());
}
if (normalizer != null) {
val = normalizer.toFieldValue(val);
}
ReflectionTools.setValue(obj, field, index, val);
} catch (IllegalArgumentException | IllegalAccessException ex) {
// ignore
@@ -150,4 +164,10 @@ public class FloatEditor extends JTextField implements GenericTagEditor {
public Object getObject() {
return obj;
}
@Override
public void setValueNormalizer(ValueNormalizer normalizer) {
this.normalizer = normalizer;
reset();
}
}
@@ -42,4 +42,6 @@ public interface GenericTagEditor {
public void validateValue();
public Object getObject();
public void setValueNormalizer(ValueNormalizer normalizer);
}
@@ -19,12 +19,14 @@ package com.jpexs.decompiler.flash.gui.generictageditors;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.ReflectionTools;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.lang.reflect.Field;
import java.util.Objects;
import javax.swing.JFormattedTextField;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;
@@ -33,7 +35,7 @@ import javax.swing.text.DefaultFormatter;
/**
* @author JPEXS
*/
public class NumberEditor extends JSpinner implements GenericTagEditor {
public class NumberEditor extends JPanel implements GenericTagEditor {
private final Object obj;
@@ -46,6 +48,10 @@ public class NumberEditor extends JSpinner implements GenericTagEditor {
private final SWFType swfType;
private String fieldName;
private ValueNormalizer normalizer;
private JSpinner spinner;
@Override
public BaselineResizeBehavior getBaselineResizeBehavior() {
@@ -71,20 +77,28 @@ public class NumberEditor extends JSpinner implements GenericTagEditor {
this.type = type;
this.swfType = swfType;
this.fieldName = fieldName;
spinner = new JSpinner();
setLayout(new BorderLayout());
add(spinner, BorderLayout.WEST);
setOpaque(false);
reset();
((JSpinner.NumberEditor) getEditor()).getFormat().setGroupingUsed(false);
JFormattedTextField jtf = ((JSpinner.NumberEditor) getEditor()).getTextField();
reset();
((JSpinner.NumberEditor) spinner.getEditor()).getFormat().setGroupingUsed(false);
JFormattedTextField jtf = ((JSpinner.NumberEditor) spinner.getEditor()).getTextField();
DefaultFormatter formatter = (DefaultFormatter) jtf.getFormatter();
formatter.setCommitsOnValidEdit(true);
}
@Override
public void reset() {
try {
Object value = ReflectionTools.getValue(obj, field, index);
setModel(getModel(swfType, value));
if (normalizer != null) {
value = normalizer.toViewValue(value);
}
spinner.setModel(getModel(swfType, value));
} catch (IllegalArgumentException | IllegalAccessException ex) {
// ignore
}
@@ -93,14 +107,22 @@ public class NumberEditor extends JSpinner implements GenericTagEditor {
@Override
public boolean save() {
try {
Object oldValue = ReflectionTools.getValue(obj, field, index);
Object newValue = getChangedValue();
if (newValue == null) {
Object oldValue = ReflectionTools.getValue(obj, field, index);
Object oldViewValue = oldValue;
if (normalizer != null) {
oldViewValue = normalizer.toViewValue(oldValue);
}
Object newViewValue = getChangedValue();
if (newViewValue == null) {
return false;
}
if (Objects.equals(oldValue, newValue)) {
if (Objects.equals(oldViewValue, newViewValue)) {
return false;
}
Object newValue = newViewValue;
if (normalizer != null) {
newValue = normalizer.toFieldValue(newViewValue);
}
ReflectionTools.setValue(obj, field, index, newValue);
} catch (IllegalArgumentException | IllegalAccessException ex) {
// ignore
@@ -210,15 +232,15 @@ public class NumberEditor extends JSpinner implements GenericTagEditor {
public Object getChangedValue() {
Object value = null;
if (type.equals(int.class) || type.equals(Integer.class)) {
value = Integer.parseInt(getValue().toString());
value = Integer.parseInt(spinner.getValue().toString());
} else if (type.equals(short.class) || type.equals(Short.class)) {
value = Short.parseShort(getValue().toString());
value = Short.parseShort(spinner.getValue().toString());
} else if (type.equals(long.class) || type.equals(Long.class)) {
value = Long.parseLong(getValue().toString());
value = Long.parseLong(spinner.getValue().toString());
} else if (type.equals(double.class) || type.equals(Double.class)) {
value = Double.parseDouble(getValue().toString());
value = Double.parseDouble(spinner.getValue().toString());
} else if (type.equals(float.class) || type.equals(Float.class)) {
value = Float.parseFloat(getValue().toString());
value = Float.parseFloat(spinner.getValue().toString());
}
return value;
}
@@ -242,4 +264,9 @@ public class NumberEditor extends JSpinner implements GenericTagEditor {
public Object getObject() {
return obj;
}
@Override
public void setValueNormalizer(ValueNormalizer normalizer) {
this.normalizer = normalizer;
}
}
@@ -151,4 +151,9 @@ public class StringEditor extends JTextArea implements GenericTagEditor {
public Object getObject() {
return obj;
}
@Override
public void setValueNormalizer(ValueNormalizer normalizer) {
}
}
@@ -165,4 +165,9 @@ public class UUIDEditor extends JTextField implements GenericTagEditor {
public Object getObject() {
return obj;
}
@Override
public void setValueNormalizer(ValueNormalizer normalizer) {
}
}
@@ -0,0 +1,27 @@
/*
* Copyright (C) 2025 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.generictageditors;
/**
*
* @author JPEXS
*/
public interface ValueNormalizer {
public Object toFieldValue(Object viewValue);
public Object toViewValue(Object fieldValue);
}
@@ -121,7 +121,9 @@ property.document.backgroundColor = Background color
properties.instance.header.filters = Filters
properties.instance.filters.header.property = Property
properties.instance.filters.header.value = Value
property.instance.filters.header.property = Property
property.instance.filters.header.value = Value
properties.instance.filters.indeterminate = Indeterminate
property.instance.filters.indeterminate = Indeterminate
property.instance.filters = Filters