mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 18:28:00 +00:00
add new GUI interface allowing cards to be moved around in a list and use for arrangeForScry if preference UI_SELECT_FROM_CARD_DISPLAYS is set
This commit is contained in:
@@ -86,7 +86,7 @@ public class Localizer {
|
|||||||
resourceBundle = ResourceBundle.getBundle(languageRegionID, new Locale(splitLocale[0], splitLocale[1]), loader);
|
resourceBundle = ResourceBundle.getBundle(languageRegionID, new Locale(splitLocale[0], splitLocale[1]), loader);
|
||||||
} catch (NullPointerException | MissingResourceException e) {
|
} catch (NullPointerException | MissingResourceException e) {
|
||||||
//If the language can't be loaded, default to US English
|
//If the language can't be loaded, default to US English
|
||||||
resourceBundle = ResourceBundle.getBundle("en-GB", new Locale("en", "GB"), loader);
|
resourceBundle = ResourceBundle.getBundle("en-US", new Locale("en", "US"), loader);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import forge.item.PaperCard;
|
|||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
import forge.screens.match.CMatchUI;
|
import forge.screens.match.CMatchUI;
|
||||||
import forge.toolbox.FOptionPane;
|
import forge.toolbox.FOptionPane;
|
||||||
|
import forge.view.arcane.ListCardArea;
|
||||||
|
|
||||||
public class GuiChoose {
|
public class GuiChoose {
|
||||||
|
|
||||||
@@ -285,5 +285,31 @@ public class GuiChoose {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<Card> manipulateCardList(final CMatchUI gui, final String title, final List<Card> cards, final List<Card> manipulable,
|
||||||
|
final boolean toTop, final boolean toBottom, final boolean toAnywhere) {
|
||||||
|
final Callable<List<Card>> callable = new Callable<List<Card>>() {
|
||||||
|
@Override
|
||||||
|
public List<Card> call() throws Exception {
|
||||||
|
ListCardArea tempArea = new ListCardArea(gui,title,cards,manipulable,toTop,toBottom,toAnywhere);
|
||||||
|
// tempArea.pack();
|
||||||
|
// window? tempArea.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||||
|
tempArea.show();
|
||||||
|
// tempArea.dispose();
|
||||||
|
//try { Thread.sleep(1000); } catch(InterruptedException ex) { }
|
||||||
|
final List<Card> cardList = tempArea.getCardList();
|
||||||
|
return cardList;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
final FutureTask<List<Card>> ft = new FutureTask<List<Card>>(callable);
|
||||||
|
FThreads.invokeInEdtAndWait(ft);
|
||||||
|
try {
|
||||||
|
List<Card> result = ft.get();
|
||||||
|
return result;
|
||||||
|
} catch (final Exception e) { // we have waited enough
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ import forge.deck.Deck;
|
|||||||
import forge.deckchooser.FDeckViewer;
|
import forge.deckchooser.FDeckViewer;
|
||||||
import forge.game.GameEntityView;
|
import forge.game.GameEntityView;
|
||||||
import forge.game.GameView;
|
import forge.game.GameView;
|
||||||
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardView;
|
import forge.game.card.CardView;
|
||||||
import forge.game.combat.CombatView;
|
import forge.game.combat.CombatView;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
@@ -1003,6 +1004,11 @@ public final class CMatchUI
|
|||||||
return (List<GameEntityView>) order(title,"Selected", min, max, optionList, null, null, false);
|
return (List<GameEntityView>) order(title,"Selected", min, max, optionList, null, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Card> manipulateCardList(final String title, final List<Card> cards, final List<Card> manipulable, final boolean toTop, final boolean toBottom, final boolean toAnywhere) {
|
||||||
|
return GuiChoose.manipulateCardList(this, title, cards, manipulable, toTop, toBottom, toAnywhere);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setPlayerAvatar(final LobbyPlayer player, final IHasIcon ihi) {
|
public void setPlayerAvatar(final LobbyPlayer player, final IHasIcon ihi) {
|
||||||
avatarImages.put(player.getName(), ihi.getIconImageKey());
|
avatarImages.put(player.getName(), ihi.getIconImageKey());
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ public class CardArea extends CardPanelContainer implements CardPanelMouseListen
|
|||||||
dragPanel.setDisplayEnabled(false);
|
dragPanel.setDisplayEnabled(false);
|
||||||
|
|
||||||
CardPanel.setDragAnimationPanel(new CardPanel(dragPanel.getMatchUI(), dragPanel.getCard()));
|
CardPanel.setDragAnimationPanel(new CardPanel(dragPanel.getMatchUI(), dragPanel.getCard()));
|
||||||
final JFrame frame = (JFrame) SwingUtilities.windowForComponent(this);
|
final RootPaneContainer frame = (RootPaneContainer) SwingUtilities.windowForComponent(this);
|
||||||
final JLayeredPane layeredPane = frame.getLayeredPane();
|
final JLayeredPane layeredPane = frame.getLayeredPane();
|
||||||
layeredPane.add(CardPanel.getDragAnimationPanel());
|
layeredPane.add(CardPanel.getDragAnimationPanel());
|
||||||
layeredPane.moveToFront(CardPanel.getDragAnimationPanel());
|
layeredPane.moveToFront(CardPanel.getDragAnimationPanel());
|
||||||
|
|||||||
@@ -182,6 +182,10 @@ public abstract class CardPanelContainer extends SkinnedPanel {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean cardPanelDraggable(final CardPanel panel) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private MouseMotionListener setupMotionMouseListener() {
|
private MouseMotionListener setupMotionMouseListener() {
|
||||||
final MouseMotionListener mml = new MouseMotionListener() {
|
final MouseMotionListener mml = new MouseMotionListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -207,6 +211,8 @@ public abstract class CardPanelContainer extends SkinnedPanel {
|
|||||||
if (panel != mouseDownPanel) {
|
if (panel != mouseDownPanel) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cardPanelDraggable(panel)) { // allow for non-draggable cards
|
||||||
if (intialMouseDragX == -1) {
|
if (intialMouseDragX == -1) {
|
||||||
intialMouseDragX = x;
|
intialMouseDragX = x;
|
||||||
intialMouseDragY = y;
|
intialMouseDragY = y;
|
||||||
@@ -222,6 +228,7 @@ public abstract class CardPanelContainer extends SkinnedPanel {
|
|||||||
mouseDragOffsetY = panel.getY() - intialMouseDragY;
|
mouseDragOffsetY = panel.getY() - intialMouseDragY;
|
||||||
mouseDragStart(getMouseDragPanel(), evt);
|
mouseDragStart(getMouseDragPanel(), evt);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseMoved(final MouseEvent evt) {
|
public void mouseMoved(final MouseEvent evt) {
|
||||||
|
|||||||
@@ -0,0 +1,317 @@
|
|||||||
|
/*
|
||||||
|
* Forge: Play Magic: the Gathering.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package forge.view.arcane;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.KeyAdapter;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.swing.ScrollPaneConstants;
|
||||||
|
import javax.swing.Timer;
|
||||||
|
|
||||||
|
import forge.Singletons;
|
||||||
|
import forge.game.card.Card;
|
||||||
|
import forge.game.card.CardView;
|
||||||
|
import forge.gui.framework.SDisplayUtil;
|
||||||
|
import forge.model.FModel;
|
||||||
|
import forge.properties.ForgePreferences;
|
||||||
|
import forge.properties.ForgePreferences.FPref;
|
||||||
|
import forge.screens.match.CMatchUI;
|
||||||
|
import forge.view.arcane.util.CardPanelMouseAdapter;
|
||||||
|
import forge.toolbox.FScrollPane;
|
||||||
|
import forge.toolbox.MouseTriggerEvent;
|
||||||
|
import forge.view.FFrame;
|
||||||
|
import forge.view.FDialog;
|
||||||
|
|
||||||
|
import forge.toolbox.FButton;
|
||||||
|
|
||||||
|
public class ListCardArea extends CardArea {
|
||||||
|
|
||||||
|
private static final String COORD_DELIM = ",";
|
||||||
|
private static final ForgePreferences prefs = FModel.getPreferences();
|
||||||
|
|
||||||
|
public void show() {
|
||||||
|
this.showWindow();
|
||||||
|
}
|
||||||
|
public void hide() {
|
||||||
|
this.hideWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList<Card> cardList;
|
||||||
|
private ArrayList<Card> moveableCards;
|
||||||
|
private boolean toTop, toBottom, toAnywhere;
|
||||||
|
private String title;
|
||||||
|
private FPref locPref;
|
||||||
|
private boolean hasBeenShown = false, locLoaded;
|
||||||
|
private static ListCardArea storedArea;
|
||||||
|
|
||||||
|
private final FButton doneButton;
|
||||||
|
|
||||||
|
public ListCardArea(final CMatchUI matchUI, final String title0, final List<Card> cardList0, final List<Card> moveableCards0, final boolean toTop0, final boolean toBottom0, final boolean toAnywhere0) {
|
||||||
|
super(matchUI, new FScrollPane(false, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER));
|
||||||
|
window.add(getScrollPane(),"grow, push");
|
||||||
|
try { Thread.sleep(1000); } catch(InterruptedException ex) { }
|
||||||
|
getScrollPane().setViewportView(this);
|
||||||
|
setOpaque(false);
|
||||||
|
doneButton = new FButton("Done");
|
||||||
|
doneButton.addActionListener(new ActionListener() {
|
||||||
|
@Override public void actionPerformed(ActionEvent e) { window.setVisible(false); }
|
||||||
|
});
|
||||||
|
window.add(doneButton,BorderLayout.SOUTH);
|
||||||
|
cardList = new ArrayList<Card>(cardList0); // this is modified - pfps - is there a better way?
|
||||||
|
moveableCards = new ArrayList<Card>(moveableCards0);
|
||||||
|
title = title0;
|
||||||
|
toTop = toTop0;
|
||||||
|
toBottom = toBottom0;
|
||||||
|
toAnywhere = toAnywhere0;
|
||||||
|
this.setDragEnabled(true);
|
||||||
|
this.setVertical(true);
|
||||||
|
storedArea = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Card> getCardList() {
|
||||||
|
return cardList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
// private SkinnedFrame window = new SkinnedFrame() {
|
||||||
|
private final FDialog window = new FDialog(true, true, "0") {
|
||||||
|
@Override
|
||||||
|
public void setLocationRelativeTo(Component c) {
|
||||||
|
super.setLocationRelativeTo(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setVisible(boolean b0) {
|
||||||
|
if (isVisible() == b0) { return; }
|
||||||
|
if (b0) {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
super.setVisible(b0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private void showWindow() {
|
||||||
|
onShow();
|
||||||
|
window.setFocusableWindowState(true);
|
||||||
|
window.setVisible(true);
|
||||||
|
}
|
||||||
|
private void hideWindow() {
|
||||||
|
onShow();
|
||||||
|
window.setFocusableWindowState(false); // should probably do this earlier
|
||||||
|
window.setVisible(false);
|
||||||
|
}
|
||||||
|
private void onShow() {
|
||||||
|
if (!hasBeenShown) {
|
||||||
|
loadLocation();
|
||||||
|
this.addCardPanelMouseListener(new CardPanelMouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseDragEnd(final CardPanel dragPanel, final MouseEvent evt) {
|
||||||
|
dragEnd(dragPanel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.addKeyListener(new KeyAdapter() {
|
||||||
|
@Override
|
||||||
|
public void keyPressed(final KeyEvent e) {
|
||||||
|
switch (e.getKeyCode()) {
|
||||||
|
case KeyEvent.VK_ENTER:
|
||||||
|
doneButton.doClick();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// is this a valid place to move the card?
|
||||||
|
private boolean validIndex(final Card card, final int index) {
|
||||||
|
if (toAnywhere) { return true; }
|
||||||
|
int oldIndex = cardList.indexOf(card);
|
||||||
|
boolean topMove = true;
|
||||||
|
for(int i=0; i<index+(oldIndex<index?1:0); i++) {
|
||||||
|
if (!moveableCards.contains(cardList.get(i))) { topMove=false; break; }
|
||||||
|
}
|
||||||
|
if (toTop && topMove) { return true; }
|
||||||
|
boolean bottomMove = true;
|
||||||
|
for(int i=index+1-(oldIndex>index?1:0); i<cardList.size(); i++) {
|
||||||
|
if (!moveableCards.contains(cardList.get(i))) { bottomMove=false; break; }
|
||||||
|
}
|
||||||
|
if (toBottom && bottomMove) { return true; }
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Card panelToCard(final CardPanel panel) { //pfps there must be a better way
|
||||||
|
final CardView panelView = panel.getCard();
|
||||||
|
Card panelCard = null;
|
||||||
|
for ( Card card : cardList ) { if ( panelView == card.getView() ) { panelCard = card; } }
|
||||||
|
return panelCard;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean cardPanelDraggable(final CardPanel panel) {
|
||||||
|
return moveableCards.contains(panelToCard(panel));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dragEnd(final CardPanel dragPanel) {
|
||||||
|
// if drag is not allowed, don't move anything
|
||||||
|
final Card dragCard = panelToCard(dragPanel);
|
||||||
|
if (moveableCards.contains(dragCard)) {
|
||||||
|
//update index of dragged card in hand zone to match new index within hand area
|
||||||
|
final int index = getCardPanels().indexOf(dragPanel);
|
||||||
|
if (validIndex(dragCard,index)) {
|
||||||
|
System.out.print("Really move card to index "); System.out.println(index);
|
||||||
|
synchronized (cardList) {
|
||||||
|
cardList.remove(dragCard);
|
||||||
|
cardList.add(index, dragCard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadLocation() {
|
||||||
|
System.out.println("loadlocation");
|
||||||
|
if (locPref != null) {
|
||||||
|
String value = prefs.getPref(locPref);
|
||||||
|
System.out.print(locPref); System.out.println(value);
|
||||||
|
if (value.length() > 0) {
|
||||||
|
String[] coords = value.split(COORD_DELIM);
|
||||||
|
if (coords.length == 4) {
|
||||||
|
try {
|
||||||
|
int x = Integer.parseInt(coords[0]);
|
||||||
|
int y = Integer.parseInt(coords[1]);
|
||||||
|
int w = Integer.parseInt(coords[2]);
|
||||||
|
int h = Integer.parseInt(coords[3]);
|
||||||
|
|
||||||
|
//ensure the window is accessible
|
||||||
|
int centerX = x + w / 2;
|
||||||
|
int centerY = y + h / 2;
|
||||||
|
Rectangle screenBounds = SDisplayUtil.getScreenBoundsForPoint(new Point(centerX, centerY));
|
||||||
|
if (centerX < screenBounds.x) {
|
||||||
|
x = screenBounds.x;
|
||||||
|
}
|
||||||
|
else if (centerX > screenBounds.x + screenBounds.width) {
|
||||||
|
x = screenBounds.x + screenBounds.width - w;
|
||||||
|
if (x < screenBounds.x) {
|
||||||
|
x = screenBounds.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (centerY < screenBounds.y) {
|
||||||
|
y = screenBounds.y;
|
||||||
|
}
|
||||||
|
else if (centerY > screenBounds.y + screenBounds.height) {
|
||||||
|
y = screenBounds.y + screenBounds.height - h;
|
||||||
|
if (y < screenBounds.y) {
|
||||||
|
y = screenBounds.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.setBounds(x, y, w, h);
|
||||||
|
locLoaded = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prefs.setPref(locPref, ""); //clear value if invalid
|
||||||
|
prefs.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//fallback default size
|
||||||
|
FFrame mainFrame = Singletons.getView().getFrame();
|
||||||
|
window.setSize(mainFrame.getWidth() / 5, mainFrame.getHeight() / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refresh() {
|
||||||
|
List<CardPanel> cardPanels = new ArrayList<CardPanel>();
|
||||||
|
// FCollectionView<Card> cards = new FCollection<Card>(cardList);
|
||||||
|
if (cardList != null) {
|
||||||
|
for (final Card card : cardList) {
|
||||||
|
CardPanel cardPanel = getCardPanel(card.getId());
|
||||||
|
if (cardPanel == null) {
|
||||||
|
cardPanel = new CardPanel(getMatchUI(), card.getView());
|
||||||
|
cardPanel.setDisplayEnabled(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cardPanel.setCard(card.getView()); //ensure card view updated
|
||||||
|
}
|
||||||
|
cardPanels.add(cardPanel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean hadCardPanels = getCardPanels().size() > 0;
|
||||||
|
setCardPanels(cardPanels);
|
||||||
|
window.setTitle(String.format(title, cardPanels.size()));
|
||||||
|
|
||||||
|
//if window had cards and now doesn't, hide window
|
||||||
|
//(e.g. cast final card from Flashback zone)
|
||||||
|
if (hadCardPanels && cardPanels.size() == 0) {
|
||||||
|
window.setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doLayout() {
|
||||||
|
// if (window.isResizing()) {
|
||||||
|
// //delay layout slightly to reduce flicker during window resize
|
||||||
|
// layoutTimer.restart();
|
||||||
|
// }
|
||||||
|
//else {
|
||||||
|
finishDoLayout();
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Timer layoutTimer = new Timer(250, new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent arg0) {
|
||||||
|
layoutTimer.stop();
|
||||||
|
finishDoLayout();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
private void finishDoLayout() {
|
||||||
|
super.doLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void mouseOver(final CardPanel panel, final MouseEvent evt) {
|
||||||
|
getMatchUI().setCard(panel.getCard(), evt.isShiftDown());
|
||||||
|
super.mouseOver(panel, evt);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public final void mouseLeftClicked(final CardPanel panel, final MouseEvent evt) {
|
||||||
|
getMatchUI().getGameController().selectCard(panel.getCard(), null, new MouseTriggerEvent(evt));
|
||||||
|
super.mouseLeftClicked(panel, evt);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public final void mouseRightClicked(final CardPanel panel, final MouseEvent evt) {
|
||||||
|
getMatchUI().getGameController().selectCard(panel.getCard(), null, new MouseTriggerEvent(evt));
|
||||||
|
super.mouseRightClicked(panel, evt);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -29,6 +29,7 @@ import forge.deck.CardPool;
|
|||||||
import forge.deck.FSideboardDialog;
|
import forge.deck.FSideboardDialog;
|
||||||
import forge.game.GameEntityView;
|
import forge.game.GameEntityView;
|
||||||
import forge.game.GameView;
|
import forge.game.GameView;
|
||||||
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardView;
|
import forge.game.card.CardView;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
import forge.game.player.DelayedReveal;
|
import forge.game.player.DelayedReveal;
|
||||||
@@ -520,6 +521,11 @@ public class MatchController extends AbstractGuiGame {
|
|||||||
return SGuiChoose.order(title, "Selected", min, max, (List<GameEntityView>) optionList, null);
|
return SGuiChoose.order(title, "Selected", min, max, (List<GameEntityView>) optionList, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Card> manipulateCardList(final String title, final List<Card> cards, final List<Card> manipulable, final boolean toTop, final boolean toBottom, final boolean toAnywhere) {
|
||||||
|
return null; // pfps not implemented yet
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCard(final CardView card) {
|
public void setCard(final CardView card) {
|
||||||
// doesn't need to do anything
|
// doesn't need to do anything
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import forge.assets.FSkinProp;
|
|||||||
import forge.deck.CardPool;
|
import forge.deck.CardPool;
|
||||||
import forge.game.GameEntityView;
|
import forge.game.GameEntityView;
|
||||||
import forge.game.GameView;
|
import forge.game.GameView;
|
||||||
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardView;
|
import forge.game.card.CardView;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
import forge.game.player.DelayedReveal;
|
import forge.game.player.DelayedReveal;
|
||||||
@@ -147,6 +148,10 @@ public interface IGuiGame {
|
|||||||
List<PaperCard> sideboard(CardPool sideboard, CardPool main);
|
List<PaperCard> sideboard(CardPool sideboard, CardPool main);
|
||||||
GameEntityView chooseSingleEntityForEffect(String title, List<? extends GameEntityView> optionList, DelayedReveal delayedReveal, boolean isOptional);
|
GameEntityView chooseSingleEntityForEffect(String title, List<? extends GameEntityView> optionList, DelayedReveal delayedReveal, boolean isOptional);
|
||||||
List<GameEntityView> chooseEntitiesForEffect(String title, List<? extends GameEntityView> optionList, int min, int max, DelayedReveal delayedReveal);
|
List<GameEntityView> chooseEntitiesForEffect(String title, List<? extends GameEntityView> optionList, int min, int max, DelayedReveal delayedReveal);
|
||||||
|
|
||||||
|
// show a list of cards and allow some of them to be moved around and return new list
|
||||||
|
List<Card> manipulateCardList(String title, final List<Card> cards, final List<Card> manipulable, boolean toTop, boolean toBottom, boolean toAnywhere);
|
||||||
|
|
||||||
void setCard(CardView card);
|
void setCard(CardView card);
|
||||||
void setPlayerAvatar(LobbyPlayer player, IHasIcon ihi);
|
void setPlayerAvatar(LobbyPlayer player, IHasIcon ihi);
|
||||||
boolean openZones(Collection<ZoneType> zones, Map<PlayerView, Object> players);
|
boolean openZones(Collection<ZoneType> zones, Map<PlayerView, Object> players);
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ public enum ProtocolMethod {
|
|||||||
sideboard (Mode.SERVER, List.class, CardPool.class, CardPool.class),
|
sideboard (Mode.SERVER, List.class, CardPool.class, CardPool.class),
|
||||||
chooseSingleEntityForEffect(Mode.SERVER, GameEntityView.class, String.class, List.class, DelayedReveal.class, Boolean.TYPE),
|
chooseSingleEntityForEffect(Mode.SERVER, GameEntityView.class, String.class, List.class, DelayedReveal.class, Boolean.TYPE),
|
||||||
chooseEntitiesForEffect(Mode.SERVER, GameEntityView.class, String.class, List.class, Integer.TYPE, Integer.TYPE, DelayedReveal.class),
|
chooseEntitiesForEffect(Mode.SERVER, GameEntityView.class, String.class, List.class, Integer.TYPE, Integer.TYPE, DelayedReveal.class),
|
||||||
|
manipulateCardList (Mode.SERVER, List.class, String.class, List.class, List.class, Boolean.TYPE, Boolean.TYPE, Boolean.TYPE),
|
||||||
setCard (Mode.SERVER, Void.TYPE, CardView.class),
|
setCard (Mode.SERVER, Void.TYPE, CardView.class),
|
||||||
// TODO case "setPlayerAvatar":
|
// TODO case "setPlayerAvatar":
|
||||||
openZones (Mode.SERVER, Boolean.TYPE, Collection/*ZoneType*/.class, Map/*PlayerView,Object*/.class),
|
openZones (Mode.SERVER, Boolean.TYPE, Collection/*ZoneType*/.class, Map/*PlayerView,Object*/.class),
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import forge.assets.FSkinProp;
|
|||||||
import forge.deck.CardPool;
|
import forge.deck.CardPool;
|
||||||
import forge.game.GameEntityView;
|
import forge.game.GameEntityView;
|
||||||
import forge.game.GameView;
|
import forge.game.GameView;
|
||||||
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardView;
|
import forge.game.card.CardView;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
import forge.game.player.DelayedReveal;
|
import forge.game.player.DelayedReveal;
|
||||||
@@ -248,6 +249,11 @@ public class NetGuiGame extends AbstractGuiGame {
|
|||||||
return sendAndWait(ProtocolMethod.chooseEntitiesForEffect, title, optionList, min, max, delayedReveal);
|
return sendAndWait(ProtocolMethod.chooseEntitiesForEffect, title, optionList, min, max, delayedReveal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Card> manipulateCardList(final String title, final List<Card> cards, final List<Card> manipulable, final boolean toTop, final boolean toBottom, final boolean toAnywhere) {
|
||||||
|
return sendAndWait(ProtocolMethod.manipulateCardList, title, cards, manipulable, toTop, toBottom, toAnywhere);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCard(final CardView card) {
|
public void setCard(final CardView card) {
|
||||||
updateGameView();
|
updateGameView();
|
||||||
|
|||||||
@@ -349,8 +349,9 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean useSelectCardsInput(final FCollectionView<? extends GameEntity> sourceList) {
|
private boolean useSelectCardsInput(final FCollectionView<? extends GameEntity> sourceList) {
|
||||||
// if UI_SELECT_FROM_ZONES not set use InputSelect only for battlefield and player hand
|
// if UI_SELECT_FROM_CARD_DISPLAYS not set use InputSelect only for battlefield and player hand
|
||||||
// if UI_SELECT_FROM_ZONES set use InputSelect for any zone that can be shown
|
// if UI_SELECT_FROM_CARD_DISPLAYS set use InputSelect for any zone that can be shown
|
||||||
|
if ( FThreads.isGuiThread() ) { return false; } // also can't use InputSelect from GUI thread (e.g., DevMode Tutor)
|
||||||
for (final GameEntity c : sourceList) {
|
for (final GameEntity c : sourceList) {
|
||||||
if (c instanceof Player) {
|
if (c instanceof Player) {
|
||||||
continue;
|
continue;
|
||||||
@@ -361,7 +362,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
|||||||
final Zone cz = ((Card) c).getZone();
|
final Zone cz = ((Card) c).getZone();
|
||||||
final boolean useUiPointAtCard =
|
final boolean useUiPointAtCard =
|
||||||
cz != null &&
|
cz != null &&
|
||||||
FModel.getPreferences().getPrefBoolean(FPref.UI_SELECT_FROM_ZONES) ?
|
FModel.getPreferences().getPrefBoolean(FPref.UI_SELECT_FROM_CARD_DISPLAYS) ?
|
||||||
(cz.is(ZoneType.Battlefield) || cz.is(ZoneType.Hand) || cz.is(ZoneType.Library) ||
|
(cz.is(ZoneType.Battlefield) || cz.is(ZoneType.Hand) || cz.is(ZoneType.Library) ||
|
||||||
cz.is(ZoneType.Graveyard) || cz.is(ZoneType.Exile) || cz.is(ZoneType.Flashback) || cz.is(ZoneType.Command)) :
|
cz.is(ZoneType.Graveyard) || cz.is(ZoneType.Exile) || cz.is(ZoneType.Flashback) || cz.is(ZoneType.Command)) :
|
||||||
(cz.is(ZoneType.Hand) && cz.getPlayer() == player || cz.is(ZoneType.Battlefield));
|
(cz.is(ZoneType.Hand) && cz.getPlayer() == player || cz.is(ZoneType.Battlefield));
|
||||||
@@ -736,12 +737,38 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ImmutablePair<CardCollection, CardCollection> arrangeForMove(final String title, final List<Card> cards, final List<Card> manipulable, final boolean topOK, final boolean bottomOK) {
|
||||||
|
List<Card> result = getGui().manipulateCardList("Move cards to top or bottom of library", cards, manipulable, topOK, bottomOK, false);
|
||||||
|
CardCollection toBottom = new CardCollection();
|
||||||
|
CardCollection toTop = new CardCollection();
|
||||||
|
for (int i = 0; manipulable.contains(result.get(i)) && i<cards.size(); i++ ) {
|
||||||
|
toTop.add(result.get(i));
|
||||||
|
}
|
||||||
|
if (toTop.size() < cards.size()) { // the top isn't everything
|
||||||
|
for (int i = result.size()-1; manipulable.contains(result.get(i)); i-- ) {
|
||||||
|
toBottom.add(result.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ImmutablePair.of(toTop,toBottom);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImmutablePair<CardCollection, CardCollection> arrangeForScry(final CardCollection topN) {
|
public ImmutablePair<CardCollection, CardCollection> arrangeForScry(final CardCollection topN) {
|
||||||
CardCollection toBottom = null;
|
CardCollection toBottom = null;
|
||||||
CardCollection toTop = null;
|
CardCollection toTop = null;
|
||||||
|
|
||||||
tempShowCards(topN);
|
tempShowCards(topN);
|
||||||
|
if ( FModel.getPreferences().getPrefBoolean(FPref.UI_SELECT_FROM_CARD_DISPLAYS) ) {
|
||||||
|
ArrayList<Card> cardList = new ArrayList<Card>(); // pfps there must be a better way
|
||||||
|
for (final Card card : player.getCardsIn(ZoneType.Library)) {
|
||||||
|
cardList.add(card);
|
||||||
|
}
|
||||||
|
ImmutablePair<CardCollection, CardCollection> result =
|
||||||
|
arrangeForMove("Move cards to top or bottom of library", cardList, topN, true, true);
|
||||||
|
System.out.print("Arrange "); System.out.println(result);
|
||||||
|
toTop = result.getLeft();
|
||||||
|
toBottom = result.getRight();
|
||||||
|
} else {
|
||||||
if (topN.size() == 1) {
|
if (topN.size() == 1) {
|
||||||
if (willPutCardOnTop(topN.get(0))) {
|
if (willPutCardOnTop(topN.get(0))) {
|
||||||
toTop = topN;
|
toTop = topN;
|
||||||
@@ -761,6 +788,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
|||||||
"Top of Library", CardView.getCollection(topN), null));
|
"Top of Library", CardView.getCollection(topN), null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
endTempShowCards();
|
endTempShowCards();
|
||||||
return ImmutablePair.of(toTop, toBottom);
|
return ImmutablePair.of(toTop, toBottom);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ public class ForgePreferences extends PreferencesStore<ForgePreferences.FPref> {
|
|||||||
UI_DISABLE_IMAGES_EFFECT_CARDS("false"),
|
UI_DISABLE_IMAGES_EFFECT_CARDS("false"),
|
||||||
UI_ALLOW_ORDER_GRAVEYARD_WHEN_NEEDED ("Never"),
|
UI_ALLOW_ORDER_GRAVEYARD_WHEN_NEEDED ("Never"),
|
||||||
UI_DEFAULT_FONT_SIZE("12"),
|
UI_DEFAULT_FONT_SIZE("12"),
|
||||||
UI_SELECT_FROM_ZONES("true"),
|
UI_SELECT_FROM_CARD_DISPLAYS("true"),
|
||||||
UI_FOR_TOUCHSCREN("false"),
|
UI_FOR_TOUCHSCREN("false"),
|
||||||
|
|
||||||
UI_VIBRATE_ON_LIFE_LOSS("true"),
|
UI_VIBRATE_ON_LIFE_LOSS("true"),
|
||||||
|
|||||||
Reference in New Issue
Block a user