From 005247cc0badcd11467e68a12239467b1edb2e3d Mon Sep 17 00:00:00 2001 From: Dmitry Isaenko Date: Thu, 20 Nov 2025 01:28:09 +0300 Subject: [PATCH] Drafting scaling options for HiDPI --- src/main/java/tihwin/MainAppUi.form | 63 ++++++++++++++---- src/main/java/tihwin/MainAppUi.java | 98 +++++++++++++++++++++++++--- src/main/java/tihwin/Settings.java | 9 ++- src/main/resources/zoom-in.png | Bin 0 -> 1463 bytes src/main/resources/zoom-out.png | Bin 0 -> 1366 bytes 5 files changed, 145 insertions(+), 25 deletions(-) create mode 100644 src/main/resources/zoom-in.png create mode 100644 src/main/resources/zoom-out.png diff --git a/src/main/java/tihwin/MainAppUi.form b/src/main/java/tihwin/MainAppUi.form index 58f8882..474e4c6 100644 --- a/src/main/java/tihwin/MainAppUi.form +++ b/src/main/java/tihwin/MainAppUi.form @@ -2,7 +2,7 @@
- + @@ -14,7 +14,7 @@ - + @@ -23,9 +23,9 @@ - + - + @@ -146,7 +146,7 @@ - + @@ -159,7 +159,7 @@ - + @@ -178,6 +178,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -187,14 +228,10 @@ - - - - - + @@ -207,9 +244,7 @@ - - - + diff --git a/src/main/java/tihwin/MainAppUi.java b/src/main/java/tihwin/MainAppUi.java index beb954b..e0d912b 100644 --- a/src/main/java/tihwin/MainAppUi.java +++ b/src/main/java/tihwin/MainAppUi.java @@ -1,5 +1,5 @@ /* - Copyright 2022-2023 Dmitry Isaenko + Copyright 2022-2025 Dmitry Isaenko This file is part of Tihwin. @@ -58,7 +58,10 @@ public class MainAppUi extends JFrame { private JLabel diskImageRoLbl; private JLabel titleRoLbl; private JLabel ulDestinationRoLbl; + private JButton zoomInBtn; + private JButton zoomOutBtn; private ResourceBundle resourceBundle; + int scale; private String recentRomLocation; private File diskImage; @@ -68,6 +71,7 @@ public class MainAppUi extends JFrame { private Thread splitThread; public MainAppUi(String appName) { + super(appName); $$$setupUI$$$(); resourceBundle = ResourceBundle.getBundle("locale"); AwesomeMediator.setMainUi(this); @@ -80,6 +84,8 @@ public class MainAppUi extends JFrame { destinationSelectBtn.addActionListener(actionEvent -> destinationSelectEventHandler()); convertBtn.addActionListener(actionEvent -> convertButtonAction()); ulCfgBtn.addActionListener(actionEvent -> ulConfigButtonAction()); + zoomInBtn.addActionListener(actionEvent -> zoomIn()); + zoomOutBtn.addActionListener(actionEvent -> zoomOut()); ((AbstractDocument) titleField.getDocument()).setDocumentFilter(new TitleFieldFilter()); if (Settings.INSTANCE.getDvdSelected()) DVDRadioButton.setSelected(true); @@ -94,6 +100,7 @@ public class MainAppUi extends JFrame { Settings.INSTANCE.setDestination(destinationDirectoryLbl.getText()); Settings.INSTANCE.setDvdSelected(DVDRadioButton.isSelected()); Settings.INSTANCE.setLocale(((LocaleHolder) ulLangComboBox.getSelectedItem()).getLocaleCode()); + Settings.INSTANCE.setScaleFactor(scale); } }); @@ -102,10 +109,56 @@ public class MainAppUi extends JFrame { BorderFactory.createEmptyBorder(5, 5, 5, 5)); diskImageSelectBtn.setBorder(fitMoreTextOnButtonBorder); destinationSelectBtn.setBorder(fitMoreTextOnButtonBorder); + ulCfgBtn.setBorder(fitMoreTextOnButtonBorder); diskImageSelectBtn.addMouseListener(new TwButtonsActionListener()); destinationSelectBtn.addMouseListener(new TwButtonsActionListener()); - titleField.setBorder(new LineBorder(Color.lightGray)); + + scale = Settings.INSTANCE.getScaleFactor(); + applyScaling(); + } + + private void applyScaling() { + if (scale == 0) + return; + + for (Component component : mainPanel.getComponents()) + applyScalingOnComponent(component); + applyScalingOnComponent(statusLbl); + applyScalingOnComponent(ulLangComboBox); + } + + private void applyScalingOnComponent(Component component) { + Font defaultFont = component.getFont(); + component.setFont(new Font(defaultFont.getName(), defaultFont.getStyle(), defaultFont.getSize() + scale)); + } + + private void zoomIn() { + for (Component c : mainPanel.getComponents()) + increaseElementScale(c); + increaseElementScale(statusLbl); + increaseElementScale(ulLangComboBox); + scale++; + } + + private void increaseElementScale(Component component) { + Font defaultFont = component.getFont(); + component.setFont(new Font(defaultFont.getName(), defaultFont.getStyle(), defaultFont.getSize() + 1)); + } + + private void zoomOut() { + if (scale == 0) + return; + for (Component c : mainPanel.getComponents()) + decreaseElementScale(c); + decreaseElementScale(statusLbl); + decreaseElementScale(ulLangComboBox); + scale--; + } + + private void decreaseElementScale(Component component) { + Font defaultFont = component.getFont(); + component.setFont(new Font(defaultFont.getName(), defaultFont.getStyle(), defaultFont.getSize() - 1)); } private void diskImageSelectEventHandler() { @@ -241,7 +294,7 @@ public class MainAppUi extends JFrame { private void $$$setupUI$$$() { createUIComponents(); mainPanel = new JPanel(); - mainPanel.setLayout(new FormLayout("fill:p:noGrow,left:4dlu:noGrow,fill:p:noGrow,left:4dlu:noGrow,fill:p:noGrow,fill:max(d;4px):noGrow,fill:d:grow,left:4dlu:noGrow,fill:p:noGrow", "center:max(d;4px):noGrow,top:m:grow,top:4dlu:noGrow,center:max(d;4px):noGrow,top:4dlu:noGrow,center:max(d;4px):noGrow,top:4dlu:noGrow,center:max(d;4px):noGrow,top:4dlu:noGrow,center:max(d;4px):noGrow,top:4dlu:noGrow,center:max(d;4px):noGrow,top:4dlu:noGrow,center:max(d;1dlu):noGrow")); + mainPanel.setLayout(new FormLayout("fill:p:noGrow,left:4dlu:noGrow,fill:p:noGrow,left:4dlu:noGrow,fill:p:noGrow,fill:max(d;4px):noGrow,fill:d:grow,left:4dlu:noGrow,fill:p:grow(0.2)", "center:max(d;4px):noGrow,top:m:grow(1.1),top:4dlu:noGrow,center:max(d;4px):noGrow,top:4dlu:noGrow,center:max(d;4px):noGrow,top:4dlu:noGrow,center:max(d;4px):noGrow,top:4dlu:noGrow,center:max(d;4px):noGrow,top:4dlu:noGrow,center:max(d;4px):noGrow,top:4dlu:noGrow,center:max(d;4px):noGrow")); diskImageSelectBtn = new JButton(); diskImageSelectBtn.setBackground(new Color(-2034433)); this.$$$loadButtonText$$$(diskImageSelectBtn, this.$$$getMessageFromBundle$$$("locale", "SelectBtn")); @@ -285,31 +338,56 @@ public class MainAppUi extends JFrame { progressBar.setIndeterminate(false); mainPanel.add(progressBar, cc.xyw(1, 12, 9, CellConstraints.FILL, CellConstraints.TOP)); final JPanel panel1 = new JPanel(); - panel1.setLayout(new GridLayoutManager(1, 2, new Insets(0, 0, 0, 0), -1, -1)); + panel1.setLayout(new GridLayoutManager(2, 2, new Insets(0, 0, 0, 0), -1, -1)); panel1.setBackground(new Color(-9251843)); mainPanel.add(panel1, cc.xyw(1, 1, 9)); final JLabel label1 = new JLabel(); label1.setIcon(new ImageIcon(getClass().getResource("/banner.png"))); label1.setText(""); - panel1.add(label1, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + panel1.add(label1, new GridConstraints(0, 0, 2, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); ulLangComboBox.setBackground(new Color(-9251843)); ulLangComboBox.setForeground(new Color(-1)); ulLangComboBox.putClientProperty("html.disable", Boolean.FALSE); panel1.add(ulLangComboBox, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_NORTHWEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 1, false)); + final JPanel panel2 = new JPanel(); + panel2.setLayout(new FlowLayout(FlowLayout.RIGHT, 0, 0)); + panel2.setAlignmentX(0.0f); + panel2.setAlignmentY(0.0f); + panel2.setFocusable(false); + panel2.setOpaque(false); + panel1.add(panel2, new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_NORTHEAST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 2, false)); + zoomInBtn = new JButton(); + zoomInBtn.setAlignmentY(0.0f); + zoomInBtn.setBorderPainted(false); + zoomInBtn.setContentAreaFilled(false); + zoomInBtn.setFocusPainted(true); + zoomInBtn.setIcon(new ImageIcon(getClass().getResource("/zoom-in.png"))); + zoomInBtn.setIconTextGap(0); + zoomInBtn.setOpaque(false); + zoomInBtn.setPreferredSize(new Dimension(25, 25)); + panel2.add(zoomInBtn); + zoomOutBtn = new JButton(); + zoomOutBtn.setAlignmentY(0.0f); + zoomOutBtn.setBorderPainted(false); + zoomOutBtn.setContentAreaFilled(false); + zoomOutBtn.setFocusPainted(true); + zoomOutBtn.setForeground(new Color(-9251843)); + zoomOutBtn.setIcon(new ImageIcon(getClass().getResource("/zoom-out.png"))); + zoomOutBtn.setIconTextGap(0); + zoomOutBtn.setOpaque(false); + zoomOutBtn.setPreferredSize(new Dimension(25, 25)); + panel2.add(zoomOutBtn); ulCfgBtn = new JButton(); ulCfgBtn.setBackground(new Color(-2031648)); - ulCfgBtn.setMargin(new Insets(1, 1, 1, 1)); - ulCfgBtn.setMinimumSize(new Dimension(130, 30)); - ulCfgBtn.setPreferredSize(new Dimension(140, 30)); this.$$$loadButtonText$$$(ulCfgBtn, this.$$$getMessageFromBundle$$$("locale", "editUlCfgBtn")); mainPanel.add(ulCfgBtn, new CellConstraints(9, 4, 1, 1, CellConstraints.DEFAULT, CellConstraints.DEFAULT, new Insets(0, 0, 0, 5))); statusJPanel = new JPanel(); - statusJPanel.setLayout(new GridLayoutManager(1, 1, new Insets(5, 5, 5, 5), -1, -1)); + statusJPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5)); statusJPanel.setBackground(new Color(-1)); mainPanel.add(statusJPanel, cc.xyw(1, 14, 9)); statusLbl = new JLabel(); this.$$$loadLabelText$$$(statusLbl, this.$$$getMessageFromBundle$$$("locale", "WelcomeText")); - statusJPanel.add(statusLbl, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + statusJPanel.add(statusLbl); ButtonGroup buttonGroup; buttonGroup = new ButtonGroup(); buttonGroup.add(DVDRadioButton); diff --git a/src/main/java/tihwin/Settings.java b/src/main/java/tihwin/Settings.java index 831e612..847ecbe 100644 --- a/src/main/java/tihwin/Settings.java +++ b/src/main/java/tihwin/Settings.java @@ -1,5 +1,5 @@ /* - Copyright 2022 Dmitry Isaenko + Copyright 2022-2025 Dmitry Isaenko This file is part of Tihwin. @@ -55,4 +55,11 @@ public class Settings { public Locale getLocale(){ return this.locale; } public void setLocale(String localeId){ preferences.put("locale", localeId); } + + public int getScaleFactor(){ + return preferences.getInt("scale", 0); + } + public void setScaleFactor(int value){ + preferences.putInt("scale", value); + } } diff --git a/src/main/resources/zoom-in.png b/src/main/resources/zoom-in.png new file mode 100644 index 0000000000000000000000000000000000000000..a8400b3fbb0c0d63421353a953b88215a9a99f79 GIT binary patch literal 1463 zcmV;o1xWgdP)P000>X1^@s6#OZ}&00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy32;bRa{vGf6951U69E94oEQKA00(qQO+^Rk3lkOw9Fh|afdBvn z4M{{nR7l6Qm0f64XBfx-=j1GjY1-5_ron0Vp%y=onz6E4>AD*!3>i~a5I1n!g}WHL z+N2jEWwMJ2yAdx6gBB^4ffTeVEwvxmVrl&-TC4eLO+VA5X;Na6ljAu#=XrLqbjW7h z1pQsT@WT7!`FNj4z;iIO0Kf)dGk`h(9|G74zyu%y;68v+0J8vOK@bS90yCSKc^fmI zBBBs8=a|_bB4TEyzc4gSOD2=aj+K>_{WCK&mRA*gKt$cltTQvIs%j(>35rIe6p2JQ z9*=W2o8`Qd6N$u<&*%H@)~#Db|Mk9!nMDBGnE9+A2#1IWkw`?ibLWoG-Q6vBc6KiH z^z%->+2s}y?RxDSrm36I?K$uVHid*800f& z&S(I}0h|I*TUS@-2H*tXX>D!&#qakotEx)O%wDf|rM!dGpid<>dt;VntE7tE;R3=+UF^yiD=~5j|5?)#&T% zGaL@b1b~|SokQ34-_q&ySaWmpiG1e)0HV?8scbfzWo8~89?rJ3v>YoGjR?R4K+-f# zxO?|*)?%?-&StYdX5OB!)kalS-EO!0E5F~ro0&HPKt)Bxb;B^00KnyPZ7`Wk`vH`` zNFo8)1VAth1GBTU>B`E=A*gH|iHOXT zlapTqhyfUuBnbdu7zPwYDFI+96v;F*vm{AEb#=9Mbab>N6bkv;+S)GI?e=Al$8$KB z%XxZxdsjlCP^&D=XpS1ptXe0?B0Z833b@WQ3W2v{)>bnwpy8ef##+?%A`) z3t(wsVd09?>3lyPk5?*+5*;2Mz6KyZKR<5)a6%NtcbS=IW@dyyAP@u~7wRr&CX>0h z-j3trlBGb@Th!C-J?adGh@W-iZUGPa3{2}d9haO=9hgPDI?7vyp|>gwv^hK7c5 z0M&)Qi2wjzuh(HVn}2q>T;CTL7fVD0MN#5J)FXguY& z%$&(&V!>eW^x)uN*$W5c`r+cmi%L~h)nGgxS7cejMA=1_nNV^5jWK(==vgPNh=X)YQ};gM))kyiWT2 z`wvb}PX{$kBWC7wI-Ps;=+WiZF1m5!#)0YSY47@;k!4x;dcD2RPwv-3Pfw305C}}E zs!E!s@zBsvD!=$%FTK6JJ0CxOd~aZ2Kxt}fk^!6+@Mb6na1uZ!zZTv+e*(jbPWsZ} Rw7LKQ002ovPDHLkV1jztm}me1 literal 0 HcmV?d00001 diff --git a/src/main/resources/zoom-out.png b/src/main/resources/zoom-out.png new file mode 100644 index 0000000000000000000000000000000000000000..cbdc5018feec5fd781febe5aceb811cb29da50ae GIT binary patch literal 1366 zcmV-c1*!UpP)P000>X1^@s6#OZ}&00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy32;bRa{vGf6951U69E94oEQKA00(qQO+^Rk3lkOx9sCarRsaA5 ztVu*cR7l6Ql}|_?;C*)VrBur1)vSUSpcU1bONXWkOmL~FbZH1KuHKeco8wP#LOK; zbeV|$B%%@#m5In9B69wfZJOq@OeS+9old_tGc!~BqJSP|4l%PqL{7O}b_#_8WwTkz zX0w#f=h-w(CL(qmhnAO@=i~AC2a2M&p0|HZrA0nw{#FR_Av5pFX0zhaqetTI-Mi-P z+qc)k;czCIOzO;xy1F{q<#I`Gx4X%*tT$IyR?>dIKYsuIecH}N9T8owIG}VoO#=f1 zc6WF8{Jwqrt_1>tcK{qdapJ^F$B!RB9}0zr5{X34wryr+j>TdN*RNkc4?t`OIYdOW zMC4>L85$TEu)SXI1b_ zx$H!vQR?pQp05DJc74_~?MKrz%goH-a5!`2%9VGk)kpwN1CUMA6cZB@=IZL|z0uLp z2s3+`xna}O$jmMPXm4*1S(dc~0Q>jvZ*aTaX93i21(7S~Kyn-hv$L}~pU*dZ=FFJ@ z5nZxvdvipkTrM{PAOhe?O-)S-K!?ZUf#Wzw0W<)}Z3U6mZ90x)H8(fUGjpSD+o#sn z*8Ce^7D9+vEOrn;9>8C+EbEnZSeDgVImlZ&Ni#D`k|g!?^vL7mwz>!>yp8NhDflp`l6(w@c(vX1>SFr0crV-`~$&U0vT) zX0m0$-b^NQ!*Lw4ZJQH`MDD?Z2cJC$Fi1oNX6C7>Demj*dj{a`Y9A*9C>e%vtz0gj zZ)s^cB@drb)$OG1S@F`G(8o5{6-LB9Vw{n%39b+dKDP{$&Dy2Y??y4}ezy z90bs~F-4I`>t|-c3?4(9UMtW3L9p40sDvHvz)1a4CRgG>0 z#pCg@iu0Y5q9}*gL55*)I2_gie2<-$q9|SQczi4z4(k^$Ud#gcTHyatBY-af6af76 Y54}DLPadG_6951J07*qoM6N<$g0EF(JOBUy literal 0 HcmV?d00001