From 282320f0615d04207a972d5f39fe38e8e73c4fc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Mon, 5 May 2025 22:40:48 +0200 Subject: [PATCH] Added: #2370 Show/Hide guides, lock guides, clear guides actions from icon menu --- CHANGELOG.md | 1 + .../flash/configuration/Configuration.java | 8 ++ .../decompiler/flash/gui/ImagePanel.java | 81 +++++++++++-------- .../decompiler/flash/gui/SoundTagPlayer.java | 5 ++ .../locales/AdvancedSettingsDialog.properties | 6 ++ .../flash/gui/locales/MainFrame.properties | 5 ++ .../flash/gui/player/FlashPlayerPanel.java | 5 ++ .../flash/gui/player/MediaDisplay.java | 2 + .../flash/gui/player/ZoomPanel.java | 58 +++++++++++-- 9 files changed, 131 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f188ad995..3cab0103f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ All notable changes to this project will be documented in this file. - [#2370] Objects display - Create guides by dragging from a ruler - Objects dragging - show touch point and snap it to 9 important points around object rectangle - [#2370] Snap to guides, objects and pixels, Snap align, toggle with magnet icon +- [#2370] Show/Hide guides, lock guides, clear guides actions from icon menu ### Fixed - [#2424] DefineEditText handling of letterSpacing, font size on incorrect values diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java index 0b46afce0..8be0600b9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java @@ -1073,6 +1073,14 @@ public final class Configuration { @ConfigurationCategory("display") public static ConfigurationItem snapAlign = null; + @ConfigurationDefaultBoolean(true) + @ConfigurationCategory("display") + public static ConfigurationItem showGuides = null; + + @ConfigurationDefaultBoolean(false) + @ConfigurationCategory("display") + public static ConfigurationItem lockGuides = null; + private enum OSId { WINDOWS, OSX, UNIX } diff --git a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java index 9f75430da..5222943ce 100644 --- a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java +++ b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java @@ -402,8 +402,8 @@ public final class ImagePanel extends JPanel implements MediaDisplay { @Override public boolean canHaveRuler() { return this.contentCanHaveRuler; - } - + } + @Override public boolean canUseSnapping() { return selectionMode || doFreeTransform || hilightedPoints != null; @@ -1432,28 +1432,30 @@ public final class ImagePanel extends JPanel implements MediaDisplay { mouseMoved(e); //to correctly calculate mode, because mouseMoved event is not called during dragging - Point mousePoint = e.getPoint(); - for (int d = 0; d < guidesX.size(); d++) { - Double guide = guidesX.get(d); - int guideInPanel = (int) Math.round(guide * getRealZoom() + offsetPoint.getX()); - if (mousePoint.x >= guideInPanel - GUIDE_MOVE_TOLERANCE && mousePoint.x <= guideInPanel + GUIDE_MOVE_TOLERANCE) { - guidesX.remove(d); - guideDragX = guideInPanel; - draggingGuideX = true; - saveGuides(); - return; + if (Configuration.showGuides.get() && !Configuration.lockGuides.get()) { + Point mousePoint = e.getPoint(); + for (int d = 0; d < guidesX.size(); d++) { + Double guide = guidesX.get(d); + int guideInPanel = (int) Math.round(guide * getRealZoom() + offsetPoint.getX()); + if (mousePoint.x >= guideInPanel - GUIDE_MOVE_TOLERANCE && mousePoint.x <= guideInPanel + GUIDE_MOVE_TOLERANCE) { + guidesX.remove(d); + guideDragX = guideInPanel; + draggingGuideX = true; + saveGuides(); + return; + } } - } - for (int d = 0; d < guidesY.size(); d++) { - Double guide = guidesY.get(d); - int guideInPanel = (int) Math.round(guide * getRealZoom() + offsetPoint.getY()); - if (mousePoint.y >= guideInPanel - GUIDE_MOVE_TOLERANCE && mousePoint.y <= guideInPanel + GUIDE_MOVE_TOLERANCE) { - guidesY.remove(d); - guideDragY = guideInPanel; - draggingGuideY = true; - saveGuides(); - return; + for (int d = 0; d < guidesY.size(); d++) { + Double guide = guidesY.get(d); + int guideInPanel = (int) Math.round(guide * getRealZoom() + offsetPoint.getY()); + if (mousePoint.y >= guideInPanel - GUIDE_MOVE_TOLERANCE && mousePoint.y <= guideInPanel + GUIDE_MOVE_TOLERANCE) { + guidesY.remove(d); + guideDragY = guideInPanel; + draggingGuideY = true; + saveGuides(); + return; + } } } @@ -1788,7 +1790,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay { double zoomDouble = getRealZoom(); - if (Configuration.snapAlign.get() && timelined != null && points == null) { + if (Configuration.snapAlign.get() && timelined != null && points == null && transform != null) { Frame fr = timelined.getTimeline().getFrame(frame); if (fr != null) { Timeline timeline = timelined.getTimeline(); @@ -2848,7 +2850,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay { boolean nearGuideX = draggingGuideX; boolean nearGuideY = draggingGuideY; - if (!draggingGuideX && !draggingGuideY) { + if (!draggingGuideX && !draggingGuideY && Configuration.showGuides.get() && !Configuration.lockGuides.get()) { Point mousePoint = e.getPoint(); for (int d = 0; d < guidesX.size(); d++) { Double guide = guidesX.get(d); @@ -3166,14 +3168,20 @@ public final class ImagePanel extends JPanel implements MediaDisplay { g2d.drawLine(0, guideDragY, getWidth(), guideDragY); } - for (Double guide : guidesX) { - int guideRealPx = (int) Math.round(offsetPoint.getX() + guide * getRealZoom()); - g2d.drawLine(guideRealPx, 0, guideRealPx, getHeight()); + if (!Configuration.showGuides.get() && (draggingGuideX || draggingGuideY) && (guideDragX > 0 || guideDragY > 0)) { + Configuration.showGuides.set(true); } - for (Double guide : guidesY) { - int guideRealPx = (int) Math.round(offsetPoint.getY() + guide * getRealZoom()); - g2d.drawLine(0, guideRealPx, getWidth(), guideRealPx); + if (Configuration.showGuides.get()) { + for (Double guide : guidesX) { + int guideRealPx = (int) Math.round(offsetPoint.getX() + guide * getRealZoom()); + g2d.drawLine(guideRealPx, 0, guideRealPx, getHeight()); + } + + for (Double guide : guidesY) { + int guideRealPx = (int) Math.round(offsetPoint.getY() + guide * getRealZoom()); + g2d.drawLine(0, guideRealPx, getWidth(), guideRealPx); + } } if (Configuration._debugMode.get()) { @@ -4226,7 +4234,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay { this.registrationPointPosition = RegistrationPointPosition.CENTER; iconPanel.calcRect(); - clearGuides(); + clearGuidesInternal(); setNoGuidesCharacter(); contentCanHaveRuler = canHaveRuler; @@ -4254,7 +4262,14 @@ public final class ImagePanel extends JPanel implements MediaDisplay { fireMediaDisplayStateChanged(); } + @Override public synchronized void clearGuides() { + clearGuidesInternal(); + saveGuides(); + repaint(); + } + + private synchronized void clearGuidesInternal() { draggingGuideX = false; draggingGuideY = false; guideDragX = -1; @@ -4285,7 +4300,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay { } private synchronized void loadGuidesCharacter() { - clearGuides(); + clearGuidesInternal(); if (guidesSwf == null) { return; } @@ -4402,7 +4417,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay { horizontalScrollBar.setVisible(false); verticalScrollBar.setVisible(false); - clearGuides(); + clearGuidesInternal(); setNoGuidesCharacter(); contentCanHaveRuler = false; diff --git a/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java b/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java index 263f537be..3ca676d82 100644 --- a/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java +++ b/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java @@ -583,4 +583,9 @@ public class SoundTagPlayer implements MediaDisplay { public boolean isMutable() { return true; } + + @Override + public void clearGuides() { + + } } diff --git a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties index 5bce7a3a1..3f0880a46 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties @@ -571,3 +571,9 @@ config.description.snapToGuides = Enables snapping cursor to whole pixels while config.name.snapAlign = Snap align config.description.snapAlign = Enables snapping cursor align lines while moving objects. + +config.name.showGuides = Show guides +config.description.showGuides = Set this to false to hide guides. + +config.name.lockGuides = Lock guides +config.description.lockGuides = Disables moving of guides so they stay in position and cannot be moved. diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties index 06aeedb73..283e83843 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties @@ -1030,3 +1030,8 @@ snap_options.snap_to_pixels = Snap to Pixels snap_options.snap_to_objects = Snap to Objects button.ruler.hint = Toggle ruler display + +button.guides_options.hint = Guides options +guides_options.show = Show guides +guides_options.lock = Lock guides +guides_options.clear = Clear guides \ No newline at end of file diff --git a/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java b/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java index 13976720c..7d1981099 100644 --- a/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java @@ -71,6 +71,11 @@ public final class FlashPlayerPanel extends Panel implements Closeable, MediaDis private Color bgColor; + @Override + public void clearGuides() { + + } + @Override public boolean canHaveRuler() { return false; diff --git a/src/com/jpexs/decompiler/flash/gui/player/MediaDisplay.java b/src/com/jpexs/decompiler/flash/gui/player/MediaDisplay.java index 8191ba9be..10ef659e8 100644 --- a/src/com/jpexs/decompiler/flash/gui/player/MediaDisplay.java +++ b/src/com/jpexs/decompiler/flash/gui/player/MediaDisplay.java @@ -86,4 +86,6 @@ public interface MediaDisplay extends Closeable { public boolean canUseSnapping(); public boolean canHaveRuler(); + + public void clearGuides(); } diff --git a/src/com/jpexs/decompiler/flash/gui/player/ZoomPanel.java b/src/com/jpexs/decompiler/flash/gui/player/ZoomPanel.java index c4532a7dc..b15990bb3 100644 --- a/src/com/jpexs/decompiler/flash/gui/player/ZoomPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/player/ZoomPanel.java @@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.gui.player; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.configuration.ConfigurationItemChangeListener; import com.jpexs.decompiler.flash.gui.AppStrings; +import com.jpexs.decompiler.flash.gui.PopupButton; import com.jpexs.decompiler.flash.gui.View; import com.jpexs.decompiler.flash.gui.abc.SnapOptionsButton; import java.awt.FlowLayout; @@ -27,8 +28,11 @@ import java.math.BigDecimal; import java.math.RoundingMode; import java.util.Objects; import javax.swing.JButton; +import javax.swing.JCheckBoxMenuItem; import javax.swing.JLabel; +import javax.swing.JMenuItem; import javax.swing.JPanel; +import javax.swing.JPopupMenu; import javax.swing.JToggleButton; /** @@ -38,8 +42,9 @@ import javax.swing.JToggleButton; public class ZoomPanel extends JPanel implements MediaDisplayListener { private MediaDisplay display; - private JButton zoomFitButton; - private SnapOptionsButton snapOptionsButton; + private final JButton zoomFitButton; + private final SnapOptionsButton snapOptionsButton; + private PopupButton guidesOptionsButton; private JToggleButton rulerButton; private final JLabel percentLabel = new JLabel("100%"); private boolean zoomToFit = false; @@ -63,19 +68,42 @@ public class ZoomPanel extends JPanel implements MediaDisplayListener { JButton zoomNoneButton = new JButton(View.getIcon("zoomnone16")); zoomNoneButton.addActionListener(this::zoomNoneButtonActionPerformed); zoomNoneButton.setToolTipText(AppStrings.translate("button.zoomnone.hint")); - + rulerButton = new JToggleButton(View.getIcon("ruler16")); rulerButton.addActionListener(this::rulerActionPerformed); rulerButton.setToolTipText(AppStrings.translate("button.ruler.hint")); rulerButton.setSelected(Configuration.showRuler.get()); - + Configuration.showRuler.addListener(new ConfigurationItemChangeListener() { @Override public void configurationItemChanged(Boolean newValue) { rulerButton.setSelected(newValue); - } + } }); - + + guidesOptionsButton = new PopupButton(View.getIcon("guides16")) { + @Override + protected JPopupMenu getPopupMenu() { + JPopupMenu menu = new JPopupMenu(); + JCheckBoxMenuItem showGuidesMenuItem = new JCheckBoxMenuItem(AppStrings.translate("guides_options.show")); + showGuidesMenuItem.setSelected(Configuration.showGuides.get()); + showGuidesMenuItem.addActionListener(ZoomPanel.this::guidesShowActionPerformed); + JCheckBoxMenuItem lockGuidesMenuItem = new JCheckBoxMenuItem(AppStrings.translate("guides_options.lock")); + lockGuidesMenuItem.setSelected(Configuration.lockGuides.get()); + lockGuidesMenuItem.addActionListener(ZoomPanel.this::guidesLockActionPerformed); + JMenuItem clearGuidesMenuItem = new JMenuItem(AppStrings.translate("guides_options.clear")); + clearGuidesMenuItem.addActionListener(ZoomPanel.this::guidesClearActionPerformed); + + menu.add(showGuidesMenuItem); + menu.add(lockGuidesMenuItem); + menu.add(clearGuidesMenuItem); + + return menu; + } + }; + + guidesOptionsButton.setToolTipText(AppStrings.translate("button.guides_options.hint")); + snapOptionsButton = new SnapOptionsButton(); setLayout(new FlowLayout()); @@ -85,16 +113,31 @@ public class ZoomPanel extends JPanel implements MediaDisplayListener { add(zoomNoneButton); add(zoomFitButton); add(rulerButton); + add(guidesOptionsButton); add(snapOptionsButton); display.addEventListener(this); } + private void guidesShowActionPerformed(ActionEvent evt) { + JCheckBoxMenuItem source = (JCheckBoxMenuItem) evt.getSource(); + Configuration.showGuides.set(source.isSelected()); + } + + private void guidesLockActionPerformed(ActionEvent evt) { + JCheckBoxMenuItem source = (JCheckBoxMenuItem) evt.getSource(); + Configuration.lockGuides.set(source.isSelected()); + } + + private void guidesClearActionPerformed(ActionEvent evt) { + display.clearGuides(); + } + private void rulerActionPerformed(ActionEvent evt) { JToggleButton toggleButton = (JToggleButton) evt.getSource(); Configuration.showRuler.set(toggleButton.isSelected()); } - + private void zoomInButtonActionPerformed(ActionEvent evt) { double currentRealZoom = getRealZoom(); if (currentRealZoom >= MAX_ZOOM) { @@ -178,6 +221,7 @@ public class ZoomPanel extends JPanel implements MediaDisplayListener { percentLabel.setVisible(zoom != null); snapOptionsButton.setVisible(display.canUseSnapping()); rulerButton.setVisible(display.canHaveRuler()); + guidesOptionsButton.setVisible(display.canHaveRuler()); Zoom currentZoom = new Zoom(); currentZoom.fit = zoomToFit; currentZoom.value = realZoom;