mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48:00 +00:00
Targeting overlay implemented (experimental, for enchantments only).
Dock button and preference toggle also enabled.
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -12465,6 +12465,7 @@ src/main/java/forge/gui/match/ControlWinLose.java -text
|
|||||||
src/main/java/forge/gui/match/GauntletWinLose.java -text
|
src/main/java/forge/gui/match/GauntletWinLose.java -text
|
||||||
src/main/java/forge/gui/match/QuestWinLoseCardViewer.java -text
|
src/main/java/forge/gui/match/QuestWinLoseCardViewer.java -text
|
||||||
src/main/java/forge/gui/match/QuestWinLoseHandler.java -text
|
src/main/java/forge/gui/match/QuestWinLoseHandler.java -text
|
||||||
|
src/main/java/forge/gui/match/TargetingOverlay.java -text
|
||||||
src/main/java/forge/gui/match/VMatchUI.java -text
|
src/main/java/forge/gui/match/VMatchUI.java -text
|
||||||
src/main/java/forge/gui/match/ViewWinLose.java -text
|
src/main/java/forge/gui/match/ViewWinLose.java -text
|
||||||
src/main/java/forge/gui/match/controllers/CAntes.java -text
|
src/main/java/forge/gui/match/controllers/CAntes.java -text
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 606 KiB After Width: | Height: | Size: 616 KiB |
@@ -256,11 +256,12 @@ public enum FControl {
|
|||||||
/** Sizes children of JLayeredPane to fully fit their layers. */
|
/** Sizes children of JLayeredPane to fully fit their layers. */
|
||||||
private void sizeChildren() {
|
private void sizeChildren() {
|
||||||
Component[] children = display.getComponentsInLayer(JLayeredPane.DEFAULT_LAYER);
|
Component[] children = display.getComponentsInLayer(JLayeredPane.DEFAULT_LAYER);
|
||||||
if (children.length == 0) { return; }
|
if (children.length != 0) { children[0].setSize(display.getSize()); }
|
||||||
children[0].setSize(display.getSize());
|
|
||||||
|
children = display.getComponentsInLayer(FView.TARGETING_LAYER);
|
||||||
|
if (children.length != 0) { children[0].setSize(display.getSize()); }
|
||||||
|
|
||||||
children = display.getComponentsInLayer(JLayeredPane.MODAL_LAYER);
|
children = display.getComponentsInLayer(JLayeredPane.MODAL_LAYER);
|
||||||
if (children.length == 0) { return; }
|
if (children.length != 0) { children[0].setSize(display.getSize()); }
|
||||||
children[0].setSize(display.getSize());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
157
src/main/java/forge/gui/match/TargetingOverlay.java
Normal file
157
src/main/java/forge/gui/match/TargetingOverlay.java
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* Forge: Play Magic: the Gathering.
|
||||||
|
* Copyright (C) 2011 Forge Team
|
||||||
|
*
|
||||||
|
* 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.gui.match;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
import forge.Card;
|
||||||
|
import forge.control.FControl;
|
||||||
|
import forge.gui.match.nonsingleton.CField;
|
||||||
|
import forge.gui.toolbox.FSkin;
|
||||||
|
import forge.model.FModel;
|
||||||
|
import forge.properties.ForgePreferences.FPref;
|
||||||
|
import forge.view.FView;
|
||||||
|
import forge.view.arcane.CardPanel;
|
||||||
|
import forge.view.arcane.PlayArea;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Semi-transparent overlay panel. Should be used with layered panes.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public enum TargetingOverlay {
|
||||||
|
/** */
|
||||||
|
SINGLETON_INSTANCE;
|
||||||
|
|
||||||
|
private final JPanel pnl = new OverlayPanel();
|
||||||
|
private final List<PlayArea> playAreas;
|
||||||
|
private List<CardPanel> cardPanels;
|
||||||
|
private final List<Point[]> arcs = new ArrayList<Point[]>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Semi-transparent overlay panel. Should be used with layered panes.
|
||||||
|
*/
|
||||||
|
private TargetingOverlay() {
|
||||||
|
playAreas = new ArrayList<PlayArea>();
|
||||||
|
cardPanels = new ArrayList<CardPanel>();
|
||||||
|
|
||||||
|
for (CField f : CMatchUI.SINGLETON_INSTANCE.getFieldControls()) {
|
||||||
|
playAreas.add(f.getView().getTabletop());
|
||||||
|
}
|
||||||
|
|
||||||
|
pnl.setOpaque(false);
|
||||||
|
pnl.setBackground(FSkin.getColor(FSkin.Colors.CLR_ZEBRA));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return {@link javax.swing.JPanel} */
|
||||||
|
public JPanel getPanel() {
|
||||||
|
return this.pnl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO - this is called every repaint, regardless if card
|
||||||
|
// positions have changed or not. Could perform better if
|
||||||
|
// it checked for a state change. Doublestrike 28-09-12
|
||||||
|
private void assembleArcs() {
|
||||||
|
arcs.clear();
|
||||||
|
cardPanels.clear();
|
||||||
|
cardPanels.addAll(playAreas.get(0).getCardPanels());
|
||||||
|
cardPanels.addAll(playAreas.get(1).getCardPanels());
|
||||||
|
|
||||||
|
final Point docOffsets = FView.SINGLETON_INSTANCE.getLpnDocument().getLocationOnScreen();
|
||||||
|
// Locations of arc endpoint, per card, with ID as primary key.
|
||||||
|
final Map<Integer, Point> endpoints = new HashMap<Integer, Point>();
|
||||||
|
|
||||||
|
// Assemble card locations for easy reference
|
||||||
|
for (CardPanel c : cardPanels) {
|
||||||
|
if (!c.isShowing()) { continue; }
|
||||||
|
endpoints.put(c.getCard().getUniqueNumber(), new Point(
|
||||||
|
(int) (c.getParent().getLocationOnScreen().getX() + c.getCardLocation().getX() - docOffsets.getX() + c.getWidth() / 4),
|
||||||
|
(int) (c.getParent().getLocationOnScreen().getY() + c.getCardLocation().getY() - docOffsets.getY() + c.getHeight() / 4)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Card> temp = new ArrayList<Card>();
|
||||||
|
for (CardPanel c : cardPanels) {
|
||||||
|
if (!c.isShowing()) { continue; }
|
||||||
|
temp = c.getCard().getEnchantedBy();
|
||||||
|
for (Card enchantingCard : temp) {
|
||||||
|
arcs.add(new Point[] {
|
||||||
|
endpoints.get(c.getCard().getUniqueNumber()),
|
||||||
|
endpoints.get(enchantingCard.getUniqueNumber())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
temp.clear();
|
||||||
|
endpoints.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class OverlayPanel extends JPanel {
|
||||||
|
/**
|
||||||
|
* For some reason, the alpha channel background doesn't work properly on
|
||||||
|
* Windows 7, so the paintComponent override is required for a
|
||||||
|
* semi-transparent overlay.
|
||||||
|
*
|
||||||
|
* @param g
|
||||||
|
*   Graphics object
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void paintComponent(final Graphics g) {
|
||||||
|
// No need for this except in match view
|
||||||
|
if (FControl.SINGLETON_INSTANCE.getState() != 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (!Boolean.valueOf(FModel.SINGLETON_INSTANCE.getPreferences().getPref(FPref.UI_TARGETING_OVERLAY))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.paintComponent(g);
|
||||||
|
// Arc drawing
|
||||||
|
Graphics2D g2d = (Graphics2D) g;
|
||||||
|
g2d.setColor(FSkin.getColor(FSkin.Colors.CLR_ACTIVE));
|
||||||
|
g2d.setStroke(new BasicStroke(3F));
|
||||||
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
||||||
|
RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
|
||||||
|
assembleArcs();
|
||||||
|
int w, h, x, y;
|
||||||
|
|
||||||
|
for (Point[] p : arcs) {
|
||||||
|
w = Math.abs((int) p[1].getX() - (int) p[0].getX());
|
||||||
|
h = Math.abs((int) p[1].getY() - (int) p[0].getY());
|
||||||
|
x = (Math.min((int) p[1].getX(), (int) p[0].getX()) - w);
|
||||||
|
y = (Math.min((int) p[1].getY(), (int) p[0].getY()));
|
||||||
|
|
||||||
|
g2d.drawArc(x, y, 2 * w, 2 * h, 0, 90);
|
||||||
|
g2d.fillOval((int) p[0].getX() - 4, (int) p[0].getY() - 4, 8, 8);
|
||||||
|
g2d.fillOval((int) p[1].getX() - 4, (int) p[1].getY() - 4, 8, 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -47,11 +47,14 @@ import forge.gui.ForgeAction;
|
|||||||
import forge.gui.SOverlayUtils;
|
import forge.gui.SOverlayUtils;
|
||||||
import forge.gui.framework.ICDoc;
|
import forge.gui.framework.ICDoc;
|
||||||
import forge.gui.framework.SLayoutIO;
|
import forge.gui.framework.SLayoutIO;
|
||||||
|
import forge.gui.match.TargetingOverlay;
|
||||||
import forge.gui.match.views.VDock;
|
import forge.gui.match.views.VDock;
|
||||||
import forge.gui.toolbox.FOverlay;
|
import forge.gui.toolbox.FOverlay;
|
||||||
import forge.gui.toolbox.SaveOpenDialog;
|
import forge.gui.toolbox.SaveOpenDialog;
|
||||||
import forge.gui.toolbox.SaveOpenDialog.Filetypes;
|
import forge.gui.toolbox.SaveOpenDialog.Filetypes;
|
||||||
import forge.item.CardPrinted;
|
import forge.item.CardPrinted;
|
||||||
|
import forge.model.FModel;
|
||||||
|
import forge.properties.ForgePreferences.FPref;
|
||||||
import forge.properties.NewConstants;
|
import forge.properties.NewConstants;
|
||||||
import forge.view.FView;
|
import forge.view.FView;
|
||||||
|
|
||||||
@@ -142,24 +145,38 @@ public enum CDock implements ICDoc {
|
|||||||
new DeckListAction(NewConstants.Lang.GuiDisplay.HUMAN_DECKLIST).actionPerformed(null);
|
new DeckListAction(NewConstants.Lang.GuiDisplay.HUMAN_DECKLIST).actionPerformed(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Attack with everyone */
|
/** Attack with everyone. */
|
||||||
public void alphaStrike() {
|
public void alphaStrike() {
|
||||||
PhaseHandler ph = Singletons.getModel().getGameState().getPhaseHandler();
|
final PhaseHandler ph = Singletons.getModel().getGameState().getPhaseHandler();
|
||||||
|
|
||||||
Player human = AllZone.getHumanPlayer();
|
final Player human = AllZone.getHumanPlayer();
|
||||||
|
|
||||||
if (ph.is(PhaseType.COMBAT_DECLARE_ATTACKERS, human)) {
|
if (ph.is(PhaseType.COMBAT_DECLARE_ATTACKERS, human)) {
|
||||||
for(Card c : human.getCardsIn(ZoneType.Battlefield).filter(Presets.CREATURES)) {
|
for (Card c : human.getCardsIn(ZoneType.Battlefield).filter(Presets.CREATURES)) {
|
||||||
if (!c.isAttacking() && CombatUtil.canAttack(c, AllZone.getCombat())) {
|
if (!c.isAttacking() && CombatUtil.canAttack(c, AllZone.getCombat())) {
|
||||||
AllZone.getCombat().addAttacker(c);
|
AllZone.getCombat().addAttacker(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//human.updateObservers();
|
//human.updateObservers();
|
||||||
|
|
||||||
// TODO Is this redrawing immediately?
|
// TODO Is this redrawing immediately?
|
||||||
FView.SINGLETON_INSTANCE.getFrame().repaint();
|
FView.SINGLETON_INSTANCE.getFrame().repaint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Toggle targeting overlay painting. */
|
||||||
|
public void toggleTargeting() {
|
||||||
|
if (Boolean.valueOf(FModel.SINGLETON_INSTANCE.getPreferences().getPref(FPref.UI_TARGETING_OVERLAY))) {
|
||||||
|
FModel.SINGLETON_INSTANCE.getPreferences().setPref(FPref.UI_TARGETING_OVERLAY, "false");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
FModel.SINGLETON_INSTANCE.getPreferences().setPref(FPref.UI_TARGETING_OVERLAY, "true");
|
||||||
|
}
|
||||||
|
|
||||||
|
FModel.SINGLETON_INSTANCE.getPreferences().save();
|
||||||
|
TargetingOverlay.SINGLETON_INSTANCE.getPanel().repaint();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receives click and programmatic requests for viewing a player's library
|
* Receives click and programmatic requests for viewing a player's library
|
||||||
* (typically used in dev mode). Allows copy of the cardlist to clipboard.
|
* (typically used in dev mode). Allows copy of the cardlist to clipboard.
|
||||||
@@ -287,6 +304,11 @@ public enum CDock implements ICDoc {
|
|||||||
.addMouseListener(new MouseAdapter() { @Override
|
.addMouseListener(new MouseAdapter() { @Override
|
||||||
public void mousePressed(final MouseEvent e) {
|
public void mousePressed(final MouseEvent e) {
|
||||||
alphaStrike(); } });
|
alphaStrike(); } });
|
||||||
|
|
||||||
|
VDock.SINGLETON_INSTANCE.getBtnTargeting()
|
||||||
|
.addMouseListener(new MouseAdapter() { @Override
|
||||||
|
public void mousePressed(final MouseEvent e) {
|
||||||
|
toggleTargeting(); } });
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ public enum VDock implements IVDoc {
|
|||||||
new DockButton(FSkin.getIcon(FSkin.DockIcons.ICO_SAVELAYOUT), "Save Layout");
|
new DockButton(FSkin.getIcon(FSkin.DockIcons.ICO_SAVELAYOUT), "Save Layout");
|
||||||
private final JLabel btnAlphaStrike =
|
private final JLabel btnAlphaStrike =
|
||||||
new DockButton(FSkin.getIcon(FSkin.DockIcons.ICO_ALPHASTRIKE), "Alpha Strike");
|
new DockButton(FSkin.getIcon(FSkin.DockIcons.ICO_ALPHASTRIKE), "Alpha Strike");
|
||||||
|
private final JLabel btnTargeting =
|
||||||
|
new DockButton(FSkin.getIcon(FSkin.DockIcons.ICO_TARGETING), "Show Targeting Arcs");
|
||||||
|
|
||||||
//========= Overridden methods
|
//========= Overridden methods
|
||||||
|
|
||||||
@@ -88,6 +90,7 @@ public enum VDock implements IVDoc {
|
|||||||
pnl.add(btnOpenLayout);
|
pnl.add(btnOpenLayout);
|
||||||
pnl.add(btnSaveLayout);
|
pnl.add(btnSaveLayout);
|
||||||
pnl.add(btnAlphaStrike);
|
pnl.add(btnAlphaStrike);
|
||||||
|
pnl.add(btnTargeting);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
@@ -172,6 +175,11 @@ public enum VDock implements IVDoc {
|
|||||||
return btnAlphaStrike;
|
return btnAlphaStrike;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return {@link javax.swing.JLabel} */
|
||||||
|
public JLabel getBtnTargeting() {
|
||||||
|
return btnTargeting;
|
||||||
|
}
|
||||||
|
|
||||||
//========= Custom class handling
|
//========= Custom class handling
|
||||||
/**
|
/**
|
||||||
* Buttons in Dock. JLabels are used to allow hover effects.
|
* Buttons in Dock. JLabels are used to allow hover effects.
|
||||||
|
|||||||
@@ -227,7 +227,8 @@ public enum FSkin {
|
|||||||
ICO_OPENLAYOUT (new int[] {0, 800, 80, 80}), /** */
|
ICO_OPENLAYOUT (new int[] {0, 800, 80, 80}), /** */
|
||||||
ICO_SAVELAYOUT (new int[] {80, 800, 80, 80}), /** */
|
ICO_SAVELAYOUT (new int[] {80, 800, 80, 80}), /** */
|
||||||
ICO_DECKLIST (new int[] {400, 640, 80, 80}), /** */
|
ICO_DECKLIST (new int[] {400, 640, 80, 80}), /** */
|
||||||
ICO_ALPHASTRIKE (new int[] {160, 800, 80, 80});
|
ICO_ALPHASTRIKE (new int[] {160, 800, 80, 80}), /** */
|
||||||
|
ICO_TARGETING (new int[] {240, 800, 80, 80});
|
||||||
|
|
||||||
private int[] coords;
|
private int[] coords;
|
||||||
/** @param xy   int[] coordinates */
|
/** @param xy   int[] coordinates */
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ public class ForgePreferences {
|
|||||||
UI_MANABURN("false"), /** */
|
UI_MANABURN("false"), /** */
|
||||||
UI_SKIN ("default"), /** */
|
UI_SKIN ("default"), /** */
|
||||||
UI_PREFERRED_AVATARS_ONLY ("false"), /** */
|
UI_PREFERRED_AVATARS_ONLY ("false"), /** */
|
||||||
|
UI_TARGETING_OVERLAY ("false"), /** */
|
||||||
|
|
||||||
SUBMENU_CURRENTMENU (EMenuItem.CONSTRUCTED.toString()), /** */
|
SUBMENU_CURRENTMENU (EMenuItem.CONSTRUCTED.toString()), /** */
|
||||||
SUBMENU_SANCTIONED ("false"), /** */
|
SUBMENU_SANCTIONED ("false"), /** */
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import forge.gui.framework.EDocID;
|
|||||||
import forge.gui.framework.SLayoutConstants;
|
import forge.gui.framework.SLayoutConstants;
|
||||||
import forge.gui.home.CMainMenu;
|
import forge.gui.home.CMainMenu;
|
||||||
import forge.gui.home.VHomeUI;
|
import forge.gui.home.VHomeUI;
|
||||||
|
import forge.gui.match.TargetingOverlay;
|
||||||
import forge.gui.match.VMatchUI;
|
import forge.gui.match.VMatchUI;
|
||||||
import forge.gui.toolbox.FOverlay;
|
import forge.gui.toolbox.FOverlay;
|
||||||
import forge.gui.toolbox.FPanel;
|
import forge.gui.toolbox.FPanel;
|
||||||
@@ -33,6 +34,9 @@ import forge.gui.toolbox.FSkin;
|
|||||||
public enum FView {
|
public enum FView {
|
||||||
/** */
|
/** */
|
||||||
SINGLETON_INSTANCE;
|
SINGLETON_INSTANCE;
|
||||||
|
|
||||||
|
/** */
|
||||||
|
public static final Integer TARGETING_LAYER = JLayeredPane.MODAL_LAYER - 1;
|
||||||
private final List<DragCell> allCells = new ArrayList<DragCell>();
|
private final List<DragCell> allCells = new ArrayList<DragCell>();
|
||||||
private SplashFrame splash;
|
private SplashFrame splash;
|
||||||
|
|
||||||
@@ -73,6 +77,10 @@ public enum FView {
|
|||||||
lpnDocument.add(pnlPreview, (Integer) 2);
|
lpnDocument.add(pnlPreview, (Integer) 2);
|
||||||
lpnDocument.add(pnlTabOverflow, (Integer) 3);
|
lpnDocument.add(pnlTabOverflow, (Integer) 3);
|
||||||
lpnDocument.add(FOverlay.SINGLETON_INSTANCE.getPanel(), JLayeredPane.MODAL_LAYER);
|
lpnDocument.add(FOverlay.SINGLETON_INSTANCE.getPanel(), JLayeredPane.MODAL_LAYER);
|
||||||
|
// Note: when adding new panels here, keep in mind that the layered pane
|
||||||
|
// has a null layout, so new components will be (0,0) - gotcha!
|
||||||
|
// FControl has a method called "sizeComponents" which will fix this.
|
||||||
|
lpnDocument.add(TargetingOverlay.SINGLETON_INSTANCE.getPanel(), TARGETING_LAYER);
|
||||||
|
|
||||||
pnlInsets.add(pnlContent, BorderLayout.CENTER);
|
pnlInsets.add(pnlContent, BorderLayout.CENTER);
|
||||||
pnlInsets.setBackgroundTexture(FSkin.getIcon(FSkin.Backgrounds.BG_TEXTURE));
|
pnlInsets.setBackgroundTexture(FSkin.getIcon(FSkin.Backgrounds.BG_TEXTURE));
|
||||||
|
|||||||
Reference in New Issue
Block a user