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/QuestWinLoseCardViewer.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/ViewWinLose.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. */
|
||||
private void sizeChildren() {
|
||||
Component[] children = display.getComponentsInLayer(JLayeredPane.DEFAULT_LAYER);
|
||||
if (children.length == 0) { return; }
|
||||
children[0].setSize(display.getSize());
|
||||
if (children.length != 0) { 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);
|
||||
if (children.length == 0) { return; }
|
||||
children[0].setSize(display.getSize());
|
||||
if (children.length != 0) { 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.framework.ICDoc;
|
||||
import forge.gui.framework.SLayoutIO;
|
||||
import forge.gui.match.TargetingOverlay;
|
||||
import forge.gui.match.views.VDock;
|
||||
import forge.gui.toolbox.FOverlay;
|
||||
import forge.gui.toolbox.SaveOpenDialog;
|
||||
import forge.gui.toolbox.SaveOpenDialog.Filetypes;
|
||||
import forge.item.CardPrinted;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.properties.NewConstants;
|
||||
import forge.view.FView;
|
||||
|
||||
@@ -141,25 +144,39 @@ public enum CDock implements ICDoc {
|
||||
private void viewDeckList() {
|
||||
new DeckListAction(NewConstants.Lang.GuiDisplay.HUMAN_DECKLIST).actionPerformed(null);
|
||||
}
|
||||
|
||||
/** Attack with everyone */
|
||||
|
||||
/** Attack with everyone. */
|
||||
public void alphaStrike() {
|
||||
PhaseHandler ph = Singletons.getModel().getGameState().getPhaseHandler();
|
||||
|
||||
Player human = AllZone.getHumanPlayer();
|
||||
|
||||
final PhaseHandler ph = Singletons.getModel().getGameState().getPhaseHandler();
|
||||
|
||||
final Player human = AllZone.getHumanPlayer();
|
||||
|
||||
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())) {
|
||||
AllZone.getCombat().addAttacker(c);
|
||||
}
|
||||
}
|
||||
//human.updateObservers();
|
||||
|
||||
// TODO Is this redrawing immediately?
|
||||
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
|
||||
* (typically used in dev mode). Allows copy of the cardlist to clipboard.
|
||||
@@ -282,11 +299,16 @@ public enum CDock implements ICDoc {
|
||||
.addMouseListener(new MouseAdapter() { @Override
|
||||
public void mousePressed(final MouseEvent e) {
|
||||
saveLayout(); } });
|
||||
|
||||
|
||||
VDock.SINGLETON_INSTANCE.getBtnAlphaStrike()
|
||||
.addMouseListener(new MouseAdapter() { @Override
|
||||
public void mousePressed(final MouseEvent e) {
|
||||
alphaStrike(); } });
|
||||
|
||||
VDock.SINGLETON_INSTANCE.getBtnTargeting()
|
||||
.addMouseListener(new MouseAdapter() { @Override
|
||||
public void mousePressed(final MouseEvent e) {
|
||||
toggleTargeting(); } });
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
@@ -67,6 +67,8 @@ public enum VDock implements IVDoc {
|
||||
new DockButton(FSkin.getIcon(FSkin.DockIcons.ICO_SAVELAYOUT), "Save Layout");
|
||||
private final JLabel btnAlphaStrike =
|
||||
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
|
||||
|
||||
@@ -88,6 +90,7 @@ public enum VDock implements IVDoc {
|
||||
pnl.add(btnOpenLayout);
|
||||
pnl.add(btnSaveLayout);
|
||||
pnl.add(btnAlphaStrike);
|
||||
pnl.add(btnTargeting);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -172,6 +175,11 @@ public enum VDock implements IVDoc {
|
||||
return btnAlphaStrike;
|
||||
}
|
||||
|
||||
/** @return {@link javax.swing.JLabel} */
|
||||
public JLabel getBtnTargeting() {
|
||||
return btnTargeting;
|
||||
}
|
||||
|
||||
//========= Custom class handling
|
||||
/**
|
||||
* 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_SAVELAYOUT (new int[] {80, 800, 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;
|
||||
/** @param xy   int[] coordinates */
|
||||
|
||||
@@ -67,6 +67,7 @@ public class ForgePreferences {
|
||||
UI_MANABURN("false"), /** */
|
||||
UI_SKIN ("default"), /** */
|
||||
UI_PREFERRED_AVATARS_ONLY ("false"), /** */
|
||||
UI_TARGETING_OVERLAY ("false"), /** */
|
||||
|
||||
SUBMENU_CURRENTMENU (EMenuItem.CONSTRUCTED.toString()), /** */
|
||||
SUBMENU_SANCTIONED ("false"), /** */
|
||||
|
||||
@@ -24,6 +24,7 @@ import forge.gui.framework.EDocID;
|
||||
import forge.gui.framework.SLayoutConstants;
|
||||
import forge.gui.home.CMainMenu;
|
||||
import forge.gui.home.VHomeUI;
|
||||
import forge.gui.match.TargetingOverlay;
|
||||
import forge.gui.match.VMatchUI;
|
||||
import forge.gui.toolbox.FOverlay;
|
||||
import forge.gui.toolbox.FPanel;
|
||||
@@ -33,6 +34,9 @@ import forge.gui.toolbox.FSkin;
|
||||
public enum FView {
|
||||
/** */
|
||||
SINGLETON_INSTANCE;
|
||||
|
||||
/** */
|
||||
public static final Integer TARGETING_LAYER = JLayeredPane.MODAL_LAYER - 1;
|
||||
private final List<DragCell> allCells = new ArrayList<DragCell>();
|
||||
private SplashFrame splash;
|
||||
|
||||
@@ -73,6 +77,10 @@ public enum FView {
|
||||
lpnDocument.add(pnlPreview, (Integer) 2);
|
||||
lpnDocument.add(pnlTabOverflow, (Integer) 3);
|
||||
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.setBackgroundTexture(FSkin.getIcon(FSkin.Backgrounds.BG_TEXTURE));
|
||||
|
||||
Reference in New Issue
Block a user