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

Fix #6546: Fixed Display of Misc Award Images; Upgraded Award Image Scaling #6583

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
48 changes: 17 additions & 31 deletions MekHQ/src/mekhq/gui/view/PersonViewPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import static mekhq.campaign.personnel.Person.getLoyaltyName;
import static mekhq.campaign.personnel.turnoverAndRetention.Fatigue.getEffectiveFatigue;
import static mekhq.utilities.ImageUtilities.addTintToImageIcon;
import static mekhq.utilities.ImageUtilities.scaleImage;
import static org.jfree.chart.ChartColor.DARK_BLUE;
import static org.jfree.chart.ChartColor.DARK_RED;

Expand Down Expand Up @@ -94,8 +95,6 @@
import mekhq.gui.utilities.MarkdownRenderer;
import mekhq.gui.utilities.WrapLayout;

import static megamek.client.ui.WrapLayout.wordWrap;

/**
* A custom panel that gets filled in with goodies from a Person record
*
Expand All @@ -104,7 +103,7 @@
public class PersonViewPanel extends JScrollablePanel {
private static final MMLogger logger = MMLogger.create(PersonViewPanel.class);

private static final int MAX_NUMBER_OF_RIBBON_AWARDS_PER_ROW = 4;
private static final int MAX_NUMBER_OF_RIBBON_AWARDS_PER_ROW = 3;

private final CampaignGUI gui;

Expand Down Expand Up @@ -408,13 +407,16 @@ private Box drawRibbons() {
int awardTierCount = getAwardTierCount(award, maximumTiers);

String ribbonFileName = award.getRibbonFileName(awardTierCount);
String directory = award.getSet() + "/ribbons/";

ribbon = (Image) MHQStaticDirectoryManager.getAwardIcons()
.getItem(award.getSet() + "/ribbons/", ribbonFileName);
ribbon = (Image) MHQStaticDirectoryManager.getAwardIcons().getItem(directory, ribbonFileName);
if (ribbon == null) {
logger.warn("No ribbon icon found for award: {}", directory + ribbonFileName);
continue;
}
ribbon = ribbon.getScaledInstance(25, 8, Image.SCALE_DEFAULT);

ribbon = scaleImage(ribbon, 8, false);

ribbonLabel.setIcon(new ImageIcon(ribbon));
ribbonLabel.setToolTipText(award.getTooltip(campaign.getCampaignOptions(), person));
rowRibbonsBox.add(ribbonLabel, 0);
Expand Down Expand Up @@ -481,23 +483,15 @@ private JPanel drawMedals() {
int awardTierCount = getAwardTierCount(award, maximumTiers);

String medalFileName = award.getMedalFileName(awardTierCount);
String directory = award.getSet() + "/medals/";

medal = (Image) MHQStaticDirectoryManager.getAwardIcons()
.getItem(award.getSet() + "/medals/", medalFileName);
medal = (Image) MHQStaticDirectoryManager.getAwardIcons().getItem(directory, medalFileName);
if (medal == null) {
logger.warn("No medal icon found for award: {}", directory + medalFileName);
continue;
}

int width = medal.getWidth(null);
int height = medal.getHeight(null);

if (width == height) {
medal = medal.getScaledInstance(40, 40, Image.SCALE_FAST);
} else if (width < height) {
medal = medal.getScaledInstance(20, 40, Image.SCALE_FAST);
} else {
medal = medal.getScaledInstance(40, 20, Image.SCALE_FAST);
}
medal = scaleImage(medal, 40, false);

medalLabel.setIcon(new ImageIcon(medal));
medalLabel.setToolTipText(award.getTooltip(campaign.getCampaignOptions(), person));
Expand Down Expand Up @@ -529,27 +523,19 @@ private JPanel drawMiscAwards() {

Image misc;
try {
int maximumTiers = award.getNumberOfMedalFiles();
int maximumTiers = award.getNumberOfMiscFiles();
int awardTierCount = getAwardTierCount(award, maximumTiers);

String miscFileName = award.getMiscFileName(awardTierCount);
String directory = award.getSet() + "/misc/";

misc = (Image) MHQStaticDirectoryManager.getAwardIcons()
.getItem(award.getSet() + "/misc/", miscFileName);
misc = (Image) MHQStaticDirectoryManager.getAwardIcons().getItem(directory, miscFileName);
if (misc == null) {
logger.warn("No misc icon found for award: {}", directory + miscFileName);
continue;
}

int width = misc.getWidth(null);
int height = misc.getHeight(null);

if (width == height) {
misc = misc.getScaledInstance(40, 40, Image.SCALE_FAST);
} else if (width < height) {
misc = misc.getScaledInstance(20, 40, Image.SCALE_FAST);
} else {
misc = misc.getScaledInstance(40, 20, Image.SCALE_FAST);
}
misc = scaleImage(misc, 40, false);

miscLabel.setIcon(new ImageIcon(misc));
miscLabel.setToolTipText(award.getTooltip(campaign.getCampaignOptions(), person));
Expand Down
71 changes: 68 additions & 3 deletions MekHQ/src/mekhq/utilities/ImageUtilities.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,72 @@ public static ImageIcon scaleImageIcon(ImageIcon icon, int size, boolean scaleBy
width = (int) Math.ceil((double) height * icon.getIconWidth() / icon.getIconHeight());
}

// Create a new BufferedImage with the desired dimensions
BufferedImage scaledImage = getBufferedImage(icon.getImage(), width, height);

return new ImageIcon(scaledImage);
}

/**
* Scales an {@link Image} proportionally based on either the specified width or height.
*
* <p>This method preserves the aspect ratio of the original image while resizing. The size to scale
* is determined by the {@code size} parameter, and whether scaling is based on width or height is controlled by the
* {@code scaleByWidth} flag.</p>
*
* <p>If the provided {@link Image} is {@code null}, an empty {@link Image} will be returned, and
* an error will be logged.</p>
*
* @param image The {@link Image} to be scaled. If {@code null}, an empty {@link Image} is returned.
* @param size The target size to scale to, either width or height depending on the {@code scaleByWidth}
* flag. This value will be scaled for the GUI using {@link UIUtil#scaleForGUI(int)}.
* @param scaleByWidth A {@code boolean} flag to determine the scaling mode:
* <ul>
* <li>If {@code true}, scales the image by the given width, and calculates the height
* proportionally.</li>
* <li>If {@code false}, scales the image by the given height, and calculates the width
* proportionally.</li>
* </ul>
*
* @return A scaled {@link Image}, resized to the specified target dimension while maintaining the aspect ratio. If
* the provided {@link Image} is {@code null}, returns an empty {@link Image}.
*
* @author Illiani
* @since 0.50.05
*/
public static Image scaleImage(Image image, int size, boolean scaleByWidth) {
if (image == null) {
logger.error(new NullPointerException(),
"Image is null in scaleImage(Image, int, boolean). Returning a placeholder image.");
return new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
}

int width, height;

if (scaleByWidth) {
width = Math.max(1, UIUtil.scaleForGUI(size));
height = (int) Math.ceil((double) width * image.getHeight(null) / image.getWidth(null));
} else {
height = Math.max(1, UIUtil.scaleForGUI(size));
width = (int) Math.ceil((double) height * image.getWidth(null) / image.getHeight(null));
}

return getBufferedImage(image, width, height);
}

/**
* Creates a high-quality, scaled {@link BufferedImage} with the specified dimensions.
*
* @param image The source {@link Image} to be scaled. Must not be {@code null}.
* @param width The target width for the scaled image.
* @param height The target height for the scaled image.
*
* @return A {@link BufferedImage} scaled to the specified dimensions with high-quality rendering.
*
* @author Illiani
* @since 0.50.05
*/
private static BufferedImage getBufferedImage(Image image, int width, int height) {
// Create a new BufferedImage with the desired dimensions
BufferedImage scaledImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

Expand All @@ -103,10 +169,9 @@ public static ImageIcon scaleImageIcon(ImageIcon icon, int size, boolean scaleBy
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

// Draw the scaled image with high-quality rendering
g2d.drawImage(icon.getImage(), 0, 0, width, height, null);
g2d.drawImage(image, 0, 0, width, height, null);
g2d.dispose();

return new ImageIcon(scaledImage);
return scaledImage;
}

/**
Expand Down
Loading