Added Context menu items to create new tags (shape, sprite, image, movie, sound, binaryData) from files and using font embed dialog for fonts

This commit is contained in:
Jindra Petřík
2023-10-22 10:25:50 +02:00
parent f3341c5490
commit 9d4a8feb2b
17 changed files with 359 additions and 66 deletions

View File

@@ -11,6 +11,8 @@ All notable changes to this project will be documented in this file.
- ActionScript Debugger - Call stack frames switching - view variables around call stack
- ActionScript Debugger - Highlight lines of callstack
- [#2105] GFX - Basic tag info
- Context menu items to create new tags (shape, sprite, image, movie, sound, binaryData) from files
and using font embed dialog for fonts
### Fixed
- [#1306], [#1768] Maximizing window on other than main monitor

View File

@@ -53,8 +53,16 @@ public class ImageImporter extends TagImporter {
return importImage(it, newData, 0);
}
/**
*
* @param it
* @param newData
* @param tagType 0 = can change for defineBits, -1 = detect based on data
* @return
* @throws IOException
*/
public Tag importImage(ImageTag it, byte[] newData, int tagType) throws IOException {
if (newData[0] == 'B' && newData[1] == 'M') {
if (newData.length >= 2 && newData[0] == 'B' && newData[1] == 'M') {
BufferedImage b = ImageHelper.read(newData);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageHelper.write(b, ImageFormat.PNG, baos);
@@ -69,6 +77,18 @@ public class ImageImporter extends TagImporter {
tagType = it.getId();
}
}
if (tagType == -1) {
if (newData.length >= 4
&& newData[0] == (byte) 0xff
&& newData[1] == (byte) 0xd8
&& newData[2] == (byte) 0xff
&& newData[3] == (byte) 0xe0
) {
tagType = DefineBitsJPEG2Tag.ID;
} else {
tagType = DefineBitsLosslessTag.ID;
}
}
if (it.getId() == tagType) {
it.setImage(newData);
@@ -108,6 +128,7 @@ public class ImageImporter extends TagImporter {
imageTag.setModified(true);
it.getTimelined().replaceTag(it, imageTag);
imageTag.setTimelined(it.getTimelined());
swf.updateCharacters();
swf.resetTimelines(swf);
return imageTag;

View File

@@ -261,9 +261,13 @@ public class MovieImporter {
if (timelined != null) {
timelined.resetTimeline();
}
if (timelined == null) {
timelined = movie.getTimelined();
}
int startFrame = 0;
int placeDepth = -1;
int maxPlaceDepth = 0;
if (timelined != null) {
for (Tag t : timelined.getTags()) {
if (t instanceof ShowFrameTag) {
@@ -275,13 +279,47 @@ public class MovieImporter {
placeDepth = pt.getDepth();
break;
}
if (pt.getDepth() > -1) {
if (pt.getDepth() > maxPlaceDepth) {
maxPlaceDepth = pt.getDepth();
}
}
}
}
}
if (placeDepth == -1) {
placeDepth = maxPlaceDepth + 1;
startFrame = 0;
}
int numTimelineFrames = timelined == null ? 0 : timelined.getFrameCount();
int importLastFrame = -1;
if (timelined != null) {
boolean placeWithCharacterIdFound = false;
ReadOnlyTagList tagList1 = timelined.getTags();
for (int p = 0; p < tagList1.size(); p++) {
Tag t = tagList1.get(p);
if (t instanceof PlaceObjectTypeTag) {
PlaceObjectTypeTag place = (PlaceObjectTypeTag) t;
if (place.getCharacterId() == movie.characterID) {
placeWithCharacterIdFound = true;
}
}
if (t instanceof ShowFrameTag) {
if (!placeWithCharacterIdFound) {
PlaceObject2Tag placeObject = new PlaceObject2Tag(swf);
placeObject.setTimelined(timelined);
placeObject.placeFlagHasCharacter = true;
placeObject.characterId = movie.characterID;
placeObject.depth = placeDepth;
placeObject.placeFlagMove = false;
timelined.addTag(p, placeObject);
break;
}
}
}
VideoFrameTag lastVideoFrame = null;
for (FLVTAG ftag : videoTags) {
videoData = ((VIDEODATA) ftag.data);
@@ -322,10 +360,28 @@ public class MovieImporter {
ReadOnlyTagList tagList = timelined.getTags();
int p = 0;
boolean found = false;
boolean placeFound = false;
for (; p < tagList.size(); p++) {
Tag t = tagList.get(p);
if (t instanceof ShowFrameTag) {
if (t instanceof PlaceObjectTypeTag) {
PlaceObjectTypeTag place = (PlaceObjectTypeTag) t;
if (place.getDepth() == placeDepth) {
placeFound = true;
}
}
if (t instanceof ShowFrameTag) {
swfFrameNum++;
if (!placeFound) {
PlaceObject2Tag placeObject = new PlaceObject2Tag(swf);
placeObject.setTimelined(timelined);
placeObject.depth = placeDepth;
placeObject.placeFlagMove = true;
placeObject.placeFlagHasRatio = true;
placeObject.ratio = swfFrameNum - startFrame;
timelined.addTag(p, placeObject);
p++;
}
placeFound = false;
if (swfFrameNum == idealFrame) {
found = true;
break;

View File

@@ -81,13 +81,33 @@ public class FontEmbedDialog extends AppDialog {
private final JCheckBox allCheckbox;
private final JCheckBox importAscentDescentLeadingCheckBox;
private final JTextField fontNameTextField;
public String getCreateFontName() {
return fontNameTextField.getText();
}
public Font getSelectedFont() {
if (ttfFileRadio.isSelected() && customFont != null) {
return customFont;
}
return ((FontFace) faceSelection.getSelectedItem()).font;
}
public boolean isBold() {
if (ttfFileRadio.isSelected() && customFont != null) {
return customFont.isBold();
}
return ((FontFace) faceSelection.getSelectedItem()).isBold();
}
public boolean isItalic() {
if (ttfFileRadio.isSelected() && customFont != null) {
return customFont.isItalic();
}
return ((FontFace) faceSelection.getSelectedItem()).isItalic();
}
public boolean isImportAscentDescentLeading() {
return importAscentDescentLeadingCheckBox.isSelected();
@@ -134,15 +154,27 @@ public class FontEmbedDialog extends AppDialog {
faceSelection.setModel(FontPanel.getFaceModel((FontFamily) familyNamesSelection.getSelectedItem()));
}
public FontEmbedDialog(Window owner, boolean hasLayout, FontFace selectedFace, String selectedChars) {
public FontEmbedDialog(Window owner, boolean hasLayout, FontFace selectedFace, String selectedChars, boolean create) {
super(owner);
setSize(900, 600);
setDefaultCloseOperation(HIDE_ON_CLOSE);
setTitle(translate("dialog.title"));
Container cnt = getContentPane();
cnt.setLayout(new BoxLayout(cnt, BoxLayout.Y_AXIS));
fontNameTextField = new JTextField(30);
fontNameTextField.setText(translate("font.name.default"));
fontNameTextField.selectAll();
if (create) {
JPanel fontNamePanel = new JPanel(new FlowLayout());
fontNamePanel.add(new JLabel(translate("font.name")));
fontNamePanel.add(fontNameTextField);
cnt.add(fontNamePanel);
}
JPanel selFontPanel = new JPanel(new FlowLayout());
installedRadio = new JRadioButton(translate("installed"));
@@ -163,6 +195,7 @@ public class FontEmbedDialog extends AppDialog {
JButton loadFromDiskButton = new JButton(View.getIcon("open16"));
loadFromDiskButton.setToolTipText(translate("button.loadfont"));
loadFromDiskButton.addActionListener(this::loadFromDiscButtonActionPerformed);
selFontPanel.add(new JLabel(translate("font.source")));
selFontPanel.add(installedRadio);
selFontPanel.add(familyNamesSelection);
selFontPanel.add(faceSelection);
@@ -257,9 +290,12 @@ public class FontEmbedDialog extends AppDialog {
importAscentDescentLeadingCheckBox = new JCheckBox(translate("ascentdescentleading"));
importAscentDescentLeadingCheckBox.setAlignmentX(Component.CENTER_ALIGNMENT);
if (hasLayout) {
if (hasLayout && !create) {
cnt.add(importAscentDescentLeadingCheckBox);
}
if (create) {
importAscentDescentLeadingCheckBox.setSelected(true);
}
JPanel buttonsPanel = new JPanel(new FlowLayout());
JButton okButton = new JButton(AppStrings.translate("button.ok"));

View File

@@ -44,6 +44,14 @@ public class FontFace implements Comparable<FontFace> {
return face;
}
public boolean isBold() {
return toString().toLowerCase().contains("bold");
}
public boolean isItalic() {
return toString().toLowerCase().contains("italic");
}
@Override
public int hashCode() {
int hash = 7;

View File

@@ -615,37 +615,51 @@ public class FontPanel extends JPanel implements TagEditorPanel {
}
}
}
public boolean fontEmbed(TreeItem item, boolean create) {
if (item == null) {
return false;
}
FontTag ft = (FontTag) item;
FontEmbedDialog fed = new FontEmbedDialog(Main.getDefaultDialogsOwner(), ft.hasLayout() || ft.getCharacterCount() == 0, (FontFace) fontFaceSelection.getSelectedItem(), fontAddCharactersField.getText(), create);
if (fed.showDialog() == AppDialog.OK_OPTION) {
Set<Integer> selChars = fed.getSelectedChars();
if (!selChars.isEmpty() || fed.isImportAscentDescentLeading()) {
if (ft.getCharacterCount() == 0) {
ft.setHasLayout(true);
}
Font selFont = fed.getSelectedFont();
fontFamilyNameSelection.setSelectedItem(new FontFamily(selFont));
fontFaceSelection.setSelectedItem(new FontFace(selFont));
fontAddChars(ft, selChars, selFont);
if (fed.isImportAscentDescentLeading()) {
Font adlFont = selFont;
if (selFont.getSize() != 1024) {
adlFont = selFont.deriveFont(1024f);
}
ft.setAscent((int) (ft.getDivider() * this.getFontMetrics(adlFont).getAscent()));
ft.setDescent((int) (ft.getDivider() * this.getFontMetrics(adlFont).getDescent()));
int leading = this.getFontMetrics(adlFont).getAscent() + this.getFontMetrics(adlFont).getDescent() - 1024;
ft.setLeading((int) (ft.getDivider() * leading));
}
if (create) {
ft.setFontNameIntag(fed.getCreateFontName());
ft.setBold(fed.isBold());
ft.setItalic(fed.isItalic());
}
fontAddCharactersField.setText("");
ft.setModified(true);
mainPanel.reload(true);
return true;
}
}
return false;
}
private void fontEmbedButtonActionPerformed(ActionEvent evt) {
TreeItem item = mainPanel.getCurrentTree().getCurrentTreeItem();
if (item instanceof FontTag) {
FontTag ft = (FontTag) item;
FontEmbedDialog fed = new FontEmbedDialog(Main.getDefaultDialogsOwner(), ft.hasLayout() || ft.getCharacterCount() == 0, (FontFace) fontFaceSelection.getSelectedItem(), fontAddCharactersField.getText());
if (fed.showDialog() == AppDialog.OK_OPTION) {
Set<Integer> selChars = fed.getSelectedChars();
if (!selChars.isEmpty() || fed.isImportAscentDescentLeading()) {
if (ft.getCharacterCount() == 0) {
ft.setHasLayout(true);
}
Font selFont = fed.getSelectedFont();
fontFamilyNameSelection.setSelectedItem(new FontFamily(selFont));
fontFaceSelection.setSelectedItem(new FontFace(selFont));
fontAddChars(ft, selChars, selFont);
if (fed.isImportAscentDescentLeading()) {
Font adlFont = selFont;
if (selFont.getSize() != 1024) {
adlFont = selFont.deriveFont(1024f);
}
ft.setAscent((int) (ft.getDivider() * this.getFontMetrics(adlFont).getAscent()));
ft.setDescent((int) (ft.getDivider() * this.getFontMetrics(adlFont).getDescent()));
int leading = this.getFontMetrics(adlFont).getAscent() + this.getFontMetrics(adlFont).getDescent() - 1024;
ft.setLeading((int) (ft.getDivider() * leading));
}
fontAddCharactersField.setText("");
ft.setModified(true);
mainPanel.reload(true);
}
}
fontEmbed(item, false);
}
}

View File

@@ -4422,8 +4422,12 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
}
public void replaceButtonActionPerformed(List<TreeItem> items) {
if (items.size() == 0) {
return;
replace(items, false);
}
public boolean replace(List<TreeItem> items, boolean create) {
if (items.isEmpty()) {
return false;
}
TreeItem ti0 = items.get(0);
@@ -4446,12 +4450,16 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
if (ti0 instanceof UnknownTag) {
file = showImportFileChooser("", false);
}
for (TreeItem ti : items) {
doReplaceAction(ti, file);
if (file == null) {
return false;
}
for (TreeItem ti : items) {
doReplaceAction(ti, file, create);
}
return true;
}
private void doReplaceAction(TreeItem item, File selectedFile) {
private void doReplaceAction(TreeItem item, File selectedFile, boolean create) {
if (selectedFile == null) {
return;
}
@@ -4496,7 +4504,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
File selfile = Helper.fixDialogFile(selectedFile);
byte[] data = Helper.readFile(selfile.getAbsolutePath());
try {
Tag newTag = new ImageImporter().importImage(it, data);
Tag newTag = new ImageImporter().importImage(it, data, create ? -1 : 0);
SWF swf = it.getSwf();
if (newTag != null) {
refreshTree(swf);
@@ -4572,9 +4580,9 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
}
}
public void replaceSpriteWithGifButtonActionPerformed(TreeItem item) {
public boolean replaceSpriteWithGif(TreeItem item) {
if (item == null) {
return;
return false;
}
if (item instanceof DefineSpriteTag) {
String filter = "filter.images|*.gif";
@@ -4595,13 +4603,23 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
}
reload(true);
refreshTree(swf);
return true;
}
}
return false;
}
public void replaceSpriteWithGifButtonActionPerformed(TreeItem item) {
replaceSpriteWithGif(item);
}
public void replaceNoFillButtonActionPerformed(TreeItem item) {
replaceNoFill(item);
}
public boolean replaceNoFill(TreeItem item) {
if (item == null) {
return;
return false;
}
if (item instanceof ShapeTag) {
@@ -4633,8 +4651,10 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
ViewMessages.showMessageDialog(this, translate("error.image.invalid"), translate("error"), JOptionPane.ERROR_MESSAGE);
}
reload(true);
return true;
}
}
return false;
}
private void showSvgImportWarning() {
@@ -6250,4 +6270,8 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
}
return dialog;
}
public boolean fontEmbed(TreeItem item, boolean create) {
return previewPanel.getFontPanel().fontEmbed(item, create);
}
}

View File

@@ -317,8 +317,8 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
if (readOnly) {
parametersPanel.setVisible(false);
}
}
}
public PreviewPanel(MainPanel mainPanel, FlashPlayerPanel flashPanel) {
super(JSplitPane.HORIZONTAL_SPLIT, Configuration.guiPreviewSplitPaneDividerLocationPercent);
this.mainPanel = mainPanel;
@@ -351,6 +351,10 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
return ret;
}
public FontPanel getFontPanel() {
return fontPanel;
}
private void createParametersPanel() {
displayWithPreview = new JPanel(new CardLayout());

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@@ -26,3 +26,8 @@ ttffile.selection = TTF file: %fontname% (%filename%)
allcharacters = All characters (%available% characters)
#after 14.0.0
ascentdescentleading = Set ascent, descent and leading
#after 19.1.2
font.name = Font name:
font.name.default = My font
font.source = Source:

View File

@@ -25,3 +25,8 @@ ttffile.noselection = TTF soubor: <vyberte>
ttffile.selection = TTF soubor: %fontname% (%filename%)
allcharacters = V\u0161echny znaky (%available% znak\u016f)
ascentdescentleading = Nastavit ascent, descent a leading
#after 19.1.2
font.name = N\u00e1zev fontu:
font.name.default = Muj font
font.source = Zdroj:

View File

@@ -1195,4 +1195,12 @@ tagInfo.textureFormat = Texture format
tagInfo.padPixels = Pad pixels
tagInfo.nominalGlyphSz = Nominal glyph size
tagInfo.glyphCount = Glyph count
tagInfo.fontCount = Font count
tagInfo.fontCount = Font count
tag.shape.create = create shape from file...
tag.image.create = create image from file...
tag.sprite.create = create sprite from GIF file...
tag.movie.create = create movie from file...
tag.sound.create = create sound from file...
tag.font.create = create font using dialog...
tag.binaryData.create = create binary data from file...

View File

@@ -1172,4 +1172,12 @@ tagInfo.textureFormat = Form\u00e1t textury
tagInfo.padPixels = Zarovn\u00e1n\u00ed pixel\u016f
tagInfo.nominalGlyphSz = Nomin\u00e1ln\u00ed velikost glyfu
tagInfo.glyphCount = Po\u010det glyf\u016f
tagInfo.fontCount = Po\u010det p\u00edsem
tagInfo.fontCount = Po\u010det p\u00edsem
tag.shape.create = vytvo\u0159it tvar ze souboru...
tag.image.create = vytvo\u0159it obr\u00e1zek ze souboru...
tag.sprite.create = vytvo\u0159it sprite z GIF souboru...
tag.movie.create = vytvo\u0159it video ze souboru...
tag.sound.create = vytvo\u0159it zvuk ze souboru...
tag.font.create = vytvo\u0159it p\u00edsmo pomoc\u00ed dialogu...
tag.binaryData.create = vytvo\u0159it bin\u00e1rn\u00ed data ze souboru...

View File

@@ -47,7 +47,11 @@ import com.jpexs.decompiler.flash.gui.action.AddScriptDialog;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
import com.jpexs.decompiler.flash.tags.DefineBitsLossless2Tag;
import com.jpexs.decompiler.flash.tags.DefineButton2Tag;
import com.jpexs.decompiler.flash.tags.DefineFont3Tag;
import com.jpexs.decompiler.flash.tags.DefineShape4Tag;
import com.jpexs.decompiler.flash.tags.DefineSoundTag;
import com.jpexs.decompiler.flash.tags.DefineSpriteTag;
import com.jpexs.decompiler.flash.tags.DefineVideoStreamTag;
import com.jpexs.decompiler.flash.tags.DoABC2Tag;
@@ -1396,8 +1400,7 @@ public class TagTreeContextMenu extends JPopupMenu {
}
private interface AddTagActionListener {
void call(ActionEvent evt, TreeItem item, Class<?> cl);
void call(ActionEvent evt, TreeItem item, Class<?> cl, TreeNodeType createNodeType);
}
private void addAddTagMenuFolder(JMenu addTagMenu, String folder, boolean gfx, TreeItem item, AddTagActionListener listener) {
@@ -1415,11 +1418,11 @@ public class TagTreeContextMenu extends JPopupMenu {
if (allowedTagTypes.isEmpty() && mappedTagTypes.isEmpty()) {
return;
}
addAddTagMenuItems(allowedTagTypes, folderMenu, item, listener);
addAddTagMenuItems(allowedTagTypes, folderMenu, item, listener, folder);
if (!allowedTagTypes.isEmpty() && !mappedTagTypes.isEmpty()) {
folderMenu.addSeparator();
}
addAddTagMenuItems(new ArrayList<Integer>(mappedTagTypes), folderMenu, item, listener);
addAddTagMenuItems(new ArrayList<Integer>(mappedTagTypes), folderMenu, item, listener, null);
addTagMenu.add(folderMenu);
}
@@ -1427,7 +1430,7 @@ public class TagTreeContextMenu extends JPopupMenu {
private void addAttachTagMenuItems(TreeItem item) {
AddTagActionListener listener = this::attachTagActionPerformed;
List<Integer> mapped = AbstractTagTree.getMappedTagIdsForClass(item.getClass());
addAddTagMenuItems(mapped, attachTagMenu, item, listener);
addAddTagMenuItems(mapped, attachTagMenu, item, listener, null);
}
private void addAddTagInsideMenuItems(TreeItem item) {
@@ -1440,12 +1443,12 @@ public class TagTreeContextMenu extends JPopupMenu {
boolean gfx = currentSwf.gfx;
if (item instanceof SWF) {
addAddTagMenuItems(null, addTagInsideMenu, item, listener);
addAddTagMenuItems(null, addTagInsideMenu, item, listener, null);
return;
}
if (item instanceof DefineSpriteTag) {
addAddTagMenuItems(AbstractTagTree.getFrameNestedTagIds(), addTagInsideMenu, item, listener);
addAddTagMenuItems(AbstractTagTree.getFrameNestedTagIds(), addTagInsideMenu, item, listener, TagTreeModel.FOLDER_FRAMES);
addTagInsideMenu.addSeparator();
addTagInsideMenu.add(createOthersMenu(item, listener));
return;
@@ -1455,10 +1458,10 @@ public class TagTreeContextMenu extends JPopupMenu {
Frame frame = (Frame) item;
boolean insideSprite = frame.timeline.timelined instanceof DefineSpriteTag;
if (mainPanel.getCurrentView() == MainPanel.VIEW_TAGLIST) {
addAddTagMenuItems(null, addTagInsideMenu, item, listener);
addAddTagMenuItems(null, addTagInsideMenu, item, listener, TagTreeModel.FOLDER_FRAMES);
return;
} else {
addAddTagMenuItems(AbstractTagTree.getFrameNestedTagIds(), addTagInsideMenu, item, listener);
addAddTagMenuItems(AbstractTagTree.getFrameNestedTagIds(), addTagInsideMenu, item, listener, TagTreeModel.FOLDER_FRAMES);
addTagInsideMenu.addSeparator();
addTagInsideMenu.add(createOthersMenu(item, listener));
}
@@ -1467,7 +1470,7 @@ public class TagTreeContextMenu extends JPopupMenu {
if (item instanceof FolderItem) {
List<Integer> allowedTagTypes = new ArrayList<>(TagTree.getSwfFolderItemNestedTagIds(((FolderItem) item).getName(), gfx));
addAddTagMenuItems(allowedTagTypes, addTagInsideMenu, item, listener);
addAddTagMenuItems(allowedTagTypes, addTagInsideMenu, item, listener, ((FolderItem) item).getName());
return;
}
@@ -1513,11 +1516,11 @@ public class TagTreeContextMenu extends JPopupMenu {
if (insideFrame) {
if (mainPanel.getCurrentView() == MainPanel.VIEW_TAGLIST && !insideSprite) {
addAddTagMenuItems(null, addTagMenu, item, listener);
addAddTagMenuItems(null, addTagMenu, item, listener, TagTreeModel.FOLDER_FRAMES);
return;
}
addAddTagMenuItems(AbstractTagTree.getFrameNestedTagIds(), addTagMenu, item, listener);
addAddTagMenuItems(AbstractTagTree.getFrameNestedTagIds(), addTagMenu, item, listener, TagTreeModel.FOLDER_FRAMES);
addTagMenu.addSeparator();
addTagMenu.add(createOthersMenu(item, listener));
@@ -1527,25 +1530,25 @@ public class TagTreeContextMenu extends JPopupMenu {
if (parent instanceof FolderItem) {
List<Integer> allowedTagTypes = new ArrayList<>(TagTree.getSwfFolderItemNestedTagIds(((FolderItem) parent).getName(), gfx));
addAddTagMenuItems(allowedTagTypes, addTagMenu, item, listener);
addAddTagMenuItems(allowedTagTypes, addTagMenu, item, listener, ((FolderItem) parent).getName());
addTagMenu.addSeparator();
addTagMenu.add(createOthersMenu(item, listener));
return;
}
if ((item instanceof HeaderItem) && !before) {
addAddTagMenuItems(null, addTagMenu, item, listener);
addAddTagMenuItems(null, addTagMenu, item, listener, null);
}
}
private JMenu createOthersMenu(TreeItem item, AddTagActionListener listener) {
JMenu othersMenu = new JMenu(AppStrings.translate("node.others"));
othersMenu.setIcon(View.getIcon("folder16"));
addAddTagMenuItems(null, othersMenu, item, listener);
addAddTagMenuItems(null, othersMenu, item, listener, TagTreeModel.FOLDER_OTHERS);
return othersMenu;
}
private void addAddTagMenuItems(List<Integer> allowedTagTypes, JMenu addTagMenu, TreeItem item, AddTagActionListener listener) {
private void addAddTagMenuItems(List<Integer> allowedTagTypes, JMenu addTagMenu, TreeItem item, AddTagActionListener listener, String parentFolder) {
if (allowedTagTypes == null) {
boolean gfx = mainPanel.getCurrentSwf().gfx;
@@ -1580,13 +1583,82 @@ public class TagTreeContextMenu extends JPopupMenu {
TreeNodeType type = AbstractTagTree.getTagNodeTypeFromTagClass(cl);
tagItem.setIcon(TagTree.getIconForType(type));
tagItem.addActionListener((ActionEvent ae) -> {
listener.call(ae, item, cl);
listener.call(ae, item, cl, null);
});
addTagMenu.add(tagItem);
}
if (parentFolder == null) {
return;
}
switch (parentFolder) {
case TagTreeModel.FOLDER_SHAPES:
addTagMenu.addSeparator();
JMenuItem createShapeItem = new JMenuItem(AppStrings.translate("tag.shape.create"));
createShapeItem.setIcon(View.getIcon("importshape16"));
createShapeItem.addActionListener((ActionEvent ae) -> {
listener.call(ae, item, DefineShape4Tag.class, TreeNodeType.SHAPE);
});
addTagMenu.add(createShapeItem);
break;
case TagTreeModel.FOLDER_IMAGES:
addTagMenu.addSeparator();
JMenuItem createImageItem = new JMenuItem(AppStrings.translate("tag.image.create"));
createImageItem.setIcon(View.getIcon("importimage16"));
createImageItem.addActionListener((ActionEvent ae) -> {
listener.call(ae, item, DefineBitsLossless2Tag.class, TreeNodeType.IMAGE);
});
addTagMenu.add(createImageItem);
break;
case TagTreeModel.FOLDER_SPRITES:
addTagMenu.addSeparator();
JMenuItem createSpriteItem = new JMenuItem(AppStrings.translate("tag.sprite.create"));
createSpriteItem.setIcon(View.getIcon("importsprite16"));
createSpriteItem.addActionListener((ActionEvent ae) -> {
listener.call(ae, item, DefineSpriteTag.class, TreeNodeType.SPRITE);
});
addTagMenu.add(createSpriteItem);
break;
case TagTreeModel.FOLDER_MOVIES:
addTagMenu.addSeparator();
JMenuItem createMovieItem = new JMenuItem(AppStrings.translate("tag.movie.create"));
createMovieItem.setIcon(View.getIcon("importmovie16"));
createMovieItem.addActionListener((ActionEvent ae) -> {
listener.call(ae, item, DefineVideoStreamTag.class, TreeNodeType.MOVIE);
});
addTagMenu.add(createMovieItem);
break;
case TagTreeModel.FOLDER_SOUNDS:
addTagMenu.addSeparator();
JMenuItem createSoundItem = new JMenuItem(AppStrings.translate("tag.sound.create"));
createSoundItem.setIcon(View.getIcon("importsound16"));
createSoundItem.addActionListener((ActionEvent ae) -> {
listener.call(ae, item, DefineSoundTag.class, TreeNodeType.SOUND);
});
addTagMenu.add(createSoundItem);
break;
case TagTreeModel.FOLDER_FONTS:
addTagMenu.addSeparator();
JMenuItem createFontItem = new JMenuItem(AppStrings.translate("tag.font.create"));
createFontItem.setIcon(View.getIcon("importfont16"));
createFontItem.addActionListener((ActionEvent ae) -> {
listener.call(ae, item, DefineFont3Tag.class, TreeNodeType.FONT);
});
addTagMenu.add(createFontItem);
break;
case TagTreeModel.FOLDER_BINARY_DATA:
addTagMenu.addSeparator();
JMenuItem createBinaryDataItem = new JMenuItem(AppStrings.translate("tag.binaryData.create"));
createBinaryDataItem.setIcon(View.getIcon("importbinarydata16"));
createBinaryDataItem.addActionListener((ActionEvent ae) -> {
listener.call(ae, item, DefineBinaryDataTag.class, TreeNodeType.BINARY_DATA);
});
addTagMenu.add(createBinaryDataItem);
break;
}
}
private void addTagInsideActionPerformed(ActionEvent evt, TreeItem item, Class<?> cl) {
private void addTagInsideActionPerformed(ActionEvent evt, TreeItem item, Class<?> cl, TreeNodeType createNodeType) {
int id = -1;
try {
id = cl.getDeclaredField("ID").getInt(null);
@@ -1629,13 +1701,14 @@ public class TagTreeContextMenu extends JPopupMenu {
swf.updateCharacters();
mainPanel.refreshTree(swf);
mainPanel.setTagTreeSelectedNode(mainPanel.getCurrentTree(), t);
handleCreateFromFile(t, createNodeType);
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException ex) {
logger.log(Level.SEVERE, null, ex);
}
}
}
private void addTagBeforeActionPerformed(ActionEvent evt, TreeItem item, Class<?> cl) {
private void addTagBeforeActionPerformed(ActionEvent evt, TreeItem item, Class<?> cl, TreeNodeType createNodeType) {
try {
SWF swf = (SWF) item.getOpenable();
Tag t = (Tag) cl.getDeclaredConstructor(SWF.class).newInstance(new Object[]{swf});
@@ -1669,12 +1742,13 @@ public class TagTreeContextMenu extends JPopupMenu {
swf.updateCharacters();
mainPanel.refreshTree(swf);
mainPanel.setTagTreeSelectedNode(mainPanel.getCurrentTree(), t);
handleCreateFromFile(t, createNodeType);
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException ex) {
logger.log(Level.SEVERE, null, ex);
}
}
private void addTagAfterActionPerformed(ActionEvent evt, TreeItem item, Class<?> cl) {
private void addTagAfterActionPerformed(ActionEvent evt, TreeItem item, Class<?> cl, TreeNodeType createNodeType) {
try {
SWF swf = (SWF) item.getOpenable();
Tag t = (Tag) cl.getDeclaredConstructor(SWF.class).newInstance(new Object[]{swf});
@@ -1711,6 +1785,7 @@ public class TagTreeContextMenu extends JPopupMenu {
swf.updateCharacters();
mainPanel.refreshTree(swf);
mainPanel.setTagTreeSelectedNode(mainPanel.getCurrentTree(), t);
handleCreateFromFile(t, createNodeType);
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException ex) {
logger.log(Level.SEVERE, null, ex);
}
@@ -3277,7 +3352,7 @@ public class TagTreeContextMenu extends JPopupMenu {
}
}
private void attachTagActionPerformed(ActionEvent evt, TreeItem item, Class<?> cl) {
private void attachTagActionPerformed(ActionEvent evt, TreeItem item, Class<?> cl, TreeNodeType createNodeType) {
int id = -1;
try {
id = cl.getDeclaredField("ID").getInt(null);
@@ -3726,4 +3801,31 @@ public class TagTreeContextMenu extends JPopupMenu {
}
}
}
private void handleCreateFromFile(Tag tag, TreeNodeType createNodeType) {
if (createNodeType == null) {
return;
}
boolean remove;
switch (createNodeType) {
case SPRITE:
remove = !mainPanel.replaceSpriteWithGif(tag);
break;
case SHAPE:
remove = !mainPanel.replaceNoFill(tag);
break;
case FONT:
remove = !mainPanel.fontEmbed(tag, true);
break;
default:
List<TreeItem> sel = new ArrayList<>();
sel.add(tag);
remove = !mainPanel.replace(sel, true);
break;
}
if (remove) {
tag.getTimelined().removeTag(tag);
mainPanel.refreshTree();
}
}
}