Merge branch 'master' into refactor_promo_sets

This commit is contained in:
Oleg Agafonov 2020-08-07 02:48:40 +02:00 committed by GitHub
commit 9e6a348cb1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4098 changed files with 115584 additions and 60811 deletions

10
.github/dependabot.yml vendored Normal file
View file

@ -0,0 +1,10 @@
version: 2
updates:
- package-ecosystem: 'github-actions'
directory: '/'
schedule:
interval: 'weekly'
- package-ecosystem: 'maven'
directory: '/'
schedule:
interval: 'weekly'

4
.gitignore vendored
View file

@ -104,7 +104,9 @@ Utils/*implemented.txt
.metadata
.project
.settings
.idea
.idea/
.vscode/
.factorypath
syntax: regexp
\.class
\.jar

1
Mage.Client/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/bin/

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.42</version>
<version>1.4.44</version>
</parent>
<artifactId>mage-client</artifactId>
@ -43,11 +43,14 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<!-- needs for server connection by jboss -->
<groupId>net.sf.trove4j</groupId>
<artifactId>trove4j</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>com.mortennobel</groupId>
<artifactId>java-image-scaling</artifactId>
@ -70,7 +73,7 @@
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>1.11.498</version>
<version>1.11.827</version>
</dependency>
<dependency>
<groupId>com.jgoodies</groupId>
@ -107,7 +110,7 @@
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.3</version>
<version>1.13.1</version>
</dependency>
<dependency>
<artifactId>truevfs-profile-base</artifactId>
@ -125,6 +128,8 @@
</exclusion>
</exclusions>
</dependency>
<!-- music player START -->
<dependency>
<groupId>com.googlecode.soundlibs</groupId>
<artifactId>mp3spi</artifactId>
@ -140,12 +145,15 @@
<artifactId>tritonus_share</artifactId>
<version>0.3.6</version>
</dependency>
<!-- music player END -->
<dependency>
<groupId>net.java.balloontip</groupId>
<artifactId>balloontip</artifactId>
<version>1.2.4.1</version>
</dependency>
<!-- svg support start -->
<!-- svg support START -->
<!--
for "SAX2 driver class org.apache.crimson.parser.XMLReaderImpl not found" error looks here:
https://stackoverflow.com/questions/714243/sax2-driver-class-org-apache-crimson-parser-xmlreaderimpl-not-found-when-using
@ -155,11 +163,17 @@
<artifactId>batik-transcoder</artifactId>
<version>1.11</version>
</dependency>
<!-- svg support end -->
<!-- svg support END -->
<dependency>
<groupId>org.ocpsoft.prettytime</groupId>
<artifactId>prettytime</artifactId>
<version>4.0.2.Final</version>
<version>4.0.5.Final</version>
</dependency>
<dependency>
<groupId>org.unbescape</groupId>
<artifactId>unbescape</artifactId>
<version>1.1.6.RELEASE</version>
</dependency>
</dependencies>

Binary file not shown.

View file

@ -69,6 +69,7 @@
</includes>
<outputDirectory>/</outputDirectory>
</fileSet>
<!-- database must be generated on first run/update
<fileSet>
<filtered>false</filtered>
<directory>db/</directory>
@ -78,6 +79,7 @@
<outputDirectory>db/</outputDirectory>
<fileMode>0644</fileMode>
</fileSet>
-->
<fileSet>
<filtered>false</filtered>
<directory>sounds/</directory>

View file

@ -200,9 +200,17 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
TConfig config = TConfig.current();
config.setArchiveDetector(new TArchiveDetector("zip"));
config.setAccessPreference(FsAccessOption.STORE, true);
try {
UIManager.put("desktop", new Color(0, 0, 0, 0));
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
UIManager.put("nimbusBlueGrey", PreferencesDialog.getCurrentTheme().getNimbusBlueGrey()); // buttons, scrollbar background, disabled inputs
UIManager.put("control", PreferencesDialog.getCurrentTheme().getControl()); // window bg
UIManager.put("nimbusLightBackground", PreferencesDialog.getCurrentTheme().getNimbusLightBackground()); // inputs, table rows
UIManager.put("info", PreferencesDialog.getCurrentTheme().getInfo()); // tooltips
UIManager.put("nimbusBase", PreferencesDialog.getCurrentTheme().getNimbusBase()); // title bars, scrollbar foreground
//UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
// stop JSplitPane from eating F6 and F8 or any other function keys
{
@ -445,16 +453,19 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
}
}
// Sets background for login screen
private void setBackground() {
if (liteMode || grayMode) {
return;
}
String filename = "/background.jpg";
try {
if (Plugins.instance.isThemePluginLoaded()) {
// If user has custom background, use that, otherwise, use theme background
if (Plugins.instance.isThemePluginLoaded() &&
!PreferencesDialog.getCachedValue(PreferencesDialog.KEY_BACKGROUND_IMAGE_DEFAULT, "true").equals("true")) {
backgroundPane = (ImagePanel) Plugins.instance.updateTablePanel(new HashMap<>());
} else {
InputStream is = this.getClass().getResourceAsStream(filename);
InputStream is = this.getClass().getResourceAsStream(PreferencesDialog.getCurrentTheme().getLoginBackgroundPath());
BufferedImage background = ImageIO.read(is);
backgroundPane = new ImagePanel(background, ImagePanelStyle.SCALED);
}
@ -870,7 +881,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
popupDebug.add(menuDebugTestCardRenderModesDialog);
setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
setMinimumSize(new java.awt.Dimension(1024, 768));
setMinimumSize(new java.awt.Dimension(1024, 500));
desktopPane.setBackground(new java.awt.Color(204, 204, 204));
@ -1020,6 +1031,10 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
.addComponent(desktopPane, javax.swing.GroupLayout.DEFAULT_SIZE, 145, Short.MAX_VALUE))
);
if (PreferencesDialog.getCurrentTheme().getMageToolbar() != null) {
mageToolbar.getParent().setBackground(PreferencesDialog.getCurrentTheme().getMageToolbar());
}
pack();
}// </editor-fold>//GEN-END:initComponents
@ -1624,6 +1639,13 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
whatsNewDialog.checkUpdatesAndShow(forceToShowPage);
}
}
public boolean isGameFrameActive(UUID gameId) {
if (activeFrame != null && activeFrame instanceof GamePane) {
return ((GamePane) activeFrame).getGameId().equals(gameId);
}
return false;
}
}
class MagePaneMenuItem extends JCheckBoxMenuItem {

View file

@ -6,7 +6,7 @@
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new Dimension(FRAME_MAX_WIDTH, FRAME_MAX_HEIGHT)" type="code"/>
</Property>
<Property name="opaque" type="boolean" value="false"/>
<Property name="name" type="java.lang.String" value="bigCardPanel" noResource="true"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection component="Form" name="minimumSize" type="property"/>
</Property>
@ -30,11 +30,18 @@
<SubComponents>
<Container class="javax.swing.JScrollPane" name="scrollPane">
<Properties>
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="dc" green="dc" red="dc" type="rgb"/>
</Property>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
<Property name="horizontalScrollBarPolicy" type="int" value="31"/>
<Property name="opaque" type="boolean" value="false"/>
<Property name="viewportBorder" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
<EtchetBorder/>
</Border>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_allCodePost" type="java.lang.String" value="scrollPane.setBounds(new Rectangle(CONTENT_MAX_XOFFSET, TEXT_MAX_YOFFSET, TEXT_MAX_WIDTH, TEXT_MAX_HEIGHT));"/>
@ -42,7 +49,7 @@
</AuxValues>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription">
<AbsoluteConstraints x="20" y="230" width="210" height="120"/>
<AbsoluteConstraints x="20" y="220" width="210" height="130"/>
</Constraint>
</Constraints>
@ -50,9 +57,7 @@
<SubComponents>
<Component class="javax.swing.JTextPane" name="text">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="focusable" type="boolean" value="false"/>
<Property name="opaque" type="boolean" value="false"/>
</Properties>
</Component>
</SubComponents>

View file

@ -8,6 +8,7 @@
package mage.client.cards;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
@ -15,9 +16,10 @@ import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.util.List;
import java.util.UUID;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.text.BadLocationException;
import javax.swing.text.StyledDocument;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import static mage.client.constants.Constants.CONTENT_MAX_XOFFSET;
import static mage.client.constants.Constants.FRAME_MAX_HEIGHT;
import static mage.client.constants.Constants.FRAME_MAX_WIDTH;
@ -29,6 +31,7 @@ import mage.client.util.ImageHelper;
import mage.constants.EnlargeMode;
import org.jdesktop.swingx.JXPanel;
import mage.client.util.TransformedImageCache;
import org.mage.card.arcane.UI;
/**
* Class for displaying big image of the card
@ -62,6 +65,9 @@ public class BigCard extends JComponent {
setOpaque(true);
this.scrollPane.setOpaque(true);
this.scrollPane.setVisible(false);
UI.setHTMLEditorKit(text);
text.setEditable(false);
}
private void initBounds(boolean rotated) {
@ -69,8 +75,8 @@ public class BigCard extends JComponent {
if (rotated) {
scrollPane.setBounds(50, 50, 100, 100);
} else {
scrollPane.setBounds(this.getWidth()*1000/17777,this.getWidth()*1000/1100,
this.getWidth()*1000/1142,this.getWidth()*1000/2539);
scrollPane.setBounds(this.getWidth()*1000/17777,this.getWidth()*1000/1150,
this.getWidth()*1000/1130,this.getWidth()*1000/2100);
}
}
@ -96,7 +102,13 @@ public class BigCard extends JComponent {
source = null;
hue = 0.000f;
}
drawText(strings);
StringBuilder displayedText = new StringBuilder();
for (String textLine: strings) {
if (textLine != null && !textLine.replace(".", "").trim().isEmpty()) {
displayedText.append("<p style='margin: 2px'>").append(textLine).append("</p>");
}
}
this.text.setText(displayedText.toString());
repaint();
}
}
@ -109,19 +121,6 @@ public class BigCard extends JComponent {
this.cardId = null;
}
private void drawText(java.util.List<String> strings) {
text.setText("");
StyledDocument doc = text.getStyledDocument();
try {
for (String line : strings) {
doc.insertString(doc.getLength(), line + '\n', doc.getStyle("regular"));
}
} catch (BadLocationException ble) {
}
text.setCaretPosition(0);
}
@Override
public void paintComponent(Graphics graphics) {
if (bigImage != null) {
@ -169,21 +168,19 @@ public class BigCard extends JComponent {
setFocusable(false);
setMinimumSize(new Dimension(FRAME_MAX_WIDTH, FRAME_MAX_HEIGHT));
setName("bigCardPanel"); // NOI18N
setOpaque(false);
setPreferredSize(getMinimumSize());
setLayout(null);
scrollPane.setBackground(new java.awt.Color(220, 220, 220));
scrollPane.setBorder(null);
scrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setOpaque(false);
scrollPane.setViewportBorder(javax.swing.BorderFactory.createEtchedBorder());
text.setEditable(false);
text.setFocusable(false);
text.setOpaque(false);
scrollPane.setViewportView(text);
add(scrollPane);
scrollPane.setBounds(20, 230, 210, 120);
scrollPane.setBounds(20, 220, 210, 130);
scrollPane.setBounds(new Rectangle(CONTENT_MAX_XOFFSET, TEXT_MAX_YOFFSET, TEXT_MAX_WIDTH, TEXT_MAX_HEIGHT));
}// </editor-fold>//GEN-END:initComponents

View file

@ -321,7 +321,7 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis
@Override
public void mouseMoved(MouseEvent arg0) {
this.bigCard.showTextComponent();
// this.bigCard.showTextComponent();
this.bigCard.setCard(card.getId(), EnlargeMode.NORMAL, image, getRules(), false);
}

View file

@ -73,8 +73,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
}
trimGrid();
layoutGrid();
cardScroll.revalidate();
cardScroll.repaint();
repaintGrid();
}
}
@ -315,8 +314,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
// Remove empty rows / cols / spaces in stacks
trimGrid();
layoutGrid();
cardScroll.revalidate();
cardScroll.repaint();
repaintGrid();
} else {
// Add new cards to grid
for (CardView card : cards) {
@ -325,14 +323,14 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
eventSource.fireEvent(card, ClientEventType.ADD_SPECIFIC_CARD);
}
layoutGrid();
cardContent.repaint();
repaintGrid();
}
}
public void changeGUISize() {
layoutGrid();
cardScroll.getVerticalScrollBar().setUnitIncrement(CardRenderer.getCardTopHeight(getCardWidth()));
cardContent.repaint();
repaintGrid();
}
public void cleanUp() {
@ -386,7 +384,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
}
trimGrid();
layoutGrid();
cardContent.repaint();
repaintGrid();
}
public DeckCardLayout getCardLayout() {
@ -562,6 +560,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
JButton selectByButton;
JButton analyseButton;
JButton blingButton;
JButton oldVersionButton;
// Popup for toolbar
final JPopupMenu filterPopup;
@ -709,60 +708,6 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
// Editting mode
this.mode = Constants.DeckEditorMode.LIMITED_BUILDING;
// Toolbar
sortButton = new JButton("Sort");
filterButton = new JButton("Filter");
visibilityButton = new JButton("V"); // "Visibility" button
selectByButton = new JButton("Select By");
analyseButton = new JButton("M"); // "Mana" button
blingButton = new JButton("B"); // "Bling" button
// Name and count label
deckNameAndCountLabel = new JLabel();
// Count labels
landCountLabel = new JLabel("", new ImageIcon(getClass().getResource("/buttons/type_land.png")), SwingConstants.LEFT);
landCountLabel.setToolTipText("Number of lands in deck");
creatureCountLabel = new JLabel("", new ImageIcon(getClass().getResource("/buttons/type_creatures.png")), SwingConstants.LEFT);
creatureCountLabel.setToolTipText("Number of creatures in deck");
JPanel toolbar = new JPanel(new BorderLayout());
JPanel toolbarInner = new JPanel();
toolbar.setBackground(new Color(250, 250, 250, 150));
toolbar.setOpaque(true);
toolbarInner.setOpaque(false);
toolbarInner.add(deckNameAndCountLabel);
toolbarInner.add(landCountLabel);
toolbarInner.add(creatureCountLabel);
toolbarInner.add(sortButton);
toolbarInner.add(filterButton);
toolbarInner.add(selectByButton);
toolbarInner.add(visibilityButton);
toolbarInner.add(analyseButton);
toolbarInner.add(blingButton);
toolbar.add(toolbarInner, BorderLayout.WEST);
JPanel sliderPanel = new JPanel(new GridBagLayout());
sliderPanel.setOpaque(false);
cardSizeSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 100, 50);
cardSizeSlider.setOpaque(false);
cardSizeSlider.setPreferredSize(new Dimension(100, (int) cardSizeSlider.getPreferredSize().getHeight()));
cardSizeSlider.addChangeListener(e -> {
if (!cardSizeSlider.getValueIsAdjusting()) {
// Fraction in [-1, 1]
float sliderFrac = ((float) (cardSizeSlider.getValue() - 50)) / 50;
// Convert to frac in [0.5, 2.0] exponentially
cardSizeMod = (float) Math.pow(2, sliderFrac);
// Update grid
layoutGrid();
cardContent.repaint();
}
});
cardSizeSliderLabel = new JLabel("Card Size:");
sliderPanel.add(cardSizeSliderLabel);
sliderPanel.add(cardSizeSlider);
toolbar.add(sliderPanel, BorderLayout.EAST);
this.add(toolbar, BorderLayout.NORTH);
// Content
cardContent = new JLayeredPane();
cardContent.setLayout(null);
@ -804,6 +749,62 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
cardScroll.getVerticalScrollBar().setUnitIncrement(CardRenderer.getCardTopHeight(getCardWidth()));
this.add(cardScroll, BorderLayout.CENTER);
// Toolbar
sortButton = new JButton("Sort");
filterButton = new JButton("Filter");
visibilityButton = new JButton("V"); // "Visibility" button
selectByButton = new JButton("Select By");
analyseButton = new JButton("M"); // "Mana" button
blingButton = new JButton("B"); // "Bling" button
oldVersionButton = new JButton("O"); // "Old version" button
// Name and count label
deckNameAndCountLabel = new JLabel();
// Count labels
landCountLabel = new JLabel("", new ImageIcon(getClass().getResource("/buttons/type_land.png")), SwingConstants.LEFT);
landCountLabel.setToolTipText("Number of lands in deck");
creatureCountLabel = new JLabel("", new ImageIcon(getClass().getResource("/buttons/type_creatures.png")), SwingConstants.LEFT);
creatureCountLabel.setToolTipText("Number of creatures in deck");
JPanel toolbar = new JPanel(new BorderLayout());
JPanel toolbarInner = new JPanel();
toolbar.setBackground(new Color(250, 250, 250, 150));
toolbar.setOpaque(true);
toolbarInner.setOpaque(false);
toolbarInner.add(deckNameAndCountLabel);
toolbarInner.add(landCountLabel);
toolbarInner.add(creatureCountLabel);
toolbarInner.add(sortButton);
toolbarInner.add(filterButton);
toolbarInner.add(selectByButton);
toolbarInner.add(visibilityButton);
toolbarInner.add(analyseButton);
toolbarInner.add(blingButton);
toolbarInner.add(oldVersionButton);
toolbar.add(toolbarInner, BorderLayout.WEST);
JPanel sliderPanel = new JPanel(new GridBagLayout());
sliderPanel.setOpaque(false);
cardSizeSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 100, 50);
cardSizeSlider.setOpaque(false);
cardSizeSlider.setPreferredSize(new Dimension(100, (int) cardSizeSlider.getPreferredSize().getHeight()));
cardSizeSlider.addChangeListener(e -> {
if (!cardSizeSlider.getValueIsAdjusting()) {
// Fraction in [-1, 1]
float sliderFrac = ((float) (cardSizeSlider.getValue() - 50)) / 50;
// Convert to frac in [0.5, 2.0] exponentially
cardSizeMod = (float) Math.pow(2, sliderFrac);
// Update grid
layoutGrid();
repaintGrid();
}
});
cardSizeSliderLabel = new JLabel("Card size:");
sliderPanel.add(cardSizeSliderLabel);
sliderPanel.add(cardSizeSlider);
toolbar.add(sliderPanel, BorderLayout.EAST);
this.add(toolbar, BorderLayout.NORTH);
// Insert arrow
insertArrow = new JLabel();
insertArrow.setSize(20, 20);
@ -982,6 +983,11 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
blingButton.addActionListener(evt -> blingDeck());
// Old version button - Switch cards to the oldest non-promo printing. In case of multiples in a set, take the lowest card number.
oldVersionButton.setToolTipText("Switch cards to the oldest non-promo printing");
oldVersionButton.addActionListener(evt -> oldVersionDeck());
// Filter popup
filterPopup = new JPopupMenu();
filterPopup.setPreferredSize(new Dimension(300, 300));
@ -1222,7 +1228,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
// And finally rerender
layoutGrid();
repaint();
repaintGrid();
}
public void reselectBy() {
@ -1332,7 +1338,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
// And finally rerender
layoutGrid();
repaint();
repaintGrid();
}
private static final Pattern pattern = Pattern.compile(".*Add(.*)(\\{[WUBRGXC]\\})");
@ -1633,13 +1639,49 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
}
layoutGrid();
cardScroll.revalidate();
repaint();
repaintGrid();
JOptionPane.showMessageDialog(null, "Added " + pimpedCards.size() + " cards. You can select them and the originals by choosing 'Multiples'");
}
}
}
private void oldVersionDeck() {
if (this.mode != Constants.DeckEditorMode.FREE_BUILDING) {
return;
}
if (JOptionPane.showConfirmDialog(null, "Are you sure you want to switch your card versions to the oldest ones?", "WARNING",
JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) {
return;
}
List<List<List<CardView>>> newCardGrid = new ArrayList<>();
for (List<List<CardView>> gridRow : cardGrid) {
List<List<CardView>> newGridRow = new ArrayList<>();
for (List<CardView> stack : gridRow) {
List<CardView> newStack = new ArrayList<>();
for (CardView card : stack) {
CardInfo oldestCardInfo = CardRepository.instance.findOldestNonPromoVersionCard(card.getName());
if (oldestCardInfo != null) {
CardView oldestCardView = new CardView(oldestCardInfo.getMockCard());
this.removeCardView(card);
eventSource.fireEvent(card, ClientEventType.REMOVE_SPECIFIC_CARD);
this.addCardView(oldestCardView, false);
eventSource.fireEvent(oldestCardView, ClientEventType.ADD_SPECIFIC_CARD);
newStack.add(oldestCardView);
} else {
newStack.add(card);
}
}
newGridRow.add(newStack);
}
newCardGrid.add(newGridRow);
}
cardGrid = newCardGrid;
layoutGrid();
repaintGrid();
}
// Update the contents of the card grid
public void setCards(CardsView cardsView, DeckCardLayout layout, BigCard bigCard) {
if (bigCard != null) {
@ -1761,10 +1803,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
if (didModify) {
// Update layout
layoutGrid();
// Update draw
cardScroll.revalidate();
repaint();
repaintGrid();
}
}
@ -1904,9 +1943,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
eventSource.fireEvent(card, ClientEventType.ADD_SPECIFIC_CARD);
// Update layout
layoutGrid();
// Update draw
cardScroll.revalidate();
repaint();
repaintGrid();
}
}
@ -2110,6 +2147,12 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
return (int) (1.4 * getCardWidth());
}
private void repaintGrid() {
cardScroll.revalidate();
cardScroll.repaint();
repaint();
}
/**
* Position all of the card views correctly
*/

View file

@ -27,6 +27,9 @@ public enum CombatManager {
private final Map<UUID, Integer> combatBlockers = new HashMap<>();
private int globalBlockersCount; // we need global counter as there are several combat groups
private static Color ARROW_COLOR_ATTACKER = Color.red;
private static Color ARROW_COLOR_BLOCKED_ATTACKER = Color.gray;
private Point parentPoint;
@ -79,15 +82,19 @@ public enum CombatManager {
private void drawDefender(CombatGroupView group, MagePermanent attackerCard, UUID gameId) {
UUID defenderId = group.getDefenderId();
if (defenderId != null) {
// if attacker was blocked then use another arrow color
Color attackColor = group.getBlockers().isEmpty() ? ARROW_COLOR_ATTACKER : ARROW_COLOR_BLOCKED_ATTACKER;
parentPoint = getParentPoint(attackerCard);
PlayAreaPanel p = MageFrame.getGamePlayers(gameId).get(defenderId);
if (p != null) {
// attack to player
Point target = p.getLocationOnScreen();
target.translate(-parentPoint.x, -parentPoint.y);
Point attackerPoint = attackerCard.getLocationOnScreen();
attackerPoint.translate(-parentPoint.x, -parentPoint.y);
ArrowBuilder.getBuilder().addArrow(gameId, (int) attackerPoint.getX() + 45, (int) attackerPoint.getY() + 25, (int) target.getX() + 40, (int) target.getY() - 20, Color.red, ArrowBuilder.Type.COMBAT);
ArrowBuilder.getBuilder().addArrow(gameId, (int) attackerPoint.getX() + 45, (int) attackerPoint.getY() + 25, (int) target.getX() + 40, (int) target.getY() - 20, attackColor, ArrowBuilder.Type.COMBAT);
} else {
// attack to planeswalker
for (PlayAreaPanel pa : MageFrame.getGamePlayers(gameId).values()) {
MagePermanent permanent = pa.getBattlefieldPanel().getPermanents().get(defenderId);
if (permanent != null) {
@ -95,7 +102,7 @@ public enum CombatManager {
target.translate(-parentPoint.x, -parentPoint.y);
Point attackerPoint = attackerCard.getLocationOnScreen();
attackerPoint.translate(-parentPoint.x, -parentPoint.y);
ArrowBuilder.getBuilder().addArrow(gameId, (int) attackerPoint.getX() + 45, (int) attackerPoint.getY() + 25, (int) target.getX() + 40, (int) target.getY() + 10, Color.red, ArrowBuilder.Type.COMBAT);
ArrowBuilder.getBuilder().addArrow(gameId, (int) attackerPoint.getX() + 45, (int) attackerPoint.getY() + 25, (int) target.getX() + 40, (int) target.getY() + 10, attackColor, ArrowBuilder.Type.COMBAT);
}
}
}

View file

@ -6,9 +6,11 @@ import mage.client.MageFrame;
import mage.client.dialog.PreferencesDialog;
import mage.client.util.gui.GuiDisplayUtil;
import mage.components.CardInfoPane;
import mage.game.command.Plane;
import mage.util.CardUtil;
import mage.utils.ThreadUtils;
import mage.view.CardView;
import mage.view.PlaneView;
import javax.swing.*;
import javax.swing.event.HyperlinkEvent.EventType;
@ -75,17 +77,24 @@ public class ColorPane extends JEditorPane {
if (!alternativeName.isEmpty()) {
cardName = alternativeName;
}
CardInfo card = CardRepository.instance.findCard(cardName);
try {
final Component container = MageFrame.getUI().getComponent(MageComponents.POPUP_CONTAINER);
if (e.getEventType() == EventType.EXITED) {
setPopupVisibility(container, false);
}
if (e.getEventType() == EventType.ENTERED && card != null) {
if (e.getEventType() == EventType.ENTERED) {
CardInfoPane cardInfoPane = (CardInfoPane) MageFrame.getUI().getComponent(MageComponents.CARD_INFO_PANE);
// card
CardInfo card = CardRepository.instance.findCard(cardName);
Plane plane = Plane.createPlaneByFullName(cardName);
if (card != null) {
cardInfoPane.setCard(new CardView(card.getMockCard()), container);
setPopupVisibility(container, true);
} else if (plane != null) {
cardInfoPane.setCard(new CardView(new PlaneView(plane)), container);
setPopupVisibility(container, true);
}
}
} catch (InterruptedException e1) {
e1.printStackTrace();

View file

@ -17,8 +17,12 @@ public class KeyboundButton extends JButton {
private boolean tinting = false;
public KeyboundButton(String key) {
public KeyboundButton(String key, boolean drawText) {
if (drawText) {
text = PreferencesDialog.getCachedKeyText(key);
} else {
text = "";
}
}
@Override
@ -27,17 +31,21 @@ public class KeyboundButton extends JButton {
Graphics sg = g.create();
try {
ui.update(sg, this);
if (tinting) {
sg.setColor(new Color(0, 0, 0, 32));
sg.fillRoundRect(2, 2, getWidth() - 4 , getHeight() - 4, 6, 6);
}
sg.setColor(tinting ? Color.lightGray : Color.white);
if (!text.isEmpty()) {
sg.setFont(keyFont);
int textWidth = sg.getFontMetrics(keyFont).stringWidth(text);
int centerX = (getWidth() - textWidth) / 2;
sg.drawString(text, centerX, 28);
}
} finally {
sg.dispose();
}
@ -48,5 +56,4 @@ public class KeyboundButton extends JButton {
this.tinting = tinting;
repaint();
}
}

View file

@ -0,0 +1,205 @@
package mage.client.components;
import mage.cards.decks.Deck;
import mage.cards.decks.DeckValidator;
import mage.cards.decks.DeckValidatorError;
import mage.cards.decks.importer.DeckImporter;
import org.unbescape.html.HtmlEscape;
import org.unbescape.html.HtmlEscapeLevel;
import org.unbescape.html.HtmlEscapeType;
import javax.swing.*;
import java.awt.*;
import java.io.File;
/**
* @author Elandril
*/
public class LegalityLabel extends JLabel {
protected static final Color COLOR_UNKNOWN = new Color(174, 174, 174);
protected static final Color COLOR_LEGAL = new Color(117, 152, 110);
protected static final Color COLOR_PARTLY_LEGAL = new Color(191, 176, 80);
protected static final Color COLOR_NOT_LEGAL = new Color(191, 84, 74);
protected static final Color COLOR_TEXT = new Color(255, 255, 255);
protected static final Dimension DIM_MINIMUM = new Dimension(75, 25);
protected static final Dimension DIM_MAXIMUM = new Dimension(150, 75);
protected static final Dimension DIM_PREFERRED = new Dimension(75, 25);
protected Deck currentDeck;
protected String errorMessage;
protected DeckValidator validator;
/**
* Creates a <code>LegalityLabel</code> instance with the specified text
* and the given DeckValidator.
*
* @param text The text to be displayed by the label.
* @param validator The DeckValidator to check against.
*/
public LegalityLabel(String text, DeckValidator validator) {
super(text);
this.validator = validator;
setBackground(COLOR_UNKNOWN);
setForeground(COLOR_TEXT);
setHorizontalAlignment(SwingConstants.CENTER);
setMinimumSize(DIM_MINIMUM);
setMaximumSize(DIM_MAXIMUM);
setName(text); // NOI18N
setOpaque(true);
setPreferredSize(DIM_PREFERRED);
}
/**
* Creates a <code>LegalityLabel</code> instance with the given DeckValidator and uses its
* shortName as the text.
*
* @param validator The DeckValidator to check against.
*/
public LegalityLabel(DeckValidator validator) {
this(validator.getShortName(), validator);
}
/**
* Creates a <code>LegalityLabel</code> instance with no DeckValidator or text.
* This is used by the Netbeans GUI Editor.
*/
public LegalityLabel() {
super();
setBackground(COLOR_UNKNOWN);
setForeground(COLOR_TEXT);
setHorizontalAlignment(SwingConstants.CENTER);
setMinimumSize(DIM_MINIMUM);
setMaximumSize(DIM_MAXIMUM);
setOpaque(true);
setPreferredSize(DIM_PREFERRED);
}
/**
* Creates hide button to close legality panel (must be same size as label)
*/
public static JButton createHideButton() {
JButton button = new JButton("Hide");
button.setHorizontalAlignment(SwingConstants.CENTER);
button.setMinimumSize(DIM_MINIMUM);
button.setMaximumSize(DIM_MAXIMUM);
button.setPreferredSize(DIM_PREFERRED);
return button;
}
public String getErrorMessage() {
return errorMessage;
}
public DeckValidator getValidator() {
return validator;
}
public void setValidator(DeckValidator validator) {
this.validator = validator;
revalidateDeck();
}
protected String escapeHtml(String string) {
return HtmlEscape.escapeHtml(string, HtmlEscapeType.HTML4_NAMED_REFERENCES_DEFAULT_TO_HEXA, HtmlEscapeLevel.LEVEL_0_ONLY_MARKUP_SIGNIFICANT_EXCEPT_APOS);
}
protected String formatInvalidTooltip(java.util.List<DeckValidatorError> sortedErrorsList) {
return sortedErrorsList.stream()
.reduce("<html><body><p>Deck is <span style='color:#BF544A;font-weight:bold;'>INVALID</span></p><u>The following problems have been found:</u><br><table>",
(str, error) -> String.format("%s<tr><td><b>%s</b></td><td>%s</td></tr>", str, escapeHtml(error.getGroup()), escapeHtml(error.getMessage())), String::concat)
+ "</table></body></html>";
}
protected String formatPartlyValidTooltip(java.util.List<DeckValidatorError> sortedErrorsList) {
return sortedErrorsList.stream()
.reduce("<html><body><p>Deck is <span style='color:#b8860b;font-weight:bold;'>PARTLY VALID</span></p><u>The following problems have been found:</u><br><table>",
(str, error) -> String.format("%s<tr><td><b>%s</b></td><td>%s</td></tr>", str, escapeHtml(error.getGroup()), escapeHtml(error.getMessage())), String::concat)
+ "</table></body></html>";
}
private String appendErrorMessage(String string) {
if (errorMessage.isEmpty())
return string;
if (string.contains("<html>")) {
return string.replaceFirst("((</body>)?</html>)", String.format("<br><br>The following errors occurred while loading the deck:<br>%s$1", escapeHtml(errorMessage)));
}
return string.concat("\n\nThe following errors occurred while loading the deck:\n" + errorMessage);
}
public void showState(Color color) {
setBackground(color);
}
public void showState(Color color, String tooltip) {
setBackground(color);
setToolTipText(appendErrorMessage(tooltip));
}
public void showStateUnknown(String tooltip) {
showState(COLOR_UNKNOWN, tooltip);
}
public void showStateLegal(String tooltip) {
showState(COLOR_LEGAL, tooltip);
}
public void showStatePartlyLegal(String tooltip) {
showState(COLOR_PARTLY_LEGAL, tooltip);
}
public void showStateNotLegal(String tooltip) {
showState(COLOR_NOT_LEGAL, tooltip);
}
public void validateDeck(Deck deck) {
errorMessage = "";
currentDeck = deck;
if (deck == null) {
showStateUnknown("<html><body><b>No deck loaded!</b></body></html>");
return;
}
if (validator == null) {
showStateUnknown("<html><body><b>No deck type selected!</b></body></html>");
return;
}
try {
if (validator.validate(deck)) {
showStateLegal("<html><body>Deck is <span style='color:green;font-weight:bold;'>VALID</span></body></html>");
} else if (validator.isPartlyValid()) {
showStatePartlyLegal(formatPartlyValidTooltip(validator.getErrorsListSorted()));
} else {
showStateNotLegal(formatInvalidTooltip(validator.getErrorsListSorted()));
}
} catch (Exception e) {
showStateUnknown(String.format("<html><body><b>Deck could not be validated!</b><br>The following error occurred while validating this deck:<br>%s</body></html>", escapeHtml(e.getMessage())));
}
}
public void validateDeck(File deckFile) {
deckFile = deckFile.getAbsoluteFile();
if (!deckFile.exists()) {
errorMessage = String.format("Deck file '%s' does not exist.", deckFile.getAbsolutePath());
showStateUnknown("<html><body><b>No Deck loaded!</b></body></html>");
return;
}
try {
StringBuilder errorMessages = new StringBuilder();
Deck deck = Deck.load(DeckImporter.importDeckFromFile(deckFile.getAbsolutePath(), errorMessages), true, true);
errorMessage = errorMessages.toString();
validateDeck(deck);
} catch (Exception ex) {
errorMessage = String.format("Error importing deck from file '%s'!", deckFile.getAbsolutePath());
}
}
public void revalidateDeck() {
validateDeck(currentDeck);
}
public void validateDeck(String deckFile) {
validateDeck(new File(deckFile));
}
}

View file

@ -1,10 +1,5 @@
package mage.client.components;
//import com.sun.java.swing.Painter;
import java.awt.Color;
import java.awt.Graphics2D;
import javax.swing.JDesktopPane;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
@ -22,7 +17,7 @@ public class MageJDesktop extends JDesktopPane {
public void updateUI() {
if ("Nimbus".equals(UIManager.getLookAndFeel().getName())) {
UIDefaults map = new UIDefaults();
Painter painter = (g, c, w, h) -> {
Painter<?> painter = (g, c, w, h) -> {
g.setColor( UIManager.getDefaults().getColor("desktop") );
g.fillRect(0,0,w,h);
};

View file

@ -383,7 +383,7 @@ public class AbilityPicker extends JXPanel implements MouseWheelListener {
public static void main(String[] argv) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Exception ex) {
}

View file

@ -10,6 +10,7 @@ import mage.ObjectColor;
import mage.cards.Card;
import mage.cards.ExpansionSet;
import mage.cards.Sets;
import mage.cards.decks.PennyDreadfulLegalityUtil;
import mage.cards.repository.*;
import mage.client.MageFrame;
import mage.client.cards.*;
@ -37,8 +38,8 @@ import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.List;
import java.util.*;
import java.util.Map.Entry;
import static mage.client.dialog.PreferencesDialog.*;
@ -299,6 +300,7 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
criteria.white(this.tbWhite.isSelected());
criteria.colorless(this.tbColorless.isSelected());
// if you add new type filter then sync it with CardType
if (this.tbLand.isSelected()) {
criteria.types(CardType.LAND);
}
@ -320,8 +322,6 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
if (this.tbPlaneswalkers.isSelected()) {
criteria.types(CardType.PLANESWALKER);
}
// criteria.types(CardType.TRIBAL);
// criteria.types(CardType.CONSPIRACY);
if (this.tbCommon.isSelected()) {
criteria.rarities(Rarity.COMMON);
@ -422,9 +422,8 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
try {
java.util.List<Card> filteredCards = new ArrayList<>();
boolean chkPD = chkPennyDreadful.isSelected();
if (chkPD) {
generatePennyDreadfulHash();
if (chkPennyDreadful.isSelected() && pdAllowed.isEmpty()) {
pdAllowed.putAll(PennyDreadfulLegalityUtil.getLegalCardList());
}
if (limited) {
@ -438,7 +437,7 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
for (CardInfo cardInfo : foundCards) {
Card card = cardInfo.getMockCard();
if (filter.match(card, null)) {
if (chkPD) {
if (chkPennyDreadful.isSelected()) {
if (!pdAllowed.containsKey(card.getName())) {
continue;
}
@ -479,22 +478,6 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
}
}
public void generatePennyDreadfulHash() {
if (pdAllowed.size() > 0) {
return;
}
Properties properties = new Properties();
try {
properties.load(CardSelector.class.getResourceAsStream("pennydreadful.properties"));
} catch (Exception e) {
e.printStackTrace();
}
for (final Entry<Object, Object> entry : properties.entrySet()) {
pdAllowed.put((String) entry.getKey(), 1);
}
}
private void reloadSetsCombobox() {
DefaultComboBoxModel model = new DefaultComboBoxModel<>(ConstructedFormats.getTypes());
cbExpansionSet.setModel(model);

View file

@ -11,39 +11,45 @@
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,121,0,0,4,76"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="deckAreaSplitPane" alignment="0" pref="918" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="deckAreaSplitPane" alignment="0" pref="377" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
<SubComponents>
<Container class="javax.swing.JSplitPane" name="deckAreaSplitPane">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
<Property name="resizeWeight" type="double" value="0.6"/>
<Property name="dividerSize" type="int" value="10"/>
<Property name="resizeWeight" type="double" value="0.5"/>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="Center"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
<SubComponents>
<Component class="mage.client.cards.DragCardGrid" name="dragCardGrid1">
<Component class="mage.client.cards.DragCardGrid" name="deckList">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[200, 56]"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
<JSplitPaneConstraints position="left"/>
</Constraint>
</Constraints>
</Component>
<Component class="mage.client.cards.DragCardGrid" name="dragCardGrid2">
<Component class="mage.client.cards.DragCardGrid" name="sideboardList">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[200, 56]"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
<JSplitPaneConstraints position="right"/>

View file

@ -1,9 +1,3 @@
/*
* DeckArea.java
*
* Created on Feb 18, 2010, 3:10:39 PM
*/
package mage.client.deckeditor;
import mage.cards.Card;
@ -26,7 +20,6 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class DeckArea extends javax.swing.JPanel {
@ -38,7 +31,6 @@ public class DeckArea extends javax.swing.JPanel {
private BigCard lastBigCard = null;
private int dividerLocationNormal = 0;
private int dividerLocationLimited = 0;
private static final boolean isLimitedBuildingOrientation = false;
public DeckCardLayout getCardLayout() {
return deckList.getCardLayout();
@ -170,7 +162,7 @@ public class DeckArea extends javax.swing.JPanel {
});
}
public Settings saveSettings() {
public Settings saveSettings(boolean isLimitedBuildingOrientation) {
Settings settings = new Settings();
settings.maindeckSettings = deckList.saveSettings();
settings.sideboardSetings = sideboardList.saveSettings();
@ -184,7 +176,7 @@ public class DeckArea extends javax.swing.JPanel {
return settings;
}
public void loadSettings(Settings s) {
public void loadSettings(Settings s, boolean isLimitedBuildingOrientation) {
if (s != null) {
deckList.loadSettings(s.maindeckSettings);
sideboardList.loadSettings(s.sideboardSetings);
@ -215,8 +207,8 @@ public class DeckArea extends javax.swing.JPanel {
private void setGUISize() {
}
public void setOrientation(boolean limitedBuildingOrientation) {
if (limitedBuildingOrientation) {
public void setOrientation(boolean isLimitedBuildingOrientation) {
if (isLimitedBuildingOrientation) {
deckAreaSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
if (dividerLocationLimited != 0) {
deckAreaSplitPane.setDividerLocation(dividerLocationLimited);
@ -298,21 +290,19 @@ public class DeckArea extends javax.swing.JPanel {
deckList = new mage.client.cards.DragCardGrid();
sideboardList = new mage.client.cards.DragCardGrid();
setLayout(new java.awt.BorderLayout());
deckAreaSplitPane.setBorder(null);
deckAreaSplitPane.setResizeWeight(0.6);
deckAreaSplitPane.setDividerSize(10);
deckAreaSplitPane.setResizeWeight(0.5);
deckList.setMinimumSize(new java.awt.Dimension(200, 56));
deckAreaSplitPane.setLeftComponent(deckList);
sideboardList.setMinimumSize(new java.awt.Dimension(200, 56));
deckAreaSplitPane.setRightComponent(sideboardList);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(deckAreaSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 918, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(deckAreaSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 377, Short.MAX_VALUE)
);
add(deckAreaSplitPane, java.awt.BorderLayout.CENTER);
}// </editor-fold>//GEN-END:initComponents
public DragCardGrid getDeckList() {

View file

@ -20,6 +20,11 @@
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
<SubComponents>
<Component class="mage.client.deckeditor.DeckEditorPanel" name="deckEditorPanel1">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[1000, 500]"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="Center"/>

View file

@ -74,6 +74,7 @@ public class DeckEditorPane extends MagePane {
deckEditorPanel1 = new mage.client.deckeditor.DeckEditorPanel();
filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 10), new java.awt.Dimension(0, 32767));
deckEditorPanel1.setMinimumSize(new java.awt.Dimension(1000, 500));
getContentPane().add(deckEditorPanel1, java.awt.BorderLayout.CENTER);
getContentPane().add(filler1, java.awt.BorderLayout.NORTH);
}// </editor-fold>//GEN-END:initComponents

View file

@ -18,21 +18,22 @@
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="panelLeft" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Component id="panelRight" pref="890" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="panelRight" pref="883" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="panelLeft" alignment="0" max="32767" attributes="0"/>
<Component id="panelRight" alignment="1" pref="808" max="32767" attributes="0"/>
<Component id="panelRight" alignment="1" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JSplitPane" name="panelRight">
<Properties>
<Property name="dividerSize" type="int" value="10"/>
<Property name="orientation" type="int" value="0"/>
<Property name="resizeWeight" type="double" value="0.5"/>
</Properties>
@ -47,6 +48,11 @@
</Constraints>
</Component>
<Component class="mage.client.deckeditor.DeckArea" name="deckArea">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[200, 56]"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
<JSplitPaneConstraints position="bottom"/>
@ -60,21 +66,16 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="panelDeck" alignment="1" max="32767" attributes="0"/>
<Component id="bigCard" alignment="0" max="32767" attributes="0"/>
</Group>
</Group>
<Component id="panelDeck" max="32767" attributes="0"/>
<Component id="scrollPaneInfo" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="panelDeck" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="bigCard" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="scrollPaneInfo" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
@ -89,8 +90,6 @@
<AuxValue name="JavaCodeGenerator_DeclarationPre" type="java.lang.String" value="private JComponent cardInfoPane;&#xa;/*"/>
</AuxValues>
</Component>
<Component class="mage.client.cards.BigCard" name="bigCard">
</Component>
<Container class="javax.swing.JPanel" name="panelDeck">
<Properties>
<Property name="opaque" type="boolean" value="false"/>
@ -112,7 +111,7 @@
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="lblDeckName" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="txtDeckName" pref="175" max="32767" attributes="0"/>
<Component id="txtDeckName" pref="205" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
@ -158,7 +157,7 @@
<Component id="btnNew" min="-2" pref="100" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnGenDeck" min="-2" pref="100" max="-2" attributes="0"/>
<EmptySpace pref="40" max="32767" attributes="0"/>
<EmptySpace pref="70" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -215,7 +214,7 @@
<Component id="btnLoad" min="-2" pref="100" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnImport" min="-2" pref="100" max="-2" attributes="0"/>
<EmptySpace pref="40" max="32767" attributes="0"/>
<EmptySpace pref="70" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -272,7 +271,7 @@
<Component id="btnSave" min="-2" pref="100" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnExport" min="-2" pref="100" max="-2" attributes="0"/>
<EmptySpace pref="40" max="32767" attributes="0"/>
<EmptySpace pref="70" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -329,7 +328,7 @@
<Component id="btnSubmit" min="-2" pref="100" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnSubmitTimer" min="-2" pref="100" max="-2" attributes="0"/>
<EmptySpace pref="40" max="32767" attributes="0"/>
<EmptySpace pref="70" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -392,15 +391,20 @@
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="btnAddLand" min="-2" pref="100" max="-2" attributes="0"/>
<EmptySpace pref="146" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnLegality" min="-2" pref="100" max="-2" attributes="0"/>
<EmptySpace pref="70" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="btnAddLand" pref="30" max="32767" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="btnAddLand" max="32767" attributes="0"/>
<Component id="btnLegality" max="32767" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
</Group>
</Group>
@ -420,6 +424,16 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnAddLandActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnLegality">
<Properties>
<Property name="text" type="java.lang.String" value="Validate"/>
<Property name="iconTextGap" type="int" value="2"/>
<Property name="name" type="java.lang.String" value="btnLegality" noResource="true"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnLegalityActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="panelDeckExit">
@ -435,7 +449,7 @@
<Component id="btnExit" min="-2" pref="100" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="txtTimeRemaining" min="-2" pref="100" max="-2" attributes="0"/>
<EmptySpace pref="40" max="32767" attributes="0"/>
<EmptySpace pref="70" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -470,6 +484,72 @@
</Container>
</SubComponents>
</Container>
<Container class="javax.swing.JScrollPane" name="scrollPaneInfo">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
<Property name="horizontalScrollBarPolicy" type="int" value="31"/>
<Property name="opaque" type="boolean" value="false"/>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="panelInfo">
<Properties>
<Property name="opaque" type="boolean" value="false"/>
</Properties>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="-2" pref="15" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="bigCard" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<Component id="deckLegalityDisplay" min="-2" pref="245" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace min="-2" pref="15" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="deckLegalityDisplay" min="-2" pref="155" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="32767" attributes="0"/>
<Component id="bigCard" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="mage.client.deckeditor.DeckLegalityPanel" name="deckLegalityDisplay">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[245, 155]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[85, 155]"/>
</Property>
<Property name="opaque" type="boolean" value="false"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_InitCodePost" type="java.lang.String" value="deckLegalityDisplay.setVisible(false);"/>
</AuxValues>
</Component>
<Component class="mage.client.cards.BigCard" name="bigCard">
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>

View file

@ -43,7 +43,7 @@ import static mage.cards.decks.DeckFormats.XMAGE;
import static mage.cards.decks.DeckFormats.XMAGE_INFO;
/**
* @author BetaSteward_at_googlemail.com, JayDi85
* @author BetaSteward_at_googlemail.com, JayDi85, Elandril
*/
public class DeckEditorPanel extends javax.swing.JPanel {
@ -78,7 +78,6 @@ public class DeckEditorPanel extends javax.swing.JPanel {
deckArea.setOpaque(false);
panelLeft.setOpaque(false);
panelRight.setOpaque(false);
restoreDividerLocationsAndDeckAreaSettings();
countdown = new javax.swing.Timer(1000,
e -> {
if (--timeout > 0) {
@ -93,13 +92,18 @@ public class DeckEditorPanel extends javax.swing.JPanel {
}
});
// Set up tracking to save the deck editor settings when the deck editor is hidden.
// save editor settings dynamicly on hides (e.g. app close)
addHierarchyListener((HierarchyEvent e) -> {
if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {
if (!isShowing()) {
// It's bugged and called on sideboarding creates too (before load). So:
// * for free mode - save here
// * for draft/sideboarding - save on cleanup call
if (mode == DeckEditorMode.FREE_BUILDING) {
saveDividerLocationsAndDeckAreaSettings();
}
}
}
});
}
@ -127,21 +131,32 @@ public class DeckEditorPanel extends javax.swing.JPanel {
}
private void saveDividerLocationsAndDeckAreaSettings() {
PreferencesDialog.saveValue(PreferencesDialog.KEY_EDITOR_HORIZONTAL_DIVIDER_LOCATION, Integer.toString(panelRight.getDividerLocation()));
PreferencesDialog.saveValue(PreferencesDialog.KEY_EDITOR_DECKAREA_SETTINGS, this.deckArea.saveSettings().toString());
boolean isLimitedBuildingOrientation = (mode != DeckEditorMode.FREE_BUILDING);
if (isLimitedBuildingOrientation) {
PreferencesDialog.saveValue(PreferencesDialog.KEY_EDITOR_HORIZONTAL_DIVIDER_LOCATION_LIMITED, Integer.toString(panelRight.getDividerLocation()));
} else {
PreferencesDialog.saveValue(PreferencesDialog.KEY_EDITOR_HORIZONTAL_DIVIDER_LOCATION_NORMAL, Integer.toString(panelRight.getDividerLocation()));
}
PreferencesDialog.saveValue(PreferencesDialog.KEY_EDITOR_DECKAREA_SETTINGS, this.deckArea.saveSettings(isLimitedBuildingOrientation).toString());
}
private void restoreDividerLocationsAndDeckAreaSettings() {
// Load horizontal split position setting
String dividerLocation = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_EDITOR_HORIZONTAL_DIVIDER_LOCATION, "");
String dividerLocation = "";
boolean isLimitedBuildingOrientation = (mode != DeckEditorMode.FREE_BUILDING);
if (isLimitedBuildingOrientation) {
dividerLocation = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_EDITOR_HORIZONTAL_DIVIDER_LOCATION_LIMITED, "");
} else {
dividerLocation = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_EDITOR_HORIZONTAL_DIVIDER_LOCATION_NORMAL, "");
}
if (!dividerLocation.isEmpty()) {
panelRight.setDividerLocation(Integer.parseInt(dividerLocation));
}
// Load deck area settings
this.deckArea.loadSettings(
DeckArea.Settings.parse(
PreferencesDialog.getCachedValue(PreferencesDialog.KEY_EDITOR_DECKAREA_SETTINGS, "")));
DeckArea.Settings.parse(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_EDITOR_DECKAREA_SETTINGS, "")),
isLimitedBuildingOrientation);
}
public void changeGUISize() {
@ -157,11 +172,18 @@ public class DeckEditorPanel extends javax.swing.JPanel {
this.mode = mode;
this.btnAddLand.setVisible(false);
// workaround to enable real opaque in scrollbar pane (transparent panel) and remove scroll pane border
scrollPaneInfo.getViewport().setOpaque(false);
scrollPaneInfo.setBorder(BorderFactory.createEmptyBorder());
scrollPaneInfo.setViewportBorder(BorderFactory.createEmptyBorder());
restoreDividerLocationsAndDeckAreaSettings();
switch (mode) {
case LIMITED_BUILDING:
this.btnAddLand.setVisible(true);
this.txtTimeRemaining.setVisible(true);
// Fall through to sideboarding
this.btnLegality.setVisible(false); // legality check available only in free building mode
// Fall through to sideboarding (no break)
case SIDEBOARDING:
this.btnSubmit.setVisible(true);
this.btnSubmitTimer.setVisible(true);
@ -194,6 +216,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
this.btnSubmit.setVisible(false);
this.btnSubmitTimer.setVisible(false);
this.btnAddLand.setVisible(true);
this.btnLegality.setVisible(true);
this.cardSelector.setVisible(true);
this.cardSelector.loadCards(this.bigCard);
//this.cardTableSelector.loadCards(this.bigCard);
@ -839,7 +862,6 @@ public class DeckEditorPanel extends javax.swing.JPanel {
cardInfoPane = new JLabel();
cardInfoPane.setVisible(false);
}
bigCard = new mage.client.cards.BigCard();
panelDeck = new javax.swing.JPanel();
panelDeckName = new javax.swing.JPanel();
lblDeckName = new javax.swing.JLabel();
@ -858,13 +880,21 @@ public class DeckEditorPanel extends javax.swing.JPanel {
btnSubmitTimer = new javax.swing.JButton();
panelDeckLands = new javax.swing.JPanel();
btnAddLand = new javax.swing.JButton();
btnLegality = new javax.swing.JButton();
panelDeckExit = new javax.swing.JPanel();
btnExit = new javax.swing.JButton();
txtTimeRemaining = new javax.swing.JTextField();
scrollPaneInfo = new javax.swing.JScrollPane();
panelInfo = new javax.swing.JPanel();
deckLegalityDisplay = new mage.client.deckeditor.DeckLegalityPanel();
bigCard = new mage.client.cards.BigCard();
panelRight.setDividerSize(10);
panelRight.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
panelRight.setResizeWeight(0.5);
panelRight.setTopComponent(cardSelector);
deckArea.setMinimumSize(new java.awt.Dimension(200, 56));
panelRight.setBottomComponent(deckArea);
panelDeck.setOpaque(false);
@ -884,7 +914,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
.addContainerGap()
.addComponent(lblDeckName)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(txtDeckName, javax.swing.GroupLayout.DEFAULT_SIZE, 175, Short.MAX_VALUE)
.addComponent(txtDeckName, javax.swing.GroupLayout.DEFAULT_SIZE, 205, Short.MAX_VALUE)
.addContainerGap())
);
panelDeckNameLayout.setVerticalGroup(
@ -928,7 +958,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
.addComponent(btnNew, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnGenDeck, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(40, Short.MAX_VALUE))
.addContainerGap(70, Short.MAX_VALUE))
);
panelDeckCreateLayout.setVerticalGroup(
panelDeckCreateLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -971,7 +1001,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
.addComponent(btnLoad, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnImport, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(40, Short.MAX_VALUE))
.addContainerGap(70, Short.MAX_VALUE))
);
panelDeckLoadLayout.setVerticalGroup(
panelDeckLoadLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -1014,7 +1044,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
.addComponent(btnSave, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnExport, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(40, Short.MAX_VALUE))
.addContainerGap(70, Short.MAX_VALUE))
);
panelDeckSaveLayout.setVerticalGroup(
panelDeckSaveLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -1059,7 +1089,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
.addComponent(btnSubmit, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnSubmitTimer, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(40, Short.MAX_VALUE))
.addContainerGap(70, Short.MAX_VALUE))
);
panelDeckDraftLayout.setVerticalGroup(
panelDeckDraftLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -1087,6 +1117,15 @@ public class DeckEditorPanel extends javax.swing.JPanel {
}
});
btnLegality.setText("Validate");
btnLegality.setIconTextGap(2);
btnLegality.setName("btnLegality"); // NOI18N
btnLegality.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnLegalityActionPerformed(evt);
}
});
javax.swing.GroupLayout panelDeckLandsLayout = new javax.swing.GroupLayout(panelDeckLands);
panelDeckLands.setLayout(panelDeckLandsLayout);
panelDeckLandsLayout.setHorizontalGroup(
@ -1094,13 +1133,17 @@ public class DeckEditorPanel extends javax.swing.JPanel {
.addGroup(panelDeckLandsLayout.createSequentialGroup()
.addContainerGap()
.addComponent(btnAddLand, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(146, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnLegality, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(70, Short.MAX_VALUE))
);
panelDeckLandsLayout.setVerticalGroup(
panelDeckLandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelDeckLandsLayout.createSequentialGroup()
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panelDeckLandsLayout.createSequentialGroup()
.addContainerGap()
.addComponent(btnAddLand, javax.swing.GroupLayout.DEFAULT_SIZE, 30, Short.MAX_VALUE)
.addGroup(panelDeckLandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(btnAddLand, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(btnLegality, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGap(0, 0, 0))
);
@ -1131,7 +1174,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
.addComponent(btnExit, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(txtTimeRemaining, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(40, Short.MAX_VALUE))
.addContainerGap(70, Short.MAX_VALUE))
);
panelDeckExitLayout.setVerticalGroup(
panelDeckExitLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -1144,22 +1187,56 @@ public class DeckEditorPanel extends javax.swing.JPanel {
panelDeck.add(panelDeckExit);
scrollPaneInfo.setBorder(null);
scrollPaneInfo.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollPaneInfo.setOpaque(false);
panelInfo.setOpaque(false);
deckLegalityDisplay.setMaximumSize(new java.awt.Dimension(245, 155));
deckLegalityDisplay.setMinimumSize(new java.awt.Dimension(85, 155));
deckLegalityDisplay.setOpaque(false);
deckLegalityDisplay.setVisible(false);
javax.swing.GroupLayout panelInfoLayout = new javax.swing.GroupLayout(panelInfo);
panelInfo.setLayout(panelInfoLayout);
panelInfoLayout.setHorizontalGroup(
panelInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelInfoLayout.createSequentialGroup()
.addGap(15, 15, 15)
.addGroup(panelInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(bigCard, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panelInfoLayout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
.addComponent(deckLegalityDisplay, javax.swing.GroupLayout.PREFERRED_SIZE, 245, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, Short.MAX_VALUE)))
.addGap(15, 15, 15))
);
panelInfoLayout.setVerticalGroup(
panelInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelInfoLayout.createSequentialGroup()
.addContainerGap()
.addComponent(deckLegalityDisplay, javax.swing.GroupLayout.PREFERRED_SIZE, 155, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(bigCard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
scrollPaneInfo.setViewportView(panelInfo);
javax.swing.GroupLayout panelLeftLayout = new javax.swing.GroupLayout(panelLeft);
panelLeft.setLayout(panelLeftLayout);
panelLeftLayout.setHorizontalGroup(
panelLeftLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelLeftLayout.createSequentialGroup()
.addGap(0, 0, 0)
.addGroup(panelLeftLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(panelDeck, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(bigCard, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addComponent(panelDeck, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(scrollPaneInfo)
);
panelLeftLayout.setVerticalGroup(
panelLeftLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelLeftLayout.createSequentialGroup()
.addComponent(panelDeck, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(bigCard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(scrollPaneInfo)
.addContainerGap())
);
@ -1169,13 +1246,13 @@ public class DeckEditorPanel extends javax.swing.JPanel {
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(panelLeft, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, 0)
.addComponent(panelRight, javax.swing.GroupLayout.DEFAULT_SIZE, 890, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(panelRight, javax.swing.GroupLayout.DEFAULT_SIZE, 883, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(panelLeft, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(panelRight, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 808, Short.MAX_VALUE)
.addComponent(panelRight, javax.swing.GroupLayout.Alignment.TRAILING)
);
}// </editor-fold>//GEN-END:initComponents
@ -1368,6 +1445,11 @@ public class DeckEditorPanel extends javax.swing.JPanel {
exportChoose(evt);
}//GEN-LAST:event_btnExportActionPerformed
private void btnLegalityActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLegalityActionPerformed
this.deckLegalityDisplay.setVisible(true);
this.deckLegalityDisplay.validateDeck(deck);
}//GEN-LAST:event_btnLegalityActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private mage.client.cards.BigCard bigCard;
@ -1376,6 +1458,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
private javax.swing.JButton btnExport;
private javax.swing.JButton btnGenDeck;
private javax.swing.JButton btnImport;
private javax.swing.JButton btnLegality;
private javax.swing.JButton btnLoad;
private javax.swing.JButton btnNew;
private javax.swing.JButton btnSave;
@ -1387,6 +1470,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
*/
private mage.client.deckeditor.CardSelector cardSelector;
private mage.client.deckeditor.DeckArea deckArea;
private mage.client.deckeditor.DeckLegalityPanel deckLegalityDisplay;
private javax.swing.JLabel lblDeckName;
private javax.swing.JPanel panelDeck;
private javax.swing.JPanel panelDeckCreate;
@ -1396,8 +1480,10 @@ public class DeckEditorPanel extends javax.swing.JPanel {
private javax.swing.JPanel panelDeckLoad;
private javax.swing.JPanel panelDeckName;
private javax.swing.JPanel panelDeckSave;
private javax.swing.JPanel panelInfo;
private javax.swing.JPanel panelLeft;
private javax.swing.JSplitPane panelRight;
private javax.swing.JScrollPane scrollPaneInfo;
private javax.swing.JTextField txtDeckName;
private javax.swing.JTextField txtTimeRemaining;
// End of variables declaration//GEN-END:variables
@ -1425,6 +1511,7 @@ class ImportFilter extends FileFilter {
|| ext.equalsIgnoreCase("dek")
|| ext.equalsIgnoreCase("cod")
|| ext.equalsIgnoreCase("o8d")
|| ext.equalsIgnoreCase("json")
|| ext.equalsIgnoreCase("draft")
|| ext.equalsIgnoreCase("mtga");
}
@ -1433,7 +1520,7 @@ class ImportFilter extends FileFilter {
@Override
public String getDescription() {
return "All formats (*.dec; *.mwDeck; *.txt; *.dek; *.cod; *.o8d; *.draft; *.mtga)";
return "All formats (*.dec; *.mwDeck; *.txt; *.dek; *.cod; *.o8d; *.json; *.draft; *.mtga;)";
}
}

View file

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.8" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[85, 35]"/>
</Property>
<Property name="name" type="java.lang.String" value="DeckLegalityPanel" noResource="true"/>
</Properties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,0,-11"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout">
<Property name="alignment" type="int" value="3"/>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="previewUnknown">
<Properties>
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="ae" green="ae" red="ae" type="rgb"/>
</Property>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="ff" green="ff" red="ff" type="rgb"/>
</Property>
<Property name="horizontalAlignment" type="int" value="0"/>
<Property name="text" type="java.lang.String" value="Unknown"/>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[150, 50]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[75, 25]"/>
</Property>
<Property name="name" type="java.lang.String" value="previewUnknown" noResource="true"/>
<Property name="opaque" type="boolean" value="true"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[75, 25]"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="previewLegal">
<Properties>
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="6e" green="98" red="75" type="rgb"/>
</Property>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="ff" green="ff" red="ff" type="rgb"/>
</Property>
<Property name="horizontalAlignment" type="int" value="0"/>
<Property name="text" type="java.lang.String" value="Legal"/>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[150, 50]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[75, 25]"/>
</Property>
<Property name="name" type="java.lang.String" value="previewLegal" noResource="true"/>
<Property name="opaque" type="boolean" value="true"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[75, 25]"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="previewNotLegal">
<Properties>
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="4a" green="54" red="bf" type="rgb"/>
</Property>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="ff" green="ff" red="ff" type="rgb"/>
</Property>
<Property name="horizontalAlignment" type="int" value="0"/>
<Property name="text" type="java.lang.String" value="Not Legal"/>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[150, 50]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[75, 25]"/>
</Property>
<Property name="name" type="java.lang.String" value="previewNotLegal" noResource="true"/>
<Property name="opaque" type="boolean" value="true"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[75, 25]"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>

View file

@ -0,0 +1,123 @@
package mage.client.deckeditor;
import mage.cards.decks.Deck;
import mage.cards.decks.DeckValidator;
import mage.client.components.LegalityLabel;
import mage.deck.*;
import javax.swing.*;
import java.util.Arrays;
import java.util.stream.Stream;
/**
* @author Elandril
*/
public class DeckLegalityPanel extends javax.swing.JPanel {
/**
* Creates new form DeckLegalityPanel
*/
public DeckLegalityPanel() {
initComponents();
initDeckLabels();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
previewUnknown = new javax.swing.JLabel();
previewLegal = new javax.swing.JLabel();
previewNotLegal = new javax.swing.JLabel();
setMinimumSize(new java.awt.Dimension(85, 35));
setName("DeckLegalityPanel"); // NOI18N
setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEADING));
previewUnknown.setBackground(new java.awt.Color(174, 174, 174));
previewUnknown.setForeground(new java.awt.Color(255, 255, 255));
previewUnknown.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
previewUnknown.setText("Unknown");
previewUnknown.setMaximumSize(new java.awt.Dimension(150, 50));
previewUnknown.setMinimumSize(new java.awt.Dimension(75, 25));
previewUnknown.setName("previewUnknown"); // NOI18N
previewUnknown.setOpaque(true);
previewUnknown.setPreferredSize(new java.awt.Dimension(75, 25));
add(previewUnknown);
previewLegal.setBackground(new java.awt.Color(117, 152, 110));
previewLegal.setForeground(new java.awt.Color(255, 255, 255));
previewLegal.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
previewLegal.setText("Legal");
previewLegal.setMaximumSize(new java.awt.Dimension(150, 50));
previewLegal.setMinimumSize(new java.awt.Dimension(75, 25));
previewLegal.setName("previewLegal"); // NOI18N
previewLegal.setOpaque(true);
previewLegal.setPreferredSize(new java.awt.Dimension(75, 25));
add(previewLegal);
previewNotLegal.setBackground(new java.awt.Color(191, 84, 74));
previewNotLegal.setForeground(new java.awt.Color(255, 255, 255));
previewNotLegal.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
previewNotLegal.setText("Not Legal");
previewNotLegal.setMaximumSize(new java.awt.Dimension(150, 50));
previewNotLegal.setMinimumSize(new java.awt.Dimension(75, 25));
previewNotLegal.setName("previewNotLegal"); // NOI18N
previewNotLegal.setOpaque(true);
previewNotLegal.setPreferredSize(new java.awt.Dimension(75, 25));
add(previewNotLegal);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel previewLegal;
private javax.swing.JLabel previewNotLegal;
private javax.swing.JLabel previewUnknown;
// End of variables declaration//GEN-END:variables
private void initDeckLabels() {
remove(previewUnknown);
remove(previewLegal);
remove(previewNotLegal);
Stream.of(
// most popular
new Standard(), new Pioneer(), new Modern(), new Legacy(), new Vintage(), new Pauper(),
// common
new Commander(), new Oathbreaker(), new Brawl(),
// other
new Frontier(), new HistoricalType2(), new PennyDreadfulCommander()
// not used: new Eternal(), new Momir(), new TinyLeaders()
).forEach(this::addLegalityLabel);
addHidePanelButton();
revalidate();
repaint();
}
protected LegalityLabel addLegalityLabel(DeckValidator validator) {
LegalityLabel label = new LegalityLabel(validator);
add(label);
return label;
}
protected void addHidePanelButton() {
JButton button = LegalityLabel.createHideButton();
button.addActionListener(e -> this.setVisible(false));
add(button);
}
public void validateDeck(Deck deck) {
Arrays.stream(getComponents())
.filter(LegalityLabel.class::isInstance)
.map(LegalityLabel.class::cast)
.forEach(label -> label.validateDeck(deck));
}
}

View file

@ -562,8 +562,8 @@ public class MageBook extends JComponent {
Constructor<?> cons = c.getConstructor();
Object newToken = cons.newInstance();
if (newToken instanceof Token) {
((Token) newToken).setExpansionSetCodeForImage(set);
((Token) newToken).setOriginalExpansionSetCode(set);
((Token) newToken).setExpansionSetCodeForImage(set);
((Token) newToken).setTokenType(token.getType());
tokens.add((Token) newToken);
}
@ -634,6 +634,10 @@ public class MageBook extends JComponent {
}
}
if (emblems.size() == 0) {
return emblems;
}
int totalTokens = getTotalNumTokens(set);
int start = 0;
if (!(page * conf.CARDS_PER_PAGE <= totalTokens && (page + 1) * conf.CARDS_PER_PAGE >= totalTokens)) {
@ -917,8 +921,8 @@ public class MageBook extends JComponent {
private int currentPage = 0;
private String currentSet = "RTR";
private int currentCardsInSet = 0;
private int currentCardsNotInSet = 0;
private final int currentCardsInSet = 0;
private final int currentCardsNotInSet = 0;
private static CardDimensions cardDimensions = new CardDimensions(1.2d);
private static final Logger log = Logger.getLogger(MageBook.class);

View file

@ -1,5 +1,14 @@
package mage.client.dialog;
import java.awt.*;
import java.beans.PropertyVetoException;
import java.util.EnumSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.UUID;
import javax.swing.*;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
import mage.client.cards.BigCard;
import mage.client.util.GUISizeHelper;
import mage.client.util.ImageHelper;
@ -13,15 +22,6 @@ import mage.view.SimpleCardsView;
import org.apache.log4j.Logger;
import org.mage.plugins.card.utils.impl.ImageManagerImpl;
import javax.swing.*;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
import java.awt.*;
import java.beans.PropertyVetoException;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.UUID;
/**
* @author BetaSteward_at_googlemail.com, JayDi85
*/
@ -30,7 +30,7 @@ public class CardInfoWindowDialog extends MageDialog {
private static final Logger LOGGER = Logger.getLogger(CardInfoWindowDialog.class);
public enum ShowType {
REVEAL, REVEAL_TOP_LIBRARY, LOOKED_AT, EXILE, GRAVEYARD, OTHER
REVEAL, REVEAL_TOP_LIBRARY, LOOKED_AT, EXILE, GRAVEYARD, COMPANION, OTHER
}
private final ShowType showType;
@ -72,6 +72,10 @@ public class CardInfoWindowDialog extends MageDialog {
case EXILE:
this.setFrameIcon(new ImageIcon(ImageManagerImpl.instance.getExileImage()));
break;
case COMPANION:
this.setFrameIcon(new ImageIcon(ImageManagerImpl.instance.getTokenIconImage()));
this.setClosable(false);
break;
default:
// no icon yet
}
@ -170,13 +174,17 @@ public class CardInfoWindowDialog extends MageDialog {
Set<String> cardTypesPresent = new LinkedHashSet<String>() {
};
for (CardView card : cardsView.values()) {
Set<CardType> cardTypes = card.getCardTypes();
Set<CardType> cardTypes = EnumSet.noneOf(CardType.class);
cardTypes.addAll(card.getCardTypes());
for (CardType cardType : cardTypes) {
cardTypesPresent.add(cardType.toString());
}
}
if (cardTypesPresent.isEmpty()) return 0;
else return cardTypesPresent.size();
if (cardTypesPresent.isEmpty()) {
return 0;
} else {
return cardTypesPresent.size();
}
}
/**

View file

@ -324,10 +324,12 @@
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
<Component id="btnFindMain" min="-2" pref="90" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="btnFindUs" min="-2" pref="90" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="btnFindMain" min="-2" pref="80" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnFindEU" min="-2" pref="80" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnFindUs" min="-2" pref="80" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnFindBeta" min="-2" pref="90" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="btnFindLocal" min="-2" pref="90" max="-2" attributes="0"/>
@ -347,6 +349,7 @@
<Component id="btnFindUs" alignment="3" min="-2" pref="30" max="-2" attributes="0"/>
<Component id="btnFindBeta" alignment="3" min="-2" pref="30" max="-2" attributes="0"/>
<Component id="btnFindOther" alignment="3" min="-2" pref="30" max="-2" attributes="0"/>
<Component id="btnFindEU" alignment="3" min="-2" pref="30" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
</Group>
@ -360,8 +363,7 @@
<Image iconType="3" name="/flags/de.png"/>
</Property>
<Property name="text" type="java.lang.String" value="X"/>
<Property name="toolTipText" type="java.lang.String" value="Connect to xmage.de (Europe, most popular, registration needs)"/>
<Property name="actionCommand" type="java.lang.String" value="connectXmageDe"/>
<Property name="toolTipText" type="java.lang.String" value="Connect to xmage.de (first Europe server, most popular, registration needs)"/>
<Property name="alignmentY" type="float" value="0.0"/>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[2, 2, 2, 2]"/>
@ -372,32 +374,29 @@
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[42, 23]"/>
</Property>
<Property name="name" type="java.lang.String" value="connectXmageDeBtn" noResource="true"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[23, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="connectXmageDe"/>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnFindMainActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnFindLocal">
<Properties>
<Property name="text" type="java.lang.String" value="LOCAL, AI"/>
<Property name="toolTipText" type="java.lang.String" value="Connect to localhost, AI enabled (run local server from launcher)"/>
<Property name="actionCommand" type="java.lang.String" value="connectLocalhost"/>
<Property name="alignmentY" type="float" value="0.0"/>
<Property name="horizontalTextPosition" type="int" value="0"/>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[2, 2, 2, 2]"/>
</Property>
<Property name="name" type="java.lang.String" value="connectLocalhostBtn" noResource="true"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[23, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="connectLocalhost"/>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnFindLocalActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnFindBeta">
@ -414,7 +413,7 @@
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnFindBetaconnectLocalhost"/>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnFindBetaActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnFindUs">
@ -424,29 +423,51 @@
</Property>
<Property name="text" type="java.lang.String" value="US"/>
<Property name="toolTipText" type="java.lang.String" value="Connect to us.xmage.today (USA, use any username without registration)"/>
<Property name="actionCommand" type="java.lang.String" value="connectXmageus"/>
<Property name="alignmentY" type="float" value="0.0"/>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[2, 2, 2, 2]"/>
</Property>
<Property name="name" type="java.lang.String" value="connectXmageusBtn" noResource="true"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[23, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="connectXmageus"/>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnFindUsActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnFindOther">
<Properties>
<Property name="text" type="java.lang.String" value="Other servers..."/>
<Property name="text" type="java.lang.String" value="Other..."/>
<Property name="toolTipText" type="java.lang.String" value="Choose server from full servers list"/>
<Property name="horizontalTextPosition" type="int" value="0"/>
<Property name="name" type="java.lang.String" value="findServerBtn" noResource="true"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="findPublicServerActionPerformed"/>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnFindOtherActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnFindEU">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/flags/europeanunion.png"/>
</Property>
<Property name="text" type="java.lang.String" value="EU"/>
<Property name="toolTipText" type="java.lang.String" value="Connect to eu.xmage.today (second Europe server, use any username without registration)"/>
<Property name="alignmentY" type="float" value="0.0"/>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[2, 2, 2, 2]"/>
</Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[42, 23]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[42, 23]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[23, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnFindEUActionPerformed"/>
</Events>
</Component>
</SubComponents>
@ -463,7 +484,7 @@
<EmptySpace max="-2" attributes="0"/>
<Component id="txtPort" min="-2" pref="75" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnCheckStatus" pref="205" max="32767" attributes="0"/>
<Component id="btnCheckStatus" max="32767" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
</Group>
</Group>

View file

@ -93,6 +93,118 @@ public class ConnectDialog extends MageDialog {
MagePreferences.saveLastServer();
}
private void setServerSettings(String address, String port, boolean needRegistration) {
this.txtServer.setText(address);
this.txtPort.setText(port);
this.txtUserName.setText(MagePreferences.getUserName(address));
if (needRegistration) {
this.txtPassword.setText(MagePreferences.getPassword(address));
} else {
this.txtPassword.setText("");
}
}
private void chooseAndSetServerSettingsFromOther() {
BufferedReader in = null;
Writer output = null;
try {
String serverUrl = PreferencesDialog.getCachedValue(KEY_CONNECTION_URL_SERVER_LIST, "http://xmage.de/files/server-list.txt");
if (serverUrl.contains("xmage.info/files/")) {
serverUrl = serverUrl.replace("xmage.info/files/", "xmage.de/files/"); // replace old URL if still saved
PreferencesDialog.saveValue(KEY_CONNECTION_URL_SERVER_LIST, serverUrl);
}
URL serverListURL = new URL(serverUrl);
Connection.ProxyType configProxyType = Connection.ProxyType.valueByText(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PROXY_TYPE, "None"));
Proxy p = null;
Proxy.Type type = Proxy.Type.DIRECT;
switch (configProxyType) {
case HTTP:
type = Proxy.Type.HTTP;
break;
case SOCKS:
type = Proxy.Type.SOCKS;
break;
case NONE:
default:
p = Proxy.NO_PROXY;
break;
}
if (p == null || !p.equals(Proxy.NO_PROXY)) {
try {
String address = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PROXY_ADDRESS, "");
Integer port = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PROXY_PORT, "80"));
p = new Proxy(type, new InetSocketAddress(address, port));
} catch (Exception ex) {
throw new RuntimeException("Gui_DownloadPictures : error 1 - " + ex);
}
}
if (p == null) {
JOptionPane.showMessageDialog(null, "Couldn't configure Proxy object!", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
boolean URLNotFound = false;
try {
in = new BufferedReader(new InputStreamReader(serverListURL.openConnection(p).getInputStream()));
} catch (SocketTimeoutException | FileNotFoundException | UnknownHostException ex) {
logger.warn("Could not read serverlist from: " + serverListURL.toString());
File f = new File("serverlist.txt");
if (f.exists() && !f.isDirectory()) {
logger.info("Using buffered serverlist: serverlist.txt");
URLNotFound = true;
in = new BufferedReader(new FileReader("serverlist.txt"));
}
}
List<String> servers = new ArrayList<>();
if (in != null) {
if (!URLNotFound) {
// write serverlist to be able to read if URL is not available
File file = new File("serverlist.txt");
if (file.exists() && !file.isDirectory()) {
file.delete();
}
output = new BufferedWriter(new FileWriter(file));
}
String inputLine;
while ((inputLine = in.readLine()) != null) {
logger.debug("Found server: " + inputLine);
servers.add(inputLine);
if (output != null) {
output.append(inputLine).append('\n');
}
}
}
if (servers.isEmpty()) {
JOptionPane.showMessageDialog(null, "Couldn't find any server.");
return;
}
String selectedServer = (String) JOptionPane.showInputDialog(null,
"Choose XMage Public Server:", "Input",
JOptionPane.INFORMATION_MESSAGE, null, servers.toArray(),
servers.get(0));
if (selectedServer != null) {
String[] params = selectedServer.split(":");
if (params.length == 3) {
setServerSettings(params[1], params[2], true);
} else {
JOptionPane.showMessageDialog(null, "Wrong server data format.");
}
}
} catch (Exception ex) {
logger.error(ex, ex);
} finally {
StreamUtils.closeQuietly(in);
StreamUtils.closeQuietly(output);
}
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
@ -127,6 +239,7 @@ public class ConnectDialog extends MageDialog {
btnFindBeta = new javax.swing.JButton();
btnFindUs = new javax.swing.JButton();
btnFindOther = new javax.swing.JButton();
btnFindEU = new javax.swing.JButton();
panelServer = new javax.swing.JPanel();
txtServer = new javax.swing.JTextField();
txtPort = new javax.swing.JTextField();
@ -242,31 +355,27 @@ public class ConnectDialog extends MageDialog {
btnFindMain.setIcon(new javax.swing.ImageIcon(getClass().getResource("/flags/de.png"))); // NOI18N
btnFindMain.setText("X");
btnFindMain.setToolTipText("Connect to xmage.de (Europe, most popular, registration needs)");
btnFindMain.setActionCommand("connectXmageDe");
btnFindMain.setToolTipText("Connect to xmage.de (first Europe server, most popular, registration needs)");
btnFindMain.setAlignmentY(0.0F);
btnFindMain.setMargin(new java.awt.Insets(2, 2, 2, 2));
btnFindMain.setMaximumSize(new java.awt.Dimension(42, 23));
btnFindMain.setMinimumSize(new java.awt.Dimension(42, 23));
btnFindMain.setName("connectXmageDeBtn"); // NOI18N
btnFindMain.setPreferredSize(new java.awt.Dimension(23, 23));
btnFindMain.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
connectXmageDe(evt);
btnFindMainActionPerformed(evt);
}
});
btnFindLocal.setText("LOCAL, AI");
btnFindLocal.setToolTipText("Connect to localhost, AI enabled (run local server from launcher)");
btnFindLocal.setActionCommand("connectLocalhost");
btnFindLocal.setAlignmentY(0.0F);
btnFindLocal.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
btnFindLocal.setMargin(new java.awt.Insets(2, 2, 2, 2));
btnFindLocal.setName("connectLocalhostBtn"); // NOI18N
btnFindLocal.setPreferredSize(new java.awt.Dimension(23, 23));
btnFindLocal.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
connectLocalhost(evt);
btnFindLocalActionPerformed(evt);
}
});
@ -278,31 +387,42 @@ public class ConnectDialog extends MageDialog {
btnFindBeta.setPreferredSize(new java.awt.Dimension(23, 23));
btnFindBeta.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnFindBetaconnectLocalhost(evt);
btnFindBetaActionPerformed(evt);
}
});
btnFindUs.setIcon(new javax.swing.ImageIcon(getClass().getResource("/flags/us.png"))); // NOI18N
btnFindUs.setText("US");
btnFindUs.setToolTipText("Connect to us.xmage.today (USA, use any username without registration)");
btnFindUs.setActionCommand("connectXmageus");
btnFindUs.setAlignmentY(0.0F);
btnFindUs.setMargin(new java.awt.Insets(2, 2, 2, 2));
btnFindUs.setName("connectXmageusBtn"); // NOI18N
btnFindUs.setPreferredSize(new java.awt.Dimension(23, 23));
btnFindUs.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
connectXmageus(evt);
btnFindUsActionPerformed(evt);
}
});
btnFindOther.setText("Other servers...");
btnFindOther.setText("Other...");
btnFindOther.setToolTipText("Choose server from full servers list");
btnFindOther.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
btnFindOther.setName("findServerBtn"); // NOI18N
btnFindOther.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
findPublicServerActionPerformed(evt);
btnFindOtherActionPerformed(evt);
}
});
btnFindEU.setIcon(new javax.swing.ImageIcon(getClass().getResource("/flags/europeanunion.png"))); // NOI18N
btnFindEU.setText("EU");
btnFindEU.setToolTipText("Connect to eu.xmage.today (second Europe server, use any username without registration)");
btnFindEU.setAlignmentY(0.0F);
btnFindEU.setMargin(new java.awt.Insets(2, 2, 2, 2));
btnFindEU.setMaximumSize(new java.awt.Dimension(42, 23));
btnFindEU.setMinimumSize(new java.awt.Dimension(42, 23));
btnFindEU.setPreferredSize(new java.awt.Dimension(23, 23));
btnFindEU.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnFindEUActionPerformed(evt);
}
});
@ -312,9 +432,11 @@ public class ConnectDialog extends MageDialog {
panelFastLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelFastLayout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(btnFindMain, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnFindMain, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnFindUs, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnFindEU, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnFindUs, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnFindBeta, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
@ -332,7 +454,8 @@ public class ConnectDialog extends MageDialog {
.addComponent(btnFindLocal, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnFindUs, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnFindBeta, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnFindOther, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(btnFindOther, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnFindEU, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(0, 0, 0))
);
@ -368,7 +491,7 @@ public class ConnectDialog extends MageDialog {
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(txtPort, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnCheckStatus, javax.swing.GroupLayout.DEFAULT_SIZE, 205, Short.MAX_VALUE)
.addComponent(btnCheckStatus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
panelServerLayout.setVerticalGroup(
@ -615,110 +738,7 @@ public class ConnectDialog extends MageDialog {
}//GEN-LAST:event_chkAutoConnectActionPerformed
private void findPublicServerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
BufferedReader in = null;
Writer output = null;
try {
String serverUrl = PreferencesDialog.getCachedValue(KEY_CONNECTION_URL_SERVER_LIST, "http://xmage.de/files/server-list.txt");
if (serverUrl.contains("xmage.info/files/")) {
serverUrl = serverUrl.replace("xmage.info/files/", "xmage.de/files/"); // replace old URL if still saved
PreferencesDialog.saveValue(KEY_CONNECTION_URL_SERVER_LIST, serverUrl);
}
URL serverListURL = new URL(serverUrl);
Connection.ProxyType configProxyType = Connection.ProxyType.valueByText(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PROXY_TYPE, "None"));
Proxy p = null;
Proxy.Type type = Proxy.Type.DIRECT;
switch (configProxyType) {
case HTTP:
type = Proxy.Type.HTTP;
break;
case SOCKS:
type = Proxy.Type.SOCKS;
break;
case NONE:
default:
p = Proxy.NO_PROXY;
break;
}
if (p == null || !p.equals(Proxy.NO_PROXY)) {
try {
String address = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PROXY_ADDRESS, "");
Integer port = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PROXY_PORT, "80"));
p = new Proxy(type, new InetSocketAddress(address, port));
} catch (Exception ex) {
throw new RuntimeException("Gui_DownloadPictures : error 1 - " + ex);
}
}
if (p == null) {
JOptionPane.showMessageDialog(null, "Couldn't configure Proxy object!", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
boolean URLNotFound = false;
try {
in = new BufferedReader(new InputStreamReader(serverListURL.openConnection(p).getInputStream()));
} catch (SocketTimeoutException | FileNotFoundException | UnknownHostException ex) {
logger.warn("Could not read serverlist from: " + serverListURL.toString());
File f = new File("serverlist.txt");
if (f.exists() && !f.isDirectory()) {
logger.info("Using buffered serverlist: serverlist.txt");
URLNotFound = true;
in = new BufferedReader(new FileReader("serverlist.txt"));
}
}
List<String> servers = new ArrayList<>();
if (in != null) {
if (!URLNotFound) {
// write serverlist to be able to read if URL is not available
File file = new File("serverlist.txt");
if (file.exists() && !file.isDirectory()) {
file.delete();
}
output = new BufferedWriter(new FileWriter(file));
}
String inputLine;
while ((inputLine = in.readLine()) != null) {
logger.debug("Found server: " + inputLine);
servers.add(inputLine);
if (output != null) {
output.append(inputLine).append('\n');
}
}
}
if (servers.isEmpty()) {
JOptionPane.showMessageDialog(null, "Couldn't find any server.");
return;
}
String selectedServer = (String) JOptionPane.showInputDialog(null,
"Choose XMage Public Server:", "Input",
JOptionPane.INFORMATION_MESSAGE, null, servers.toArray(),
servers.get(0));
if (selectedServer != null) {
String[] params = selectedServer.split(":");
if (params.length == 3) {
String serverAddress = params[1];
this.txtServer.setText(serverAddress);
this.txtPort.setText(params[2]);
// Update userName and password according to the chosen server.
this.txtUserName.setText(MagePreferences.getUserName(serverAddress));
this.txtPassword.setText(MagePreferences.getPassword(serverAddress));
} else {
JOptionPane.showMessageDialog(null, "Wrong server data format.");
}
}
} catch (Exception ex) {
logger.error(ex, ex);
} finally {
StreamUtils.closeQuietly(in);
StreamUtils.closeQuietly(output);
}
}//GEN-LAST:event_jButton1ActionPerformed
private void jProxySettingsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jProxySettingsButtonActionPerformed
@ -786,10 +806,6 @@ public class ConnectDialog extends MageDialog {
doFastFlagSearch();
}//GEN-LAST:event_btnFlagSearchActionPerformed
private void btnFindBetaconnectLocalhost(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFindBetaconnectLocalhost
connectBeta(evt);
}//GEN-LAST:event_btnFindBetaconnectLocalhost
private void btnCheckStatusActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCheckStatusActionPerformed
if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
try {
@ -804,6 +820,30 @@ public class ConnectDialog extends MageDialog {
MageFrame.getInstance().showWhatsNewDialog(true);
}//GEN-LAST:event_btnWhatsNewActionPerformed
private void btnFindMainActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFindMainActionPerformed
setServerSettings("xmage.de", "17171", true);
}//GEN-LAST:event_btnFindMainActionPerformed
private void btnFindEUActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFindEUActionPerformed
setServerSettings("eu.xmage.today", "17171", false);
}//GEN-LAST:event_btnFindEUActionPerformed
private void btnFindUsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFindUsActionPerformed
setServerSettings("us.xmage.today", "17171", false);
}//GEN-LAST:event_btnFindUsActionPerformed
private void btnFindBetaActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFindBetaActionPerformed
setServerSettings("beta.xmage.today", "17171", false);
}//GEN-LAST:event_btnFindBetaActionPerformed
private void btnFindLocalActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFindLocalActionPerformed
setServerSettings("localhost", "17171", false);
}//GEN-LAST:event_btnFindLocalActionPerformed
private void btnFindOtherActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFindOtherActionPerformed
chooseAndSetServerSettingsFromOther();
}//GEN-LAST:event_btnFindOtherActionPerformed
private void doFastFlagSearch() {
Choice choice = new ChoiceImpl(false);
@ -852,6 +892,7 @@ public class ConnectDialog extends MageDialog {
private javax.swing.JButton btnCheckStatus;
private javax.swing.JButton btnConnect;
private javax.swing.JButton btnFindBeta;
private javax.swing.JButton btnFindEU;
private javax.swing.JButton btnFindLocal;
private javax.swing.JButton btnFindMain;
private javax.swing.JButton btnFindOther;

View file

@ -31,15 +31,12 @@
*/
public class GameEndDialog extends MageDialog {
private final DateFormat df = DateFormat.getDateTimeInstance();
/**
* Creates new form GameEndDialog
*
* @param gameEndView
*/
public GameEndDialog(GameEndView gameEndView) {
initComponents();
this.modal = true;
@ -47,7 +44,14 @@
pnlText.setBackground(new Color(240, 240, 240, 140));
Rectangle r = new Rectangle(610, 250);
Image image = ImageHelper.getImageFromResources(gameEndView.hasWon() ? "/game_won.jpg" : "/game_lost.jpg");
Image image;
if (gameEndView.hasWon()) {
image = ImageHelper.getImageFromResources(PreferencesDialog.getCurrentTheme().getWinlossPath("game_won.jpg"));
} else {
image = ImageHelper.getImageFromResources(PreferencesDialog.getCurrentTheme().getWinlossPath("game_lost.jpg"));
}
BufferedImage imageResult = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r);
ImageIcon icon = new ImageIcon(imageResult);
lblResultImage.setIcon(icon);
@ -61,6 +65,8 @@
this.saveGameLog(gameEndView);
}
DateFormat df = DateFormat.getDateTimeInstance();
// game duration
txtDurationGame.setText(" " + Format.getDuration(gameEndView.getStartTime(), gameEndView.getEndTime()));
txtDurationGame.setToolTipText(new StringBuilder(df.format(gameEndView.getStartTime())).append(" - ").append(df.format(gameEndView.getEndTime())).toString());

View file

@ -890,7 +890,7 @@ public class NewTableDialog extends MageDialog {
this.spnFreeMulligans.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_NUMBER_OF_FREE_MULLIGANS + versionStr, "0")));
this.cbMulligan.setSelectedItem(MulliganType.valueByName(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_MULLIGAN_TYPE + versionStr, MulliganType.GAME_DEFAULT.toString())));
int range = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_RANGE + versionStr, "1"));
int range = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_RANGE + versionStr, "0"));
for (RangeOfInfluence roi : RangeOfInfluence.values()) {
if (roi.getRange() == range) {
this.cbRange.setSelectedItem(roi);

View file

@ -1203,6 +1203,7 @@ public class NewTournamentDialog extends MageDialog {
tOptions.getLimitedOptions().setConstructionTime((Integer) this.spnConstructTime.getValue() * 60);
tOptions.getLimitedOptions().setIsRandom(tournamentType.isRandom());
tOptions.getLimitedOptions().setIsRichMan(tournamentType.isRichMan());
tOptions.getLimitedOptions().setIsJumpstart(tournamentType.isJumpstart());
if (tournamentType.isCubeBooster()) {
tOptions.getLimitedOptions().setDraftCubeName(this.cbDraftCube.getSelectedItem().toString());
if (!(cubeFromDeckFilename.isEmpty())) {

View file

@ -230,12 +230,12 @@ public class PickCheckBoxDialog extends MageDialog {
if (filter == null) {
filter = "";
}
filter = filter.toLowerCase();
filter = filter.toLowerCase(Locale.ENGLISH);
this.dataModel.clear();
this.m_dataModel.clear();
for (KeyValueItem item : this.allItems) {
if (!choice.isSearchEnabled() || item.Value.toLowerCase().contains(filter)) {
if (!choice.isSearchEnabled() || item.Value.toLowerCase(Locale.ENGLISH).contains(filter)) {
this.dataModel.addElement(item);
this.m_dataModel.addElement(item.getObjectValue());
}

View file

@ -1,6 +1,9 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.9" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JInternalFrameFormInfo">
<Properties>
<Property name="resizable" type="boolean" value="true"/>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
</SyntheticProperties>
@ -39,7 +42,7 @@
<EmptySpace max="-2" attributes="0"/>
<Component id="panelSearch" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="scrollList" pref="246" max="32767" attributes="0"/>
<Component id="scrollList" pref="282" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="panelCommands" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
@ -55,8 +58,8 @@
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="labelMessage" alignment="1" pref="210" max="32767" attributes="0"/>
<Component id="labelSubMessage" alignment="1" pref="210" max="32767" attributes="0"/>
<Component id="labelMessage" alignment="1" pref="337" max="32767" attributes="0"/>
<Component id="labelSubMessage" alignment="1" pref="337" max="32767" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
</Group>

View file

@ -1,25 +1,22 @@
package mage.client.dialog;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import mage.choices.Choice;
import mage.client.MageFrame;
import mage.client.util.gui.MageDialogState;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.List;
/**
* @author JayDi85
*/
public class PickChoiceDialog extends MageDialog {
Choice choice;
List<KeyValueItem> allItems = new ArrayList<>();
java.util.List<KeyValueItem> allItems = new ArrayList<>();
DefaultListModel<KeyValueItem> dataModel = new DefaultListModel<>();
final private static String HTML_TEMPLATE = "<html><div style='text-align: center;'>%s</div></html>";
@ -152,8 +149,11 @@ public class PickChoiceDialog extends MageDialog {
} else {
MageFrame.getDesktop().add(this, JLayeredPane.PALETTE_LAYER);
}
if (mageDialogState != null) mageDialogState.setStateToDialog(this);
else this.makeWindowCentered();
if (mageDialogState != null) {
mageDialogState.setStateToDialog(this);
} else {
this.makeWindowCentered();
}
// final load
loadData();
@ -269,6 +269,7 @@ public class PickChoiceDialog extends MageDialog {
}
class KeyValueItem {
private final String Key;
private final String Value;
@ -312,6 +313,8 @@ public class PickChoiceDialog extends MageDialog {
btOK = new javax.swing.JButton();
btCancel = new javax.swing.JButton();
setResizable(true);
labelMessage.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
labelMessage.setText("<html><div style='text-align: center;'>example long message example long message example long message example long message example long message</div></html>");
@ -325,8 +328,8 @@ public class PickChoiceDialog extends MageDialog {
panelHeaderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelHeaderLayout.createSequentialGroup()
.addGroup(panelHeaderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(labelMessage, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 210, Short.MAX_VALUE)
.addComponent(labelSubMessage, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 210, Short.MAX_VALUE))
.addComponent(labelMessage, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 337, Short.MAX_VALUE)
.addComponent(labelSubMessage, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 337, Short.MAX_VALUE))
.addGap(0, 0, 0))
);
panelHeaderLayout.setVerticalGroup(
@ -364,15 +367,9 @@ public class PickChoiceDialog extends MageDialog {
);
listChoices.setModel(new javax.swing.AbstractListModel() {
String[] strings = {"item1", "item2", "item3"};
public int getSize() {
return strings.length;
}
public Object getElementAt(int i) {
return strings[i];
}
String[] strings = { "item1", "item2", "item3" };
public int getSize() { return strings.length; }
public Object getElementAt(int i) { return strings[i]; }
});
scrollList.setViewportView(listChoices);
@ -402,7 +399,7 @@ public class PickChoiceDialog extends MageDialog {
.addContainerGap())
);
panelCommandsLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, btCancel, btOK);
panelCommandsLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {btCancel, btOK});
panelCommandsLayout.setVerticalGroup(
panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -437,7 +434,7 @@ public class PickChoiceDialog extends MageDialog {
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(panelSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(scrollList, javax.swing.GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE)
.addComponent(scrollList, javax.swing.GroupLayout.DEFAULT_SIZE, 282, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(panelCommands, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())

View file

@ -6236,6 +6236,114 @@
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="tabThemes">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
<JTabbedPaneConstraints tabName="Themes">
<Property name="tabTitle" type="java.lang.String" value="Themes"/>
</JTabbedPaneConstraints>
</Constraint>
</Constraints>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="750" max="32767" attributes="0"/>
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="themesCategory" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="526" max="32767" attributes="0"/>
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="21" max="-2" attributes="0"/>
<Component id="themesCategory" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="430" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="themesCategory">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="Themes">
<Border PropertyName="innerBorder" info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
<EtchetBorder/>
</Border>
</TitledBorder>
</Border>
</Property>
</Properties>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="lbSelectLabel" min="-2" pref="96" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lbThemeHint" min="-2" max="-2" attributes="0"/>
<Component id="cbTheme" min="-2" pref="303" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="303" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="1" attributes="0">
<Component id="cbTheme" min="-2" max="-2" attributes="0"/>
<Component id="lbSelectLabel" min="-2" pref="22" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="lbThemeHint" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="lbSelectLabel">
<Properties>
<Property name="horizontalAlignment" type="int" value="2"/>
<Property name="text" type="java.lang.String" value="Select a theme:"/>
<Property name="toolTipText" type="java.lang.String" value=""/>
<Property name="horizontalTextPosition" type="int" value="10"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[110, 16]"/>
</Property>
<Property name="verticalTextPosition" type="int" value="1"/>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="cbTheme">
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbThemeActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;ThemeType&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="lbThemeHint">
<Properties>
<Property name="text" type="java.lang.String" value="Requires a restart to apply new theme."/>
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Container>
<Component class="javax.swing.JButton" name="saveButton">

View file

@ -3,6 +3,7 @@ package mage.client.dialog;
import mage.client.MageFrame;
import mage.client.SessionHandler;
import mage.client.components.KeyBindButton;
import mage.client.themes.ThemeType;
import mage.client.util.CardLanguage;
import mage.client.util.ClientDefaultSettings;
import mage.client.util.GUISizeHelper;
@ -100,6 +101,9 @@ public class PreferencesDialog extends javax.swing.JDialog {
public static final String KEY_BIG_CARD_TOGGLED = "bigCardToggled";
// Themes
public static final String KEY_THEME = "themeSelection";
// Phases
public static final String UPKEEP_YOU = "upkeepYou";
public static final String DRAW_YOU = "drawYou";
@ -156,7 +160,8 @@ public class PreferencesDialog extends javax.swing.JDialog {
public static final String KEY_TABLES_DIVIDER_LOCATION_4 = "tablePanelDividerLocation4";
// Positions of deck editor divider bars
public static final String KEY_EDITOR_HORIZONTAL_DIVIDER_LOCATION = "editorHorizontalDividerLocation";
public static final String KEY_EDITOR_HORIZONTAL_DIVIDER_LOCATION_NORMAL = "editorHorizontalDividerLocationNormal";
public static final String KEY_EDITOR_HORIZONTAL_DIVIDER_LOCATION_LIMITED = "editorHorizontalDividerLocationLimited";
public static final String KEY_EDITOR_DECKAREA_SETTINGS = "editorDeckAreaSettings";
// user list
@ -310,6 +315,17 @@ public class PreferencesDialog extends javax.swing.JDialog {
private static int selectedAvatarId;
private static ThemeType currentTheme = null;
public static ThemeType getCurrentTheme() {
if (currentTheme == null) {
currentTheme = ThemeType.valueByName(getCachedValue(KEY_THEME, "Default"));
logger.info("Using GUI theme: " + currentTheme.getName());
}
return currentTheme;
}
private final JFileChooser fc = new JFileChooser();
{
@ -359,6 +375,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
initComponents();
txtImageFolderPath.setEditable(false);
cbProxyType.setModel(new DefaultComboBoxModel<>(Connection.ProxyType.values()));
cbTheme.setModel(new DefaultComboBoxModel<>(ThemeType.values()));
addAvatars();
cbPreferedImageLanguage.setModel(new DefaultComboBoxModel<>(CardLanguage.toList()));
@ -469,7 +486,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
txtImageFolderPath = new javax.swing.JTextField();
btnBrowseImageLocation = new javax.swing.JButton();
cbSaveToZipFiles = new javax.swing.JCheckBox();
cbPreferedImageLanguage = new javax.swing.JComboBox<>();
cbPreferedImageLanguage = new javax.swing.JComboBox<String>();
labelPreferedImageLanguage = new javax.swing.JLabel();
labelNumberOfDownloadThreads = new javax.swing.JLabel();
cbNumberOfDownloadThreads = new javax.swing.JComboBox();
@ -530,7 +547,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
txtURLServerList = new javax.swing.JTextField();
jLabel17 = new javax.swing.JLabel();
lblProxyType = new javax.swing.JLabel();
cbProxyType = new javax.swing.JComboBox<>();
cbProxyType = new javax.swing.JComboBox<ProxyType>();
pnlProxySettings = new javax.swing.JPanel();
pnlProxy = new javax.swing.JPanel();
lblProxyServer = new javax.swing.JLabel();
@ -568,6 +585,11 @@ public class PreferencesDialog extends javax.swing.JDialog {
keyToggleRecordMacro = new KeyBindButton(this, KEY_CONTROL_TOGGLE_MACRO);
labelSwitchChat = new javax.swing.JLabel();
keySwitchChat = new KeyBindButton(this, KEY_CONTROL_SWITCH_CHAT);
tabThemes = new javax.swing.JPanel();
themesCategory = new javax.swing.JPanel();
lbSelectLabel = new javax.swing.JLabel();
cbTheme = new javax.swing.JComboBox<ThemeType>();
lbThemeHint = new javax.swing.JLabel();
saveButton = new javax.swing.JButton();
exitButton = new javax.swing.JButton();
@ -1534,7 +1556,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
});
cbPreferedImageLanguage.setMaximumRowCount(20);
cbPreferedImageLanguage.setModel(new javax.swing.DefaultComboBoxModel<>(new String[]{"Item 1", "Item 2", "Item 3", "Item 4"}));
cbPreferedImageLanguage.setModel(new javax.swing.DefaultComboBoxModel(new String[]{"Item 1", "Item 2", "Item 3", "Item 4"}));
labelPreferedImageLanguage.setText("Default images language:");
labelPreferedImageLanguage.setFocusable(false);
@ -2663,6 +2685,70 @@ public class PreferencesDialog extends javax.swing.JDialog {
tabsPanel.addTab("Controls", tabControls);
themesCategory.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Themes"));
lbSelectLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
lbSelectLabel.setText("Select a theme:");
lbSelectLabel.setToolTipText("");
lbSelectLabel.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING);
lbSelectLabel.setPreferredSize(new java.awt.Dimension(110, 16));
lbSelectLabel.setVerticalTextPosition(javax.swing.SwingConstants.TOP);
cbTheme.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cbThemeActionPerformed(evt);
}
});
lbThemeHint.setText("Requires a restart to apply new theme.");
org.jdesktop.layout.GroupLayout themesCategoryLayout = new org.jdesktop.layout.GroupLayout(themesCategory);
themesCategory.setLayout(themesCategoryLayout);
themesCategoryLayout.setHorizontalGroup(
themesCategoryLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(themesCategoryLayout.createSequentialGroup()
.addContainerGap()
.add(lbSelectLabel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 96, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(themesCategoryLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(lbThemeHint)
.add(cbTheme, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 303, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
.addContainerGap(303, Short.MAX_VALUE))
);
themesCategoryLayout.setVerticalGroup(
themesCategoryLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(themesCategoryLayout.createSequentialGroup()
.add(themesCategoryLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
.add(cbTheme, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.add(lbSelectLabel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 22, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(lbThemeHint)
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
org.jdesktop.layout.GroupLayout tabThemesLayout = new org.jdesktop.layout.GroupLayout(tabThemes);
tabThemes.setLayout(tabThemesLayout);
tabThemesLayout.setHorizontalGroup(
tabThemesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(0, 750, Short.MAX_VALUE)
.add(tabThemesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(tabThemesLayout.createSequentialGroup()
.addContainerGap()
.add(themesCategory, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addContainerGap()))
);
tabThemesLayout.setVerticalGroup(
tabThemesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(0, 526, Short.MAX_VALUE)
.add(tabThemesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(tabThemesLayout.createSequentialGroup()
.add(21, 21, 21)
.add(themesCategory, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addContainerGap(430, Short.MAX_VALUE)))
);
tabsPanel.addTab("Themes", tabThemes);
saveButton.setLabel("Save");
saveButton.setMaximumSize(new java.awt.Dimension(100, 30));
saveButton.setMinimumSize(new java.awt.Dimension(100, 30));
@ -2879,6 +2965,9 @@ public class PreferencesDialog extends javax.swing.JDialog {
save(prefs, dialog.keyToggleRecordMacro);
save(prefs, dialog.keySwitchChat);
// Themes
save(prefs, dialog.cbTheme, KEY_THEME);
// Avatar
if (selectedAvatarId < MIN_AVATAR_ID || selectedAvatarId > MAX_AVATAR_ID) {
selectedAvatarId = DEFAULT_AVATAR_ID;
@ -3184,6 +3273,10 @@ public class PreferencesDialog extends javax.swing.JDialog {
}
}//GEN-LAST:event_cbUseDefaultImageFolderActionPerformed
private void cbThemeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbThemeActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_cbThemeActionPerformed
private void showProxySettings() {
Connection.ProxyType proxyType = (Connection.ProxyType) cbProxyType.getSelectedItem();
switch (proxyType) {
@ -3268,6 +3361,9 @@ public class PreferencesDialog extends javax.swing.JDialog {
// Controls
loadControlSettings(prefs);
// Themes
loadThemeSettings(prefs);
// Selected avatar
loadSelectedAvatar(prefs);
@ -3457,6 +3553,10 @@ public class PreferencesDialog extends javax.swing.JDialog {
load(prefs, dialog.keySwitchChat);
}
private static void loadThemeSettings(Preferences prefs) {
dialog.cbTheme.setSelectedItem(PreferencesDialog.getCurrentTheme());
}
private static void loadSelectedAvatar(Preferences prefs) {
getSelectedAvatar();
dialog.setSelectedId(selectedAvatarId);
@ -3916,6 +4016,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
private javax.swing.JCheckBox cbStopOnAllEnd;
private javax.swing.JCheckBox cbStopOnAllMain;
private javax.swing.JCheckBox cbStopOnNewStackObjects;
private javax.swing.JComboBox<ThemeType> cbTheme;
private javax.swing.JCheckBox cbUseDefaultBackground;
private javax.swing.JCheckBox cbUseDefaultBattleImage;
private javax.swing.JCheckBox cbUseDefaultImageFolder;
@ -4015,6 +4116,8 @@ public class PreferencesDialog extends javax.swing.JDialog {
private javax.swing.JLabel labelToggleRecordMacro;
private javax.swing.JLabel labelTooltipSize;
private javax.swing.JLabel labelYourTurn;
private javax.swing.JLabel lbSelectLabel;
private javax.swing.JLabel lbThemeHint;
private javax.swing.JLabel lblBattlefieldFeedbackColorizingMode;
private javax.swing.JLabel lblProxyPassword;
private javax.swing.JLabel lblProxyPort;
@ -4062,7 +4165,9 @@ public class PreferencesDialog extends javax.swing.JDialog {
private javax.swing.JPanel tabMain;
private javax.swing.JPanel tabPhases;
private javax.swing.JPanel tabSounds;
private javax.swing.JPanel tabThemes;
private javax.swing.JTabbedPane tabsPanel;
private javax.swing.JPanel themesCategory;
private javax.swing.JSlider tooltipDelay;
private javax.swing.JLabel tooltipDelayLabel;
private javax.swing.JTextField txtBackgroundImagePath;

View file

@ -35,6 +35,7 @@ import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
@ -202,7 +203,7 @@ public class TestCardRenderDialog extends MageDialog {
Player playerOpponent = new StubPlayer("player2", RangeOfInfluence.ALL);
game.addPlayer(playerOpponent, deck);
java.util.List<CardView> cardViews = new ArrayList<>();
List<CardView> cardViews = new ArrayList<>();
///*
cardViews.add(createPermanentCard(game, playerYou.getId(), "RNA", "263", 0, 0, 0, false)); // mountain
cardViews.add(createPermanentCard(game, playerYou.getId(), "RNA", "185", 0, 0, 0, true)); // Judith, the Scourge Diva
@ -399,7 +400,7 @@ class TestGame extends GameImpl {
private int numPlayers;
public TestGame(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) {
super(attackOption, range, mulligan, startLife);
super(attackOption, range, mulligan, startLife, 60);
}
public TestGame(final TestGame game) {

View file

@ -5,40 +5,39 @@
*
* Created on Jan 7, 2011, 2:15:48 PM
*/
package mage.client.draft;
package mage.client.draft;
import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
import mage.client.MageFrame;
import mage.client.SessionHandler;
import mage.client.components.tray.MageTray;
import mage.client.deckeditor.SortSettingDraft;
import mage.client.dialog.PreferencesDialog;
import mage.client.plugins.impl.Plugins;
import mage.client.util.*;
import mage.client.util.Event;
import mage.client.util.audio.AudioManager;
import mage.client.util.gui.BufferedImageBuilder;
import mage.constants.PlayerAction;
import mage.view.*;
import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
import mage.client.MageFrame;
import mage.client.SessionHandler;
import mage.client.components.tray.MageTray;
import mage.client.deckeditor.SortSettingDraft;
import mage.client.dialog.PreferencesDialog;
import mage.client.plugins.impl.Plugins;
import mage.client.util.Event;
import mage.client.util.*;
import mage.client.util.audio.AudioManager;
import mage.client.util.gui.BufferedImageBuilder;
import mage.constants.PlayerAction;
import mage.view.*;
import javax.swing.*;
import javax.swing.Timer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import javax.swing.Timer;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.*;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class DraftPanel extends javax.swing.JPanel {
public class DraftPanel extends javax.swing.JPanel {
private UUID draftId;
private Timer countdown;
@ -285,7 +284,7 @@ public class DraftPanel extends javax.swing.JPanel {
}
);
setMessage("Pick a card");
if (!MageFrame.getInstance().isActive()) {
if (!AppUtil.isAppActive()) {
MageTray.instance.displayMessage("Pick the next card.");
MageTray.instance.blink();
}
@ -408,7 +407,7 @@ public class DraftPanel extends javax.swing.JPanel {
if (currentBooster != null) {
String lastPick = getCardName(getLastPick(pickView.getPicks().values()));
if (lastPick != null && currentBooster.length > 1) {
draftLogger.logPick(getCurrentSetCode(), packNo, pickNo-1, lastPick, currentBooster);
draftLogger.logPick(getCurrentSetCode(), packNo, pickNo - 1, lastPick, currentBooster);
}
currentBooster = null;
}
@ -420,7 +419,7 @@ public class DraftPanel extends javax.swing.JPanel {
private String getCurrentSetCode() {
if (!setCodes.isEmpty()) {
return setCodes.get(packNo-1);
return setCodes.get(packNo - 1);
} else {
return "";
}
@ -861,4 +860,4 @@ public class DraftPanel extends javax.swing.JPanel {
private javax.swing.JTextField txtTimeRemaining;
// End of variables declaration//GEN-END:variables
}
}

View file

@ -1,39 +1,32 @@
package mage.client.game;
import mage.cards.MagePermanent;
import mage.client.cards.BigCard;
import mage.client.cards.Permanent;
import mage.client.dialog.PreferencesDialog;
import mage.client.plugins.impl.Plugins;
import mage.client.util.ClientDefaultSettings;
import mage.client.util.GUISizeHelper;
import mage.client.util.audio.AudioManager;
import mage.client.util.layout.CardLayoutStrategy;
import mage.client.util.layout.impl.OldCardLayoutStrategy;
import mage.view.CounterView;
import mage.view.PermanentView;
/*
* BattlefieldPanel.java
*
* Created on 10-Jan-2010, 10:43:14 PM
*/
package mage.client.game;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.List;
import java.util.*;
import java.util.Map.Entry;
import mage.cards.MagePermanent;
import mage.client.cards.BigCard;
import mage.client.cards.Permanent;
import mage.client.dialog.PreferencesDialog;
import mage.client.plugins.impl.Plugins;
import mage.client.util.ClientDefaultSettings;
import mage.client.util.GUISizeHelper;
import mage.client.util.audio.AudioManager;
import mage.client.util.layout.CardLayoutStrategy;
import mage.client.util.layout.impl.OldCardLayoutStrategy;
import mage.view.CounterView;
import mage.view.PermanentView;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.List;
import java.util.*;
import java.util.Map.Entry;
/**
/**
* @author BetaSteward_at_googlemail.com
*/
public class BattlefieldPanel extends javax.swing.JLayeredPane {
public class BattlefieldPanel extends javax.swing.JLayeredPane {
private final Map<UUID, MagePermanent> permanents = new LinkedHashMap<>();
private UUID gameId;
@ -45,7 +38,6 @@
private JLayeredPane jPanel;
private JScrollPane jScrollPane;
private int width;
private final CardLayoutStrategy layoutStrategy = new OldCardLayoutStrategy();
@ -70,15 +62,16 @@
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
int width = e.getComponent().getWidth();
int height = e.getComponent().getHeight();
BattlefieldPanel.this.jScrollPane.setSize(width, height);
BattlefieldPanel.this.width = width;
sortLayout();
updateSize();
}
});
}
public void updateSize() {
this.jScrollPane.setSize(this.getWidth(), this.getHeight());
sortLayout();
}
public void init(UUID gameId, BigCard bigCard) {
this.gameId = gameId;
this.bigCard = bigCard;
@ -215,7 +208,7 @@
return;
}
layoutStrategy.doLayout(this, width);
layoutStrategy.doLayout(this, this.getWidth());
this.jScrollPane.repaint();
this.jScrollPane.revalidate();
@ -321,4 +314,4 @@
public Map<String, JComponent> getUiComponentsList() {
return uiComponentsList;
}
}
}

View file

@ -1,20 +1,5 @@
/*
* FeedbackPanel.java
*
* Created on 23-Dec-2009, 9:54:01 PM
*/
package mage.client.game;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.io.Serializable;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import mage.client.MageFrame;
import mage.client.SessionHandler;
import mage.client.chat.ChatPanelBasic;
@ -22,15 +7,22 @@ import mage.client.dialog.MageDialog;
import mage.client.util.GUISizeHelper;
import mage.client.util.audio.AudioManager;
import mage.client.util.gui.ArrowBuilder;
import static mage.constants.Constants.Option.ORIGINAL_ID;
import static mage.constants.Constants.Option.SECOND_MESSAGE;
import static mage.constants.Constants.Option.SPECIAL_BUTTON;
import mage.constants.PlayerAction;
import mage.constants.TurnPhase;
import org.apache.log4j.Logger;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.Serializable;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static mage.constants.Constants.Option.*;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class FeedbackPanel extends javax.swing.JPanel {
@ -85,6 +77,7 @@ public class FeedbackPanel extends javax.swing.JPanel {
String lblText = addAdditionalText(message, options);
this.helper.setTextArea(lblText);
//this.lblMessage.setText(lblText);
this.mode = mode;
switch (this.mode) {
case INFORM:
@ -178,12 +171,12 @@ public class FeedbackPanel extends javax.swing.JPanel {
if (options.containsKey("UI.left.btn.text")) {
String text = (String) options.get("UI.left.btn.text");
this.btnLeft.setText(text);
this.helper.setLeft(text, true);
this.helper.setLeft(text, !text.isEmpty());
}
if (options.containsKey("UI.right.btn.text")) {
String text = (String) options.get("UI.right.btn.text");
this.btnRight.setText(text);
this.helper.setRight(text, true);
this.helper.setRight(text, !text.isEmpty());
}
if (options.containsKey("dialog")) {
connectedDialog = (MageDialog) options.get("dialog");

View file

@ -40,6 +40,7 @@ import javax.swing.plaf.basic.BasicSplitPaneDivider;
import javax.swing.plaf.basic.BasicSplitPaneUI;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyVetoException;
import java.io.Serializable;
import java.util.List;
import java.util.*;
@ -74,6 +75,7 @@ public final class GamePanel extends javax.swing.JPanel {
private final Map<String, CardInfoWindowDialog> revealed = new HashMap<>();
private final Map<String, CardInfoWindowDialog> lookedAt = new HashMap<>();
private final Map<String, CardInfoWindowDialog> graveyardWindows = new HashMap<>();
private final Map<String, CardInfoWindowDialog> companion = new HashMap<>();
private final Map<String, CardsView> graveyards = new HashMap<>();
private final ArrayList<ShowCardsDialog> pickTarget = new ArrayList<>();
@ -241,6 +243,10 @@ public final class GamePanel extends javax.swing.JPanel {
lookedAtDialog.cleanUp();
lookedAtDialog.removeDialog();
}
for (CardInfoWindowDialog companionDialog : companion.values()) {
companionDialog.cleanUp();
companionDialog.removeDialog();
}
for (ShowCardsDialog pickTargetDialog : pickTarget) {
pickTargetDialog.cleanUp();
pickTargetDialog.removeDialog();
@ -275,6 +281,9 @@ public final class GamePanel extends javax.swing.JPanel {
for (CardInfoWindowDialog cardInfoWindowDialog : lookedAt.values()) {
cardInfoWindowDialog.changeGUISize();
}
for (CardInfoWindowDialog cardInfoWindowDialog : companion.values()) {
cardInfoWindowDialog.changeGUISize();
}
for (CardInfoWindowDialog cardInfoWindowDialog : graveyardWindows.values()) {
cardInfoWindowDialog.changeGUISize();
}
@ -602,6 +611,21 @@ public final class GamePanel extends javax.swing.JPanel {
this.pnlBattlefield.add(topPanel, panelC);
panelC.gridy = 1;
this.pnlBattlefield.add(bottomPanel, panelC);
// TODO: combat arrows aren't visible on re-connect, must click on avatar to update correctrly
// reason: panels aren't visible/located here, so battlefieldpanel see wrong sizes
// recalc all component sizes and update permanents/arrows positions
// if you don't do it here then will catch wrong arrows drawing on re-connect (no sortLayout calls)
/*
this.validate();
for (Map.Entry<UUID, PlayAreaPanel> p : players.entrySet()) {
PlayerView playerView = game.getPlayers().stream().filter(view -> view.getPlayerId().equals(p.getKey())).findFirst().orElse(null);
if (playerView != null) {
p.getValue().getBattlefieldPanel().updateSize();
p.getValue().update(null, playerView, null);
}
}
*/
}
public synchronized void updateGame(GameView game) {
@ -781,6 +805,7 @@ public final class GamePanel extends javax.swing.JPanel {
showRevealed(game);
showLookedAt(game);
showCompanion(game);
if (!game.getCombat().isEmpty()) {
CombatManager.instance.showCombat(game.getCombat(), gameId);
} else {
@ -1085,6 +1110,9 @@ public final class GamePanel extends javax.swing.JPanel {
for (CardInfoWindowDialog lookedAtDialog : lookedAt.values()) {
lookedAtDialog.hideDialog();
}
for (CardInfoWindowDialog companionDialog : companion.values()) {
companionDialog.hideDialog();
}
}
// Called if the game frame comes to front again
@ -1102,6 +1130,9 @@ public final class GamePanel extends javax.swing.JPanel {
for (CardInfoWindowDialog lookedAtDialog : lookedAt.values()) {
lookedAtDialog.show();
}
for (CardInfoWindowDialog companionDialog : companion.values()) {
companionDialog.show();
}
}
public void openGraveyardWindow(String playerName) {
@ -1146,6 +1177,23 @@ public final class GamePanel extends javax.swing.JPanel {
removeClosedCardInfoWindows(lookedAt);
}
private void showCompanion(GameView game) {
for (RevealedView revealView : game.getCompanion()) {
handleGameInfoWindow(companion, ShowType.COMPANION, revealView.getName(), revealView.getCards());
}
// Close the companion view if not in the game view
companion.forEach((name, companionDialog) -> {
if (game.getCompanion().stream().noneMatch(revealedView -> revealedView.getName().equals(name))) {
try {
companionDialog.setClosed(true);
} catch (PropertyVetoException e) {
logger.error("Couldn't close companion dialog", e);
}
}
});
removeClosedCardInfoWindows(companion);
}
private void handleGameInfoWindow(Map<String, CardInfoWindowDialog> windowMap, ShowType showType, String name, LinkedHashMap cardsView) {
CardInfoWindowDialog cardInfoWindowDialog;
if (!windowMap.containsKey(name)) {
@ -1160,6 +1208,7 @@ public final class GamePanel extends javax.swing.JPanel {
switch (showType) {
case REVEAL:
case REVEAL_TOP_LIBRARY:
case COMPANION:
cardInfoWindowDialog.loadCards((CardsView) cardsView, bigCard, gameId);
break;
case LOOKED_AT:
@ -1332,6 +1381,22 @@ public final class GamePanel extends javax.swing.JPanel {
}
}
// companion
for (RevealedView rev : gameView.getCompanion()) {
for (Map.Entry<UUID, CardView> card : rev.getCards().entrySet()) {
if (needSelectable.contains(card.getKey())) {
card.getValue().setChoosable(true);
}
if (needChoosen.contains(card.getKey())) {
card.getValue().setSelected(true);
}
if (needPlayable.containsKey(card.getKey())) {
card.getValue().setPlayable(true);
card.getValue().setPlayableAmount(needPlayable.get(card.getKey()));
}
}
}
// looked at
for (LookedAtView look : gameView.getLookedAt()) {
for (Map.Entry<UUID, SimpleCardView> card : look.getCards().entrySet()) {
@ -1525,7 +1590,6 @@ public final class GamePanel extends javax.swing.JPanel {
@SuppressWarnings("unchecked")
private void initComponents() {
abilityPicker = new mage.client.components.ability.AbilityPicker();
jSplitPane1 = new javax.swing.JSplitPane();
jSplitPane0 = new javax.swing.JSplitPane();
@ -1560,14 +1624,16 @@ public final class GamePanel extends javax.swing.JPanel {
txtHoldPriority.setToolTipText("Holding priority after the next spell cast or ability activation");
txtHoldPriority.setVisible(false);
btnToggleMacro = new KeyboundButton(KEY_CONTROL_TOGGLE_MACRO);
btnCancelSkip = new KeyboundButton(KEY_CONTROL_CANCEL_SKIP); // F3
btnSkipToNextTurn = new KeyboundButton(KEY_CONTROL_NEXT_TURN); // F4
btnSkipToEndTurn = new KeyboundButton(KEY_CONTROL_END_STEP); // F5
btnSkipToNextMain = new KeyboundButton(KEY_CONTROL_MAIN_STEP); // F7
btnSkipStack = new KeyboundButton(KEY_CONTROL_SKIP_STACK); // F10
btnSkipToYourTurn = new KeyboundButton(KEY_CONTROL_YOUR_TURN); // F9
btnSkipToEndStepBeforeYourTurn = new KeyboundButton(KEY_CONTROL_PRIOR_END); // F11
boolean displayButtonText = PreferencesDialog.getCurrentTheme().isShortcutsVisibleForSkipButtons();
btnToggleMacro = new KeyboundButton(KEY_CONTROL_TOGGLE_MACRO, displayButtonText);
btnCancelSkip = new KeyboundButton(KEY_CONTROL_CANCEL_SKIP, displayButtonText); // F3
btnSkipToNextTurn = new KeyboundButton(KEY_CONTROL_NEXT_TURN, displayButtonText); // F4
btnSkipToEndTurn = new KeyboundButton(KEY_CONTROL_END_STEP, displayButtonText); // F5
btnSkipToNextMain = new KeyboundButton(KEY_CONTROL_MAIN_STEP, displayButtonText); // F7
btnSkipStack = new KeyboundButton(KEY_CONTROL_SKIP_STACK, displayButtonText); // F10
btnSkipToYourTurn = new KeyboundButton(KEY_CONTROL_YOUR_TURN, displayButtonText); // F9
btnSkipToEndStepBeforeYourTurn = new KeyboundButton(KEY_CONTROL_PRIOR_END, displayButtonText); // F11
btnConcede = new javax.swing.JButton();
btnSwitchHands = new javax.swing.JButton();

View file

@ -1,4 +1,3 @@
package mage.client.game;
import mage.client.SessionHandler;
@ -6,7 +5,9 @@ import mage.client.components.MageTextArea;
import mage.client.constants.Constants;
import mage.client.dialog.PreferencesDialog;
import mage.client.game.FeedbackPanel.FeedbackMode;
import mage.client.util.AppUtil;
import mage.client.util.GUISizeHelper;
import mage.client.util.audio.AudioManager;
import mage.constants.TurnPhase;
import javax.swing.*;
@ -14,6 +15,7 @@ import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import static mage.client.game.FeedbackPanel.FeedbackMode.QUESTION;
@ -63,6 +65,22 @@ public class HelperPanel extends JPanel {
private boolean gameNeedFeedback = false;
private TurnPhase gameTurnPhase = null;
private Timer needFeedbackTimer;
{
// start timer to inform user about needed feedback (example: inform by sound play)
needFeedbackTimer = new Timer(100, evt -> SwingUtilities.invokeLater(() -> {
needFeedbackTimer.stop();
if (!AppUtil.isAppActive() || !AppUtil.isGameActive(this.gameId)) {
// sound notification
AudioManager.playFeedbackNeeded();
// tray notification (baloon + icon blinking)
//MageTray.instance.displayMessage("Game needs your action.");
//MageTray.instance.blink();
}
}));
}
public HelperPanel() {
initComponents();
}
@ -296,7 +314,7 @@ public class HelperPanel extends JPanel {
public void autoSizeButtonsAndFeedbackState() {
// two mode: same size for small texts (flow), different size for long texts (grid)
// plus colorize feedback panel on player's priority
// also colorize feedback panel on player's priority and enable sound notification
int BUTTONS_H_GAP = 15;
Color ACTIVE_FEEDBACK_BACKGROUND_COLOR_MAIN = new Color(0, 0, 255, 50);
@ -308,7 +326,7 @@ public class HelperPanel extends JPanel {
this.buttonGrid.setLayout(new FlowLayout(FlowLayout.CENTER, BUTTONS_H_GAP, 0));
this.buttonGrid.setPreferredSize(null);
java.util.List<JButton> buttons = new ArrayList<>();
List<JButton> buttons = new ArrayList<>();
if (this.btnSpecial.isVisible()) {
buttons.add(this.btnSpecial);
}
@ -324,6 +342,10 @@ public class HelperPanel extends JPanel {
// color panel on player's feedback waiting
if (this.gameNeedFeedback) {
// start notification sound timer
this.needFeedbackTimer.restart();
// wait player's action
switch (FEEDBACK_COLORIZING_MODE) {
case Constants.BATTLEFIELD_FEEDBACK_COLORIZING_MODE_DISABLE:
@ -361,6 +383,9 @@ public class HelperPanel extends JPanel {
break;
}
} else {
// stop notification sound timer
this.needFeedbackTimer.stop();
// inform about other players
this.mainPanel.setOpaque(false);
}

View file

@ -494,7 +494,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
}
public final void init(PlayerView player, BigCard bigCard, UUID gameId, int priorityTime) {
this.playerPanel.init(gameId, player.getPlayerId(), bigCard, priorityTime);
this.playerPanel.init(gameId, player.getPlayerId(), player.getControlled(), bigCard, priorityTime);
this.battlefieldPanel.init(gameId, bigCard);
this.gameId = gameId;
this.playerId = player.getPlayerId();

View file

@ -1,5 +1,13 @@
package mage.client.game;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.*;
import javax.swing.*;
import javax.swing.GroupLayout.Alignment;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
import mage.cards.decks.importer.DckDeckImporter;
import mage.client.MageFrame;
import mage.client.SessionHandler;
@ -8,6 +16,7 @@ import mage.client.components.HoverButton;
import mage.client.components.MageRoundPane;
import mage.client.components.ext.dlg.DialogManager;
import mage.client.dialog.PreferencesDialog;
import mage.client.themes.ThemeType;
import mage.client.util.CardsViewUtil;
import mage.client.util.ImageHelper;
import mage.client.util.gui.BufferedImageBuilder;
@ -15,6 +24,7 @@ import mage.client.util.gui.countryBox.CountryUtil;
import mage.components.ImagePanel;
import mage.components.ImagePanelStyle;
import mage.constants.CardType;
import static mage.constants.Constants.*;
import mage.constants.ManaType;
import mage.counters.Counter;
import mage.counters.CounterType;
@ -23,17 +33,6 @@ import mage.utils.timer.PriorityTimer;
import mage.view.*;
import org.mage.card.arcane.ManaSymbols;
import javax.swing.*;
import javax.swing.GroupLayout.Alignment;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.*;
import static mage.constants.Constants.*;
/**
* Enhanced player pane.
*
@ -42,7 +41,6 @@ import static mage.constants.Constants.*;
public class PlayerPanelExt extends javax.swing.JPanel {
// TODO: *.form file was lost, panel must be reworks in designer
private UUID playerId;
private UUID gameId;
private PlayerView player;
@ -59,9 +57,9 @@ public class PlayerPanelExt extends javax.swing.JPanel {
private static final Border GREEN_BORDER = new LineBorder(Color.green, 3);
private static final Border RED_BORDER = new LineBorder(Color.red, 2);
private static final Border EMPTY_BORDER = BorderFactory.createEmptyBorder(0, 0, 0, 0);
private final Color inactiveBackgroundColor = new Color(200, 200, 180, 200);
private final Color activeBackgroundColor = new Color(200, 255, 200, 200);
private final Color deadBackgroundColor = new Color(131, 94, 83, 200);
private final Color inactiveBackgroundColor;
private final Color activeBackgroundColor;
private final Color deadBackgroundColor;
private final Color activeValueColor = new Color(244, 9, 47);
private final Font fontValuesZero = this.getFont().deriveFont(Font.PLAIN);
@ -81,13 +79,18 @@ public class PlayerPanelExt extends javax.swing.JPanel {
setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
initComponents();
setGUISize();
ThemeType currentTheme = PreferencesDialog.getCurrentTheme();
inactiveBackgroundColor = currentTheme.getPlayerPanel_inactiveBackgroundColor();
activeBackgroundColor = currentTheme.getPlayerPanel_activeBackgroundColor();
deadBackgroundColor = currentTheme.getPlayerPanel_deadBackgroundColor();
}
public void init(UUID gameId, UUID playerId, BigCard bigCard, int priorityTime) {
public void init(UUID gameId, UUID playerId, boolean controlled, BigCard bigCard, int priorityTime) {
this.gameId = gameId;
this.playerId = playerId;
this.bigCard = bigCard;
cheat.setVisible(SessionHandler.isTestMode());
cheat.setVisible(SessionHandler.isTestMode() && controlled);
cheat.setFocusable(false);
flagName = null;
if (priorityTime > 0) {
@ -612,7 +615,6 @@ public class PlayerPanelExt extends javax.swing.JPanel {
manaCountLabelW.addMouseListener(manaMouseAdapter);
manaLabels.put(manaCountLabelW, ManaType.WHITE);l
//*/
///*
JLabel manaCountLabelW = new JLabel();
manaCountLabelW.setToolTipText("White mana");
@ -944,7 +946,8 @@ public class PlayerPanelExt extends javax.swing.JPanel {
Set<String> cardTypesPresent = new LinkedHashSet<String>() {
};
for (CardView card : cardsView.values()) {
Set<CardType> cardTypes = card.getCardTypes();
Set<CardType> cardTypes = EnumSet.noneOf(CardType.class);
cardTypes.addAll(card.getCardTypes());
for (CardType cardType : cardTypes) {
cardTypesPresent.add(cardType.toString());
}

View file

@ -242,7 +242,7 @@ public class MageActionCallback implements ActionCallback {
if (this.startedDragging && prevCardPanel != null && card != null) {
for (Component component : card.getCardArea().getComponents()) {
if (component instanceof CardPanel) {
if (cardPanels.contains(component)) {
if (cardPanels.contains((CardPanel) component)) {
component.setLocation(component.getLocation().x, component.getLocation().y - GO_DOWN_ON_DRAG_Y_OFFSET);
}
}
@ -316,7 +316,7 @@ public class MageActionCallback implements ActionCallback {
for (Component component : container.getComponents()) {
if (component instanceof CardPanel) {
if (!component.equals(card)) {
if (!cardPanels.contains(component)) {
if (!cardPanels.contains((CardPanel) component)) {
component.setLocation(component.getLocation().x, component.getLocation().y + GO_DOWN_ON_DRAG_Y_OFFSET);
}
cardPanels.add((CardPanel) component);
@ -593,8 +593,7 @@ public class MageActionCallback implements ActionCallback {
image = mageCard.getImage();
}
// shows the card in the popup Container
BigCard bigCard = (BigCard) cardPreviewPane;
displayCardInfo(mageCard, image, bigCard);
displayCardInfo(mageCard, image, (BigCard) cardPreviewPane);
} else {
LOGGER.warn("No Card preview Pane in Mage Frame defined. Card: " + cardView.getName());

View file

@ -429,7 +429,7 @@ public class CallbackClientImpl implements CallbackClient {
.append("</b> - Undo F4/F5/F7/F9/F11")
.append("<br/><b>")
.append(KeyEvent.getKeyText(PreferencesDialog.getCurrentControlKey(PreferencesDialog.KEY_CONTROL_SWITCH_CHAT)))
.append("</b> - Switth in/out to chat text field")
.append("</b> - Switch in/out to chat text field")
/*
.append("<br/><b>")
.append(KeyEvent.getKeyText(PreferencesDialog.getCurrentControlKey(PreferencesDialog.KEY_CONTROL_TOGGLE_MACRO)))

View file

@ -1,10 +1,3 @@
/*
* NewPlayerPanel.java
*
* Created on 15-Dec-2009, 10:09:46 PM
*/
package mage.client.table;
import java.io.File;

View file

@ -126,7 +126,9 @@ public class TablePlayerPanel extends javax.swing.JPanel {
private void cbPlayerTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbPlayerTypeActionPerformed
if (getPlayerType() != PlayerType.HUMAN) {
this.newPlayerPanel.setVisible(true);
} else {
this.newPlayerPanel.setPlayerName(ClientDefaultSettings.computerName + " " + this.lblPlayerNum.getText().charAt(this.lblPlayerNum.getText().length() - 1));
}
else {
this.newPlayerPanel.setVisible(false);
}
this.revalidate();

View file

@ -44,10 +44,14 @@
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="btnQuickStartDuel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnQuickStartMCTS" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="btnQuickStartCommander" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="667" max="32767" attributes="0"/>
<EmptySpace pref="540" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -63,7 +67,13 @@
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="filterBar1" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="btnQuickStartDuel" min="-2" max="-2" attributes="0"/>
<Component id="btnQuickStartMCTS" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
@ -567,6 +577,14 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnQuickStartCommanderActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnQuickStartMCTS">
<Properties>
<Property name="text" type="java.lang.String" value="Quick start MCTS"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnQuickStartMCTSActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JSplitPane" name="jSplitPane1">

View file

@ -582,6 +582,7 @@ public class TablesPanel extends javax.swing.JPanel {
Dimension newDimension = new Dimension((int) jPanelBottom.getPreferredSize().getWidth(), GUISizeHelper.menuFont.getSize() + 28);
jPanelBottom.setMinimumSize(newDimension);
jPanelBottom.setPreferredSize(newDimension);
buttonWhatsNew.setFont(GUISizeHelper.menuFont);
buttonNextMessage.setFont(GUISizeHelper.menuFont);
labelMessageHeader.setFont(new Font(GUISizeHelper.menuFont.getName(), Font.BOLD, GUISizeHelper.menuFont.getSize()));
labelMessageText.setFont(GUISizeHelper.menuFont);
@ -693,6 +694,7 @@ public class TablesPanel extends javax.swing.JPanel {
if (SessionHandler.getSession() != null) {
btnQuickStartDuel.setVisible(SessionHandler.isTestMode());
btnQuickStartCommander.setVisible(SessionHandler.isTestMode());
btnQuickStartMCTS.setVisible(SessionHandler.isTestMode());
gameChooser.init();
chatRoomId = SessionHandler.getRoomChatId(roomId).orElse(null);
}
@ -791,7 +793,7 @@ public class TablesPanel extends javax.swing.JPanel {
typeFilterList.add(RowFilter.regexFilter("Constructed", TablesTableModel.COLUMN_GAME_TYPE));
}
if (btnTypeTourneyLimited.isSelected()) {
typeFilterList.add(RowFilter.regexFilter("Booster|Sealed", TablesTableModel.COLUMN_GAME_TYPE));
typeFilterList.add(RowFilter.regexFilter("Booster|Sealed|Jumpstart", TablesTableModel.COLUMN_GAME_TYPE));
}
// format
@ -987,6 +989,7 @@ public class TablesPanel extends javax.swing.JPanel {
btnPassword = new javax.swing.JToggleButton();
btnQuickStartDuel = new javax.swing.JButton();
btnQuickStartCommander = new javax.swing.JButton();
btnQuickStartMCTS = new javax.swing.JButton();
jSplitPane1 = new javax.swing.JSplitPane();
jPanelTables = new javax.swing.JPanel();
jSplitPaneTables = new javax.swing.JSplitPane();
@ -1456,6 +1459,13 @@ public class TablesPanel extends javax.swing.JPanel {
}
});
btnQuickStartMCTS.setText("Quick start MCTS");
btnQuickStartMCTS.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnQuickStartMCTSActionPerformed(evt);
}
});
javax.swing.GroupLayout jPanelTopLayout = new javax.swing.GroupLayout(jPanelTop);
jPanelTop.setLayout(jPanelTopLayout);
jPanelTopLayout.setHorizontalGroup(
@ -1471,9 +1481,12 @@ public class TablesPanel extends javax.swing.JPanel {
.addComponent(filterBar2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanelTopLayout.createSequentialGroup()
.addComponent(btnQuickStartDuel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnQuickStartMCTS))
.addComponent(btnQuickStartCommander))
.addContainerGap(667, Short.MAX_VALUE))
.addContainerGap(540, Short.MAX_VALUE))
);
jPanelTopLayout.setVerticalGroup(
jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -1486,7 +1499,11 @@ public class TablesPanel extends javax.swing.JPanel {
.addGroup(jPanelTopLayout.createSequentialGroup()
.addGroup(jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(filterBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(btnQuickStartDuel))
.addGroup(jPanelTopLayout.createSequentialGroup()
.addGroup(jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(btnQuickStartDuel)
.addComponent(btnQuickStartMCTS))
.addGap(0, 0, Short.MAX_VALUE)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(filterBar2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
@ -1553,7 +1570,7 @@ public class TablesPanel extends javax.swing.JPanel {
jPanelBottom.setPreferredSize(new java.awt.Dimension(516, 37));
jPanelBottom.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));
buttonWhatsNew.setText("Show that's new");
buttonWhatsNew.setText("Show what's new");
buttonWhatsNew.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
buttonWhatsNew.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
buttonWhatsNew.setOpaque(false);
@ -1596,7 +1613,7 @@ public class TablesPanel extends javax.swing.JPanel {
newTournamentDialog.showDialog(roomId);
}//GEN-LAST:event_btnNewTournamentActionPerformed
private void createTestGame(String gameName, String gameType) {
private void createTestGame(String gameName, String gameType, boolean useMonteCarloAI) {
TableView table;
try {
String testDeckFile = "test.dck";
@ -1612,9 +1629,10 @@ public class TablesPanel extends javax.swing.JPanel {
}
DeckCardLists testDeck = DeckImporter.importDeckFromFile(testDeckFile);
PlayerType aiType = useMonteCarloAI ? PlayerType.COMPUTER_MONTE_CARLO : PlayerType.COMPUTER_MAD;
MatchOptions options = new MatchOptions(gameName, gameType, false, 2);
options.getPlayerTypes().add(PlayerType.HUMAN);
options.getPlayerTypes().add(PlayerType.COMPUTER_MAD);
options.getPlayerTypes().add(aiType);
options.setDeckType("Limited");
options.setAttackOption(MultiplayerAttackOption.LEFT);
options.setRange(RangeOfInfluence.ALL);
@ -1630,7 +1648,7 @@ public class TablesPanel extends javax.swing.JPanel {
table = SessionHandler.createTable(roomId, options);
SessionHandler.joinTable(roomId, table.getTableId(), "Human", PlayerType.HUMAN, 1, testDeck, "");
SessionHandler.joinTable(roomId, table.getTableId(), "Computer", PlayerType.COMPUTER_MAD, 5, testDeck, "");
SessionHandler.joinTable(roomId, table.getTableId(), "Computer", aiType, 5, testDeck, "");
SessionHandler.startMatch(roomId, table.getTableId());
} catch (HeadlessException ex) {
handleError(ex);
@ -1638,7 +1656,7 @@ public class TablesPanel extends javax.swing.JPanel {
}
private void btnQuickStartDuelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQuickStartDuelActionPerformed
createTestGame("Test duel", "Two Player Duel");
createTestGame("Test duel", "Two Player Duel", false);
}//GEN-LAST:event_btnQuickStartDuelActionPerformed
private void btnNewTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNewTableActionPerformed
@ -1677,9 +1695,13 @@ public class TablesPanel extends javax.swing.JPanel {
}//GEN-LAST:event_buttonWhatsNewActionPerformed
private void btnQuickStartCommanderActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQuickStartCommanderActionPerformed
createTestGame("Test commander", "Commander Two Player Duel");
createTestGame("Test commander", "Commander Two Player Duel", false);
}//GEN-LAST:event_btnQuickStartCommanderActionPerformed
private void btnQuickStartMCTSActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQuickStartMCTSActionPerformed
createTestGame("Test Monte Carlo AI", "Two Player Duel", true);
}//GEN-LAST:event_btnQuickStartMCTSActionPerformed
private void handleError(Exception ex) {
LOGGER.fatal("Error loading deck: ", ex);
JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Error loading deck.", "Error", JOptionPane.ERROR_MESSAGE);
@ -1691,9 +1713,9 @@ public class TablesPanel extends javax.swing.JPanel {
private javax.swing.JToggleButton btnFormatLegacy;
private javax.swing.JToggleButton btnFormatLimited;
private javax.swing.JToggleButton btnFormatModern;
private javax.swing.JToggleButton btnFormatPioneer;
private javax.swing.JToggleButton btnFormatOathbreaker;
private javax.swing.JToggleButton btnFormatOther;
private javax.swing.JToggleButton btnFormatPioneer;
private javax.swing.JToggleButton btnFormatPremodern;
private javax.swing.JToggleButton btnFormatStandard;
private javax.swing.JToggleButton btnFormatTinyLeader;
@ -1704,6 +1726,7 @@ public class TablesPanel extends javax.swing.JPanel {
private javax.swing.JToggleButton btnPassword;
private javax.swing.JButton btnQuickStartCommander;
private javax.swing.JButton btnQuickStartDuel;
private javax.swing.JButton btnQuickStartMCTS;
private javax.swing.JToggleButton btnRated;
private javax.swing.JToggleButton btnSkillBeginner;
private javax.swing.JToggleButton btnSkillCasual;

View file

@ -10,6 +10,7 @@ package mage.client.table;
import mage.cards.decks.DeckCardLists;
import mage.client.SessionHandler;
import mage.client.util.ClientDefaultSettings;
import mage.players.PlayerType;
import javax.swing.*;
@ -136,9 +137,9 @@ public class TournamentPlayerPanel extends javax.swing.JPanel {
private void cbPlayerTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbPlayerTypeActionPerformed
if (this.cbPlayerType.getSelectedItem() != PlayerType.HUMAN) {
this.pnlPlayerName.setVisible(true);
if (this.txtPlayerName.getText().isEmpty()) {
this.txtPlayerName.setText("Computer " + this.lblPlayerNum.getText());
}
this.txtPlayerName.setText(ClientDefaultSettings.computerName + " " + this.lblPlayerNum.getText().charAt(this.lblPlayerNum.getText().length() - 1));
this.txtPlayerName.setEditable(false);
this.txtPlayerName.setEnabled(false);
} else {
this.pnlPlayerName.setVisible(false);
}

View file

@ -0,0 +1,270 @@
package mage.client.themes;
import java.awt.*;
public enum ThemeType {
// https://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/_nimbusDefaults.html
DEFAULT("Default",
"",
true,
false,
true,
true,
true,
true,
true,
new Color(169, 176, 190), // nimbusBlueGrey
new Color(214, 217, 223), // control
new Color(255, 255, 255), // nimbusLightBackground
new Color(242, 242, 189), // info
new Color(51, 98, 140), // nimbusBase
null, // mageToolbar
new Color(200, 200, 180, 200), // playerPanel_inactiveBackgroundColor
new Color(200, 255, 200, 200), // playerPanel_activeBackgroundColor
new Color(131, 94, 83, 200) // playerPanel_deadBackgroundColor
),
GREY("Grey",
"grey-theme/",
false,
false,
false,
false,
false,
true,
true,
new Color(158, 158, 158), // nimbusBlueGrey
new Color(212, 212, 212), // control
new Color(215, 215, 215), // nimbusLightBackground
new Color(189, 189, 164), // info
new Color(102, 102, 102), // nimbusBase
null, // mageToolbar
new Color(172, 172, 172, 200), // playerPanel_inactiveBackgroundColor
new Color(180, 234, 180, 200), // playerPanel_activeBackgroundColor
new Color(99, 99, 99, 200) // playerPanel_deadBackgroundColor
),
SUNSET_VAPORWAVE("Vaporwave Sunset",
"16bit-theme/",
true,
true,
false,
true,
true,
true,
false,
new Color(246, 136, 158),
new Color(243, 233, 164),
new Color(204, 236, 201),
new Color(117, 174, 238),
new Color(106, 0, 255),
new Color(192, 166, 232),
new Color(243, 233, 164),
new Color(204, 236, 201),
new Color(106, 0, 255)
),
COFFEE("Coffee",
"coffee-theme/",
true,
true,
true,
true,
true,
true,
false,
new Color(219, 193, 172), // nimbusBlueGrey
new Color(182, 157, 135), // control
new Color(219, 193, 172), // nimbusLightBackground
new Color(219, 197, 182), // info
new Color(97, 27, 0), // nimbusBase
new Color(219, 193, 172), // mageToolbar
new Color(219, 193, 172),
new Color(204, 236, 201),
new Color(99, 72, 50, 255)
),
ISLAND("Island",
"island-theme/",
true,
true,
false,
true,
true,
true,
false,
new Color(172, 197, 219), // nimbusBlueGrey
new Color(135, 158, 182), // control
new Color(172, 197, 219), // nimbusLightBackground
new Color(182, 200, 219), // info
new Color(0, 78, 97), // nimbusBase
new Color(172, 195, 219), // mageToolbar
new Color(172, 195, 219),
new Color(204, 236, 201),
new Color(50, 68, 99, 255)
);
private final String name;
private final String path;
private final boolean hasBackground;
private final boolean hasLoginBackground;
private final boolean hasBattleBackground;
private final boolean hasSkipButtons;
private final boolean hasPhaseIcons;
private final boolean hasWinLossImages;
private final boolean shortcutsVisibleForSkipButtons; // Whether or not to display skip button shortcuts
private final Color nimbusBlueGrey; // buttons, scrollbar background, disabled inputs
private final Color control; // window bg
private final Color nimbusLightBackground; // inputs, table rows
private final Color info;// tooltips
private final Color nimbusBase;// title bars, scrollbar foreground
private final Color mageToolbar;
private final Color playerPanel_inactiveBackgroundColor;
private final Color playerPanel_activeBackgroundColor;
private final Color playerPanel_deadBackgroundColor;
ThemeType(String name,
String path,
boolean hasBackground,
boolean hasLoginBackground,
boolean hasBattleBackground,
boolean hasSkipButtons,
boolean hasPhaseIcons,
boolean hasWinLossImages,
boolean shortcutsVisibleForSkipButtons,
Color nimbusBlueGrey,
Color control,
Color nimbusLightBackground,
Color info,
Color nimbusBase,
Color mageToolbar,
Color playerPanel_inactiveBackgroundColor,
Color playerPanel_activeBackgroundColor,
Color playerPanel_deadBackgroundColor
) {
this.name = name;
this.path = path;
this.hasBackground = hasBackground;
this.hasLoginBackground = hasLoginBackground;
this.hasBattleBackground = hasBattleBackground;
this.hasSkipButtons = hasSkipButtons;
this.hasPhaseIcons = hasPhaseIcons;
this.hasWinLossImages = hasWinLossImages;
this.shortcutsVisibleForSkipButtons = shortcutsVisibleForSkipButtons;
this.nimbusBlueGrey = nimbusBlueGrey;
this.control = control;
this.nimbusLightBackground = nimbusLightBackground;
this.info = info;
this.nimbusBase = nimbusBase;
this.mageToolbar = mageToolbar;
this.playerPanel_activeBackgroundColor = playerPanel_activeBackgroundColor;
this.playerPanel_deadBackgroundColor = playerPanel_deadBackgroundColor;
this.playerPanel_inactiveBackgroundColor = playerPanel_inactiveBackgroundColor;
}
@Override
public String toString() {
return name;
}
public static ThemeType valueByName(String value) {
for (ThemeType themeType : values()) {
if (themeType.name.equals(value)) {
return themeType;
}
}
return DEFAULT;
}
public String getName() {
return name;
}
public boolean isShortcutsVisibleForSkipButtons() {
return shortcutsVisibleForSkipButtons;
}
public Color getNimbusBlueGrey() {
return nimbusBlueGrey;
}
public Color getControl() {
return control;
}
public Color getNimbusLightBackground() {
return nimbusLightBackground;
}
public Color getInfo() {
return info;
}
public Color getNimbusBase() {
return nimbusBase;
}
public Color getMageToolbar() {
return mageToolbar;
}
public Color getPlayerPanel_inactiveBackgroundColor() {
return playerPanel_inactiveBackgroundColor;
}
public Color getPlayerPanel_activeBackgroundColor() {
return playerPanel_activeBackgroundColor;
}
public Color getPlayerPanel_deadBackgroundColor() {
return playerPanel_deadBackgroundColor;
}
private String getImagePath(String imageType, String name) {
return "/" + imageType + "/" + path + name;
}
public String getButtonPath(String name) {
if (hasSkipButtons) {
return getImagePath("buttons", name);
} else {
return "/buttons/" + name;
}
}
public String getPhasePath(String name) {
if (hasPhaseIcons) {
return getImagePath("phases", name);
} else {
return "/phases/" + name;
}
}
public String getWinlossPath(String name) {
if (hasWinLossImages) {
return getImagePath("winloss", name);
} else {
return "/winloss/" + name;
}
}
public String getBackgroundPath() {
if (hasBackground) {
return getImagePath("background", "background.png");
} else {
return "/background/background.png";
}
}
public String getLoginBackgroundPath() {
if (hasLoginBackground) {
return getImagePath("background", "login-background.png");
} else {
return getBackgroundPath();
}
}
public String getBattleBackgroundPath() {
if (hasBattleBackground) {
return getImagePath("background", "battle-background.png");
} else {
return getBackgroundPath();
}
}
}

View file

@ -0,0 +1,28 @@
package mage.client.util;
import mage.client.MageFrame;
import java.util.UUID;
/**
* @author JayDi85
*/
public class AppUtil {
/**
* Application is active in operation system (got user focus)
*/
public static boolean isAppActive() {
return MageFrame.getInstance().isActive();
}
/**
* Current active panel is game panel (e.g. the user sees the checking game)
*
* @param gameId game to check
* @return
*/
public static boolean isGameActive(UUID gameId) {
return MageFrame.getInstance().isGameFrameActive(gameId);
}
}

View file

@ -15,16 +15,10 @@ public class CardViewRarityComparator implements Comparator<CardView> {
Rarity r1 = o1.getRarity();
Rarity r2 = o2.getRarity();
int val = Integer.compare(
return Integer.compare(
r1 == null ? 0 : r1.getSorting(),
r2 == null ? 0 : r2.getSorting()
);
if (val == 0) {
return o1.getName().compareTo(o2.getName());
} else {
return val;
}
}
}

View file

@ -28,7 +28,7 @@ public final class ClientDefaultSettings {
handScalingFactor = 1.3;
deckPath = "";
otherPlayerIndex = "1"; // combobox default, example: 0: Human, 1: Computer - mad, 2: Computer - Draft Bot
computerName = "computer";
computerName = "Computer";
dimensions = new CardDimensions(cardScalingFactor);
dimensionsEnlarged = new CardDimensions(cardScalingFactorEnlarged);
}

View file

@ -47,6 +47,7 @@ public class AudioManager {
private MageClip playerQuitTournament = null;
private MageClip playerWon = null;
private MageClip playerLost = null;
private MageClip feedbackNeeded = null;
/**
* AudioManager singleton.
*/
@ -285,6 +286,13 @@ public class AudioManager {
checkAndPlayClip(audioManager.playerWon);
}
public static void playFeedbackNeeded() {
if (audioManager.feedbackNeeded == null) {
audioManager.feedbackNeeded = new MageClip(Constants.BASE_SOUND_PATH + "FeedbackNeeded.wav", AudioGroup.GameSounds);
}
checkAndPlayClip(audioManager.feedbackNeeded);
}
private static boolean audioGroupEnabled(AudioGroup audioGroup) {
switch (audioGroup) {
case GameSounds:

View file

@ -1,18 +1,11 @@
package mage.client.util.gui;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Area;
import java.awt.geom.GeneralPath;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Arrow extends JPanel {
@ -26,6 +19,7 @@ public class Arrow extends JPanel {
private float headSize = 17;
private Composite composite;
private Color color = Color.red;
private Color strokeColor = Color.black;
public Arrow() {
setOpaque(false);
@ -53,8 +47,11 @@ public class Arrow extends JPanel {
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setComposite(composite);
g2d.setColor(this.color);
//debug stroke draw
//float[] dash2 = {10, 5};
//g2d.setStroke(new BasicStroke(3.5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 10.0f, dash2, 0));
g2d.fill(arrow);
g2d.setColor(Color.BLACK);
g2d.setColor(this.strokeColor);
g2d.draw(arrow);
}

View file

@ -14,8 +14,8 @@ import org.mage.card.arcane.UI;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Locale;
import java.util.List;
import java.util.*;
import static mage.client.dialog.PreferencesDialog.KEY_MAGE_PANEL_LAST_SIZE;
@ -38,7 +38,7 @@ public final class GuiDisplayUtil {
this.basicTextLength = basicTextLength;
}
public java.util.List<String> getLines() {
public List<String> getLines() {
return lines;
}
@ -343,6 +343,9 @@ public final class GuiDisplayUtil {
}
buffer.append("</td></tr></table>");
// split card rules shows up by parts, so no needs to duplicate it later (only dynamic abilities must be shown)
Set<String> duplicatedRules = new HashSet<>();
StringBuilder rule = new StringBuilder("<br/>");
if (card.isSplitCard()) {
rule.append("<table cellspacing=0 cellpadding=0 border=0 width='100%'>");
@ -355,7 +358,9 @@ public final class GuiDisplayUtil {
rule.append("</td></tr></table>");
for (String ruling : card.getLeftSplitRules()) {
if (ruling != null && !ruling.replace(".", "").trim().isEmpty()) {
rule.append("<p style='margin: 2px'>").append(ruling).append("</p>");
// split names must be replaced
duplicatedRules.add(ruling);
rule.append("<p style='margin: 2px'>").append(replaceNamesInRule(ruling, card.getLeftSplitName())).append("</p>");
}
}
rule.append("<table cellspacing=0 cellpadding=0 border=0 width='100%'>");
@ -368,13 +373,18 @@ public final class GuiDisplayUtil {
rule.append("</td></tr></table>");
for (String ruling : card.getRightSplitRules()) {
if (ruling != null && !ruling.replace(".", "").trim().isEmpty()) {
rule.append("<p style='margin: 2px'>").append(ruling).append("</p>");
// split names must be replaced
duplicatedRules.add(ruling);
rule.append("<p style='margin: 2px'>").append(replaceNamesInRule(ruling, card.getRightSplitName())).append("</p>");
}
}
}
if (!textLines.getLines().isEmpty()) {
for (String textLine : textLines.getLines()) {
if (textLine != null && !textLine.replace(".", "").trim().isEmpty()) {
if (duplicatedRules.contains(textLine)) {
continue;
}
rule.append("<p style='margin: 2px'>").append(textLine).append("</p>");
}
}
@ -382,8 +392,7 @@ public final class GuiDisplayUtil {
String legal = rule.toString();
if (!legal.isEmpty()) {
legal = legal.replaceAll("\\{this\\}", card.getName().isEmpty() ? "this" : card.getName());
legal = legal.replaceAll("\\{source\\}", card.getName().isEmpty() ? "this" : card.getName());
legal = replaceNamesInRule(legal, card.getDisplayName()); // must show real display name (e.g. split part, not original card)
buffer.append(ManaSymbols.replaceSymbolsWithHTML(legal, ManaSymbols.Type.TOOLTIP));
}
@ -396,6 +405,12 @@ public final class GuiDisplayUtil {
return buffer;
}
private static String replaceNamesInRule(String rule, String cardName) {
String res = rule.replaceAll("\\{this\\}", cardName.isEmpty() ? "this" : cardName);
res = res.replaceAll("\\{source\\}", cardName.isEmpty() ? "this" : cardName);
return res;
}
private static String getResourcePath(String image) {
return GuiDisplayUtil.class.getClassLoader().getResource(image).toString();
}

View file

@ -154,6 +154,7 @@ public class CardPanelRenderImpl extends CardPanel {
sb.append(this.view.getToughness());
sb.append(this.view.getLoyalty());
sb.append(this.view.getColor().toString());
sb.append(this.view.getType());
sb.append(this.view.getExpansionSetCode());
for (CardType type : this.view.getCardTypes()) {
sb.append((char) type.ordinal());
@ -227,7 +228,7 @@ public class CardPanelRenderImpl extends CardPanel {
private BufferedImage faceArtImage;
// Factory to generate card appropriate views
private CardRendererFactory cardRendererFactory = new CardRendererFactory();
private final CardRendererFactory cardRendererFactory = new CardRendererFactory();
// The rendered card image, with or without the art image loaded yet
// = null while invalid

View file

@ -140,13 +140,30 @@ public abstract class CardRenderer {
break;
}
// workaround to use real split card names
String realCardName = cardView.getDisplayName();
if (cardView.isSplitCard()) {
for (String partRule : cardView.getLeftSplitRules()) {
if (partRule.equals(rule)) {
realCardName = cardView.getLeftSplitName();
break;
}
}
for (String partRule : cardView.getRightSplitRules()) {
if (partRule.equals(rule)) {
realCardName = cardView.getRightSplitName();
break;
}
}
}
// Kill reminder text
if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_RENDERING_REMINDER_TEXT, "false").equals("false")) {
rule = CardRendererUtils.killReminderText(rule).trim();
}
if (!rule.isEmpty()) {
TextboxRule tbRule = TextboxRuleParser.parse(cardView, rule);
TextboxRule tbRule = TextboxRuleParser.parse(cardView, rule, realCardName);
if (tbRule.type == TextboxRuleType.SIMPLE_KEYWORD) {
keywords.add(tbRule);
} else if (tbRule.text.isEmpty()) {

View file

@ -7,6 +7,7 @@ package org.mage.card.arcane;
import java.awt.Font;
import java.awt.Image;
import java.awt.Paint;
import java.awt.font.GraphicAttribute;
import java.awt.font.ImageGraphicAttribute;
import java.awt.font.TextAttribute;
@ -47,6 +48,25 @@ public class TextboxRule {
}
}
public static class ColorRegion implements AttributeRegion {
ColorRegion(int start, int end, Paint color) {
this.start = start;
this.end = end;
this.color = color;
}
private final int start;
private final int end;
private final Paint color;
@Override
public void applyToAttributedString(AttributedString str, Font normal, Font italic) {
if (end > start + 1) {
str.addAttribute(TextAttribute.FOREGROUND, color, start, end);
}
}
}
// A special symbol embedded at some point in a string
public static class EmbeddedSymbol implements AttributeRegion {

View file

@ -8,6 +8,7 @@ import java.awt.*;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -22,15 +23,16 @@ public final class TextboxRuleParser {
private static final Pattern LevelAbilityPattern = Pattern.compile("Level (\\d+)-?(\\d*)(\\+?)");
private static final Pattern LoyaltyAbilityPattern = Pattern.compile("^(\\+|\\-)(\\d+|X): ");
private static final Pattern SimpleKeywordPattern = Pattern.compile("^(\\w+( \\w+)?)\\s*(\\([^\\)]*\\))?\\s*$");
private static final Pattern FontColorValuePattern = Pattern.compile("color\\s*=\\s*[\"'](\\w+)[\"']");
// Parse a given rule (given as a string) into a TextboxRule, replacing
// symbol annotations, italics, etc, parsing out information such as
// if the ability is a loyalty ability, and returning an TextboxRule
// representing that information, which can be used to render the rule in
// the textbox of a card.
public static TextboxRule parse(CardView source, String rule) {
public static TextboxRule parse(CardView source, String rule, String cardNameToUse) {
// List of regions to apply
java.util.List<TextboxRule.AttributeRegion> regions = new ArrayList<>();
List<TextboxRule.AttributeRegion> regions = new ArrayList<>();
// Leveler / loyalty / basic
boolean isLeveler = false;
@ -102,10 +104,9 @@ public final class TextboxRuleParser {
String contents = rule.substring(index + 1, closeIndex);
if (contents.equals("this") || contents.equals("source")) {
// Replace {this} with the card's name
String cardName = source.getName();
build.append(cardName);
build.append(cardNameToUse);
index += contents.length() + 2;
outputIndex += cardName.length();
outputIndex += cardNameToUse.length();
} else {
Image symbol = ManaSymbols.getSizedManaSymbol(contents.replace("/", ""), 10);
if (symbol != null) {
@ -199,6 +200,11 @@ public final class TextboxRuleParser {
}
}
break;
case "/font":
// Font it is an additional info of a card
// lets make it blue like it is in tooltip
regions.add(new TextboxRule.ColorRegion(openingIndex, outputIndex, Color.BLUE));
break;
default:
// Unknown
build.append('<').append(tag).append('>');

View file

@ -2,6 +2,7 @@ package org.mage.plugins.card.dl.sources;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @author JayDi85
@ -25,7 +26,10 @@ public class CardImageUrls {
this.baseUrl = baseUrl;
if (alternativeUrl != null && !alternativeUrl.isEmpty()) {
if (alternativeUrl != null
&& alternativeUrl != null
&& !alternativeUrl.isEmpty()
&& !Objects.equals(baseUrl, alternativeUrl)) {
this.alternativeUrls.add(alternativeUrl);
}
}

View file

@ -24,7 +24,7 @@ public enum GrabbagImageSource implements CardImageSource {
@Override
public String getSourceName() {
return "";
return "Grabbag";
}
@Override
@ -75,7 +75,6 @@ public enum GrabbagImageSource implements CardImageSource {
return;
}
singleLinks = new HashMap<>();
singleLinks.put("SWS/AAT-1", "CqmDY8V.jpg");
singleLinks.put("SWS/Acklay of the Arena", "ESVRm6F.jpg");
singleLinks.put("SWS/Acquire Target", "FOskB4q.jpg");
@ -468,7 +467,7 @@ public enum GrabbagImageSource implements CardImageSource {
if (card.getSet().equals("MTG")) {
return "http://static.starcitygames.com/sales/cardscans/";
} else if (card.getSet().equals("SWS")) {
return "http://i.imgur.com/";
return "https://i.imgur.com/";
} else {
return "http://magiccards.info/scans/en/";
}

View file

@ -114,6 +114,15 @@ public enum ScryfallImageSource implements CardImageSource {
+ card.getCollectorId() + "/" + localizedCode + "?format=image";
alternativeUrl = "https://api.scryfall.com/cards/" + formatSetName(card.getSet(), isToken) + "/"
+ card.getCollectorId() + "/" + defaultCode + "?format=image";
// workaround to use cards without english images (some promos or special cards)
// bug: https://github.com/magefree/mage/issues/6829
// example: Mysterious Egg from IKO https://api.scryfall.com/cards/iko/385/?format=image
if (Objects.equals(baseUrl, alternativeUrl)) {
// without loc code scryfall must return first available image
alternativeUrl = "https://api.scryfall.com/cards/" + formatSetName(card.getSet(), isToken) + "/"
+ card.getCollectorId() + "/?format=image";
}
}
return new CardImageUrls(baseUrl, alternativeUrl);

View file

@ -473,6 +473,141 @@ public class ScryfallImageSupportCards {
// TODO: DuelsOfThePlaneswalkersPromos
add("DPAP");
add("GRC");
//
add("ARC");
add("M11");
add("V10");
add("DDF");
add("SOM");
// add("TD0"); // Commander Theme Decks
add("PD2");
add("ME4");
add("MBS");
add("DDG");
add("NPH");
add("CMD");
add("M12");
add("V11");
add("DDH");
add("ISD");
add("PD3");
add("DKA");
add("DDI");
add("AVR");
add("PC2");
add("M13");
add("V12");
add("DDJ");
add("RTR");
add("CM1");
// add("TD2"); // Duel Decks: Mirrodin Pure vs. New Phyrexia
add("GTC");
add("DDK");
add("DGM");
add("MMA");
add("M14");
add("V13");
add("DDL");
add("THS");
add("C13");
add("BNG");
add("DDM");
add("JOU");
// add("MD1"); // Modern Event Deck
add("CNS");
add("VMA");
add("M15");
add("V14");
add("DDN");
add("KTK");
add("C14");
// add("DD3"); // Duel Decks Anthology
add("FRF");
add("DDO");
add("DTK");
add("TPR");
add("MM2");
add("ORI");
add("V15");
add("DDP");
add("BFZ");
add("EXP");
add("C15");
// add("PZ1"); // Legendary Cube
add("OGW");
add("DDQ");
add("W16");
add("SOI");
add("EMA");
add("EMN");
add("V16");
add("CN2");
add("DDR");
add("KLD");
add("MPS");
// add("PZ2");
add("C16");
add("PCA");
add("AER");
add("MM3");
add("DDS");
add("W17");
add("AKH");
add("CMA");
add("E01");
add("HOU");
add("C17");
add("XLN");
add("DDT");
add("IMA");
add("E02");
add("V17");
add("UST");
add("DDU");
add("RIX");
add("WMCQ");
add("PPRO");
add("A25");
add("DOM");
add("BBD");
add("C18");
add("CM2");
add("M19");
add("GS1");
add("GRN");
add("GK1");
add("GNT");
add("UMA");
add("PUMA");
add("RNA");
add("MEDM");
add("GK2");
add("MH1");
add("WAR");
add("M20");
add("C19");
add("ELD");
add("THB");
add("IKO");
add("C20");
add("MB1");
add("FMB1");
//
add("EURO");
add("GPX");
add("ATH");
add("GRC");
add("ANA");
add("G18");
add("PM20");
add("PS19");
add("SS1");
add("SS2");
add("PPP1");
add("PF19");
add("MPS-AKH");
add("M21");
add("JMP");
}
};

View file

@ -94,16 +94,33 @@ public class ScryfallImageSupportTokens {
put("HOU/Insect", "https://api.scryfall.com/cards/thou/12/en?format=image");
put("HOU/Snake", "https://api.scryfall.com/cards/thou/11/en?format=image");
//AKH
//AKH - tokens
put("AKH/Beast", "https://api.scryfall.com/cards/takh/21/en?format=image");
put("AKH/Cat", "https://api.scryfall.com/cards/takh/16/en?format=image");
put("AKH/Drake", "https://api.scryfall.com/cards/takh/18/en?format=image");
put("AKH/Emblem Gideon", "https://api.scryfall.com/cards/takh/25/en?format=image");
put("AKH/Hippo", "https://api.scryfall.com/cards/takh/22/en?format=image");
put("AKH/Insect", "https://api.scryfall.com/cards/takh/19/en?format=image");
put("AKH/Snake", "https://api.scryfall.com/cards/takh/23/en?format=image");
put("AKH/Warrior", "https://api.scryfall.com/cards/takh/17/en?format=image");
put("AKH/Wurm", "https://api.scryfall.com/cards/takh/24/en?format=image");
put("AKH/Zombie", "https://api.scryfall.com/cards/takh/20/en?format=image");
//AKH - embalm ability (token from card)
put("AKH/Angel of Sanctions", "https://api.scryfall.com/cards/takh/1/en?format=image");
put("AKH/Anointer Priest", "https://api.scryfall.com/cards/takh/2/en?format=image");
put("AKH/Aven Initiate", "https://api.scryfall.com/cards/takh/3/en?format=image");
put("AKH/Aven Wind Guide", "https://api.scryfall.com/cards/takh/4/en?format=image");
put("AKH/Glyph Keeper", "https://api.scryfall.com/cards/takh/5/en?format=image");
put("AKH/Heart-Piercer Manticore", "https://api.scryfall.com/cards/takh/6/en?format=image");
put("AKH/Honored Hydra", "https://api.scryfall.com/cards/takh/7/en?format=image");
put("AKH/Labyrinth Guardian", "https://api.scryfall.com/cards/takh/8/en?format=image");
put("AKH/Oketra's Attendant", "https://api.scryfall.com/cards/takh/9/en?format=image");
put("AKH/Sacred Cat", "https://api.scryfall.com/cards/takh/10/en?format=image");
put("AKH/Tah-Crop Skirmisher", "https://api.scryfall.com/cards/takh/11/en?format=image");
put("AKH/Temmet, Vizier of Naktamun", "https://api.scryfall.com/cards/takh/12/en?format=image");
put("AKH/Trueheart Duelist", "https://api.scryfall.com/cards/takh/13/en?format=image");
put("AKH/Unwavering Initiate", "https://api.scryfall.com/cards/takh/14/en?format=image");
put("AKH/Vizier of Many Faces", "https://api.scryfall.com/cards/takh/15/en?format=image");
//AER
put("AER/Etherium Cell", "https://api.scryfall.com/cards/taer/3/en?format=image");
@ -350,6 +367,88 @@ public class ScryfallImageSupportTokens {
put("THB/Wolf", "https://api.scryfall.com/cards/tthb/11/en?format=image");
put("THB/Zombie", "https://api.scryfall.com/cards/tthb/7/en?format=image");
// IKO
put("IKO/Emblem Narset Of The Ancient Way", "https://api.scryfall.com/cards/tiko/12/en?format=image");
put("IKO/Beast", "https://api.scryfall.com/cards/tiko/10/en?format=image");
put("IKO/Cat Bird", "https://api.scryfall.com/cards/tiko/2/en?format=image");
put("IKO/Cat", "https://api.scryfall.com/cards/tiko/1/en?format=image");
put("IKO/Dinosaur Beast", "https://api.scryfall.com/cards/tiko/11/en?format=image");
put("IKO/Dinosaur", "https://api.scryfall.com/cards/tiko/8/en?format=image");
put("IKO/Feather", "https://api.scryfall.com/cards/tiko/9/en?format=image");
put("IKO/Human Soldier/1", "https://api.scryfall.com/cards/tiko/3/en?format=image");
put("IKO/Human Soldier/2", "https://api.scryfall.com/cards/tiko/4/en?format=image");
put("IKO/Human Soldier/3", "https://api.scryfall.com/cards/tiko/5/en?format=image");
put("IKO/Kraken", "https://api.scryfall.com/cards/tiko/6/en?format=image");
put("IKO/Shark", "https://api.scryfall.com/cards/tiko/7/en?format=image");
// PCA (planes)
put("PCA/Eldrazi", "https://api.scryfall.com/cards/tpca/1/en?format=image");
put("PCA/Plane - Academy at Tolaria West", "https://api.scryfall.com/cards/opca/9/en?format=image");
put("PCA/Plane - Agyrem", "https://api.scryfall.com/cards/opca/11/en?format=image");
put("PCA/Plane - Akoum", "https://api.scryfall.com/cards/opca/12/en?format=image");
put("PCA/Plane - Astral Arena", "https://api.scryfall.com/cards/opca/14/en?format=image");
put("PCA/Plane - Bant", "https://api.scryfall.com/cards/opca/15/en?format=image");
put("PCA/Plane - Edge of Malacol", "https://api.scryfall.com/cards/opca/20/en?format=image");
put("PCA/Plane - Feeding Grounds", "https://api.scryfall.com/cards/opca/23/en?format=image");
put("PCA/Plane - Fields of Summer", "https://api.scryfall.com/cards/opca/24/en?format=image");
put("PCA/Plane - Hedron Fields of Agadeem", "https://api.scryfall.com/cards/opca/35/en?format=image");
put("PCA/Plane - Lethe Lake", "https://api.scryfall.com/cards/opca/47/en?format=image");
put("PCA/Plane - Naya", "https://api.scryfall.com/cards/opca/55/en?format=image");
put("PCA/Plane - Panopticon", "https://api.scryfall.com/cards/opca/62/en?format=image");
put("PCA/Plane - Tazeem", "https://api.scryfall.com/cards/opca/78/en?format=image");
put("PCA/Plane - The Dark Barony", "https://api.scryfall.com/cards/opca/19/en?format=image");
put("PCA/Plane - The Eon Fog", "https://api.scryfall.com/cards/opca/22/en?format=image");
put("PCA/Plane - The Great Forest", "https://api.scryfall.com/cards/opca/32/en?format=image");
put("PCA/Plane - The Zephyr Maze", "https://api.scryfall.com/cards/opca/86/en?format=image");
put("PCA/Plane - Truga Jungle", "https://api.scryfall.com/cards/opca/81/en?format=image");
put("PCA/Plane - Trail of the Mage-Rings", "https://api.scryfall.com/cards/opca/80/en?format=image");
put("PCA/Plane - Turri Island", "https://api.scryfall.com/cards/opca/82/en?format=image");
put("PCA/Plane - Undercity Reaches", "https://api.scryfall.com/cards/opca/83/en?format=image");
// C20
put("C20/Angel", "https://api.scryfall.com/cards/tc20/1/en?format=image");
put("C20/Beast", "https://api.scryfall.com/cards/tc20/11/en?format=image");
put("C20/Bird Illusion", "https://api.scryfall.com/cards/tc20/7/en?format=image");
put("C20/Bird", "https://api.scryfall.com/cards/tc20/2/en?format=image");
put("C20/Dinosaur Cat", "https://api.scryfall.com/cards/tc20/16/en?format=image");
put("C20/Drake", "https://api.scryfall.com/cards/tc20/8/en?format=image");
put("C20/Elemental/1", "https://api.scryfall.com/cards/tc20/10/en?format=image"); // 3/1
put("C20/Elemental/2", "https://api.scryfall.com/cards/tc20/3/en?format=image"); // 4/4
put("C20/Goblin Warrior", "https://api.scryfall.com/cards/tc20/17/en?format=image");
put("C20/Human", "https://api.scryfall.com/cards/tc20/4/en?format=image");
put("C20/Hydra", "https://api.scryfall.com/cards/tc20/12/en?format=image");
put("C20/Insect/1", "https://api.scryfall.com/cards/tc20/13/en?format=image"); // deathtouch
put("C20/Insect/2", "https://api.scryfall.com/cards/tc20/18/en?format=image"); // haste
put("C20/Saproling", "https://api.scryfall.com/cards/tc20/14/en?format=image");
put("C20/Snake", "https://api.scryfall.com/cards/tc20/15/en?format=image");
put("C20/Soldier", "https://api.scryfall.com/cards/tc20/5/en?format=image");
put("C20/Spirit", "https://api.scryfall.com/cards/tc20/6/en?format=image");
put("C20/Treasure", "https://api.scryfall.com/cards/tc20/19/en?format=image");
put("C20/Zombie", "https://api.scryfall.com/cards/tc20/9/en?format=image");
// M21
put("M21/Angel", "https://api.scryfall.com/cards/tm21/1/en?format=image");
put("M21/Emblem Basri Ket", "https://api.scryfall.com/cards/tm21/16/en?format=image");
put("M21/Beast", "https://api.scryfall.com/cards/tm21/10/en?format=image");
put("M21/Bird", "https://api.scryfall.com/cards/tm21/2/en?format=image");
put("M21/Cat/1", "https://api.scryfall.com/cards/tm21/20/en?format=image"); // 1/1
put("M21/Cat/2", "https://api.scryfall.com/cards/tm21/11/en?format=image"); // 2/2
put("M21/Construct", "https://api.scryfall.com/cards/tm21/14/en?format=image");
put("M21/Demon", "https://api.scryfall.com/cards/tm21/6/en?format=image");
put("M21/Dog", "https://api.scryfall.com/cards/tm21/19/en?format=image");
put("M21/Emblem Garruk, Unleashed", "https://api.scryfall.com/cards/tm21/17/en?format=image");
put("M21/Goblin Wizard", "https://api.scryfall.com/cards/tm21/8/en?format=image");
put("M21/Griffin", "https://api.scryfall.com/cards/tm21/3/en?format=image");
put("M21/Knight", "https://api.scryfall.com/cards/tm21/4/en?format=image");
put("M21/Emblem Liliana, Waker of the Dead", "https://api.scryfall.com/cards/tm21/18/en?format=image");
put("M21/Pirate", "https://api.scryfall.com/cards/tm21/9/en?format=image");
put("M21/Saproling", "https://api.scryfall.com/cards/tm21/12/en?format=image");
put("M21/Soldier", "https://api.scryfall.com/cards/tm21/5/en?format=image");
put("M21/Treasure", "https://api.scryfall.com/cards/tm21/15/en?format=image");
put("M21/Weird", "https://api.scryfall.com/cards/tm21/13/en?format=image");
put("M21/Zombie", "https://api.scryfall.com/cards/tm21/7/en?format=image");
// generate supported sets
supportedSets.clear();
for (String cardName : this.keySet()) {

View file

@ -47,7 +47,7 @@ public final class ImageCache {
private static final SoftValuesLoadingCache<String, BufferedImage> FACE_IMAGE_CACHE;
/**
* Common pattern for keys. Format: "<cardname>#<setname>#<collectorID>"
* Common pattern for keys. See ImageCache.getKey for structure info
*/
private static final Pattern KEY_PATTERN = Pattern.compile("(.*)#(.*)#(.*)#(.*)#(.*)#(.*)");
@ -84,14 +84,22 @@ public final class ImageCache {
boolean cardback = false;
String path;
if (collectorId.isEmpty() || "0".equals(collectorId)) {
if (collectorId.isEmpty() || "0".equals(collectorId) || !tokenDescriptor.isEmpty()) { // tokenDescriptor for embalm ability
info.setToken(true);
path = CardImageUtils.generateTokenImagePath(info);
if (path == null) {
cardback = true;
// try token image from card
CardDownloadData newInfo = new CardDownloadData(info);
newInfo.setToken(false);
path = CardImageUtils.buildImagePathToCard(newInfo);
TFile tokenFile = getTFile(path);
if (tokenFile == null || !tokenFile.exists()) {
// token empty token image
// TODO: replace empty token by other default card, not cardback
path = CardImageUtils.buildImagePathToDefault(DirectLinksForDownload.cardbackFilename);
}
}
} else {
path = CardImageUtils.buildImagePathToCard(info);
}
@ -245,13 +253,21 @@ public final class ImageCache {
CardDownloadData info = new CardDownloadData(name, set, collectorId, usesVariousArt, type, tokenSetCode, tokenDescriptor);
String path;
if (collectorId.isEmpty() || "0".equals(collectorId)) {
if (collectorId.isEmpty() || "0".equals(collectorId) || !tokenDescriptor.isEmpty()) { // tokenDescriptor for embalm ability
info.setToken(true);
path = CardImageUtils.generateFullTokenImagePath(info);
path = CardImageUtils.generateTokenImagePath(info);
if (path == null) {
// try token image from card
CardDownloadData newInfo = new CardDownloadData(info);
newInfo.setToken(false);
path = CardImageUtils.buildImagePathToCard(newInfo);
TFile tokenFile = getTFile(path);
if (tokenFile == null || !tokenFile.exists()) {
// token empty token image
// TODO: replace empty token by other default card, not cardback
path = CardImageUtils.buildImagePathToDefault(DirectLinksForDownload.cardbackFilename);
}
}
} else {
path = CardImageUtils.buildImagePathToCard(info);
}
@ -428,11 +444,14 @@ public final class ImageCache {
* Returns the map key for a card, without any suffixes for the image size.
*/
private static String getKey(CardView card, String name, String suffix) {
return name + '#' + card.getExpansionSetCode() + '#' + card.getType() + '#' + card.getCardNumber() + '#'
+ (card.getTokenSetCode() == null ? "" : card.getTokenSetCode())
return name
+ '#' + card.getExpansionSetCode()
+ '#' + card.getType()
+ '#' + card.getCardNumber()
+ '#' + (card.getTokenSetCode() == null ? "" : card.getTokenSetCode())
+ suffix
+ (card.getUsesVariousArt() ? "#usesVariousArt" : "")
+ (card.getTokenDescriptor() != null ? '#' + card.getTokenDescriptor() : "#");
+ '#' + (card.getTokenDescriptor() != null ? card.getTokenDescriptor() : "");
}
/**

View file

@ -14,6 +14,8 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.imageio.ImageIO;
import mage.client.dialog.PreferencesDialog;
import mage.client.util.gui.BufferedImageBuilder;
import org.mage.plugins.card.utils.ImageManager;
import org.mage.plugins.card.utils.Transparency;
@ -31,7 +33,9 @@ public enum ImageManagerImpl implements ImageManager {
"Main2", "Cleanup", "Next_Turn"};
phasesImages = new HashMap<>();
for (String name : phases) {
Image image = getImageFromResource("/phases/phase_" + name.toLowerCase(Locale.ENGLISH) + ".png", new Rectangle(36, 36));
Image image = getImageFromResource(
PreferencesDialog.getCurrentTheme().getPhasePath("phase_" + name.toLowerCase(Locale.ENGLISH) + ".png"),
new Rectangle(36, 36));
phasesImages.put(name, image);
}
}
@ -263,7 +267,8 @@ public enum ImageManagerImpl implements ImageManager {
@Override
public Image getConcedeButtonImage() {
if (imageConcedeButton == null) {
imageConcedeButton = getBufferedImageFromResource("/buttons/concede.png");
imageConcedeButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("concede.png"));
}
return imageConcedeButton;
}
@ -271,7 +276,8 @@ public enum ImageManagerImpl implements ImageManager {
@Override
public Image getSwitchHandsButtonImage() {
if (imageSwitchHandsButton == null) {
imageSwitchHandsButton = getBufferedImageFromResource("/buttons/switch_hands.png");
imageSwitchHandsButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("switch_hands.png"));
}
return imageSwitchHandsButton;
}
@ -279,7 +285,8 @@ public enum ImageManagerImpl implements ImageManager {
@Override
public Image getStopWatchButtonImage() {
if (imageStopWatchingButton == null) {
imageStopWatchingButton = getBufferedImageFromResource("/buttons/stop_watching.png");
imageStopWatchingButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("stop_watching.png"));
}
return imageStopWatchingButton;
}
@ -287,7 +294,8 @@ public enum ImageManagerImpl implements ImageManager {
@Override
public Image getCancelSkipButtonImage() {
if (imageCancelSkipButton == null) {
imageCancelSkipButton = getBufferedImageFromResource("/buttons/cancel_skip.png");
imageCancelSkipButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("cancel_skip.png"));
}
return imageCancelSkipButton;
}
@ -295,7 +303,8 @@ public enum ImageManagerImpl implements ImageManager {
@Override
public Image getSkipNextTurnButtonImage() {
if (imageSkipNextTurnButton == null) {
imageSkipNextTurnButton = getBufferedImageFromResource("/buttons/skip_turn.png");
imageSkipNextTurnButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("skip_turn.png"));
}
return imageSkipNextTurnButton;
}
@ -303,7 +312,8 @@ public enum ImageManagerImpl implements ImageManager {
@Override
public Image getSkipEndTurnButtonImage() {
if (imageSkipToEndTurnButton == null) {
imageSkipToEndTurnButton = getBufferedImageFromResource("/buttons/skip_to_end.png");
imageSkipToEndTurnButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("skip_to_end.png"));
}
return imageSkipToEndTurnButton;
}
@ -311,7 +321,8 @@ public enum ImageManagerImpl implements ImageManager {
@Override
public Image getSkipMainButtonImage() {
if (imageSkipToMainButton == null) {
imageSkipToMainButton = getBufferedImageFromResource("/buttons/skip_to_main.png");
imageSkipToMainButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("skip_to_main.png"));
}
return imageSkipToMainButton;
}
@ -319,7 +330,8 @@ public enum ImageManagerImpl implements ImageManager {
@Override
public Image getSkipStackButtonImage() {
if (imageSkipStackButton == null) {
imageSkipStackButton = getBufferedImageFromResource("/buttons/skip_stack.png");
imageSkipStackButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("skip_stack.png"));
}
return imageSkipStackButton;
}
@ -327,7 +339,8 @@ public enum ImageManagerImpl implements ImageManager {
@Override
public Image getSkipEndStepBeforeYourTurnButtonImage() {
if (imageSkipUntilEndStepBeforeYourTurnButton == null) {
imageSkipUntilEndStepBeforeYourTurnButton = getBufferedImageFromResource("/buttons/skip_to_previous_end.png");
imageSkipUntilEndStepBeforeYourTurnButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("skip_to_previous_end.png"));
}
return imageSkipUntilEndStepBeforeYourTurnButton;
}
@ -335,7 +348,8 @@ public enum ImageManagerImpl implements ImageManager {
@Override
public Image getSkipYourNextTurnButtonImage() {
if (imageSkipYourNextTurnButton == null) {
imageSkipYourNextTurnButton = getBufferedImageFromResource("/buttons/skip_all.png");
imageSkipYourNextTurnButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("skip_all.png"));
}
return imageSkipYourNextTurnButton;
}
@ -343,7 +357,8 @@ public enum ImageManagerImpl implements ImageManager {
@Override
public Image getToggleRecordMacroButtonImage() {
if (imageToggleRecordMacroButton == null) {
imageToggleRecordMacroButton = getBufferedImageFromResource("/buttons/toggle_macro.png");
imageToggleRecordMacroButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("toggle_macro.png"));
}
return imageToggleRecordMacroButton;
}

View file

@ -12,7 +12,6 @@ import mage.components.ImagePanel;
import mage.components.ImagePanelStyle;
import mage.interfaces.plugin.ThemePlugin;
import net.xeoh.plugins.base.annotations.PluginImplementation;
import net.xeoh.plugins.base.annotations.events.Init;
import net.xeoh.plugins.base.annotations.events.PluginLoaded;
import net.xeoh.plugins.base.annotations.meta.Author;
import org.apache.log4j.Logger;
@ -27,10 +26,6 @@ public class ThemePluginImpl implements ThemePlugin {
private final List flist = new List();
private final String BackgroundDir = "backgrounds" + File.separator;
@Init
public void init() {
}
@PluginLoaded
public void newPlugin(ThemePlugin plugin) {
log.info(plugin.toString() + " has been loaded.");
@ -104,10 +99,11 @@ public class ThemePluginImpl implements ThemePlugin {
}
}
// Sets background for in-battle
// loadbuffer_default - Only apply theme background if no custom user background set
private BufferedImage loadbuffer_default() throws IOException {
String filename = "/dragon.png";
BufferedImage res;
InputStream is = this.getClass().getResourceAsStream(filename);
InputStream is = this.getClass().getResourceAsStream(PreferencesDialog.getCurrentTheme().getBattleBackgroundPath());
res = ImageIO.read(is);
return res;
}
@ -150,14 +146,14 @@ public class ThemePluginImpl implements ThemePlugin {
return bgPanel;
}
// Sets background for logged in user for tables/deck editor/card viewer/etc
private synchronized ImagePanel createImagePanelInstance() {
if (background == null) {
String filename = "/background.png";
try {
if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_BACKGROUND_IMAGE_DEFAULT, "true").equals("true")) {
InputStream is = this.getClass().getResourceAsStream(filename);
InputStream is = this.getClass().getResourceAsStream(PreferencesDialog.getCurrentTheme().getBackgroundPath());
if (is == null) {
throw new FileNotFoundException("Couldn't find " + filename + " in resources.");
throw new FileNotFoundException("Couldn't find " + PreferencesDialog.getCurrentTheme().getBackgroundPath() + " in resources.");
}
background = ImageIO.read(is);
} else {
@ -174,15 +170,16 @@ public class ThemePluginImpl implements ThemePlugin {
}
}
if (background == null) {
String filename = "/background/background.png";
InputStream is = this.getClass().getResourceAsStream(filename);
if (is == null) {
throw new FileNotFoundException("Couldn't find " + filename + " in resources.");
}
background = ImageIO.read(is);
}
if (background == null) {
throw new FileNotFoundException("Couldn't find " + filename + " in resources.");
}
}
} catch (Exception e) {
log.error(e.getMessage(), e);
return null;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 KiB

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View file

Before

Width:  |  Height:  |  Size: 2 MiB

After

Width:  |  Height:  |  Size: 2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 655 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 951 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Some files were not shown because too many files have changed in this diff Show more