/* * Copyright (C) 2024 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 . */ package com.jpexs.decompiler.flash.easygui.properties.panels; import com.jpexs.decompiler.flash.easygui.EasyStrings; import com.jpexs.decompiler.flash.easygui.EasySwfPanel; import com.jpexs.decompiler.flash.easygui.EasyTagNameResolver; 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.BoundsChangeListener; 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; import com.jpexs.decompiler.flash.timeline.Timelined; import com.jpexs.decompiler.flash.types.CXFORMWITHALPHA; import com.jpexs.decompiler.flash.types.ColorTransform; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.border.BevelBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import com.jpexs.decompiler.flash.easygui.properties.JTriStateCheckBox; import com.jpexs.decompiler.flash.easygui.properties.PropertyChangeDoableOperation; import com.jpexs.decompiler.flash.gui.ViewMessages; import com.jpexs.decompiler.flash.types.RGBA; import java.awt.Color; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Arrays; import javax.swing.DefaultComboBoxModel; import javax.swing.SwingUtilities; /** * * @author JPEXS */ public class InstancePropertiesPanel 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); private final IntegerPropertyField bluePercentPropertyField = new IntegerPropertyField(100, -100, 100); private final IntegerPropertyField alphaAddPropertyField = new IntegerPropertyField(0, -255, 255); private final IntegerPropertyField redAddPropertyField = new IntegerPropertyField(0, -255, 255); private final IntegerPropertyField greenAddPropertyField = new IntegerPropertyField(0, -255, 255); private final IntegerPropertyField blueAddPropertyField = new IntegerPropertyField(0, -255, 255); private final EasySwfPanel swfPanel; private final JPanel propertiesPanel; private Rectangle2D lastBounds = null; private JLabel instanceLabel; private final JTriStateCheckBox visibleCheckBox = new JTriStateCheckBox(); private final JComboBox blendingComboBox = new JComboBox<>(); private final JTriStateCheckBox cacheAsBitmapCheckBox = new JTriStateCheckBox(); private final JComboBox backgroundComboBox = new JComboBox<>(); private final JPanel backgroundColorPanel = new JPanel(); private final JLabel backgroundColorLabel = new JLabel(); private boolean updating = false; public InstancePropertiesPanel(EasySwfPanel swfPanel, UndoManager undoManager) { super("instance"); setLayout(new BorderLayout()); instanceLabel = new JLabel(EasyStrings.translate("properties.instance.none")); instanceLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0)); add(instanceLabel, BorderLayout.NORTH); 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); gbc = new GridBagConstraints(); gbc.weightx = 0; gbc.insets = new Insets(3, 3, 3, 3); gbc.gridx = 0; gbc.gridy = 0; gbc.anchor = GridBagConstraints.EAST; colorEffectPanel.add(new JLabel(formatPropertyName("colorEffect.alpha")), gbc); gbc.anchor = GridBagConstraints.WEST; gbc.gridx++; colorEffectPanel.add(alphaPercentPropertyField, gbc); gbc.gridx++; colorEffectPanel.add(new JLabel("% \u00D7 A + "), gbc); gbc.gridx++; colorEffectPanel.add(alphaAddPropertyField, gbc); gbc.gridx = 0; gbc.gridy++; gbc.anchor = GridBagConstraints.EAST; colorEffectPanel.add(new JLabel(formatPropertyName("colorEffect.red")), gbc); gbc.anchor = GridBagConstraints.WEST; gbc.gridx++; colorEffectPanel.add(redPercentPropertyField, gbc); gbc.gridx++; colorEffectPanel.add(new JLabel("% \u00D7 R + "), gbc); gbc.gridx++; colorEffectPanel.add(redAddPropertyField, gbc); gbc.gridx = 0; gbc.gridy++; gbc.anchor = GridBagConstraints.EAST; colorEffectPanel.add(new JLabel(formatPropertyName("colorEffect.green")), gbc); gbc.anchor = GridBagConstraints.WEST; gbc.gridx++; colorEffectPanel.add(greenPercentPropertyField, gbc); gbc.gridx++; colorEffectPanel.add(new JLabel("% \u00D7 G + "), gbc); gbc.gridx++; colorEffectPanel.add(greenAddPropertyField, gbc); gbc.gridx = 0; gbc.gridy++; gbc.anchor = GridBagConstraints.EAST; colorEffectPanel.add(new JLabel(formatPropertyName("colorEffect.blue")), gbc); gbc.anchor = GridBagConstraints.WEST; gbc.gridx++; colorEffectPanel.add(bluePercentPropertyField, gbc); gbc.gridx++; colorEffectPanel.add(new JLabel("% \u00D7 B + "), gbc); gbc.gridx++; colorEffectPanel.add(blueAddPropertyField, gbc); gbc.gridx++; gbc.gridy = 0; gbc.gridheight = 4; gbc.weightx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; colorEffectPanel.add(new JPanel(), gbc); JPanel displayPanel = new JPanel(); gridBag = new GridBagLayout(); displayPanel.setLayout(gridBag); gbc = new GridBagConstraints(); gbc.insets = new Insets(3, 3, 3, 3); gbc.gridx = 0; gbc.gridy = 0; gbc.gridwidth = 1; gbc.anchor = GridBagConstraints.EAST; displayPanel.add(new JLabel(formatPropertyName("display.visible")), gbc); gbc.gridx++; gbc.gridwidth = 2; gbc.anchor = GridBagConstraints.WEST; displayPanel.add(visibleCheckBox, gbc); gbc.gridy++; gbc.gridx = 0; gbc.gridwidth = 1; gbc.anchor = GridBagConstraints.EAST; displayPanel.add(new JLabel(formatPropertyName("display.blending")), gbc); blendingComboBox.addItem(EasyStrings.translate("property.instance.display.blending.normal")); blendingComboBox.addItem(EasyStrings.translate("property.instance.display.blending.layer")); blendingComboBox.addItem(EasyStrings.translate("property.instance.display.blending.multiply")); blendingComboBox.addItem(EasyStrings.translate("property.instance.display.blending.screen")); blendingComboBox.addItem(EasyStrings.translate("property.instance.display.blending.lighten")); blendingComboBox.addItem(EasyStrings.translate("property.instance.display.blending.darken")); blendingComboBox.addItem(EasyStrings.translate("property.instance.display.blending.difference")); blendingComboBox.addItem(EasyStrings.translate("property.instance.display.blending.add")); blendingComboBox.addItem(EasyStrings.translate("property.instance.display.blending.subtract")); blendingComboBox.addItem(EasyStrings.translate("property.instance.display.blending.invert")); blendingComboBox.addItem(EasyStrings.translate("property.instance.display.blending.alpha")); blendingComboBox.addItem(EasyStrings.translate("property.instance.display.blending.erase")); blendingComboBox.addItem(EasyStrings.translate("property.instance.display.blending.overlay")); blendingComboBox.addItem(EasyStrings.translate("property.instance.display.blending.hardlight")); gbc.gridx++; gbc.anchor = GridBagConstraints.WEST; gbc.gridwidth = 2; displayPanel.add(blendingComboBox, gbc); gbc.gridy++; gbc.gridx = 0; gbc.gridwidth = 1; gbc.anchor = GridBagConstraints.EAST; displayPanel.add(new JLabel(formatPropertyName("display.cacheAsBitmap")), gbc); gbc.gridx++; gbc.gridwidth = 2; gbc.anchor = GridBagConstraints.WEST; displayPanel.add(cacheAsBitmapCheckBox, gbc); backgroundComboBox.addItem(EasyStrings.translate("property.instance.display.cacheAsBitmap.transparent")); backgroundComboBox.addItem(EasyStrings.translate("property.instance.display.cacheAsBitmap.opaque")); backgroundColorPanel.setLayout(new BorderLayout()); backgroundColorPanel.add(backgroundColorLabel, BorderLayout.CENTER); backgroundColorPanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED)); backgroundColorPanel.setPreferredSize(new Dimension(16,16)); gbc.gridy++; gbc.gridx = 1; gbc.gridwidth = 1; displayPanel.add(backgroundComboBox, gbc); gbc.gridx++; displayPanel.add(backgroundColorPanel, gbc); cacheAsBitmapCheckBox.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (updating) { return; } backgroundComboBox.setVisible(cacheAsBitmapCheckBox.isSelected()); backgroundColorPanel.setVisible(cacheAsBitmapCheckBox.isSelected() && backgroundComboBox.getSelectedIndex() == backgroundComboBox.getItemCount() - 1); revalidate(); } }); backgroundComboBox.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (updating) { return; } backgroundColorPanel.setVisible(backgroundComboBox.getSelectedIndex() == backgroundComboBox.getItemCount() - 1); revalidate(); } }); gbc.gridy++; gbc.gridx=0; gbc.gridwidth=3; gbc.weightx = 0; gbc.weighty = 1; gbc.fill = GridBagConstraints.VERTICAL; displayPanel.add(new JPanel(), gbc); gbc.gridx = 3; gbc.gridy = 0; gbc.gridheight = 4; gbc.weighty = 0; gbc.weightx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; displayPanel.add(new JPanel(), gbc); propertiesPanel = new JPanel(); propertiesPanel.setLayout(new BoxLayout(propertiesPanel, BoxLayout.Y_AXIS)); propertiesPanel.add(makeCard("positionSize", null, positionSizePanel)); setCardOpened("positionSize", true); propertiesPanel.add(makeCard("colorEffect", null, colorEffectPanel)); propertiesPanel.add(makeCard("display", null, displayPanel)); this.swfPanel = swfPanel; alphaPercentPropertyField.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { undoManager.doOperation(new ColorEffectChangeDoableOperation("alpha") { int value = alphaPercentPropertyField.getValue(); @Override public void doColorEffectOperation(CXFORMWITHALPHA colorTransform) { colorTransform.alphaMultTerm = Math.round(value * 256 / 100f); colorTransform.hasMultTerms = true; } }, swfPanel.getSwf()); } }); alphaAddPropertyField.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { undoManager.doOperation(new ColorEffectChangeDoableOperation("alpha") { int value = alphaAddPropertyField.getValue(); @Override public void doColorEffectOperation(CXFORMWITHALPHA colorTransform) { colorTransform.alphaAddTerm = value; colorTransform.hasAddTerms = true; } }, swfPanel.getSwf()); } }); redPercentPropertyField.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { undoManager.doOperation(new ColorEffectChangeDoableOperation("red") { int value = redPercentPropertyField.getValue(); @Override public void doColorEffectOperation(CXFORMWITHALPHA colorTransform) { colorTransform.redMultTerm = Math.round(value * 256 / 100f); colorTransform.hasMultTerms = true; } }, swfPanel.getSwf()); } }); redAddPropertyField.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { undoManager.doOperation(new ColorEffectChangeDoableOperation("red") { int value = redAddPropertyField.getValue(); @Override public void doColorEffectOperation(CXFORMWITHALPHA colorTransform) { colorTransform.redAddTerm = value; colorTransform.hasAddTerms = true; } }, swfPanel.getSwf()); } }); greenPercentPropertyField.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { undoManager.doOperation(new ColorEffectChangeDoableOperation("green") { int value = greenPercentPropertyField.getValue(); @Override public void doColorEffectOperation(CXFORMWITHALPHA colorTransform) { colorTransform.greenMultTerm = Math.round(value * 256 / 100f); colorTransform.hasMultTerms = true; } }, swfPanel.getSwf()); } }); greenAddPropertyField.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { undoManager.doOperation(new ColorEffectChangeDoableOperation("green") { int value = greenAddPropertyField.getValue(); @Override public void doColorEffectOperation(CXFORMWITHALPHA colorTransform) { colorTransform.greenAddTerm = value; colorTransform.hasAddTerms = true; } }, swfPanel.getSwf()); } }); bluePercentPropertyField.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { undoManager.doOperation(new ColorEffectChangeDoableOperation("blue") { int value = bluePercentPropertyField.getValue(); @Override public void doColorEffectOperation(CXFORMWITHALPHA colorTransform) { colorTransform.blueMultTerm = Math.round(value * 256 / 100f); colorTransform.hasMultTerms = true; } }, swfPanel.getSwf()); } }); blueAddPropertyField.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { undoManager.doOperation(new ColorEffectChangeDoableOperation("blue") { int value = blueAddPropertyField.getValue(); @Override public void doColorEffectOperation(CXFORMWITHALPHA colorTransform) { colorTransform.blueAddTerm = value; colorTransform.hasAddTerms = true; } }, swfPanel.getSwf()); } }); 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 nonZeroFloatValidation = new PropertyValidationInteface() { @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); visibleCheckBox.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (updating) { return; } undoManager.doOperation(new PlaceChangeDoableOperation("instance.display.visible", 3) { int visible = visibleCheckBox.isSelected() ? 1 : 0; @Override public void doPlaceOperation(PlaceObjectTypeTag placeObject, DepthState depthState) { placeObject.setVisible(visible); } }, swfPanel.getSwf()); } }); blendingComboBox.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (updating) { return; } undoManager.doOperation(new PlaceChangeDoableOperation("instance.display.blending", 3) { int blendMode = blendingComboBox.getSelectedIndex() + 1; @Override public void doPlaceOperation(PlaceObjectTypeTag placeObject, DepthState depthState) { placeObject.setBlendMode(blendMode); } }, swfPanel.getSwf()); } }); cacheAsBitmapCheckBox.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (updating) { return; } undoManager.doOperation(new PlaceChangeDoableOperation("instance.display.cacheAsBitmap", 3) { int bitmapCache = cacheAsBitmapCheckBox.isSelected() ? 1 : 0; @Override public void doPlaceOperation(PlaceObjectTypeTag placeObject, DepthState depthState) { placeObject.setBitmapCache(bitmapCache); placeObject.setPlaceFlagHasCacheAsBitmap(bitmapCache == 1); if (bitmapCache == 0) { placeObject.setBackgroundColor(null); placeObject.setPlaceFlagOpaqueBackground(false); } } }, swfPanel.getSwf()); } }); backgroundComboBox.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (updating) { return; } boolean isOpaque = backgroundComboBox.getSelectedIndex() == backgroundComboBox.getItemCount() - 1; undoManager.doOperation(new PlaceChangeDoableOperation("instance.display.cacheAsBitmap", 3) { RGBA color = isOpaque ? new RGBA(backgroundColorPanel.getBackground()) : null; @Override public void doPlaceOperation(PlaceObjectTypeTag placeObject, DepthState depthState) { if (color != null) { backgroundColorLabel.setText(""); placeObject.setBackgroundColor(color); } else { placeObject.setPlaceFlagOpaqueBackground(false); } } }, swfPanel.getSwf()); } }); backgroundColorPanel.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 1) { Color newColor = ViewMessages.showColorDialog(InstancePropertiesPanel.this, backgroundColorPanel.getBackground(), false); if (newColor != null) { backgroundColorPanel.setBackground(newColor); backgroundColorLabel.setText(""); undoManager.doOperation(new PlaceChangeDoableOperation("instance.display.cacheAsBitmap", 3) { RGBA color = new RGBA(newColor); @Override public void doPlaceOperation(PlaceObjectTypeTag placeObject, DepthState depthState) { placeObject.setBackgroundColor(color); } }, swfPanel.getSwf()); } } } }); 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 dss = swfPanel.getSelectedDepthStates(); if (dss == null || dss.isEmpty()) { instanceLabel.setText(EasyStrings.translate("properties.instance.none")); propertiesPanel.setVisible(false); return; } propertiesPanel.setVisible(true); if (dss.size() == 1) { EasyTagNameResolver resolver = new EasyTagNameResolver(); instanceLabel.setText(EasyStrings.translate("properties.instance.single").replace("%item%", resolver.getTagName(dss.get(0).getCharacter()))); } else { instanceLabel.setText(EasyStrings.translate("properties.instance.multiple").replace("%count%", "" + dss.size())); } //swfPanel.getStagePanel().get Set alphaPercent = new HashSet<>(); Set alphaAdd = new HashSet<>(); Set redPercent = new HashSet<>(); Set redAdd = new HashSet<>(); Set greenPercent = new HashSet<>(); Set greenAdd = new HashSet<>(); Set bluePercent = new HashSet<>(); Set blueAdd = new HashSet<>(); Set visible = new HashSet<>(); Set blendMode = new HashSet<>(); Set cacheAsBitmap = new HashSet<>(); Set backgroundColor = new HashSet<>(); for (DepthState ds : dss) { if (ds == null) { continue; } ColorTransform colorTransform = ds.colorTransForm; if (colorTransform == null) { alphaPercent.add(100); alphaAdd.add(0); redPercent.add(100); redAdd.add(0); greenPercent.add(100); greenAdd.add(0); bluePercent.add(100); blueAdd.add(0); } else { alphaPercent.add(colorTransform.getAlphaMulti() * 100 / 256); alphaAdd.add(colorTransform.getAlphaAdd()); redPercent.add(colorTransform.getRedMulti() * 100 / 256); redAdd.add(colorTransform.getRedAdd()); greenPercent.add(colorTransform.getGreenMulti() * 100 / 256); greenAdd.add(colorTransform.getGreenAdd()); bluePercent.add(colorTransform.getBlueMulti() * 100 / 256); blueAdd.add(colorTransform.getBlueAdd()); } visible.add(ds.isVisible); int bm = ds.blendMode; if (bm == 0) { bm = 1; } blendMode.add(bm); cacheAsBitmap.add(ds.cacheAsBitmap); backgroundColor.add(ds.backGroundColor); } 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); if (visible.size() > 1) { visibleCheckBox.setSelectionState(1); } else { visibleCheckBox.setSelected(visible.iterator().next()); } DefaultComboBoxModel model = (DefaultComboBoxModel) blendingComboBox.getModel(); if (blendMode.size() > 1) { if (!model.getElementAt(0).equals("")) { model.addAll(0, Arrays.asList("")); } blendingComboBox.setSelectedIndex(0); } else { if (model.getElementAt(0).equals("")) { model.removeElementAt(0); } int bm = blendMode.iterator().next(); bm--; blendingComboBox.setSelectedIndex(bm); } if (cacheAsBitmap.size() > 1) { cacheAsBitmapCheckBox.setSelectionState(1); } else { cacheAsBitmapCheckBox.setSelected(cacheAsBitmap.iterator().next()); } backgroundComboBox.setVisible(cacheAsBitmapCheckBox.getSelectionState() == 2); DefaultComboBoxModel backgroundModel = (DefaultComboBoxModel) backgroundComboBox.getModel(); if (backgroundColor.size() > 1) { if (backgroundColor.contains(null)) { if (backgroundModel.getSize() == 2) { backgroundModel.addAll(0, Arrays.asList("")); } backgroundComboBox.setSelectedIndex(0); backgroundColorPanel.setVisible(false); } else { if (backgroundModel.getSize() == 3) { backgroundModel.removeElementAt(0); } backgroundComboBox.setSelectedIndex(1); backgroundColorPanel.setVisible(true); backgroundColorLabel.setText("--"); backgroundColorPanel.setBackground(Color.WHITE); backgroundColorPanel.setOpaque(true); } } else { if (backgroundModel.getSize() == 3) { backgroundModel.removeElementAt(0); } RGBA bgColor = backgroundColor.iterator().next(); backgroundComboBox.setSelectedIndex(bgColor == null ? 0 : 1); backgroundColorLabel.setText(""); if (bgColor == null) { backgroundColorPanel.setVisible(false); } else { backgroundColorPanel.setVisible(true); backgroundColorPanel.setBackground(bgColor.toColor()); backgroundColorPanel.setOpaque(true); } } updating = false; revalidate(); } abstract class PlaceChangeDoableOperation extends PropertyChangeDoableOperation { List fdepths = swfPanel.getDepths(); int fframe = swfPanel.getFrame(); List depthStatesBefore = swfPanel.getSelectedDepthStates(); List placeObjectsBefore = swfPanel.getSelectedPlaceTags(); List placeObjectsAfter = new ArrayList<>(); private final boolean timelinedModifiedBefore = swfPanel.getTimelined().isModified(); private final Timelined timelined = swfPanel.getTimelined(); public PlaceChangeDoableOperation(String propertyIdentifier, int minPlace) { super(propertyIdentifier); for (int i = 0; i < fdepths.size(); i++) { PlaceObjectTypeTag placeObjectBefore = placeObjectsBefore.get(i); int convNum = placeObjectBefore.getPlaceObjectNum() < minPlace ? minPlace : placeObjectBefore.getPlaceObjectNum(); PlaceObjectTypeConverter conv = new PlaceObjectTypeConverter(); PlaceObjectTypeTag placeObjectAfter = conv.convertTagType(placeObjectBefore, timelined.getSwf(), convNum, false); placeObjectsAfter.add(placeObjectAfter); } } @Override public final void doOperation() { swfPanel.getStagePanel().gotoFrame(fframe + 1); swfPanel.getStagePanel().selectDepths(fdepths); for (int i = 0; i < fdepths.size(); i++) { PlaceObjectTypeTag placeObjectBefore = placeObjectsBefore.get(i); PlaceObjectTypeTag placeObjectAfter = placeObjectsAfter.get(i); int index = timelined.indexOfTag(placeObjectBefore); timelined.removeTag(index); timelined.addTag(index, placeObjectAfter); timelined.setModified(true); DepthState depthStateBefore = depthStatesBefore.get(i); doPlaceOperation(placeObjectAfter, depthStateBefore); } timelined.resetTimeline(); update(); } @Override public final void undoOperation() { swfPanel.getStagePanel().gotoFrame(fframe + 1); swfPanel.getStagePanel().selectDepths(fdepths); for (int i = 0; i < placeObjectsAfter.size(); i++) { PlaceObjectTypeTag placeObjectAfter = placeObjectsAfter.get(i); PlaceObjectTypeTag placeObjectBefore = placeObjectsBefore.get(i); int index = timelined.indexOfTag(placeObjectAfter); timelined.removeTag(index); timelined.addTag(index, placeObjectBefore); } if (!timelinedModifiedBefore) { timelined.setModified(false); } timelined.resetTimeline(); update(); } public abstract void doPlaceOperation(PlaceObjectTypeTag placeObject, DepthState depthState); } abstract class ColorEffectChangeDoableOperation extends PlaceChangeDoableOperation { CXFORMWITHALPHA colorTransformAfter; public ColorEffectChangeDoableOperation(String colorProperty) { super("instance.colorEffect." + colorProperty, 2); } @Override public final void doPlaceOperation(PlaceObjectTypeTag placeObject, DepthState depthState) { colorTransformAfter = depthState.colorTransForm == null ? new CXFORMWITHALPHA() : new CXFORMWITHALPHA(depthState.colorTransForm); doColorEffectOperation(colorTransformAfter); placeObject.setColorTransform(colorTransformAfter); } public abstract void doColorEffectOperation(CXFORMWITHALPHA colorTransform); } }