1
0
Fork 0
mirror of https://github.com/correl/mage.git synced 2025-04-06 01:04:10 -09:00

Collection Viewer.

This commit is contained in:
magenoxx 2011-01-09 03:03:19 +03:00
parent fc3d8cb708
commit 56eff16857
32 changed files with 1505 additions and 494 deletions

View file

@ -34,6 +34,7 @@
package mage.client; package mage.client;
import mage.cards.Card;
import mage.cards.decks.Deck; import mage.cards.decks.Deck;
import mage.client.cards.CardsStorage; import mage.client.cards.CardsStorage;
import mage.client.components.MageComponents; import mage.client.components.MageComponents;
@ -41,6 +42,7 @@ import mage.client.components.MageJDesktop;
import mage.client.components.MageRoundPane; import mage.client.components.MageRoundPane;
import mage.client.components.arcane.ManaSymbols; import mage.client.components.arcane.ManaSymbols;
import mage.client.constants.Constants.DeckEditorMode; import mage.client.constants.Constants.DeckEditorMode;
import mage.client.deckeditor.collection.viewer.CollectionViewerPane;
import mage.client.dialog.*; import mage.client.dialog.*;
import mage.client.plugins.impl.Plugins; import mage.client.plugins.impl.Plugins;
import mage.client.remote.Session; import mage.client.remote.Session;
@ -61,6 +63,7 @@ import java.awt.image.BufferedImage;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Level; import java.util.logging.Level;
@ -122,6 +125,7 @@ public class MageFrame extends javax.swing.JFrame {
} }
Plugins.getInstance().loadPlugins(); Plugins.getInstance().loadPlugins();
ManaSymbols.loadImages();
initComponents(); initComponents();
setSize(1024, 768); setSize(1024, 768);
@ -137,8 +141,6 @@ public class MageFrame extends javax.swing.JFrame {
desktopPane.add(pickNumber, JLayeredPane.POPUP_LAYER); desktopPane.add(pickNumber, JLayeredPane.POPUP_LAYER);
session.getUI().addComponent(MageComponents.DESKTOP_PANE, desktopPane); session.getUI().addComponent(MageComponents.DESKTOP_PANE, desktopPane);
ManaSymbols.loadImages();
addTooltipContainer(); addTooltipContainer();
setBackground(); setBackground();
addMageLabel(); addMageLabel();
@ -287,7 +289,7 @@ public class MageFrame extends javax.swing.JFrame {
} }
private void btnImagesActionPerformed(java.awt.event.ActionEvent evt) { private void btnImagesActionPerformed(java.awt.event.ActionEvent evt) {
Plugins.getInstance().downloadImage(CardsStorage.getAllCards()); Plugins.getInstance().downloadImage(new HashSet<Card>(CardsStorage.getAllCards()));
} }
private void btnSymbolsActionPerformed(java.awt.event.ActionEvent evt) { private void btnSymbolsActionPerformed(java.awt.event.ActionEvent evt) {
@ -355,6 +357,7 @@ public class MageFrame extends javax.swing.JFrame {
tablesPane = new mage.client.table.TablesPane(); tablesPane = new mage.client.table.TablesPane();
gamePane = new mage.client.game.GamePane(); gamePane = new mage.client.game.GamePane();
deckEditorPane = new mage.client.deckeditor.DeckEditorPane(); deckEditorPane = new mage.client.deckeditor.DeckEditorPane();
collectionViewerPane = new CollectionViewerPane();
mageToolbar = new javax.swing.JToolBar(); mageToolbar = new javax.swing.JToolBar();
btnConnect = new javax.swing.JButton(); btnConnect = new javax.swing.JButton();
jSeparator5 = new javax.swing.JToolBar.Separator(); jSeparator5 = new javax.swing.JToolBar.Separator();
@ -368,11 +371,12 @@ public class MageFrame extends javax.swing.JFrame {
jSeparator1 = new javax.swing.JToolBar.Separator(); jSeparator1 = new javax.swing.JToolBar.Separator();
btnExit = new javax.swing.JButton(); btnExit = new javax.swing.JButton();
lblStatus = new javax.swing.JLabel(); lblStatus = new javax.swing.JLabel();
jSeparator6 = new javax.swing.JToolBar.Separator();
btnCollectionViewer = new JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
//setMinimumSize(new java.awt.Dimension(1024, 768)); //setMinimumSize(new java.awt.Dimension(1024, 768));
//desktopPane.setBackground(new java.awt.Color(204, 204, 204));
tablesPane.setBounds(20, 10, 560, 440); tablesPane.setBounds(20, 10, 560, 440);
desktopPane.add(tablesPane, javax.swing.JLayeredPane.DEFAULT_LAYER); desktopPane.add(tablesPane, javax.swing.JLayeredPane.DEFAULT_LAYER);
try { try {
@ -394,6 +398,13 @@ public class MageFrame extends javax.swing.JFrame {
} catch (java.beans.PropertyVetoException e1) { } catch (java.beans.PropertyVetoException e1) {
e1.printStackTrace(); e1.printStackTrace();
} }
collectionViewerPane.setBounds(140, 50, -1, -1);
desktopPane.add(collectionViewerPane, javax.swing.JLayeredPane.DEFAULT_LAYER);
try {
collectionViewerPane.setMaximum(true);
} catch (java.beans.PropertyVetoException e1) {
e1.printStackTrace();
}
mageToolbar.setFloatable(false); mageToolbar.setFloatable(false);
mageToolbar.setRollover(true); mageToolbar.setRollover(true);
@ -437,6 +448,19 @@ public class MageFrame extends javax.swing.JFrame {
mageToolbar.add(btnDeckEditor); mageToolbar.add(btnDeckEditor);
mageToolbar.add(jSeparator2); mageToolbar.add(jSeparator2);
btnCollectionViewer.setText("Collection Viewer");
btnCollectionViewer.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
btnCollectionViewer.setFocusable(false);
btnCollectionViewer.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
btnCollectionViewer.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
btnCollectionViewer.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnCollectionViewerActionPerformed(evt);
}
});
mageToolbar.add(btnCollectionViewer);
mageToolbar.add(jSeparator6);
btnPreferences.setText("Preferences"); btnPreferences.setText("Preferences");
btnPreferences.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); btnPreferences.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
btnPreferences.setFocusable(false); btnPreferences.setFocusable(false);
@ -500,9 +524,17 @@ public class MageFrame extends javax.swing.JFrame {
private void btnDeckEditorActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDeckEditorActionPerformed private void btnDeckEditorActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDeckEditorActionPerformed
this.gamePane.setVisible(false); this.gamePane.setVisible(false);
this.tablesPane.setVisible(false); this.tablesPane.setVisible(false);
this.collectionViewerPane.setVisible(false);
showDeckEditor(DeckEditorMode.Constructed, null, null); showDeckEditor(DeckEditorMode.Constructed, null, null);
}//GEN-LAST:event_btnDeckEditorActionPerformed }//GEN-LAST:event_btnDeckEditorActionPerformed
private void btnCollectionViewerActionPerformed(java.awt.event.ActionEvent evt) {
this.gamePane.setVisible(false);
this.tablesPane.setVisible(false);
this.deckEditorPane.setVisible(false);
showCollectionViewer();
}
private void btnPreferencesActionPerformed(java.awt.event.ActionEvent evt) { private void btnPreferencesActionPerformed(java.awt.event.ActionEvent evt) {
PhasesDialog.main(new String[]{}); PhasesDialog.main(new String[]{});
} }
@ -510,6 +542,7 @@ public class MageFrame extends javax.swing.JFrame {
private void btnGamesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnGamesActionPerformed private void btnGamesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnGamesActionPerformed
this.gamePane.setVisible(false); this.gamePane.setVisible(false);
this.deckEditorPane.setVisible(false); this.deckEditorPane.setVisible(false);
this.collectionViewerPane.setVisible(false);
this.tablesPane.setVisible(true); this.tablesPane.setVisible(true);
this.tablesPane.showTables(); this.tablesPane.showTables();
}//GEN-LAST:event_btnGamesActionPerformed }//GEN-LAST:event_btnGamesActionPerformed
@ -556,6 +589,7 @@ public class MageFrame extends javax.swing.JFrame {
this.tablesPane.setVisible(false); this.tablesPane.setVisible(false);
this.gamePane.setVisible(false); this.gamePane.setVisible(false);
this.deckEditorPane.setVisible(false); this.deckEditorPane.setVisible(false);
this.collectionViewerPane.setVisible(false);
} }
public void showDeckEditor(DeckEditorMode mode, Deck deck, UUID tableId) { public void showDeckEditor(DeckEditorMode mode, Deck deck, UUID tableId) {
@ -563,6 +597,10 @@ public class MageFrame extends javax.swing.JFrame {
this.deckEditorPane.show(mode, deck, tableId); this.deckEditorPane.show(mode, deck, tableId);
} }
public void showCollectionViewer() {
this.collectionViewerPane.setVisible(true);
}
public static CombatDialog getCombatDialog() { public static CombatDialog getCombatDialog() {
return combat; return combat;
} }
@ -608,10 +646,12 @@ public class MageFrame extends javax.swing.JFrame {
private javax.swing.JButton btnAbout; private javax.swing.JButton btnAbout;
private javax.swing.JButton btnConnect; private javax.swing.JButton btnConnect;
private javax.swing.JButton btnDeckEditor; private javax.swing.JButton btnDeckEditor;
private javax.swing.JButton btnCollectionViewer;
private javax.swing.JButton btnPreferences; private javax.swing.JButton btnPreferences;
private javax.swing.JButton btnExit; private javax.swing.JButton btnExit;
private javax.swing.JButton btnGames; private javax.swing.JButton btnGames;
private mage.client.deckeditor.DeckEditorPane deckEditorPane; private mage.client.deckeditor.DeckEditorPane deckEditorPane;
private CollectionViewerPane collectionViewerPane;
private static MageJDesktop desktopPane; private static MageJDesktop desktopPane;
private mage.client.game.GamePane gamePane; private mage.client.game.GamePane gamePane;
private javax.swing.JToolBar.Separator jSeparator1; private javax.swing.JToolBar.Separator jSeparator1;
@ -619,6 +659,7 @@ public class MageFrame extends javax.swing.JFrame {
private javax.swing.JToolBar.Separator jSeparator3; private javax.swing.JToolBar.Separator jSeparator3;
private javax.swing.JToolBar.Separator jSeparator4; private javax.swing.JToolBar.Separator jSeparator4;
private javax.swing.JToolBar.Separator jSeparator5; private javax.swing.JToolBar.Separator jSeparator5;
private javax.swing.JToolBar.Separator jSeparator6;
private javax.swing.JLabel lblStatus; private javax.swing.JLabel lblStatus;
private javax.swing.JToolBar mageToolbar; private javax.swing.JToolBar mageToolbar;
private mage.client.table.TablesPane tablesPane; private mage.client.table.TablesPane tablesPane;

View file

@ -69,9 +69,9 @@ public class BigCard extends JComponent {
protected float hue = 0.005f; protected float hue = 0.005f;
protected float dh = 0.005f; protected float dh = 0.005f;
static private final int DEFAULT_DELAY_PERIOD = 40; static private final int DEFAULT_DELAY_PERIOD = 30;
static private final float LEFT_BOUNDARY = 0.0f; static private final float LEFT_BOUNDARY = 0.0f;
static private final float RIGHT_BOUNDARY = 0.1f; static private final float RIGHT_BOUNDARY = 1f;
public BigCard() { public BigCard() {
initComponents(); initComponents();
@ -247,6 +247,7 @@ public class BigCard extends JComponent {
setFocusable(false); setFocusable(false);
setMinimumSize(new Dimension(FRAME_MAX_WIDTH, FRAME_MAX_HEIGHT)); setMinimumSize(new Dimension(FRAME_MAX_WIDTH, FRAME_MAX_HEIGHT));
setMaximumSize(new Dimension(FRAME_MAX_WIDTH, FRAME_MAX_HEIGHT));
setOpaque(false); setOpaque(false);
setPreferredSize(getMinimumSize()); setPreferredSize(getMinimumSize());
setLayout(null); setLayout(null);

View file

@ -93,7 +93,7 @@ public class CardGrid extends javax.swing.JLayeredPane implements MouseListener
} }
private void addCard(CardView card, BigCard bigCard, UUID gameId) { private void addCard(CardView card, BigCard bigCard, UUID gameId) {
MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, Config.dimensions, gameId); MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, Config.dimensions, gameId, true);
cards.put(card.getId(), cardImg); cards.put(card.getId(), cardImg);
cardImg.addMouseListener(this); cardImg.addMouseListener(this);
add(cardImg); add(cardImg);

View file

@ -120,7 +120,7 @@ public class Cards extends javax.swing.JPanel {
} }
private void addCard(CardView card, BigCard bigCard, UUID gameId) { private void addCard(CardView card, BigCard bigCard, UUID gameId) {
MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, Config.dimensions, gameId); MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, Config.dimensions, gameId, true);
cards.put(card.getId(), cardImg); cards.put(card.getId(), cardImg);
cardArea.add(cardImg); cardArea.add(cardImg);
} }

View file

@ -101,7 +101,7 @@ public class CardsList extends javax.swing.JPanel implements MouseListener {
} }
private void addCard(CardView card, BigCard bigCard, UUID gameId, Rectangle rectangle) { private void addCard(CardView card, BigCard bigCard, UUID gameId, Rectangle rectangle) {
MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, Config.dimensions, gameId); MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, Config.dimensions, gameId, true);
cardImg.setBounds(rectangle); cardImg.setBounds(rectangle);
cardArea.add(cardImg); cardArea.add(cardImg);
cardArea.moveToFront(cardImg); cardArea.moveToFront(cardImg);

View file

@ -1,93 +1,193 @@
package mage.client.cards; package mage.client.cards;
import java.io.InputStream;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.ExpansionSet; import mage.cards.ExpansionSet;
import mage.sets.Sets; import mage.sets.Sets;
import mage.utils.CardUtil; import mage.utils.CardUtil;
import java.io.InputStream;
import java.util.*;
/**
* Stores all implemented cards on client side.
* Used by deck editor, deck generator, collection viewer, etc.
*
* @author nantuko
*/
public class CardsStorage { public class CardsStorage {
private static Set<Card> allCards = new LinkedHashSet<Card>(); private static List<Card> allCards = new ArrayList<Card>();
private static Set<Card> nonBasicLandCards = new LinkedHashSet<Card>(); private static Set<Card> nonBasicLandCards = new LinkedHashSet<Card>();
private static Map<String, Integer> ratings; private static Map<String, Integer> ratings;
private static Integer min = Integer.MAX_VALUE, max = 0; private static Integer min = Integer.MAX_VALUE, max = 0;
private static int cardsCount;
private static List<String> setCodes = new ArrayList<String>();
static { static {
for (ExpansionSet set : Sets.getInstance().values()) { for (ExpansionSet set : Sets.getInstance().values()) {
Set<Card> cards = set.createCards(); setCodes.add(set.getCode());
allCards.addAll(cards); Set<Card> cards = set.createCards();
for (Card card : cards) { allCards.addAll(cards);
if (CardUtil.isLand(card) && !CardUtil.isBasicLand(card)) { for (Card card : cards) {
nonBasicLandCards.add(card); if (CardUtil.isLand(card) && !CardUtil.isBasicLand(card)) {
} nonBasicLandCards.add(card);
} }
} }
} }
Collections.sort(allCards, new CardComparator());
Collections.sort(setCodes, new SetComparator());
cardsCount = allCards.size();
}
public static Set<Card> getAllCards() { public static List<Card> getAllCards() {
return allCards; return allCards;
} }
public static Set<Card> getNonBasicLandCards() { /**
return nonBasicLandCards; * Get cards from card pool starting from start index and ending with end index.
} * Can filter cards by set (if parameter is not null).
*
* @param start
* @param end
* @param set Cards set code. Can be null.
* @return
*/
public static List<Card> getAllCards(int start, int end, String set) {
List<Card> cards = new ArrayList<Card>();
List<Card> pool;
if (set == null) {
pool = allCards;
} else {
pool = new ArrayList<Card>();
for (Card card : allCards) {
if (card.getExpansionSetCode().equals(set)) {
pool.add(card);
}
}
}
for (int i = start; i < Math.min(end + 1, pool.size()); i++) {
cards.add(pool.get(i));
}
return cards;
}
/** public static int getCardsCount() {
* Return rating of a card: 1-10. return cardsCount;
* }
* @param card
* @return
*/
public static int rateCard(Card card) {
if (ratings == null) {
readRatings();
}
if (ratings.containsKey(card.getName())) {
int r = ratings.get(card.getName());
float f = 10.0f * (r - min) / (max - min);
return (int)Math.round(f); // normalize to [1..10]
}
return 0;
}
private synchronized static void readRatings() {
if (ratings == null) {
ratings = new HashMap<String, Integer>();
String filename = "/ratings.txt";
try {
InputStream is = CardsStorage.class.getResourceAsStream(filename);
Scanner scanner = new Scanner(is);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] s = line.split(":");
if (s.length == 2) {
Integer rating = Integer.parseInt(s[0].trim());
String name = s[1].trim();
if (rating > max) { max = rating; }
if (rating < min) { min = rating; }
ratings.put(name, rating);
}
}
} catch (Exception e) {
e.printStackTrace();
ratings.clear(); // no rating available on exception
}
}
}
public static void main(String[] argv) { public static List<String> getSetCodes() {
for (Card card : getAllCards()) { return setCodes;
String name = card.getName(); }
if (name.equals("Baneslayer Angel") || name.equals("Lightning Bolt") || name.equals("Zombie Outlander")
|| name.equals("Naturalize") || name.equals("Kraken's Eye") || name.equals("Serra Angel")) { public static Set<Card> getNonBasicLandCards() {
System.out.println(name + " : " + rateCard(card)); return nonBasicLandCards;
} }
}
} /**
* Return rating of a card: 1-10.
*
* @param card
* @return
*/
public static int rateCard(Card card) {
if (ratings == null) {
readRatings();
}
if (ratings.containsKey(card.getName())) {
int r = ratings.get(card.getName());
float f = 10.0f * (r - min) / (max - min);
return (int) Math.round(f); // normalize to [1..10]
}
return 0;
}
private synchronized static void readRatings() {
if (ratings == null) {
ratings = new HashMap<String, Integer>();
String filename = "/ratings.txt";
try {
InputStream is = CardsStorage.class.getResourceAsStream(filename);
Scanner scanner = new Scanner(is);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] s = line.split(":");
if (s.length == 2) {
Integer rating = Integer.parseInt(s[0].trim());
String name = s[1].trim();
if (rating > max) {
max = rating;
}
if (rating < min) {
min = rating;
}
ratings.put(name, rating);
}
}
} catch (Exception e) {
e.printStackTrace();
ratings.clear(); // no rating available on exception
}
}
}
public static void main(String[] argv) {
for (Card card : getAllCards()) {
String name = card.getName();
if (name.equals("Baneslayer Angel") || name.equals("Lightning Bolt") || name.equals("Zombie Outlander")
|| name.equals("Naturalize") || name.equals("Kraken's Eye") || name.equals("Serra Angel")) {
System.out.println(name + " : " + rateCard(card));
}
}
}
/**
* Card comparator.
* First compares set codes, then collector ids and just then card names.
* <p/>
* Show latest set cards on top.
*
* @author nantuko
*/
private static class CardComparator implements Comparator<Card> {
private static final String LATEST_SET_CODE = "SOM";
@Override
public int compare(Card o1, Card o2) {
String set1 = o1.getExpansionSetCode();
String set2 = o2.getExpansionSetCode();
if (set1.equals(set2)) {
Integer cid1 = o1.getCardNumber();
Integer cid2 = o2.getCardNumber();
if (cid1 == cid2) {
return o1.getName().compareTo(o2.getName());
} else {
return cid1.compareTo(cid2);
}
} else {
// put latest set on top
if (set1.equals(LATEST_SET_CODE)) {
return -1;
}
if (set2.equals(LATEST_SET_CODE)) {
return 1;
}
return set1.compareTo(set2);
}
}
}
private static class SetComparator implements Comparator<String> {
private static final String LATEST_SET_CODE = "SOM";
@Override
public int compare(String set1, String set2) {
// put latest set on top
if (set1.equals(LATEST_SET_CODE)) {
return -1;
}
if (set2.equals(LATEST_SET_CODE)) {
return 1;
}
return set1.compareTo(set2);
}
}
} }

View file

@ -0,0 +1,171 @@
package mage.client.components;
import mage.client.util.Command;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.font.FontRenderContext;
/**
* Image button with hover.
*
* @author nantuko
*/
public class HoverButton extends JPanel implements MouseListener {
private Image image;
private Image hoverImage;
private Image disabledImage;
private Image selectedImage;
private Image overlayImage;
private Rectangle imageSize;
private Rectangle buttonSize;
private String text;
private int textOffsetY = 0;
private int textOffsetX = -1;
private Dimension overlayImageSize;
private boolean isHovered = false;
private boolean isSelected = false;
private Command observer = null;
private Command onHover = null;
private Color textColor = Color.white;
final static Font textFont = new Font("Arial", Font.PLAIN, 12);
final static Font textFontMini = new Font("Arial", Font.PLAIN, 11);
private boolean useMiniFont = false;
public HoverButton(String text, Image image, Image hover, Image disabled, Rectangle size) {
this(text, image, hover, null, disabled, size);
}
public HoverButton(String text, Image image, Image hover, Image selected, Image disabled, Rectangle size) {
this.image = image;
this.hoverImage = hover;
this.selectedImage = selected;
this.disabledImage = disabled;
this.imageSize = size;
this.text = text;
setOpaque(false);
addMouseListener(this);
}
@Override
public void paintComponent(Graphics g) {
if (isEnabled()) {
if (isHovered) {
g.drawImage(hoverImage, 0, 0, imageSize.width, imageSize.height, this);
if (text != null) {
Graphics2D g2d = (Graphics2D) g;
if (textColor != null) g2d.setColor(textColor);
if (useMiniFont) g2d.setFont(textFontMini);
else g2d.setFont(textFont);
if (textOffsetX == -1) { // calculate once
FontRenderContext frc = g2d.getFontRenderContext();
int textWidth = (int) textFont.getStringBounds(text, frc).getWidth();
if (textWidth > buttonSize.width) {
g2d.setFont(textFontMini);
useMiniFont = true;
frc = g2d.getFontRenderContext();
textWidth = (int) textFontMini.getStringBounds(text, frc).getWidth();
}
textOffsetX = (int) ((imageSize.width - textWidth) / 2);
}
g2d.drawString(text, textOffsetX, textOffsetY);
}
} else {
g.drawImage(image, 0, 0, imageSize.width, imageSize.height, this);
}
if (isSelected) {
if (selectedImage != null) {
g.drawImage(selectedImage, 0, 0, imageSize.width, imageSize.height, this);
} else {
System.err.println("No selectedImage for button.");
}
}
} else {
g.drawImage(disabledImage, 0, 0, imageSize.width, imageSize.height, this);
}
if (overlayImage != null) {
g.drawImage(overlayImage, (imageSize.width - overlayImageSize.width) / 2, 10, this);
}
}
public void setTextColor(Color textColor) {
this.textColor = textColor;
}
public void setOverlayImage(Image image) {
this.overlayImage = image;
this.overlayImageSize = new Dimension(image.getWidth(null), image.getHeight(null));
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
isHovered = true;
this.repaint();
if (onHover != null) {
onHover.execute();
}
}
@Override
public void mouseExited(MouseEvent e) {
isHovered = false;
this.repaint();
}
@Override
public void mousePressed(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1) {
if (isEnabled() && observer != null) {
observer.execute();
}
}
}
@Override
public void mouseReleased(MouseEvent e) {
}
public void setObserver(Command observer) {
this.observer = observer;
}
public void setOnHover(Command onHover) {
this.onHover = onHover;
}
@Override
public void setBounds(Rectangle r) {
super.setBounds(r);
this.textOffsetY = r.height - 2;
this.buttonSize = r;
}
@Override
public void setBounds(int x, int y, int width, int height) {
super.setBounds(x, y, width, height);
this.textOffsetY = height - 2;
this.buttonSize = new Rectangle(x, y, width, height);
}
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean isSelected) {
this.isSelected = isSelected;
}
public void changeSelected() {
this.isSelected = !this.isSelected;
}
}

View file

@ -0,0 +1,59 @@
package mage.client.components;
import javax.swing.*;
import java.awt.*;
/**
* Image based button.
*
* @author nantuko
*/
public class ImageButton extends JButton {
private Image image;
private String text;
public ImageButton(String text, Image image) {
super(new ImageIcon(image));
this.image = image;
this.text = text;
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (text != null) {
g.setColor(Color.GRAY);
int dx = 15;
int dy = 17;
g.setColor(Color.WHITE);
if (text.length() > 5) {
g.drawString(this.text, 8, dy);
} else {
g.drawString(this.text, dx, dy);
}
}
}
public void setImage(Image src) {
this.image = src;
repaint();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(image.getWidth(this), image.getHeight(this));
}
@Override
public Dimension getMinimumSize() {
return new Dimension(image.getWidth(this), image.getHeight(this));
}
@Override
public void setText(String text) {
this.text = text;
repaint();
}
}

View file

@ -0,0 +1,96 @@
package mage.client.components.arcane;
import javax.swing.*;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.text.BreakIterator;
import java.util.Locale;
public class GlowText extends JLabel {
private static final long serialVersionUID = 1827677946939348001L;
private int glowSize;
@SuppressWarnings("unused")
private float glowIntensity;
private Color glowColor;
private boolean wrap;
private int lineCount = 0;
public void setGlow (Color glowColor, int size, float intensity) {
this.glowColor = glowColor;
this.glowSize = size;
this.glowIntensity = intensity;
}
public void setWrap (boolean wrap) {
this.wrap = wrap;
}
public Dimension getPreferredSize () {
Dimension size = super.getPreferredSize();
size.width += glowSize;
size.height += glowSize / 2;
return size;
}
public void setText (String text) {
super.setText(text);
}
public void paint (Graphics g) {
if (getText().length() == 0) return;
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
Dimension size = getSize();
int textX = 0, textY = 0;
int wrapWidth = Math.max(0, wrap ? size.width - glowSize : Integer.MAX_VALUE);
AttributedString attributedString = new AttributedString(getText());
attributedString.addAttribute(TextAttribute.FONT, getFont());
AttributedCharacterIterator charIterator = attributedString.getIterator();
FontRenderContext fontContext = g2d.getFontRenderContext();
LineBreakMeasurer measurer = new LineBreakMeasurer(charIterator, BreakIterator.getWordInstance(Locale.ENGLISH), fontContext);
lineCount = 0;
while (measurer.getPosition() < charIterator.getEndIndex()) {
//TextLayout textLayout = measurer.nextLayout(wrapWidth);
lineCount++;
if (lineCount > 2) break;
}
charIterator.first();
// Use char wrap if word wrap would cause more than two lines of text.
if (lineCount > 2)
measurer = new LineBreakMeasurer(charIterator, BreakIterator.getCharacterInstance(Locale.ENGLISH), fontContext);
else
measurer.setPosition(0);
while (measurer.getPosition() < charIterator.getEndIndex()) {
TextLayout textLayout = measurer.nextLayout(wrapWidth);
float ascent = textLayout.getAscent();
textY += ascent; // Move down to baseline.
g2d.setColor(glowColor);
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f));
textLayout.draw(g2d, textX + glowSize / 2 + 1, textY + glowSize / 2 - 1);
textLayout.draw(g2d, textX + glowSize / 2 + 1, textY + glowSize / 2 + 1);
textLayout.draw(g2d, textX + glowSize / 2 - 1, textY + glowSize / 2 - 1);
textLayout.draw(g2d, textX + glowSize / 2 - 1, textY + glowSize / 2 + 1);
g2d.setColor(getForeground());
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
textLayout.draw(g2d, textX + glowSize / 2, textY + glowSize / 2);
textY += textLayout.getDescent() + textLayout.getLeading(); // Move down to top of next line.
}
}
public int getLineCount() {
return this.lineCount;
}
}

View file

@ -1,5 +1,6 @@
package mage.client.components.arcane; package mage.client.components.arcane;
import mage.client.cards.CardsStorage;
import mage.client.constants.Constants; import mage.client.constants.Constants;
import mage.client.util.gui.BufferedImageBuilder; import mage.client.util.gui.BufferedImageBuilder;
import mage.client.util.gui.ImageResizeUtil; import mage.client.util.gui.ImageResizeUtil;
@ -18,6 +19,7 @@ public class ManaSymbols {
private static final Logger log = Logger.getLogger(ManaSymbols.class); private static final Logger log = Logger.getLogger(ManaSymbols.class);
static private final Map<String, Image> manaImages = new HashMap<String, Image>(); static private final Map<String, Image> manaImages = new HashMap<String, Image>();
static private final Map<String, Image> manaImagesOriginal = new HashMap<String, Image>(); static private final Map<String, Image> manaImagesOriginal = new HashMap<String, Image>();
static private final Map<String, Image> setImages = new HashMap<String, Image>();
static private Pattern replaceSymbolsPattern = Pattern.compile("\\{([^}/]*)/?([^}]*)\\}"); static private Pattern replaceSymbolsPattern = Pattern.compile("\\{([^}/]*)/?([^}]*)\\}");
static private boolean noManaSymbols = false; static private boolean noManaSymbols = false;
@ -40,11 +42,33 @@ public class ManaSymbols {
manaImagesOriginal.put(symbol, image); manaImagesOriginal.put(symbol, image);
} catch (Exception e) {} } catch (Exception e) {}
} }
for (String set : CardsStorage.getSetCodes()) {
String _set = set.equals("CON") ? "CFX" : set;
File file = new File(Constants.RESOURCE_PATH_SET + _set + ".jpg");
try {
Image image = UI.getImageIcon(file.getAbsolutePath()).getImage();
int width = image.getWidth(null);
if (width > 21) {
int h = image.getHeight(null);
if (h > 0) {
Rectangle r = new Rectangle(21, (int)(h * 21.0f / width));
BufferedImage resized = ImageResizeUtil.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r);
setImages.put(set, resized);
}
} else {
setImages.put(set, image);
}
} catch (Exception e) {}
}
} }
static public Image getManaSymbolImage(String symbol) { static public Image getManaSymbolImage(String symbol) {
return manaImagesOriginal.get(symbol); return manaImagesOriginal.get(symbol);
} }
static public Image getSetSymbolImage(String set) {
return setImages.get(set);
}
static public void draw (Graphics g, String manaCost, int x, int y) { static public void draw (Graphics g, String manaCost, int x, int y) {
if (manaCost.length() == 0) return; if (manaCost.length() == 0) return;

View file

@ -77,6 +77,7 @@ public final class Constants {
public static final String RESOURCE_PATH_MANA_LARGE = IO.imageBaseDir + "symbols" + File.separator + "large"; public static final String RESOURCE_PATH_MANA_LARGE = IO.imageBaseDir + "symbols" + File.separator + "large";
public static final String RESOURCE_PATH_MANA_MEDIUM = IO.imageBaseDir + "symbols" + File.separator + "medium"; public static final String RESOURCE_PATH_MANA_MEDIUM = IO.imageBaseDir + "symbols" + File.separator + "medium";
public static final String RESOURCE_PATH_SET = IO.imageBaseDir + "sets" + File.separator;
public interface IO { public interface IO {
public static final String imageBaseDir = "plugins" + File.separator + "images" + File.separator; public static final String imageBaseDir = "plugins" + File.separator + "images" + File.separator;

View file

@ -0,0 +1,86 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.client.deckeditor.collection.viewer;
import mage.client.MagePane;
import mage.client.plugins.impl.Plugins;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.util.HashMap;
import java.util.Map;
/**
* Collection viewer pane.
* Contains background and components container.
*
* @author nantuko
*/
public class CollectionViewerPane extends MagePane {
public CollectionViewerPane() {
boolean initialized = false;
if (Plugins.getInstance().isThemePluginLoaded()) {
Map<String, JComponent> ui = new HashMap<String, JComponent>();
JComponent container = Plugins.getInstance().updateTablePanel(ui);
if (container != null) {
collectionViewerPanel = new CollectionViewerPanel();
initComponents(container);
container.add(collectionViewerPanel);
container.setOpaque(false);
collectionViewerPanel.setOpaque(false);
initialized = true;
}
}
if (!initialized) {
initComponents(null);
}
}
private void initComponents(Component container) {
Component component = container != null ? container : collectionViewerPanel;
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(component, javax.swing.GroupLayout.DEFAULT_SIZE, 885, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(component, javax.swing.GroupLayout.DEFAULT_SIZE, 626, Short.MAX_VALUE)
);
pack();
}
private CollectionViewerPanel collectionViewerPanel;
}

View file

@ -0,0 +1,103 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.client.deckeditor.collection.viewer;
import mage.client.cards.BigCard;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
/**
* Pane with big card and mage book.
*
* @author nantuko
*/
public class CollectionViewerPanel extends JPanel {
public CollectionViewerPanel() {
initComponents();
}
public void initComponents() {
jPanel1 = new javax.swing.JPanel();
jPanel1.setOpaque(false);
bigCard = new BigCard();
BoxLayout boxlayout = new BoxLayout(jPanel1, BoxLayout.X_AXIS);
jPanel1.setLayout(boxlayout);
bigCard.setAlignmentY(Component.BOTTOM_ALIGNMENT);
bigCard.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
jPanel1.add(bigCard);
jPanel2 = new MageBookContainer();
jPanel2.setOpaque(false);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, 0)
.addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, 604, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, 615, Short.MAX_VALUE)
);
}
private class MageBookContainer extends JPanel {
public MageBookContainer() {
super();
initComponents();
}
public void initComponents() {
jPanel = new JPanel();
jScrollPane1 = new JScrollPane(jPanel);
jScrollPane1.getViewport().setBackground(new Color(0,0,0,0));
jPanel.setLayout(new GridBagLayout()); // centers mage book
jPanel.setBackground(new Color(0,0,0,0));
jPanel.add(new MageBook(bigCard));
setLayout(new java.awt.BorderLayout());
add(jScrollPane1, java.awt.BorderLayout.CENTER);
}
private JPanel jPanel;
private javax.swing.JScrollPane jScrollPane1;
}
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private mage.client.cards.BigCard bigCard;
}

View file

@ -0,0 +1,305 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.client.deckeditor.collection.viewer;
import mage.cards.Card;
import mage.cards.CardDimensions;
import mage.cards.MageCard;
import mage.client.cards.BigCard;
import mage.client.cards.CardsStorage;
import mage.client.components.HoverButton;
import mage.client.components.ImageButton;
import mage.client.components.arcane.GlowText;
import mage.client.components.arcane.ManaSymbols;
import mage.client.plugins.impl.Plugins;
import mage.client.util.Command;
import mage.client.util.Config;
import mage.client.util.ImageHelper;
import mage.components.ImagePanel;
import mage.utils.ThreadUtils;
import mage.view.CardView;
import org.apache.log4j.Logger;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.UUID;
/**
* Mage book with cards and page flipping.
*
* @author nantuko
*/
public class MageBook extends JComponent {
public MageBook(BigCard bigCard) {
super();
this.bigCard = bigCard;
initComponents();
}
private void initComponents() {
setOpaque(false);
setSize(WIDTH, HEIGHT);
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setMinimumSize(new Dimension(WIDTH, HEIGHT));
//setBorder(BorderFactory.createLineBorder(Color.green));
jPanelLeft = getImagePanel(LEFT_PANEL_IMAGE_PATH, ImagePanel.TILED);
jPanelLeft.setPreferredSize(new Dimension(LEFT_RIGHT_PAGES_WIDTH, 0));
jPanelLeft.setLayout(null);
jPanelCenter = getImagePanel(CENTER_PANEL_IMAGE_PATH, ImagePanel.SCALED);
jPanelCenter.setLayout(new BorderLayout());
jPanelRight = getImagePanel(RIGHT_PANEL_IMAGE_PATH, ImagePanel.TILED);
jPanelRight.setPreferredSize(new Dimension(LEFT_RIGHT_PAGES_WIDTH, 0));
jPanelRight.setLayout(null);
jLayeredPane = new JLayeredPane();
jPanelCenter.add(jLayeredPane, BorderLayout.CENTER);
Image image = ImageHelper.loadImage(LEFT_PAGE_BUTTON_IMAGE_PATH);
pageLeft = new HoverButton(null, image, image, image, new Rectangle(64,64));
pageLeft.setBounds(0,0,64,64);
pageLeft.setVisible(false);
pageLeft.setObserver(new Command() {
public void execute() {
currentPage--;
if (currentPage == 0) {
pageLeft.setVisible(false);
}
pageRight.setVisible(true);
showCards();
}
});
image = ImageHelper.loadImage(RIGHT_PAGE_BUTTON_IMAGE_PATH);
pageRight = new HoverButton(null, image, image, image, new Rectangle(64,64));
pageRight.setBounds(WIDTH - 2*LEFT_RIGHT_PAGES_WIDTH - 64,0,64,64);
pageRight.setVisible(false);
pageRight.setObserver(new Command() {
public void execute() {
currentPage++;
pageLeft.setVisible(true);
pageRight.setVisible(false);
showCards();
}
});
addSetTabs();
setLayout(new BorderLayout());
add(jPanelLeft, BorderLayout.LINE_START);
add(jPanelCenter, BorderLayout.CENTER);
add(jPanelRight, BorderLayout.LINE_END);
cardDimensions = new CardDimensions(0.45d);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
showCards();
}
});
}
private void addLeftRightPageButtons() {
jLayeredPane.add(pageLeft, JLayeredPane.DEFAULT_LAYER, 0);
jLayeredPane.add(pageRight, JLayeredPane.DEFAULT_LAYER, 1);
}
private void addSetTabs() {
jPanelLeft.removeAll();
jPanelRight.removeAll();
Image image = ImageHelper.loadImage(LEFT_TAB_IMAGE_PATH);
Image imageRight = ImageHelper.loadImage(RIGHT_TAB_IMAGE_PATH);
int y = 0;
int dy = 0;
if (CardsStorage.getSetCodes().size() > 1) {
dy = (HEIGHT - 120) / (CardsStorage.getSetCodes().size() - 1) + 1;
}
int count = 0;
JPanel currentPanel = jPanelLeft;
for (String set : CardsStorage.getSetCodes()) {
HoverButton tab = new HoverButton(null, image, image, image, new Rectangle(39,120));
Image setImage = ManaSymbols.getSetSymbolImage(set);
if (setImage != null) {
tab.setOverlayImage(setImage);
} else {
System.out.println("Couldn't find: " + "/plugins/images/sets/" + set + ".jpg");
}
tab.setBounds(0, y, 39, 120);
final String _set = set;
tab.setObserver(new Command() {
public void execute() {
currentPage = 0;
currentSet = _set;
pageLeft.setVisible(false);
pageRight.setVisible(false);
addSetTabs();
showCards();
}
});
currentPanel.add(tab, JLayeredPane.DEFAULT_LAYER + count++, 0);
y += dy;
if (set.equals(currentSet)) {
currentPanel = jPanelRight;
image = imageRight;
}
}
jPanelLeft.revalidate();
jPanelLeft.repaint();
jPanelRight.revalidate();
jPanelRight.repaint();
}
private void showCards() {
jLayeredPane.removeAll();
addLeftRightPageButtons();
java.util.List<Card> cards = getCards(currentPage, currentSet);
int size = cards.size();
Rectangle rectangle = new Rectangle();
rectangle.translate(OFFSET_X, OFFSET_Y);
for (int i = 0; i < Math.min(CARDS_PER_PAGE / 2, size); i++) {
addCard(new CardView(cards.get(i)), bigCard, null, rectangle);
rectangle = CardPosition.translatePosition(i, rectangle);
}
// calculate the x offset of the second (right) page
int second_page_x = (WIDTH - 2*LEFT_RIGHT_PAGES_WIDTH) -
(cardDimensions.frameWidth+ CardPosition.GAP_X)*3 + CardPosition.GAP_X - OFFSET_X;
rectangle.setLocation(second_page_x, OFFSET_Y);
for (int i = CARDS_PER_PAGE / 2; i < Math.min(CARDS_PER_PAGE, size); i++) {
addCard(new CardView(cards.get(i)), bigCard, null, rectangle);
rectangle = CardPosition.translatePosition(i - CARDS_PER_PAGE / 2, rectangle);
}
}
private void addCard(CardView card, BigCard bigCard, UUID gameId, Rectangle rectangle) {
final MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, cardDimensions, gameId, false);
cardImg.setBounds(rectangle);
jLayeredPane.add(cardImg, JLayeredPane.DEFAULT_LAYER, 10);
cardImg.update(card);
cardImg.setCardBounds(rectangle.x, rectangle.y, cardDimensions.frameWidth, cardDimensions.frameHeight);
GlowText label = new GlowText();
label.setGlow(Color.green, 12, 0.0f);
label.setText("Implemented");
label.setBounds(rectangle.x + 15, rectangle.y + cardDimensions.frameHeight + 7, 100, 30);
jLayeredPane.add(label);
}
private java.util.List<Card> getCards(int page, String set) {
int start = page * CARDS_PER_PAGE;
int end = (page + 1) * CARDS_PER_PAGE;
java.util.List<Card> cards = CardsStorage.getAllCards(start, end, currentSet);
if (cards.size() > CARDS_PER_PAGE) {
pageRight.setVisible(true);
}
return cards;
}
private ImagePanel getImagePanel(String filename, int type) {
try {
InputStream is = this.getClass().getResourceAsStream(filename);
if (is == null) {
throw new FileNotFoundException("Couldn't find " + filename + " in resources.");
}
BufferedImage background = ImageIO.read(is);
if (background == null) {
throw new FileNotFoundException("Couldn't find " + filename + " in resources.");
}
return new ImagePanel(background, type);
} catch (Exception e) {
log.error(e.getMessage(), e);
return null;
}
}
/**
* Defines the position of the next card on the mage book
*/
private static class CardPosition {
private CardPosition() {
}
public static Rectangle translatePosition(int index, Rectangle r) {
Rectangle rect = new Rectangle(r);
rect.translate((cardDimensions.frameWidth+GAP_X) * dx[index],
(cardDimensions.frameHeight + GAP_Y) * dy[index]);
return rect;
}
private static final int[] dx = {1, 1, -2, 1, 1, -2, 1, 1, 2, 1, -2, 1, 1, -2, 1, 1};
private static final int[] dy = {0, 0, 1, 0, 0, 1, 0, 0, -2, 0, 1, 0, 0, 1, 0, 0};
public static final int GAP_X = 17;
public static final int GAP_Y = 45;
private static int cardWidth;
private static int cardHeight;
}
private JPanel jPanelLeft;
private ImagePanel jPanelCenter;
private JPanel jPanelRight;
private JLayeredPane jLayeredPane;
private BigCard bigCard;
private HoverButton pageLeft;
private HoverButton pageRight;
private int currentPage = 0;
private String currentSet = "M10";
private static CardDimensions cardDimensions = new CardDimensions(1.2d);
private static Font font = new Font("Arial", Font.PLAIN, 14);
private static final Logger log = Logger.getLogger(MageBook.class);
static private final String CENTER_PANEL_IMAGE_PATH = "/book_bg.jpg";
static private final String RIGHT_PANEL_IMAGE_PATH = "/book_right.jpg";
static private final String LEFT_PANEL_IMAGE_PATH = "/book_left.jpg";
static private final String LEFT_PAGE_BUTTON_IMAGE_PATH = "/book_pager_left.png";
static private final String RIGHT_PAGE_BUTTON_IMAGE_PATH = "/book_pager_right.png";
static private final String LEFT_TAB_IMAGE_PATH = "/tab_left.png";
static private final String RIGHT_TAB_IMAGE_PATH = "/tab_right.png";
static private final int CARDS_PER_PAGE = 18;
static private final int WIDTH = 950;
static private final int HEIGHT = 650;
static private final int OFFSET_X = 25;
static private final int OFFSET_Y = 20;
static private final int LEFT_RIGHT_PAGES_WIDTH = 40;
}

View file

@ -0,0 +1,21 @@
package mage.client.deckeditor.collection.viewer;
import mage.client.components.arcane.ManaSymbols;
import mage.client.plugins.impl.Plugins;
import javax.swing.*;
/**
* @author nantuko
*/
public class TestMageBook extends JFrame {
public static void main(String[] args) {
Plugins.getInstance().loadPlugins();
ManaSymbols.loadImages();
JFrame frame = new TestMageBook();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new MageBook(null));
frame.pack();
frame.setVisible(true);
}
}

View file

@ -100,7 +100,7 @@ public class ShowCardsDialog extends MageDialog implements MouseListener {
tmp.setAbility(card); // cross-reference, required for ability picker tmp.setAbility(card); // cross-reference, required for ability picker
card = tmp; card = tmp;
} }
MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, dimension, gameId); MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, dimension, gameId, true);
cardImg.setBounds(rectangle); cardImg.setBounds(rectangle);
cardArea.add(cardImg); cardArea.add(cardImg);
cardArea.moveToFront(cardImg); cardArea.moveToFront(cardImg);

View file

@ -156,7 +156,7 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
} }
private void addPermanent(PermanentView permanent, final int count) { private void addPermanent(PermanentView permanent, final int count) {
final MagePermanent perm = Plugins.getInstance().getMagePermanent(permanent, bigCard, Config.dimensions, gameId); final MagePermanent perm = Plugins.getInstance().getMagePermanent(permanent, bigCard, Config.dimensions, gameId, true);
if (!Plugins.getInstance().isCardPluginLoaded()) { if (!Plugins.getInstance().isCardPluginLoaded()) {
perm.setBounds(findEmptySpace(new Dimension(Config.dimensions.frameWidth, Config.dimensions.frameHeight))); perm.setBounds(findEmptySpace(new Dimension(Config.dimensions.frameWidth, Config.dimensions.frameHeight)));
} else { } else {

View file

@ -21,8 +21,8 @@ public interface MagePlugins {
void shutdown(); void shutdown();
void updateGamePanel(Map<String, JComponent> ui); void updateGamePanel(Map<String, JComponent> ui);
JComponent updateTablePanel(Map<String, JComponent> ui); JComponent updateTablePanel(Map<String, JComponent> ui);
MagePermanent getMagePermanent(PermanentView card, BigCard bigCard, CardDimensions dimension, UUID gameId); MagePermanent getMagePermanent(PermanentView card, BigCard bigCard, CardDimensions dimension, UUID gameId, boolean canBeFoil);
MageCard getMageCard(CardView card, BigCard bigCard, CardDimensions dimension, UUID gameId); MageCard getMageCard(CardView card, BigCard bigCard, CardDimensions dimension, UUID gameId, boolean canBeFoil);
boolean isThemePluginLoaded(); boolean isThemePluginLoaded();
boolean isCardPluginLoaded(); boolean isCardPluginLoaded();
boolean isCounterPluginLoaded(); boolean isCounterPluginLoaded();

View file

@ -142,6 +142,9 @@ public class MageActionCallback implements ActionCallback {
} }
try { try {
if (session == null) {
return;
}
final Component popupContainer = session.getUI().getComponent(MageComponents.POPUP_CONTAINER); final Component popupContainer = session.getUI().getComponent(MageComponents.POPUP_CONTAINER);
Component popup2 = session.getUI().getComponent(MageComponents.CARD_INFO_PANE); Component popup2 = session.getUI().getComponent(MageComponents.CARD_INFO_PANE);
((CardInfoPane) popup2).setCard(data.card); ((CardInfoPane) popup2).setCard(data.card);
@ -211,6 +214,9 @@ public class MageActionCallback implements ActionCallback {
jPopupMenu.setVisible(false); jPopupMenu.setVisible(false);
} }
try { try {
if (session == null) {
return;
}
Component popupContainer = session.getUI().getComponent(MageComponents.POPUP_CONTAINER); Component popupContainer = session.getUI().getComponent(MageComponents.POPUP_CONTAINER);
popupContainer.setVisible(false); popupContainer.setVisible(false);
} catch (Exception e2) { } catch (Exception e2) {

View file

@ -80,22 +80,22 @@ public class Plugins implements MagePlugins {
} }
@Override @Override
public MagePermanent getMagePermanent(PermanentView card, BigCard bigCard, CardDimensions dimension, UUID gameId) { public MagePermanent getMagePermanent(PermanentView card, BigCard bigCard, CardDimensions dimension, UUID gameId, boolean canBeFoil) {
if (cardPlugin != null) { if (cardPlugin != null) {
mageActionCallback.refreshSession(); mageActionCallback.refreshSession();
mageActionCallback.setCardPreviewComponent(bigCard); mageActionCallback.setCardPreviewComponent(bigCard);
return cardPlugin.getMagePermanent(card, dimension, gameId, mageActionCallback); return cardPlugin.getMagePermanent(card, dimension, gameId, mageActionCallback, canBeFoil);
} else { } else {
return new Permanent(card, bigCard, Config.dimensions, gameId); return new Permanent(card, bigCard, Config.dimensions, gameId);
} }
} }
@Override @Override
public MageCard getMageCard(CardView card, BigCard bigCard, CardDimensions dimension, UUID gameId) { public MageCard getMageCard(CardView card, BigCard bigCard, CardDimensions dimension, UUID gameId, boolean canBeFoil) {
if (cardPlugin != null) { if (cardPlugin != null) {
mageActionCallback.refreshSession(); mageActionCallback.refreshSession();
mageActionCallback.setCardPreviewComponent(bigCard); mageActionCallback.setCardPreviewComponent(bigCard);
return cardPlugin.getMageCard(card, dimension, gameId, mageActionCallback); return cardPlugin.getMageCard(card, dimension, gameId, mageActionCallback, canBeFoil);
} else { } else {
return new Card(card, bigCard, Config.dimensions, gameId); return new Card(card, bigCard, Config.dimensions, gameId);
} }

View file

@ -0,0 +1,8 @@
package mage.client.util;
/**
* @author nantuko
*/
public interface Command {
public void execute();
}

Binary file not shown.

After

(image error) Size: 2 MiB

Binary file not shown.

After

(image error) Size: 23 KiB

Binary file not shown.

After

(image error) Size: 5.9 KiB

Binary file not shown.

After

(image error) Size: 5.1 KiB

Binary file not shown.

After

(image error) Size: 23 KiB

Binary file not shown.

After

(image error) Size: 14 KiB

Binary file not shown.

After

(image error) Size: 15 KiB

View file

@ -25,8 +25,8 @@ import net.xeoh.plugins.base.Plugin;
* @author nantuko * @author nantuko
*/ */
public interface CardPlugin extends Plugin { public interface CardPlugin extends Plugin {
MagePermanent getMagePermanent(PermanentView permanent, CardDimensions dimension, UUID gameId, ActionCallback callback); MagePermanent getMagePermanent(PermanentView permanent, CardDimensions dimension, UUID gameId, ActionCallback callback, boolean canBeFoil);
MagePermanent getMageCard(CardView permanent, CardDimensions dimension, UUID gameId, ActionCallback callback); MagePermanent getMageCard(CardView permanent, CardDimensions dimension, UUID gameId, ActionCallback callback, boolean canBeFoil);
void sortPermanents(Map<String, JComponent> ui, Collection<MagePermanent> cards); void sortPermanents(Map<String, JComponent> ui, Collection<MagePermanent> cards);
void downloadImages(Set<Card> allCards); void downloadImages(Set<Card> allCards);
void downloadSymbols(); void downloadSymbols();

View file

@ -1,23 +1,9 @@
package org.mage.plugins.card; package org.mage.plugins.card;
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.*;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLayeredPane;
import javax.swing.JScrollPane;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardDimensions; import mage.cards.CardDimensions;
import mage.cards.MagePermanent; import mage.cards.MagePermanent;
import mage.cards.action.ActionCallback; import mage.cards.action.ActionCallback;
import mage.components.CardInfoPane;
import mage.interfaces.plugin.CardPlugin; import mage.interfaces.plugin.CardPlugin;
import mage.utils.CardUtil; import mage.utils.CardUtil;
import mage.view.CardView; import mage.view.CardView;
@ -26,7 +12,6 @@ import net.xeoh.plugins.base.annotations.PluginImplementation;
import net.xeoh.plugins.base.annotations.events.Init; import net.xeoh.plugins.base.annotations.events.Init;
import net.xeoh.plugins.base.annotations.events.PluginLoaded; import net.xeoh.plugins.base.annotations.events.PluginLoaded;
import net.xeoh.plugins.base.annotations.meta.Author; import net.xeoh.plugins.base.annotations.meta.Author;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.mage.card.arcane.Animation; import org.mage.card.arcane.Animation;
import org.mage.card.arcane.CardPanel; import org.mage.card.arcane.CardPanel;
@ -40,436 +25,440 @@ import org.mage.plugins.card.dl.sources.GathererSymbols;
import org.mage.plugins.card.images.DownloadPictures; import org.mage.plugins.card.images.DownloadPictures;
import org.mage.plugins.card.info.CardInfoPaneImpl; import org.mage.plugins.card.info.CardInfoPaneImpl;
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.*;
import java.util.List;
/** /**
* {@link CardPlugin} implementation. * {@link CardPlugin} implementation.
* *
* @version 0.4 05.01.2011 Added support for foil cards.
* @version 0.3 07.11.2010 Mage cards.
* @version 0.2 07.11.2010 Downloading images.
* @version 0.1 01.11.2010 Mage permanents. Sorting card layout.
* @author nantuko * @author nantuko
* @version 0.1 01.11.2010 Mage permanents. Sorting card layout.
*/ */
@PluginImplementation @PluginImplementation
@Author(name = "nantuko") @Author(name = "nantuko")
public class CardPluginImpl implements CardPlugin { public class CardPluginImpl implements CardPlugin {
private final static Logger log = Logger.getLogger(CardPluginImpl.class); private final static Logger log = Logger.getLogger(CardPluginImpl.class);
static private final int GUTTER_Y = 15; static private final int GUTTER_Y = 15;
static private final int GUTTER_X = 5; static private final int GUTTER_X = 5;
static final float EXTRA_CARD_SPACING_X = 0.04f; static final float EXTRA_CARD_SPACING_X = 0.04f;
static private final float CARD_SPACING_Y = 0.03f; static private final float CARD_SPACING_Y = 0.03f;
static private final float STACK_SPACING_X = 0.07f; static private final float STACK_SPACING_X = 0.07f;
static private final float STACK_SPACING_Y = 0.13f; static private final float STACK_SPACING_Y = 0.13f;
static private final int MW_GUIDE_HEIGHT = 30; static private final int MW_GUIDE_HEIGHT = 30;
private int landStackMax = 5; private int landStackMax = 5;
private int cardWidthMin = 50, cardWidthMax = Constants.CARD_SIZE_FULL.width; private int cardWidthMin = 50, cardWidthMax = Constants.CARD_SIZE_FULL.width;
private boolean stackVertical = false; private boolean stackVertical = false;
private int playAreaWidth, playAreaHeight; private int playAreaWidth, playAreaHeight;
private int cardWidth, cardHeight; private int cardWidth, cardHeight;
private int extraCardSpacingX, cardSpacingX, cardSpacingY; private int extraCardSpacingX, cardSpacingX, cardSpacingY;
private int stackSpacingX, stackSpacingY; private int stackSpacingX, stackSpacingY;
private List<Row> rows = new ArrayList<Row>(); private List<Row> rows = new ArrayList<Row>();
@Init @Init
public void init() { public void init() {
} }
@PluginLoaded @PluginLoaded
public void newPlugin(CardPlugin plugin) { public void newPlugin(CardPlugin plugin) {
ManaSymbols.loadImages(); ManaSymbols.loadImages();
log.info(plugin.toString() + " has been loaded."); log.info(plugin.toString() + " has been loaded.");
} }
public String toString() { public String toString() {
return "[Card plugin, version 0.4]"; return "[Card plugin, version 0.4]";
} }
@Override @Override
public MagePermanent getMagePermanent(PermanentView permanent, CardDimensions dimension, UUID gameId, ActionCallback callback) { public MagePermanent getMagePermanent(PermanentView permanent, CardDimensions dimension, UUID gameId, ActionCallback callback, boolean canBeFoil) {
boolean foil = (new Random()).nextInt(5) == 0; boolean foil = canBeFoil && (new Random()).nextInt(5) == 0;
CardPanel cardPanel = new CardPanel(permanent, gameId, true, callback, foil);
cardPanel.setShowCastingCost(true);
cardPanel.setCardBounds(0, 0, dimension.frameWidth, dimension.frameHeight);
cardPanel.setShowCastingCost(true);
return cardPanel;
}
@Override
public MagePermanent getMageCard(CardView permanent, CardDimensions dimension, UUID gameId, ActionCallback callback) {
boolean foil = (new Random()).nextInt(5) == 0;
CardPanel cardPanel = new CardPanel(permanent, gameId, true, callback, foil); CardPanel cardPanel = new CardPanel(permanent, gameId, true, callback, foil);
cardPanel.setShowCastingCost(true); cardPanel.setShowCastingCost(true);
cardPanel.setCardBounds(0, 0, dimension.frameWidth, dimension.frameHeight); cardPanel.setCardBounds(0, 0, dimension.frameWidth, dimension.frameHeight);
cardPanel.setShowCastingCost(true); cardPanel.setShowCastingCost(true);
return cardPanel;
}
return cardPanel; @Override
} public MagePermanent getMageCard(CardView permanent, CardDimensions dimension, UUID gameId, ActionCallback callback, boolean canBeFoil) {
boolean foil = canBeFoil && (new Random()).nextInt(5) == 0;
CardPanel cardPanel = new CardPanel(permanent, gameId, true, callback, foil);
cardPanel.setShowCastingCost(true);
cardPanel.setCardBounds(0, 0, dimension.frameWidth, dimension.frameHeight);
cardPanel.setShowCastingCost(true);
@Override return cardPanel;
public void sortPermanents(Map<String, JComponent> ui, Collection<MagePermanent> permanents) { }
if (ui == null)
throw new RuntimeException("Error: no components");
JComponent component = ui.get("jScrollPane");
JComponent component2 = ui.get("battlefieldPanel");
if (component == null)
throw new RuntimeException("Error: jScrollPane is missing");
if (component2 == null)
throw new RuntimeException("Error: battlefieldPanel is missing");
if (!(component instanceof JScrollPane))
throw new RuntimeException("Error: jScrollPane has wrong type.");
if (!(component instanceof JScrollPane))
throw new RuntimeException("Error: battlefieldPanel is missing");
JScrollPane jScrollPane = (JScrollPane)component;
JLayeredPane battlefieldPanel = (JLayeredPane)component2;
Row allLands = new Row();
outerLoop: // @Override
for (MagePermanent permanent : permanents) { public void sortPermanents(Map<String, JComponent> ui, Collection<MagePermanent> permanents) {
if (!CardUtil.isLand(permanent) || CardUtil.isCreature(permanent)) if (ui == null)
continue; throw new RuntimeException("Error: no components");
JComponent component = ui.get("jScrollPane");
JComponent component2 = ui.get("battlefieldPanel");
if (component == null)
throw new RuntimeException("Error: jScrollPane is missing");
if (component2 == null)
throw new RuntimeException("Error: battlefieldPanel is missing");
if (!(component instanceof JScrollPane))
throw new RuntimeException("Error: jScrollPane has wrong type.");
if (!(component instanceof JScrollPane))
throw new RuntimeException("Error: battlefieldPanel is missing");
int insertIndex = -1; JScrollPane jScrollPane = (JScrollPane) component;
JLayeredPane battlefieldPanel = (JLayeredPane) component2;
// Find lands with the same name. Row allLands = new Row();
for (int i = 0, n = allLands.size(); i < n; i++) {
Stack stack = allLands.get(i);
MagePermanent firstPanel = stack.get(0);
if (firstPanel.getOriginal().getName().equals(permanent.getOriginal().getName())) {
if (!empty(firstPanel.getLinks())) {
// Put this land to the left of lands with the same name and attachments.
insertIndex = i;
break;
}
if (!empty(permanent.getLinks()) || stack.size() == landStackMax) {
// If this land has attachments or the stack is full, put it to the right.
insertIndex = i + 1;
continue;
}
// Add to stack.
stack.add(0, permanent);
continue outerLoop;
}
if (insertIndex != -1)
break;
}
Stack stack = new Stack(); outerLoop:
stack.add(permanent); //
allLands.add(insertIndex == -1 ? allLands.size() : insertIndex, stack); for (MagePermanent permanent : permanents) {
} if (!CardUtil.isLand(permanent) || CardUtil.isCreature(permanent))
continue;
Row allCreatures = new Row(permanents, RowType.creature); int insertIndex = -1;
Row allOthers = new Row(permanents, RowType.other);
cardWidth = cardWidthMax; // Find lands with the same name.
Rectangle rect = jScrollPane.getVisibleRect(); for (int i = 0, n = allLands.size(); i < n; i++) {
playAreaWidth = rect.width; Stack stack = allLands.get(i);
playAreaHeight = rect.height - MW_GUIDE_HEIGHT; MagePermanent firstPanel = stack.get(0);
while (true) { if (firstPanel.getOriginal().getName().equals(permanent.getOriginal().getName())) {
rows.clear(); if (!empty(firstPanel.getLinks())) {
cardHeight = Math.round(cardWidth * CardPanel.ASPECT_RATIO); // Put this land to the left of lands with the same name and attachments.
extraCardSpacingX = (int) Math.round(cardWidth * EXTRA_CARD_SPACING_X); insertIndex = i;
cardSpacingX = cardHeight - cardWidth + extraCardSpacingX; break;
cardSpacingY = (int) Math.round(cardHeight * CARD_SPACING_Y); }
stackSpacingX = stackVertical ? 0 : (int) Math.round(cardWidth * STACK_SPACING_X); if (!empty(permanent.getLinks()) || stack.size() == landStackMax) {
stackSpacingY = (int) Math.round(cardHeight * STACK_SPACING_Y); // If this land has attachments or the stack is full, put it to the right.
Row creatures = (Row) allCreatures.clone(); insertIndex = i + 1;
Row lands = (Row) allLands.clone(); continue;
Row others = (Row) allOthers.clone(); }
// Wrap all creatures and lands. // Add to stack.
wrap(creatures, rows, -1); stack.add(0, permanent);
int afterCreaturesIndex = rows.size(); continue outerLoop;
wrap(lands, rows, afterCreaturesIndex); }
// Store the current rows and others. if (insertIndex != -1)
List<Row> storedRows = new ArrayList<Row>(rows.size()); break;
for (Row row : rows) }
storedRows.add((Row) row.clone());
Row storedOthers = (Row) others.clone();
// Fill in all rows with others.
for (Row row : rows)
fillRow(others, rows, row);
// Stop if everything fits, otherwise revert back to the stored values. Stack stack = new Stack();
if (creatures.isEmpty() && lands.isEmpty() && others.isEmpty()) stack.add(permanent);
break; allLands.add(insertIndex == -1 ? allLands.size() : insertIndex, stack);
rows = storedRows; }
others = storedOthers;
// Try to put others on their own row(s) and fill in the rest.
wrap(others, rows, afterCreaturesIndex);
for (Row row : rows)
fillRow(others, rows, row);
// If that still doesn't fit, scale down.
if (creatures.isEmpty() && lands.isEmpty() && others.isEmpty())
break;
//cardWidth = (int)(cardWidth / 1.2);
cardWidth--;
}
// Get size of all the rows. Row allCreatures = new Row(permanents, RowType.creature);
int x, y = GUTTER_Y; Row allOthers = new Row(permanents, RowType.other);
int maxRowWidth = 0;
for (Row row : rows) {
int rowBottom = 0;
x = GUTTER_X;
for (int stackIndex = 0, stackCount = row.size(); stackIndex < stackCount; stackIndex++) {
Stack stack = row.get(stackIndex);
rowBottom = Math.max(rowBottom, y + stack.getHeight());
x += stack.getWidth();
}
y = rowBottom;
maxRowWidth = Math.max(maxRowWidth, x);
}
//setPreferredSize(new Dimension(maxRowWidth - cardSpacingX, y - cardSpacingY));
//revalidate();
// Position all card panels. cardWidth = cardWidthMax;
x = 0; Rectangle rect = jScrollPane.getVisibleRect();
y = GUTTER_Y; playAreaWidth = rect.width;
for (Row row : rows) { playAreaHeight = rect.height - MW_GUIDE_HEIGHT;
int rowBottom = 0; while (true) {
x = GUTTER_X; rows.clear();
for (int stackIndex = 0, stackCount = row.size(); stackIndex < stackCount; stackIndex++) { cardHeight = Math.round(cardWidth * CardPanel.ASPECT_RATIO);
Stack stack = row.get(stackIndex); extraCardSpacingX = (int) Math.round(cardWidth * EXTRA_CARD_SPACING_X);
// Align others to the right. cardSpacingX = cardHeight - cardWidth + extraCardSpacingX;
if (RowType.other.isType(stack.get(0))) { cardSpacingY = (int) Math.round(cardHeight * CARD_SPACING_Y);
x = playAreaWidth - GUTTER_X + extraCardSpacingX; stackSpacingX = stackVertical ? 0 : (int) Math.round(cardWidth * STACK_SPACING_X);
for (int i = stackIndex, n = row.size(); i < n; i++) stackSpacingY = (int) Math.round(cardHeight * STACK_SPACING_Y);
x -= row.get(i).getWidth(); Row creatures = (Row) allCreatures.clone();
} Row lands = (Row) allLands.clone();
for (int panelIndex = 0, panelCount = stack.size(); panelIndex < panelCount; panelIndex++) { Row others = (Row) allOthers.clone();
MagePermanent panel = stack.get(panelIndex); // Wrap all creatures and lands.
int stackPosition = panelCount - panelIndex - 1; wrap(creatures, rows, -1);
///setComponentZOrder((Component)panel, panelIndex); int afterCreaturesIndex = rows.size();
int panelX = x + (stackPosition * stackSpacingX); wrap(lands, rows, afterCreaturesIndex);
int panelY = y + (stackPosition * stackSpacingY); // Store the current rows and others.
//panel.setLocation(panelX, panelY); List<Row> storedRows = new ArrayList<Row>(rows.size());
battlefieldPanel.moveToBack(panel); for (Row row : rows)
panel.setCardBounds(panelX, panelY, cardWidth, cardHeight); storedRows.add((Row) row.clone());
} Row storedOthers = (Row) others.clone();
rowBottom = Math.max(rowBottom, y + stack.getHeight()); // Fill in all rows with others.
x += stack.getWidth(); for (Row row : rows)
} fillRow(others, rows, row);
y = rowBottom;
}
}
private boolean empty(List<?> list) {
return list == null || list.size() == 0;
}
private int wrap(Row sourceRow, List<Row> rows, int insertIndex) {
// The cards are sure to fit (with vertical scrolling) at the minimum card width.
boolean allowHeightOverflow = cardWidth == cardWidthMin;
Row currentRow = new Row(); // Stop if everything fits, otherwise revert back to the stored values.
for (int i = 0, n = sourceRow.size() - 1; i <= n; i++) { if (creatures.isEmpty() && lands.isEmpty() && others.isEmpty())
Stack stack = sourceRow.get(i); break;
// If the row is not empty and this stack doesn't fit, add the row. rows = storedRows;
int rowWidth = currentRow.getWidth(); others = storedOthers;
if (!currentRow.isEmpty() && rowWidth + stack.getWidth() > playAreaWidth) { // Try to put others on their own row(s) and fill in the rest.
// Stop processing if the row is too wide or tall. wrap(others, rows, afterCreaturesIndex);
if (!allowHeightOverflow && rowWidth > playAreaWidth) for (Row row : rows)
break; fillRow(others, rows, row);
if (!allowHeightOverflow && getRowsHeight(rows) + sourceRow.getHeight() > playAreaHeight) // If that still doesn't fit, scale down.
break; if (creatures.isEmpty() && lands.isEmpty() && others.isEmpty())
rows.add(insertIndex == -1 ? rows.size() : insertIndex, currentRow); break;
currentRow = new Row(); //cardWidth = (int)(cardWidth / 1.2);
} cardWidth--;
currentRow.add(stack); }
}
// Add the last row if it is not empty and it fits.
if (!currentRow.isEmpty()) {
int rowWidth = currentRow.getWidth();
if (allowHeightOverflow || rowWidth <= playAreaWidth) {
if (allowHeightOverflow || getRowsHeight(rows) + sourceRow.getHeight() <= playAreaHeight) {
rows.add(insertIndex == -1 ? rows.size() : insertIndex, currentRow);
}
}
}
// Remove the wrapped stacks from the source row.
for (Row row : rows)
for (Stack stack : row)
sourceRow.remove(stack);
return insertIndex;
}
private void fillRow(Row sourceRow, List<Row> rows, Row row) { // Get size of all the rows.
int rowWidth = row.getWidth(); int x, y = GUTTER_Y;
while (!sourceRow.isEmpty()) { int maxRowWidth = 0;
Stack stack = sourceRow.get(0); for (Row row : rows) {
rowWidth += stack.getWidth(); int rowBottom = 0;
if (rowWidth > playAreaWidth) x = GUTTER_X;
break; for (int stackIndex = 0, stackCount = row.size(); stackIndex < stackCount; stackIndex++) {
if (stack.getHeight() > row.getHeight()) { Stack stack = row.get(stackIndex);
if (getRowsHeight(rows) - row.getHeight() + stack.getHeight() > playAreaHeight) rowBottom = Math.max(rowBottom, y + stack.getHeight());
break; x += stack.getWidth();
} }
row.add(sourceRow.remove(0)); y = rowBottom;
} maxRowWidth = Math.max(maxRowWidth, x);
} }
//setPreferredSize(new Dimension(maxRowWidth - cardSpacingX, y - cardSpacingY));
//revalidate();
private int getRowsHeight(List<Row> rows) { // Position all card panels.
int height = 0; x = 0;
for (Row row : rows) y = GUTTER_Y;
height += row.getHeight(); for (Row row : rows) {
return height - cardSpacingY + GUTTER_Y * 2; int rowBottom = 0;
} x = GUTTER_X;
for (int stackIndex = 0, stackCount = row.size(); stackIndex < stackCount; stackIndex++) {
Stack stack = row.get(stackIndex);
// Align others to the right.
if (RowType.other.isType(stack.get(0))) {
x = playAreaWidth - GUTTER_X + extraCardSpacingX;
for (int i = stackIndex, n = row.size(); i < n; i++)
x -= row.get(i).getWidth();
}
for (int panelIndex = 0, panelCount = stack.size(); panelIndex < panelCount; panelIndex++) {
MagePermanent panel = stack.get(panelIndex);
int stackPosition = panelCount - panelIndex - 1;
///setComponentZOrder((Component)panel, panelIndex);
int panelX = x + (stackPosition * stackSpacingX);
int panelY = y + (stackPosition * stackSpacingY);
//panel.setLocation(panelX, panelY);
battlefieldPanel.moveToBack(panel);
panel.setCardBounds(panelX, panelY, cardWidth, cardHeight);
}
rowBottom = Math.max(rowBottom, y + stack.getHeight());
x += stack.getWidth();
}
y = rowBottom;
}
}
static private enum RowType { private boolean empty(List<?> list) {
land, creature, other; return list == null || list.size() == 0;
}
public boolean isType(MagePermanent card) { private int wrap(Row sourceRow, List<Row> rows, int insertIndex) {
switch (this) { // The cards are sure to fit (with vertical scrolling) at the minimum card width.
case land: boolean allowHeightOverflow = cardWidth == cardWidthMin;
return CardUtil.isLand(card);
case creature:
return CardUtil.isCreature(card);
case other:
return !CardUtil.isLand(card) && !CardUtil.isCreature(card);
default:
throw new RuntimeException("Unhandled type: " + this);
}
}
}
private class Row extends ArrayList<Stack> { Row currentRow = new Row();
public Row() { for (int i = 0, n = sourceRow.size() - 1; i <= n; i++) {
super(16); Stack stack = sourceRow.get(i);
} // If the row is not empty and this stack doesn't fit, add the row.
int rowWidth = currentRow.getWidth();
if (!currentRow.isEmpty() && rowWidth + stack.getWidth() > playAreaWidth) {
// Stop processing if the row is too wide or tall.
if (!allowHeightOverflow && rowWidth > playAreaWidth)
break;
if (!allowHeightOverflow && getRowsHeight(rows) + sourceRow.getHeight() > playAreaHeight)
break;
rows.add(insertIndex == -1 ? rows.size() : insertIndex, currentRow);
currentRow = new Row();
}
currentRow.add(stack);
}
// Add the last row if it is not empty and it fits.
if (!currentRow.isEmpty()) {
int rowWidth = currentRow.getWidth();
if (allowHeightOverflow || rowWidth <= playAreaWidth) {
if (allowHeightOverflow || getRowsHeight(rows) + sourceRow.getHeight() <= playAreaHeight) {
rows.add(insertIndex == -1 ? rows.size() : insertIndex, currentRow);
}
}
}
// Remove the wrapped stacks from the source row.
for (Row row : rows)
for (Stack stack : row)
sourceRow.remove(stack);
return insertIndex;
}
public Row(Collection<MagePermanent> permanents, RowType type) { private void fillRow(Row sourceRow, List<Row> rows, Row row) {
this(); int rowWidth = row.getWidth();
addAll(permanents, type); while (!sourceRow.isEmpty()) {
} Stack stack = sourceRow.get(0);
rowWidth += stack.getWidth();
if (rowWidth > playAreaWidth)
break;
if (stack.getHeight() > row.getHeight()) {
if (getRowsHeight(rows) - row.getHeight() + stack.getHeight() > playAreaHeight)
break;
}
row.add(sourceRow.remove(0));
}
}
private void addAll(Collection<MagePermanent> permanents, RowType type) { private int getRowsHeight(List<Row> rows) {
for (MagePermanent panel : permanents) { int height = 0;
if (!type.isType(panel)) for (Row row : rows)
continue; height += row.getHeight();
Stack stack = new Stack(); return height - cardSpacingY + GUTTER_Y * 2;
stack.add(panel); }
add(stack);
}
}
public boolean addAll(Collection<? extends Stack> c) { static private enum RowType {
boolean changed = super.addAll(c); land, creature, other;
c.clear();
return changed;
}
private int getWidth() { public boolean isType(MagePermanent card) {
if (isEmpty()) switch (this) {
return 0; case land:
int width = 0; return CardUtil.isLand(card);
for (Stack stack : this) case creature:
width += stack.getWidth(); return CardUtil.isCreature(card);
return width + GUTTER_X * 2 - extraCardSpacingX; case other:
} return !CardUtil.isLand(card) && !CardUtil.isCreature(card);
default:
throw new RuntimeException("Unhandled type: " + this);
}
}
}
private int getHeight() { private class Row extends ArrayList<Stack> {
if (isEmpty()) public Row() {
return 0; super(16);
int height = 0; }
for (Stack stack : this)
height = Math.max(height, stack.getHeight());
return height;
}
}
private class Stack extends ArrayList<MagePermanent> { public Row(Collection<MagePermanent> permanents, RowType type) {
public Stack() { this();
super(8); addAll(permanents, type);
} }
public boolean add(MagePermanent panel) { private void addAll(Collection<MagePermanent> permanents, RowType type) {
boolean appended = super.add(panel); for (MagePermanent panel : permanents) {
//for (CardPanel attachedPanel : panel.attachedPanels) if (!type.isType(panel))
//add(attachedPanel); continue;
return appended; Stack stack = new Stack();
} stack.add(panel);
add(stack);
}
}
private int getWidth() { public boolean addAll(Collection<? extends Stack> c) {
return cardWidth + (size() - 1) * stackSpacingX + cardSpacingX; boolean changed = super.addAll(c);
} c.clear();
return changed;
}
private int getHeight() { private int getWidth() {
return cardHeight + (size() - 1) * stackSpacingY + cardSpacingY; if (isEmpty())
} return 0;
} int width = 0;
for (Stack stack : this)
width += stack.getWidth();
return width + GUTTER_X * 2 - extraCardSpacingX;
}
@Override private int getHeight() {
public void downloadImages(Set<Card> allCards) { if (isEmpty())
DownloadPictures.startDownload(null, allCards); return 0;
} int height = 0;
for (Stack stack : this)
@Override height = Math.max(height, stack.getHeight());
public void downloadSymbols() { return height;
final DownloadGui g = new DownloadGui(new Downloader()); }
}
Iterable<DownloadJob> it = new GathererSymbols(); private class Stack extends ArrayList<MagePermanent> {
public Stack() {
for(DownloadJob job:it) { super(8);
}
public boolean add(MagePermanent panel) {
boolean appended = super.add(panel);
//for (CardPanel attachedPanel : panel.attachedPanels)
//add(attachedPanel);
return appended;
}
private int getWidth() {
return cardWidth + (size() - 1) * stackSpacingX + cardSpacingX;
}
private int getHeight() {
return cardHeight + (size() - 1) * stackSpacingY + cardSpacingY;
}
}
@Override
public void downloadImages(Set<Card> allCards) {
DownloadPictures.startDownload(null, allCards);
}
@Override
public void downloadSymbols() {
final DownloadGui g = new DownloadGui(new Downloader());
Iterable<DownloadJob> it = new GathererSymbols();
for (DownloadJob job : it) {
g.getDownloader().add(job); g.getDownloader().add(job);
} }
it = new GathererSets(); it = new GathererSets();
for(DownloadJob job:it) { for(DownloadJob job:it) {
g.getDownloader().add(job); g.getDownloader().add(job);
}
JDialog d = new JDialog((Frame) null, "Download pictures", false);
d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
d.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
g.getDownloader().dispose();
}
});
d.setLayout(new BorderLayout());
d.add(g);
d.pack();
d.setVisible(true);
}
@Override
public Image getManaSymbolImage(String symbol) {
return ManaSymbols.getManaSymbolImage(symbol);
}
@Override
public void onAddCard(MagePermanent card, int count) {
if (card != null) {
Animation.showCard((CardPanel) card, count > 0 ? count : 1);
try {
while ((card).getAlpha() + 0.05f < 1) {
Thread.sleep(30);
}
} catch (Exception e) {
e.printStackTrace();
}
} }
}
@Override
JDialog d = new JDialog((Frame) null, "Download pictures", false); public void onRemoveCard(MagePermanent card, int count) {
d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); if (card != null) {
d.addWindowListener(new WindowAdapter() { Animation.hideCard((CardPanel) card, count > 0 ? count : 1);
@Override try {
public void windowClosing(WindowEvent e) { while ((card).getAlpha() - 0.05f > 0) {
g.getDownloader().dispose(); Thread.sleep(30);
} }
}); } catch (Exception e) {
d.setLayout(new BorderLayout()); e.printStackTrace();
d.add(g); }
d.pack(); }
d.setVisible(true); }
}
@Override
public Image getManaSymbolImage(String symbol) {
return ManaSymbols.getManaSymbolImage(symbol);
}
@Override
public void onAddCard(MagePermanent card, int count) {
if (card != null) {
Animation.showCard((CardPanel) card, count > 0 ? count : 1);
try {
while ((card).getAlpha() + 0.05f < 1) {
Thread.sleep(30);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void onRemoveCard(MagePermanent card, int count) {
if (card != null) {
Animation.hideCard((CardPanel) card, count > 0 ? count : 1);
try {
while ((card).getAlpha() - 0.05f > 0) {
Thread.sleep(30);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override @Override
public JComponent getCardInfoPane() { public JComponent getCardInfoPane() {

View file

@ -12,7 +12,7 @@ import static org.mage.plugins.card.dl.DownloadJob.toFile;
public class GathererSets implements Iterable<DownloadJob> { public class GathererSets implements Iterable<DownloadJob> {
private static final File outDir = new File("plugins/images/sets"); private static final File outDir = new File("plugins/images/sets");
private static final String[] symbols = { "M10", "M11", "ARB", "DIS", "GPT", "RAV", "ALA", private static final String[] symbols = { "M10", "M11", "ARB", "DIS", "GPT", "RAV", "ALA",
"ZEN", "WWK", "ROE", "SOM", "10E", "CFX" }; "ZEN", "WWK", "ROE", "SOM", "10E", "CFX", "HOP" };
@Override @Override
public Iterator<DownloadJob> iterator() { public Iterator<DownloadJob> iterator() {