From 04b01512c124c76f3b3d99ba07ef30ea6a90b52f Mon Sep 17 00:00:00 2001 From: 2xsaiko Date: Fri, 24 Apr 2020 18:39:57 +0200 Subject: Add a configurable scale factor (#230) * Add swing-dpi dependency * Implement scale factor * Improve custom scale dialog, fix crash * Remove use of $ in identifiers * Use custom functional interface for scale listeners * Bump version Co-authored-by: modmuss50 --- src/main/java/cuchaz/enigma/config/Config.java | 5 +- src/main/java/cuchaz/enigma/config/Themes.java | 66 +++++++------ src/main/java/cuchaz/enigma/gui/Gui.java | 48 +++++----- .../java/cuchaz/enigma/gui/dialog/AboutDialog.java | 3 +- .../java/cuchaz/enigma/gui/dialog/CrashDialog.java | 3 +- .../cuchaz/enigma/gui/dialog/JavadocDialog.java | 3 +- .../cuchaz/enigma/gui/dialog/ProgressDialog.java | 5 +- .../cuchaz/enigma/gui/dialog/SearchDialog.java | 3 +- .../java/cuchaz/enigma/gui/elements/MenuBar.java | 91 +++++++++++++----- .../java/cuchaz/enigma/gui/panels/PanelEditor.java | 7 +- .../cuchaz/enigma/gui/panels/PanelIdentifier.java | 3 +- .../enigma/gui/util/ScaleChangeListener.java | 8 ++ .../java/cuchaz/enigma/gui/util/ScaleUtil.java | 104 +++++++++++++++++++++ 13 files changed, 265 insertions(+), 84 deletions(-) create mode 100644 src/main/java/cuchaz/enigma/gui/util/ScaleChangeListener.java create mode 100644 src/main/java/cuchaz/enigma/gui/util/ScaleUtil.java (limited to 'src/main/java') diff --git a/src/main/java/cuchaz/enigma/config/Config.java b/src/main/java/cuchaz/enigma/config/Config.java index 15a974c3..20605b76 100644 --- a/src/main/java/cuchaz/enigma/config/Config.java +++ b/src/main/java/cuchaz/enigma/config/Config.java @@ -7,6 +7,7 @@ import cuchaz.enigma.source.DecompilerService; import cuchaz.enigma.source.Decompilers; import cuchaz.enigma.utils.I18n; +import cuchaz.enigma.gui.util.ScaleUtil; import javax.swing.*; import javax.swing.plaf.metal.MetalLookAndFeel; @@ -78,7 +79,7 @@ public class Config { public static boolean isDarkLaf() { // a bit of a hack because swing doesn't give any API for that, and we need colors that aren't defined in look and feel JPanel panel = new JPanel(); - panel.setSize(new Dimension(10, 10)); + panel.setSize(ScaleUtil.getDimension(10, 10)); panel.doLayout(); BufferedImage image = new BufferedImage(panel.getSize().width, panel.getSize().height, BufferedImage.TYPE_INT_RGB); @@ -187,6 +188,8 @@ public class Config { public LookAndFeel lookAndFeel = LookAndFeel.DEFAULT; + public float scaleFactor = 1.0f; + public Decompiler decompiler = Decompiler.PROCYON; private Config() { diff --git a/src/main/java/cuchaz/enigma/config/Themes.java b/src/main/java/cuchaz/enigma/config/Themes.java index 753654e1..547a4202 100644 --- a/src/main/java/cuchaz/enigma/config/Themes.java +++ b/src/main/java/cuchaz/enigma/config/Themes.java @@ -1,40 +1,48 @@ package cuchaz.enigma.config; +import java.awt.Font; +import java.io.IOException; +import java.lang.reflect.Field; + +import javax.swing.SwingUtilities; + +import com.github.swingdpi.UiDefaultsScaler; import com.google.common.collect.ImmutableMap; -import cuchaz.enigma.gui.Gui; import cuchaz.enigma.gui.EnigmaSyntaxKit; +import cuchaz.enigma.gui.Gui; import cuchaz.enigma.gui.highlight.BoxHighlightPainter; import cuchaz.enigma.gui.highlight.TokenHighlightType; +import cuchaz.enigma.gui.util.ScaleUtil; import de.sciss.syntaxpane.DefaultSyntaxKit; -import javax.swing.*; -import java.io.IOException; - public class Themes { - public static void setLookAndFeel(Gui gui, Config.LookAndFeel lookAndFeel) { - Config.getInstance().lookAndFeel = lookAndFeel; - updateTheme(gui); - } - - public static void updateTheme(Gui gui) { - Config config = Config.getInstance(); - config.lookAndFeel.setGlobalLAF(); - config.lookAndFeel.apply(config); - try { - config.saveConfig(); - } catch (IOException e) { - e.printStackTrace(); - } - EnigmaSyntaxKit.invalidate(); - DefaultSyntaxKit.initKit(); - DefaultSyntaxKit.registerContentType("text/enigma-sources", EnigmaSyntaxKit.class.getName()); - gui.boxHighlightPainters = ImmutableMap.of( - TokenHighlightType.OBFUSCATED, BoxHighlightPainter.create(config.obfuscatedColor, config.obfuscatedColorOutline), - TokenHighlightType.PROPOSED, BoxHighlightPainter.create(config.proposedColor, config.proposedColorOutline), - TokenHighlightType.DEOBFUSCATED, BoxHighlightPainter.create(config.deobfuscatedColor, config.deobfuscatedColorOutline) - ); - gui.setEditorTheme(config.lookAndFeel); - SwingUtilities.updateComponentTreeUI(gui.getFrame()); - } + public static void setLookAndFeel(Gui gui, Config.LookAndFeel lookAndFeel) { + Config.getInstance().lookAndFeel = lookAndFeel; + updateTheme(gui); + } + + public static void updateTheme(Gui gui) { + Config config = Config.getInstance(); + config.lookAndFeel.setGlobalLAF(); + config.lookAndFeel.apply(config); + try { + config.saveConfig(); + } catch (IOException e) { + e.printStackTrace(); + } + EnigmaSyntaxKit.invalidate(); + DefaultSyntaxKit.initKit(); + DefaultSyntaxKit.registerContentType("text/enigma-sources", EnigmaSyntaxKit.class.getName()); + gui.boxHighlightPainters = ImmutableMap.of( + TokenHighlightType.OBFUSCATED, BoxHighlightPainter.create(config.obfuscatedColor, config.obfuscatedColorOutline), + TokenHighlightType.PROPOSED, BoxHighlightPainter.create(config.proposedColor, config.proposedColorOutline), + TokenHighlightType.DEOBFUSCATED, BoxHighlightPainter.create(config.deobfuscatedColor, config.deobfuscatedColorOutline) + ); + gui.setEditorTheme(config.lookAndFeel); + SwingUtilities.updateComponentTreeUI(gui.getFrame()); + ScaleUtil.applyScaling(); + } + + } diff --git a/src/main/java/cuchaz/enigma/gui/Gui.java b/src/main/java/cuchaz/enigma/gui/Gui.java index ee8fbdff..8f0d6fac 100644 --- a/src/main/java/cuchaz/enigma/gui/Gui.java +++ b/src/main/java/cuchaz/enigma/gui/Gui.java @@ -11,6 +11,18 @@ package cuchaz.enigma.gui; +import java.awt.*; +import java.awt.event.*; +import java.nio.file.Path; +import java.util.List; +import java.util.*; +import java.util.function.Function; + +import javax.swing.*; +import javax.swing.text.BadLocationException; +import javax.swing.text.Highlighter; +import javax.swing.tree.*; + import com.google.common.base.Strings; import com.google.common.collect.Lists; import cuchaz.enigma.Constants; @@ -37,20 +49,10 @@ import cuchaz.enigma.throwables.IllegalNameException; import cuchaz.enigma.translation.mapping.*; import cuchaz.enigma.translation.representation.entry.*; import cuchaz.enigma.utils.I18n; +import cuchaz.enigma.gui.util.ScaleUtil; import cuchaz.enigma.utils.Utils; import de.sciss.syntaxpane.DefaultSyntaxKit; -import javax.swing.*; -import javax.swing.text.BadLocationException; -import javax.swing.text.Highlighter; -import javax.swing.tree.*; -import java.awt.*; -import java.awt.event.*; -import java.nio.file.Path; -import java.util.List; -import java.util.*; -import java.util.function.Function; - public class Gui { public final PopupMenuBar popupMenu; @@ -119,6 +121,8 @@ public class Gui { this.controller = new GuiController(this, profile); + Themes.updateTheme(this); + // init file choosers this.jarFileChooser = new FileDialog(getFrame(), I18n.translate("menu.file.jar.open"), FileDialog.LOAD); @@ -135,14 +139,13 @@ public class Gui { splitClasses.setResizeWeight(0.3); this.classesPanel = new JPanel(); this.classesPanel.setLayout(new BorderLayout()); - this.classesPanel.setPreferredSize(new Dimension(250, 0)); + this.classesPanel.setPreferredSize(ScaleUtil.getDimension(250, 0)); // init info panel infoPanel = new PanelIdentifier(this); infoPanel.clearReference(); // init editor - Themes.updateTheme(this); selectionHighlightPainter = new SelectionHighlightPainter(); this.editor = new PanelEditor(this); JScrollPane sourceScroller = new JScrollPane(this.editor); @@ -257,8 +260,8 @@ public class Gui { } } }); - tokens.setPreferredSize(new Dimension(0, 200)); - tokens.setMinimumSize(new Dimension(0, 200)); + tokens.setPreferredSize(ScaleUtil.getDimension(0, 200)); + tokens.setMinimumSize(ScaleUtil.getDimension(0, 200)); JSplitPane callPanel = new JSplitPane( JSplitPane.VERTICAL_SPLIT, true, @@ -274,7 +277,7 @@ public class Gui { centerPanel.add(infoPanel, BorderLayout.NORTH); centerPanel.add(sourceScroller, BorderLayout.CENTER); tabs = new JTabbedPane(); - tabs.setPreferredSize(new Dimension(250, 0)); + tabs.setPreferredSize(ScaleUtil.getDimension(250, 0)); tabs.addTab(I18n.translate("info_panel.tree.inheritance"), inheritancePanel); tabs.addTab(I18n.translate("info_panel.tree.implementations"), implementationsPanel); tabs.addTab(I18n.translate("info_panel.tree.calls"), callPanel); @@ -301,10 +304,11 @@ public class Gui { // show the frame pane.doLayout(); - this.frame.setSize(1024, 576); - this.frame.setMinimumSize(new Dimension(640, 480)); + this.frame.setSize(ScaleUtil.getDimension(1024, 576)); + this.frame.setMinimumSize(ScaleUtil.getDimension(640, 480)); this.frame.setVisible(true); this.frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); + this.frame.setLocationRelativeTo(null); } public JFrame getFrame() { @@ -492,7 +496,7 @@ public class Gui { panel.setLayout(new FlowLayout(FlowLayout.LEFT, 6, 0)); JLabel label = new JLabel(name + ":", JLabel.RIGHT); - label.setPreferredSize(new Dimension(100, label.getPreferredSize().height)); + label.setPreferredSize(ScaleUtil.getDimension(100, ScaleUtil.invert(label.getPreferredSize().height))); panel.add(label); panel.add(Utils.unboldLabel(new JLabel(value, JLabel.LEFT))); @@ -506,11 +510,11 @@ public class Gui { JPanel panel = new JPanel(); panel.setLayout(new FlowLayout(FlowLayout.LEFT, 6, 0)); JLabel label = new JLabel(name + ":", JLabel.RIGHT); - label.setPreferredSize(new Dimension(100, label.getPreferredSize().height)); + label.setPreferredSize(ScaleUtil.getDimension(100, ScaleUtil.invert(label.getPreferredSize().height))); panel.add(label); JComboBox combo = new JComboBox<>(AccessModifier.values()); ((JLabel) combo.getRenderer()).setHorizontalAlignment(JLabel.LEFT); - combo.setPreferredSize(new Dimension(100, label.getPreferredSize().height)); + combo.setPreferredSize(ScaleUtil.getDimension(100, ScaleUtil.invert(label.getPreferredSize().height))); EntryMapping mapping = controller.project.getMapper().getDeobfMapping(entry); if (mapping != null) { @@ -628,7 +632,7 @@ public class Gui { EntryReference, Entry> translatedReference = controller.project.getMapper().deobfuscate(cursorReference); renameTextField.setText(translatedReference.getNameableName()); - renameTextField.setPreferredSize(new Dimension(360, renameTextField.getPreferredSize().height)); + renameTextField.setPreferredSize(ScaleUtil.getDimension(360, ScaleUtil.invert(renameTextField.getPreferredSize().height))); renameTextField.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent event) { diff --git a/src/main/java/cuchaz/enigma/gui/dialog/AboutDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/AboutDialog.java index 82fd6a5c..43b82651 100644 --- a/src/main/java/cuchaz/enigma/gui/dialog/AboutDialog.java +++ b/src/main/java/cuchaz/enigma/gui/dialog/AboutDialog.java @@ -13,6 +13,7 @@ package cuchaz.enigma.gui.dialog; import cuchaz.enigma.Constants; import cuchaz.enigma.utils.I18n; +import cuchaz.enigma.gui.util.ScaleUtil; import cuchaz.enigma.utils.Utils; import javax.swing.*; @@ -59,7 +60,7 @@ public class AboutDialog { // show the frame pane.doLayout(); - frame.setSize(400, 220); + frame.setSize(ScaleUtil.getDimension(400, 220)); frame.setResizable(false); frame.setLocationRelativeTo(parent); frame.setVisible(true); diff --git a/src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java index 78b1d751..908b42e9 100644 --- a/src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java +++ b/src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java @@ -13,6 +13,7 @@ package cuchaz.enigma.gui.dialog; import cuchaz.enigma.Constants; import cuchaz.enigma.utils.I18n; +import cuchaz.enigma.gui.util.ScaleUtil; import cuchaz.enigma.utils.Utils; import javax.swing.*; @@ -81,7 +82,7 @@ public class CrashDialog { pane.add(buttonsPanel, BorderLayout.SOUTH); // show the frame - frame.setSize(600, 400); + frame.setSize(ScaleUtil.getDimension(600, 400)); frame.setLocationRelativeTo(parent); frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); } diff --git a/src/main/java/cuchaz/enigma/gui/dialog/JavadocDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/JavadocDialog.java index 033318ae..b2c159d7 100644 --- a/src/main/java/cuchaz/enigma/gui/dialog/JavadocDialog.java +++ b/src/main/java/cuchaz/enigma/gui/dialog/JavadocDialog.java @@ -12,6 +12,7 @@ package cuchaz.enigma.gui.dialog; import cuchaz.enigma.utils.I18n; +import cuchaz.enigma.gui.util.ScaleUtil; import cuchaz.enigma.utils.Utils; import javax.swing.*; @@ -72,7 +73,7 @@ public class JavadocDialog { pane.add(buttonsPanel, BorderLayout.SOUTH); // show the frame - frame.setSize(600, 400); + frame.setSize(ScaleUtil.getDimension(600, 400)); frame.setLocationRelativeTo(parent); frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); } diff --git a/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java index 6d9a4198..e33ae821 100644 --- a/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java +++ b/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java @@ -14,6 +14,7 @@ package cuchaz.enigma.gui.dialog; import cuchaz.enigma.Constants; import cuchaz.enigma.ProgressListener; import cuchaz.enigma.utils.I18n; +import cuchaz.enigma.gui.util.ScaleUtil; import cuchaz.enigma.utils.Utils; import javax.swing.*; @@ -48,11 +49,11 @@ public class ProgressDialog implements ProgressListener, AutoCloseable { this.labelText.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0)); panel.add(this.labelText, BorderLayout.NORTH); panel.add(this.progress, BorderLayout.CENTER); - panel.setPreferredSize(new Dimension(360, 50)); + panel.setPreferredSize(ScaleUtil.getDimension(360, 50)); // show the frame pane.doLayout(); - this.frame.setSize(400, 120); + this.frame.setSize(ScaleUtil.getDimension(400, 120)); this.frame.setResizable(false); this.frame.setLocationRelativeTo(parent); this.frame.setVisible(true); diff --git a/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java index 47f9149d..56ce7515 100644 --- a/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java +++ b/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java @@ -15,6 +15,7 @@ import com.google.common.collect.Lists; import cuchaz.enigma.gui.Gui; import cuchaz.enigma.translation.representation.entry.ClassEntry; import cuchaz.enigma.utils.I18n; +import cuchaz.enigma.gui.util.ScaleUtil; import me.xdrop.fuzzywuzzy.FuzzySearch; import me.xdrop.fuzzywuzzy.model.ExtractedResult; @@ -107,7 +108,7 @@ public class SearchDialog { frame.setContentPane(pane); frame.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS)); - frame.setSize(360, 500); + frame.setSize(ScaleUtil.getDimension(360, 500)); frame.setAlwaysOnTop(true); frame.setResizable(false); frame.setLocationRelativeTo(parent.getFrame()); diff --git a/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java b/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java index f3bf69ab..fd521aba 100644 --- a/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java +++ b/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java @@ -1,16 +1,8 @@ package cuchaz.enigma.gui.elements; -import cuchaz.enigma.config.Config; -import cuchaz.enigma.config.Themes; -import cuchaz.enigma.gui.Gui; -import cuchaz.enigma.gui.dialog.AboutDialog; -import cuchaz.enigma.gui.dialog.SearchDialog; -import cuchaz.enigma.gui.stats.StatsMember; -import cuchaz.enigma.translation.mapping.serde.MappingFormat; -import cuchaz.enigma.utils.I18n; - -import javax.swing.*; -import java.awt.*; +import java.awt.Container; +import java.awt.Desktop; +import java.awt.FlowLayout; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.io.File; @@ -20,9 +12,22 @@ import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.List; import java.util.*; import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import javax.swing.*; + +import cuchaz.enigma.config.Config; +import cuchaz.enigma.config.Themes; +import cuchaz.enigma.gui.Gui; +import cuchaz.enigma.gui.dialog.AboutDialog; +import cuchaz.enigma.gui.dialog.SearchDialog; +import cuchaz.enigma.gui.stats.StatsMember; +import cuchaz.enigma.gui.util.ScaleUtil; +import cuchaz.enigma.translation.mapping.serde.MappingFormat; +import cuchaz.enigma.utils.I18n; +import cuchaz.enigma.utils.Pair; public class MenuBar extends JMenuBar { @@ -167,7 +172,7 @@ public class MenuBar extends JMenuBar { JMenuItem stats = new JMenuItem(I18n.translate("menu.file.stats")); stats.addActionListener(event -> { - JFrame frame = new JFrame(I18n.translate("menu.file.stats.title")); + JFrame frame = new JFrame(I18n.translate("menu.file.stats.title")); Container pane = frame.getContentPane(); pane.setLayout(new FlowLayout()); @@ -195,10 +200,10 @@ public class MenuBar extends JMenuBar { }); pane.add(button); - frame.pack(); - frame.setLocationRelativeTo(this.gui.getFrame()); - frame.setVisible(true); - }); + frame.pack(); + frame.setLocationRelativeTo(this.gui.getFrame()); + frame.setVisible(true); + }); menu.add(stats); } @@ -247,7 +252,7 @@ public class MenuBar extends JMenuBar { themes.add(theme); theme.addActionListener(event -> Themes.setLookAndFeel(gui, lookAndFeel)); } - + JMenu languages = new JMenu(I18n.translate("menu.view.languages")); menu.add(languages); for (String lang : I18n.getAvailableLanguages()) { @@ -258,21 +263,63 @@ public class MenuBar extends JMenuBar { JFrame frame = new JFrame(I18n.translate("menu.view.languages.title")); Container pane = frame.getContentPane(); pane.setLayout(new FlowLayout()); - + JLabel text = new JLabel((I18n.translate("menu.view.languages.summary"))); text.setHorizontalAlignment(JLabel.CENTER); pane.add(text); - + JButton okButton = new JButton(I18n.translate("menu.view.languages.ok")); pane.add(okButton); okButton.addActionListener(arg0 -> frame.dispose()); - + frame.pack(); frame.setLocationRelativeTo(this.gui.getFrame()); frame.setVisible(true); }); } + JMenu scale = new JMenu(I18n.translate("menu.view.scale")); + { + ButtonGroup scaleGroup = new ButtonGroup(); + Map map = IntStream.of(100, 125, 150, 175, 200) + .mapToObj(scaleFactor -> { + float realScaleFactor = scaleFactor / 100f; + JRadioButtonMenuItem menuItem = new JRadioButtonMenuItem(String.format("%d%%", scaleFactor)); + menuItem.addActionListener(event -> ScaleUtil.setScaleFactor(realScaleFactor)); + scaleGroup.add(menuItem); + scale.add(menuItem); + return new Pair<>(realScaleFactor, menuItem); + }) + .collect(Collectors.toMap(x -> x.a, x -> x.b)); + + JMenuItem customScale = new JMenuItem(I18n.translate("menu.view.scale.custom")); + customScale.addActionListener(event -> { + String answer = (String) JOptionPane.showInputDialog(gui.getFrame(), "Custom Scale", "Custom Scale", + JOptionPane.QUESTION_MESSAGE, null, null, Float.toString(ScaleUtil.getScaleFactor() * 100)); + if (answer == null) return; + float newScale = 1.0f; + try { + newScale = Float.parseFloat(answer) / 100f; + } catch (NumberFormatException ignored) { + } + ScaleUtil.setScaleFactor(newScale); + }); + scale.add(customScale); + ScaleUtil.addListener((newScale, _oldScale) -> { + JRadioButtonMenuItem mi = map.get(newScale); + if (mi != null) { + mi.setSelected(true); + } else { + scaleGroup.clearSelection(); + } + }); + JRadioButtonMenuItem mi = map.get(ScaleUtil.getScaleFactor()); + if (mi != null) { + mi.setSelected(true); + } + } + menu.add(scale); + JMenuItem search = new JMenuItem(I18n.translate("menu.view.search")); search.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, InputEvent.SHIFT_MASK)); menu.add(search); @@ -284,7 +331,7 @@ public class MenuBar extends JMenuBar { } } - + /* * Help menu */ diff --git a/src/main/java/cuchaz/enigma/gui/panels/PanelEditor.java b/src/main/java/cuchaz/enigma/gui/panels/PanelEditor.java index 1a34edf8..8296842c 100644 --- a/src/main/java/cuchaz/enigma/gui/panels/PanelEditor.java +++ b/src/main/java/cuchaz/enigma/gui/panels/PanelEditor.java @@ -7,6 +7,7 @@ import cuchaz.enigma.gui.BrowserCaret; import cuchaz.enigma.gui.Gui; import cuchaz.enigma.translation.representation.entry.ClassEntry; import cuchaz.enigma.translation.representation.entry.Entry; +import cuchaz.enigma.gui.util.ScaleUtil; import javax.swing.*; import java.awt.*; @@ -23,7 +24,7 @@ public class PanelEditor extends JEditorPane { this.setEditable(false); this.setSelectionColor(new Color(31, 46, 90)); this.setCaret(new BrowserCaret()); - this.setFont(new Font(this.getFont().getFontName(), Font.PLAIN, this.fontSize)); + this.setFont(ScaleUtil.getFont(this.getFont().getFontName(), Font.PLAIN, this.fontSize)); this.addCaretListener(event -> gui.onCaretMove(event.getDot(), mouseIsPressed)); final PanelEditor self = this; this.addMouseListener(new MouseAdapter() { @@ -154,13 +155,13 @@ public class PanelEditor extends JEditorPane { int newResult = this.fontSize + zoomAmount; if (newResult > 8 && newResult < 72) { this.fontSize = newResult; - this.setFont(new Font(this.getFont().getFontName(), Font.PLAIN, this.fontSize)); + this.setFont(ScaleUtil.getFont(this.getFont().getFontName(), Font.PLAIN, this.fontSize)); } } public void resetEditorZoom() { this.fontSize = 12; - this.setFont(new Font(this.getFont().getFontName(), Font.PLAIN, this.fontSize)); + this.setFont(ScaleUtil.getFont(this.getFont().getFontName(), Font.PLAIN, this.fontSize)); } @Override diff --git a/src/main/java/cuchaz/enigma/gui/panels/PanelIdentifier.java b/src/main/java/cuchaz/enigma/gui/panels/PanelIdentifier.java index 0cca40d9..de069bc6 100644 --- a/src/main/java/cuchaz/enigma/gui/panels/PanelIdentifier.java +++ b/src/main/java/cuchaz/enigma/gui/panels/PanelIdentifier.java @@ -2,6 +2,7 @@ package cuchaz.enigma.gui.panels; import cuchaz.enigma.gui.Gui; import cuchaz.enigma.utils.I18n; +import cuchaz.enigma.gui.util.ScaleUtil; import cuchaz.enigma.utils.Utils; import javax.swing.*; @@ -15,7 +16,7 @@ public class PanelIdentifier extends JPanel { this.gui = gui; this.setLayout(new GridLayout(4, 1, 0, 0)); - this.setPreferredSize(new Dimension(0, 100)); + this.setPreferredSize(ScaleUtil.getDimension(0, 100)); this.setBorder(BorderFactory.createTitledBorder(I18n.translate("info_panel.identifier"))); } diff --git a/src/main/java/cuchaz/enigma/gui/util/ScaleChangeListener.java b/src/main/java/cuchaz/enigma/gui/util/ScaleChangeListener.java new file mode 100644 index 00000000..d045c6d5 --- /dev/null +++ b/src/main/java/cuchaz/enigma/gui/util/ScaleChangeListener.java @@ -0,0 +1,8 @@ +package cuchaz.enigma.gui.util; + +@FunctionalInterface +public interface ScaleChangeListener { + + void onScaleChanged(float scale, float oldScale); + +} diff --git a/src/main/java/cuchaz/enigma/gui/util/ScaleUtil.java b/src/main/java/cuchaz/enigma/gui/util/ScaleUtil.java new file mode 100644 index 00000000..8bc826fc --- /dev/null +++ b/src/main/java/cuchaz/enigma/gui/util/ScaleUtil.java @@ -0,0 +1,104 @@ +package cuchaz.enigma.gui.util; + +import java.awt.Dimension; +import java.awt.Font; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.UIManager; + +import com.github.swingdpi.UiDefaultsScaler; +import com.github.swingdpi.plaf.BasicTweaker; +import com.github.swingdpi.plaf.MetalTweaker; +import com.github.swingdpi.plaf.NimbusTweaker; +import com.github.swingdpi.plaf.WindowsTweaker; +import cuchaz.enigma.config.Config; +import de.sciss.syntaxpane.DefaultSyntaxKit; + +public class ScaleUtil { + + private static List listeners = new ArrayList<>(); + + public static float getScaleFactor() { + return Config.getInstance().scaleFactor; + } + + public static void setScaleFactor(float scaleFactor) { + float oldScale = getScaleFactor(); + float clamped = Math.min(Math.max(0.25f, scaleFactor), 10.0f); + Config.getInstance().scaleFactor = clamped; + try { + Config.getInstance().saveConfig(); + } catch (IOException e) { + e.printStackTrace(); + } + listeners.forEach(l -> l.onScaleChanged(clamped, oldScale)); + } + + public static void addListener(ScaleChangeListener listener) { + listeners.add(listener); + } + + public static void removeListener(ScaleChangeListener listener) { + listeners.remove(listener); + } + + public static Dimension getDimension(int width, int height) { + return new Dimension(scale(width), scale(height)); + } + + public static Font getFont(String fontName, int plain, int fontSize) { + return scaleFont(new Font(fontName, plain, fontSize)); + } + + public static Font scaleFont(Font font) { + return createTweakerForCurrentLook(getScaleFactor()).modifyFont("", font); + } + + public static float scale(float f) { + return f * getScaleFactor(); + } + + public static float invert(float f) { + return f / getScaleFactor(); + } + + public static int scale(int i) { + return (int) (i * getScaleFactor()); + } + + public static int invert(int i) { + return (int) (i / getScaleFactor()); + } + + public static void applyScaling() { + float scale = getScaleFactor(); + UiDefaultsScaler.updateAndApplyGlobalScaling((int) (100 * scale), true); + try { + Field defaultFontField = DefaultSyntaxKit.class.getDeclaredField("DEFAULT_FONT"); + defaultFontField.setAccessible(true); + Font font = (Font) defaultFontField.get(null); + font = font.deriveFont(12 * scale); + defaultFontField.set(null, font); + } catch (NoSuchFieldException | IllegalAccessException e) { + e.printStackTrace(); + } + } + + private static BasicTweaker createTweakerForCurrentLook(float dpiScaling) { + String testString = UIManager.getLookAndFeel().getName().toLowerCase(); + if (testString.contains("windows")) { + return new WindowsTweaker(dpiScaling, testString.contains("classic")); + } + if (testString.contains("metal")) { + return new MetalTweaker(dpiScaling); + } + if (testString.contains("nimbus")) { + return new NimbusTweaker(dpiScaling); + } + return new BasicTweaker(dpiScaling); + } + +} -- cgit v1.2.3