diff --git a/Mage.Client/plugins/mage-card-plugin.jar b/Mage.Client/plugins/mage-card-plugin.jar index 45bf0f62ec8..1ad58bba6e9 100644 Binary files a/Mage.Client/plugins/mage-card-plugin.jar and b/Mage.Client/plugins/mage-card-plugin.jar differ diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java index a31bcc88b8a..95f83f64d15 100644 --- a/Mage.Client/src/main/java/mage/client/MageFrame.java +++ b/Mage.Client/src/main/java/mage/client/MageFrame.java @@ -137,7 +137,7 @@ public class MageFrame extends javax.swing.JFrame { initComponents(); setSize(1024,768); - this.setExtendedState(JFrame.MAXIMIZED_BOTH); + //this.setExtendedState(JFrame.MAXIMIZED_BOTH); session = new Session(this); connectDialog = new ConnectDialog(); diff --git a/Mage.Client/src/main/java/mage/client/cards/BigCard.java b/Mage.Client/src/main/java/mage/client/cards/BigCard.java index 6d13f4a0b16..5c7d1adab0e 100644 --- a/Mage.Client/src/main/java/mage/client/cards/BigCard.java +++ b/Mage.Client/src/main/java/mage/client/cards/BigCard.java @@ -51,6 +51,7 @@ import java.util.UUID; import javax.swing.text.BadLocationException; import javax.swing.text.StyledDocument; +import mage.client.components.CardInfoPane; import mage.client.plugins.impl.Plugins; import org.jdesktop.swingx.JXPanel; @@ -66,6 +67,8 @@ public class BigCard extends javax.swing.JPanel { protected JXPanel panel; protected boolean initState; + protected CardInfoPane cardInfoPane; + public BigCard() { initComponents(); if (!Plugins.getInstance().isCardPluginLoaded()) { diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java index 74c9e2b6210..6ed8cc69e05 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java @@ -34,7 +34,20 @@ package mage.client.deckeditor; -import java.awt.Cursor; +import mage.cards.Card; +import mage.cards.decks.Deck; +import mage.cards.decks.DeckCardLists; +import mage.client.MageFrame; +import mage.client.plugins.impl.Plugins; +import mage.client.util.Event; +import mage.client.util.Listener; +import mage.components.CardInfoPane; +import mage.game.GameException; +import mage.view.CardsView; + +import javax.swing.*; +import javax.swing.filechooser.FileFilter; +import java.awt.*; import java.io.File; import java.io.IOException; import java.lang.reflect.Constructor; @@ -42,19 +55,6 @@ import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; -import javax.swing.JFileChooser; -import javax.swing.JOptionPane; -import javax.swing.filechooser.FileFilter; - -import mage.cards.Card; -import mage.cards.decks.Deck; -import mage.cards.decks.DeckCardLists; -import mage.client.MageFrame; -import mage.client.util.Event; -import mage.client.util.Listener; -import mage.game.GameException; -import mage.view.CardsView; - /** * * @author BetaSteward_at_googlemail.com @@ -64,6 +64,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { private JFileChooser fcSelectDeck; private JFileChooser fcImportDeck; private Deck deck = new Deck(); + private boolean isShowCardInfo = false; /** Creates new form DeckEditorPanel */ public DeckEditorPanel() { @@ -96,6 +97,9 @@ public class DeckEditorPanel extends javax.swing.JPanel { if (System.getProperty("draft") != null) { cardSelector.getCardsList().removeCard(card.getId()); } + if (cardInfoPane instanceof CardInfoPane) { + ((CardInfoPane)cardInfoPane).setCard(card); + } break; } } @@ -150,13 +154,6 @@ public class DeckEditorPanel extends javax.swing.JPanel { } } - /** 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") - // //GEN-BEGIN:initComponents private void initComponents() { jSplitPane1 = new javax.swing.JSplitPane(); @@ -179,6 +176,16 @@ public class DeckEditorPanel extends javax.swing.JPanel { bigCard.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))); + cardInfoPane = Plugins.getInstance().getCardInfoPane(); + if (cardInfoPane != null && System.getProperty("testCardInfo") != null) { + cardInfoPane.setPreferredSize(new Dimension(170,230)); + cardInfoPane.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))); + isShowCardInfo = true; + } else { + cardInfoPane = new JLabel(); + cardInfoPane.setVisible(false); + } + lblDeckName.setLabelFor(txtDeckName); lblDeckName.setText("Deck Name:"); @@ -225,10 +232,11 @@ public class DeckEditorPanel extends javax.swing.JPanel { .addGroup(jPanel1Layout.createSequentialGroup() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() - .addGap(6, 6, 6) - .addComponent(lblDeckName) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtDeckName, javax.swing.GroupLayout.DEFAULT_SIZE, 189, Short.MAX_VALUE)) + .addGap(6, 6, 6) + .addComponent(lblDeckName) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtDeckName, javax.swing.GroupLayout.DEFAULT_SIZE, 189, Short.MAX_VALUE)) + .addComponent(cardInfoPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(bigCard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() @@ -249,17 +257,18 @@ public class DeckEditorPanel extends javax.swing.JPanel { .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(txtDeckName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lblDeckName)) + .addComponent(txtDeckName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lblDeckName)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(btnSave) - .addComponent(btnLoad) - .addComponent(btnNew) - .addComponent(btnExit)) + .addComponent(btnSave) + .addComponent(btnLoad) + .addComponent(btnNew) + .addComponent(btnExit)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnImport) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 159, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, isShowCardInfo ? 30 : 159, Short.MAX_VALUE) + .addComponent(cardInfoPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(bigCard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) ); @@ -277,7 +286,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jSplitPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 615, Short.MAX_VALUE) ); - }// //GEN-END:initComponents + } private void btnLoadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLoadActionPerformed String lastFolder = MageFrame.getPreferences().get("lastDeckFolder", ""); @@ -396,6 +405,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { private javax.swing.JTextField txtDeckName; // End of variables declaration//GEN-END:variables + private JComponent cardInfoPane; } class DeckFilter extends FileFilter { diff --git a/Mage.Client/src/main/java/mage/client/plugins/MagePlugins.java b/Mage.Client/src/main/java/mage/client/plugins/MagePlugins.java index 000b2727fef..61807e13ed9 100644 --- a/Mage.Client/src/main/java/mage/client/plugins/MagePlugins.java +++ b/Mage.Client/src/main/java/mage/client/plugins/MagePlugins.java @@ -34,4 +34,5 @@ public interface MagePlugins { Image getManaSymbolImage(String symbol); void onAddCard(MagePermanent card); void onRemoveCard(MagePermanent card); + JComponent getCardInfoPane(); } diff --git a/Mage.Client/src/main/java/mage/client/plugins/impl/Plugins.java b/Mage.Client/src/main/java/mage/client/plugins/impl/Plugins.java index 88c645203bd..eef3fa4139e 100644 --- a/Mage.Client/src/main/java/mage/client/plugins/impl/Plugins.java +++ b/Mage.Client/src/main/java/mage/client/plugins/impl/Plugins.java @@ -181,4 +181,14 @@ public class Plugins implements MagePlugins { this.cardPlugin.onRemoveCard(card); } } + + @Override + public JComponent getCardInfoPane() { + if (this.cardPlugin != null) { + return this.cardPlugin.getCardInfoPane(); + } + return null; + } + + } diff --git a/Mage.Common/src/mage/components/CardInfoPane.java b/Mage.Common/src/mage/components/CardInfoPane.java new file mode 100644 index 00000000000..19b1047ca23 --- /dev/null +++ b/Mage.Common/src/mage/components/CardInfoPane.java @@ -0,0 +1,14 @@ +package mage.components; + +import mage.cards.Card; + +/** + * Card info pane for displaying card rules. + * Supports drawing mana symbols. + * + * @author nantuko + */ +public interface CardInfoPane { + public void setCard (final Card card); + public boolean isCurrentCard (Card card); +} diff --git a/Mage.Common/src/mage/interfaces/plugin/CardPlugin.java b/Mage.Common/src/mage/interfaces/plugin/CardPlugin.java index 72cdd0346d4..4ba61be4d29 100644 --- a/Mage.Common/src/mage/interfaces/plugin/CardPlugin.java +++ b/Mage.Common/src/mage/interfaces/plugin/CardPlugin.java @@ -33,4 +33,5 @@ public interface CardPlugin extends Plugin { Image getManaSymbolImage(String symbol); void onAddCard(MagePermanent card); void onRemoveCard(MagePermanent card); + JComponent getCardInfoPane(); } diff --git a/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/arcane/ManaSymbols.java b/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/arcane/ManaSymbols.java index 6cdc968b436..932e57bd155 100644 --- a/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/arcane/ManaSymbols.java +++ b/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/arcane/ManaSymbols.java @@ -84,10 +84,10 @@ public class ManaSymbols { static public synchronized String replaceSymbolsWithHTML (String value, boolean small) { if (small) - return replaceSymbolsPattern.matcher(value).replaceAll(""); + return replaceSymbolsPattern.matcher(value).replaceAll(""); else { - value = value.replace("{slash}", ""); - return replaceSymbolsPattern.matcher(value).replaceAll(""); + value = value.replace("{slash}", ""); + return replaceSymbolsPattern.matcher(value).replaceAll(""); } } } diff --git a/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/arcane/ThreadUtils.java b/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/arcane/ThreadUtils.java new file mode 100644 index 00000000000..4df8c5a0d20 --- /dev/null +++ b/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/card/arcane/ThreadUtils.java @@ -0,0 +1,44 @@ +package org.mage.card.arcane; + +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * Util method to work with threads. + * + * @author ayrat + */ +public class ThreadUtils { + + static public ThreadPoolExecutor threadPool; + static private int threadCount; + static { + threadPool = new ThreadPoolExecutor(4, 4, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), new ThreadFactory() { + public Thread newThread (Runnable runnable) { + threadCount++; + Thread thread = new Thread(runnable, "Util" + threadCount); + thread.setDaemon(true); + return thread; + } + }); + threadPool.prestartAllCoreThreads(); + } + + static public void sleep (int millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException ignored) { + } + } + + static public void wait (Object lock) { + synchronized (lock) { + try { + lock.wait(); + } catch (InterruptedException ex) { + } + } + } +} diff --git a/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/plugins/card/CardPluginImpl.java b/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/plugins/card/CardPluginImpl.java index dd70c1aba95..7afd87da181 100644 --- a/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/plugins/card/CardPluginImpl.java +++ b/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/plugins/card/CardPluginImpl.java @@ -22,6 +22,7 @@ import mage.cards.Card; import mage.cards.CardDimensions; import mage.cards.MagePermanent; import mage.cards.action.ActionCallback; +import mage.components.CardInfoPane; import mage.interfaces.plugin.CardPlugin; import mage.utils.CardUtil; import mage.view.CardView; @@ -41,6 +42,7 @@ import org.mage.plugins.card.dl.DownloadJob; import org.mage.plugins.card.dl.Downloader; import org.mage.plugins.card.dl.sources.GathererSymbols; import org.mage.plugins.card.images.DownloadPictures; +import org.mage.plugins.card.info.CardInfoPaneImpl; /** * {@link CardPlugin} implementation. @@ -462,4 +464,9 @@ public class CardPluginImpl implements CardPlugin { } } } + + @Override + public JComponent getCardInfoPane() { + return new CardInfoPaneImpl(); + } } diff --git a/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/plugins/card/info/CardInfoPaneImpl.java b/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/plugins/card/info/CardInfoPaneImpl.java new file mode 100644 index 00000000000..e13fd59aa91 --- /dev/null +++ b/Mage.Plugins/Mage.Card.Plugin/src/main/java/org/mage/plugins/card/info/CardInfoPaneImpl.java @@ -0,0 +1,162 @@ +package org.mage.plugins.card.info; + +import mage.Constants; +import mage.cards.Card; +import mage.components.CardInfoPane; +import mage.utils.CardUtil; +import org.mage.card.arcane.ManaSymbols; +import org.mage.card.arcane.ThreadUtils; +import org.mage.card.arcane.UI; + +import javax.swing.*; +import java.awt.*; +import java.util.List; + +/** + * Card info pane for displaying card rules. + * Supports drawing mana symbols. + * + * @author nantuko + */ +public class CardInfoPaneImpl extends JEditorPane implements CardInfoPane { + + private Card currentCard; + + public CardInfoPaneImpl() { + UI.setHTMLEditorKit(this); + setEditable(false); + setBackground(Color.white); + } + + public void setCard (final Card card) { + if (card == null) return; + if (isCurrentCard(card)) return; + currentCard = card; + + ThreadUtils.threadPool.submit(new Runnable() { + public void run () { + if (!card.equals(currentCard)) return; + + String castingCost = UI.getDisplayManaCost(card.getManaCost().getText()); + castingCost = ManaSymbols.replaceSymbolsWithHTML(castingCost, false); + + int symbolCount = 0; + int offset = 0; + while ((offset = castingCost.indexOf(" rulings = card.getRules(); + + boolean smallImages = true; + int fontSize = 11; + + String fontFamily = "tahoma"; + /*if (prefs.fontFamily == CardFontFamily.arial) + fontFamily = "arial"; + else if (prefs.fontFamily == CardFontFamily.verdana) { + fontFamily = "verdana"; + }*/ + + final StringBuffer buffer = new StringBuffer(512); + buffer.append(""); + buffer.append(""); + buffer.append("
"); + buffer.append(card.getName()); + buffer.append(""); + buffer.append(castingCost); + buffer.append("
"); + buffer.append("
"); + buffer.append(getTypes(card)); + buffer.append(""); + switch (card.getRarity()) { + case RARE: + buffer.append(""); + break; + case UNCOMMON: + buffer.append(""); + break; + case COMMON: + buffer.append(""); + break; + case MYTHIC: + buffer.append(""); + break; + } + buffer.append(card.getExpansionSetCode().toUpperCase()); + buffer.append("
"); + + String legal = ""; + if (rulings.size() > 0) { + legal = legal.replaceAll("#([^#]+)#", "$1"); + legal = legal.replaceAll("\\s*//\\s*", "
"); + legal = legal.replace("\r\n", "
"); + legal += "
"; + for (String ruling : rulings) { + legal += ruling; + legal += "

"; + } + } + + if (legal.length() > 0) { + buffer.append("
"); + legal = legal.replaceAll("\\{this\\}", card.getName()); + legal = legal.replaceAll("\\{source\\}", card.getName()); + buffer.append(ManaSymbols.replaceSymbolsWithHTML(legal, smallImages)); + } + + String pt = ""; + if (card.getCardType().contains(Constants.CardType.CREATURE)) { + pt = card.getPower() + "/" + card.getToughness(); + } else if (card.getCardType().contains(Constants.CardType.PLANESWALKER)) { + pt = card.getLoyalty().toString(); + } + if (pt.length() > 0) { + buffer.append("
"); + buffer.append(""); + buffer.append(""); + buffer.append(pt); + buffer.append(""); + buffer.append("
"); + } + + buffer.append("
"); + + SwingUtilities.invokeLater(new Runnable() { + public void run () { + if (!card.equals(currentCard)) return; + setText(buffer.toString()); + System.out.println(buffer.toString()); + setCaretPosition(0); + } + }); + } + }); + } + + private String getTypes(Card card) { + String types = ""; + for (String superType : card.getSupertype()) { + types += superType + " "; + } + for (Constants.CardType cardType : card.getCardType()) { + types += cardType.toString() + " "; + } + if (card.getSubtype().size() > 0) { + types += "- "; + } + for (String subType : card.getSubtype()) { + types += subType + " "; + } + return types.trim(); + } + + public boolean isCurrentCard (Card card) { + return currentCard != null && card.equals(currentCard); + } +}