mirror of
https://github.com/magefree/mage.git
synced 2025-12-25 04:52:07 -08:00
[READY FOR REVIEW] Implement a "multi-amount" dialog (#7528)
* Implemented chooseTargetAmount and new GUI dialog (distribute damage, distribute mana) * Added tests and AI support; * Test framework: added aliases support in TargetAmount dialogs; Co-authored-by: Oleg Agafonov <jaydi85@gmail.com>
This commit is contained in:
parent
042aa61ad4
commit
600cac6fc7
35 changed files with 1209 additions and 232 deletions
|
|
@ -0,0 +1,103 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.2" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JInternalFrameFormInfo">
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="2"/>
|
||||
</SyntheticProperties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace min="12" pref="12" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="header" alignment="1" max="32767" attributes="0"/>
|
||||
<Component id="counterText" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace min="-2" pref="184" max="-2" attributes="0"/>
|
||||
<Component id="chooseButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="172" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jScrollPane1" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="header" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="counterText" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jScrollPane1" pref="276" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="chooseButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JButton" name="chooseButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Choose"/>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="chooseButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="header">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Header"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="counterText">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Counter"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanel1">
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="413" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="273" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
|
|
@ -0,0 +1,215 @@
|
|||
package mage.client.dialog;
|
||||
|
||||
import mage.constants.ColoredManaSymbol;
|
||||
import org.mage.card.arcane.ManaSymbols;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author weirddan455
|
||||
*/
|
||||
public class PickMultiNumberDialog extends MageDialog {
|
||||
|
||||
private List<JLabel> labelList = null;
|
||||
private List<JSpinner> spinnerList = null;
|
||||
|
||||
public PickMultiNumberDialog() {
|
||||
initComponents();
|
||||
this.setModal(true);
|
||||
}
|
||||
|
||||
public void showDialog(List<String> messages, int min, int max, Map<String, Serializable> options) {
|
||||
this.header.setText((String) options.get("header"));
|
||||
this.header.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
this.setTitle((String) options.get("title"));
|
||||
|
||||
if (labelList != null) {
|
||||
for (JLabel label : labelList) {
|
||||
jPanel1.remove(label);
|
||||
}
|
||||
}
|
||||
if (spinnerList != null) {
|
||||
for (JSpinner spinner : spinnerList) {
|
||||
jPanel1.remove(spinner);
|
||||
}
|
||||
}
|
||||
int size = messages.size();
|
||||
labelList = new ArrayList<>(size);
|
||||
spinnerList = new ArrayList<>(size);
|
||||
jPanel1.setLayout(new GridBagLayout());
|
||||
GridBagConstraints labelC = new GridBagConstraints();
|
||||
GridBagConstraints spinnerC = new GridBagConstraints();
|
||||
for (int i = 0; i < size; i++) {
|
||||
JLabel label = new JLabel();
|
||||
|
||||
// mana mode
|
||||
String manaText = null;
|
||||
String input = messages.get(i);
|
||||
switch (input) {
|
||||
case "W":
|
||||
manaText = ColoredManaSymbol.W.getColorHtmlName();
|
||||
break;
|
||||
case "U":
|
||||
manaText = ColoredManaSymbol.U.getColorHtmlName();
|
||||
break;
|
||||
case "B":
|
||||
manaText = ColoredManaSymbol.B.getColorHtmlName();
|
||||
break;
|
||||
case "R":
|
||||
manaText = ColoredManaSymbol.R.getColorHtmlName();
|
||||
break;
|
||||
case "G":
|
||||
manaText = ColoredManaSymbol.G.getColorHtmlName();
|
||||
break;
|
||||
}
|
||||
if (manaText != null) {
|
||||
label.setText("<html>" + manaText);
|
||||
Image image = ManaSymbols.getSizedManaSymbol(input);
|
||||
if (image != null) {
|
||||
label.setIcon(new ImageIcon(image));
|
||||
}
|
||||
} else {
|
||||
// text mode
|
||||
label.setText("<html>" + input);
|
||||
}
|
||||
|
||||
labelC.weightx = 0.5;
|
||||
labelC.gridx = 0;
|
||||
labelC.gridy = i;
|
||||
jPanel1.add(label, labelC);
|
||||
labelList.add(label);
|
||||
|
||||
JSpinner spinner = new JSpinner();
|
||||
spinner.setModel(new SpinnerNumberModel(0, 0, max, 1));
|
||||
spinnerC.weightx = 0.5;
|
||||
spinnerC.gridx = 1;
|
||||
spinnerC.gridy = i;
|
||||
spinnerC.ipadx = 20;
|
||||
spinner.addChangeListener(e -> {
|
||||
updateControls(min, max);
|
||||
});
|
||||
jPanel1.add(spinner, spinnerC);
|
||||
spinnerList.add(spinner);
|
||||
}
|
||||
this.counterText.setText("0 out of 0");
|
||||
this.counterText.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
|
||||
updateControls(min, max);
|
||||
|
||||
this.pack();
|
||||
this.makeWindowCentered();
|
||||
this.setVisible(true);
|
||||
}
|
||||
|
||||
private void updateControls(int min, int max) {
|
||||
int totalChosenAmount = 0;
|
||||
for (JSpinner jSpinner : spinnerList) {
|
||||
totalChosenAmount += ((Number) jSpinner.getValue()).intValue();
|
||||
}
|
||||
counterText.setText(totalChosenAmount + " out of " + max);
|
||||
chooseButton.setEnabled(totalChosenAmount >= min && totalChosenAmount <= max);
|
||||
}
|
||||
|
||||
public String getMultiAmount() {
|
||||
return spinnerList
|
||||
.stream()
|
||||
.map(spinner -> ((Number) spinner.getValue()).intValue())
|
||||
.map(String::valueOf)
|
||||
.collect(Collectors.joining(" "));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
chooseButton = new javax.swing.JButton();
|
||||
header = new javax.swing.JLabel();
|
||||
counterText = new javax.swing.JLabel();
|
||||
jScrollPane1 = new javax.swing.JScrollPane();
|
||||
jPanel1 = new javax.swing.JPanel();
|
||||
|
||||
chooseButton.setText("Choose");
|
||||
chooseButton.setEnabled(false);
|
||||
chooseButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
chooseButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
header.setText("Header");
|
||||
|
||||
counterText.setText("Counter");
|
||||
|
||||
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
|
||||
jPanel1.setLayout(jPanel1Layout);
|
||||
jPanel1Layout.setHorizontalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 413, Short.MAX_VALUE)
|
||||
);
|
||||
jPanel1Layout.setVerticalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 273, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
jScrollPane1.setViewportView(jPanel1);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
||||
getContentPane().setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(12, 12, 12)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(header, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(counterText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(184, 184, 184)
|
||||
.addComponent(chooseButton)
|
||||
.addGap(0, 172, Short.MAX_VALUE))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jScrollPane1)))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(header)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(counterText)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 276, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(chooseButton)
|
||||
.addContainerGap())
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void chooseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chooseButtonActionPerformed
|
||||
this.hideDialog();
|
||||
}//GEN-LAST:event_chooseButtonActionPerformed
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton chooseButton;
|
||||
private javax.swing.JLabel counterText;
|
||||
private javax.swing.JLabel header;
|
||||
private javax.swing.JPanel jPanel1;
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
|
|
@ -86,6 +86,7 @@ public final class GamePanel extends javax.swing.JPanel {
|
|||
GamePane gamePane;
|
||||
private ReplayTask replayTask;
|
||||
private final PickNumberDialog pickNumber;
|
||||
private final PickMultiNumberDialog pickMultiNumber;
|
||||
private JLayeredPane jLayeredPane;
|
||||
private String chosenHandKey = "You";
|
||||
private boolean smallMode = false;
|
||||
|
|
@ -134,6 +135,9 @@ public final class GamePanel extends javax.swing.JPanel {
|
|||
pickNumber = new PickNumberDialog();
|
||||
MageFrame.getDesktop().add(pickNumber, JLayeredPane.MODAL_LAYER);
|
||||
|
||||
pickMultiNumber = new PickMultiNumberDialog();
|
||||
MageFrame.getDesktop().add(pickMultiNumber, JLayeredPane.MODAL_LAYER);
|
||||
|
||||
this.feedbackPanel.setConnectedChatPanel(this.userChatPanel);
|
||||
|
||||
// Override layout (I can't edit generated code)
|
||||
|
|
@ -238,6 +242,9 @@ public final class GamePanel extends javax.swing.JPanel {
|
|||
if (pickNumber != null) {
|
||||
pickNumber.removeDialog();
|
||||
}
|
||||
if (pickMultiNumber != null) {
|
||||
pickMultiNumber.removeDialog();
|
||||
}
|
||||
for (CardInfoWindowDialog exileDialog : exiles.values()) {
|
||||
exileDialog.cleanUp();
|
||||
exileDialog.removeDialog();
|
||||
|
|
@ -1617,6 +1624,11 @@ public final class GamePanel extends javax.swing.JPanel {
|
|||
}
|
||||
}
|
||||
|
||||
public void getMultiAmount(List<String> messages, int min, int max, Map<String, Serializable> options) {
|
||||
pickMultiNumber.showDialog(messages, min, max, options);
|
||||
SessionHandler.sendPlayerString(gameId, pickMultiNumber.getMultiAmount());
|
||||
}
|
||||
|
||||
public void getChoice(Choice choice, UUID objectId) {
|
||||
hideAll();
|
||||
// TODO: remember last choices and search incremental for same events?
|
||||
|
|
|
|||
|
|
@ -297,6 +297,18 @@ public class CallbackClientImpl implements CallbackClient {
|
|||
break;
|
||||
}
|
||||
|
||||
case GAME_GET_MULTI_AMOUNT: {
|
||||
GameClientMessage message = (GameClientMessage) callback.getData();
|
||||
|
||||
GamePanel panel = MageFrame.getGame(callback.getObjectId());
|
||||
if (panel != null) {
|
||||
appendJsonEvent("GAME_GET_MULTI_AMOUNT", callback.getObjectId(), message);
|
||||
|
||||
panel.getMultiAmount(message.getMessages(), message.getMin(), message.getMax(), message.getOptions());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GAME_UPDATE: {
|
||||
GamePanel panel = MageFrame.getGame(callback.getObjectId());
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue