Targeting overlay implemented (experimental, for enchantments only).

Dock button and preference toggle also enabled.
This commit is contained in:
Doublestrike
2012-09-28 01:53:34 +00:00
parent e890541c2a
commit 537fbb0491
9 changed files with 212 additions and 13 deletions

1
.gitattributes vendored
View File

@@ -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

View File

@@ -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()); }
}
}

View 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
* &emsp; 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);
}
}
}
}

View File

@@ -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;
@@ -142,11 +145,11 @@ public enum CDock implements ICDoc {
new DeckListAction(NewConstants.Lang.GuiDisplay.HUMAN_DECKLIST).actionPerformed(null);
}
/** Attack with everyone */
/** Attack with everyone. */
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)) {
for (Card c : human.getCardsIn(ZoneType.Battlefield).filter(Presets.CREATURES)) {
@@ -155,11 +158,25 @@ public enum CDock implements ICDoc {
}
}
//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.
@@ -287,6 +304,11 @@ public enum CDock implements ICDoc {
.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)

View File

@@ -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.

View File

@@ -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 &emsp; int[] coordinates */

View File

@@ -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"), /** */

View File

@@ -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));