Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add FlatLaf GUi scaling to MHQ #4990

Merged
merged 7 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions MekHQ/src/mekhq/MekHQ.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import megamek.server.Server;
import megamek.server.totalwarfare.TWGameManager;
import megameklab.MegaMekLab;
import megameklab.util.CConfig;
import mekhq.campaign.Campaign;
import mekhq.campaign.CampaignController;
import mekhq.campaign.Kill;
Expand Down Expand Up @@ -173,6 +174,8 @@ private MekHQ() {
* At startup create and show the main frame of the application.
*/
protected void startup() {
updateGuiScaling(); // also sets the look-and-feel

// Setup user preferences
MegaMek.getMMPreferences().loadFromFile(SuiteConstants.MM_PREFERENCES_FILE);
MegaMekLab.getMMLPreferences().loadFromFile(SuiteConstants.MML_PREFERENCES_FILE);
Expand Down Expand Up @@ -667,13 +670,7 @@ private static void setLookAndFeel(String themeName) {
addOSXKeyStrokes((InputMap) UIManager.get("TextArea.focusInputMap"));
}

for (final Frame frame : Frame.getFrames()) {
SwingUtilities.updateComponentTreeUI(frame);
}

for (Window window : Window.getWindows()) {
SwingUtilities.updateComponentTreeUI(window);
}
updateAfterUiChange();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e) {
logger.error(e, "setLookAndFeel()");
Expand All @@ -682,6 +679,25 @@ private static void setLookAndFeel(String themeName) {
SwingUtilities.invokeLater(runnable);
}

public static void updateGuiScaling() {
System.setProperty("flatlaf.uiScale", Double.toString(GUIPreferences.getInstance().getGUIScale()));
setLookAndFeel(GUIPreferences.getInstance().getUITheme());
updateAfterUiChange();
}

/**
* Updates all existing windows and frames. Use after a gui scale change or look-and-feel change.
*/
public static void updateAfterUiChange() {
for (Window window : Window.getWindows()) {
SwingUtilities.updateComponentTreeUI(window);
window.pack();
window.invalidate();
window.validate();
window.repaint();
}
}

private static class MekHqPropertyChangedListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
Expand Down
39 changes: 19 additions & 20 deletions MekHQ/src/mekhq/gui/CampaignGUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import megamek.client.generator.RandomUnitGenerator;
import megamek.client.ui.preferences.JWindowPreference;
import megamek.client.ui.preferences.PreferencesNode;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.GameOptionsDialog;
import megamek.client.ui.swing.UnitLoadingDialog;
import megamek.client.ui.swing.dialog.AbstractUnitSelectorDialog;
Expand Down Expand Up @@ -1061,7 +1062,7 @@ private void initTopButtons() {
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.fill = GridBagConstraints.NONE;
gridBagConstraints.weightx = 0.0;
gridBagConstraints.weightx = 1;
gridBagConstraints.weighty = 0.0;
gridBagConstraints.gridheight = 2;
gridBagConstraints.anchor = GridBagConstraints.WEST;
Expand All @@ -1072,14 +1073,11 @@ private void initTopButtons() {
btnGMMode.setToolTipText(resourceMap.getString("btnGMMode.toolTipText"));
btnGMMode.setSelected(getCampaign().isGM());
btnGMMode.addActionListener(e -> getCampaign().setGMMode(btnGMMode.isSelected()));
btnGMMode.setMinimumSize(new Dimension(150, 25));
btnGMMode.setPreferredSize(new Dimension(150, 25));
btnGMMode.setMaximumSize(new Dimension(150, 25));
gridBagConstraints = new GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 0;
gridBagConstraints.fill = GridBagConstraints.NONE;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
gridBagConstraints.weightx = 0;
gridBagConstraints.weighty = 0.0;
gridBagConstraints.anchor = GridBagConstraints.EAST;
gridBagConstraints.insets = new Insets(3, 3, 3, 3);
Expand All @@ -1088,25 +1086,22 @@ private void initTopButtons() {
btnOvertime = new JToggleButton(resourceMap.getString("btnOvertime.text"));
btnOvertime.setToolTipText(resourceMap.getString("btnOvertime.toolTipText"));
btnOvertime.addActionListener(evt -> getCampaign().setOvertime(btnOvertime.isSelected()));
btnOvertime.setMinimumSize(new Dimension(150, 25));
btnOvertime.setPreferredSize(new Dimension(150, 25));
btnOvertime.setMaximumSize(new Dimension(150, 25));
gridBagConstraints = new GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 1;
gridBagConstraints.fill = GridBagConstraints.NONE;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
gridBagConstraints.weightx = 0;
gridBagConstraints.weighty = 0.0;
gridBagConstraints.anchor = GridBagConstraints.EAST;
gridBagConstraints.insets = new Insets(3, 3, 3, 3);
btnPanel.add(btnOvertime, gridBagConstraints);

// This button uses a mnemonic that is unique and listed in the initMenu JavaDoc
JButton btnAdvanceDay = new JButton(resourceMap.getString("btnAdvanceDay.text"));
String padding = " ";
JButton btnAdvanceDay = new JButton(padding + resourceMap.getString("btnAdvanceDay.text") + padding);
btnAdvanceDay.setToolTipText(resourceMap.getString("btnAdvanceDay.toolTipText"));
btnAdvanceDay.addActionListener(evt -> getCampaignController().advanceDay());
btnAdvanceDay.setMnemonic(KeyEvent.VK_A);
btnAdvanceDay.setPreferredSize(new Dimension(250, 50));
gridBagConstraints = new GridBagConstraints();
gridBagConstraints.gridx = 2;
gridBagConstraints.gridy = 0;
Expand Down Expand Up @@ -1254,14 +1249,18 @@ private void refreshThemeChoices() {
menuThemes.removeAll();
JCheckBoxMenuItem miPlaf;
for (LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
miPlaf = new JCheckBoxMenuItem(laf.getName());
if (laf.getClassName().equalsIgnoreCase(MekHQ.getSelectedTheme().getValue())) {
miPlaf.setSelected(true);
}
// intentionally only limits the themes in the menu; as a last resort for GUI problems, other laf can be used by
// hand-editing mhq.preferences
if (GUIPreferences.isSupportedLookAndFeel(laf)) {
miPlaf = new JCheckBoxMenuItem(laf.getName());
if (laf.getClassName().equalsIgnoreCase(MekHQ.getSelectedTheme().getValue())) {
miPlaf.setSelected(true);
}

menuThemes.add(miPlaf);
miPlaf.setActionCommand(laf.getClassName());
miPlaf.addActionListener(this::changeTheme);
menuThemes.add(miPlaf);
miPlaf.setActionCommand(laf.getClassName());
miPlaf.addActionListener(this::changeTheme);
}
}
}

Expand Down
5 changes: 3 additions & 2 deletions MekHQ/src/mekhq/gui/HangarTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import megamek.client.ui.preferences.JComboBoxPreference;
import megamek.client.ui.preferences.JTablePreference;
import megamek.client.ui.preferences.PreferencesNode;
import megamek.client.ui.swing.util.UIUtil;
import megamek.common.Entity;
import megamek.common.UnitType;
import megamek.common.event.Subscribe;
Expand Down Expand Up @@ -291,7 +292,7 @@ public static String getUnitViewName(int group) {
public void changeUnitView() {
int view = choiceUnitView.getSelectedIndex();
XTableColumnModel columnModel = (XTableColumnModel) unitTable.getColumnModel();
unitTable.setRowHeight(15);
unitTable.setRowHeight(UIUtil.scaleForGUI(15));

// set the renderer
TableColumn column;
Expand All @@ -311,7 +312,7 @@ public void changeUnitView() {
}

if (view == UV_GRAPHIC) {
unitTable.setRowHeight(80);
unitTable.setRowHeight(UIUtil.scaleForGUI(80));
columnModel.setColumnVisible(columnModel.getColumnByModelIndex(UnitTableModel.COL_NAME), false);
columnModel.setColumnVisible(columnModel.getColumnByModelIndex(UnitTableModel.COL_TYPE), false);
columnModel.setColumnVisible(columnModel.getColumnByModelIndex(UnitTableModel.COL_WCLASS), true);
Expand Down
3 changes: 2 additions & 1 deletion MekHQ/src/mekhq/gui/PersonnelTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import megamek.client.ui.preferences.JTablePreference;
import megamek.client.ui.preferences.JToggleButtonPreference;
import megamek.client.ui.preferences.PreferencesNode;
import megamek.client.ui.swing.util.UIUtil;
import megamek.common.event.Subscribe;
import megamek.logging.MMLogger;
import mekhq.MHQOptionsChangedEvent;
Expand Down Expand Up @@ -297,7 +298,7 @@ private void changePersonnelView() {
? PersonnelTabView.GENERAL
: choicePersonView.getSelectedItem();
final XTableColumnModel columnModel = (XTableColumnModel) getPersonnelTable().getColumnModel();
getPersonnelTable().setRowHeight(15);
getPersonnelTable().setRowHeight(UIUtil.scaleForGUI(15));

// set the renderer
for (final PersonnelTableModelColumn column : PersonnelTableModel.PERSONNEL_COLUMNS) {
Expand Down
7 changes: 4 additions & 3 deletions MekHQ/src/mekhq/gui/RepairTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import megamek.client.ui.models.XTableColumnModel;
import megamek.client.ui.preferences.JTablePreference;
import megamek.client.ui.preferences.PreferencesNode;
import megamek.client.ui.swing.util.UIUtil;
import megamek.common.MekView;
import megamek.common.TargetRoll;
import megamek.common.event.Subscribe;
Expand Down Expand Up @@ -279,9 +280,9 @@ public void initTab() {
scrollTechTable.setPreferredSize(new Dimension(300, 300));

panDoTask = new JPanel(new GridBagLayout());
panDoTask.setMinimumSize(new Dimension(100, 100));
panDoTask.setMinimumSize(UIUtil.scaleForGUI(100, 100));
panDoTask.setName("panelDoTask");
panDoTask.setPreferredSize(new Dimension(100, 100));
panDoTask.setPreferredSize(UIUtil.scaleForGUI(100, 100));

btnDoTask = new JButton(resourceMap.getString("btnDoTask.text"));
btnDoTask.setToolTipText(resourceMap.getString("btnDoTask.toolTipText"));
Expand Down Expand Up @@ -744,7 +745,7 @@ public boolean include(Entry<? extends TechTableModel, ? extends Integer> entry)

/**
* Focuses on the unit with the given ID if it exists.
*
*
* @param id The unique identifier of the unit.
* @return A value indicating whether or not the unit was focused.
*/
Expand Down
27 changes: 27 additions & 0 deletions MekHQ/src/mekhq/gui/dialog/MHQOptionsDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import megamek.client.ui.displayWrappers.FontDisplay;
import megamek.client.ui.swing.ColourSelectorButton;
import megamek.client.ui.swing.CommonSettingsDialog;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.HelpDialog;
import megamek.common.preference.PreferenceManager;
import megamek.logging.MMLogger;
Expand All @@ -45,6 +46,7 @@
import java.net.URL;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Hashtable;
import java.util.Objects;

/**
Expand Down Expand Up @@ -72,6 +74,7 @@ public class MHQOptionsDialog extends AbstractMHQButtonDialog {
private JCheckBox optionHistoricalDailyLog;
private JCheckBox chkCompanyGeneratorStartup;
private JCheckBox chkShowCompanyGenerator;
private final JSlider guiScale = new JSlider();

// region Command Center Tab
private JCheckBox optionCommandCenterUseUnitMarket;
Expand Down Expand Up @@ -221,6 +224,25 @@ protected Container createCenterPane() {
}

private JPanel createDisplayTab() {
guiScale.setMajorTickSpacing(3);
guiScale.setMinimum(7);
guiScale.setMaximum(24);
Hashtable<Integer, JComponent> table = new Hashtable<>();
table.put(7, new JLabel("70%"));
table.put(10, new JLabel("100%"));
table.put(16, new JLabel("160%"));
table.put(22, new JLabel("220%"));
guiScale.setLabelTable(table);
guiScale.setPaintTicks(true);
guiScale.setPaintLabels(true);
guiScale.setValue((int) (GUIPreferences.getInstance().getGUIScale() * 10));
guiScale.setToolTipText(Messages.getString("CommonSettingsDialog.guiScaleTT"));
JLabel guiScaleLabel = new JLabel(Messages.getString("CommonSettingsDialog.guiScale"));
JPanel scaleLine = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
scaleLine.add(guiScaleLabel);
scaleLine.add(Box.createHorizontalStrut(5));
scaleLine.add(guiScale);

// Initialize Components Used in ActionListeners
final JLabel lblInterstellarMapShowJumpRadiusMinimumZoom = new JLabel();
final JLabel lblInterstellarMapShowPlanetaryAcquisitionRadiusMinimumZoom = new JLabel();
Expand Down Expand Up @@ -410,6 +432,7 @@ public Component getListCellRendererComponent(final JList<?> list, final Object
.addComponent(optionLongDisplayDateFormat)
.addComponent(labelLongDisplayDateFormatExample,
Alignment.TRAILING))
.addComponent(scaleLine)
.addComponent(optionHistoricalDailyLog)
.addComponent(chkCompanyGeneratorStartup)
.addComponent(chkShowCompanyGenerator)
Expand Down Expand Up @@ -449,6 +472,7 @@ public Component getListCellRendererComponent(final JList<?> list, final Object
.addComponent(labelLongDisplayDateFormat)
.addComponent(optionLongDisplayDateFormat)
.addComponent(labelLongDisplayDateFormatExample))
.addComponent(scaleLine)
.addComponent(optionHistoricalDailyLog)
.addComponent(chkCompanyGeneratorStartup)
.addComponent(chkShowCompanyGenerator)
Expand Down Expand Up @@ -1256,6 +1280,8 @@ public Component getListCellRendererComponent(final JList<?> list, final Object

@Override
protected void okAction() {
GUIPreferences.getInstance().setValue(GUIPreferences.GUI_SCALE, 0.1 * guiScale.getValue());
MekHQ.updateGuiScaling();
if (validateDateFormat(optionDisplayDateFormat.getText())) {
MekHQ.getMHQOptions().setDisplayDateFormat(optionDisplayDateFormat.getText());
}
Expand Down Expand Up @@ -1401,6 +1427,7 @@ protected void okAction() {
}

private void setInitialState() {
guiScale.setValue((int) (GUIPreferences.getInstance().getGUIScale() * 10));
optionDisplayDateFormat.setText(MekHQ.getMHQOptions().getDisplayDateFormat());
optionLongDisplayDateFormat.setText(MekHQ.getMHQOptions().getLongDisplayDateFormat());
optionHistoricalDailyLog.setSelected(MekHQ.getMHQOptions().getHistoricalDailyLog());
Expand Down
3 changes: 2 additions & 1 deletion MekHQ/src/mekhq/gui/enums/PersonnelTableModelColumn.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
package mekhq.gui.enums;

import megamek.client.ui.swing.util.UIUtil;
import megamek.codeUtilities.StringUtility;
import megamek.common.Entity;
import megamek.common.Jumpship;
Expand Down Expand Up @@ -806,7 +807,7 @@ public boolean isVisible(final Campaign campaign, final PersonnelTabView view,
final JTable table) {
return switch (view) {
case GRAPHIC -> {
table.setRowHeight(80);
table.setRowHeight(UIUtil.scaleForGUI(80));
yield switch (this) {
case PERSON, UNIT_ASSIGNMENT, FORCE -> true;
default -> false;
Expand Down