Zoom controls for easy gui.

This commit is contained in:
Jindra Petřík
2024-10-29 16:55:43 +01:00
parent fa87f31c71
commit e531f8411d
4 changed files with 228 additions and 121 deletions
@@ -28,6 +28,7 @@ import com.jpexs.decompiler.flash.gui.TimelinedMaker;
import com.jpexs.decompiler.flash.gui.TransformPanel;
import com.jpexs.decompiler.flash.gui.View;
import com.jpexs.decompiler.flash.gui.controls.JPersistentSplitPane;
import com.jpexs.decompiler.flash.gui.player.ZoomPanel;
import com.jpexs.decompiler.flash.tags.DefineSpriteTag;
import com.jpexs.decompiler.flash.tags.PlaceObject2Tag;
import com.jpexs.decompiler.flash.tags.RemoveObject2Tag;
@@ -291,7 +292,7 @@ public class EasySwfPanel extends JPanel {
JPanel topPanel = new JPanel(new BorderLayout());
JPanel toolbarPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
undoButton = new JButton(View.getIcon("rotateanticlockwise16"));
//undoButton.setToolTipText("Undo");
@@ -342,9 +343,17 @@ public class EasySwfPanel extends JPanel {
undoManager.addChangeListener(undoChangeListener);
toolbarPanel.add(undoButton);
toolbarPanel.add(redoButton);
JPanel toolbarPanel = new JPanel(new BorderLayout());
JPanel leftToolbar = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
leftToolbar.add(undoButton);
leftToolbar.add(redoButton);
toolbarPanel.add(leftToolbar, BorderLayout.WEST);
ZoomPanel zoomPanel = new ZoomPanel(stagePanel);
toolbarPanel.add(zoomPanel, BorderLayout.EAST);
topPanel.add(toolbarPanel, BorderLayout.NORTH);
topPanel.add(stagePanel, BorderLayout.CENTER);
@@ -96,9 +96,9 @@ public class PlayerControls extends JPanel implements MediaDisplayListener {
private static final Icon resampleIcon = View.getIcon("resample16");
private final JLabel percentLabel = new JLabel("100%");
//private final JLabel percentLabel = new JLabel("100%");
private final JPanel zoomPanel;
private final ZoomPanel zoomPanel;
private final JPanel graphicControls;
@@ -106,11 +106,11 @@ public class PlayerControls extends JPanel implements MediaDisplayListener {
private final JPanel frameControls;
private boolean zoomToFit = false;
// private boolean zoomToFit = false;
private double realZoom = 1.0;
// private double realZoom = 1.0;
private final JButton zoomFitButton;
//private final JButton zoomFitButton;
private final JButton snapshotButton;
@@ -134,10 +134,10 @@ public class PlayerControls extends JPanel implements MediaDisplayListener {
private static Font notUnderlinedFont = null;
private final int zeroCharacterWidth;
private final double MAX_ZOOM = 1.0e6; //in larger zooms, flash viewer stops working
private final int zeroCharacterWidth;
private JButton selectColorButton;
static {
Font font = new JLabel().getFont();
notUnderlinedFont = font;
@@ -160,41 +160,22 @@ public class PlayerControls extends JPanel implements MediaDisplayListener {
graphicControls = new JPanel(new BorderLayout());
JPanel graphicButtonsPanel = new JPanel(new FlowLayout());
JButton selectColorButton = new JButton(View.getIcon("color16"));
selectColorButton = new JButton(View.getIcon("color16"));
selectColorButton.addActionListener(this::selectBkColorButtonActionPerformed);
selectColorButton.setToolTipText(AppStrings.translate("button.selectbkcolor.hint"));
JButton zoomInButton = new JButton(View.getIcon("zoomin16"));
zoomInButton.addActionListener(this::zoomInButtonActionPerformed);
zoomInButton.setToolTipText(AppStrings.translate("button.zoomin.hint"));
JButton zoomOutButton = new JButton(View.getIcon("zoomout16"));
zoomOutButton.addActionListener(this::zoomOutButtonActionPerformed);
zoomOutButton.setToolTipText(AppStrings.translate("button.zoomout.hint"));
zoomFitButton = new JButton(View.getIcon("zoomfit16"));
zoomFitButton.addActionListener(this::zoomFitButtonActionPerformed);
zoomFitButton.setToolTipText(AppStrings.translate("button.zoomfit.hint"));
JButton zoomNoneButton = new JButton(View.getIcon("zoomnone16"));
zoomNoneButton.addActionListener(this::zoomNoneButtonActionPerformed);
zoomNoneButton.setToolTipText(AppStrings.translate("button.zoomnone.hint"));
zoomPanel = new ZoomPanel(display);
zoomPanel.setVisible(false);
snapshotButton = new JButton(View.getIcon("snapshot16"));
snapshotButton.addActionListener(this::snapShotButtonActionPerformed);
snapshotButton.setToolTipText(AppStrings.translate("button.snapshot.hint"));
snapshotButton.setVisible(false);
zoomPanel = new JPanel(new FlowLayout());
zoomPanel.add(percentLabel);
zoomPanel.add(zoomInButton);
zoomPanel.add(zoomOutButton);
zoomPanel.add(zoomNoneButton);
zoomPanel.add(zoomFitButton);
zoomPanel.add(selectColorButton);
zoomPanel.setVisible(false);
graphicButtonsPanel.add(zoomPanel);
graphicButtonsPanel.add(selectColorButton);
graphicButtonsPanel.add(snapshotButton);
JPanel displayButtonsPanel = new JPanel(new FlowLayout());
@@ -403,21 +384,12 @@ public class PlayerControls extends JPanel implements MediaDisplayListener {
currentFrame = totalFrames;
}
float frameRate = display.getFrameRate();
Zoom zoom = display.getZoom();
zoomFitButton.setVisible(zoom != null);
percentLabel.setVisible(zoom != null);
Zoom currentZoom = new Zoom();
currentZoom.fit = zoomToFit;
currentZoom.value = realZoom;
if (zoom != null && !Objects.equals(zoom, currentZoom)) {
zoomToFit = zoom.fit;
realZoom = zoom.value;
updateZoomDisplay();
}
zoomPanel.update();
zoomPanel.setVisible(display.zoomAvailable());
boolean screenAvailable = display.screenAvailable();
showButton.setVisible(!display.alwaysDisplay() && screenAvailable);
selectColorButton.setVisible(screenAvailable);
if (!display.alwaysDisplay()) {
showButton.setSelected(display.isDisplayed());
}
@@ -464,44 +436,7 @@ public class PlayerControls extends JPanel implements MediaDisplayListener {
}
});
}
private static double roundZoom(double realZoom, int mantisa) {
double l10 = Math.log10(realZoom);
int lg = (int) (-Math.floor(l10) + mantisa - 1);
if (lg < 0) {
lg = 0;
}
BigDecimal bd = new BigDecimal(String.valueOf(realZoom)).setScale(lg, RoundingMode.HALF_UP);
return bd.doubleValue();
}
private void updateZoomDisplay() {
double pctzoom = roundZoom(getRealZoom() * 100, 3);
String r = Double.toString(pctzoom);
if (r.endsWith(".0")) {
r = r.substring(0, r.length() - 2);
}
r += "%";
if (zoomToFit) {
percentLabel.setText(AppStrings.translate("fit") + " (" + r + ")");
} else {
percentLabel.setText(r);
}
}
private void updateZoom() {
updateZoomDisplay();
double pctzoom = roundZoom(getRealZoom() * 100, 3);
double zoom = pctzoom / 100.0;
Zoom zoomObj = new Zoom();
zoomObj.value = zoom;
zoomObj.fit = zoomToFit;
display.zoom(zoomObj);
}
}
private void pauseButtonActionPerformed(ActionEvent evt) {
if (display.isPlaying()) {
@@ -586,33 +521,7 @@ public class PlayerControls extends JPanel implements MediaDisplayListener {
}
}
private void zoomInButtonActionPerformed(ActionEvent evt) {
double currentRealZoom = getRealZoom();
if (currentRealZoom >= MAX_ZOOM) {
return;
}
realZoom = currentRealZoom * ZOOM_MULTIPLIER;
zoomToFit = false;
updateZoom();
}
private void zoomOutButtonActionPerformed(ActionEvent evt) {
realZoom = getRealZoom() / ZOOM_MULTIPLIER;
zoomToFit = false;
updateZoom();
}
private void zoomNoneButtonActionPerformed(ActionEvent evt) {
realZoom = 1.0;
zoomToFit = false;
updateZoom();
}
private void zoomFitButtonActionPerformed(ActionEvent evt) {
realZoom = 1.0;
zoomToFit = true;
updateZoom();
}
private void snapShotButtonActionPerformed(ActionEvent evt) {
putImageToClipBoard(display.printScreen());
@@ -640,13 +549,7 @@ public class PlayerControls extends JPanel implements MediaDisplayListener {
Configuration.playFrameSounds.set(!muteButton.isSelected());
}
private double getRealZoom() {
if (zoomToFit) {
return display.getZoomToFit();
}
return realZoom;
}
@Override
public void mediaDisplayStateChanged(MediaDisplay source) {
@@ -0,0 +1,190 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.gui.player;
import com.jpexs.decompiler.flash.gui.AppStrings;
import com.jpexs.decompiler.flash.gui.View;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Objects;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
*
* @author JPEXS
*/
public class ZoomPanel extends JPanel implements MediaDisplayListener {
private MediaDisplay display;
private JButton zoomFitButton;
private final JLabel percentLabel = new JLabel("100%");
private boolean zoomToFit = false;
private double realZoom = 1.0;
private final double MAX_ZOOM = 1.0e6; //in larger zooms, flash viewer stops working
public ZoomPanel(MediaDisplay display) {
this.display = display;
JButton zoomInButton = new JButton(View.getIcon("zoomin16"));
zoomInButton.addActionListener(this::zoomInButtonActionPerformed);
zoomInButton.setToolTipText(AppStrings.translate("button.zoomin.hint"));
JButton zoomOutButton = new JButton(View.getIcon("zoomout16"));
zoomOutButton.addActionListener(this::zoomOutButtonActionPerformed);
zoomOutButton.setToolTipText(AppStrings.translate("button.zoomout.hint"));
zoomFitButton = new JButton(View.getIcon("zoomfit16"));
zoomFitButton.addActionListener(this::zoomFitButtonActionPerformed);
zoomFitButton.setToolTipText(AppStrings.translate("button.zoomfit.hint"));
JButton zoomNoneButton = new JButton(View.getIcon("zoomnone16"));
zoomNoneButton.addActionListener(this::zoomNoneButtonActionPerformed);
zoomNoneButton.setToolTipText(AppStrings.translate("button.zoomnone.hint"));
setLayout(new FlowLayout());
add(percentLabel);
add(zoomInButton);
add(zoomOutButton);
add(zoomNoneButton);
add(zoomFitButton);
display.addEventListener(this);
}
private void zoomInButtonActionPerformed(ActionEvent evt) {
double currentRealZoom = getRealZoom();
if (currentRealZoom >= MAX_ZOOM) {
return;
}
realZoom = currentRealZoom * PlayerControls.ZOOM_MULTIPLIER;
zoomToFit = false;
updateZoom();
}
private void zoomOutButtonActionPerformed(ActionEvent evt) {
realZoom = getRealZoom() / PlayerControls.ZOOM_MULTIPLIER;
zoomToFit = false;
updateZoom();
}
private void zoomNoneButtonActionPerformed(ActionEvent evt) {
realZoom = 1.0;
zoomToFit = false;
updateZoom();
}
private void zoomFitButtonActionPerformed(ActionEvent evt) {
realZoom = 1.0;
zoomToFit = true;
updateZoom();
}
private double getRealZoom() {
if (zoomToFit) {
return display.getZoomToFit();
}
return realZoom;
}
private void updateZoom() {
updateZoomDisplay();
double pctzoom = roundZoom(getRealZoom() * 100, 3);
double zoom = pctzoom / 100.0;
Zoom zoomObj = new Zoom();
zoomObj.value = zoom;
zoomObj.fit = zoomToFit;
display.zoom(zoomObj);
}
private void updateZoomDisplay() {
double pctzoom = roundZoom(getRealZoom() * 100, 3);
String r = Double.toString(pctzoom);
if (r.endsWith(".0")) {
r = r.substring(0, r.length() - 2);
}
r += "%";
if (zoomToFit) {
percentLabel.setText(AppStrings.translate("fit") + " (" + r + ")");
} else {
percentLabel.setText(r);
}
}
private static double roundZoom(double realZoom, int mantisa) {
double l10 = Math.log10(realZoom);
int lg = (int) (-Math.floor(l10) + mantisa - 1);
if (lg < 0) {
lg = 0;
}
BigDecimal bd = new BigDecimal(String.valueOf(realZoom)).setScale(lg, RoundingMode.HALF_UP);
return bd.doubleValue();
}
public void update() {
if (!display.isLoaded()) {
return;
}
View.execInEventDispatchLater(() -> {
Zoom zoom = display.getZoom();
zoomFitButton.setVisible(zoom != null);
percentLabel.setVisible(zoom != null);
Zoom currentZoom = new Zoom();
currentZoom.fit = zoomToFit;
currentZoom.value = realZoom;
if (zoom != null && !Objects.equals(zoom, currentZoom)) {
zoomToFit = zoom.fit;
realZoom = zoom.value;
updateZoomDisplay();
}
});
}
public void setMedia(MediaDisplay media) {
if (this.display != null) {
this.display.removeEventListener(this);
}
this.display = media;
this.display.addEventListener(this);
update();
}
@Override
public void mediaDisplayStateChanged(MediaDisplay source) {
if (display != source) {
return;
}
update();
}
@Override
public void playingFinished(MediaDisplay source) {
}
@Override
public void statusChanged(String status) {
}
}