diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java index 19d804dd5..21e5734d0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java @@ -577,7 +577,7 @@ public class PlaceObject3Tag extends PlaceObjectTypeTag implements ASMSourceCont @Override public boolean cacheAsBitmap() { - return placeFlagHasCacheAsBitmap; + return placeFlagHasCacheAsBitmap && bitmapCache == 1; } @Override @@ -704,4 +704,45 @@ public class PlaceObject3Tag extends PlaceObjectTypeTag implements ASMSourceCont this.colorTransform = new CXFORMWITHALPHA(colorTransform); placeFlagHasColorTransform = true; } + + @Override + public void setVisible(int value) { + this.visible = value; + placeFlagHasVisible = true; + } + + @Override + public void setPlaceFlagHasVisible(boolean value) { + this.placeFlagHasVisible = value; + } + + @Override + public void setBlendMode(int value) { + this.blendMode = value; + this.placeFlagHasBlendMode = true; + } + + @Override + public void setPlaceFlagHasBlendMode(boolean value) { + this.placeFlagHasBlendMode = value; + } + + public void setBitmapCache(int value) { + this.bitmapCache = value; + this.placeFlagHasCacheAsBitmap = true; + } + + public void setPlaceFlagHasCacheAsBitmap(boolean value) { + this.placeFlagHasCacheAsBitmap = value; + } + + public void setBackgroundColor(RGBA value) { + this.backgroundColor = value; + this.placeFlagOpaqueBackground = true; + } + + public void setPlaceFlagOpaqueBackground(boolean value) { + this.placeFlagOpaqueBackground = value; + } + } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObject4Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObject4Tag.java index 58ac123b4..6a4b40ca6 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObject4Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/PlaceObject4Tag.java @@ -598,7 +598,7 @@ public class PlaceObject4Tag extends PlaceObjectTypeTag implements ASMSourceCont @Override public boolean cacheAsBitmap() { - return placeFlagHasCacheAsBitmap; + return placeFlagHasCacheAsBitmap && bitmapCache == 1; } @Override @@ -725,4 +725,44 @@ public class PlaceObject4Tag extends PlaceObjectTypeTag implements ASMSourceCont this.colorTransform = new CXFORMWITHALPHA(colorTransform); placeFlagHasColorTransform = true; } + + @Override + public void setVisible(int value) { + this.visible = value; + placeFlagHasVisible = true; + } + + @Override + public void setPlaceFlagHasVisible(boolean value) { + this.placeFlagHasVisible = value; + } + + @Override + public void setBlendMode(int value) { + this.blendMode = value; + this.placeFlagHasBlendMode = true; + } + + @Override + public void setPlaceFlagHasBlendMode(boolean value) { + this.placeFlagHasBlendMode = value; + } + + public void setBitmapCache(int value) { + this.bitmapCache = value; + this.placeFlagHasCacheAsBitmap = true; + } + + public void setPlaceFlagHasCacheAsBitmap(boolean value) { + this.placeFlagHasCacheAsBitmap = value; + } + + public void setBackgroundColor(RGBA value) { + this.backgroundColor = value; + this.placeFlagOpaqueBackground = true; + } + + public void setPlaceFlagOpaqueBackground(boolean value) { + this.placeFlagOpaqueBackground = value; + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/PlaceObjectTypeTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/PlaceObjectTypeTag.java index 75d959b9b..ca847c75c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/PlaceObjectTypeTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/PlaceObjectTypeTag.java @@ -214,7 +214,39 @@ public abstract class PlaceObjectTypeTag extends Tag implements CharacterIdTag, * @param colorTransform Color transform */ public abstract void setColorTransform(ColorTransform colorTransform); + + public void setVisible(int visible) { + throw new UnsupportedOperationException(); + } + + public void setPlaceFlagHasVisible(boolean value) { + throw new UnsupportedOperationException(); + } + + public void setBlendMode(int value) { + throw new UnsupportedOperationException(); + } + + public void setPlaceFlagHasBlendMode(boolean value) { + throw new UnsupportedOperationException(); + } + + public void setBitmapCache(int value) { + throw new UnsupportedOperationException(); + } + public void setPlaceFlagHasCacheAsBitmap(boolean value) { + throw new UnsupportedOperationException(); + } + + public void setBackgroundColor(RGBA value) { + throw new UnsupportedOperationException(); + } + + public void setPlaceFlagOpaqueBackground(boolean value) { + throw new UnsupportedOperationException(); + } + /** * Checks if place equals. * @param other Other place object type tag diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java index 89423eb46..805c23364 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java @@ -61,6 +61,7 @@ import com.jpexs.decompiler.flash.types.CXFORMWITHALPHA; import com.jpexs.decompiler.flash.types.ColorTransform; import com.jpexs.decompiler.flash.types.MATRIX; import com.jpexs.decompiler.flash.types.RECT; +import com.jpexs.decompiler.flash.types.RGBA; import com.jpexs.decompiler.flash.types.SOUNDINFO; import com.jpexs.decompiler.flash.types.filters.BlendComposite; import com.jpexs.decompiler.flash.types.filters.FILTER; @@ -603,6 +604,11 @@ public class Timeline { if (clipDepth2 > -1) { fl.clipDepth = clipDepth2; } + + RGBA bgColor = po.getBackgroundColor(); + if (bgColor != null) { + fl.backGroundColor = bgColor; + } fl.isVisible = po.isVisible(); } else { @@ -616,6 +622,7 @@ public class Timeline { fl.clipActions = po.getClipActions(); fl.clipDepth = po.getClipDepth(); fl.isVisible = po.isVisible(); + fl.backGroundColor = po.getBackgroundColor(); } } diff --git a/src/com/jpexs/decompiler/flash/easygui/properties/JTriStateCheckBox.java b/src/com/jpexs/decompiler/flash/easygui/properties/JTriStateCheckBox.java new file mode 100644 index 000000000..45340d400 --- /dev/null +++ b/src/com/jpexs/decompiler/flash/easygui/properties/JTriStateCheckBox.java @@ -0,0 +1,141 @@ +/* + * 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; + +/** + * + * @author JPEXS + */ +import com.jpexs.decompiler.flash.configuration.Configuration; +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; + +public class JTriStateCheckBox extends JCheckBox { + + final static boolean MID_AS_SELECTED = true; //consider mid-state as selected ? + + public JTriStateCheckBox() { + this(""); + } + + public JTriStateCheckBox(String text) { + super(text); + putClientProperty("SelectionState", 0); + } + + @Override + protected void fireActionPerformed(ActionEvent event) { + actionPerformed(); + super.fireActionPerformed(event); + } + + + + public JTriStateCheckBox(String text, int sel) { + /* tri-state checkbox has 3 selection states: + * 0 unselected + * 1 mid-state selection + * 2 fully selected + */ + super(text, sel > 1 ? true : false); + + switch (sel) { + case 2: + setSelected(true); + case 1: + case 0: + putClientProperty("SelectionState", sel); + break; + default: + throw new IllegalArgumentException(); + } + } + + @Override + public boolean isSelected() { + if (MID_AS_SELECTED && (getSelectionState() > 0)) { + return true; + } + return super.isSelected(); + } + + public int getSelectionState() { + return (getClientProperty("SelectionState") != null ? (int) getClientProperty("SelectionState") + : super.isSelected() ? 2 + : 0); + } + + public void setSelectionState(int sel) { + switch (sel) { + case 2: + super.setSelected(true); + break; + case 1: + case 0: + super.setSelected(false); + break; + default: + throw new IllegalArgumentException(); + } + putClientProperty("SelectionState", sel); + } + + @Override + public void setSelected(boolean b) { + super.setSelected(b); + putClientProperty("SelectionState", b ? 2 : 0); + } + + + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + if (getSelectionState() == 1) { + int w = 12; + if (Configuration.useRibbonInterface.get()) { + /*SubstanceColorScheme baseMarkColorScheme = SubstanceColorSchemeUtilities + .getColorScheme(this, ColorSchemeAssociationKind.MARK, + ComponentState.getState(this)); + + g.setColor(baseMarkColorScheme.getSelectionForegroundColor());*/ + w = 14; + } else { + w = 12; + } + g.setColor(getForeground()); + g.fillRect(5, getHeight() / 2 - 2, w, 4); + } + } + + private void actionPerformed() { + int selectionState = getSelectionState(); + switch (selectionState) { + case 0: + case 1: + selectionState = 2; + break; + case 2: + selectionState = 0; + break; + } + putClientProperty("SelectionState", selectionState); + + repaint(); + } +} diff --git a/src/com/jpexs/decompiler/flash/easygui/properties/PropertyChangeDoableOperation.java b/src/com/jpexs/decompiler/flash/easygui/properties/PropertyChangeDoableOperation.java new file mode 100644 index 000000000..2430dd7ec --- /dev/null +++ b/src/com/jpexs/decompiler/flash/easygui/properties/PropertyChangeDoableOperation.java @@ -0,0 +1,39 @@ +/* + * 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; + +import com.jpexs.decompiler.flash.easygui.DoableOperation; +import com.jpexs.decompiler.flash.easygui.EasyStrings; + +/** + * + * @author JPEXS + */ +public abstract class PropertyChangeDoableOperation implements DoableOperation { + + private final String itemIdentifier; + + public PropertyChangeDoableOperation(String propertyIdentifier) { + this.itemIdentifier = propertyIdentifier; + } + + + @Override + public String getDescription() { + return EasyStrings.translate("action.change").replace("%item%", EasyStrings.translate("property." + itemIdentifier)); + } +} diff --git a/src/com/jpexs/decompiler/flash/easygui/properties/panels/InstancePropertiesPanel.java b/src/com/jpexs/decompiler/flash/easygui/properties/panels/InstancePropertiesPanel.java index abaf9ec41..f0c586e1d 100644 --- a/src/com/jpexs/decompiler/flash/easygui/properties/panels/InstancePropertiesPanel.java +++ b/src/com/jpexs/decompiler/flash/easygui/properties/panels/InstancePropertiesPanel.java @@ -27,6 +27,7 @@ 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.PlaceObject3Tag; import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag; import com.jpexs.decompiler.flash.tags.converters.PlaceObjectTypeConverter; import com.jpexs.decompiler.flash.timeline.DepthState; @@ -34,9 +35,12 @@ 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; @@ -45,10 +49,23 @@ import java.util.List; import java.util.Set; import javax.swing.BorderFactory; import javax.swing.BoxLayout; +import javax.swing.JCheckBox; +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; /** * @@ -77,6 +94,16 @@ public class InstancePropertiesPanel extends AbstractPropertiesPanel { 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()); @@ -192,6 +219,125 @@ public class InstancePropertiesPanel extends AbstractPropertiesPanel { 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)); @@ -200,6 +346,9 @@ public class InstancePropertiesPanel extends AbstractPropertiesPanel { setCardOpened("positionSize", true); propertiesPanel.add(makeCard("colorEffect", null, colorEffectPanel)); + + propertiesPanel.add(makeCard("display", null, displayPanel)); + this.swfPanel = swfPanel; alphaPercentPropertyField.addChangeListener(new ChangeListener() { @@ -373,6 +522,102 @@ public class InstancePropertiesPanel extends AbstractPropertiesPanel { }); 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() { @@ -396,6 +641,7 @@ public class InstancePropertiesPanel extends AbstractPropertiesPanel { } public void update() { + updating = true; List dss = swfPanel.getSelectedDepthStates(); if (dss == null || dss.isEmpty()) { instanceLabel.setText(EasyStrings.translate("properties.instance.none")); @@ -421,6 +667,10 @@ public class InstancePropertiesPanel extends AbstractPropertiesPanel { 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) { @@ -446,6 +696,14 @@ public class InstancePropertiesPanel extends AbstractPropertiesPanel { 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); } @@ -457,9 +715,81 @@ public class InstancePropertiesPanel extends AbstractPropertiesPanel { 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 ChangeDoableOperation { + abstract class PlaceChangeDoableOperation extends PropertyChangeDoableOperation { List fdepths = swfPanel.getDepths(); int fframe = swfPanel.getFrame(); @@ -470,12 +800,12 @@ public class InstancePropertiesPanel extends AbstractPropertiesPanel { private final boolean timelinedModifiedBefore = swfPanel.getTimelined().isModified(); - private Timelined timelined = swfPanel.getTimelined(); + private final Timelined timelined = swfPanel.getTimelined(); - public PlaceChangeDoableOperation(String itemIdentifier, int minPlace) { - super(itemIdentifier); + public PlaceChangeDoableOperation(String propertyIdentifier, int minPlace) { + super(propertyIdentifier); for (int i = 0; i < fdepths.size(); i++) { PlaceObjectTypeTag placeObjectBefore = placeObjectsBefore.get(i); @@ -534,7 +864,7 @@ public class InstancePropertiesPanel extends AbstractPropertiesPanel { CXFORMWITHALPHA colorTransformAfter; public ColorEffectChangeDoableOperation() { - super("colorEffect", 2); + super("instance.header.colorEffect", 2); } @Override diff --git a/src/com/jpexs/decompiler/flash/gui/locales/EasyPanel.properties b/src/com/jpexs/decompiler/flash/gui/locales/EasyPanel.properties index d3e7a48cd..58de6d2d1 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/EasyPanel.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/EasyPanel.properties @@ -92,4 +92,26 @@ property.instance.positionSize.y = Y property.instance.positionSize.width = W property.instance.positionSize.height = H +properties.instance.header.display = Display +property.instance.display.visible = Visible +property.instance.display.blending = Blending + +property.instance.display.blending.normal = Normal +property.instance.display.blending.layer = Layer +property.instance.display.blending.multiply = Multiply +property.instance.display.blending.screen = Screen +property.instance.display.blending.lighten = Lighten +property.instance.display.blending.darken = Darken +property.instance.display.blending.difference = Difference +property.instance.display.blending.add = Add +property.instance.display.blending.subtract = Subtract +property.instance.display.blending.invert = Invert +property.instance.display.blending.alpha = Alpha +property.instance.display.blending.erase = Erase +property.instance.display.blending.overlay = Overlay +property.instance.display.blending.hardlight = Hardlight + +property.instance.display.cacheAsBitmap = Cache as bitmap +property.instance.display.cacheAsBitmap.transparent = Transparent +property.instance.display.cacheAsBitmap.opaque = Opaque