GUI, preferences: improved theme switch at runtime (fixed skip and step buttons update);

This commit is contained in:
Oleg Agafonov 2024-07-05 18:11:09 +04:00
parent 6c0f7ebb90
commit 9864cdd46c
5 changed files with 186 additions and 155 deletions

View file

@ -353,6 +353,10 @@ public class HoverButton extends JPanel implements MouseListener {
this.isSelected = !this.isSelected; this.isSelected = !this.isSelected;
} }
public String getText() {
return this.text;
}
public void setText(String text) { public void setText(String text) {
this.text = text; this.text = text;
} }
@ -365,13 +369,17 @@ public class HoverButton extends JPanel implements MouseListener {
this.drawSet = true; this.drawSet = true;
} }
public void update(String text, Image image) {
update(text, image, this.hoverImage, this.selectedImage, this.disabledImage, this.imageSize);
}
public void update(String text, Image image, Image hover, Image selected, Image disabled, Rectangle size) { public void update(String text, Image image, Image hover, Image selected, Image disabled, Rectangle size) {
this.text = text;
this.image = image; this.image = image;
this.hoverImage = hover; this.hoverImage = hover;
this.selectedImage = selected; this.selectedImage = selected;
this.disabledImage = disabled; this.disabledImage = disabled;
this.imageSize = size; this.imageSize = size;
this.text = text;
repaint(); repaint();
} }

View file

@ -1,28 +1,41 @@
package mage.client.components; package mage.client.components;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JButton;
import mage.client.dialog.PreferencesDialog; import mage.client.dialog.PreferencesDialog;
import javax.swing.*;
import java.awt.*;
/** /**
* GUI component: button with hotkey info on it
* *
* @author Campbell Suter <znix@znix.xyz> * @author Campbell Suter <znix@znix.xyz>, JayDi85
*/ */
public class KeyboundButton extends JButton { public class KeyboundButton extends JButton {
private final String text; private final String key;
private boolean showKey;
private String drawingText;
private static final Font keyFont = new Font(Font.SANS_SERIF, Font.BOLD, 13); private static final Font keyFont = new Font(Font.SANS_SERIF, Font.BOLD, 13);
private boolean tinting = false; private boolean tinting = false;
public KeyboundButton(String key, boolean drawText) { public KeyboundButton(String key, boolean showKey) {
if (drawText) { this.key = key;
text = PreferencesDialog.getCachedKeyText(key); this.showKey = showKey;
} else { updateDrawingText();
text = "";
} }
private void updateDrawingText() {
if (this.showKey) {
this.drawingText = PreferencesDialog.getCachedKeyText(key);
} else {
this.drawingText = "";
}
}
public void setShowKey(boolean showKey) {
this.showKey = showKey;
updateDrawingText();
} }
@Override @Override
@ -34,17 +47,17 @@ public class KeyboundButton extends JButton {
if (tinting) { if (tinting) {
sg.setColor(new Color(0, 0, 0, 32)); sg.setColor(new Color(0, 0, 0, 32));
sg.fillRoundRect(2, 2, getWidth() - 4 , getHeight() - 4, 6, 6); sg.fillRoundRect(2, 2, getWidth() - 4, getHeight() - 4, 6, 6);
} }
sg.setColor(tinting ? Color.lightGray : Color.white); sg.setColor(tinting ? Color.lightGray : Color.white);
if (!text.isEmpty()) { if (!this.drawingText.isEmpty()) {
sg.setFont(keyFont); sg.setFont(keyFont);
int textWidth = sg.getFontMetrics(keyFont).stringWidth(text); int textWidth = sg.getFontMetrics(keyFont).stringWidth(this.drawingText);
int centerX = (getWidth() - textWidth) / 2; int centerX = (getWidth() - textWidth) / 2;
sg.drawString(text, centerX, 28); sg.drawString(this.drawingText, centerX, 28);
} }
} finally { } finally {
sg.dispose(); sg.dispose();

View file

@ -106,7 +106,7 @@ public final class GamePanel extends javax.swing.JPanel {
private final Map<String, Card> loadedCards = new HashMap<>(); private final Map<String, Card> loadedCards = new HashMap<>();
private int storedHeight; private int storedHeight;
private Map<String, HoverButton> hoverButtons; private final Map<String, HoverButton> phaseButtons = new LinkedHashMap<>(); // phase name, phase button
private MageDialogState choiceWindowState; private MageDialogState choiceWindowState;
@ -452,6 +452,39 @@ public final class GamePanel extends javax.swing.JPanel {
pnlShortCuts.setPreferredSize(newDimension); pnlShortCuts.setPreferredSize(newDimension);
pnlShortCuts.setMinimumSize(newDimension); pnlShortCuts.setMinimumSize(newDimension);
pnlShortCuts.setMaximumSize(newDimension); pnlShortCuts.setMaximumSize(newDimension);
reloadThemeRelatedGraphic();
}
private void reloadThemeRelatedGraphic() {
// skip buttons
btnCancelSkip.setIcon(new ImageIcon(ImageManagerImpl.instance.getCancelSkipButtonImage()));
btnSkipToNextTurn.setIcon(new ImageIcon(ImageManagerImpl.instance.getSkipNextTurnButtonImage()));
btnSkipToEndTurn.setIcon(new ImageIcon(ImageManagerImpl.instance.getSkipEndTurnButtonImage()));
btnSkipToEndStepBeforeYourTurn.setIcon(new ImageIcon(ImageManagerImpl.instance.getSkipEndStepBeforeYourTurnButtonImage()));
btnSkipToYourTurn.setIcon(new ImageIcon(ImageManagerImpl.instance.getSkipYourNextTurnButtonImage()));
btnSkipToNextMain.setIcon(new ImageIcon(ImageManagerImpl.instance.getSkipMainButtonImage()));
btnSkipStack.setIcon(new ImageIcon(ImageManagerImpl.instance.getSkipStackButtonImage()));
btnConcede.setIcon(new ImageIcon(ImageManagerImpl.instance.getConcedeButtonImage()));
btnToggleMacro.setIcon(new ImageIcon(ImageManagerImpl.instance.getToggleRecordMacroButtonImage()));
btnSwitchHands.setIcon(new ImageIcon(ImageManagerImpl.instance.getSwitchHandsButtonImage()));
btnStopWatching.setIcon(new ImageIcon(ImageManagerImpl.instance.getStopWatchButtonImage()));
// hotkeys for skip buttons
boolean displayButtonText = PreferencesDialog.getCurrentTheme().isShortcutsVisibleForSkipButtons();
btnCancelSkip.setShowKey(displayButtonText);
btnSkipToNextTurn.setShowKey(displayButtonText);
btnSkipToEndTurn.setShowKey(displayButtonText);
btnSkipToEndStepBeforeYourTurn.setShowKey(displayButtonText);
btnSkipToYourTurn.setShowKey(displayButtonText);
btnSkipToNextMain.setShowKey(displayButtonText);
btnSkipStack.setShowKey(displayButtonText);
btnToggleMacro.setShowKey(displayButtonText);
// phase buttons
phaseButtons.forEach((phaseName, phaseButton) -> {
phaseButton.update(phaseButton.getText(), ImageManagerImpl.instance.getPhaseImage(phaseName));
});
} }
private void saveDividerLocations() { private void saveDividerLocations() {
@ -1260,8 +1293,8 @@ public final class GamePanel extends javax.swing.JPanel {
} }
private void updateButton(String name) { private void updateButton(String name) {
if (hoverButtons.containsKey(name)) { if (phaseButtons.containsKey(name)) {
currentStep = hoverButtons.get(name); currentStep = phaseButtons.get(name);
prevPoint = currentStep.getLocation(); prevPoint = currentStep.getLocation();
currentStep.setLocation(prevPoint.x - 15, prevPoint.y); currentStep.setLocation(prevPoint.x - 15, prevPoint.y);
} }
@ -1979,7 +2012,6 @@ public final class GamePanel extends javax.swing.JPanel {
txtHoldPriority.setVisible(false); txtHoldPriority.setVisible(false);
boolean displayButtonText = PreferencesDialog.getCurrentTheme().isShortcutsVisibleForSkipButtons(); boolean displayButtonText = PreferencesDialog.getCurrentTheme().isShortcutsVisibleForSkipButtons();
btnToggleMacro = new KeyboundButton(KEY_CONTROL_TOGGLE_MACRO, displayButtonText); btnToggleMacro = new KeyboundButton(KEY_CONTROL_TOGGLE_MACRO, displayButtonText);
btnCancelSkip = new KeyboundButton(KEY_CONTROL_CANCEL_SKIP, displayButtonText); // F3 btnCancelSkip = new KeyboundButton(KEY_CONTROL_CANCEL_SKIP, displayButtonText); // F3
btnSkipToNextTurn = new KeyboundButton(KEY_CONTROL_NEXT_TURN, displayButtonText); // F4 btnSkipToNextTurn = new KeyboundButton(KEY_CONTROL_NEXT_TURN, displayButtonText); // F4
@ -2081,7 +2113,6 @@ public final class GamePanel extends javax.swing.JPanel {
btnToggleMacro.setContentAreaFilled(false); btnToggleMacro.setContentAreaFilled(false);
btnToggleMacro.setBorder(new EmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE)); btnToggleMacro.setBorder(new EmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE));
btnToggleMacro.setIcon(new ImageIcon(ImageManagerImpl.instance.getToggleRecordMacroButtonImage()));
btnToggleMacro.setToolTipText("Toggle Record Macro (" btnToggleMacro.setToolTipText("Toggle Record Macro ("
+ getCachedKeyText(KEY_CONTROL_TOGGLE_MACRO) + ")."); + getCachedKeyText(KEY_CONTROL_TOGGLE_MACRO) + ").");
btnToggleMacro.setFocusable(false); btnToggleMacro.setFocusable(false);
@ -2109,10 +2140,10 @@ public final class GamePanel extends javax.swing.JPanel {
}); });
// SKIP BUTTONS (button's hint/state is dynamic) // SKIP BUTTONS (button's hint/state is dynamic)
// button icons setup in setGUISize
btnCancelSkip.setContentAreaFilled(false); btnCancelSkip.setContentAreaFilled(false);
btnCancelSkip.setBorder(new EmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE)); btnCancelSkip.setBorder(new EmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE));
btnCancelSkip.setIcon(new ImageIcon(ImageManagerImpl.instance.getCancelSkipButtonImage()));
btnCancelSkip.setToolTipText("CANCEL all skips"); btnCancelSkip.setToolTipText("CANCEL all skips");
btnCancelSkip.setFocusable(false); btnCancelSkip.setFocusable(false);
btnCancelSkip.addMouseListener(new FirstButtonMousePressedAction(e -> btnCancelSkip.addMouseListener(new FirstButtonMousePressedAction(e ->
@ -2120,7 +2151,6 @@ public final class GamePanel extends javax.swing.JPanel {
btnSkipToNextTurn.setContentAreaFilled(false); btnSkipToNextTurn.setContentAreaFilled(false);
btnSkipToNextTurn.setBorder(new EmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE)); btnSkipToNextTurn.setBorder(new EmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE));
btnSkipToNextTurn.setIcon(new ImageIcon(ImageManagerImpl.instance.getSkipNextTurnButtonImage()));
btnSkipToNextTurn.setToolTipText("dynamic"); btnSkipToNextTurn.setToolTipText("dynamic");
btnSkipToNextTurn.setFocusable(false); btnSkipToNextTurn.setFocusable(false);
btnSkipToNextTurn.addMouseListener(new FirstButtonMousePressedAction(e -> btnSkipToNextTurn.addMouseListener(new FirstButtonMousePressedAction(e ->
@ -2138,7 +2168,6 @@ public final class GamePanel extends javax.swing.JPanel {
btnSkipToEndTurn.setContentAreaFilled(false); btnSkipToEndTurn.setContentAreaFilled(false);
btnSkipToEndTurn.setBorder(new EmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE)); btnSkipToEndTurn.setBorder(new EmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE));
btnSkipToEndTurn.setIcon(new ImageIcon(ImageManagerImpl.instance.getSkipEndTurnButtonImage()));
btnSkipToEndTurn.setToolTipText("dynamic"); btnSkipToEndTurn.setToolTipText("dynamic");
btnSkipToEndTurn.setFocusable(false); btnSkipToEndTurn.setFocusable(false);
btnSkipToEndTurn.addMouseListener(new FirstButtonMousePressedAction(e -> btnSkipToEndTurn.addMouseListener(new FirstButtonMousePressedAction(e ->
@ -2166,7 +2195,6 @@ public final class GamePanel extends javax.swing.JPanel {
btnSkipToNextMain.setContentAreaFilled(false); btnSkipToNextMain.setContentAreaFilled(false);
btnSkipToNextMain.setBorder(new EmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE)); btnSkipToNextMain.setBorder(new EmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE));
btnSkipToNextMain.setIcon(new ImageIcon(ImageManagerImpl.instance.getSkipMainButtonImage()));
btnSkipToNextMain.setToolTipText("dynamic"); btnSkipToNextMain.setToolTipText("dynamic");
btnSkipToNextMain.setFocusable(false); btnSkipToNextMain.setFocusable(false);
btnSkipToNextMain.addMouseListener(new FirstButtonMousePressedAction(e -> btnSkipToNextMain.addMouseListener(new FirstButtonMousePressedAction(e ->
@ -2184,7 +2212,6 @@ public final class GamePanel extends javax.swing.JPanel {
btnSkipToYourTurn.setContentAreaFilled(false); btnSkipToYourTurn.setContentAreaFilled(false);
btnSkipToYourTurn.setBorder(new EmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE)); btnSkipToYourTurn.setBorder(new EmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE));
btnSkipToYourTurn.setIcon(new ImageIcon(ImageManagerImpl.instance.getSkipYourNextTurnButtonImage()));
btnSkipToYourTurn.setToolTipText("dynamic"); btnSkipToYourTurn.setToolTipText("dynamic");
btnSkipToYourTurn.setFocusable(false); btnSkipToYourTurn.setFocusable(false);
btnSkipToYourTurn.addMouseListener(new FirstButtonMousePressedAction(e -> btnSkipToYourTurn.addMouseListener(new FirstButtonMousePressedAction(e ->
@ -2202,7 +2229,6 @@ public final class GamePanel extends javax.swing.JPanel {
btnSkipToEndStepBeforeYourTurn.setContentAreaFilled(false); btnSkipToEndStepBeforeYourTurn.setContentAreaFilled(false);
btnSkipToEndStepBeforeYourTurn.setBorder(new EmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE)); btnSkipToEndStepBeforeYourTurn.setBorder(new EmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE));
btnSkipToEndStepBeforeYourTurn.setIcon(new ImageIcon(ImageManagerImpl.instance.getSkipEndStepBeforeYourTurnButtonImage()));
btnSkipToEndStepBeforeYourTurn.setToolTipText("dynamic"); btnSkipToEndStepBeforeYourTurn.setToolTipText("dynamic");
btnSkipToEndStepBeforeYourTurn.setFocusable(false); btnSkipToEndStepBeforeYourTurn.setFocusable(false);
btnSkipToEndStepBeforeYourTurn.addMouseListener(new FirstButtonMousePressedAction(e -> btnSkipToEndStepBeforeYourTurn.addMouseListener(new FirstButtonMousePressedAction(e ->
@ -2220,7 +2246,6 @@ public final class GamePanel extends javax.swing.JPanel {
btnSkipStack.setContentAreaFilled(false); btnSkipStack.setContentAreaFilled(false);
btnSkipStack.setBorder(new EmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE)); btnSkipStack.setBorder(new EmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE));
btnSkipStack.setIcon(new ImageIcon(ImageManagerImpl.instance.getSkipStackButtonImage()));
btnSkipStack.setToolTipText("dynamic"); btnSkipStack.setToolTipText("dynamic");
btnSkipStack.setFocusable(false); btnSkipStack.setFocusable(false);
btnSkipStack.addMouseListener(new FirstButtonMousePressedAction(e -> btnSkipStack.addMouseListener(new FirstButtonMousePressedAction(e ->
@ -2238,7 +2263,6 @@ public final class GamePanel extends javax.swing.JPanel {
btnConcede.setContentAreaFilled(false); btnConcede.setContentAreaFilled(false);
btnConcede.setBorder(new EmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE)); btnConcede.setBorder(new EmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE));
btnConcede.setIcon(new ImageIcon(ImageManagerImpl.instance.getConcedeButtonImage()));
btnConcede.setToolTipText("CONCEDE current game"); btnConcede.setToolTipText("CONCEDE current game");
btnConcede.setFocusable(false); btnConcede.setFocusable(false);
btnConcede.addMouseListener(new FirstButtonMousePressedAction(e -> btnConcede.addMouseListener(new FirstButtonMousePressedAction(e ->
@ -2368,7 +2392,6 @@ public final class GamePanel extends javax.swing.JPanel {
btnSwitchHands.setContentAreaFilled(false); btnSwitchHands.setContentAreaFilled(false);
btnSwitchHands.setBorder(new EmptyBorder(0, 0, 0, 0)); btnSwitchHands.setBorder(new EmptyBorder(0, 0, 0, 0));
btnSwitchHands.setIcon(new ImageIcon(ImageManagerImpl.instance.getSwitchHandsButtonImage()));
btnSwitchHands.setFocusable(false); btnSwitchHands.setFocusable(false);
btnSwitchHands.setToolTipText("Switch between your hand cards and hand cards of controlled players."); btnSwitchHands.setToolTipText("Switch between your hand cards and hand cards of controlled players.");
btnSwitchHands.addMouseListener(new FirstButtonMousePressedAction(e -> btnSwitchHands.addMouseListener(new FirstButtonMousePressedAction(e ->
@ -2376,7 +2399,6 @@ public final class GamePanel extends javax.swing.JPanel {
btnStopWatching.setContentAreaFilled(false); btnStopWatching.setContentAreaFilled(false);
btnStopWatching.setBorder(new EmptyBorder(0, 0, 0, 0)); btnStopWatching.setBorder(new EmptyBorder(0, 0, 0, 0));
btnStopWatching.setIcon(new ImageIcon(ImageManagerImpl.instance.getStopWatchButtonImage()));
btnStopWatching.setFocusable(false); btnStopWatching.setFocusable(false);
btnStopWatching.setToolTipText("Stop watching this game."); btnStopWatching.setToolTipText("Stop watching this game.");
btnStopWatching.addMouseListener(new FirstButtonMousePressedAction(e -> btnStopWatching.addMouseListener(new FirstButtonMousePressedAction(e ->
@ -2506,14 +2528,13 @@ public final class GamePanel extends javax.swing.JPanel {
} }
int i = 0; int i = 0;
for (String name : hoverButtons.keySet()) { for (String name : phaseButtons.keySet()) {
HoverButton hoverButton = hoverButtons.get(name); HoverButton hoverButton = phaseButtons.get(name);
hoverButton.setAlignmentX(LEFT_ALIGNMENT); hoverButton.setAlignmentX(LEFT_ALIGNMENT);
hoverButton.setBounds(X_PHASE_WIDTH - 36, i * 36, 36, 36); hoverButton.setBounds(X_PHASE_WIDTH - 36, i * 36, 36, 36);
jPhases.add(hoverButton); jPhases.add(hoverButton);
i++; i++;
} }
jPhases.addMouseListener(phasesMouseAdapter);
pnlReplay.setOpaque(false); pnlReplay.setOpaque(false);
@ -2657,8 +2678,8 @@ public final class GamePanel extends javax.swing.JPanel {
for (MouseListener ml : this.jPhases.getMouseListeners()) { for (MouseListener ml : this.jPhases.getMouseListeners()) {
this.jPhases.removeMouseListener(ml); this.jPhases.removeMouseListener(ml);
} }
for (String name : hoverButtons.keySet()) { for (String name : phaseButtons.keySet()) {
HoverButton hoverButton = hoverButtons.get(name); HoverButton hoverButton = phaseButtons.get(name);
for (MouseListener ml : hoverButton.getMouseListeners()) { for (MouseListener ml : hoverButton.getMouseListeners()) {
hoverButton.removeMouseListener(ml); hoverButton.removeMouseListener(ml);
} }
@ -2878,15 +2899,12 @@ public final class GamePanel extends javax.swing.JPanel {
} }
private void createPhaseButton(String name, MouseAdapter mouseAdapter) { private void createPhaseButton(String name, MouseAdapter mouseAdapter) {
if (hoverButtons == null) {
hoverButtons = new LinkedHashMap<>();
}
Rectangle rect = new Rectangle(36, 36); Rectangle rect = new Rectangle(36, 36);
HoverButton button = new HoverButton("", ImageManagerImpl.instance.getPhaseImage(name), rect); HoverButton button = new HoverButton("", ImageManagerImpl.instance.getPhaseImage(name), rect);
button.setToolTipText(name.replaceAll("_", " ")); button.setToolTipText(name.replaceAll("_", " "));
button.setPreferredSize(new Dimension(36, 36)); button.setPreferredSize(new Dimension(36, 36));
button.addMouseListener(mouseAdapter); button.addMouseListener(mouseAdapter);
hoverButtons.put(name, button); phaseButtons.put(name, button);
} }
// Event listener for the ShowCardsDialog // Event listener for the ShowCardsDialog
@ -3047,7 +3065,6 @@ public final class GamePanel extends javax.swing.JPanel {
private mage.client.components.ability.AbilityPicker abilityPicker; private mage.client.components.ability.AbilityPicker abilityPicker;
private mage.client.cards.BigCard bigCard; private mage.client.cards.BigCard bigCard;
// private JPanel cancelSkipPanel;
private KeyboundButton btnToggleMacro; private KeyboundButton btnToggleMacro;
private KeyboundButton btnCancelSkip; private KeyboundButton btnCancelSkip;
private KeyboundButton btnSkipToNextTurn; // F4 private KeyboundButton btnSkipToNextTurn; // F4

View file

@ -9,7 +9,6 @@ import mage.view.CardView;
import net.java.truevfs.access.TFile; import net.java.truevfs.access.TFile;
import net.java.truevfs.access.TFileInputStream; import net.java.truevfs.access.TFileInputStream;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.mage.card.arcane.CardPanelRenderModeImage;
import org.mage.plugins.card.dl.sources.DirectLinksForDownload; import org.mage.plugins.card.dl.sources.DirectLinksForDownload;
import org.mage.plugins.card.utils.CardImageUtils; import org.mage.plugins.card.utils.CardImageUtils;
import org.mage.plugins.card.utils.impl.ImageManagerImpl; import org.mage.plugins.card.utils.impl.ImageManagerImpl;
@ -25,6 +24,8 @@ import java.util.regex.Pattern;
* This class stores ALL card images in a cache with soft values. This means * This class stores ALL card images in a cache with soft values. This means
* that the images may be garbage collected when they are not needed any more, * that the images may be garbage collected when they are not needed any more,
* but will be kept as long as possible. * but will be kept as long as possible.
* <p>
* It used to refresh themes at runtime too. Use GUISizeHelper.refreshGUIAndCards()
* *
* @author JayDi85 * @author JayDi85
*/ */
@ -160,7 +161,8 @@ public final class ImageCache {
} }
} }
/** Find image for current side /**
* Find image for current side
*/ */
public static ImageCacheData getCardImageOriginal(CardView card) { public static ImageCacheData getCardImageOriginal(CardView card) {
return getCardImage(getKey(card, card.getName(), 0)); return getCardImage(getKey(card, card.getName(), 0));

View file

@ -2,6 +2,8 @@ package org.mage.plugins.card.utils.impl;
import mage.abilities.icon.CardIconColor; import mage.abilities.icon.CardIconColor;
import mage.client.dialog.PreferencesDialog; import mage.client.dialog.PreferencesDialog;
import mage.client.util.ImageCaches;
import mage.client.util.SoftValuesLoadingCache;
import mage.client.util.gui.BufferedImageBuilder; import mage.client.util.gui.BufferedImageBuilder;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.mage.card.arcane.SvgUtils; import org.mage.card.arcane.SvgUtils;
@ -16,32 +18,109 @@ import java.net.URL;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects;
/**
* GUI plugin: images and icons with theme support
*
* @author JayDi85
*/
public enum ImageManagerImpl implements ImageManager { public enum ImageManagerImpl implements ImageManager {
instance; instance;
private static final Logger logger = Logger.getLogger(ImageManagerImpl.class); private static final Logger logger = Logger.getLogger(ImageManagerImpl.class);
ImageManagerImpl() { private static BufferedImage appImage;
init(); private static BufferedImage appSmallImage;
private static BufferedImage appImageFlashed;
private static BufferedImage imageSickness;
private static BufferedImage imageDay;
private static BufferedImage imageNight;
private static BufferedImage imageTokenIcon;
private static BufferedImage triggeredAbilityIcon;
private static BufferedImage activatedAbilityIcon;
private static BufferedImage lookedAtIcon;
private static BufferedImage revealedIcon;
private static BufferedImage exileIcon;
private static BufferedImage imageCopyIcon;
private static BufferedImage imageCounterGreen;
private static BufferedImage imageCounterGrey;
private static BufferedImage imageCounterRed;
private static BufferedImage imageCounterViolet;
private static BufferedImage imageDlgAcceptButton;
private static BufferedImage imageDlgActiveAcceptButton;
private static BufferedImage imageDlgCancelButton;
private static BufferedImage imageDlgActiveCancelButton;
private static BufferedImage imageDlgPrevButton;
private static BufferedImage imageDlgActivePrevButton;
private static BufferedImage imageDlgNextButton;
private static BufferedImage imageDlgActiveNextButton;
private static final SoftValuesLoadingCache<Key, BufferedImage> THEME_BUTTON_IMAGES_CACHE;
private static final SoftValuesLoadingCache<Key, Image> PHASE_THEME_BUTTON_IMAGES_CACHE;
static {
THEME_BUTTON_IMAGES_CACHE = ImageCaches.register(SoftValuesLoadingCache.from(ImageManagerImpl::createThemeButtonImage));
PHASE_THEME_BUTTON_IMAGES_CACHE = ImageCaches.register(SoftValuesLoadingCache.from(ImageManagerImpl::createPhaseThemeButtonImage));
} }
public void init() { private static final class Key {
String[] phases = {"Untap", "Upkeep", "Draw", "Main1",
"Combat_Start", "Combat_Attack", "Combat_Block", "Combat_Damage", "Combat_End", final String resourceName;
"Main2", "Cleanup", "Next_Turn"};
phasesImages = new HashMap<>(); public Key(String resourceName) {
for (String name : phases) { this.resourceName = resourceName;
Image image = getImageFromResource(
PreferencesDialog.getCurrentTheme().getPhasePath("phase_" + name.toLowerCase(Locale.ENGLISH) + ".png"),
new Rectangle(36, 36));
phasesImages.put(name, image);
}
} }
@Override @Override
public Image getPhaseImage(String phase) { public int hashCode() {
return phasesImages.get(phase); int hash = 3;
hash = 53 * hash + Objects.hashCode(this.resourceName);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ImageManagerImpl.Key other = (ImageManagerImpl.Key) obj;
if (!this.resourceName.equals(other.resourceName)) {
return false;
}
return true;
}
}
private static BufferedImage createThemeButtonImage(ImageManagerImpl.Key key) {
return getBufferedImageFromResource(PreferencesDialog.getCurrentTheme().getButtonPath(key.resourceName));
}
private static Image createPhaseThemeButtonImage(ImageManagerImpl.Key key) {
return getImageFromResource(
PreferencesDialog.getCurrentTheme().getPhasePath("phase_" + key.resourceName.toLowerCase(Locale.ENGLISH) + ".png"),
new Rectangle(36, 36)
);
}
ImageManagerImpl() {
}
public BufferedImage getThemeButton(String resourceName) {
return THEME_BUTTON_IMAGES_CACHE.getOrThrow(new ImageManagerImpl.Key(resourceName));
}
@Override
public Image getPhaseImage(String phaseName) {
return PHASE_THEME_BUTTON_IMAGES_CACHE.getOrThrow(new ImageManagerImpl.Key(phaseName));
} }
@Override @Override
@ -266,101 +345,57 @@ public enum ImageManagerImpl implements ImageManager {
@Override @Override
public Image getConcedeButtonImage() { public Image getConcedeButtonImage() {
if (imageConcedeButton == null) { return getThemeButton("concede.png");
imageConcedeButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("concede.png"));
}
return imageConcedeButton;
} }
@Override @Override
public Image getSwitchHandsButtonImage() { public Image getSwitchHandsButtonImage() {
if (imageSwitchHandsButton == null) { return getThemeButton("switch_hands.png");
imageSwitchHandsButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("switch_hands.png"));
}
return imageSwitchHandsButton;
} }
@Override @Override
public Image getStopWatchButtonImage() { public Image getStopWatchButtonImage() {
if (imageStopWatchingButton == null) { return getThemeButton("stop_watching.png");
imageStopWatchingButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("stop_watching.png"));
}
return imageStopWatchingButton;
} }
@Override @Override
public Image getCancelSkipButtonImage() { public Image getCancelSkipButtonImage() {
if (imageCancelSkipButton == null) { return getThemeButton("cancel_skip.png");
imageCancelSkipButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("cancel_skip.png"));
}
return imageCancelSkipButton;
} }
@Override @Override
public Image getSkipNextTurnButtonImage() { public Image getSkipNextTurnButtonImage() {
if (imageSkipNextTurnButton == null) { return getThemeButton("skip_turn.png");
imageSkipNextTurnButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("skip_turn.png"));
}
return imageSkipNextTurnButton;
} }
@Override @Override
public Image getSkipEndTurnButtonImage() { public Image getSkipEndTurnButtonImage() {
if (imageSkipToEndTurnButton == null) { return getThemeButton("skip_to_end.png");
imageSkipToEndTurnButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("skip_to_end.png"));
}
return imageSkipToEndTurnButton;
} }
@Override @Override
public Image getSkipMainButtonImage() { public Image getSkipMainButtonImage() {
if (imageSkipToMainButton == null) { return getThemeButton("skip_to_main.png");
imageSkipToMainButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("skip_to_main.png"));
}
return imageSkipToMainButton;
} }
@Override @Override
public Image getSkipStackButtonImage() { public Image getSkipStackButtonImage() {
if (imageSkipStackButton == null) { return getThemeButton("skip_stack.png");
imageSkipStackButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("skip_stack.png"));
}
return imageSkipStackButton;
} }
@Override @Override
public Image getSkipEndStepBeforeYourTurnButtonImage() { public Image getSkipEndStepBeforeYourTurnButtonImage() {
if (imageSkipUntilEndStepBeforeYourTurnButton == null) { return getThemeButton("skip_to_previous_end.png");
imageSkipUntilEndStepBeforeYourTurnButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("skip_to_previous_end.png"));
}
return imageSkipUntilEndStepBeforeYourTurnButton;
} }
@Override @Override
public Image getSkipYourNextTurnButtonImage() { public Image getSkipYourNextTurnButtonImage() {
if (imageSkipYourNextTurnButton == null) { return getThemeButton("skip_all.png");
imageSkipYourNextTurnButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("skip_all.png"));
}
return imageSkipYourNextTurnButton;
} }
@Override @Override
public Image getToggleRecordMacroButtonImage() { public Image getToggleRecordMacroButtonImage() {
if (imageToggleRecordMacroButton == null) { return getThemeButton("toggle_macro.png");
imageToggleRecordMacroButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("toggle_macro.png"));
}
return imageToggleRecordMacroButton;
} }
@Override @Override
@ -432,48 +467,4 @@ public enum ImageManagerImpl implements ImageManager {
WritableRaster raster = bi.copyData(null); WritableRaster raster = bi.copyData(null);
return new BufferedImage(cm, raster, isAlphaPremultiplied, null); return new BufferedImage(cm, raster, isAlphaPremultiplied, null);
} }
private static BufferedImage appImage;
private static BufferedImage appSmallImage;
private static BufferedImage appImageFlashed;
private static BufferedImage imageSickness;
private static BufferedImage imageDay;
private static BufferedImage imageNight;
private static BufferedImage imageTokenIcon;
private static BufferedImage triggeredAbilityIcon;
private static BufferedImage activatedAbilityIcon;
private static BufferedImage lookedAtIcon;
private static BufferedImage revealedIcon;
private static BufferedImage exileIcon;
private static BufferedImage imageCopyIcon;
private static BufferedImage imageCounterGreen;
private static BufferedImage imageCounterGrey;
private static BufferedImage imageCounterRed;
private static BufferedImage imageCounterViolet;
private static BufferedImage imageDlgAcceptButton;
private static BufferedImage imageDlgActiveAcceptButton;
private static BufferedImage imageDlgCancelButton;
private static BufferedImage imageDlgActiveCancelButton;
private static BufferedImage imageDlgPrevButton;
private static BufferedImage imageDlgActivePrevButton;
private static BufferedImage imageDlgNextButton;
private static BufferedImage imageDlgActiveNextButton;
// TODO: enable buttons and related GUI refresh on theme change
private static BufferedImage imageCancelSkipButton; // theme depends
private static BufferedImage imageSwitchHandsButton; // theme depends
private static BufferedImage imageStopWatchingButton; // theme depends
private static BufferedImage imageConcedeButton; // theme depends
private static BufferedImage imageSkipNextTurnButton; // theme depends
private static BufferedImage imageSkipToEndTurnButton; // theme depends
private static BufferedImage imageSkipToMainButton; // theme depends
private static BufferedImage imageSkipStackButton; // theme depends
private static BufferedImage imageSkipUntilEndStepBeforeYourTurnButton; // theme depends
private static BufferedImage imageSkipYourNextTurnButton; // theme depends
private static BufferedImage imageToggleRecordMacroButton; // theme depends
private static Map<String, Image> phasesImages; // theme depends
} }