mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 11:18:01 +00:00
Compare commits
30 Commits
forge-1.5.
...
forge-1.5.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
748523f9cf | ||
|
|
e64336abe9 | ||
|
|
15450a7fba | ||
|
|
ad2f63cd8f | ||
|
|
dbd3d956fb | ||
|
|
aabb4399ed | ||
|
|
a99386ac1d | ||
|
|
b400f22d15 | ||
|
|
8843054b89 | ||
|
|
8c8bde0799 | ||
|
|
109a990b28 | ||
|
|
8e9ac2e3e7 | ||
|
|
c0ad9b1b71 | ||
|
|
01609a1f29 | ||
|
|
2f5219615d | ||
|
|
91cd93783f | ||
|
|
2d8e4e9053 | ||
|
|
9500b3a5ae | ||
|
|
84e124bbf5 | ||
|
|
0d0377ae4a | ||
|
|
9e1ec67253 | ||
|
|
4f8ee5ea52 | ||
|
|
56654ffcb1 | ||
|
|
ac48d3634b | ||
|
|
934e4cbb2c | ||
|
|
53e631d65f | ||
|
|
1483d7c969 | ||
|
|
71ddee1033 | ||
|
|
480bba7a8c | ||
|
|
9c4c529c62 |
15
.gitattributes
vendored
15
.gitattributes
vendored
@@ -14417,6 +14417,11 @@ res/skins/smith/bg_splash.png -text
|
|||||||
res/skins/smith/bg_texture.jpg -text
|
res/skins/smith/bg_texture.jpg -text
|
||||||
res/skins/smith/font1.ttf -text
|
res/skins/smith/font1.ttf -text
|
||||||
res/skins/smith/sprite_icons.png -text
|
res/skins/smith/sprite_icons.png -text
|
||||||
|
res/skins/the_dale/bg_match.jpg -text
|
||||||
|
res/skins/the_dale/bg_splash.png -text
|
||||||
|
res/skins/the_dale/bg_texture.jpg -text
|
||||||
|
res/skins/the_dale/font1.ttf -text
|
||||||
|
res/skins/the_dale/sprite_icons.png -text
|
||||||
res/skins/the_simpsons/bg_match.jpg -text
|
res/skins/the_simpsons/bg_match.jpg -text
|
||||||
res/skins/the_simpsons/bg_splash.png -text
|
res/skins/the_simpsons/bg_splash.png -text
|
||||||
res/skins/the_simpsons/bg_texture.jpg -text
|
res/skins/the_simpsons/bg_texture.jpg -text
|
||||||
@@ -15260,12 +15265,11 @@ src/main/java/forge/gui/match/views/VPicture.java -text
|
|||||||
src/main/java/forge/gui/match/views/VPlayers.java -text
|
src/main/java/forge/gui/match/views/VPlayers.java -text
|
||||||
src/main/java/forge/gui/match/views/VStack.java -text
|
src/main/java/forge/gui/match/views/VStack.java -text
|
||||||
src/main/java/forge/gui/match/views/package-info.java svneol=native#text/plain
|
src/main/java/forge/gui/match/views/package-info.java svneol=native#text/plain
|
||||||
src/main/java/forge/gui/menubar/FMenuBar.java -text
|
|
||||||
src/main/java/forge/gui/menubar/IMenuProvider.java -text
|
|
||||||
src/main/java/forge/gui/menubar/MenuUtil.java -text
|
|
||||||
src/main/java/forge/gui/menus/ForgeMenu.java -text
|
src/main/java/forge/gui/menus/ForgeMenu.java -text
|
||||||
src/main/java/forge/gui/menus/HelpMenu.java -text
|
src/main/java/forge/gui/menus/HelpMenu.java -text
|
||||||
|
src/main/java/forge/gui/menus/IMenuProvider.java -text
|
||||||
src/main/java/forge/gui/menus/LayoutMenu.java -text
|
src/main/java/forge/gui/menus/LayoutMenu.java -text
|
||||||
|
src/main/java/forge/gui/menus/MenuUtil.java -text
|
||||||
src/main/java/forge/gui/package-info.java svneol=native#text/plain
|
src/main/java/forge/gui/package-info.java svneol=native#text/plain
|
||||||
src/main/java/forge/gui/toolbox/CardFaceSymbols.java svneol=native#text/plain
|
src/main/java/forge/gui/toolbox/CardFaceSymbols.java svneol=native#text/plain
|
||||||
src/main/java/forge/gui/toolbox/FAbsolutePositioner.java -text
|
src/main/java/forge/gui/toolbox/FAbsolutePositioner.java -text
|
||||||
@@ -15408,6 +15412,7 @@ src/main/java/forge/quest/QuestUtilCards.java -text
|
|||||||
src/main/java/forge/quest/QuestUtilUnlockSets.java -text
|
src/main/java/forge/quest/QuestUtilUnlockSets.java -text
|
||||||
src/main/java/forge/quest/QuestWorld.java -text
|
src/main/java/forge/quest/QuestWorld.java -text
|
||||||
src/main/java/forge/quest/SellRules.java -text
|
src/main/java/forge/quest/SellRules.java -text
|
||||||
|
src/main/java/forge/quest/StartingPoolPreferences.java -text
|
||||||
src/main/java/forge/quest/StartingPoolType.java -text
|
src/main/java/forge/quest/StartingPoolType.java -text
|
||||||
src/main/java/forge/quest/bazaar/IQuestBazaarItem.java svneol=native#text/plain
|
src/main/java/forge/quest/bazaar/IQuestBazaarItem.java svneol=native#text/plain
|
||||||
src/main/java/forge/quest/bazaar/QuestBazaarManager.java svneol=native#text/plain
|
src/main/java/forge/quest/bazaar/QuestBazaarManager.java svneol=native#text/plain
|
||||||
@@ -15489,7 +15494,10 @@ src/main/java/forge/util/storage/StorageReaderFolder.java -text
|
|||||||
src/main/java/forge/util/storage/package-info.java -text
|
src/main/java/forge/util/storage/package-info.java -text
|
||||||
src/main/java/forge/view/ButtonUtil.java svneol=native#text/plain
|
src/main/java/forge/view/ButtonUtil.java svneol=native#text/plain
|
||||||
src/main/java/forge/view/FFrame.java -text
|
src/main/java/forge/view/FFrame.java -text
|
||||||
|
src/main/java/forge/view/FNavigationBar.java -text
|
||||||
|
src/main/java/forge/view/FStatusBar.java -text
|
||||||
src/main/java/forge/view/FTitleBar.java -text
|
src/main/java/forge/view/FTitleBar.java -text
|
||||||
|
src/main/java/forge/view/FTitleBarBase.java -text
|
||||||
src/main/java/forge/view/FView.java -text
|
src/main/java/forge/view/FView.java -text
|
||||||
src/main/java/forge/view/Main.java -text
|
src/main/java/forge/view/Main.java -text
|
||||||
src/main/java/forge/view/SplashFrame.java -text
|
src/main/java/forge/view/SplashFrame.java -text
|
||||||
@@ -15516,7 +15524,6 @@ src/test/java/forge/GuiDownloadPicturesLQTest.java svneol=native#text/plain
|
|||||||
src/test/java/forge/GuiDownloadSetPicturesLQTest.java svneol=native#text/plain
|
src/test/java/forge/GuiDownloadSetPicturesLQTest.java svneol=native#text/plain
|
||||||
src/test/java/forge/GuiProgressBarWindowTest.java svneol=native#text/plain
|
src/test/java/forge/GuiProgressBarWindowTest.java svneol=native#text/plain
|
||||||
src/test/java/forge/PanelTest.java svneol=native#text/plain
|
src/test/java/forge/PanelTest.java svneol=native#text/plain
|
||||||
src/test/java/forge/ReadDraftRankingsTest.java -text
|
|
||||||
src/test/java/forge/RunTest.java svneol=native#text/plain
|
src/test/java/forge/RunTest.java svneol=native#text/plain
|
||||||
src/test/java/forge/TinyTest.java svneol=native#text/plain
|
src/test/java/forge/TinyTest.java svneol=native#text/plain
|
||||||
src/test/java/forge/card/mana/ManaPartTest.java svneol=native#text/plain
|
src/test/java/forge/card/mana/ManaPartTest.java svneol=native#text/plain
|
||||||
|
|||||||
63
CHANGES.txt
63
CHANGES.txt
@@ -1,4 +1,4 @@
|
|||||||
Forge Beta: 10-01-2013 ver 1.5.1
|
Forge Beta: 10-04-2013 ver 1.5.2
|
||||||
|
|
||||||
|
|
||||||
13328 cards in total.
|
13328 cards in total.
|
||||||
@@ -8,14 +8,27 @@ Forge Beta: 10-01-2013 ver 1.5.1
|
|||||||
Release Notes
|
Release Notes
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
- Forge freezing during a match bug -
|
- Introducing the Forge button -
|
||||||
A number of people have reported this bug and we now feel that it may have been fixed in this version. Please play test this version and let us know.
|
The old menu bar has been removed.
|
||||||
|
The Forge button on the left side of the titlebar will drop down the same menu of options.
|
||||||
|
The Alt and Menu keys will also open this menu (even if the titlebar is hidden), with full keyboard navigation of the menus then possible.
|
||||||
|
The titlebar, minimize, maximize, and close buttons have all been increased in height to make room for the Forge button.
|
||||||
|
Menu items have been increased in height to make them more touch screen friendly. They also now enforce a minimum 100px width.
|
||||||
|
F1 has been changed to launch the Forge wiki since it no longer needs to toggle menu bar visibility.
|
||||||
|
|
||||||
|
|
||||||
- Skinned titlebar for main window -
|
- New status bar -
|
||||||
Titlebar is now skinned instead of displaying using standard OS window titlebar
|
The Forge version and digital clock have been moved to a new thin status bar to make room for the new Forge button.
|
||||||
Maximizing window now displays full-screen
|
Status messages that used to display on the right side of the old menu bar will now display in place of the version on the left side of the status bar.
|
||||||
Can use Layout > View > Titlebar (F11) to toggle visibility of titlebar (will also open full-screen if hiding titlebar)
|
F12 and Forge > Layout > View > Status Bar will allow hiding this status bar.
|
||||||
|
While status bar hidden and maximized, digital clock will display in title bar left of minimize button
|
||||||
|
Both titlebar and status bar visibility will now be remembered between sessions.
|
||||||
|
|
||||||
|
|
||||||
|
- Hidden title bar can be revealed temporarily -
|
||||||
|
If the title bar is hidden, moving the mouse to the top of the screen will now drop down the title bar until you mouse away
|
||||||
|
The title bar will appear on top of other components in this case rather than pushing anything down
|
||||||
|
The title bar will remain visible while accessing the Forge menu
|
||||||
|
|
||||||
|
|
||||||
- Forge now requires Java 7 -
|
- Forge now requires Java 7 -
|
||||||
@@ -30,36 +43,6 @@ Unfortunately, the Mac OS X builder that we were using does not support Java 7.
|
|||||||
Currently, the windows/unix release of Forge includes a launcher file named "forge.command". Double click on the "forge.command" launcher command file and this will in turn launch the Forge jar file via the terminal application while increasing the Java heap space. This should be a temporary inconvenience.
|
Currently, the windows/unix release of Forge includes a launcher file named "forge.command". Double click on the "forge.command" launcher command file and this will in turn launch the Forge jar file via the terminal application while increasing the Java heap space. This should be a temporary inconvenience.
|
||||||
|
|
||||||
|
|
||||||
---------
|
|
||||||
New Cards
|
|
||||||
---------
|
|
||||||
|
|
||||||
Chaos Moon
|
|
||||||
Deep Water
|
|
||||||
Infernal Darkness
|
|
||||||
Mana Reflection
|
|
||||||
Mausoleum Turnkey
|
|
||||||
Naked Singularity
|
|
||||||
Pale Moon
|
|
||||||
Pulse of Llanowar
|
|
||||||
Reality Twist
|
|
||||||
Ritual of Subdual
|
|
||||||
|
|
||||||
|
|
||||||
-----------
|
|
||||||
New Schemes
|
|
||||||
-----------
|
|
||||||
|
|
||||||
Nature Demands an Offering
|
|
||||||
|
|
||||||
|
|
||||||
--------------------
|
|
||||||
New Vanguard Avatars
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
Mirri
|
|
||||||
|
|
||||||
|
|
||||||
------------
|
------------
|
||||||
Known Issues
|
Known Issues
|
||||||
------------
|
------------
|
||||||
@@ -83,11 +66,13 @@ Contributors to This Release
|
|||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
DrDev
|
DrDev
|
||||||
Dripton
|
|
||||||
Gos
|
Gos
|
||||||
Hellfish
|
Juzamjedi
|
||||||
|
Marc
|
||||||
Max
|
Max
|
||||||
|
RumbleBBU
|
||||||
Sloth
|
Sloth
|
||||||
|
Sol
|
||||||
spr
|
spr
|
||||||
Swordshine
|
Swordshine
|
||||||
Chris H
|
Chris H
|
||||||
|
|||||||
10
README.txt
10
README.txt
@@ -847,6 +847,16 @@ Card overlays can be switched on/off during a match via the Game menu. Added new
|
|||||||
Forge now includes most of the new Theros cards. It may take a few days before these new card pictures become available for downloading via the "Download LQ Card Pictures" button. The LQ set pictures tend to take a few more weeks to process before they become available for downloading via the "Download LQ Set Pictures" button. Please be patient.
|
Forge now includes most of the new Theros cards. It may take a few days before these new card pictures become available for downloading via the "Download LQ Card Pictures" button. The LQ set pictures tend to take a few more weeks to process before they become available for downloading via the "Download LQ Set Pictures" button. Please be patient.
|
||||||
|
|
||||||
|
|
||||||
|
- Forge freezing during a match bug -
|
||||||
|
A number of people have reported this bug and we now feel that it may have been fixed in this version. Please play test this version and let us know.
|
||||||
|
|
||||||
|
|
||||||
|
- Skinned titlebar for main window -
|
||||||
|
Titlebar is now skinned instead of displaying using standard OS window titlebar
|
||||||
|
Maximizing window now displays full-screen
|
||||||
|
Can use Layout > View > Titlebar (F11) to toggle visibility of titlebar (will also open full-screen if hiding titlebar)
|
||||||
|
|
||||||
|
|
||||||
Our Lawyers Made Us Do This:
|
Our Lawyers Made Us Do This:
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
|
|||||||
8
pom.xml
8
pom.xml
@@ -5,7 +5,7 @@
|
|||||||
<artifactId>forge</artifactId>
|
<artifactId>forge</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<name>Forge</name>
|
<name>Forge</name>
|
||||||
<version>1.5.1</version>
|
<version>1.5.2</version>
|
||||||
<description>
|
<description>
|
||||||
Forge lets you play the card game Magic: The Gathering against a computer opponent
|
Forge lets you play the card game Magic: The Gathering against a computer opponent
|
||||||
using all of the rules.
|
using all of the rules.
|
||||||
@@ -153,9 +153,9 @@
|
|||||||
</licenses>
|
</licenses>
|
||||||
|
|
||||||
<scm>
|
<scm>
|
||||||
<connection>scm:svn:http://svn.slightlymagic.net/forge/tags/forge-1.5.1</connection>
|
<connection>scm:svn:http://svn.slightlymagic.net/forge/tags/forge-1.5.2</connection>
|
||||||
<developerConnection>scm:svn:http://svn.slightlymagic.net/forge/tags/forge-1.5.1</developerConnection>
|
<developerConnection>scm:svn:http://svn.slightlymagic.net/forge/tags/forge-1.5.2</developerConnection>
|
||||||
<url>http://svn.slightlymagic.net/websvn/listing.php/tags/forge-1.5.1?repname=forge</url>
|
<url>http://svn.slightlymagic.net/websvn/listing.php/tags/forge-1.5.2?repname=forge</url>
|
||||||
</scm>
|
</scm>
|
||||||
|
|
||||||
<prerequisites>
|
<prerequisites>
|
||||||
|
|||||||
@@ -5,6 +5,6 @@ K:CARDNAME enters the battlefield tapped.
|
|||||||
A:AB$ Mana | Cost$ T | Produced$ W U | SpellDescription$ Add W U to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ W U | SpellDescription$ Add W U to your mana pool.
|
||||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME enters the battlefield, return a land you control to its owner's hand.
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME enters the battlefield, return a land you control to its owner's hand.
|
||||||
SVar:TrigReturn:DB$ChangeZone | Origin$ Battlefield | Destination$ Hand | Cost$ 0 | Hidden$ True | Mandatory$ True | ChangeType$ Land.YouCtrl
|
SVar:TrigReturn:DB$ChangeZone | Origin$ Battlefield | Destination$ Hand | Cost$ 0 | Hidden$ True | Mandatory$ True | ChangeType$ Land.YouCtrl
|
||||||
SVar:RemAIDeck:True
|
SVar:NeedsToPlay:Land.Basic+YouCtrl
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/azorius_chancery.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/azorius_chancery.jpg
|
||||||
Oracle:Azorius Chancery enters the battlefield tapped.\nWhen Azorius Chancery enters the battlefield, return a land you control to its owner's hand.\n{T}: Add {W}{U} to your mana pool.
|
Oracle:Azorius Chancery enters the battlefield tapped.\nWhen Azorius Chancery enters the battlefield, return a land you control to its owner's hand.\n{T}: Add {W}{U} to your mana pool.
|
||||||
@@ -2,11 +2,11 @@ Name:Bloom Tender
|
|||||||
ManaCost:1 G
|
ManaCost:1 G
|
||||||
Types:Creature Elf Druid
|
Types:Creature Elf Druid
|
||||||
PT:1/1
|
PT:1/1
|
||||||
A:AB$ Mana | Cost$ T | Produced$ W | ConditionCheckSVar$ CheckW | ConditionSVarCompare$ GE1 | SubAbility$ DBManaU | SpellDescription$ For each color among permanents you control, add one mana of that color to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ W | ConditionCheckSVar$ CheckW | References$ CheckW | ConditionSVarCompare$ GE1 | SubAbility$ DBManaU | SpellDescription$ For each color among permanents you control, add one mana of that color to your mana pool.
|
||||||
SVar:DBManaU:DB$ Mana | Produced$ U | ConditionCheckSVar$ CheckU | ConditionSVarCompare$ GE1 | SubAbility$ DBManaB
|
SVar:DBManaU:DB$ Mana | Produced$ U | ConditionCheckSVar$ CheckU | References$ CheckU | ConditionSVarCompare$ GE1 | SubAbility$ DBManaB
|
||||||
SVar:DBManaB:DB$ Mana | Produced$ B | ConditionCheckSVar$ CheckB | ConditionSVarCompare$ GE1 | SubAbility$ DBManaR
|
SVar:DBManaB:DB$ Mana | Produced$ B | ConditionCheckSVar$ CheckB | References$ CheckB | ConditionSVarCompare$ GE1 | SubAbility$ DBManaR
|
||||||
SVar:DBManaR:DB$ Mana | Produced$ R | ConditionCheckSVar$ CheckR | ConditionSVarCompare$ GE1 | SubAbility$ DBManaG
|
SVar:DBManaR:DB$ Mana | Produced$ R | ConditionCheckSVar$ CheckR | References$ CheckR | ConditionSVarCompare$ GE1 | SubAbility$ DBManaG
|
||||||
SVar:DBManaG:DB$ Mana | Produced$ G | ConditionCheckSVar$ CheckG | ConditionSVarCompare$ GE1
|
SVar:DBManaG:DB$ Mana | Produced$ G | ConditionCheckSVar$ CheckG | References$ CheckG | ConditionSVarCompare$ GE1
|
||||||
SVar:CheckW:Count$Valid Permanent.YouCtrl+White
|
SVar:CheckW:Count$Valid Permanent.YouCtrl+White
|
||||||
SVar:CheckU:Count$Valid Permanent.YouCtrl+Blue
|
SVar:CheckU:Count$Valid Permanent.YouCtrl+Blue
|
||||||
SVar:CheckB:Count$Valid Permanent.YouCtrl+Black
|
SVar:CheckB:Count$Valid Permanent.YouCtrl+Black
|
||||||
|
|||||||
@@ -5,6 +5,6 @@ K:CARDNAME enters the battlefield tapped.
|
|||||||
A:AB$ Mana | Cost$ T | Produced$ R W | SpellDescription$ Add R W to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ R W | SpellDescription$ Add R W to your mana pool.
|
||||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME enters the battlefield, return a land you control to its owner's hand.
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME enters the battlefield, return a land you control to its owner's hand.
|
||||||
SVar:TrigReturn:DB$ChangeZone | Origin$ Battlefield | Destination$ Hand | Cost$ 0 | Hidden$ True | Mandatory$ True | ChangeType$ Land.YouCtrl
|
SVar:TrigReturn:DB$ChangeZone | Origin$ Battlefield | Destination$ Hand | Cost$ 0 | Hidden$ True | Mandatory$ True | ChangeType$ Land.YouCtrl
|
||||||
SVar:RemAIDeck:True
|
SVar:NeedsToPlay:Land.Basic+YouCtrl
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/boros_garrison.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/boros_garrison.jpg
|
||||||
Oracle:Boros Garrison enters the battlefield tapped.\nWhen Boros Garrison enters the battlefield, return a land you control to its owner's hand.\n{T}: Add {R}{W} to your mana pool.
|
Oracle:Boros Garrison enters the battlefield tapped.\nWhen Boros Garrison enters the battlefield, return a land you control to its owner's hand.\n{T}: Add {R}{W} to your mana pool.
|
||||||
@@ -2,5 +2,5 @@ Name:Boulderfall
|
|||||||
ManaCost:6 R R
|
ManaCost:6 R R
|
||||||
Types:Instant
|
Types:Instant
|
||||||
A:SP$ DealDamage | Cost$ 6 R R | ValidTgts$ Creature,Player | TgtPrompt$ Select target creature or player to distribute damage to | NumDmg$ 5 | TargetMin$ 1 | TargetMax$ 5 | DividedAsYouChoose$ 5 | SpellDescription$ CARDNAME deals 5 damage divided as you choose among any number of target creatures and/or players.
|
A:SP$ DealDamage | Cost$ 6 R R | ValidTgts$ Creature,Player | TgtPrompt$ Select target creature or player to distribute damage to | NumDmg$ 5 | TargetMin$ 1 | TargetMax$ 5 | DividedAsYouChoose$ 5 | SpellDescription$ CARDNAME deals 5 damage divided as you choose among any number of target creatures and/or players.
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/boulderfal.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/boulderfall.jpg
|
||||||
Oracle:Boulderfall deals 5 damage divided as you choose among any number of target creatures and/or players.
|
Oracle:Boulderfall deals 5 damage divided as you choose among any number of target creatures and/or players.
|
||||||
@@ -5,6 +5,6 @@ K:CARDNAME enters the battlefield tapped.
|
|||||||
A:AB$ Mana | Cost$ T | Produced$ U B | SpellDescription$ Add U B to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ U B | SpellDescription$ Add U B to your mana pool.
|
||||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME enters the battlefield, return a land you control to its owner's hand.
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME enters the battlefield, return a land you control to its owner's hand.
|
||||||
SVar:TrigReturn:AB$ChangeZone | Origin$ Battlefield | Destination$ Hand | Cost$ 0 | Hidden$ True | Mandatory$ True | ChangeType$ Land.YouCtrl
|
SVar:TrigReturn:AB$ChangeZone | Origin$ Battlefield | Destination$ Hand | Cost$ 0 | Hidden$ True | Mandatory$ True | ChangeType$ Land.YouCtrl
|
||||||
SVar:RemAIDeck:True
|
SVar:NeedsToPlay:Land.Basic+YouCtrl
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/dimir_aqueduct.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/dimir_aqueduct.jpg
|
||||||
Oracle:Dimir Aqueduct enters the battlefield tapped.\nWhen Dimir Aqueduct enters the battlefield, return a land you control to its owner's hand.\n{T}: Add {U}{B} to your mana pool.
|
Oracle:Dimir Aqueduct enters the battlefield tapped.\nWhen Dimir Aqueduct enters the battlefield, return a land you control to its owner's hand.\n{T}: Add {U}{B} to your mana pool.
|
||||||
@@ -5,6 +5,6 @@ K:CARDNAME enters the battlefield tapped.
|
|||||||
A:AB$ Mana | Cost$ T | Produced$ B G | SpellDescription$ Add B G to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ B G | SpellDescription$ Add B G to your mana pool.
|
||||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME enters the battlefield, return a land you control to its owner's hand.
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME enters the battlefield, return a land you control to its owner's hand.
|
||||||
SVar:TrigReturn:AB$ChangeZone | Origin$ Battlefield | Destination$ Hand | Cost$ 0 | Hidden$ True | Mandatory$ True | ChangeType$ Land.YouCtrl
|
SVar:TrigReturn:AB$ChangeZone | Origin$ Battlefield | Destination$ Hand | Cost$ 0 | Hidden$ True | Mandatory$ True | ChangeType$ Land.YouCtrl
|
||||||
SVar:RemAIDeck:True
|
SVar:NeedsToPlay:Land.Basic+YouCtrl
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/golgari_rot_farm.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/golgari_rot_farm.jpg
|
||||||
Oracle:Golgari Rot Farm enters the battlefield tapped.\nWhen Golgari Rot Farm enters the battlefield, return a land you control to its owner's hand.\n{T}: Add {B}{G} to your mana pool.
|
Oracle:Golgari Rot Farm enters the battlefield tapped.\nWhen Golgari Rot Farm enters the battlefield, return a land you control to its owner's hand.\n{T}: Add {B}{G} to your mana pool.
|
||||||
@@ -5,6 +5,6 @@ K:CARDNAME enters the battlefield tapped.
|
|||||||
A:AB$ Mana | Cost$ T | Produced$ R G | SpellDescription$ Add R G to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ R G | SpellDescription$ Add R G to your mana pool.
|
||||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME enters the battlefield, return a land you control to its owner's hand.
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME enters the battlefield, return a land you control to its owner's hand.
|
||||||
SVar:TrigReturn:AB$ChangeZone | Origin$ Battlefield | Destination$ Hand | Cost$ 0 | Hidden$ True | Mandatory$ True | ChangeType$ Land.YouCtrl
|
SVar:TrigReturn:AB$ChangeZone | Origin$ Battlefield | Destination$ Hand | Cost$ 0 | Hidden$ True | Mandatory$ True | ChangeType$ Land.YouCtrl
|
||||||
SVar:RemAIDeck:True
|
SVar:NeedsToPlay:Land.Basic+YouCtrl
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/gruul_turf.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/gruul_turf.jpg
|
||||||
Oracle:Gruul Turf enters the battlefield tapped.\nWhen Gruul Turf enters the battlefield, return a land you control to its owner's hand.\n{T}: Add {R}{G} to your mana pool.
|
Oracle:Gruul Turf enters the battlefield tapped.\nWhen Gruul Turf enters the battlefield, return a land you control to its owner's hand.\n{T}: Add {R}{G} to your mana pool.
|
||||||
@@ -5,6 +5,6 @@ K:CARDNAME enters the battlefield tapped.
|
|||||||
A:AB$ Mana | Cost$ T | Produced$ U R | SpellDescription$ Add U R to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ U R | SpellDescription$ Add U R to your mana pool.
|
||||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME enters the battlefield, return a land you control to its owner's hand.
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME enters the battlefield, return a land you control to its owner's hand.
|
||||||
SVar:TrigReturn:AB$ChangeZone | Origin$ Battlefield | Destination$ Hand | Cost$ 0 | Hidden$ True | Mandatory$ True | ChangeType$ Land.YouCtrl
|
SVar:TrigReturn:AB$ChangeZone | Origin$ Battlefield | Destination$ Hand | Cost$ 0 | Hidden$ True | Mandatory$ True | ChangeType$ Land.YouCtrl
|
||||||
SVar:RemAIDeck:True
|
SVar:NeedsToPlay:Land.Basic+YouCtrl
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/izzet_boilerworks.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/izzet_boilerworks.jpg
|
||||||
Oracle:Izzet Boilerworks enters the battlefield tapped.\nWhen Izzet Boilerworks enters the battlefield, return a land you control to its owner's hand.\n{T}: Add {U}{R} to your mana pool.
|
Oracle:Izzet Boilerworks enters the battlefield tapped.\nWhen Izzet Boilerworks enters the battlefield, return a land you control to its owner's hand.\n{T}: Add {U}{R} to your mana pool.
|
||||||
@@ -2,7 +2,7 @@ Name:Nest Invader
|
|||||||
ManaCost:1 G
|
ManaCost:1 G
|
||||||
Types:Creature Eldrazi Drone
|
Types:Creature Eldrazi Drone
|
||||||
PT:2/2
|
PT:2/2
|
||||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, put a 0/1 colorless Eldrazi Spawn creature tokens onto the battlefield. They have "Sacrifice this creature: Add 1 to your mana pool."
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, put a 0/1 colorless Eldrazi Spawn creature tokens onto the battlefield. It has "Sacrifice this creature: Add 1 to your mana pool."
|
||||||
SVar:TrigToken:AB$Token | Cost$ 0 | TokenAmount$ 1 | TokenName$ Eldrazi Spawn | TokenTypes$ Creature,Eldrazi,Spawn | TokenOwner$ You | TokenColors$ Colorless | TokenPower$ 0 | TokenToughness$ 1 | TokenAbilities$ ABMana
|
SVar:TrigToken:AB$Token | Cost$ 0 | TokenAmount$ 1 | TokenName$ Eldrazi Spawn | TokenTypes$ Creature,Eldrazi,Spawn | TokenOwner$ You | TokenColors$ Colorless | TokenPower$ 0 | TokenToughness$ 1 | TokenAbilities$ ABMana
|
||||||
SVar:ABMana:AB$Mana | Cost$ Sac<1/CARDNAME> | Produced$ 1 | Amount$ 1 | SpellDescription$ Add 1 to your mana pool.
|
SVar:ABMana:AB$Mana | Cost$ Sac<1/CARDNAME> | Produced$ 1 | Amount$ 1 | SpellDescription$ Add 1 to your mana pool.
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/nest_invader.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/nest_invader.jpg
|
||||||
|
|||||||
@@ -5,6 +5,6 @@ K:CARDNAME enters the battlefield tapped.
|
|||||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME enters the battlefield, return a land you control to its owner's hand.
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME enters the battlefield, return a land you control to its owner's hand.
|
||||||
SVar:TrigReturn:AB$ChangeZone | Origin$ Battlefield | Destination$ Hand | Cost$ 0 | Hidden$ True | Mandatory$ True | ChangeType$ Land.YouCtrl
|
SVar:TrigReturn:AB$ChangeZone | Origin$ Battlefield | Destination$ Hand | Cost$ 0 | Hidden$ True | Mandatory$ True | ChangeType$ Land.YouCtrl
|
||||||
A:AB$ Mana | Cost$ T | Produced$ W B | SpellDescription$ Add W B to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ W B | SpellDescription$ Add W B to your mana pool.
|
||||||
SVar:RemAIDeck:True
|
SVar:NeedsToPlay:Land.Basic+YouCtrl
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/orzhov_basilica.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/orzhov_basilica.jpg
|
||||||
Oracle:Orzhov Basilica enters the battlefield tapped.\nWhen Orzhov Basilica enters the battlefield, return a land you control to its owner's hand.\n{T}: Add {W}{B} to your mana pool.
|
Oracle:Orzhov Basilica enters the battlefield tapped.\nWhen Orzhov Basilica enters the battlefield, return a land you control to its owner's hand.\n{T}: Add {W}{B} to your mana pool.
|
||||||
@@ -5,6 +5,6 @@ K:CARDNAME enters the battlefield tapped.
|
|||||||
A:AB$ Mana | Cost$ T | Produced$ B R | SpellDescription$ Add B R to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ B R | SpellDescription$ Add B R to your mana pool.
|
||||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME enters the battlefield, return a land you control to its owner's hand.
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME enters the battlefield, return a land you control to its owner's hand.
|
||||||
SVar:TrigReturn:AB$ChangeZone | Origin$ Battlefield | Destination$ Hand | Cost$ 0 | Hidden$ True | Mandatory$ True | ChangeType$ Land.YouCtrl
|
SVar:TrigReturn:AB$ChangeZone | Origin$ Battlefield | Destination$ Hand | Cost$ 0 | Hidden$ True | Mandatory$ True | ChangeType$ Land.YouCtrl
|
||||||
SVar:RemAIDeck:True
|
SVar:NeedsToPlay:Land.Basic+YouCtrl
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/rakdos_carnarium.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/rakdos_carnarium.jpg
|
||||||
Oracle:Rakdos Carnarium enters the battlefield tapped.\nWhen Rakdos Carnarium enters the battlefield, return a land you control to its owner's hand.\n{T}: Add {B}{R} to your mana pool.
|
Oracle:Rakdos Carnarium enters the battlefield tapped.\nWhen Rakdos Carnarium enters the battlefield, return a land you control to its owner's hand.\n{T}: Add {B}{R} to your mana pool.
|
||||||
@@ -2,7 +2,7 @@ Name:Scroll Rack
|
|||||||
ManaCost:2
|
ManaCost:2
|
||||||
Types:Artifact
|
Types:Artifact
|
||||||
A:AB$ ChangeZone | Cost$ 1 T | Origin$ Hand | Destination$ Exile | ChangeType$ Card | ChangeNum$ XFetch | References$ XFetch | RememberChanged$ True | SubAbility$ DBDig | SpellDescription$ Exile any number of cards from your hand face down. Put that many cards from the top of your library into your hand. Then look at the exiled cards and put them on top of your library in any order. | StackDescription$ SpellDescription
|
A:AB$ ChangeZone | Cost$ 1 T | Origin$ Hand | Destination$ Exile | ChangeType$ Card | ChangeNum$ XFetch | References$ XFetch | RememberChanged$ True | SubAbility$ DBDig | SpellDescription$ Exile any number of cards from your hand face down. Put that many cards from the top of your library into your hand. Then look at the exiled cards and put them on top of your library in any order. | StackDescription$ SpellDescription
|
||||||
SVar:DBDig:DB$ Dig | DigNum$ X | Reveal$ True | ChangeNum$ All | ChangeValid$ Card | DestinationZone$ Hand | SubAbility$ DBReplace
|
SVar:DBDig:DB$ Dig | DigNum$ X | References$ X | Reveal$ True | ChangeNum$ All | ChangeValid$ Card | DestinationZone$ Hand | SubAbility$ DBReplace
|
||||||
SVar:DBReplace:DB$ ChangeZoneAll | Origin$ Exile | Destination$ Library | ChangeType$ Card.IsRemembered | SubAbility$ DBCleanup
|
SVar:DBReplace:DB$ ChangeZoneAll | Origin$ Exile | Destination$ Library | ChangeType$ Card.IsRemembered | SubAbility$ DBCleanup
|
||||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
SVar:XFetch:Count$InYourHand
|
SVar:XFetch:Count$InYourHand
|
||||||
|
|||||||
@@ -5,6 +5,6 @@ K:CARDNAME enters the battlefield tapped.
|
|||||||
A:AB$ Mana | Cost$ T | Produced$ G W | SpellDescription$ Add G W to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ G W | SpellDescription$ Add G W to your mana pool.
|
||||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME enters the battlefield, return a land you control to its owner's hand.
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME enters the battlefield, return a land you control to its owner's hand.
|
||||||
SVar:TrigReturn:AB$ChangeZone | Origin$ Battlefield | Destination$ Hand | Cost$ 0 | Hidden$ True | Mandatory$ True | ChangeType$ Land.YouCtrl
|
SVar:TrigReturn:AB$ChangeZone | Origin$ Battlefield | Destination$ Hand | Cost$ 0 | Hidden$ True | Mandatory$ True | ChangeType$ Land.YouCtrl
|
||||||
SVar:RemAIDeck:True
|
SVar:NeedsToPlay:Land.Basic+YouCtrl
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/selesnya_sanctuary.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/selesnya_sanctuary.jpg
|
||||||
Oracle:Selesnya Sanctuary enters the battlefield tapped.\nWhen Selesnya Sanctuary enters the battlefield, return a land you control to its owner's hand.\n{T}: Add {G}{W} to your mana pool.
|
Oracle:Selesnya Sanctuary enters the battlefield tapped.\nWhen Selesnya Sanctuary enters the battlefield, return a land you control to its owner's hand.\n{T}: Add {G}{W} to your mana pool.
|
||||||
@@ -5,6 +5,6 @@ K:CARDNAME enters the battlefield tapped.
|
|||||||
A:AB$ Mana | Cost$ T | Produced$ G U | SpellDescription$ Add G U to your mana pool.
|
A:AB$ Mana | Cost$ T | Produced$ G U | SpellDescription$ Add G U to your mana pool.
|
||||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME enters the battlefield, return a land you control to its owner's hand.
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME enters the battlefield, return a land you control to its owner's hand.
|
||||||
SVar:TrigReturn:AB$ChangeZone | Origin$ Battlefield | Destination$ Hand | Cost$ 0 | Hidden$ True | Mandatory$ True | ChangeType$ Land.YouCtrl
|
SVar:TrigReturn:AB$ChangeZone | Origin$ Battlefield | Destination$ Hand | Cost$ 0 | Hidden$ True | Mandatory$ True | ChangeType$ Land.YouCtrl
|
||||||
SVar:RemAIDeck:True
|
SVar:NeedsToPlay:Land.Basic+YouCtrl
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/simic_growth_chamber.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/simic_growth_chamber.jpg
|
||||||
Oracle:Simic Growth Chamber enters the battlefield tapped.\nWhen Simic Growth Chamber enters the battlefield, return a land you control to its owner's hand.\n{T}: Add {G}{U} to your mana pool.
|
Oracle:Simic Growth Chamber enters the battlefield tapped.\nWhen Simic Growth Chamber enters the battlefield, return a land you control to its owner's hand.\n{T}: Add {G}{U} to your mana pool.
|
||||||
@@ -3,5 +3,5 @@ ManaCost:5 U
|
|||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ Draw | Cost$ 5 U | NumCards$ 3 | SubAbility$ DB | SpellDescription$ Draw three cards. Target player puts the top three cards of his or her library into his or her graveyard.
|
A:SP$ Draw | Cost$ 5 U | NumCards$ 3 | SubAbility$ DB | SpellDescription$ Draw three cards. Target player puts the top three cards of his or her library into his or her graveyard.
|
||||||
SVar:DB:DB$ Mill | Cost$ 0 | NumCards$ 3 | ValidTgts$ Player | TgtPrompt$ Choose target player
|
SVar:DB:DB$ Mill | Cost$ 0 | NumCards$ 3 | ValidTgts$ Player | TgtPrompt$ Choose target player
|
||||||
SVar:Picture:http://serv4.tcgimages.eu/img/cards/Portal_Second_Age/thassas_bounty.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/thassas_bounty.jpg
|
||||||
Oracle:Draw three cards. Target player puts the top three cards of his or her library into his or her graveyard.
|
Oracle:Draw three cards. Target player puts the top three cards of his or her library into his or her graveyard.
|
||||||
@@ -1,15 +1,17 @@
|
|||||||
[metadata]
|
[metadata]
|
||||||
Name=JuzamjediCube
|
Name=JuzamjediCube
|
||||||
[Main]
|
[Main]
|
||||||
1 Abrupt Decay|RTR
|
|
||||||
1 Abyssal Persecutor|WWK
|
1 Abyssal Persecutor|WWK
|
||||||
1 Accorder Paladin|MBS
|
1 Accorder Paladin|MBS
|
||||||
1 Acidic Slime|M11
|
1 Acidic Slime|M11
|
||||||
1 AEther Adept|M11
|
1 AEther Adept|M11
|
||||||
|
1 AEtherling|DGM
|
||||||
1 Ajani Goldmane|M10
|
1 Ajani Goldmane|M10
|
||||||
|
1 Ajani Vengeant|ALA
|
||||||
1 Ajani, Caller of the Pride|M13
|
1 Ajani, Caller of the Pride|M13
|
||||||
1 Ancestral Recall|2ED
|
1 Ancestral Recall|2ED
|
||||||
1 Ancestral Vision|TSP
|
1 Ancestral Vision|TSP
|
||||||
|
1 Ancient Tomb|TMP
|
||||||
1 Angel of Serenity|RTR
|
1 Angel of Serenity|RTR
|
||||||
1 Animate Dead|4ED
|
1 Animate Dead|4ED
|
||||||
1 Ankh of Mishra|4ED
|
1 Ankh of Mishra|4ED
|
||||||
@@ -20,15 +22,15 @@ Name=JuzamjediCube
|
|||||||
1 Armageddon|S99
|
1 Armageddon|S99
|
||||||
1 Arrogant Bloodlord|ROE
|
1 Arrogant Bloodlord|ROE
|
||||||
1 Ash Zealot|RTR
|
1 Ash Zealot|RTR
|
||||||
1 Augur of Bolas|M13
|
1 Ashiok, Nightmare Weaver|THS
|
||||||
1 Avalanche Riders|ULG
|
1 Avalanche Riders|ULG
|
||||||
1 Azorius Arrester|RTR
|
|
||||||
1 Badlands|3ED
|
1 Badlands|3ED
|
||||||
|
1 Balance|4ED
|
||||||
1 Baleful Strix|PC2
|
1 Baleful Strix|PC2
|
||||||
1 Ball Lightning|DRK
|
1 Ball Lightning|DRK
|
||||||
1 Bane of the Living|LGN
|
1 Bane of the Living|LGN
|
||||||
1 Banefire|CFX
|
|
||||||
1 Baneslayer Angel|M11
|
1 Baneslayer Angel|M11
|
||||||
|
1 Banisher Priest|M14
|
||||||
1 Batterskull|NPH
|
1 Batterskull|NPH
|
||||||
1 Battlefield Forge|10E
|
1 Battlefield Forge|10E
|
||||||
1 Bayou|3ED
|
1 Bayou|3ED
|
||||||
@@ -40,7 +42,6 @@ Name=JuzamjediCube
|
|||||||
1 Black Vise|4ED
|
1 Black Vise|4ED
|
||||||
1 Blade of the Sixth Pride|FUT
|
1 Blade of the Sixth Pride|FUT
|
||||||
1 Blade Splicer|NPH
|
1 Blade Splicer|NPH
|
||||||
1 Blastoderm|NMS
|
|
||||||
1 Blightning|ALA
|
1 Blightning|ALA
|
||||||
1 Blistering Firecat|ONS
|
1 Blistering Firecat|ONS
|
||||||
1 Blood Crypt|DIS
|
1 Blood Crypt|DIS
|
||||||
@@ -53,7 +54,7 @@ Name=JuzamjediCube
|
|||||||
1 Bone Shredder|ULG
|
1 Bone Shredder|ULG
|
||||||
1 Bonesplitter|MRD
|
1 Bonesplitter|MRD
|
||||||
1 Bonfire of the Damned|AVR
|
1 Bonfire of the Damned|AVR
|
||||||
1 Boros Charm|GTC
|
1 Boon Satyr|THS
|
||||||
1 Boros Reckoner|GTC
|
1 Boros Reckoner|GTC
|
||||||
1 Brainstorm|ICE
|
1 Brainstorm|ICE
|
||||||
1 Bramblecrush|ISD
|
1 Bramblecrush|ISD
|
||||||
@@ -61,12 +62,15 @@ Name=JuzamjediCube
|
|||||||
1 Bribery|8ED
|
1 Bribery|8ED
|
||||||
1 Brimstone Volley|ISD
|
1 Brimstone Volley|ISD
|
||||||
1 Burst Lightning|ZEN
|
1 Burst Lightning|ZEN
|
||||||
|
1 Catastrophe|USG
|
||||||
1 Caves of Koilos|10E
|
1 Caves of Koilos|10E
|
||||||
1 Celestial Colonnade|WWK
|
1 Celestial Colonnade|WWK
|
||||||
|
1 Chain Lightning|LEG
|
||||||
1 Chainer's Edict|TOR
|
1 Chainer's Edict|TOR
|
||||||
1 Chameleon Colossus|MOR
|
1 Chameleon Colossus|MOR
|
||||||
1 Chandra Nalaar|M11
|
1 Chandra Nalaar|M11
|
||||||
1 Chandra's Phoenix|M12
|
1 Chandra's Phoenix|M12
|
||||||
|
1 Chandra, Pyromaster|M14
|
||||||
1 Char|RAV
|
1 Char|RAV
|
||||||
1 Chromatic Lantern|RTR
|
1 Chromatic Lantern|RTR
|
||||||
1 Chrome Mox|MRD
|
1 Chrome Mox|MRD
|
||||||
@@ -74,16 +78,17 @@ Name=JuzamjediCube
|
|||||||
1 Cloistered Youth|ISD
|
1 Cloistered Youth|ISD
|
||||||
1 Cloudgoat Ranger|LRW
|
1 Cloudgoat Ranger|LRW
|
||||||
1 Coalition Relic|FUT
|
1 Coalition Relic|FUT
|
||||||
|
1 Coldsteel Heart|CSP
|
||||||
1 Compulsive Research|RAV
|
1 Compulsive Research|RAV
|
||||||
1 Condescend|5DN
|
1 Condescend|5DN
|
||||||
1 Consecrated Sphinx|MBS
|
1 Consecrated Sphinx|MBS
|
||||||
1 Consuming Vapors|ROE
|
1 Consuming Vapors|ROE
|
||||||
1 Control Magic|4ED
|
1 Control Magic|4ED
|
||||||
1 Counterspell|7ED
|
1 Counterspell|7ED
|
||||||
|
1 Craterhoof Behemoth|AVR
|
||||||
1 Creeping Tar Pit|WWK
|
1 Creeping Tar Pit|WWK
|
||||||
1 Crucible of Worlds|5DN
|
1 Crucible of Worlds|5DN
|
||||||
1 Cryptic Command|LRW
|
1 Cryptic Command|LRW
|
||||||
1 Crystal Shard|MRD
|
|
||||||
1 Cultivate|M11
|
1 Cultivate|M11
|
||||||
1 Cursed Scroll|TMP
|
1 Cursed Scroll|TMP
|
||||||
1 Cyclonic Rift|RTR
|
1 Cyclonic Rift|RTR
|
||||||
@@ -93,18 +98,17 @@ Name=JuzamjediCube
|
|||||||
1 Dark Ritual|4ED
|
1 Dark Ritual|4ED
|
||||||
1 Day of Judgment|M11
|
1 Day of Judgment|M11
|
||||||
1 Daze|NMS
|
1 Daze|NMS
|
||||||
1 Deadbridge Goliath|RTR
|
|
||||||
1 Deathrite Shaman|RTR
|
1 Deathrite Shaman|RTR
|
||||||
1 Delver of Secrets|ISD
|
1 Deep Analysis|TOR
|
||||||
1 Demonic Tutor|3ED
|
1 Demonic Tutor|3ED
|
||||||
1 Deranged Hermit|ULG
|
1 Deranged Hermit|ULG
|
||||||
1 Detention Sphere|RTR
|
1 Detention Sphere|RTR
|
||||||
|
1 Devil's Play|DDK
|
||||||
1 Diabolic Edict|TMP
|
1 Diabolic Edict|TMP
|
||||||
1 Diabolic Servitude|USG
|
1 Diabolic Servitude|USG
|
||||||
1 Disciple of Bolas|M13
|
1 Disciple of Bolas|M13
|
||||||
1 Disenchant|6ED
|
1 Disenchant|6ED
|
||||||
1 Dismember|NPH
|
1 Dismember|NPH
|
||||||
1 Domri Rade|GTC
|
|
||||||
1 Doom Blade|M11
|
1 Doom Blade|M11
|
||||||
1 Drana, Kalastria Bloodchief|ROE
|
1 Drana, Kalastria Bloodchief|ROE
|
||||||
1 Dreadbore|RTR
|
1 Dreadbore|RTR
|
||||||
@@ -112,15 +116,15 @@ Name=JuzamjediCube
|
|||||||
1 Duplicant|MRD
|
1 Duplicant|MRD
|
||||||
1 Duress|M11
|
1 Duress|M11
|
||||||
1 Duskmantle Seer|GTC
|
1 Duskmantle Seer|GTC
|
||||||
1 Earthquake|PO2
|
|
||||||
1 Electrolyze|GPT
|
1 Electrolyze|GPT
|
||||||
1 Elesh Norn, Grand Cenobite|NPH
|
1 Elesh Norn, Grand Cenobite|NPH
|
||||||
1 Elite Vanguard|M11
|
1 Elite Vanguard|M11
|
||||||
1 Elspeth, Knight-Errant|ALA
|
1 Elspeth, Knight-Errant|ALA
|
||||||
|
1 Elspeth, Sun's Champion|THS
|
||||||
|
1 Elvish Mystic|M14
|
||||||
1 Enclave Cryptologist|ROE
|
1 Enclave Cryptologist|ROE
|
||||||
1 Enlightened Tutor|6ED
|
1 Enlightened Tutor|6ED
|
||||||
1 Entomb|ODY
|
1 Entomb|ODY
|
||||||
1 Erratic Portal|EXO
|
|
||||||
1 Eternal Dragon|SCG
|
1 Eternal Dragon|SCG
|
||||||
1 Eternal Witness|5DN
|
1 Eternal Witness|5DN
|
||||||
1 Everflowing Chalice|WWK
|
1 Everflowing Chalice|WWK
|
||||||
@@ -131,14 +135,15 @@ Name=JuzamjediCube
|
|||||||
1 Fact or Fiction|INV
|
1 Fact or Fiction|INV
|
||||||
1 Faith's Fetters|RAV
|
1 Faith's Fetters|RAV
|
||||||
1 Faithless Looting|DKA
|
1 Faithless Looting|DKA
|
||||||
1 Far // Away|DGM
|
|
||||||
1 Farseek|M13
|
1 Farseek|M13
|
||||||
1 Fauna Shaman|M11
|
1 Fauna Shaman|M11
|
||||||
1 Fettergeist|AVR
|
1 Fettergeist|AVR
|
||||||
|
1 Fiend Hunter|DDK
|
||||||
1 Figure of Destiny|EVE
|
1 Figure of Destiny|EVE
|
||||||
1 Fire Imp|POR
|
1 Fire Imp|POR
|
||||||
1 Fireblast|VIS
|
1 Fireblast|VIS
|
||||||
1 Firebolt|ODY
|
1 Firebolt|ODY
|
||||||
|
1 Firedrinker Satyr|THS
|
||||||
1 Flagstones of Trokair|TSP
|
1 Flagstones of Trokair|TSP
|
||||||
1 Flames of the Firebrand|M13
|
1 Flames of the Firebrand|M13
|
||||||
1 Flametongue Kavu|PLS
|
1 Flametongue Kavu|PLS
|
||||||
@@ -154,17 +159,20 @@ Name=JuzamjediCube
|
|||||||
1 Fyndhorn Elves|ICE
|
1 Fyndhorn Elves|ICE
|
||||||
1 Garruk Relentless|ISD
|
1 Garruk Relentless|ISD
|
||||||
1 Garruk Wildspeaker|M11
|
1 Garruk Wildspeaker|M11
|
||||||
|
1 Garruk, Caller of Beasts|M14
|
||||||
1 Garruk, Primal Hunter|M12
|
1 Garruk, Primal Hunter|M12
|
||||||
1 Geist of Saint Traft|ISD
|
1 Geist of Saint Traft|ISD
|
||||||
|
1 Gemstone Mine|WTH
|
||||||
1 Genesis|JUD
|
1 Genesis|JUD
|
||||||
1 Ghastly Demise|ODY
|
1 Ghastly Demise|ODY
|
||||||
1 Ghor-Clan Rampager|GTC
|
1 Ghor-Clan Rampager|GTC
|
||||||
1 Gideon Jura|ROE
|
1 Gideon Jura|ROE
|
||||||
1 Gideon, Champion of Justice|GTC
|
1 Gifts Ungiven|MMA
|
||||||
|
1 Gilded Drake|USG
|
||||||
1 Glen Elendra Archmage|EVE
|
1 Glen Elendra Archmage|EVE
|
||||||
1 Glorious Anthem|USG
|
|
||||||
1 Go for the Throat|MBS
|
1 Go for the Throat|MBS
|
||||||
1 Goblin Guide|ZEN
|
1 Goblin Guide|ZEN
|
||||||
|
1 Goblin Welder|ULG
|
||||||
1 Godless Shrine|GPT
|
1 Godless Shrine|GPT
|
||||||
1 Gore-House Chainwalker|RTR
|
1 Gore-House Chainwalker|RTR
|
||||||
1 Grafted Wargear|5DN
|
1 Grafted Wargear|5DN
|
||||||
@@ -188,6 +196,7 @@ Name=JuzamjediCube
|
|||||||
1 Hellspark Elemental|CFX
|
1 Hellspark Elemental|CFX
|
||||||
1 Hero of Bladehold|MBS
|
1 Hero of Bladehold|MBS
|
||||||
1 Hero of Oxid Ridge|MBS
|
1 Hero of Oxid Ridge|MBS
|
||||||
|
1 Hero's Downfall|THS
|
||||||
1 High Priest of Penance|GTC
|
1 High Priest of Penance|GTC
|
||||||
1 Hinterland Harbor|ISD
|
1 Hinterland Harbor|ISD
|
||||||
1 Horizon Canopy|FUT
|
1 Horizon Canopy|FUT
|
||||||
@@ -195,6 +204,7 @@ Name=JuzamjediCube
|
|||||||
1 Hymn to Tourach|FEM
|
1 Hymn to Tourach|FEM
|
||||||
1 Hypnotic Specter|M10
|
1 Hypnotic Specter|M10
|
||||||
1 Icy Manipulator|ICE
|
1 Icy Manipulator|ICE
|
||||||
|
1 Imposing Sovereign|M14
|
||||||
1 Impulse|VIS
|
1 Impulse|VIS
|
||||||
1 Incinerate|10E
|
1 Incinerate|10E
|
||||||
1 Indrik Stomphowler|DIS
|
1 Indrik Stomphowler|DIS
|
||||||
@@ -211,26 +221,31 @@ Name=JuzamjediCube
|
|||||||
1 Joraga Treespeaker|ROE
|
1 Joraga Treespeaker|ROE
|
||||||
1 Journey to Nowhere|ZEN
|
1 Journey to Nowhere|ZEN
|
||||||
1 Jungle Lion|POR
|
1 Jungle Lion|POR
|
||||||
|
1 Kalonian Hydra|M14
|
||||||
1 Kargan Dragonlord|ROE
|
1 Kargan Dragonlord|ROE
|
||||||
|
1 Karmic Guide|ULG
|
||||||
1 Karn Liberated|NPH
|
1 Karn Liberated|NPH
|
||||||
1 Keiga, the Tide Star|CHK
|
|
||||||
1 Keldon Champion|UDS
|
1 Keldon Champion|UDS
|
||||||
1 Keldon Marauders|PLC
|
1 Keldon Marauders|PLC
|
||||||
1 Keldon Vandals|UDS
|
1 Keldon Vandals|UDS
|
||||||
|
1 Kira, Great Glass-Spinner|BOK
|
||||||
1 Kird Ape|9ED
|
1 Kird Ape|9ED
|
||||||
1 Kitchen Finks|SHM
|
1 Kitchen Finks|SHM
|
||||||
1 Knight of Meadowgrain|LRW
|
1 Knight of Meadowgrain|LRW
|
||||||
1 Knight of the Reliquary|CFX
|
1 Knight of the Reliquary|CFX
|
||||||
1 Kodama's Reach|CHK
|
1 Kodama's Reach|CHK
|
||||||
1 Kokusho, the Evening Star|CHK
|
1 Kokusho, the Evening Star|CHK
|
||||||
1 Kor Duelist|ZEN
|
1 Kor Sanctifiers|HOP
|
||||||
|
1 Kor Skyfisher|DDF
|
||||||
1 Koth of the Hammer|SOM
|
1 Koth of the Hammer|SOM
|
||||||
1 Kozilek, Butcher of Truth|ROE
|
1 Kozilek, Butcher of Truth|ROE
|
||||||
1 Krosan Tusker|ONS
|
1 Krosan Tusker|ONS
|
||||||
1 Land Tax|4ED
|
1 Land Tax|4ED
|
||||||
1 Leonin Relic-Warder|MBS
|
1 Leonin Relic-Warder|MBS
|
||||||
1 Library of Alexandria|ARN
|
1 Library of Alexandria|ARN
|
||||||
|
1 Life // Death|APC
|
||||||
1 Life from the Loam|RAV
|
1 Life from the Loam|RAV
|
||||||
|
1 Lifebane Zombie|M14
|
||||||
1 Lightning Bolt|M11
|
1 Lightning Bolt|M11
|
||||||
1 Lightning Greaves|MRD
|
1 Lightning Greaves|MRD
|
||||||
1 Lightning Helix|RAV
|
1 Lightning Helix|RAV
|
||||||
@@ -240,6 +255,7 @@ Name=JuzamjediCube
|
|||||||
1 Liliana Vess|M11
|
1 Liliana Vess|M11
|
||||||
1 Liliana's Specter|M11
|
1 Liliana's Specter|M11
|
||||||
1 Lingering Souls|DKA
|
1 Lingering Souls|DKA
|
||||||
|
1 Living Death|COM
|
||||||
1 Llanowar Elves|M11
|
1 Llanowar Elves|M11
|
||||||
1 Llanowar Wastes|10E
|
1 Llanowar Wastes|10E
|
||||||
1 Lodestone Golem|WWK
|
1 Lodestone Golem|WWK
|
||||||
@@ -257,7 +273,7 @@ Name=JuzamjediCube
|
|||||||
1 Manic Vandal|M11
|
1 Manic Vandal|M11
|
||||||
1 Marsh Flats|ZEN
|
1 Marsh Flats|ZEN
|
||||||
1 Master of the Wild Hunt|M10
|
1 Master of the Wild Hunt|M10
|
||||||
1 Masticore|UDS
|
1 Mayor of Avabruck|ISD
|
||||||
1 Maze of Ith|DRK
|
1 Maze of Ith|DRK
|
||||||
1 Meloku the Clouded Mirror|CHK
|
1 Meloku the Clouded Mirror|CHK
|
||||||
1 Memory Lapse|7ED
|
1 Memory Lapse|7ED
|
||||||
@@ -265,12 +281,14 @@ Name=JuzamjediCube
|
|||||||
1 Mimic Vat|SOM
|
1 Mimic Vat|SOM
|
||||||
1 Mind Stone|10E
|
1 Mind Stone|10E
|
||||||
1 Mind Twist|3ED
|
1 Mind Twist|3ED
|
||||||
|
1 Mindsparker|M14
|
||||||
1 Mirran Crusader|MBS
|
1 Mirran Crusader|MBS
|
||||||
1 Mirror Entity|LRW
|
1 Mirror Entity|LRW
|
||||||
1 Miscalculation|ULG
|
1 Miscalculation|ULG
|
||||||
1 Mishra's Factory|4ED
|
1 Mishra's Factory|4ED
|
||||||
1 Mistral Charger|DIS
|
1 Mistral Charger|DIS
|
||||||
1 Misty Rainforest|ZEN
|
1 Misty Rainforest|ZEN
|
||||||
|
1 Moat|LEG
|
||||||
1 Mogg Fanatic|TMP
|
1 Mogg Fanatic|TMP
|
||||||
1 Molten Rain|MRD
|
1 Molten Rain|MRD
|
||||||
1 Molten-Tail Masticore|SOM
|
1 Molten-Tail Masticore|SOM
|
||||||
@@ -285,19 +303,24 @@ Name=JuzamjediCube
|
|||||||
1 Mutavault|MOR
|
1 Mutavault|MOR
|
||||||
1 Myr Battlesphere|SOM
|
1 Myr Battlesphere|SOM
|
||||||
1 Mystic Snake|APC
|
1 Mystic Snake|APC
|
||||||
|
1 Mystical Tutor|MIR
|
||||||
|
1 Natural Order|POR
|
||||||
|
1 Necromancy|VIS
|
||||||
1 Negate|M10
|
1 Negate|M10
|
||||||
1 Nekrataal|10E
|
1 Nekrataal|10E
|
||||||
1 Nevinyrral's Disk|5ED
|
1 Nevinyrral's Disk|5ED
|
||||||
1 Nezumi Graverobber|CHK
|
1 Nezumi Graverobber|CHK
|
||||||
1 Night's Whisper|5DN
|
1 Night's Whisper|5DN
|
||||||
1 Niv-Mizzet, Dracogenius|RTR
|
|
||||||
1 Noble Hierarch|CFX
|
1 Noble Hierarch|CFX
|
||||||
1 Ob Nixilis, the Fallen|ZEN
|
1 Ob Nixilis, the Fallen|ZEN
|
||||||
1 Oblivion Ring|ALA
|
1 Oblivion Ring|ALA
|
||||||
1 Oblivion Stone|COM
|
1 Oblivion Stone|COM
|
||||||
1 Obzedat, Ghost Council|GTC
|
1 Obzedat, Ghost Council|GTC
|
||||||
1 Ohran Viper|CSP
|
1 Olivia Voldaren|ISD
|
||||||
|
1 Omenspeaker|THS
|
||||||
1 Oona's Prowler|LRW
|
1 Oona's Prowler|LRW
|
||||||
|
1 Opposition|7ED
|
||||||
|
1 Oracle of Mul Daya|ZEN
|
||||||
1 Overgrown Tomb|RAV
|
1 Overgrown Tomb|RAV
|
||||||
1 Pack Rat|RTR
|
1 Pack Rat|RTR
|
||||||
1 Path to Exile|CFX
|
1 Path to Exile|CFX
|
||||||
@@ -312,6 +335,7 @@ Name=JuzamjediCube
|
|||||||
1 Plated Geopede|ZEN
|
1 Plated Geopede|ZEN
|
||||||
1 Plow Under|8ED
|
1 Plow Under|8ED
|
||||||
1 Polluted Delta|ONS
|
1 Polluted Delta|ONS
|
||||||
|
1 Polukranos, World Eater|THS
|
||||||
1 Ponder|LRW
|
1 Ponder|LRW
|
||||||
1 Porcelain Legionnaire|NPH
|
1 Porcelain Legionnaire|NPH
|
||||||
1 Pouncing Jaguar|USG
|
1 Pouncing Jaguar|USG
|
||||||
@@ -319,24 +343,28 @@ Name=JuzamjediCube
|
|||||||
1 Preordain|M11
|
1 Preordain|M11
|
||||||
1 Prime Speaker Zegana|GTC
|
1 Prime Speaker Zegana|GTC
|
||||||
1 Primeval Titan|M11
|
1 Primeval Titan|M11
|
||||||
1 Prophetic Bolt|COM
|
1 Profane Command|LRW
|
||||||
1 Psionic Blast|TSB
|
1 Psionic Blast|TSB
|
||||||
|
1 Psychatog|ODY
|
||||||
1 Puppeteer Clique|SHM
|
1 Puppeteer Clique|SHM
|
||||||
1 Qasali Pridemage|ARB
|
1 Qasali Pridemage|ARB
|
||||||
1 Raging Ravine|WWK
|
1 Raging Ravine|WWK
|
||||||
|
1 Ral Zarek|DGM
|
||||||
1 Rancor|ULG
|
1 Rancor|ULG
|
||||||
1 Ravages of War|PTK
|
1 Ravages of War|PTK
|
||||||
1 Razormane Masticore|5DN
|
|
||||||
1 Reanimate|TMP
|
1 Reanimate|TMP
|
||||||
|
1 Reckless Charge|HOP
|
||||||
1 Reckless Waif|ISD
|
1 Reckless Waif|ISD
|
||||||
1 Recurring Nightmare|EXO
|
1 Recurring Nightmare|EXO
|
||||||
1 Red Sun's Zenith|MBS
|
1 Red Sun's Zenith|MBS
|
||||||
|
1 Reflecting Pool|SHM
|
||||||
1 Regrowth|3ED
|
1 Regrowth|3ED
|
||||||
1 Remand|RAV
|
1 Remand|RAV
|
||||||
1 Repeal|GPT
|
1 Repeal|GPT
|
||||||
1 Restoration Angel|AVR
|
1 Restoration Angel|AVR
|
||||||
1 Reveillark|MOR
|
1 Reveillark|MOR
|
||||||
1 Rift Bolt|TSP
|
1 Rift Bolt|TSP
|
||||||
|
1 Rishadan Port|MMQ
|
||||||
1 River Boa|ZEN
|
1 River Boa|ZEN
|
||||||
1 Rofellos, Llanowar Emissary|UDS
|
1 Rofellos, Llanowar Emissary|UDS
|
||||||
1 Rolling Earthquake|PTK
|
1 Rolling Earthquake|PTK
|
||||||
@@ -353,10 +381,10 @@ Name=JuzamjediCube
|
|||||||
1 Searing Spear|M13
|
1 Searing Spear|M13
|
||||||
1 Sensei's Divining Top|CHK
|
1 Sensei's Divining Top|CHK
|
||||||
1 Serendib Efreet|3ED
|
1 Serendib Efreet|3ED
|
||||||
1 Serum Visions|5DN
|
1 Shadowborn Demon|M14
|
||||||
1 Shadowmage Infiltrator|TSB
|
|
||||||
1 Shelldock Isle|LRW
|
1 Shelldock Isle|LRW
|
||||||
1 Sheoldred, Whispering One|NPH
|
1 Sheoldred, Whispering One|NPH
|
||||||
|
1 Show and Tell|USG
|
||||||
1 Shriekmaw|LRW
|
1 Shriekmaw|LRW
|
||||||
1 Shrine of Burning Rage|NPH
|
1 Shrine of Burning Rage|NPH
|
||||||
1 Siege-Gang Commander|10E
|
1 Siege-Gang Commander|10E
|
||||||
@@ -366,12 +394,14 @@ Name=JuzamjediCube
|
|||||||
1 Skinrender|SOM
|
1 Skinrender|SOM
|
||||||
1 Skinshifter|M12
|
1 Skinshifter|M12
|
||||||
1 Skullclamp|DST
|
1 Skullclamp|DST
|
||||||
1 Skylasher|DGM
|
|
||||||
1 Smash to Smithereens|SHM
|
1 Smash to Smithereens|SHM
|
||||||
|
1 Smokestack|USG
|
||||||
1 Smother|ONS
|
1 Smother|ONS
|
||||||
1 Snapcaster Mage|ISD
|
1 Snapcaster Mage|ISD
|
||||||
|
1 Sneak Attack|USG
|
||||||
1 Snuff Out|MMQ
|
1 Snuff Out|MMQ
|
||||||
1 Sol Ring|LEA
|
1 Sol Ring|LEA
|
||||||
|
1 Soldier of the Pantheon|THS
|
||||||
1 Solemn Simulacrum|MRD
|
1 Solemn Simulacrum|MRD
|
||||||
1 Soltari Champion|STH
|
1 Soltari Champion|STH
|
||||||
1 Soltari Monk|TMP
|
1 Soltari Monk|TMP
|
||||||
@@ -379,16 +409,18 @@ Name=JuzamjediCube
|
|||||||
1 Soltari Trooper|TMP
|
1 Soltari Trooper|TMP
|
||||||
1 Sorin, Lord of Innistrad|DKA
|
1 Sorin, Lord of Innistrad|DKA
|
||||||
1 Sower of Temptation|LRW
|
1 Sower of Temptation|LRW
|
||||||
|
1 Spear of Heliod|THS
|
||||||
1 Spectral Procession|SHM
|
1 Spectral Procession|SHM
|
||||||
1 Spell Pierce|ZEN
|
1 Spell Pierce|ZEN
|
||||||
|
1 Spellskite|NPH
|
||||||
1 Sphinx of Jwar Isle|ZEN
|
1 Sphinx of Jwar Isle|ZEN
|
||||||
|
1 Sphinx of the Steel Wind|PD3
|
||||||
1 Sphinx's Revelation|RTR
|
1 Sphinx's Revelation|RTR
|
||||||
1 Spike Jester|DGM
|
|
||||||
1 Spikeshot Elder|SOM
|
1 Spikeshot Elder|SOM
|
||||||
1 Spined Thopter|NPH
|
|
||||||
1 Splatter Thug|RTR
|
1 Splatter Thug|RTR
|
||||||
1 Squee, Goblin Nabob|MMQ
|
1 Squee, Goblin Nabob|MMQ
|
||||||
1 Staggershock|ROE
|
1 Staggershock|ROE
|
||||||
|
1 Steam Augury|THS
|
||||||
1 Steam Vents|GPT
|
1 Steam Vents|GPT
|
||||||
1 Steppe Lynx|ZEN
|
1 Steppe Lynx|ZEN
|
||||||
1 Stomping Ground|GPT
|
1 Stomping Ground|GPT
|
||||||
@@ -412,17 +444,21 @@ Name=JuzamjediCube
|
|||||||
1 Sword of Light and Shadow|DST
|
1 Sword of Light and Shadow|DST
|
||||||
1 Sword of War and Peace|NPH
|
1 Sword of War and Peace|NPH
|
||||||
1 Swords to Plowshares|ICE
|
1 Swords to Plowshares|ICE
|
||||||
|
1 Sylvan Caryatid|THS
|
||||||
1 Sylvan Library|4ED
|
1 Sylvan Library|4ED
|
||||||
1 Taiga|3ED
|
1 Taiga|3ED
|
||||||
1 Tamiyo, the Moon Sage|AVR
|
1 Tamiyo, the Moon Sage|AVR
|
||||||
1 Tangle Wire|NMS
|
1 Tangle Wire|NMS
|
||||||
1 Tarmogoyf|FUT
|
1 Tarmogoyf|FUT
|
||||||
|
1 Tattermunge Maniac|SHM
|
||||||
1 Temple Garden|RAV
|
1 Temple Garden|RAV
|
||||||
1 Terastodon|WWK
|
1 Terastodon|WWK
|
||||||
1 Terminate|ARB
|
1 Terminate|ARB
|
||||||
1 Terramorphic Expanse|10E
|
1 Terramorphic Expanse|10E
|
||||||
1 Terror|6ED
|
1 Terror|6ED
|
||||||
|
1 Tezzeret the Seeker|DDF
|
||||||
1 Thalia, Guardian of Thraben|DKA
|
1 Thalia, Guardian of Thraben|DKA
|
||||||
|
1 Thassa, God of the Sea|THS
|
||||||
1 Thirst for Knowledge|MRD
|
1 Thirst for Knowledge|MRD
|
||||||
1 Thoughtseize|LRW
|
1 Thoughtseize|LRW
|
||||||
1 Thragtusk|M13
|
1 Thragtusk|M13
|
||||||
@@ -431,12 +467,12 @@ Name=JuzamjediCube
|
|||||||
1 Thundermaw Hellkite|M13
|
1 Thundermaw Hellkite|M13
|
||||||
1 Time Spiral|USG
|
1 Time Spiral|USG
|
||||||
1 Time Walk|2ED
|
1 Time Walk|2ED
|
||||||
|
1 Timetwister|LEA
|
||||||
1 Tinker|ULG
|
1 Tinker|ULG
|
||||||
1 Tombstalker|FUT
|
1 Tombstalker|FUT
|
||||||
1 Torch Fiend|DKA
|
1 Torch Fiend|DKA
|
||||||
1 Treachery|UDS
|
1 Treachery|UDS
|
||||||
1 Treetop Village|10E
|
1 Treetop Village|10E
|
||||||
1 Triskelion|ATQ
|
|
||||||
1 Troll Ascetic|10E
|
1 Troll Ascetic|10E
|
||||||
1 Tropical Island|3ED
|
1 Tropical Island|3ED
|
||||||
1 Trygon Predator|DIS
|
1 Trygon Predator|DIS
|
||||||
@@ -445,6 +481,7 @@ Name=JuzamjediCube
|
|||||||
1 Ulamog, the Infinite Gyre|ROE
|
1 Ulamog, the Infinite Gyre|ROE
|
||||||
1 Ultimate Price|RTR
|
1 Ultimate Price|RTR
|
||||||
1 Umezawa's Jitte|BOK
|
1 Umezawa's Jitte|BOK
|
||||||
|
1 Unburial Rites|ISD
|
||||||
1 Underground Sea|3ED
|
1 Underground Sea|3ED
|
||||||
1 Upheaval|ODY
|
1 Upheaval|ODY
|
||||||
1 Vampire Nighthawk|ZEN
|
1 Vampire Nighthawk|ZEN
|
||||||
@@ -469,6 +506,7 @@ Name=JuzamjediCube
|
|||||||
1 Weathered Wayfarer|ONS
|
1 Weathered Wayfarer|ONS
|
||||||
1 Wheel of Fortune|LEA
|
1 Wheel of Fortune|LEA
|
||||||
1 Wickerbough Elder|EVE
|
1 Wickerbough Elder|EVE
|
||||||
|
1 Wild Dogs|USG
|
||||||
1 Wild Mongrel|ODY
|
1 Wild Mongrel|ODY
|
||||||
1 Wild Nacatl|ALA
|
1 Wild Nacatl|ALA
|
||||||
1 Windswept Heath|ONS
|
1 Windswept Heath|ONS
|
||||||
@@ -480,6 +518,7 @@ Name=JuzamjediCube
|
|||||||
1 Worn Powerstone|USG
|
1 Worn Powerstone|USG
|
||||||
1 Wrath of God|10E
|
1 Wrath of God|10E
|
||||||
1 Wurmcoil Engine|SOM
|
1 Wurmcoil Engine|SOM
|
||||||
|
1 Xenagos, the Reveler|THS
|
||||||
1 Yavimaya Elder|UDS
|
1 Yavimaya Elder|UDS
|
||||||
1 Yosei, the Morning Star|CHK
|
1 Young Pyromancer|M14
|
||||||
1 Zealous Conscripts|AVR
|
1 Zealous Conscripts|AVR
|
||||||
|
|||||||
BIN
res/skins/the_dale/bg_match.jpg
Normal file
BIN
res/skins/the_dale/bg_match.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 247 KiB |
BIN
res/skins/the_dale/bg_splash.png
Normal file
BIN
res/skins/the_dale/bg_splash.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 443 KiB |
BIN
res/skins/the_dale/bg_texture.jpg
Normal file
BIN
res/skins/the_dale/bg_texture.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 48 KiB |
BIN
res/skins/the_dale/font1.ttf
Normal file
BIN
res/skins/the_dale/font1.ttf
Normal file
Binary file not shown.
BIN
res/skins/the_dale/sprite_icons.png
Normal file
BIN
res/skins/the_dale/sprite_icons.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 706 KiB |
@@ -92,7 +92,7 @@ public abstract class CostPartWithList extends CostPart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final boolean executePayment(SpellAbility ability, Card targetCard) {
|
public final boolean executePayment(SpellAbility ability, Card targetCard) {
|
||||||
this.list.add(targetCard);
|
this.list.add(CardUtil.getLKICopy(targetCard));
|
||||||
doPayment(ability, targetCard);
|
doPayment(ability, targetCard);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,11 +64,9 @@ import forge.gui.match.controllers.CMessage;
|
|||||||
import forge.gui.match.controllers.CStack;
|
import forge.gui.match.controllers.CStack;
|
||||||
import forge.gui.match.nonsingleton.VField;
|
import forge.gui.match.nonsingleton.VField;
|
||||||
import forge.gui.match.views.VAntes;
|
import forge.gui.match.views.VAntes;
|
||||||
import forge.gui.menubar.FMenuBar;
|
import forge.gui.menus.ForgeMenu;
|
||||||
import forge.gui.menubar.MenuUtil;
|
|
||||||
import forge.gui.toolbox.FSkin;
|
import forge.gui.toolbox.FSkin;
|
||||||
import forge.net.FServer;
|
import forge.net.FServer;
|
||||||
import forge.properties.ForgePreferences;
|
|
||||||
import forge.properties.ForgePreferences.FPref;
|
import forge.properties.ForgePreferences.FPref;
|
||||||
import forge.properties.NewConstants;
|
import forge.properties.NewConstants;
|
||||||
import forge.quest.QuestController;
|
import forge.quest.QuestController;
|
||||||
@@ -88,10 +86,11 @@ import forge.view.FView;
|
|||||||
public enum FControl implements KeyEventDispatcher {
|
public enum FControl implements KeyEventDispatcher {
|
||||||
instance;
|
instance;
|
||||||
|
|
||||||
private FMenuBar menuBar;
|
private ForgeMenu forgeMenu;
|
||||||
private List<Shortcut> shortcuts;
|
private List<Shortcut> shortcuts;
|
||||||
private JLayeredPane display;
|
private JLayeredPane display;
|
||||||
private Screens state = Screens.UNKNOWN;
|
private Screens state = Screens.UNKNOWN;
|
||||||
|
private boolean altKeyLastDown;
|
||||||
|
|
||||||
private WindowListener waDefault, waConcede, waLeaveBazaar, waLeaveEditor;
|
private WindowListener waDefault, waConcede, waLeaveBazaar, waLeaveEditor;
|
||||||
|
|
||||||
@@ -174,7 +173,7 @@ public enum FControl implements KeyEventDispatcher {
|
|||||||
// Preloads skin components (using progress bar).
|
// Preloads skin components (using progress bar).
|
||||||
FSkin.loadFull(true);
|
FSkin.loadFull(true);
|
||||||
|
|
||||||
createMenuBar();
|
forgeMenu = new ForgeMenu();
|
||||||
|
|
||||||
this.shortcuts = KeyboardShortcuts.attachKeyboardShortcuts();
|
this.shortcuts = KeyboardShortcuts.attachKeyboardShortcuts();
|
||||||
this.display = FView.SINGLETON_INSTANCE.getLpnDocument();
|
this.display = FView.SINGLETON_INSTANCE.getLpnDocument();
|
||||||
@@ -217,13 +216,8 @@ public enum FControl implements KeyEventDispatcher {
|
|||||||
manager.addKeyEventDispatcher(this);
|
manager.addKeyEventDispatcher(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createMenuBar() {
|
public ForgeMenu getForgeMenu() {
|
||||||
this.menuBar = new FMenuBar(Singletons.getView().getFrame());
|
return this.forgeMenu;
|
||||||
this.menuBar.setVisible(MenuUtil.isMenuBarVisible());
|
|
||||||
}
|
|
||||||
|
|
||||||
public FMenuBar getMenuBar() {
|
|
||||||
return this.menuBar;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -486,27 +480,33 @@ public enum FControl implements KeyEventDispatcher {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean dispatchKeyEvent(KeyEvent e) {
|
public boolean dispatchKeyEvent(KeyEvent e) {
|
||||||
// Toggle menu bar visibility using F1 key.
|
// Show Forge menu if Alt key pressed without modifiers and released without pressing any other keys in between
|
||||||
if (e.getKeyCode() == KeyEvent.VK_F1 && e.getID() == KeyEvent.KEY_RELEASED) {
|
if (e.getKeyCode() == KeyEvent.VK_ALT) {
|
||||||
toggleMenuBarVisibility();
|
if (e.getID() == KeyEvent.KEY_RELEASED) {
|
||||||
|
if (altKeyLastDown) {
|
||||||
|
forgeMenu.show(true);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
}
|
||||||
|
}
|
||||||
|
else if (e.getID() == KeyEvent.KEY_PRESSED && e.getModifiers() == KeyEvent.ALT_MASK) {
|
||||||
|
altKeyLastDown = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
altKeyLastDown = false;
|
||||||
|
if (e.getID() == KeyEvent.KEY_PRESSED) {
|
||||||
|
if (forgeMenu.handleKeyEvent(e)) { //give Forge menu the chance to handle the key event
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (e.getID() == KeyEvent.KEY_RELEASED) {
|
||||||
|
if (e.getKeyCode() == KeyEvent.VK_CONTEXT_MENU) {
|
||||||
|
forgeMenu.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
//Allow the event to be redispatched
|
//Allow the event to be redispatched
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void toggleMenuBarVisibility() {
|
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
ForgePreferences prefs = Singletons.getModel().getPreferences();
|
|
||||||
boolean isHidden = !prefs.getPrefBoolean(FPref.UI_HIDE_MENUBAR);
|
|
||||||
menuBar.setVisible(!isHidden);
|
|
||||||
prefs.setPref(FPref.UI_HIDE_MENUBAR, String.valueOf(isHidden));
|
|
||||||
prefs.save();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ import org.apache.commons.lang3.tuple.Pair;
|
|||||||
import com.google.common.collect.ArrayListMultimap;
|
import com.google.common.collect.ArrayListMultimap;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
import com.google.common.collect.Multimaps;
|
||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.CardLists;
|
import forge.CardLists;
|
||||||
import forge.CardPredicates;
|
import forge.CardPredicates;
|
||||||
@@ -51,8 +53,8 @@ public class Combat {
|
|||||||
private final List<GameEntity> attackableEntries = new ArrayList<GameEntity>();
|
private final List<GameEntity> attackableEntries = new ArrayList<GameEntity>();
|
||||||
|
|
||||||
// Keyed by attackable defender (player or planeswalker)
|
// Keyed by attackable defender (player or planeswalker)
|
||||||
private final Multimap<GameEntity, AttackingBand> attackedBands = ArrayListMultimap.create();
|
private final Multimap<GameEntity, AttackingBand> attackedByBands = Multimaps.synchronizedMultimap(ArrayListMultimap.<GameEntity, AttackingBand>create());
|
||||||
private final Multimap<AttackingBand, Card> blockedBands = ArrayListMultimap.create();
|
private final Multimap<AttackingBand, Card> blockedBands = Multimaps.synchronizedMultimap(ArrayListMultimap.<AttackingBand, Card>create());
|
||||||
|
|
||||||
private final HashMap<Card, Integer> defendingDamageMap = new HashMap<Card, Integer>();
|
private final HashMap<Card, Integer> defendingDamageMap = new HashMap<Card, Integer>();
|
||||||
|
|
||||||
@@ -106,12 +108,12 @@ public class Combat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final List<AttackingBand> getAttackingBandsOf(GameEntity defender) {
|
public final List<AttackingBand> getAttackingBandsOf(GameEntity defender) {
|
||||||
return Lists.newArrayList(attackedBands.get(defender));
|
return Lists.newArrayList(attackedByBands.get(defender));
|
||||||
}
|
}
|
||||||
|
|
||||||
public final List<Card> getAttackersOf(GameEntity defender) {
|
public final List<Card> getAttackersOf(GameEntity defender) {
|
||||||
List<Card> result = new ArrayList<Card>();
|
List<Card> result = new ArrayList<Card>();
|
||||||
for(AttackingBand v : attackedBands.get(defender)) {
|
for(AttackingBand v : attackedByBands.get(defender)) {
|
||||||
result.addAll(v.getAttackers());
|
result.addAll(v.getAttackers());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -122,7 +124,7 @@ public class Combat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final void addAttacker(final Card c, GameEntity defender, AttackingBand band) {
|
public final void addAttacker(final Card c, GameEntity defender, AttackingBand band) {
|
||||||
Collection<AttackingBand> attackersOfDefender = attackedBands.get(defender);
|
Collection<AttackingBand> attackersOfDefender = attackedByBands.get(defender);
|
||||||
if (attackersOfDefender == null) {
|
if (attackersOfDefender == null) {
|
||||||
System.out.println("Trying to add Attacker " + c + " to missing defender " + defender);
|
System.out.println("Trying to add Attacker " + c + " to missing defender " + defender);
|
||||||
return;
|
return;
|
||||||
@@ -141,7 +143,7 @@ public class Combat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final GameEntity getDefenderByAttacker(final AttackingBand c) {
|
public final GameEntity getDefenderByAttacker(final AttackingBand c) {
|
||||||
for(Entry<GameEntity, AttackingBand> e : attackedBands.entries()) {
|
for(Entry<GameEntity, AttackingBand> e : attackedByBands.entries()) {
|
||||||
if ( e.getValue() == c )
|
if ( e.getValue() == c )
|
||||||
return e.getKey();
|
return e.getKey();
|
||||||
}
|
}
|
||||||
@@ -165,7 +167,7 @@ public class Combat {
|
|||||||
|
|
||||||
// takes LKI into consideration, should use it at all times (though a single iteration over multimap seems faster)
|
// takes LKI into consideration, should use it at all times (though a single iteration over multimap seems faster)
|
||||||
public final AttackingBand getBandOfAttacker(final Card c) {
|
public final AttackingBand getBandOfAttacker(final Card c) {
|
||||||
for(AttackingBand ab : attackedBands.values()) {
|
for(AttackingBand ab : attackedByBands.values()) {
|
||||||
if ( ab.contains(c) )
|
if ( ab.contains(c) )
|
||||||
return ab;
|
return ab;
|
||||||
}
|
}
|
||||||
@@ -174,7 +176,7 @@ public class Combat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final List<AttackingBand> getAttackingBands() {
|
public final List<AttackingBand> getAttackingBands() {
|
||||||
return Lists.newArrayList(attackedBands.values());
|
return Lists.newArrayList(attackedByBands.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean isAttacking(final Card c) {
|
public final boolean isAttacking(final Card c) {
|
||||||
@@ -184,7 +186,7 @@ public class Combat {
|
|||||||
|
|
||||||
public boolean isAttacking(Card card, GameEntity defender) {
|
public boolean isAttacking(Card card, GameEntity defender) {
|
||||||
AttackingBand ab = getBandOfAttacker(card);
|
AttackingBand ab = getBandOfAttacker(card);
|
||||||
for(Entry<GameEntity, AttackingBand> ee : attackedBands.entries())
|
for(Entry<GameEntity, AttackingBand> ee : attackedByBands.entries())
|
||||||
if ( ee.getValue() == ab )
|
if ( ee.getValue() == ab )
|
||||||
return ee.getKey() == defender;
|
return ee.getKey() == defender;
|
||||||
return false;
|
return false;
|
||||||
@@ -192,7 +194,7 @@ public class Combat {
|
|||||||
|
|
||||||
public final List<Card> getAttackers() {
|
public final List<Card> getAttackers() {
|
||||||
List<Card> result = Lists.newArrayList();
|
List<Card> result = Lists.newArrayList();
|
||||||
for(AttackingBand ab : attackedBands.values())
|
for(AttackingBand ab : attackedByBands.values())
|
||||||
result.addAll(ab.getAttackers());
|
result.addAll(ab.getAttackers());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -286,7 +288,7 @@ public class Combat {
|
|||||||
|
|
||||||
List<Pair<Card, List<Card>>> blockersNeedManualOrdering = new ArrayList<>();
|
List<Pair<Card, List<Card>>> blockersNeedManualOrdering = new ArrayList<>();
|
||||||
|
|
||||||
for(AttackingBand band : attackedBands.values())
|
for(AttackingBand band : attackedByBands.values())
|
||||||
{
|
{
|
||||||
if (band.isEmpty()) continue;
|
if (band.isEmpty()) continue;
|
||||||
|
|
||||||
@@ -372,7 +374,7 @@ public class Combat {
|
|||||||
|
|
||||||
public final void removeAbsentCombatants() {
|
public final void removeAbsentCombatants() {
|
||||||
// iterate all attackers and remove them
|
// iterate all attackers and remove them
|
||||||
for(Entry<GameEntity, AttackingBand> ee : attackedBands.entries()) {
|
for(Entry<GameEntity, AttackingBand> ee : attackedByBands.entries()) {
|
||||||
List<Card> atk = ee.getValue().getAttackers();
|
List<Card> atk = ee.getValue().getAttackers();
|
||||||
for(int i = atk.size() - 1; i >= 0; i--) { // might remove items from collection, so no iterators
|
for(int i = atk.size() - 1; i >= 0; i--) { // might remove items from collection, so no iterators
|
||||||
Card c = atk.get(i);
|
Card c = atk.get(i);
|
||||||
@@ -396,7 +398,7 @@ public class Combat {
|
|||||||
|
|
||||||
// Call this method right after turn-based action of declare blockers has been performed
|
// Call this method right after turn-based action of declare blockers has been performed
|
||||||
public final void fireTriggersForUnblockedAttackers() {
|
public final void fireTriggersForUnblockedAttackers() {
|
||||||
for(AttackingBand ab : attackedBands.values()) {
|
for(AttackingBand ab : attackedByBands.values()) {
|
||||||
Collection<Card> blockers = blockedBands.get(ab);
|
Collection<Card> blockers = blockedBands.get(ab);
|
||||||
boolean isBlocked = blockers != null && !blockers.isEmpty();
|
boolean isBlocked = blockers != null && !blockers.isEmpty();
|
||||||
ab.setBlocked(isBlocked);
|
ab.setBlocked(isBlocked);
|
||||||
@@ -649,7 +651,7 @@ public class Combat {
|
|||||||
*/
|
*/
|
||||||
public final List<Card> getUnblockedAttackers() {
|
public final List<Card> getUnblockedAttackers() {
|
||||||
List<Card> unblocked = new ArrayList<Card>();
|
List<Card> unblocked = new ArrayList<Card>();
|
||||||
for (AttackingBand ab : attackedBands.values())
|
for (AttackingBand ab : attackedByBands.values())
|
||||||
if ( Boolean.TRUE.equals(ab.isBlocked()) )
|
if ( Boolean.TRUE.equals(ab.isBlocked()) )
|
||||||
unblocked.addAll(ab.getAttackers());
|
unblocked.addAll(ab.getAttackers());
|
||||||
|
|
||||||
@@ -657,13 +659,13 @@ public class Combat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPlayerAttacked(Player who) {
|
public boolean isPlayerAttacked(Player who) {
|
||||||
for(GameEntity defender : attackedBands.keySet() ) {
|
for(GameEntity defender : attackedByBands.keySet() ) {
|
||||||
Card defenderAsCard = defender instanceof Card ? (Card)defender : null;
|
Card defenderAsCard = defender instanceof Card ? (Card)defender : null;
|
||||||
if ((null != defenderAsCard && defenderAsCard.getController() != who ) ||
|
if ((null != defenderAsCard && defenderAsCard.getController() != who ) ||
|
||||||
(null == defenderAsCard && defender != who) )
|
(null == defenderAsCard && defender != who) )
|
||||||
continue; // defender is not related to player 'who'
|
continue; // defender is not related to player 'who'
|
||||||
|
|
||||||
for(AttackingBand ab : attackedBands.get(defender)) {
|
for(AttackingBand ab : attackedByBands.get(defender)) {
|
||||||
if ( !ab.isEmpty() )
|
if ( !ab.isEmpty() )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ public final class SOverlayUtils {
|
|||||||
|
|
||||||
private static Component prevFocusOwner;
|
private static Component prevFocusOwner;
|
||||||
public static void showOverlay() {
|
public static void showOverlay() {
|
||||||
Singletons.getControl().getMenuBar().setEnabled(false);
|
Singletons.getControl().getForgeMenu().getPopupMenu().setEnabled(false);
|
||||||
prevFocusOwner = FocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner();
|
prevFocusOwner = FocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner();
|
||||||
FOverlay.SINGLETON_INSTANCE.getPanel().setVisible(true);
|
FOverlay.SINGLETON_INSTANCE.getPanel().setVisible(true);
|
||||||
// ensure no background element has focus
|
// ensure no background element has focus
|
||||||
@@ -138,7 +138,7 @@ public final class SOverlayUtils {
|
|||||||
* Removes child components and closes overlay.
|
* Removes child components and closes overlay.
|
||||||
*/
|
*/
|
||||||
public static void hideOverlay() {
|
public static void hideOverlay() {
|
||||||
Singletons.getControl().getMenuBar().setEnabled(true);
|
Singletons.getControl().getForgeMenu().getPopupMenu().setEnabled(true);
|
||||||
FOverlay.SINGLETON_INSTANCE.getPanel().removeAll();
|
FOverlay.SINGLETON_INSTANCE.getPanel().removeAll();
|
||||||
FOverlay.SINGLETON_INSTANCE.getPanel().setVisible(false);
|
FOverlay.SINGLETON_INSTANCE.getPanel().setVisible(false);
|
||||||
if (null != prevFocusOwner) {
|
if (null != prevFocusOwner) {
|
||||||
|
|||||||
@@ -45,14 +45,14 @@ public class DecksComboBox extends FComboBox<DeckType> {
|
|||||||
private DeckType selectedDeckType = null;
|
private DeckType selectedDeckType = null;
|
||||||
|
|
||||||
public DecksComboBox() {
|
public DecksComboBox() {
|
||||||
setButtonVisible(false);
|
setButtonVisible(true);
|
||||||
FSkin.get(this).setFont(FSkin.getBoldFont(14));
|
FSkin.get(this).setFont(FSkin.getBoldFont(14));
|
||||||
setTextAlignment(TextAlignment.CENTER);
|
setTextAlignment(TextAlignment.CENTER);
|
||||||
setModel(new DefaultComboBoxModel<DeckType>(DeckType.values()));
|
|
||||||
addActionListener(getDeckTypeComboListener());
|
addActionListener(getDeckTypeComboListener());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refresh(DeckType deckType) {
|
public void refresh(DeckType deckType) {
|
||||||
|
setModel(new DefaultComboBoxModel<DeckType>(DeckType.values()));
|
||||||
setSelectedItem(deckType);
|
setSelectedItem(deckType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package forge.gui.deckchooser;
|
package forge.gui.deckchooser;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Font;
|
|
||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
@@ -16,6 +16,7 @@ import javax.swing.ScrollPaneConstants;
|
|||||||
|
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
import forge.Command;
|
import forge.Command;
|
||||||
@@ -31,6 +32,8 @@ import forge.gui.toolbox.FLabel;
|
|||||||
import forge.gui.toolbox.FList;
|
import forge.gui.toolbox.FList;
|
||||||
import forge.gui.toolbox.FScrollPane;
|
import forge.gui.toolbox.FScrollPane;
|
||||||
import forge.gui.toolbox.FSkin;
|
import forge.gui.toolbox.FSkin;
|
||||||
|
import forge.properties.ForgePreferences;
|
||||||
|
import forge.properties.ForgePreferences.FPref;
|
||||||
import forge.quest.QuestController;
|
import forge.quest.QuestController;
|
||||||
import forge.quest.QuestEvent;
|
import forge.quest.QuestEvent;
|
||||||
import forge.quest.QuestEventChallenge;
|
import forge.quest.QuestEventChallenge;
|
||||||
@@ -47,6 +50,7 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
|
|
||||||
private DecksComboBox decksComboBox;
|
private DecksComboBox decksComboBox;
|
||||||
private DeckType selectedDeckType = DeckType.COLOR_DECK;
|
private DeckType selectedDeckType = DeckType.COLOR_DECK;
|
||||||
|
private List<String> selectedDecks = new ArrayList<String>();
|
||||||
|
|
||||||
private final JList<String> lstDecks = new FList<String>();
|
private final JList<String> lstDecks = new FList<String>();
|
||||||
private final FLabel btnRandom = new FLabel.ButtonBuilder().text("Random").fontSize(16).build();
|
private final FLabel btnRandom = new FLabel.ButtonBuilder().text("Random").fontSize(16).build();
|
||||||
@@ -56,11 +60,11 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
|
|
||||||
private final FLabel lblDecklist = new FLabel.Builder().text("Double click deck for its decklist.").fontSize(12).build();
|
private final FLabel lblDecklist = new FLabel.Builder().text("Double click deck for its decklist.").fontSize(12).build();
|
||||||
|
|
||||||
private final FLabel titleLabel;
|
|
||||||
private final String titleTextTemplate;
|
|
||||||
private final boolean canChoosePlayerType;
|
|
||||||
private boolean isAi;
|
private boolean isAi;
|
||||||
|
|
||||||
|
private final ForgePreferences prefs = Singletons.getModel().getPreferences();
|
||||||
|
private FPref stateSetting = null;
|
||||||
|
|
||||||
private final MouseAdapter madDecklist = new MouseAdapter() {
|
private final MouseAdapter madDecklist = new MouseAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void mouseClicked(final MouseEvent e) {
|
public void mouseClicked(final MouseEvent e) {
|
||||||
@@ -75,32 +79,21 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
public FDeckChooser(final String titleText, boolean forAi, boolean canSwitchType) {
|
public FDeckChooser(final String titleText, boolean forAi, boolean canSwitchType) {
|
||||||
setOpaque(false);
|
setOpaque(false);
|
||||||
isAi = forAi;
|
isAi = forAi;
|
||||||
titleTextTemplate = titleText;
|
|
||||||
canChoosePlayerType = canSwitchType;
|
|
||||||
|
|
||||||
titleLabel = new FLabel.Builder()
|
|
||||||
.text(titleText)
|
|
||||||
.fontStyle(Font.BOLD)
|
|
||||||
.fontSize(20)
|
|
||||||
.opaque(false)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
if( canChoosePlayerType )
|
|
||||||
updateTitle();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public FDeckChooser(String titleText, boolean forAi) {
|
public FDeckChooser(String titleText, boolean forAi) {
|
||||||
this(titleText, forAi, false);
|
this(titleText, forAi, false);
|
||||||
}
|
}
|
||||||
private void updateTitle() {
|
|
||||||
String title = canChoosePlayerType ? String.format(titleTextTemplate, isAi ? "Computer" : "Human" ) : titleTextTemplate;
|
|
||||||
titleLabel.setText(title);
|
|
||||||
|
|
||||||
|
public void initialize(FPref savedStateSetting, DeckType defaultDeckType) {
|
||||||
|
stateSetting = savedStateSetting;
|
||||||
|
selectedDeckType = defaultDeckType;
|
||||||
|
}
|
||||||
|
public void initialize(DeckType defaultDeckType) {
|
||||||
|
initialize(null, defaultDeckType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
lstDecks.setOpaque(false);
|
initialize(DeckType.COLOR_DECK);
|
||||||
scrDecks.setBorder(BorderFactory.createMatteBorder(0, 1, 1, 1, BORDER_COLOR));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private JList<String> getLstDecks() { return lstDecks; }
|
private JList<String> getLstDecks() { return lstDecks; }
|
||||||
@@ -110,7 +103,8 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
final JList<String> lst = getLstDecks();
|
final JList<String> lst = getLstDecks();
|
||||||
lst.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
lst.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||||
|
|
||||||
lst.setListData(new String[] {"Random 1", "Random 2", "Random 3", "Black", "Blue", "Green", "Red", "White"});
|
final String[] listData = new String[] {"Random 1", "Random 2", "Random 3", "Black", "Blue", "Green", "Red", "White"};
|
||||||
|
lst.setListData(listData);
|
||||||
lst.setName(DeckgenUtil.DeckTypes.COLORS.toString());
|
lst.setName(DeckgenUtil.DeckTypes.COLORS.toString());
|
||||||
lst.removeMouseListener(madDecklist);
|
lst.removeMouseListener(madDecklist);
|
||||||
lst.addMouseListener(madDecklist);
|
lst.addMouseListener(madDecklist);
|
||||||
@@ -119,8 +113,12 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
getBtnRandom().setCommand(new Command() {
|
getBtnRandom().setCommand(new Command() {
|
||||||
@Override public void run() { lst.setSelectedIndices(DeckgenUtil.randomSelectColors(8)); } });
|
@Override public void run() { lst.setSelectedIndices(DeckgenUtil.randomSelectColors(8)); } });
|
||||||
|
|
||||||
// Init basic two color deck
|
if (listData.length > 0) {
|
||||||
lst.setSelectedIndices(new int[]{0, 1});
|
// default selection = basic two color deck
|
||||||
|
lst.setSelectedIndices(getSelectedDeckIndices(Arrays.asList(listData), new int[]{0, 1}));
|
||||||
|
lst.ensureIndexIsVisible(lst.getSelectedIndices()[0]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateThemes() {
|
private void updateThemes() {
|
||||||
@@ -130,10 +128,10 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
lst.removeMouseListener(madDecklist);
|
lst.removeMouseListener(madDecklist);
|
||||||
lst.addMouseListener(madDecklist);
|
lst.addMouseListener(madDecklist);
|
||||||
|
|
||||||
final List<String> themeNames = new ArrayList<String>();
|
final List<String> listData = new ArrayList<String>();
|
||||||
for (final String s : GenerateThemeDeck.getThemeNames()) { themeNames.add(s); }
|
for (final String s : GenerateThemeDeck.getThemeNames()) { listData.add(s); }
|
||||||
|
|
||||||
lst.setListData(themeNames.toArray(ArrayUtils.EMPTY_STRING_ARRAY));
|
lst.setListData(listData.toArray(ArrayUtils.EMPTY_STRING_ARRAY));
|
||||||
lst.setName(DeckgenUtil.DeckTypes.THEMES.toString());
|
lst.setName(DeckgenUtil.DeckTypes.THEMES.toString());
|
||||||
lst.removeMouseListener(madDecklist);
|
lst.removeMouseListener(madDecklist);
|
||||||
|
|
||||||
@@ -141,18 +139,21 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
getBtnRandom().setCommand(new Command() {
|
getBtnRandom().setCommand(new Command() {
|
||||||
@Override public void run() { DeckgenUtil.randomSelect(lst); } });
|
@Override public void run() { DeckgenUtil.randomSelect(lst); } });
|
||||||
|
|
||||||
// Init first in list
|
if (listData.size() > 0) {
|
||||||
lst.setSelectedIndex(0);
|
lst.setSelectedIndices(getSelectedDeckIndices(listData, new int[]{0}));
|
||||||
|
lst.ensureIndexIsVisible(lst.getSelectedIndices()[0]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateCustom() {
|
private void updateCustom() {
|
||||||
final JList<String> lst = getLstDecks();
|
final JList<String> lst = getLstDecks();
|
||||||
lst.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
lst.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||||
|
|
||||||
final List<String> customNames = new ArrayList<String>();
|
final List<String> listData = new ArrayList<String>();
|
||||||
addDecksRecursive(Singletons.getModel().getDecks().getConstructed(), customNames, null);
|
addDecksRecursive(Singletons.getModel().getDecks().getConstructed(), listData, null);
|
||||||
|
|
||||||
lst.setListData(customNames.toArray(ArrayUtils.EMPTY_STRING_ARRAY));
|
lst.setListData(listData.toArray(ArrayUtils.EMPTY_STRING_ARRAY));
|
||||||
lst.setName(DeckgenUtil.DeckTypes.CUSTOM.toString());
|
lst.setName(DeckgenUtil.DeckTypes.CUSTOM.toString());
|
||||||
lst.removeMouseListener(madDecklist);
|
lst.removeMouseListener(madDecklist);
|
||||||
lst.addMouseListener(madDecklist);
|
lst.addMouseListener(madDecklist);
|
||||||
@@ -161,8 +162,10 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
getBtnRandom().setCommand(new Command() {
|
getBtnRandom().setCommand(new Command() {
|
||||||
@Override public void run() { DeckgenUtil.randomSelect(lst); } });
|
@Override public void run() { DeckgenUtil.randomSelect(lst); } });
|
||||||
|
|
||||||
// Init first in list
|
if (listData.size() > 0) {
|
||||||
lst.setSelectedIndex(0);
|
lst.setSelectedIndices(getSelectedDeckIndices(listData, new int[]{0}));
|
||||||
|
lst.ensureIndexIsVisible(lst.getSelectedIndices()[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T extends IHasName> void addDecksRecursive(IStorage<T> node, List<String> customNames, String namePrefix ) {
|
private <T extends IHasName> void addDecksRecursive(IStorage<T> node, List<String> customNames, String namePrefix ) {
|
||||||
@@ -179,10 +182,10 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
final JList<String> lst = getLstDecks();
|
final JList<String> lst = getLstDecks();
|
||||||
lst.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
lst.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||||
|
|
||||||
final List<String> customNames = new ArrayList<String>();
|
final List<String> listData = new ArrayList<String>();
|
||||||
addDecksRecursive(QuestController.getPrecons(), customNames, null);
|
addDecksRecursive(QuestController.getPrecons(), listData, null);
|
||||||
|
|
||||||
lst.setListData(customNames.toArray(ArrayUtils.EMPTY_STRING_ARRAY));
|
lst.setListData(listData.toArray(ArrayUtils.EMPTY_STRING_ARRAY));
|
||||||
lst.setName(DeckgenUtil.DeckTypes.PRECON.toString());
|
lst.setName(DeckgenUtil.DeckTypes.PRECON.toString());
|
||||||
lst.removeMouseListener(madDecklist);
|
lst.removeMouseListener(madDecklist);
|
||||||
lst.addMouseListener(madDecklist);
|
lst.addMouseListener(madDecklist);
|
||||||
@@ -191,26 +194,28 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
getBtnRandom().setCommand(new Command() {
|
getBtnRandom().setCommand(new Command() {
|
||||||
@Override public void run() { DeckgenUtil.randomSelect(lst); } });
|
@Override public void run() { DeckgenUtil.randomSelect(lst); } });
|
||||||
|
|
||||||
// Init first in list
|
if (listData.size() > 0) {
|
||||||
lst.setSelectedIndex(0);
|
lst.setSelectedIndices(getSelectedDeckIndices(listData, new int[]{0}));
|
||||||
|
lst.ensureIndexIsVisible(lst.getSelectedIndices()[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateQuestEvents() {
|
private void updateQuestEvents() {
|
||||||
final JList<String> lst = getLstDecks();
|
final JList<String> lst = getLstDecks();
|
||||||
lst.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
lst.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||||
|
|
||||||
final List<String> eventNames = new ArrayList<String>();
|
final List<String> listData = new ArrayList<String>();
|
||||||
|
|
||||||
QuestController quest = Singletons.getModel().getQuest();
|
QuestController quest = Singletons.getModel().getQuest();
|
||||||
for (QuestEvent e : quest.getDuelsManager().getAllDuels()) {
|
for (QuestEvent e : quest.getDuelsManager().getAllDuels()) {
|
||||||
eventNames.add(e.getName());
|
listData.add(e.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (QuestEvent e : quest.getChallenges()) {
|
for (QuestEvent e : quest.getChallenges()) {
|
||||||
eventNames.add(e.getTitle());
|
listData.add(e.getTitle());
|
||||||
}
|
}
|
||||||
|
|
||||||
lst.setListData(eventNames.toArray(ArrayUtils.EMPTY_STRING_ARRAY));
|
lst.setListData(listData.toArray(ArrayUtils.EMPTY_STRING_ARRAY));
|
||||||
lst.setName(DeckgenUtil.DeckTypes.QUESTEVENTS.toString());
|
lst.setName(DeckgenUtil.DeckTypes.QUESTEVENTS.toString());
|
||||||
lst.removeMouseListener(madDecklist);
|
lst.removeMouseListener(madDecklist);
|
||||||
lst.addMouseListener(madDecklist);
|
lst.addMouseListener(madDecklist);
|
||||||
@@ -219,8 +224,11 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
getBtnRandom().setCommand(new Command() {
|
getBtnRandom().setCommand(new Command() {
|
||||||
@Override public void run() { DeckgenUtil.randomSelect(lst); } });
|
@Override public void run() { DeckgenUtil.randomSelect(lst); } });
|
||||||
|
|
||||||
// Init first in list
|
if (listData.size() > 0) {
|
||||||
lst.setSelectedIndex(0);
|
lst.setSelectedIndices(getSelectedDeckIndices(listData, new int[]{0}));
|
||||||
|
lst.ensureIndexIsVisible(lst.getSelectedIndices()[0]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Deck getDeck() {
|
public Deck getDeck() {
|
||||||
@@ -271,7 +279,6 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
setupUI();
|
setupUI();
|
||||||
removeAll();
|
removeAll();
|
||||||
this.setLayout(new MigLayout("insets 0, gap 0, flowy"));
|
this.setLayout(new MigLayout("insets 0, gap 0, flowy"));
|
||||||
this.add(titleLabel, "w 10:100%, h 28px!, gap 0 0 0 5px");
|
|
||||||
this.add(decksComboBox, "w 10:100%, h 30px!");
|
this.add(decksComboBox, "w 10:100%, h 30px!");
|
||||||
this.add(scrDecks, "w 10:100%, growy, pushy");
|
this.add(scrDecks, "w 10:100%, growy, pushy");
|
||||||
this.add(btnRandom, "w 10:100%, h 26px!, gap 0 0 2px 0");
|
this.add(btnRandom, "w 10:100%, h 26px!, gap 0 0 2px 0");
|
||||||
@@ -284,7 +291,6 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
|
|
||||||
public void setIsAiDeck(boolean isAiDeck) {
|
public void setIsAiDeck(boolean isAiDeck) {
|
||||||
this.isAi = isAiDeck;
|
this.isAi = isAiDeck;
|
||||||
updateTitle();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
@@ -310,10 +316,12 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
// core UI components.
|
// core UI components.
|
||||||
decksComboBox = new DecksComboBox();
|
decksComboBox = new DecksComboBox();
|
||||||
// set component styles.
|
// set component styles.
|
||||||
// ...
|
lstDecks.setOpaque(false);
|
||||||
|
scrDecks.setBorder(BorderFactory.createMatteBorder(0, 1, 1, 1, BORDER_COLOR));
|
||||||
// monitor events generated by these components.
|
// monitor events generated by these components.
|
||||||
decksComboBox.addListener(this);
|
decksComboBox.addListener(this);
|
||||||
// now everything is in place, fire initial populate event.
|
// now everything is in place, fire initial populate event.
|
||||||
|
restoreSavedState();
|
||||||
decksComboBox.refresh(selectedDeckType);
|
decksComboBox.refresh(selectedDeckType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -344,4 +352,79 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
selectedDeckType = deckType;
|
selectedDeckType = deckType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final String SELECTED_DECK_DELIMITER = "::";
|
||||||
|
|
||||||
|
public void saveState() {
|
||||||
|
if (stateSetting == null) {
|
||||||
|
throw new NullPointerException("State setting missing. Specify first using the initialize() method.");
|
||||||
|
}
|
||||||
|
prefs.setPref(stateSetting, getState());
|
||||||
|
prefs.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getState() {
|
||||||
|
String deckType = decksComboBox.getDeckType().name();
|
||||||
|
String state = deckType;
|
||||||
|
final JList<String> lst = getLstDecks();
|
||||||
|
state += ";";
|
||||||
|
for (String value : lst.getSelectedValuesList()) {
|
||||||
|
state += value + SELECTED_DECK_DELIMITER;
|
||||||
|
}
|
||||||
|
state = state.substring(0, state.length()-SELECTED_DECK_DELIMITER.length());
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void restoreSavedState() {
|
||||||
|
if (stateSetting != null) {
|
||||||
|
String savedState = prefs.getPref(stateSetting);
|
||||||
|
selectedDeckType = getDeckTypeFromSavedState(savedState);
|
||||||
|
selectedDecks = getSelectedDecksFromSavedState(savedState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private DeckType getDeckTypeFromSavedState(String savedState) {
|
||||||
|
try {
|
||||||
|
if (StringUtils.isBlank(savedState)) {
|
||||||
|
return selectedDeckType;
|
||||||
|
} else {
|
||||||
|
return DeckType.valueOf(savedState.split(";")[0]);
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
System.err.println(ex.getMessage() + ". Using default : " + selectedDeckType);
|
||||||
|
return selectedDeckType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> getSelectedDecksFromSavedState(String savedState) {
|
||||||
|
try {
|
||||||
|
if (StringUtils.isBlank(savedState)) {
|
||||||
|
return new ArrayList<String>();
|
||||||
|
} else {
|
||||||
|
return Arrays.asList(savedState.split(";")[1].split(SELECTED_DECK_DELIMITER));
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
System.err.println(ex + " [savedState=" + savedState + "]");
|
||||||
|
return new ArrayList<String>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] getSelectedDeckIndices(List<String> listData, int[] defaultSelection) {
|
||||||
|
if (selectedDecks != null && selectedDecks.size() > 0) {
|
||||||
|
List<Integer> selectedIndices = new ArrayList<Integer>();
|
||||||
|
for (String deck : selectedDecks) {
|
||||||
|
int index = listData.indexOf(deck);
|
||||||
|
if (index >= 0) {
|
||||||
|
selectedIndices.add(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int[] indices = ArrayUtils.toPrimitive(selectedIndices.toArray(new Integer[selectedIndices.size()]));
|
||||||
|
if (indices.length == 0) { indices = defaultSelection; }
|
||||||
|
// only do this once at startup.
|
||||||
|
selectedDecks = null;
|
||||||
|
return indices;
|
||||||
|
} else {
|
||||||
|
return defaultSelection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ import forge.gui.deckeditor.views.VCardCatalog;
|
|||||||
import forge.gui.framework.ICDoc;
|
import forge.gui.framework.ICDoc;
|
||||||
import forge.gui.match.controllers.CDetail;
|
import forge.gui.match.controllers.CDetail;
|
||||||
import forge.gui.match.controllers.CPicture;
|
import forge.gui.match.controllers.CPicture;
|
||||||
import forge.gui.menubar.IMenuProvider;
|
import forge.gui.menus.IMenuProvider;
|
||||||
import forge.gui.toolbox.FLabel;
|
import forge.gui.toolbox.FLabel;
|
||||||
import forge.gui.toolbox.FSkin;
|
import forge.gui.toolbox.FSkin;
|
||||||
import forge.gui.toolbox.itemmanager.ItemManager;
|
import forge.gui.toolbox.itemmanager.ItemManager;
|
||||||
@@ -554,7 +554,7 @@ public enum CDeckEditorUI implements ICDoc, IMenuProvider {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
Singletons.getControl().getMenuBar().setupMenuBar(this);
|
Singletons.getControl().getForgeMenu().setProvider(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
|||||||
@@ -364,7 +364,6 @@ public final class CEditorQuestCardShop extends ACEditorBase<InventoryItem, Deck
|
|||||||
if (item instanceof PaperCard) {
|
if (item instanceof PaperCard) {
|
||||||
final PaperCard card = (PaperCard) item;
|
final PaperCard card = (PaperCard) item;
|
||||||
this.getDeckManager().addItem(card, qty);
|
this.getDeckManager().addItem(card, qty);
|
||||||
this.getCatalogManager().removeItem(item, qty);
|
|
||||||
this.questData.getCards().buyCard(card, qty, value);
|
this.questData.getCards().buyCard(card, qty, value);
|
||||||
|
|
||||||
} else if (item instanceof OpenablePack) {
|
} else if (item instanceof OpenablePack) {
|
||||||
@@ -379,13 +378,13 @@ public final class CEditorQuestCardShop extends ACEditorBase<InventoryItem, Deck
|
|||||||
}
|
}
|
||||||
this.questData.getCards().buyPack(booster, value);
|
this.questData.getCards().buyPack(booster, value);
|
||||||
final List<PaperCard> newCards = booster.getCards();
|
final List<PaperCard> newCards = booster.getCards();
|
||||||
final List<InventoryItem> newInventory = new LinkedList<InventoryItem>(newCards);
|
|
||||||
|
ItemPool<InventoryItem> newInventory = new ItemPool<InventoryItem>(InventoryItem.class);
|
||||||
|
newInventory.addAllFlat(newCards);
|
||||||
getDeckManager().addItems(newInventory);
|
getDeckManager().addItems(newInventory);
|
||||||
final CardListViewer c = new CardListViewer(booster.getName(),
|
final CardListViewer c = new CardListViewer(booster.getName(), "You have found the following cards inside:", newCards);
|
||||||
"You have found the following cards inside:", newCards);
|
|
||||||
c.show();
|
c.show();
|
||||||
}
|
}
|
||||||
this.getCatalogManager().removeItem(item, qty);
|
|
||||||
} else if (item instanceof PreconDeck) {
|
} else if (item instanceof PreconDeck) {
|
||||||
final PreconDeck deck = (PreconDeck) item;
|
final PreconDeck deck = (PreconDeck) item;
|
||||||
this.questData.getCards().buyPreconDeck(deck, value);
|
this.questData.getCards().buyPreconDeck(deck, value);
|
||||||
@@ -400,8 +399,8 @@ public final class CEditorQuestCardShop extends ACEditorBase<InventoryItem, Deck
|
|||||||
one ? "Deck" : String.format("%d copies of deck", qty),
|
one ? "Deck" : String.format("%d copies of deck", qty),
|
||||||
deck.getName(), one ? "was" : "were", one ? "Its" : "Their"),
|
deck.getName(), one ? "was" : "were", one ? "Its" : "Their"),
|
||||||
"Thanks for purchasing!", JOptionPane.INFORMATION_MESSAGE);
|
"Thanks for purchasing!", JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
} else return;
|
||||||
this.getCatalogManager().removeItem(item, qty);
|
this.getCatalogManager().removeItem(item, qty);
|
||||||
}
|
|
||||||
|
|
||||||
this.creditsLabel.setText("Credits: " + this.questData.getAssets().getCredits());
|
this.creditsLabel.setText("Credits: " + this.questData.getAssets().getCredits());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,9 +19,15 @@ import java.util.Set;
|
|||||||
|
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
import forge.Singletons;
|
||||||
import forge.gui.FNetOverlay;
|
import forge.gui.FNetOverlay;
|
||||||
import forge.gui.toolbox.FAbsolutePositioner;
|
import forge.gui.toolbox.FAbsolutePositioner;
|
||||||
import forge.gui.toolbox.FOverlay;
|
import forge.gui.toolbox.FOverlay;
|
||||||
|
import forge.properties.ForgePreferences;
|
||||||
|
import forge.properties.ForgePreferences.FPref;
|
||||||
|
import forge.view.FFrame;
|
||||||
|
import forge.view.FNavigationBar;
|
||||||
|
import forge.view.FStatusBar;
|
||||||
import forge.view.FView;
|
import forge.view.FView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -114,18 +120,31 @@ public final class SResizingUtil {
|
|||||||
|
|
||||||
public static void resizeWindow() {
|
public static void resizeWindow() {
|
||||||
final List<DragCell> cells = FView.SINGLETON_INSTANCE.getDragCells();
|
final List<DragCell> cells = FView.SINGLETON_INSTANCE.getDragCells();
|
||||||
|
final FFrame frame = FView.SINGLETON_INSTANCE.getFrame();
|
||||||
|
final FNavigationBar navigationBar = FView.SINGLETON_INSTANCE.getNavigationBar();
|
||||||
final JPanel pnlContent = FView.SINGLETON_INSTANCE.getPnlContent();
|
final JPanel pnlContent = FView.SINGLETON_INSTANCE.getPnlContent();
|
||||||
final JPanel pnlInsets = FView.SINGLETON_INSTANCE.getPnlInsets();
|
final JPanel pnlInsets = FView.SINGLETON_INSTANCE.getPnlInsets();
|
||||||
|
final FStatusBar statusBar = FView.SINGLETON_INSTANCE.getStatusBar();
|
||||||
|
|
||||||
Rectangle mainBounds = FView.SINGLETON_INSTANCE.getFrame().getInnerPane().getContentPane().getBounds();
|
Rectangle mainBounds = frame.getContentPane().getBounds();
|
||||||
mainBounds.y = 0; // Play nicely with MenuBar if visible or not.
|
mainBounds.y = 0; // Play nicely with MenuBar if visible or not.
|
||||||
FAbsolutePositioner.SINGLETON_INSTANCE.containerResized(mainBounds);
|
FAbsolutePositioner.SINGLETON_INSTANCE.containerResized(mainBounds);
|
||||||
FOverlay.SINGLETON_INSTANCE.getPanel().setBounds(mainBounds);
|
FOverlay.SINGLETON_INSTANCE.getPanel().setBounds(mainBounds);
|
||||||
FNetOverlay.SINGLETON_INSTANCE.containerResized(mainBounds);
|
FNetOverlay.SINGLETON_INSTANCE.containerResized(mainBounds);
|
||||||
|
|
||||||
pnlInsets.setBounds(mainBounds);
|
final ForgePreferences prefs = Singletons.getModel().getPreferences();
|
||||||
|
final int navigationBarHeight = frame.getShowTitleBar() ? navigationBar.getPreferredSize().height : 0;
|
||||||
|
final int statusBarHeight = prefs.getPrefBoolean(FPref.UI_HIDE_STATUS_BAR) ? 0 : statusBar.getPreferredSize().height;
|
||||||
|
|
||||||
|
navigationBar.setBounds(mainBounds.x, mainBounds.y, mainBounds.width, navigationBarHeight);
|
||||||
|
navigationBar.validate();
|
||||||
|
|
||||||
|
pnlInsets.setBounds(mainBounds.x, mainBounds.y + navigationBarHeight, mainBounds.width, mainBounds.height - navigationBarHeight - statusBarHeight);
|
||||||
pnlInsets.validate();
|
pnlInsets.validate();
|
||||||
|
|
||||||
|
statusBar.setBounds(mainBounds.x, mainBounds.y + mainBounds.height - statusBarHeight, mainBounds.width, statusBarHeight);
|
||||||
|
statusBar.validate();
|
||||||
|
|
||||||
final int w = pnlContent.getWidth();
|
final int w = pnlContent.getWidth();
|
||||||
final int h = pnlContent.getHeight();
|
final int h = pnlContent.getHeight();
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ import forge.gui.deckeditor.controllers.CEditorConstructed;
|
|||||||
import forge.gui.framework.EDocID;
|
import forge.gui.framework.EDocID;
|
||||||
import forge.gui.framework.ICDoc;
|
import forge.gui.framework.ICDoc;
|
||||||
import forge.gui.home.sanctioned.VSubmenuConstructed;
|
import forge.gui.home.sanctioned.VSubmenuConstructed;
|
||||||
import forge.gui.menubar.IMenuProvider;
|
import forge.gui.menus.IMenuProvider;
|
||||||
|
import forge.gui.menus.MenuUtil;
|
||||||
import forge.net.FServer;
|
import forge.net.FServer;
|
||||||
import forge.net.NetServer;
|
import forge.net.NetServer;
|
||||||
import forge.properties.ForgePreferences;
|
import forge.properties.ForgePreferences;
|
||||||
@@ -30,6 +31,8 @@ public enum CHomeUI implements ICDoc, IMenuProvider {
|
|||||||
/** */
|
/** */
|
||||||
SINGLETON_INSTANCE;
|
SINGLETON_INSTANCE;
|
||||||
|
|
||||||
|
Object previousDoc = null;
|
||||||
|
|
||||||
private LblMenuItem lblSelected = new LblMenuItem(VSubmenuConstructed.SINGLETON_INSTANCE);
|
private LblMenuItem lblSelected = new LblMenuItem(VSubmenuConstructed.SINGLETON_INSTANCE);
|
||||||
|
|
||||||
/** Programatically selects a menu item.
|
/** Programatically selects a menu item.
|
||||||
@@ -42,6 +45,12 @@ public enum CHomeUI implements ICDoc, IMenuProvider {
|
|||||||
lblSelected.repaintSelf();
|
lblSelected.repaintSelf();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (previousDoc != null) {
|
||||||
|
if (!previousDoc.equals(id0.getDoc().getLayoutControl())) {
|
||||||
|
MenuUtil.setMenuProvider(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
id0.getDoc().populate();
|
id0.getDoc().populate();
|
||||||
id0.getDoc().getLayoutControl().update();
|
id0.getDoc().getLayoutControl().update();
|
||||||
lblSelected = VHomeUI.SINGLETON_INSTANCE.getAllSubmenuLabels().get(id0);
|
lblSelected = VHomeUI.SINGLETON_INSTANCE.getAllSubmenuLabels().get(id0);
|
||||||
@@ -49,6 +58,8 @@ public enum CHomeUI implements ICDoc, IMenuProvider {
|
|||||||
|
|
||||||
prefs.setPref(FPref.SUBMENU_CURRENTMENU, id0.toString());
|
prefs.setPref(FPref.SUBMENU_CURRENTMENU, id0.toString());
|
||||||
Singletons.getModel().getPreferences().save();
|
Singletons.getModel().getPreferences().save();
|
||||||
|
|
||||||
|
previousDoc = id0.getDoc().getLayoutControl();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param lbl0 {@link forge.gui.home.LblMenuItem} */
|
/** @param lbl0 {@link forge.gui.home.LblMenuItem} */
|
||||||
@@ -113,7 +124,7 @@ public enum CHomeUI implements ICDoc, IMenuProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setupMyMenuBar() {
|
private void setupMyMenuBar() {
|
||||||
Singletons.getControl().getMenuBar().setupMenuBar(this);
|
Singletons.getControl().getForgeMenu().setProvider(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import javax.swing.SwingUtilities;
|
|||||||
|
|
||||||
import forge.Command;
|
import forge.Command;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
|
import forge.card.MagicColor;
|
||||||
import forge.deck.Deck;
|
import forge.deck.Deck;
|
||||||
import forge.deck.DeckSection;
|
import forge.deck.DeckSection;
|
||||||
import forge.game.GameFormat;
|
import forge.game.GameFormat;
|
||||||
@@ -24,6 +25,7 @@ import forge.properties.NewConstants;
|
|||||||
import forge.quest.QuestController;
|
import forge.quest.QuestController;
|
||||||
import forge.quest.QuestMode;
|
import forge.quest.QuestMode;
|
||||||
import forge.quest.QuestWorld;
|
import forge.quest.QuestWorld;
|
||||||
|
import forge.quest.StartingPoolPreferences;
|
||||||
import forge.quest.StartingPoolType;
|
import forge.quest.StartingPoolType;
|
||||||
import forge.quest.data.GameFormatQuest;
|
import forge.quest.data.GameFormatQuest;
|
||||||
import forge.quest.data.QuestData;
|
import forge.quest.data.QuestData;
|
||||||
@@ -246,6 +248,7 @@ public enum CSubmenuQuestData implements ICDoc {
|
|||||||
// } else {
|
// } else {
|
||||||
// fmtPrizes = worldFormat;
|
// fmtPrizes = worldFormat;
|
||||||
// }
|
// }
|
||||||
|
final StartingPoolPreferences userPrefs = new StartingPoolPreferences(false, MagicColor.ALL_COLORS); // To be changed later
|
||||||
|
|
||||||
final Object o = JOptionPane.showInputDialog(null, "Poets will remember your quest as:", "Quest Name", JOptionPane.OK_CANCEL_OPTION);
|
final Object o = JOptionPane.showInputDialog(null, "Poets will remember your quest as:", "Quest Name", JOptionPane.OK_CANCEL_OPTION);
|
||||||
if (o == null) { return; }
|
if (o == null) { return; }
|
||||||
@@ -259,7 +262,7 @@ public enum CSubmenuQuestData implements ICDoc {
|
|||||||
|
|
||||||
QuestController qc = Singletons.getModel().getQuest();
|
QuestController qc = Singletons.getModel().getQuest();
|
||||||
|
|
||||||
qc.newGame(questName, difficulty, mode, fmtPrizes, view.isUnlockSetsAllowed(), dckStartPool, fmtStartPool, view.getStartingWorldName());
|
qc.newGame(questName, difficulty, mode, fmtPrizes, view.isUnlockSetsAllowed(), dckStartPool, fmtStartPool, view.getStartingWorldName(), userPrefs);
|
||||||
Singletons.getModel().getQuest().save();
|
Singletons.getModel().getQuest().save();
|
||||||
|
|
||||||
// Save in preferences.
|
// Save in preferences.
|
||||||
|
|||||||
@@ -18,9 +18,10 @@ import forge.game.Match;
|
|||||||
import forge.game.RegisteredPlayer;
|
import forge.game.RegisteredPlayer;
|
||||||
import forge.game.player.LobbyPlayer;
|
import forge.game.player.LobbyPlayer;
|
||||||
import forge.gui.SOverlayUtils;
|
import forge.gui.SOverlayUtils;
|
||||||
|
import forge.gui.deckchooser.DecksComboBox.DeckType;
|
||||||
import forge.gui.framework.ICDoc;
|
import forge.gui.framework.ICDoc;
|
||||||
import forge.gui.menubar.IMenuProvider;
|
import forge.gui.menus.IMenuProvider;
|
||||||
import forge.gui.menubar.MenuUtil;
|
import forge.gui.menus.MenuUtil;
|
||||||
import forge.gui.toolbox.FComboBox;
|
import forge.gui.toolbox.FComboBox;
|
||||||
import forge.net.FServer;
|
import forge.net.FServer;
|
||||||
import forge.net.Lobby;
|
import forge.net.Lobby;
|
||||||
@@ -64,7 +65,7 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider {
|
|||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update() {
|
||||||
|
|
||||||
MenuUtil.setupMenuBar(this);
|
MenuUtil.setMenuProvider(this);
|
||||||
|
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
@Override public void run() { view.getBtnStart().requestFocusInWindow(); }
|
@Override public void run() { view.getBtnStart().requestFocusInWindow(); }
|
||||||
@@ -79,8 +80,8 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider {
|
|||||||
|
|
||||||
initializeGamePlayersComboBox();
|
initializeGamePlayersComboBox();
|
||||||
|
|
||||||
view.getDcLeft().initialize();
|
view.getDcLeft().initialize(FPref.CONSTRUCTED_P1_DECK_STATE, DeckType.PRECONSTRUCTED_DECK);
|
||||||
view.getDcRight().initialize();
|
view.getDcRight().initialize(FPref.CONSTRUCTED_P2_DECK_STATE, DeckType.COLOR_DECK);
|
||||||
|
|
||||||
// Checkbox event handling
|
// Checkbox event handling
|
||||||
view.getBtnStart().addActionListener(new ActionListener() {
|
view.getBtnStart().addActionListener(new ActionListener() {
|
||||||
@@ -129,6 +130,9 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider {
|
|||||||
SOverlayUtils.startGameOverlay();
|
SOverlayUtils.startGameOverlay();
|
||||||
SOverlayUtils.showOverlay();
|
SOverlayUtils.showOverlay();
|
||||||
|
|
||||||
|
view.getDcLeft().saveState();
|
||||||
|
view.getDcRight().saveState();
|
||||||
|
|
||||||
FThreads.invokeInEdtLater(new Runnable(){
|
FThreads.invokeInEdtLater(new Runnable(){
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import javax.swing.JMenu;
|
|||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
|
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.gui.menubar.MenuUtil;
|
import forge.gui.menus.MenuUtil;
|
||||||
import forge.properties.ForgePreferences;
|
import forge.properties.ForgePreferences;
|
||||||
import forge.properties.ForgePreferences.FPref;
|
import forge.properties.ForgePreferences.FPref;
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public enum VSubmenuConstructed implements IVSubmenu<CSubmenuConstructed> {
|
|||||||
// CTR
|
// CTR
|
||||||
private VSubmenuConstructed() {
|
private VSubmenuConstructed() {
|
||||||
FSkin.get(lblTitle).setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
|
FSkin.get(lblTitle).setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
|
||||||
cboGamePlayers.setButtonVisible(false);
|
cboGamePlayers.setButtonVisible(true);
|
||||||
cboGamePlayers.setTextAlignment(TextAlignment.CENTER);
|
cboGamePlayers.setTextAlignment(TextAlignment.CENTER);
|
||||||
FSkin.get(cboGamePlayers).setFont(FSkin.getBoldFont(16));
|
FSkin.get(cboGamePlayers).setFont(FSkin.getBoldFont(16));
|
||||||
}
|
}
|
||||||
@@ -92,7 +92,7 @@ public enum VSubmenuConstructed implements IVSubmenu<CSubmenuConstructed> {
|
|||||||
container.removeAll();
|
container.removeAll();
|
||||||
container.setLayout(new MigLayout("insets 0, gap 0, wrap 2"));
|
container.setLayout(new MigLayout("insets 0, gap 0, wrap 2"));
|
||||||
container.add(lblTitle, "w 80%, h 40px!, gap 0 0 15px 15px, span 2, al right, pushx");
|
container.add(lblTitle, "w 80%, h 40px!, gap 0 0 15px 15px, span 2, al right, pushx");
|
||||||
container.add(cboGamePlayers, "w 400px!, h 40px!, gap 0 0 15px 5px, span 2, al center");
|
container.add(cboGamePlayers, "w 400px!, h 30px!, gap 0 0 15px 5px, span 2, al center");
|
||||||
container.add(dcLeft, "w 50%, gap 40px 20px 20px 5px, growy, pushy");
|
container.add(dcLeft, "w 50%, gap 40px 20px 20px 5px, growy, pushy");
|
||||||
container.add(dcRight, "w 50%, gap 20px 40px 20px 5px, growy, pushy");
|
container.add(dcRight, "w 50%, gap 20px 40px 20px 5px, growy, pushy");
|
||||||
container.add(btnStart, "span 2, gap 0 0 0px 20px, center");
|
container.add(btnStart, "span 2, gap 0 0 0px 20px, center");
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ import forge.gui.match.nonsingleton.VCommand;
|
|||||||
import forge.gui.match.nonsingleton.VField;
|
import forge.gui.match.nonsingleton.VField;
|
||||||
import forge.gui.match.nonsingleton.VHand;
|
import forge.gui.match.nonsingleton.VHand;
|
||||||
import forge.gui.match.views.VPlayers;
|
import forge.gui.match.views.VPlayers;
|
||||||
import forge.gui.menubar.IMenuProvider;
|
import forge.gui.menus.IMenuProvider;
|
||||||
import forge.gui.toolbox.FSkin;
|
import forge.gui.toolbox.FSkin;
|
||||||
import forge.gui.toolbox.FSkin.SkinImage;
|
import forge.gui.toolbox.FSkin.SkinImage;
|
||||||
import forge.gui.toolbox.special.PhaseLabel;
|
import forge.gui.toolbox.special.PhaseLabel;
|
||||||
@@ -422,7 +422,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
Singletons.getControl().getMenuBar().setupMenuBar(this);
|
Singletons.getControl().getForgeMenu().setProvider(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import javax.swing.SwingUtilities;
|
|||||||
|
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.gui.match.CMatchUI;
|
import forge.gui.match.CMatchUI;
|
||||||
import forge.gui.menubar.MenuUtil;
|
import forge.gui.menus.MenuUtil;
|
||||||
import forge.properties.ForgePreferences;
|
import forge.properties.ForgePreferences;
|
||||||
import forge.properties.ForgePreferences.FPref;
|
import forge.properties.ForgePreferences.FPref;
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import javax.swing.event.MenuListener;
|
|||||||
|
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.gui.match.controllers.CDev;
|
import forge.gui.match.controllers.CDev;
|
||||||
import forge.gui.menubar.MenuUtil;
|
import forge.gui.menus.MenuUtil;
|
||||||
import forge.properties.ForgePreferences;
|
import forge.properties.ForgePreferences;
|
||||||
import forge.properties.ForgePreferences.FPref;
|
import forge.properties.ForgePreferences.FPref;
|
||||||
|
|
||||||
@@ -93,11 +93,11 @@ public class DevModeMenu implements ActionListener {
|
|||||||
return new MenuListener() {
|
return new MenuListener() {
|
||||||
@Override
|
@Override
|
||||||
public void menuSelected(MenuEvent arg0) {
|
public void menuSelected(MenuEvent arg0) {
|
||||||
Singletons.getControl().getMenuBar().setStatusText("Options for testing during development");
|
Singletons.getView().getStatusBar().setStatusText("Options for testing during development");
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void menuDeselected(MenuEvent arg0) {
|
public void menuDeselected(MenuEvent arg0) {
|
||||||
Singletons.getControl().getMenuBar().setStatusText("");
|
Singletons.getView().getStatusBar().setStatusText("");
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void menuCanceled(MenuEvent arg0) { }
|
public void menuCanceled(MenuEvent arg0) { }
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import javax.swing.JRadioButtonMenuItem;
|
|||||||
|
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.gui.match.controllers.CDock;
|
import forge.gui.match.controllers.CDock;
|
||||||
import forge.gui.menubar.MenuUtil;
|
import forge.gui.menus.MenuUtil;
|
||||||
import forge.gui.toolbox.FSkin;
|
import forge.gui.toolbox.FSkin;
|
||||||
import forge.gui.toolbox.FSkin.SkinIcon;
|
import forge.gui.toolbox.FSkin.SkinIcon;
|
||||||
import forge.gui.toolbox.FSkin.SkinProp;
|
import forge.gui.toolbox.FSkin.SkinProp;
|
||||||
|
|||||||
@@ -1,110 +0,0 @@
|
|||||||
package forge.gui.menubar;
|
|
||||||
|
|
||||||
import java.awt.Component;
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.swing.Box;
|
|
||||||
import javax.swing.JLabel;
|
|
||||||
import javax.swing.JMenu;
|
|
||||||
import javax.swing.JMenuBar;
|
|
||||||
|
|
||||||
import forge.gui.menus.ForgeMenu;
|
|
||||||
import forge.gui.menus.HelpMenu;
|
|
||||||
import forge.gui.menus.LayoutMenu;
|
|
||||||
import forge.gui.toolbox.FSkin;
|
|
||||||
import forge.gui.toolbox.FSkin.JLabelSkin;
|
|
||||||
import forge.view.FFrame;
|
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
public class FMenuBar extends JMenuBar {
|
|
||||||
private final FFrame frame;
|
|
||||||
private String statusText;
|
|
||||||
private JLabel lblStatus;
|
|
||||||
private IMenuProvider provider;
|
|
||||||
|
|
||||||
public FMenuBar(FFrame f) {
|
|
||||||
this.frame = f;
|
|
||||||
setVisible(false); //hide by default until prefs decide whether to show it
|
|
||||||
super.setVisible(true); //ensure super is visible since setVisible overriden to only set height to 0 to hide
|
|
||||||
f.getInnerPane().setJMenuBar(this);
|
|
||||||
refresh();
|
|
||||||
setStatusText(""); //set default status text
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setupMenuBar(IMenuProvider provider0) {
|
|
||||||
provider = provider0;
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void refresh() {
|
|
||||||
removeAll();
|
|
||||||
add(ForgeMenu.getMenu());
|
|
||||||
addProviderMenus();
|
|
||||||
add(LayoutMenu.getMenu());
|
|
||||||
add(HelpMenu.getMenu());
|
|
||||||
addStatusLabel();
|
|
||||||
revalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a label to the right-hand side of the MenuBar which can
|
|
||||||
* be used to show hints or status information.
|
|
||||||
*/
|
|
||||||
private void addStatusLabel() {
|
|
||||||
add(Box.createHorizontalGlue()); // align right hack/patch.
|
|
||||||
lblStatus = new JLabel(statusText);
|
|
||||||
JLabelSkin<JLabel> labelSkin = FSkin.get(lblStatus);
|
|
||||||
if (FSkin.isLookAndFeelSet()) {
|
|
||||||
labelSkin.setForeground(FSkin.getColor(FSkin.Colors.CLR_TEXT));
|
|
||||||
}
|
|
||||||
else { //ensure status is visible on default menu bar
|
|
||||||
labelSkin.setForeground(getForeground());
|
|
||||||
}
|
|
||||||
labelSkin.setFont(FSkin.getItalicFont(11));
|
|
||||||
lblStatus.setOpaque(false);
|
|
||||||
add(lblStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatusText(String text) {
|
|
||||||
statusText = text.trim();
|
|
||||||
if (statusText.isEmpty()) {
|
|
||||||
statusText = "F1 : hide menu"; //show shortcut to hide menu if no other status to show
|
|
||||||
}
|
|
||||||
statusText += " "; //add padding from right edge of menu bar
|
|
||||||
lblStatus.setText(statusText);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addProviderMenus() {
|
|
||||||
if (provider != null) {
|
|
||||||
List<JMenu> menus = provider.getMenus();
|
|
||||||
if (menus != null) {
|
|
||||||
for (JMenu m : menus) {
|
|
||||||
m.setBorderPainted(false);
|
|
||||||
add(m);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see javax.swing.JComponent#setEnabled(boolean)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setEnabled(boolean enabled) {
|
|
||||||
super.setEnabled(enabled);
|
|
||||||
for (Component c : getComponents()) {
|
|
||||||
c.setEnabled(enabled);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see javax.swing.JComponent#setVisible(boolean)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setVisible(boolean visible) {
|
|
||||||
//use height 0 to hide rather than setting visible to false to allow menu item accelerators to work
|
|
||||||
setPreferredSize(new Dimension(this.frame.getWidth(), visible ? 22 : 0));
|
|
||||||
revalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +1,130 @@
|
|||||||
package forge.gui.menus;
|
package forge.gui.menus;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.swing.JMenu;
|
import javax.swing.JMenu;
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
|
import javax.swing.JPopupMenu;
|
||||||
|
import javax.swing.KeyStroke;
|
||||||
|
import javax.swing.event.PopupMenuEvent;
|
||||||
|
import javax.swing.event.PopupMenuListener;
|
||||||
|
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.control.RestartUtil;
|
import forge.control.RestartUtil;
|
||||||
import forge.control.FControl.Screens;
|
import forge.control.FControl.Screens;
|
||||||
import forge.gui.menubar.MenuUtil;
|
import forge.util.TypeUtil;
|
||||||
|
|
||||||
public final class ForgeMenu {
|
public final class ForgeMenu {
|
||||||
private ForgeMenu() { }
|
private static final int minItemWidth = 100;
|
||||||
|
private static final int itemHeight = 25;
|
||||||
|
|
||||||
public static JMenu getMenu() {
|
private JPopupMenu popupMenu;
|
||||||
JMenu menu = new JMenu("Forge");
|
private IMenuProvider provider;
|
||||||
menu.setMnemonic(KeyEvent.VK_F);
|
private static HashMap<KeyStroke, JMenuItem> activeShortcuts = new HashMap<KeyStroke, JMenuItem>();
|
||||||
menu.add(getMenuItem_Restart());
|
|
||||||
menu.add(getMenuItem_Exit());
|
public ForgeMenu() {
|
||||||
return menu;
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static JMenuItem getMenuItem_Exit() {
|
public void show() {
|
||||||
JMenuItem menuItem = new JMenuItem("Exit");
|
show(false);
|
||||||
menuItem.addActionListener(getExitAction());
|
|
||||||
return menuItem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ActionListener getExitAction() {
|
public void show(boolean hideIfAlreadyShown) {
|
||||||
return new ActionListener() {
|
Singletons.getView().getNavigationBar().showForgeMenu(hideIfAlreadyShown);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hide() {
|
||||||
|
popupMenu.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JPopupMenu getPopupMenu() {
|
||||||
|
return popupMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProvider(IMenuProvider provider0) {
|
||||||
|
provider = provider0;
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refresh() {
|
||||||
|
activeShortcuts.clear();
|
||||||
|
popupMenu = new JPopupMenu();
|
||||||
|
popupMenu.addPopupMenuListener(new PopupMenuListener() {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void popupMenuWillBecomeInvisible(PopupMenuEvent popupMenuEvent) {
|
||||||
if (!isHomeScreenActive()) {
|
Singletons.getView().getNavigationBar().onForgeMenuHidden();
|
||||||
String userPrompt = "Please confirm you want to close Forge.\n\n";
|
}
|
||||||
if (!MenuUtil.getUserConfirmation(userPrompt, "Exit Forge")) {
|
@Override
|
||||||
return;
|
public void popupMenuWillBecomeVisible(PopupMenuEvent popupMenuEvent) {}
|
||||||
|
@Override
|
||||||
|
public void popupMenuCanceled(PopupMenuEvent popupMenuEvent) {}
|
||||||
|
});
|
||||||
|
if (provider != null) {
|
||||||
|
List<JMenu> menus = provider.getMenus();
|
||||||
|
if (menus != null) {
|
||||||
|
for (JMenu m : menus) {
|
||||||
|
m.setBorderPainted(false);
|
||||||
|
add(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.exit(0);
|
|
||||||
}
|
}
|
||||||
};
|
add(LayoutMenu.getMenu());
|
||||||
|
add(HelpMenu.getMenu());
|
||||||
|
addSeparator();
|
||||||
|
add(getMenuItem_Restart());
|
||||||
|
add(getMenuItem_Exit());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(JMenuItem item) {
|
||||||
|
item = popupMenu.add(item);
|
||||||
|
setupItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addSeparator() {
|
||||||
|
popupMenu.addSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupMenu(JMenu menu) {
|
||||||
|
for (int i = 0; i < menu.getItemCount(); i++) {
|
||||||
|
setupItem(menu.getItem(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupItem(JMenuItem item) {
|
||||||
|
if (item == null) { return; }
|
||||||
|
|
||||||
|
item.setPreferredSize(new Dimension(Math.max(item.getPreferredSize().width, minItemWidth), itemHeight));
|
||||||
|
|
||||||
|
KeyStroke shortcut = item.getAccelerator();
|
||||||
|
if (shortcut != null) {
|
||||||
|
activeShortcuts.put(shortcut, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
JMenu subMenu = TypeUtil.safeCast(item, JMenu.class);
|
||||||
|
if (subMenu != null) {
|
||||||
|
setupMenu(subMenu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean handleKeyEvent(KeyEvent e) {
|
||||||
|
JMenuItem item = activeShortcuts.get(KeyStroke.getKeyStrokeForEvent(e));
|
||||||
|
if (item != null) {
|
||||||
|
hide(); //ensure menu doesn't stay open if currently open
|
||||||
|
item.doClick();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static JMenuItem getMenuItem_Restart() {
|
private static JMenuItem getMenuItem_Restart() {
|
||||||
JMenuItem menuItem = new JMenuItem("Restart");
|
JMenuItem menuItem = new JMenuItem("Restart");
|
||||||
|
menuItem.setMnemonic(KeyEvent.VK_R);
|
||||||
menuItem.addActionListener(getRestartAction());
|
menuItem.addActionListener(getRestartAction());
|
||||||
return menuItem;
|
return menuItem;
|
||||||
}
|
}
|
||||||
@@ -63,8 +144,29 @@ public final class ForgeMenu {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static JMenuItem getMenuItem_Exit() {
|
||||||
|
JMenuItem menuItem = new JMenuItem("Exit");
|
||||||
|
menuItem.setMnemonic(KeyEvent.VK_X);
|
||||||
|
menuItem.addActionListener(getExitAction());
|
||||||
|
return menuItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ActionListener getExitAction() {
|
||||||
|
return new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
if (!isHomeScreenActive()) {
|
||||||
|
String userPrompt = "Please confirm you want to close Forge.\n\n";
|
||||||
|
if (!MenuUtil.getUserConfirmation(userPrompt, "Exit Forge")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean isHomeScreenActive() {
|
private static boolean isHomeScreenActive() {
|
||||||
return Singletons.getControl().getState() == Screens.HOME_SCREEN;
|
return Singletons.getControl().getState() == Screens.HOME_SCREEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import java.io.IOException;
|
|||||||
|
|
||||||
import javax.swing.JMenu;
|
import javax.swing.JMenu;
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
import forge.gui.menubar.MenuUtil;
|
|
||||||
import forge.util.FileUtil;
|
import forge.util.FileUtil;
|
||||||
|
|
||||||
public final class HelpMenu {
|
public final class HelpMenu {
|
||||||
@@ -47,7 +47,7 @@ public final class HelpMenu {
|
|||||||
JMenu mnu = new JMenu("Getting Started");
|
JMenu mnu = new JMenu("Getting Started");
|
||||||
mnu.add(getMenuItem_HowToPlayFile());
|
mnu.add(getMenuItem_HowToPlayFile());
|
||||||
mnu.addSeparator();
|
mnu.addSeparator();
|
||||||
mnu.add(getMenuItem_UrlLink("Forge Wiki", "http://www.slightlymagic.net/wiki/Forge"));
|
mnu.add(getMenuItem_UrlLink("Forge Wiki", "http://www.slightlymagic.net/wiki/Forge", KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0)));
|
||||||
mnu.add(getMenuItem_UrlLink("What is Forge?", "http://www.slightlymagic.net/forum/viewtopic.php?f=26&t=468"));
|
mnu.add(getMenuItem_UrlLink("What is Forge?", "http://www.slightlymagic.net/forum/viewtopic.php?f=26&t=468"));
|
||||||
return mnu;
|
return mnu;
|
||||||
}
|
}
|
||||||
@@ -113,13 +113,18 @@ public final class HelpMenu {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static JMenuItem getMenuItem_UrlLink(String caption, String url) {
|
private static JMenuItem getMenuItem_UrlLink(String caption, String url) {
|
||||||
JMenuItem menuItem = new JMenuItem(caption);
|
JMenuItem menuItem = new JMenuItem(caption);
|
||||||
menuItem.addActionListener(getLaunchUrlAction(url));
|
menuItem.addActionListener(getLaunchUrlAction(url));
|
||||||
return menuItem;
|
return menuItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static JMenuItem getMenuItem_UrlLink(String caption, String url, KeyStroke accelerator) {
|
||||||
|
JMenuItem menuItem = getMenuItem_UrlLink(caption, url);
|
||||||
|
menuItem.setAccelerator(accelerator);
|
||||||
|
return menuItem;
|
||||||
|
}
|
||||||
|
|
||||||
private static ActionListener getLaunchUrlAction(final String url) {
|
private static ActionListener getLaunchUrlAction(final String url) {
|
||||||
return new ActionListener() {
|
return new ActionListener() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package forge.gui.menubar;
|
package forge.gui.menus;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -17,11 +17,12 @@ import forge.control.FControl.Screens;
|
|||||||
import forge.gui.GuiChoose;
|
import forge.gui.GuiChoose;
|
||||||
import forge.gui.MouseUtil;
|
import forge.gui.MouseUtil;
|
||||||
import forge.gui.MouseUtil.MouseCursor;
|
import forge.gui.MouseUtil.MouseCursor;
|
||||||
|
import forge.gui.framework.SResizingUtil;
|
||||||
import forge.gui.match.controllers.CDock;
|
import forge.gui.match.controllers.CDock;
|
||||||
import forge.gui.menubar.MenuUtil;
|
|
||||||
import forge.gui.toolbox.FSkin;
|
import forge.gui.toolbox.FSkin;
|
||||||
import forge.properties.ForgePreferences;
|
import forge.properties.ForgePreferences;
|
||||||
import forge.properties.ForgePreferences.FPref;
|
import forge.properties.ForgePreferences.FPref;
|
||||||
|
import forge.view.FFrame;
|
||||||
import forge.view.FView;
|
import forge.view.FView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,9 +33,9 @@ import forge.view.FView;
|
|||||||
public final class LayoutMenu {
|
public final class LayoutMenu {
|
||||||
private LayoutMenu() { }
|
private LayoutMenu() { }
|
||||||
|
|
||||||
private static CDock controller = CDock.SINGLETON_INSTANCE;
|
private static final CDock controller = CDock.SINGLETON_INSTANCE;
|
||||||
private static Screens currentScreen;
|
private static Screens currentScreen;
|
||||||
private static ForgePreferences prefs = Singletons.getModel().getPreferences();
|
private static final ForgePreferences prefs = Singletons.getModel().getPreferences();
|
||||||
private static boolean showIcons = false;
|
private static boolean showIcons = false;
|
||||||
|
|
||||||
public static JMenu getMenu() {
|
public static JMenu getMenu() {
|
||||||
@@ -58,6 +59,7 @@ public final class LayoutMenu {
|
|||||||
private static JMenu getMenu_ViewOptions() {
|
private static JMenu getMenu_ViewOptions() {
|
||||||
JMenu menu = new JMenu("View");
|
JMenu menu = new JMenu("View");
|
||||||
menu.add(getMenuItem_ShowTitleBar());
|
menu.add(getMenuItem_ShowTitleBar());
|
||||||
|
menu.add(getMenuItem_ShowStatusBar());
|
||||||
if (currentScreen != Screens.HOME_SCREEN) {
|
if (currentScreen != Screens.HOME_SCREEN) {
|
||||||
menu.add(getMenuItem_ShowTabs());
|
menu.add(getMenuItem_ShowTabs());
|
||||||
}
|
}
|
||||||
@@ -139,14 +141,15 @@ public final class LayoutMenu {
|
|||||||
boolean showTabs = menuItem.getState();
|
boolean showTabs = menuItem.getState();
|
||||||
FView.SINGLETON_INSTANCE.refreshAllCellLayouts(showTabs);
|
FView.SINGLETON_INSTANCE.refreshAllCellLayouts(showTabs);
|
||||||
prefs.setPref(FPref.UI_HIDE_GAME_TABS, !showTabs);
|
prefs.setPref(FPref.UI_HIDE_GAME_TABS, !showTabs);
|
||||||
|
prefs.save();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static JMenuItem getMenuItem_ShowTitleBar() {
|
private static JMenuItem getMenuItem_ShowTitleBar() {
|
||||||
final JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem("Titlebar");
|
final JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem("Title Bar");
|
||||||
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F11, 0));
|
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F11, 0));
|
||||||
menuItem.setState(Singletons.getView().getFrame().getShowTitleBar());
|
menuItem.setState(!prefs.getPrefBoolean(FPref.UI_HIDE_TITLE_BAR));
|
||||||
menuItem.addActionListener(getShowTitleBarAction(menuItem));
|
menuItem.addActionListener(getShowTitleBarAction(menuItem));
|
||||||
return menuItem;
|
return menuItem;
|
||||||
}
|
}
|
||||||
@@ -155,7 +158,37 @@ public final class LayoutMenu {
|
|||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
boolean showTitleBar = menuItem.getState();
|
boolean showTitleBar = menuItem.getState();
|
||||||
Singletons.getView().getFrame().setShowTitleBar(showTitleBar);
|
final FFrame frame = Singletons.getView().getFrame();
|
||||||
|
if (showTitleBar && !frame.getMaximized()) {
|
||||||
|
//if titlebar toggled back on while frame not maximized (likely using F11), instead just maximize frame
|
||||||
|
frame.setMaximized(true);
|
||||||
|
menuItem.setState(false); //reset menu item state in this case
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
prefs.setPref(FPref.UI_HIDE_TITLE_BAR, !showTitleBar);
|
||||||
|
prefs.save();
|
||||||
|
frame.setShowTitleBar(showTitleBar);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JMenuItem getMenuItem_ShowStatusBar() {
|
||||||
|
final JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem("Status Bar");
|
||||||
|
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F12, 0));
|
||||||
|
menuItem.setState(!prefs.getPrefBoolean(FPref.UI_HIDE_STATUS_BAR));
|
||||||
|
menuItem.addActionListener(getShowStatusBarAction(menuItem));
|
||||||
|
return menuItem;
|
||||||
|
}
|
||||||
|
private static ActionListener getShowStatusBarAction(final JCheckBoxMenuItem menuItem) {
|
||||||
|
return new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
boolean showStatusBar = menuItem.getState();
|
||||||
|
prefs.setPref(FPref.UI_HIDE_STATUS_BAR, !showStatusBar);
|
||||||
|
prefs.save();
|
||||||
|
Singletons.getView().getStatusBar().setVisible(showStatusBar);
|
||||||
|
Singletons.getView().getNavigationBar().updateClockVisibility();
|
||||||
|
SResizingUtil.resizeWindow();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package forge.gui.menubar;
|
package forge.gui.menus;
|
||||||
|
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -14,21 +14,12 @@ import forge.Singletons;
|
|||||||
import forge.gui.toolbox.FSkin;
|
import forge.gui.toolbox.FSkin;
|
||||||
import forge.gui.toolbox.FSkin.SkinProp;
|
import forge.gui.toolbox.FSkin.SkinProp;
|
||||||
import forge.gui.toolbox.imaging.ImageUtil;
|
import forge.gui.toolbox.imaging.ImageUtil;
|
||||||
import forge.properties.ForgePreferences;
|
|
||||||
import forge.properties.ForgePreferences.FPref;
|
|
||||||
|
|
||||||
public final class MenuUtil {
|
public final class MenuUtil {
|
||||||
private MenuUtil() { }
|
private MenuUtil() { }
|
||||||
|
|
||||||
private static ForgePreferences prefs = Singletons.getModel().getPreferences();
|
|
||||||
|
|
||||||
// Get appropriate OS standard accelerator key for menu shortcuts.
|
// Get appropriate OS standard accelerator key for menu shortcuts.
|
||||||
private static final int DEFAULT_MenuShortcutKeyMask =
|
private static final int DEFAULT_MenuShortcutKeyMask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
|
||||||
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
|
|
||||||
|
|
||||||
public static boolean isMenuBarVisible() {
|
|
||||||
return !prefs.getPrefBoolean(FPref.UI_HIDE_MENUBAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void openUrlInBrowser(String url) {
|
public static void openUrlInBrowser(String url) {
|
||||||
try {
|
try {
|
||||||
@@ -61,8 +52,8 @@ public final class MenuUtil {
|
|||||||
return (reply == JOptionPane.YES_OPTION);
|
return (reply == JOptionPane.YES_OPTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setupMenuBar(IMenuProvider provider) {
|
public static void setMenuProvider(IMenuProvider provider) {
|
||||||
Singletons.getControl().getMenuBar().setupMenuBar(provider);
|
Singletons.getControl().getForgeMenu().setProvider(provider);
|
||||||
}
|
}
|
||||||
public static void setMenuHint(final JMenuItem menu, final String hint) {
|
public static void setMenuHint(final JMenuItem menu, final String hint) {
|
||||||
menu.addChangeListener(new ChangeListener() {
|
menu.addChangeListener(new ChangeListener() {
|
||||||
@@ -70,9 +61,9 @@ public final class MenuUtil {
|
|||||||
public void stateChanged(ChangeEvent e) {
|
public void stateChanged(ChangeEvent e) {
|
||||||
JMenuItem item = (JMenuItem) e.getSource();
|
JMenuItem item = (JMenuItem) e.getSource();
|
||||||
if (item.isArmed() || (item.isSelected() && e.getSource() instanceof JMenu)) {
|
if (item.isArmed() || (item.isSelected() && e.getSource() instanceof JMenu)) {
|
||||||
Singletons.getControl().getMenuBar().setStatusText(hint);
|
Singletons.getView().getStatusBar().setStatusText(hint);
|
||||||
} else {
|
} else {
|
||||||
Singletons.getControl().getMenuBar().setStatusText("");
|
Singletons.getView().getStatusBar().setStatusText("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -3,6 +3,7 @@ package forge.gui.toolbox;
|
|||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
@@ -14,22 +15,35 @@ import javax.swing.Timer;
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class FDigitalClock extends JLabel {
|
public class FDigitalClock extends JLabel {
|
||||||
private final Calendar now = Calendar.getInstance();
|
private static final Calendar now = Calendar.getInstance();
|
||||||
|
private static final DateFormat timeFormatter = DateFormat.getTimeInstance(DateFormat.SHORT);
|
||||||
|
private static final ArrayList<FDigitalClock> clocks = new ArrayList<FDigitalClock>();
|
||||||
|
private static Timer timer;
|
||||||
|
private static String currentTimeDisplay;
|
||||||
|
|
||||||
public FDigitalClock() {
|
public FDigitalClock() {
|
||||||
Timer timer = new Timer(60000, new ActionListener() {
|
clocks.add(this);
|
||||||
|
if (timer == null) {
|
||||||
|
timer = new Timer(60000, new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
now.add(Calendar.MINUTE, 1);
|
now.add(Calendar.MINUTE, 1);
|
||||||
updateDisplay();
|
updateTimeDisplay();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
updateDisplay();
|
updateTimeDisplay();
|
||||||
//ensure timer starts when current minute ends
|
//ensure timer starts when current minute ends
|
||||||
timer.setInitialDelay(60000 - (now.get(Calendar.MILLISECOND) + now.get(Calendar.SECOND) * 1000));
|
timer.setInitialDelay(60000 - (now.get(Calendar.MILLISECOND) + now.get(Calendar.SECOND) * 1000));
|
||||||
timer.start();
|
timer.start();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
setText(currentTimeDisplay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateDisplay() {
|
private static void updateTimeDisplay() {
|
||||||
setText(DateFormat.getTimeInstance(DateFormat.SHORT).format(now.getTime()));
|
currentTimeDisplay = timeFormatter.format(now.getTime());
|
||||||
|
for (FDigitalClock clock : clocks) {
|
||||||
|
clock.setText(currentTimeDisplay);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1631,7 +1631,7 @@ public enum FSkin {
|
|||||||
ComponentSkin.reapplyAll();
|
ComponentSkin.reapplyAll();
|
||||||
|
|
||||||
//refresh certain components skinned via look and feel
|
//refresh certain components skinned via look and feel
|
||||||
Singletons.getControl().getMenuBar().refresh();
|
Singletons.getControl().getForgeMenu().refresh();
|
||||||
FComboBoxWrapper.refreshAllSkins();
|
FComboBoxWrapper.refreshAllSkins();
|
||||||
FComboBoxPanel.refreshAllSkins();
|
FComboBoxPanel.refreshAllSkins();
|
||||||
CSubmenuPreferences.SINGLETON_INSTANCE.updateCurrentSkin();
|
CSubmenuPreferences.SINGLETON_INSTANCE.updateCurrentSkin();
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ package forge.gui.toolbox.itemmanager;
|
|||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -280,29 +279,9 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
|
|||||||
*/
|
*/
|
||||||
public void addItems(Iterable<Map.Entry<T, Integer>> itemsToAdd) {
|
public void addItems(Iterable<Map.Entry<T, Integer>> itemsToAdd) {
|
||||||
final int n = this.table.getSelectedRow();
|
final int n = this.table.getSelectedRow();
|
||||||
for (Map.Entry<T, Integer> item : itemsToAdd) {
|
this.pool.addAll(itemsToAdd);
|
||||||
this.pool.add(item.getKey(), item.getValue());
|
|
||||||
if (this.isUnfiltered()) {
|
if (this.isUnfiltered()) {
|
||||||
this.model.addItem(item.getKey(), item.getValue());
|
this.model.addItems(itemsToAdd);
|
||||||
}
|
|
||||||
}
|
|
||||||
this.updateView(false);
|
|
||||||
this.table.fixSelection(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* addItems.
|
|
||||||
*
|
|
||||||
* @param itemsToAdd
|
|
||||||
*/
|
|
||||||
public void addItems(Collection<T> itemsToAdd) {
|
|
||||||
final int n = this.table.getSelectedRow();
|
|
||||||
for (T item : itemsToAdd) {
|
|
||||||
this.pool.add(item, 1);
|
|
||||||
if (this.isUnfiltered()) {
|
|
||||||
this.model.addItem(item, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this.updateView(false);
|
this.updateView(false);
|
||||||
this.table.fixSelection(n);
|
this.table.fixSelection(n);
|
||||||
|
|||||||
@@ -111,12 +111,12 @@ public class ItemPool<T extends InventoryItem> extends ItemPoolView<T> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.getItems().put(item, Integer.valueOf(this.count(item) + amount));
|
this.getItems().put(item, Integer.valueOf(this.count(item) + amount));
|
||||||
this.setListInSync(false);
|
this.isListInSync = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void put(final T item, final int amount) {
|
private void put(final T item, final int amount) {
|
||||||
this.getItems().put(item, amount);
|
this.getItems().put(item, amount);
|
||||||
this.setListInSync(false);
|
this.isListInSync = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -134,7 +134,7 @@ public class ItemPool<T extends InventoryItem> extends ItemPoolView<T> {
|
|||||||
this.add((T) cr);
|
this.add((T) cr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.setListInSync(false);
|
this.isListInSync = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -153,7 +153,7 @@ public class ItemPool<T extends InventoryItem> extends ItemPoolView<T> {
|
|||||||
this.add((T) e.getKey(), e.getValue());
|
this.add((T) e.getKey(), e.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.setListInSync(false);
|
this.isListInSync = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -186,7 +186,7 @@ public class ItemPool<T extends InventoryItem> extends ItemPoolView<T> {
|
|||||||
} else {
|
} else {
|
||||||
this.getItems().put(item, count - amount);
|
this.getItems().put(item, count - amount);
|
||||||
}
|
}
|
||||||
this.setListInSync(false);
|
this.isListInSync = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,6 +222,6 @@ public class ItemPool<T extends InventoryItem> extends ItemPoolView<T> {
|
|||||||
*/
|
*/
|
||||||
public void clear() {
|
public void clear() {
|
||||||
this.getItems().clear();
|
this.getItems().clear();
|
||||||
this.setListInSync(false);
|
this.isListInSync = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ public class ItemPoolView<T extends InventoryItem> implements Iterable<Entry<T,
|
|||||||
private final transient List<Entry<T, Integer>> itemsOrdered = new ArrayList<Map.Entry<T, Integer>>();
|
private final transient List<Entry<T, Integer>> itemsOrdered = new ArrayList<Map.Entry<T, Integer>>();
|
||||||
|
|
||||||
/** Whether list is in sync. */
|
/** Whether list is in sync. */
|
||||||
private transient boolean isListInSync = false;
|
protected transient boolean isListInSync = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* iterator.
|
* iterator.
|
||||||
@@ -188,7 +188,7 @@ public class ItemPoolView<T extends InventoryItem> implements Iterable<Entry<T,
|
|||||||
* @return List<Entry<T, Integer>>
|
* @return List<Entry<T, Integer>>
|
||||||
*/
|
*/
|
||||||
public final List<Entry<T, Integer>> getOrderedList() {
|
public final List<Entry<T, Integer>> getOrderedList() {
|
||||||
if (!this.isListInSync()) {
|
if (!this.isListInSync) {
|
||||||
this.rebuildOrderedList();
|
this.rebuildOrderedList();
|
||||||
}
|
}
|
||||||
return this.itemsOrdered;
|
return this.itemsOrdered;
|
||||||
@@ -201,7 +201,7 @@ public class ItemPoolView<T extends InventoryItem> implements Iterable<Entry<T,
|
|||||||
this.itemsOrdered.add(e);
|
this.itemsOrdered.add(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.setListInSync(true);
|
this.isListInSync = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -238,24 +238,6 @@ public class ItemPoolView<T extends InventoryItem> implements Iterable<Entry<T,
|
|||||||
return this.myClass;
|
return this.myClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if is list in sync.
|
|
||||||
*
|
|
||||||
* @return the isListInSync
|
|
||||||
*/
|
|
||||||
public boolean isListInSync() {
|
|
||||||
return this.isListInSync;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the list in sync.
|
|
||||||
*
|
|
||||||
* @param isListInSync0
|
|
||||||
* the isListInSync to set
|
|
||||||
*/
|
|
||||||
protected void setListInSync(final boolean isListInSync0) {
|
|
||||||
this.isListInSync = isListInSync0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To item list string.
|
* To item list string.
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ public class ForgePreferences extends PreferencesStore<ForgePreferences.FPref> {
|
|||||||
* Preference identifiers, and their default values.
|
* Preference identifiers, and their default values.
|
||||||
*/
|
*/
|
||||||
public static enum FPref {
|
public static enum FPref {
|
||||||
|
CONSTRUCTED_P1_DECK_STATE(""),
|
||||||
|
CONSTRUCTED_P2_DECK_STATE(""),
|
||||||
CONSTRUCTED_GAMEPLAYERS(""),
|
CONSTRUCTED_GAMEPLAYERS(""),
|
||||||
UI_COMPACT_MAIN_MENU ("false"),
|
UI_COMPACT_MAIN_MENU ("false"),
|
||||||
UI_USE_OLD ("false"),
|
UI_USE_OLD ("false"),
|
||||||
@@ -64,7 +66,8 @@ public class ForgePreferences extends PreferencesStore<ForgePreferences.FPref> {
|
|||||||
UI_CLONE_MODE_SOURCE ("false"), /** */
|
UI_CLONE_MODE_SOURCE ("false"), /** */
|
||||||
UI_MATCH_IMAGE_VISIBLE ("true"),
|
UI_MATCH_IMAGE_VISIBLE ("true"),
|
||||||
UI_THEMED_COMBOBOX ("true"),
|
UI_THEMED_COMBOBOX ("true"),
|
||||||
UI_HIDE_MENUBAR ("false"), // Dev setting only - cannot be set from GUI.
|
UI_HIDE_TITLE_BAR ("false"),
|
||||||
|
UI_HIDE_STATUS_BAR ("false"),
|
||||||
UI_HIDE_GAME_TABS ("false"), // Visibility of tabs in match screen.
|
UI_HIDE_GAME_TABS ("false"), // Visibility of tabs in match screen.
|
||||||
|
|
||||||
UI_FOR_TOUCHSCREN("false"),
|
UI_FOR_TOUCHSCREN("false"),
|
||||||
|
|||||||
@@ -64,10 +64,13 @@ public final class BoosterUtils {
|
|||||||
* the num uncommon
|
* the num uncommon
|
||||||
* @param numRare
|
* @param numRare
|
||||||
* the num rare
|
* the num rare
|
||||||
|
* @param userPrefs
|
||||||
|
* the starting pool preferences
|
||||||
* @return the quest starter deck
|
* @return the quest starter deck
|
||||||
*/
|
*/
|
||||||
public static List<PaperCard> getQuestStarterDeck(final Predicate<PaperCard> filter, final int numCommon,
|
public static List<PaperCard> getQuestStarterDeck(final Predicate<PaperCard> filter, final int numCommon,
|
||||||
final int numUncommon, final int numRare) {
|
final int numUncommon, final int numRare, final StartingPoolPreferences userPrefs) {
|
||||||
|
|
||||||
final ArrayList<PaperCard> cards = new ArrayList<PaperCard>();
|
final ArrayList<PaperCard> cards = new ArrayList<PaperCard>();
|
||||||
|
|
||||||
// Each color should have around the same amount of monocolored cards
|
// Each color should have around the same amount of monocolored cards
|
||||||
@@ -75,9 +78,12 @@ public final class BoosterUtils {
|
|||||||
// There should be 1 Multicolor card for every 4 cards in a single color
|
// There should be 1 Multicolor card for every 4 cards in a single color
|
||||||
|
|
||||||
final List<Predicate<CardRules>> colorFilters = new ArrayList<Predicate<CardRules>>();
|
final List<Predicate<CardRules>> colorFilters = new ArrayList<Predicate<CardRules>>();
|
||||||
|
final boolean preferred = (userPrefs != null && userPrefs.getPreferredColor() != MagicColor.ALL_COLORS);
|
||||||
|
|
||||||
|
if (userPrefs != null && !userPrefs.useRandomPool()) {
|
||||||
colorFilters.add(CardRulesPredicates.Presets.IS_MULTICOLOR);
|
colorFilters.add(CardRulesPredicates.Presets.IS_MULTICOLOR);
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < (preferred ? 3 : 4); i++) {
|
||||||
if (i != 2) {
|
if (i != 2) {
|
||||||
colorFilters.add(CardRulesPredicates.Presets.IS_COLORLESS);
|
colorFilters.add(CardRulesPredicates.Presets.IS_COLORLESS);
|
||||||
}
|
}
|
||||||
@@ -88,6 +94,13 @@ public final class BoosterUtils {
|
|||||||
colorFilters.add(CardRulesPredicates.isMonoColor(MagicColor.BLACK));
|
colorFilters.add(CardRulesPredicates.isMonoColor(MagicColor.BLACK));
|
||||||
colorFilters.add(CardRulesPredicates.isMonoColor(MagicColor.GREEN));
|
colorFilters.add(CardRulesPredicates.isMonoColor(MagicColor.GREEN));
|
||||||
}
|
}
|
||||||
|
// Add some extra filters of the preferred color if chosen
|
||||||
|
if (preferred) {
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
colorFilters.add(CardRulesPredicates.isMonoColor(userPrefs.getPreferredColor()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This will save CPU time when sets are limited
|
// This will save CPU time when sets are limited
|
||||||
final List<PaperCard> cardpool = Lists.newArrayList(Iterables.filter(CardDb.instance().getAllCards(), filter));
|
final List<PaperCard> cardpool = Lists.newArrayList(Iterables.filter(CardDb.instance().getAllCards(), filter));
|
||||||
@@ -181,8 +194,9 @@ public final class BoosterUtils {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public static Predicate<CardRules> parseRulesLimitation(final String input) {
|
public static Predicate<CardRules> parseRulesLimitation(final String input) {
|
||||||
if (null == input || "random".equalsIgnoreCase(input))
|
if (null == input || "random".equalsIgnoreCase(input)) {
|
||||||
return Predicates.alwaysTrue();
|
return Predicates.alwaysTrue();
|
||||||
|
}
|
||||||
|
|
||||||
if (input.equalsIgnoreCase("black")) return CardRulesPredicates.Presets.IS_BLACK;
|
if (input.equalsIgnoreCase("black")) return CardRulesPredicates.Presets.IS_BLACK;
|
||||||
if (input.equalsIgnoreCase("blue")) return CardRulesPredicates.Presets.IS_BLUE;
|
if (input.equalsIgnoreCase("blue")) return CardRulesPredicates.Presets.IS_BLUE;
|
||||||
@@ -214,7 +228,7 @@ public final class BoosterUtils {
|
|||||||
List<InventoryItem> rewards = new ArrayList<InventoryItem>();
|
List<InventoryItem> rewards = new ArrayList<InventoryItem>();
|
||||||
|
|
||||||
// last word starts with 'rare' ignore case
|
// last word starts with 'rare' ignore case
|
||||||
if (temp.length > 1 && temp[temp.length-1].regionMatches(true, 0, "rare", 0, 4)) {
|
if (temp.length > 1 && temp[temp.length - 1].regionMatches(true, 0, "rare", 0, 4)) {
|
||||||
// Type 1: 'n [color] rares'
|
// Type 1: 'n [color] rares'
|
||||||
final int qty = Integer.parseInt(temp[0]);
|
final int qty = Integer.parseInt(temp[0]);
|
||||||
|
|
||||||
@@ -223,9 +237,10 @@ public final class BoosterUtils {
|
|||||||
|
|
||||||
if (temp.length > 2) {
|
if (temp.length > 2) {
|
||||||
Predicate<CardRules> cr = parseRulesLimitation(temp[1]);
|
Predicate<CardRules> cr = parseRulesLimitation(temp[1]);
|
||||||
if(Predicates.alwaysTrue() != (Object)cr) // guava has a single instance for always-const predicates
|
if (Predicates.alwaysTrue() != (Object) cr) { // guava has a single instance for always-const predicates
|
||||||
preds.add(Predicates.compose(cr, PaperCard.FN_GET_RULES));
|
preds.add(Predicates.compose(cr, PaperCard.FN_GET_RULES));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Singletons.getModel().getQuest().getFormat() != null) {
|
if (Singletons.getModel().getQuest().getFormat() != null) {
|
||||||
preds.add(Singletons.getModel().getQuest().getFormat().getFilterPrinted());
|
preds.add(Singletons.getModel().getQuest().getFormat().getFilterPrinted());
|
||||||
|
|||||||
@@ -213,23 +213,26 @@ public class QuestController {
|
|||||||
* New game.
|
* New game.
|
||||||
*
|
*
|
||||||
* @param name the name
|
* @param name the name
|
||||||
* @param diff the diff
|
* @param difficulty
|
||||||
|
* the difficulty
|
||||||
* @param mode the mode
|
* @param mode the mode
|
||||||
* @param startPool the start type
|
* @param formatPrizes
|
||||||
* @param startFormat the format of starting pool
|
* prize boosters format
|
||||||
* @param preconName the precon name
|
* @param allowSetUnlocks
|
||||||
* @param userFormat user-defined format, if any
|
* allow unlocking of sets
|
||||||
* @param persist
|
* @param startingCards
|
||||||
* enforce the format for the whole quest
|
* the starting deck
|
||||||
* @param userDeck
|
* @param formatStartingPool
|
||||||
* user-specified starting deck
|
* format used for the starting pool
|
||||||
* @param startingWorld
|
* @param startingWorld
|
||||||
* starting world
|
* starting world
|
||||||
|
* @param userPrefs
|
||||||
|
* user preferences
|
||||||
*/
|
*/
|
||||||
public void newGame(final String name, final int difficulty, final QuestMode mode,
|
public void newGame(final String name, final int difficulty, final QuestMode mode,
|
||||||
final GameFormat formatPrizes, final boolean allowSetUnlocks,
|
final GameFormat formatPrizes, final boolean allowSetUnlocks,
|
||||||
final Deck startingCards, final GameFormat formatStartingPool,
|
final Deck startingCards, final GameFormat formatStartingPool,
|
||||||
final String startingWorld) {
|
final String startingWorld, final StartingPoolPreferences userPrefs) {
|
||||||
|
|
||||||
this.load(new QuestData(name, difficulty, mode, formatPrizes, allowSetUnlocks, startingWorld)); // pass awards and unlocks here
|
this.load(new QuestData(name, difficulty, mode, formatPrizes, allowSetUnlocks, startingWorld)); // pass awards and unlocks here
|
||||||
|
|
||||||
@@ -240,7 +243,7 @@ public class QuestController {
|
|||||||
if (formatStartingPool != null) {
|
if (formatStartingPool != null) {
|
||||||
filter = formatStartingPool.getFilterPrinted();
|
filter = formatStartingPool.getFilterPrinted();
|
||||||
}
|
}
|
||||||
this.myCards.setupNewGameCardPool(filter, difficulty);
|
this.myCards.setupNewGameCardPool(filter, difficulty, userPrefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getAssets().setCredits(Singletons.getModel().getQuestPreferences().getPrefInt(DifficultyPrefs.STARTING_CREDITS, difficulty));
|
this.getAssets().setCredits(Singletons.getModel().getQuestPreferences().getPrefInt(DifficultyPrefs.STARTING_CREDITS, difficulty));
|
||||||
@@ -427,8 +430,8 @@ public class QuestController {
|
|||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void receiveGameEvent(GameEvent ev) { // Receives events only during quest games
|
public void receiveGameEvent(GameEvent ev) { // Receives events only during quest games
|
||||||
if ( ev instanceof GameEventMulligan ) {
|
if (ev instanceof GameEventMulligan) {
|
||||||
GameEventMulligan mev = (GameEventMulligan)ev;
|
GameEventMulligan mev = (GameEventMulligan) ev;
|
||||||
// First mulligan is free
|
// First mulligan is free
|
||||||
if (mev.player.getLobbyPlayer() == FServer.instance.getLobby().getQuestPlayer()
|
if (mev.player.getLobbyPlayer() == FServer.instance.getLobby().getQuestPlayer()
|
||||||
&& getAssets().hasItem(QuestItemType.SLEIGHT) && mev.player.getStats().getMulliganCount() == 0) {
|
&& getAssets().hasItem(QuestItemType.SLEIGHT) && mev.player.getStats().getMulliganCount() == 0) {
|
||||||
@@ -464,8 +467,12 @@ public class QuestController {
|
|||||||
// Generate IDs as needed.
|
// Generate IDs as needed.
|
||||||
if (achievements.getCurrentChallenges().size() < maxChallenges) {
|
if (achievements.getCurrentChallenges().size() < maxChallenges) {
|
||||||
for (final QuestEventChallenge qc : allChallenges) {
|
for (final QuestEventChallenge qc : allChallenges) {
|
||||||
if( qc.getWinsReqd() > achievements.getWin()) continue;
|
if (qc.getWinsReqd() > achievements.getWin()) {
|
||||||
if( !qc.isRepeatable() && achievements.getLockedChallenges().contains(qc.getId())) continue;
|
continue;
|
||||||
|
}
|
||||||
|
if (!qc.isRepeatable() && achievements.getLockedChallenges().contains(qc.getId())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!availableChallengeIds.contains(qc.getId())) {
|
if (!availableChallengeIds.contains(qc.getId())) {
|
||||||
unlockedChallengeIds.add(qc.getId());
|
unlockedChallengeIds.add(qc.getId());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ public final class QuestUtilCards {
|
|||||||
for (String edCode : availableEditions) {
|
for (String edCode : availableEditions) {
|
||||||
CardEdition ed = Singletons.getModel().getEditions().get(edCode);
|
CardEdition ed = Singletons.getModel().getEditions().get(edCode);
|
||||||
// Duel decks might have only 2 types of basic lands
|
// Duel decks might have only 2 types of basic lands
|
||||||
if( CardEdition.Predicates.hasBasicLands.apply(ed) ) {
|
if (CardEdition.Predicates.hasBasicLands.apply(ed)) {
|
||||||
landCodes.add(edCode);
|
landCodes.add(edCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,14 +126,14 @@ public final class QuestUtilCards {
|
|||||||
landCode = "M10";
|
landCode = "M10";
|
||||||
}
|
}
|
||||||
|
|
||||||
for(String landName : Constant.Color.BASIC_LANDS) {
|
for (String landName : Constant.Color.BASIC_LANDS) {
|
||||||
pool.add(db.getCard(landName, landCode), nBasic);
|
pool.add(db.getCard(landName, landCode), nBasic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!snowLandCodes.isEmpty()) {
|
if (!snowLandCodes.isEmpty()) {
|
||||||
String snowLandCode = Aggregates.random(snowLandCodes);
|
String snowLandCode = Aggregates.random(snowLandCodes);
|
||||||
for(String landName : Constant.Color.SNOW_LANDS) {
|
for (String landName : Constant.Color.SNOW_LANDS) {
|
||||||
pool.add(db.getCard(landName, snowLandCode), nSnow);
|
pool.add(db.getCard(landName, snowLandCode), nSnow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,6 +172,8 @@ public final class QuestUtilCards {
|
|||||||
*
|
*
|
||||||
* @param card
|
* @param card
|
||||||
* the card
|
* the card
|
||||||
|
* @param qty
|
||||||
|
* quantity
|
||||||
*/
|
*/
|
||||||
public void addSingleCard(final PaperCard card, int qty) {
|
public void addSingleCard(final PaperCard card, int qty) {
|
||||||
this.qa.getCardPool().add(card, qty);
|
this.qa.getCardPool().add(card, qty);
|
||||||
@@ -229,13 +231,15 @@ public final class QuestUtilCards {
|
|||||||
* the filter
|
* the filter
|
||||||
* @param idxDifficulty
|
* @param idxDifficulty
|
||||||
* the idx difficulty
|
* the idx difficulty
|
||||||
|
* @param userPrefs
|
||||||
|
* user preferences
|
||||||
*/
|
*/
|
||||||
public void setupNewGameCardPool(final Predicate<PaperCard> filter, final int idxDifficulty) {
|
public void setupNewGameCardPool(final Predicate<PaperCard> filter, final int idxDifficulty, final StartingPoolPreferences userPrefs) {
|
||||||
final int nC = this.qpref.getPrefInt(DifficultyPrefs.STARTING_COMMONS, idxDifficulty);
|
final int nC = this.qpref.getPrefInt(DifficultyPrefs.STARTING_COMMONS, idxDifficulty);
|
||||||
final int nU = this.qpref.getPrefInt(DifficultyPrefs.STARTING_UNCOMMONS, idxDifficulty);
|
final int nU = this.qpref.getPrefInt(DifficultyPrefs.STARTING_UNCOMMONS, idxDifficulty);
|
||||||
final int nR = this.qpref.getPrefInt(DifficultyPrefs.STARTING_RARES, idxDifficulty);
|
final int nR = this.qpref.getPrefInt(DifficultyPrefs.STARTING_RARES, idxDifficulty);
|
||||||
|
|
||||||
this.addAllCards(BoosterUtils.getQuestStarterDeck(filter, nC, nU, nR));
|
this.addAllCards(BoosterUtils.getQuestStarterDeck(filter, nC, nU, nR, userPrefs));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -243,6 +247,8 @@ public final class QuestUtilCards {
|
|||||||
*
|
*
|
||||||
* @param card
|
* @param card
|
||||||
* the card
|
* the card
|
||||||
|
* @param qty
|
||||||
|
* quantity
|
||||||
* @param value
|
* @param value
|
||||||
* the value
|
* the value
|
||||||
*/
|
*/
|
||||||
@@ -299,22 +305,33 @@ public final class QuestUtilCards {
|
|||||||
}
|
}
|
||||||
this.qc.getMyDecks().add(fromDeck);
|
this.qc.getMyDecks().add(fromDeck);
|
||||||
this.addAllCards(fromDeck.getMain().toFlatList());
|
this.addAllCards(fromDeck.getMain().toFlatList());
|
||||||
if (fromDeck.has(DeckSection.Sideboard))
|
if (fromDeck.has(DeckSection.Sideboard)) {
|
||||||
this.addAllCards(fromDeck.get(DeckSection.Sideboard).toFlatList());
|
this.addAllCards(fromDeck.get(DeckSection.Sideboard).toFlatList());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sell card.
|
* Sell card.
|
||||||
*
|
*
|
||||||
* @param card
|
* @param card
|
||||||
* the card
|
* the card
|
||||||
* @param price
|
* @param qty
|
||||||
* the price
|
* quantity
|
||||||
|
* @param pricePerCard
|
||||||
|
* the price per card
|
||||||
*/
|
*/
|
||||||
public void sellCard(final PaperCard card, int qty, final int pricePerCard) {
|
public void sellCard(final PaperCard card, int qty, final int pricePerCard) {
|
||||||
this.sellCard(card, qty, pricePerCard, true);
|
this.sellCard(card, qty, pricePerCard, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lose card.
|
||||||
|
*
|
||||||
|
* @param card
|
||||||
|
* the card
|
||||||
|
* @param qty
|
||||||
|
* quantity
|
||||||
|
*/
|
||||||
public void loseCard(final PaperCard card, int qty) {
|
public void loseCard(final PaperCard card, int qty) {
|
||||||
this.sellCard(card, qty, 0, false);
|
this.sellCard(card, qty, 0, false);
|
||||||
}
|
}
|
||||||
@@ -345,7 +362,9 @@ public final class QuestUtilCards {
|
|||||||
int cntInMain = deck.getMain().count(card);
|
int cntInMain = deck.getMain().count(card);
|
||||||
int cntInSb = deck.has(DeckSection.Sideboard) ? deck.get(DeckSection.Sideboard).count(card) : 0;
|
int cntInSb = deck.has(DeckSection.Sideboard) ? deck.get(DeckSection.Sideboard).count(card) : 0;
|
||||||
int nToRemoveFromThisDeck = cntInMain + cntInSb - leftInPool;
|
int nToRemoveFromThisDeck = cntInMain + cntInSb - leftInPool;
|
||||||
if ( nToRemoveFromThisDeck <= 0 ) continue; // this is not the deck you are looking for
|
if (nToRemoveFromThisDeck <= 0) {
|
||||||
|
continue; // this is not the deck you are looking for
|
||||||
|
}
|
||||||
|
|
||||||
int nToRemoveFromSb = Math.min(cntInSb, nToRemoveFromThisDeck);
|
int nToRemoveFromSb = Math.min(cntInSb, nToRemoveFromThisDeck);
|
||||||
if (nToRemoveFromSb > 0) {
|
if (nToRemoveFromSb > 0) {
|
||||||
@@ -496,8 +515,8 @@ public final class QuestUtilCards {
|
|||||||
private void generatePreconsInShop(final int count) {
|
private void generatePreconsInShop(final int count) {
|
||||||
final List<PreconDeck> meetRequirements = new ArrayList<PreconDeck>();
|
final List<PreconDeck> meetRequirements = new ArrayList<PreconDeck>();
|
||||||
for (final PreconDeck deck : QuestController.getPrecons()) {
|
for (final PreconDeck deck : QuestController.getPrecons()) {
|
||||||
if (deck.getRecommendedDeals().meetsRequiremnts(this.qc.getAchievements()) &&
|
if (deck.getRecommendedDeals().meetsRequiremnts(this.qc.getAchievements())
|
||||||
(null == qc.getFormat() || qc.getFormat().isSetLegal(deck.getEdition()))) {
|
&& (null == qc.getFormat() || qc.getFormat().isSetLegal(deck.getEdition()))) {
|
||||||
meetRequirements.add(deck);
|
meetRequirements.add(deck);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -538,7 +557,7 @@ public final class QuestUtilCards {
|
|||||||
|
|
||||||
|
|
||||||
SealedProductTemplate tpl = getShopBoosterTemplate();
|
SealedProductTemplate tpl = getShopBoosterTemplate();
|
||||||
UnOpenedProduct unopened = qc.getFormat() == null ? new UnOpenedProduct( tpl ) : new UnOpenedProduct( tpl, qc.getFormat().getFilterPrinted());
|
UnOpenedProduct unopened = qc.getFormat() == null ? new UnOpenedProduct(tpl) : new UnOpenedProduct(tpl, qc.getFormat().getFilterPrinted());
|
||||||
|
|
||||||
for (int i = 0; i < totalPacks; i++) {
|
for (int i = 0; i < totalPacks; i++) {
|
||||||
this.qa.getShopList().addAllFlat(unopened.get());
|
this.qa.getShopList().addAllFlat(unopened.get());
|
||||||
@@ -658,12 +677,12 @@ public final class QuestUtilCards {
|
|||||||
public Comparable<?> apply(final Entry<InventoryItem, Integer> from) {
|
public Comparable<?> apply(final Entry<InventoryItem, Integer> from) {
|
||||||
InventoryItem i = from.getKey();
|
InventoryItem i = from.getKey();
|
||||||
if (i instanceof PaperCard) {
|
if (i instanceof PaperCard) {
|
||||||
return QuestUtilCards.this.qa.getCardPool().count((PaperCard)i);
|
return QuestUtilCards.this.qa.getCardPool().count((PaperCard) i);
|
||||||
} else if (i instanceof PreconDeck) {
|
} else if (i instanceof PreconDeck) {
|
||||||
PreconDeck pDeck = (PreconDeck)i;
|
PreconDeck pDeck = (PreconDeck) i;
|
||||||
return Singletons.getModel().getQuest().getMyDecks().contains(pDeck.getName()) ? -1 : -2;
|
return Singletons.getModel().getQuest().getMyDecks().contains(pDeck.getName()) ? -1 : -2;
|
||||||
} else if (i instanceof OpenablePack) {
|
} else if (i instanceof OpenablePack) {
|
||||||
OpenablePack oPack = (OpenablePack)i;
|
OpenablePack oPack = (OpenablePack) i;
|
||||||
return getCompletionPercent(oPack.getEdition()) - 103;
|
return getCompletionPercent(oPack.getEdition()) - 103;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -676,12 +695,12 @@ public final class QuestUtilCards {
|
|||||||
public Object apply(final Entry<InventoryItem, Integer> from) {
|
public Object apply(final Entry<InventoryItem, Integer> from) {
|
||||||
InventoryItem i = from.getKey();
|
InventoryItem i = from.getKey();
|
||||||
if (i instanceof PaperCard) {
|
if (i instanceof PaperCard) {
|
||||||
return QuestUtilCards.this.qa.getCardPool().count((PaperCard)i);
|
return QuestUtilCards.this.qa.getCardPool().count((PaperCard) i);
|
||||||
} else if (i instanceof PreconDeck) {
|
} else if (i instanceof PreconDeck) {
|
||||||
PreconDeck pDeck = (PreconDeck)i;
|
PreconDeck pDeck = (PreconDeck) i;
|
||||||
return Singletons.getModel().getQuest().getMyDecks().contains(pDeck.getName()) ? "YES" : "NO";
|
return Singletons.getModel().getQuest().getMyDecks().contains(pDeck.getName()) ? "YES" : "NO";
|
||||||
} else if (i instanceof OpenablePack) {
|
} else if (i instanceof OpenablePack) {
|
||||||
OpenablePack oPack = (OpenablePack)i;
|
OpenablePack oPack = (OpenablePack) i;
|
||||||
return String.format("%d%%", getCompletionPercent(oPack.getEdition()));
|
return String.format("%d%%", getCompletionPercent(oPack.getEdition()));
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
61
src/main/java/forge/quest/StartingPoolPreferences.java
Normal file
61
src/main/java/forge/quest/StartingPoolPreferences.java
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Forge: Play Magic: the Gathering.
|
||||||
|
* Copyright (C) 2011 Nate
|
||||||
|
*
|
||||||
|
* 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.quest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is used to store the Quest starting pool preferences.
|
||||||
|
* (It could be expanded to store other Quest starting preferences as well,
|
||||||
|
* in order to reduce the number of parameters that need to be passed to
|
||||||
|
* QuestController.newGame from CSubmenuQuestData)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public final class StartingPoolPreferences {
|
||||||
|
|
||||||
|
private final boolean randomPool;
|
||||||
|
private final byte preferredColor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The constructor.
|
||||||
|
* @param random
|
||||||
|
* true = use completely random pool without filter restrictions
|
||||||
|
* (Note that this does NOT bypass card rarity restrictions!)
|
||||||
|
* @param preference
|
||||||
|
* preferred color/COLORLESS (ALL_COLORS = no preference)
|
||||||
|
*/
|
||||||
|
public StartingPoolPreferences(final boolean random, final byte preference) {
|
||||||
|
randomPool = random;
|
||||||
|
preferredColor = preference;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the starting pool completely random?
|
||||||
|
* @return boolean, true if the starting pool is completely random (except for rarity)
|
||||||
|
*/
|
||||||
|
public boolean useRandomPool() {
|
||||||
|
return randomPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the preferred starting pool color.
|
||||||
|
* Return ALL_COLORS if no preference set.
|
||||||
|
* @return MagicColor
|
||||||
|
*/
|
||||||
|
public byte getPreferredColor() {
|
||||||
|
return preferredColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -72,8 +72,6 @@ public final class QuestData {
|
|||||||
* achievement diff
|
* achievement diff
|
||||||
* @param name2
|
* @param name2
|
||||||
* quest name
|
* quest name
|
||||||
* @param formatString
|
|
||||||
* String, persistent format for the quest (null if none).
|
|
||||||
* @param userFormat
|
* @param userFormat
|
||||||
* user-defined format, if any (null if none).
|
* user-defined format, if any (null if none).
|
||||||
* @param allowSetUnlocks
|
* @param allowSetUnlocks
|
||||||
|
|||||||
@@ -15,10 +15,13 @@ import javax.swing.JFrame;
|
|||||||
import javax.swing.JRootPane;
|
import javax.swing.JRootPane;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
|
import forge.Singletons;
|
||||||
|
import forge.gui.framework.SResizingUtil;
|
||||||
import forge.gui.toolbox.FSkin;
|
import forge.gui.toolbox.FSkin;
|
||||||
import forge.gui.toolbox.FSkin.Colors;
|
import forge.gui.toolbox.FSkin.Colors;
|
||||||
import forge.gui.toolbox.FSkin.CompoundSkinBorder;
|
import forge.gui.toolbox.FSkin.CompoundSkinBorder;
|
||||||
import forge.gui.toolbox.FSkin.LineSkinBorder;
|
import forge.gui.toolbox.FSkin.LineSkinBorder;
|
||||||
|
import forge.properties.ForgePreferences.FPref;
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class FFrame extends JFrame {
|
public class FFrame extends JFrame {
|
||||||
@@ -27,27 +30,31 @@ public class FFrame extends JFrame {
|
|||||||
private Dimension sizeBeforeResize;
|
private Dimension sizeBeforeResize;
|
||||||
private Point mouseDownLoc;
|
private Point mouseDownLoc;
|
||||||
private int resizeCursor;
|
private int resizeCursor;
|
||||||
private FTitleBar titleBar;
|
private FTitleBarBase titleBar;
|
||||||
private boolean maximized, showTitleBar;
|
private boolean maximized, showTitleBar, isMainFrame;
|
||||||
private final JRootPane innerPane = new JRootPane();
|
|
||||||
|
|
||||||
public FFrame() {
|
public FFrame() {
|
||||||
setUndecorated(true);
|
setUndecorated(true);
|
||||||
setContentPane(innerPane);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
|
initialize(new FTitleBar(this), true); //show titlebar by default
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initialize(FTitleBarBase titleBar0, boolean showTitleBar0) {
|
||||||
|
this.isMainFrame = (FView.SINGLETON_INSTANCE.getFrame() == this);
|
||||||
|
|
||||||
// Frame border
|
// Frame border
|
||||||
updateBorder();
|
updateBorder();
|
||||||
addResizeSupport();
|
addResizeSupport();
|
||||||
|
|
||||||
// Title bar
|
// Title bar
|
||||||
this.titleBar = new FTitleBar(this);
|
this.titleBar = titleBar0;
|
||||||
this.setShowTitleBar(true); //show titlebar by default
|
this.setShowTitleBar(showTitleBar0);
|
||||||
addMoveSupport();
|
addMoveSupport();
|
||||||
}
|
}
|
||||||
|
|
||||||
public FTitleBar getTitleBar() {
|
public FTitleBarBase getTitleBar() {
|
||||||
return this.titleBar;
|
return this.titleBar;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,9 +66,12 @@ public class FFrame extends JFrame {
|
|||||||
if (this.showTitleBar == showTitleBar0) { return; }
|
if (this.showTitleBar == showTitleBar0) { return; }
|
||||||
this.showTitleBar = showTitleBar0;
|
this.showTitleBar = showTitleBar0;
|
||||||
this.titleBar.setVisible(showTitleBar0);
|
this.titleBar.setVisible(showTitleBar0);
|
||||||
if (!showTitleBar0) {
|
if (!showTitleBar0 && !this.getMaximized()) {
|
||||||
this.setMaximized(true); //only support hidden titlebar if maximized
|
this.setMaximized(true); //only support hidden titlebar if maximized
|
||||||
}
|
}
|
||||||
|
else if (this.isMainFrame) {
|
||||||
|
SResizingUtil.resizeWindow(); //ensure window layout updated to account for showing titlebar
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -134,8 +144,13 @@ public class FFrame extends JFrame {
|
|||||||
if (getMinimized()) { return; } //skip remaining logic while minimized
|
if (getMinimized()) { return; } //skip remaining logic while minimized
|
||||||
|
|
||||||
this.maximized = (state == Frame.MAXIMIZED_BOTH);
|
this.maximized = (state == Frame.MAXIMIZED_BOTH);
|
||||||
if (!this.maximized) {
|
if (this.maximized) {
|
||||||
this.setShowTitleBar(true); //only support hidden titlebar if maximized
|
if (this.isMainFrame) { //for main frame, use preference to determine whether to hide title bar when maximizing
|
||||||
|
this.setShowTitleBar(!Singletons.getModel().getPreferences().getPrefBoolean(FPref.UI_HIDE_TITLE_BAR));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { //only support hidden titlebar if maximized
|
||||||
|
this.setShowTitleBar(true);
|
||||||
}
|
}
|
||||||
updateBorder();
|
updateBorder();
|
||||||
this.titleBar.handleMaximizedChanged(); //update icon and tooltip for maximize button
|
this.titleBar.handleMaximizedChanged(); //update icon and tooltip for maximize button
|
||||||
@@ -152,10 +167,6 @@ public class FFrame extends JFrame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public JRootPane getInnerPane() {
|
|
||||||
return innerPane;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addMoveSupport() {
|
private void addMoveSupport() {
|
||||||
this.titleBar.addMouseListener(new MouseAdapter() {
|
this.titleBar.addMouseListener(new MouseAdapter() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
217
src/main/java/forge/view/FNavigationBar.java
Normal file
217
src/main/java/forge/view/FNavigationBar.java
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
package forge.view;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.awt.MouseInfo;
|
||||||
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.SpringLayout;
|
||||||
|
import javax.swing.Timer;
|
||||||
|
import forge.Singletons;
|
||||||
|
import forge.gui.menus.ForgeMenu;
|
||||||
|
import forge.gui.toolbox.FButton;
|
||||||
|
import forge.gui.toolbox.FDigitalClock;
|
||||||
|
import forge.gui.toolbox.FSkin;
|
||||||
|
import forge.properties.ForgePreferences;
|
||||||
|
import forge.properties.ForgePreferences.FPref;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class FNavigationBar extends FTitleBarBase {
|
||||||
|
|
||||||
|
private static final ForgeMenu forgeMenu = Singletons.getControl().getForgeMenu();
|
||||||
|
private static final ForgePreferences prefs = Singletons.getModel().getPreferences();
|
||||||
|
|
||||||
|
private final FButton btnForge = new FButton("Forge");
|
||||||
|
private final FDigitalClock clock = new FDigitalClock();
|
||||||
|
private final JPanel pnlReveal = new JPanel();
|
||||||
|
private Timer incrementRevealTimer, checkForRevealChangeTimer;
|
||||||
|
private boolean hidden;
|
||||||
|
private int revealDir = 0;
|
||||||
|
private long timeMenuHidden = 0;
|
||||||
|
|
||||||
|
public FNavigationBar(FFrame f) {
|
||||||
|
super(f);
|
||||||
|
btnForge.setFocusable(false);
|
||||||
|
btnForge.setPreferredSize(new Dimension(100, 23));
|
||||||
|
setIconImage(this.frame.getIconImage()); //set default icon image based on frame icon image
|
||||||
|
FSkin.get(btnForge).setForeground(foreColor);
|
||||||
|
FSkin.get(clock).setForeground(foreColor);
|
||||||
|
addControls();
|
||||||
|
setupPnlReveal();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addControls() {
|
||||||
|
add(btnForge);
|
||||||
|
layout.putConstraint(SpringLayout.WEST, btnForge, 1, SpringLayout.WEST, this);
|
||||||
|
layout.putConstraint(SpringLayout.SOUTH, btnForge, -1, SpringLayout.SOUTH, this);
|
||||||
|
addForgeButtonListeners();
|
||||||
|
|
||||||
|
super.addControls();
|
||||||
|
|
||||||
|
add(clock);
|
||||||
|
layout.putConstraint(SpringLayout.EAST, clock, -6, SpringLayout.WEST, btnMinimize);
|
||||||
|
layout.putConstraint(SpringLayout.SOUTH, clock, -5, SpringLayout.SOUTH, this);
|
||||||
|
updateClockVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleMaximizedChanged() {
|
||||||
|
super.handleMaximizedChanged();
|
||||||
|
updateClockVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
//only show clock if maximized and status bar hidden
|
||||||
|
public void updateClockVisibility() {
|
||||||
|
clock.setVisible(this.frame.getMaximized() && prefs.getPrefBoolean(FPref.UI_HIDE_STATUS_BAR));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addForgeButtonListeners() {
|
||||||
|
btnForge.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
if (System.currentTimeMillis() - timeMenuHidden > 250) { //time comparsion needed clicking button a second time to hide menu
|
||||||
|
showForgeMenu(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showForgeMenu(boolean hideIfAlreadyShown) {
|
||||||
|
if (!btnForge.isToggled()) {
|
||||||
|
btnForge.setToggled(true);
|
||||||
|
forgeMenu.getPopupMenu().show(this, 1, this.getHeight());
|
||||||
|
}
|
||||||
|
else if (hideIfAlreadyShown) {
|
||||||
|
forgeMenu.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onForgeMenuHidden() {
|
||||||
|
btnForge.setToggled(false);
|
||||||
|
timeMenuHidden = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
//setup panel used to reveal navigation bar when hidden
|
||||||
|
private void setupPnlReveal() {
|
||||||
|
pnlReveal.setVisible(hidden);
|
||||||
|
pnlReveal.setOpaque(false);
|
||||||
|
pnlReveal.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent e) {
|
||||||
|
if (revealDir == 0) {
|
||||||
|
startReveal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
incrementRevealTimer = new Timer(500 / visibleHeight, new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
incrementReveal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
checkForRevealChangeTimer = new Timer(250, new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
checkForRevealChange();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startReveal() {
|
||||||
|
if (this.getHeight() == visibleHeight) { return; }
|
||||||
|
if (revealDir == 0) {
|
||||||
|
incrementRevealTimer.setInitialDelay(250);
|
||||||
|
incrementRevealTimer.start();
|
||||||
|
checkForRevealChangeTimer.stop();
|
||||||
|
}
|
||||||
|
revealDir = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopReveal() {
|
||||||
|
if (this.getHeight() == 0) { return; }
|
||||||
|
if (revealDir == 0) {
|
||||||
|
incrementRevealTimer.setInitialDelay(250);
|
||||||
|
incrementRevealTimer.start();
|
||||||
|
checkForRevealChangeTimer.stop();
|
||||||
|
}
|
||||||
|
revealDir = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void incrementReveal() {
|
||||||
|
int newHeight = this.getHeight() + revealDir * 2;
|
||||||
|
switch (revealDir) {
|
||||||
|
case 0:
|
||||||
|
incrementRevealTimer.stop();
|
||||||
|
return;
|
||||||
|
case 1:
|
||||||
|
if (newHeight >= visibleHeight) {
|
||||||
|
newHeight = visibleHeight;
|
||||||
|
revealDir = 0;
|
||||||
|
incrementRevealTimer.stop();
|
||||||
|
checkForRevealChangeTimer.start(); //once open fully, start another timer to check when mouse moves away
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
if (newHeight <= 0) {
|
||||||
|
newHeight = 0;
|
||||||
|
revealDir = 0;
|
||||||
|
incrementRevealTimer.stop();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.setSize(this.getWidth(), newHeight);
|
||||||
|
revalidate();
|
||||||
|
checkForRevealChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkForRevealChange() {
|
||||||
|
if (hidden && this.getHeight() > 0 && !btnForge.isToggled()) { //don't change reveal while Forge menu open
|
||||||
|
final Rectangle screenBounds = new Rectangle(this.getLocationOnScreen(), this.getSize());
|
||||||
|
if (screenBounds.contains(MouseInfo.getPointerInfo().getLocation())) {
|
||||||
|
startReveal();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
stopReveal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setVisible(boolean visible) {
|
||||||
|
hidden = !visible;
|
||||||
|
if (pnlReveal != null) { //check needed because FTitleBarBase constructor calls this
|
||||||
|
revealDir = 0;
|
||||||
|
incrementRevealTimer.stop();
|
||||||
|
checkForRevealChangeTimer.stop();
|
||||||
|
pnlReveal.setVisible(hidden);
|
||||||
|
}
|
||||||
|
super.setVisible(visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBounds(int x, int y, int width, int height) {
|
||||||
|
super.setBounds(x, y, width, height);
|
||||||
|
pnlReveal.setBounds(x, y, width, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JPanel getPnlReveal() {
|
||||||
|
return pnlReveal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTitle() {
|
||||||
|
return "Forge";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTitle(String title) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setIconImage(Image image) {
|
||||||
|
}
|
||||||
|
}
|
||||||
56
src/main/java/forge/view/FStatusBar.java
Normal file
56
src/main/java/forge/view/FStatusBar.java
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package forge.view;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.SpringLayout;
|
||||||
|
|
||||||
|
import forge.gui.toolbox.FDigitalClock;
|
||||||
|
import forge.gui.toolbox.FSkin;
|
||||||
|
import forge.gui.toolbox.FSkin.Colors;
|
||||||
|
import forge.gui.toolbox.FSkin.JComponentSkin;
|
||||||
|
import forge.gui.toolbox.FSkin.SkinColor;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class FStatusBar extends JPanel {
|
||||||
|
private static final SkinColor foreColor = FSkin.getColor(Colors.CLR_TEXT).alphaColor(150);
|
||||||
|
private static final SkinColor clrTheme = FSkin.getColor(Colors.CLR_THEME);
|
||||||
|
private static final SkinColor backColor = clrTheme.stepColor(0).darker();
|
||||||
|
private static final SkinColor borderColor = clrTheme.stepColor(-80);
|
||||||
|
|
||||||
|
private final FFrame frame;
|
||||||
|
private final JComponentSkin<FStatusBar> skin = FSkin.get(this);
|
||||||
|
private final SpringLayout layout = new SpringLayout();
|
||||||
|
private final JLabel lblStatus = new JLabel();
|
||||||
|
private final FDigitalClock clock = new FDigitalClock();
|
||||||
|
|
||||||
|
public FStatusBar(FFrame f, boolean visible0) {
|
||||||
|
this.frame = f;
|
||||||
|
setPreferredSize(new Dimension(f.getWidth(), 19));
|
||||||
|
setLayout(this.layout);
|
||||||
|
setStatusText(""); //set default status based on frame title
|
||||||
|
skin.setBackground(backColor);
|
||||||
|
skin.setMatteBorder(1, 0, 0, 0, borderColor);
|
||||||
|
FSkin.get(lblStatus).setForeground(foreColor);
|
||||||
|
FSkin.get(clock).setForeground(foreColor);
|
||||||
|
|
||||||
|
add(lblStatus);
|
||||||
|
layout.putConstraint(SpringLayout.WEST, lblStatus, 5, SpringLayout.WEST, this);
|
||||||
|
layout.putConstraint(SpringLayout.NORTH, lblStatus, 0, SpringLayout.NORTH, this);
|
||||||
|
|
||||||
|
add(clock);
|
||||||
|
layout.putConstraint(SpringLayout.EAST, clock, -4, SpringLayout.EAST, this);
|
||||||
|
layout.putConstraint(SpringLayout.NORTH, clock, 0, SpringLayout.NORTH, lblStatus);
|
||||||
|
|
||||||
|
this.setVisible(visible0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatusText(String text) {
|
||||||
|
text = text.trim();
|
||||||
|
if (text.isEmpty()) {
|
||||||
|
text = this.frame.getTitle(); //show Forge frame title if no other status to show
|
||||||
|
}
|
||||||
|
this.lblStatus.setText(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,96 +1,43 @@
|
|||||||
package forge.view;
|
package forge.view;
|
||||||
|
|
||||||
import java.awt.BasicStroke;
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.Graphics;
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.Image;
|
import java.awt.Image;
|
||||||
import java.awt.RenderingHints;
|
|
||||||
import java.awt.Toolkit;
|
|
||||||
import java.awt.event.MouseAdapter;
|
|
||||||
import java.awt.event.MouseEvent;
|
|
||||||
import java.awt.event.WindowEvent;
|
|
||||||
|
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JMenuBar;
|
|
||||||
import javax.swing.SpringLayout;
|
import javax.swing.SpringLayout;
|
||||||
import javax.swing.SwingUtilities;
|
|
||||||
|
|
||||||
import forge.gui.framework.ILocalRepaint;
|
|
||||||
import forge.gui.toolbox.FDigitalClock;
|
|
||||||
import forge.gui.toolbox.FSkin;
|
import forge.gui.toolbox.FSkin;
|
||||||
import forge.gui.toolbox.FSkin.Colors;
|
|
||||||
import forge.gui.toolbox.FSkin.JLabelSkin;
|
|
||||||
import forge.gui.toolbox.FSkin.SkinColor;
|
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class FTitleBar extends JMenuBar {
|
public class FTitleBar extends FTitleBarBase {
|
||||||
private static final SkinColor foreColor = FSkin.getColor(Colors.CLR_TEXT);
|
|
||||||
private static final SkinColor backColor = FSkin.getColor(Colors.CLR_THEME2);
|
|
||||||
private static final SkinColor buttonHoverColor = backColor.stepColor(40);
|
|
||||||
private static final SkinColor buttonDownColor = backColor.stepColor(-40);
|
|
||||||
|
|
||||||
private final FFrame frame;
|
|
||||||
private final SpringLayout layout = new SpringLayout();
|
|
||||||
private final JLabel lblTitle = new JLabel();
|
private final JLabel lblTitle = new JLabel();
|
||||||
private final FDigitalClock clock = new FDigitalClock();
|
|
||||||
private final MinimizeButton btnMinimize = new MinimizeButton();
|
|
||||||
private final MaximizeButton btnMaximize = new MaximizeButton();
|
|
||||||
private final CloseButton btnClose = new CloseButton();
|
|
||||||
|
|
||||||
public FTitleBar(FFrame f) {
|
public FTitleBar(FFrame f) {
|
||||||
this.frame = f;
|
super(f);
|
||||||
f.setJMenuBar(this);
|
f.setJMenuBar(this);
|
||||||
setPreferredSize(new Dimension(f.getWidth(), 22));
|
|
||||||
setLayout(this.layout);
|
|
||||||
FSkin.get(this).setBackground(backColor);
|
|
||||||
setTitle(f.getTitle()); //set default title based on frame title
|
setTitle(f.getTitle()); //set default title based on frame title
|
||||||
setIconImage(f.getIconImage()); //set default icon image based on frame icon image
|
setIconImage(f.getIconImage()); //set default icon image based on frame icon image
|
||||||
FSkin.get(lblTitle).setForeground(foreColor);
|
FSkin.get(lblTitle).setForeground(foreColor);
|
||||||
FSkin.get(clock).setForeground(foreColor);
|
addControls();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addControls() {
|
||||||
add(lblTitle);
|
add(lblTitle);
|
||||||
layout.putConstraint(SpringLayout.WEST, lblTitle, 1, SpringLayout.WEST, this);
|
layout.putConstraint(SpringLayout.WEST, lblTitle, 1, SpringLayout.WEST, this);
|
||||||
layout.putConstraint(SpringLayout.NORTH, lblTitle, 2, SpringLayout.NORTH, this);
|
layout.putConstraint(SpringLayout.SOUTH, lblTitle, -5, SpringLayout.SOUTH, this);
|
||||||
|
super.addControls();
|
||||||
add(btnClose);
|
|
||||||
layout.putConstraint(SpringLayout.EAST, btnClose, 0, SpringLayout.EAST, this);
|
|
||||||
layout.putConstraint(SpringLayout.NORTH, btnClose, 1, SpringLayout.NORTH, this);
|
|
||||||
|
|
||||||
add(btnMaximize);
|
|
||||||
layout.putConstraint(SpringLayout.EAST, btnMaximize, 0, SpringLayout.WEST, btnClose);
|
|
||||||
layout.putConstraint(SpringLayout.NORTH, btnMaximize, 0, SpringLayout.NORTH, btnClose);
|
|
||||||
|
|
||||||
add(btnMinimize);
|
|
||||||
layout.putConstraint(SpringLayout.EAST, btnMinimize, 0, SpringLayout.WEST, btnMaximize);
|
|
||||||
layout.putConstraint(SpringLayout.NORTH, btnMinimize, 0, SpringLayout.NORTH, btnMaximize);
|
|
||||||
|
|
||||||
add(clock);
|
|
||||||
clock.setVisible(false); //hide unless maximized
|
|
||||||
layout.putConstraint(SpringLayout.EAST, clock, -6, SpringLayout.WEST, btnMinimize);
|
|
||||||
layout.putConstraint(SpringLayout.NORTH, clock, 0, SpringLayout.NORTH, lblTitle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleMaximizedChanged() {
|
|
||||||
clock.setVisible(frame.getMaximized());
|
|
||||||
if (frame.getMaximized()) {
|
|
||||||
btnMaximize.setToolTipText("Restore Down");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
btnMaximize.setToolTipText("Maximize");
|
|
||||||
}
|
|
||||||
btnMaximize.repaintSelf();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return this.lblTitle.getText();
|
return this.lblTitle.getText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setTitle(String title) {
|
public void setTitle(String title) {
|
||||||
this.lblTitle.setText(title);
|
this.lblTitle.setText(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setIconImage(Image image) {
|
public void setIconImage(Image image) {
|
||||||
if (image != null) {
|
if (image != null) {
|
||||||
this.lblTitle.setIcon(new ImageIcon(image.getScaledInstance(16, 16, Image.SCALE_AREA_AVERAGING)));
|
this.lblTitle.setIcon(new ImageIcon(image.getScaledInstance(16, 16, Image.SCALE_AREA_AVERAGING)));
|
||||||
@@ -99,163 +46,4 @@ public class FTitleBar extends JMenuBar {
|
|||||||
this.lblTitle.setIcon(null);
|
this.lblTitle.setIcon(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class TitleBarButton extends JLabel implements ILocalRepaint {
|
|
||||||
protected JLabelSkin<TitleBarButton> skin = FSkin.get(this);
|
|
||||||
private boolean pressed, hovered;
|
|
||||||
|
|
||||||
private TitleBarButton() {
|
|
||||||
setPreferredSize(new Dimension(19, 19));
|
|
||||||
addMouseListener(new MouseAdapter() {
|
|
||||||
@Override
|
|
||||||
public void mousePressed(MouseEvent e) {
|
|
||||||
if (SwingUtilities.isLeftMouseButton(e)) {
|
|
||||||
pressed = true;
|
|
||||||
repaintSelf();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void mouseReleased(MouseEvent e) {
|
|
||||||
if (SwingUtilities.isLeftMouseButton(e)) {
|
|
||||||
if (pressed) {
|
|
||||||
pressed = false;
|
|
||||||
repaintSelf();
|
|
||||||
onClick();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void mouseEntered(MouseEvent e) {
|
|
||||||
hovered = true;
|
|
||||||
repaintSelf();
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void mouseExited(MouseEvent e) {
|
|
||||||
hovered = false;
|
|
||||||
repaintSelf();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void onClick();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void repaintSelf() {
|
|
||||||
final Dimension d = this.getSize();
|
|
||||||
repaint(0, 0, d.width, d.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void paintComponent(Graphics g) {
|
|
||||||
if (pressed) {
|
|
||||||
skin.setGraphicsColor(g, buttonDownColor);
|
|
||||||
g.fillRect(0, 0, getWidth(), getHeight());
|
|
||||||
g.translate(1, 1); //translate icon to give pressed button look
|
|
||||||
}
|
|
||||||
else if (hovered) {
|
|
||||||
skin.setGraphicsColor(g, buttonHoverColor);
|
|
||||||
g.fillRect(0, 0, getWidth(), getHeight());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MinimizeButton extends TitleBarButton {
|
|
||||||
private MinimizeButton() {
|
|
||||||
setToolTipText("Minimize");
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected void onClick() {
|
|
||||||
frame.setMinimized(true);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void paintComponent(Graphics g) {
|
|
||||||
super.paintComponent(g);
|
|
||||||
|
|
||||||
int thickness = 2;
|
|
||||||
int offset = 6;
|
|
||||||
int x1 = offset;
|
|
||||||
int x2 = getWidth() - offset;
|
|
||||||
int y = getHeight() - offset - thickness;
|
|
||||||
|
|
||||||
Graphics2D g2d = (Graphics2D) g;
|
|
||||||
skin.setGraphicsColor(g2d, foreColor);
|
|
||||||
g2d.setStroke(new BasicStroke(thickness));
|
|
||||||
g2d.drawLine(x1, y, x2, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MaximizeButton extends TitleBarButton {
|
|
||||||
private MaximizeButton() {
|
|
||||||
setToolTipText("Maximize");
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected void onClick() {
|
|
||||||
frame.setMaximized(!frame.getMaximized());
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void paintComponent(Graphics g) {
|
|
||||||
super.paintComponent(g);
|
|
||||||
|
|
||||||
int thickness = 2;
|
|
||||||
int offsetX = 5;
|
|
||||||
int offsetY = 6;
|
|
||||||
int x = offsetX;
|
|
||||||
int y = offsetY;
|
|
||||||
int width = getWidth() - 2 * offsetX;
|
|
||||||
int height = getHeight() - 2 * offsetY;
|
|
||||||
|
|
||||||
Graphics2D g2d = (Graphics2D) g;
|
|
||||||
skin.setGraphicsColor(g2d, foreColor);
|
|
||||||
g2d.setStroke(new BasicStroke(thickness));
|
|
||||||
|
|
||||||
if (frame.getMaximized()) { //draw 2 rectangles offset if icon to restore window
|
|
||||||
x -= 1;
|
|
||||||
y += 2;
|
|
||||||
width -= 1;
|
|
||||||
height -= 1;
|
|
||||||
g2d.drawRect(x, y, width, height);
|
|
||||||
x += 3;
|
|
||||||
y -= 3;
|
|
||||||
//draw back rectangle as 4 lines so front rectangle doesn't show back rectangle through it
|
|
||||||
g2d.drawLine(x, y, x, y + 2);
|
|
||||||
g2d.drawLine(x, y, x + width, y);
|
|
||||||
x += width;
|
|
||||||
g2d.drawLine(x, y, x, y + height);
|
|
||||||
y += height;
|
|
||||||
g2d.drawLine(x - 2, y, x, y);
|
|
||||||
}
|
|
||||||
else { //otherwise just draw 1 rectangle if icon to maximize window
|
|
||||||
g2d.drawRect(x, y, width, height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CloseButton extends TitleBarButton {
|
|
||||||
private CloseButton() {
|
|
||||||
setToolTipText("Close");
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected void onClick() {
|
|
||||||
WindowEvent wev = new WindowEvent(frame, WindowEvent.WINDOW_CLOSING);
|
|
||||||
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void paintComponent(Graphics g) {
|
|
||||||
super.paintComponent(g);
|
|
||||||
|
|
||||||
int thickness = 2;
|
|
||||||
int offset = 6;
|
|
||||||
int x1 = offset;
|
|
||||||
int y1 = offset;
|
|
||||||
int x2 = getWidth() - offset - 1;
|
|
||||||
int y2 = getHeight() - offset - 1;
|
|
||||||
|
|
||||||
Graphics2D g2d = (Graphics2D) g;
|
|
||||||
skin.setGraphicsColor(g2d, foreColor);
|
|
||||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
|
||||||
g2d.setStroke(new BasicStroke(thickness));
|
|
||||||
g2d.drawLine(x1, y1, x2, y2);
|
|
||||||
g2d.drawLine(x2, y1, x1, y2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
251
src/main/java/forge/view/FTitleBarBase.java
Normal file
251
src/main/java/forge/view/FTitleBarBase.java
Normal file
@@ -0,0 +1,251 @@
|
|||||||
|
package forge.view;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.WindowEvent;
|
||||||
|
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JMenuBar;
|
||||||
|
import javax.swing.SpringLayout;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
|
import forge.gui.framework.ILocalRepaint;
|
||||||
|
import forge.gui.toolbox.FSkin;
|
||||||
|
import forge.gui.toolbox.FSkin.Colors;
|
||||||
|
import forge.gui.toolbox.FSkin.JComponentSkin;
|
||||||
|
import forge.gui.toolbox.FSkin.JLabelSkin;
|
||||||
|
import forge.gui.toolbox.FSkin.SkinColor;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public abstract class FTitleBarBase extends JMenuBar {
|
||||||
|
protected static final int visibleHeight = 26;
|
||||||
|
protected static final SkinColor foreColor = FSkin.getColor(Colors.CLR_TEXT);
|
||||||
|
protected static final SkinColor backColor = FSkin.getColor(Colors.CLR_THEME2);
|
||||||
|
protected static final SkinColor borderColor = backColor.stepColor(-80);
|
||||||
|
protected static final SkinColor buttonHoverColor = backColor.stepColor(40);
|
||||||
|
protected static final SkinColor buttonDownColor = backColor.stepColor(-40);
|
||||||
|
|
||||||
|
protected final FFrame frame;
|
||||||
|
protected final JComponentSkin<FTitleBarBase> skin = FSkin.get(this);
|
||||||
|
protected final SpringLayout layout = new SpringLayout();
|
||||||
|
protected final MinimizeButton btnMinimize = new MinimizeButton();
|
||||||
|
protected final MaximizeButton btnMaximize = new MaximizeButton();
|
||||||
|
protected final CloseButton btnClose = new CloseButton();
|
||||||
|
|
||||||
|
protected FTitleBarBase(FFrame f) {
|
||||||
|
this.frame = f;
|
||||||
|
setVisible(false); //start out hidden unless frame chooses to show title bar
|
||||||
|
setLayout(this.layout);
|
||||||
|
skin.setBackground(backColor);
|
||||||
|
skin.setMatteBorder(0, 0, 1, 0, borderColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addControls() {
|
||||||
|
add(btnClose);
|
||||||
|
layout.putConstraint(SpringLayout.EAST, btnClose, 0, SpringLayout.EAST, this);
|
||||||
|
layout.putConstraint(SpringLayout.SOUTH, btnClose, 0, SpringLayout.SOUTH, this);
|
||||||
|
|
||||||
|
add(btnMaximize);
|
||||||
|
layout.putConstraint(SpringLayout.EAST, btnMaximize, 0, SpringLayout.WEST, btnClose);
|
||||||
|
layout.putConstraint(SpringLayout.SOUTH, btnMaximize, 0, SpringLayout.SOUTH, btnClose);
|
||||||
|
|
||||||
|
add(btnMinimize);
|
||||||
|
layout.putConstraint(SpringLayout.EAST, btnMinimize, 0, SpringLayout.WEST, btnMaximize);
|
||||||
|
layout.putConstraint(SpringLayout.SOUTH, btnMinimize, 0, SpringLayout.SOUTH, btnMaximize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract String getTitle();
|
||||||
|
public abstract void setTitle(String title);
|
||||||
|
public abstract void setIconImage(Image image);
|
||||||
|
|
||||||
|
public void handleMaximizedChanged() {
|
||||||
|
if (frame.getMaximized()) {
|
||||||
|
btnMaximize.setToolTipText("Restore Down");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
btnMaximize.setToolTipText("Maximize");
|
||||||
|
}
|
||||||
|
btnMaximize.repaintSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see javax.swing.JComponent#setVisible(boolean)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setVisible(boolean visible) {
|
||||||
|
//use height 0 to hide rather than setting visible to false to allow menu item accelerators to work
|
||||||
|
setPreferredSize(new Dimension(this.frame.getWidth(), visible ? visibleHeight : 0));
|
||||||
|
revalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class TitleBarButton extends JLabel implements ILocalRepaint {
|
||||||
|
protected JLabelSkin<TitleBarButton> skin = FSkin.get(this);
|
||||||
|
private boolean pressed, hovered;
|
||||||
|
|
||||||
|
private TitleBarButton() {
|
||||||
|
setPreferredSize(new Dimension(25, 25));
|
||||||
|
addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
if (SwingUtilities.isLeftMouseButton(e)) {
|
||||||
|
pressed = true;
|
||||||
|
repaintSelf();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(MouseEvent e) {
|
||||||
|
if (SwingUtilities.isLeftMouseButton(e)) {
|
||||||
|
if (pressed) {
|
||||||
|
pressed = false;
|
||||||
|
if (hovered) { //only handle click if mouse released over button
|
||||||
|
repaintSelf();
|
||||||
|
onClick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent e) {
|
||||||
|
hovered = true;
|
||||||
|
repaintSelf();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent e) {
|
||||||
|
hovered = false;
|
||||||
|
repaintSelf();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void onClick();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void repaintSelf() {
|
||||||
|
final Dimension d = this.getSize();
|
||||||
|
repaint(0, 0, d.width, d.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paintComponent(Graphics g) {
|
||||||
|
if (hovered) {
|
||||||
|
if (pressed) {
|
||||||
|
skin.setGraphicsColor(g, buttonDownColor);
|
||||||
|
g.fillRect(0, 0, getWidth(), getHeight());
|
||||||
|
g.translate(1, 1); //translate icon to give pressed button look
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
skin.setGraphicsColor(g, buttonHoverColor);
|
||||||
|
g.fillRect(0, 0, getWidth(), getHeight());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MinimizeButton extends TitleBarButton {
|
||||||
|
private MinimizeButton() {
|
||||||
|
setToolTipText("Minimize");
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected void onClick() {
|
||||||
|
frame.setMinimized(true);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void paintComponent(Graphics g) {
|
||||||
|
super.paintComponent(g);
|
||||||
|
|
||||||
|
int thickness = 2;
|
||||||
|
int offsetX = 8;
|
||||||
|
int offsetY = 7;
|
||||||
|
int x1 = offsetX;
|
||||||
|
int x2 = getWidth() - offsetX;
|
||||||
|
int y = getHeight() - offsetY - thickness;
|
||||||
|
|
||||||
|
Graphics2D g2d = (Graphics2D) g;
|
||||||
|
skin.setGraphicsColor(g2d, foreColor);
|
||||||
|
g2d.setStroke(new BasicStroke(thickness));
|
||||||
|
g2d.drawLine(x1, y, x2, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MaximizeButton extends TitleBarButton {
|
||||||
|
private MaximizeButton() {
|
||||||
|
setToolTipText("Maximize");
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected void onClick() {
|
||||||
|
frame.setMaximized(!frame.getMaximized());
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void paintComponent(Graphics g) {
|
||||||
|
super.paintComponent(g);
|
||||||
|
|
||||||
|
int thickness = 2;
|
||||||
|
int offsetX = 7;
|
||||||
|
int offsetY = 8;
|
||||||
|
int x = offsetX;
|
||||||
|
int y = offsetY;
|
||||||
|
int width = getWidth() - 2 * offsetX;
|
||||||
|
int height = getHeight() - 2 * offsetY;
|
||||||
|
|
||||||
|
Graphics2D g2d = (Graphics2D) g;
|
||||||
|
skin.setGraphicsColor(g2d, foreColor);
|
||||||
|
g2d.setStroke(new BasicStroke(thickness));
|
||||||
|
|
||||||
|
if (frame.getMaximized()) { //draw 2 rectangles offset if icon to restore window
|
||||||
|
x -= 1;
|
||||||
|
y += 2;
|
||||||
|
width -= 1;
|
||||||
|
height -= 1;
|
||||||
|
g2d.drawRect(x, y, width, height);
|
||||||
|
x += 3;
|
||||||
|
y -= 3;
|
||||||
|
//draw back rectangle as 4 lines so front rectangle doesn't show back rectangle through it
|
||||||
|
g2d.drawLine(x, y, x, y + 2);
|
||||||
|
g2d.drawLine(x, y, x + width, y);
|
||||||
|
x += width;
|
||||||
|
g2d.drawLine(x, y, x, y + height);
|
||||||
|
y += height;
|
||||||
|
g2d.drawLine(x - 2, y, x, y);
|
||||||
|
}
|
||||||
|
else { //otherwise just draw 1 rectangle if icon to maximize window
|
||||||
|
g2d.drawRect(x, y, width, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CloseButton extends TitleBarButton {
|
||||||
|
private CloseButton() {
|
||||||
|
setToolTipText("Close");
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected void onClick() {
|
||||||
|
WindowEvent wev = new WindowEvent(frame, WindowEvent.WINDOW_CLOSING);
|
||||||
|
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void paintComponent(Graphics g) {
|
||||||
|
super.paintComponent(g);
|
||||||
|
|
||||||
|
int thickness = 2;
|
||||||
|
int offset = 7;
|
||||||
|
int x1 = offset;
|
||||||
|
int y1 = offset;
|
||||||
|
int x2 = getWidth() - offset - 1;
|
||||||
|
int y2 = getHeight() - offset - 1;
|
||||||
|
|
||||||
|
Graphics2D g2d = (Graphics2D) g;
|
||||||
|
skin.setGraphicsColor(g2d, foreColor);
|
||||||
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
g2d.setStroke(new BasicStroke(thickness));
|
||||||
|
g2d.drawLine(x1, y1, x2, y2);
|
||||||
|
g2d.drawLine(x2, y1, x1, y2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -56,7 +56,9 @@ import forge.gui.toolbox.FSkin;
|
|||||||
import forge.gui.toolbox.FSkin.JComponentSkin;
|
import forge.gui.toolbox.FSkin.JComponentSkin;
|
||||||
import forge.gui.toolbox.FSkin.SkinCursor;
|
import forge.gui.toolbox.FSkin.SkinCursor;
|
||||||
import forge.model.BuildInfo;
|
import forge.model.BuildInfo;
|
||||||
|
import forge.properties.ForgePreferences;
|
||||||
import forge.properties.NewConstants;
|
import forge.properties.NewConstants;
|
||||||
|
import forge.properties.ForgePreferences.FPref;
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
public enum FView {
|
public enum FView {
|
||||||
@@ -65,6 +67,7 @@ public enum FView {
|
|||||||
|
|
||||||
/** */
|
/** */
|
||||||
public static final Integer TARGETING_LAYER = JLayeredPane.MODAL_LAYER - 1;
|
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 frmSplash;
|
private SplashFrame frmSplash;
|
||||||
|
|
||||||
@@ -75,11 +78,15 @@ public enum FView {
|
|||||||
private final FFrame frmDocument = new FFrame();
|
private final FFrame frmDocument = new FFrame();
|
||||||
// A layered pane is the frame's viewport, allowing overlay effects.
|
// A layered pane is the frame's viewport, allowing overlay effects.
|
||||||
private final DocumentPane lpnDocument = new DocumentPane();
|
private final DocumentPane lpnDocument = new DocumentPane();
|
||||||
|
// The status bar to display at the bottom of the frame
|
||||||
|
private FNavigationBar navigationBar;
|
||||||
// The content panel is placed in the layered pane.
|
// The content panel is placed in the layered pane.
|
||||||
private final JPanel pnlContent = new JPanel();
|
private final JPanel pnlContent = new JPanel();
|
||||||
// An insets panel neatly maintains a space from the edges of the window and
|
// An insets panel neatly maintains a space from the edges of the window and
|
||||||
// whatever layout is happening, without having to explicitly define a margin each time.
|
// whatever layout is happening, without having to explicitly define a margin each time.
|
||||||
private FPanel pnlInsets;
|
private FPanel pnlInsets;
|
||||||
|
// The status bar to display at the bottom of the frame
|
||||||
|
private FStatusBar statusBar;
|
||||||
// Preview panel is what is shown when a drag cell is being moved around
|
// Preview panel is what is shown when a drag cell is being moved around
|
||||||
private final JPanel pnlPreview = new PreviewPanel();
|
private final JPanel pnlPreview = new PreviewPanel();
|
||||||
// Tab overflow is for the +X display for extra tabs.
|
// Tab overflow is for the +X display for extra tabs.
|
||||||
@@ -87,29 +94,36 @@ public enum FView {
|
|||||||
|
|
||||||
private FView() {
|
private FView() {
|
||||||
frmSplash = new SplashFrame();
|
frmSplash = new SplashFrame();
|
||||||
|
frmDocument.setTitle("Forge: " + BuildInfo.getVersionString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
// Insets panel has background image / texture, which
|
final ForgePreferences prefs = Singletons.getModel().getPreferences();
|
||||||
// must be instantiated after the skin is loaded.
|
|
||||||
|
// pnlInsets, navigationBar, and statusBar are skinned components
|
||||||
|
// which must be instantiated after the skin is loaded.
|
||||||
pnlInsets = new FPanel(new BorderLayout());
|
pnlInsets = new FPanel(new BorderLayout());
|
||||||
pnlInsets.setBorderToggle(false);
|
pnlInsets.setBorderToggle(false);
|
||||||
|
navigationBar = new FNavigationBar(frmDocument);
|
||||||
|
statusBar = new FStatusBar(frmDocument, !prefs.getPrefBoolean(FPref.UI_HIDE_STATUS_BAR));
|
||||||
|
|
||||||
// Frame styling
|
// Frame styling
|
||||||
frmDocument.initialize();
|
frmDocument.initialize(navigationBar, !prefs.getPrefBoolean(FPref.UI_HIDE_TITLE_BAR));
|
||||||
frmDocument.setMinimumSize(new Dimension(800, 600));
|
frmDocument.setMinimumSize(new Dimension(800, 600));
|
||||||
frmDocument.setLocationRelativeTo(null);
|
frmDocument.setLocationRelativeTo(null);
|
||||||
frmDocument.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
frmDocument.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||||
FSkin.get(frmDocument).setIconImage(FSkin.getIcon(FSkin.InterfaceIcons.ICO_FAVICON));
|
FSkin.get(frmDocument).setIconImage(FSkin.getIcon(FSkin.InterfaceIcons.ICO_FAVICON));
|
||||||
frmDocument.setTitle("Forge: " + BuildInfo.getVersionString());
|
|
||||||
|
|
||||||
// Frame components
|
// Frame components
|
||||||
frmDocument.getInnerPane().setContentPane(lpnDocument);
|
frmDocument.setContentPane(lpnDocument);
|
||||||
lpnDocument.add(pnlInsets, (Integer) 1);
|
lpnDocument.add(pnlInsets, (Integer) 1);
|
||||||
|
lpnDocument.add(statusBar, (Integer) 1); //should always appear below pnlInsets, so put at same level
|
||||||
FAbsolutePositioner.SINGLETON_INSTANCE.initialize(lpnDocument, (Integer) 2);
|
FAbsolutePositioner.SINGLETON_INSTANCE.initialize(lpnDocument, (Integer) 2);
|
||||||
lpnDocument.add(pnlPreview, (Integer) 3);
|
lpnDocument.add(pnlPreview, (Integer) 3);
|
||||||
lpnDocument.add(pnlTabOverflow, (Integer) 4);
|
lpnDocument.add(pnlTabOverflow, (Integer) 4);
|
||||||
|
lpnDocument.add(navigationBar.getPnlReveal(), (Integer) 5); //put this at layer directly behind navigation bar
|
||||||
|
lpnDocument.add(navigationBar, (Integer) 6); //ensure this appears over all other non-overlay layers
|
||||||
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
|
// Note: when adding new panels here, keep in mind that the layered pane
|
||||||
// has a null layout, so new components will be W0 x H0 pixels - gotcha!
|
// has a null layout, so new components will be W0 x H0 pixels - gotcha!
|
||||||
@@ -304,6 +318,11 @@ public enum FView {
|
|||||||
return lpnDocument;
|
return lpnDocument;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return {@link forge.view.FNavigationBar} */
|
||||||
|
public FNavigationBar getNavigationBar() {
|
||||||
|
return navigationBar;
|
||||||
|
}
|
||||||
|
|
||||||
/** @return {@link forge.gui.toolbox.FPanel} */
|
/** @return {@link forge.gui.toolbox.FPanel} */
|
||||||
public FPanel getPnlInsets() {
|
public FPanel getPnlInsets() {
|
||||||
return pnlInsets;
|
return pnlInsets;
|
||||||
@@ -314,6 +333,11 @@ public enum FView {
|
|||||||
return pnlContent;
|
return pnlContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return {@link forge.view.FStatusBar} */
|
||||||
|
public FStatusBar getStatusBar() {
|
||||||
|
return statusBar;
|
||||||
|
}
|
||||||
|
|
||||||
/** @return {@link javax.swing.JPanel} */
|
/** @return {@link javax.swing.JPanel} */
|
||||||
public JPanel getPnlPreview() {
|
public JPanel getPnlPreview() {
|
||||||
return pnlPreview;
|
return pnlPreview;
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
package forge;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import junit.framework.Assert;
|
|
||||||
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import forge.card.CardRules;
|
|
||||||
import forge.card.CardRulesReader;
|
|
||||||
import forge.game.limited.ReadDraftRankings;
|
|
||||||
import forge.properties.NewConstants;
|
|
||||||
import forge.util.FileUtil;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests for ReadDraftRankings.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Test(enabled = true)
|
|
||||||
public class ReadDraftRankingsTest {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Card test.
|
|
||||||
*/
|
|
||||||
@Test(enabled = true)
|
|
||||||
void test() {
|
|
||||||
ReadDraftRankings rdr = new ReadDraftRankings();
|
|
||||||
Assert.assertNotNull(rdr);
|
|
||||||
|
|
||||||
CardRulesReader cr = new CardRulesReader();
|
|
||||||
|
|
||||||
List<String> cardLines = FileUtil.readFile(new File(NewConstants.CARD_DATA_DIR + "/g", "garruk_primal_hunter.txt"));
|
|
||||||
CardRules c = cr.readCard(cardLines);
|
|
||||||
// Assert.assertEquals(1.0 / 234.0, rdr.getRanking(c.getName(), "M13").doubleValue());
|
|
||||||
|
|
||||||
cardLines = FileUtil.readFile(new File(NewConstants.CARD_DATA_DIR + "/c", "clone.txt"));
|
|
||||||
c = cr.readCard(cardLines);
|
|
||||||
// Assert.assertEquals(38.0 / 234.0, rdr.getRanking(c.getName(), "M13").doubleValue());
|
|
||||||
|
|
||||||
cardLines = FileUtil.readFile(new File(NewConstants.CARD_DATA_DIR + "/t", "tamiyo_the_moon_sage.txt"));
|
|
||||||
c = cr.readCard(cardLines);
|
|
||||||
// Assert.assertEquals(1.0 / 234.0, rdr.getRanking(c.getName(), "AVR").doubleValue());
|
|
||||||
|
|
||||||
// Mikaeus, the Lunarch has a comma in its name in the rankings file
|
|
||||||
cardLines = FileUtil.readFile(new File(NewConstants.CARD_DATA_DIR + "/m", "mikaeus_the_lunarch.txt"));
|
|
||||||
c = cr.readCard(cardLines);
|
|
||||||
// Assert.assertEquals(4.0 / 255.0, rdr.getRanking(c.getName(), "ISD").doubleValue());
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user