From 59122728bc48479a4895a4793adf76fa3e7ccd77 Mon Sep 17 00:00:00 2001 From: Doublestrike Date: Sun, 20 May 2012 05:43:26 +0000 Subject: [PATCH] Deck editor UI integration. --- .gitattributes | 97 +- .gitignore | 2 - editor.preferences | 32 + res/images/deckeditor/filter_artifact_n.png | Bin 3382 -> 0 bytes res/images/deckeditor/filter_artifact_y.png | Bin 3346 -> 0 bytes res/images/deckeditor/filter_black_n.png | Bin 2398 -> 0 bytes res/images/deckeditor/filter_black_y.png | Bin 2281 -> 0 bytes res/images/deckeditor/filter_blue_n.png | Bin 2305 -> 0 bytes res/images/deckeditor/filter_blue_y.png | Bin 2234 -> 0 bytes res/images/deckeditor/filter_colorless_n.png | Bin 2313 -> 0 bytes res/images/deckeditor/filter_colorless_y.png | Bin 2251 -> 0 bytes res/images/deckeditor/filter_creature_n.png | Bin 3346 -> 0 bytes res/images/deckeditor/filter_creature_y.png | Bin 3299 -> 0 bytes res/images/deckeditor/filter_enchant_n.png | Bin 3462 -> 0 bytes res/images/deckeditor/filter_enchant_y.png | Bin 3462 -> 0 bytes res/images/deckeditor/filter_green_n.png | Bin 2299 -> 0 bytes res/images/deckeditor/filter_green_y.png | Bin 2243 -> 0 bytes res/images/deckeditor/filter_instant_n.png | Bin 3383 -> 0 bytes res/images/deckeditor/filter_instant_y.png | Bin 3347 -> 0 bytes res/images/deckeditor/filter_land_n.png | Bin 3353 -> 0 bytes res/images/deckeditor/filter_land_y.png | Bin 3315 -> 0 bytes .../deckeditor/filter_planeswalker_n.png | Bin 3460 -> 0 bytes .../deckeditor/filter_planeswalker_y.png | Bin 3442 -> 0 bytes res/images/deckeditor/filter_red_n.png | Bin 2316 -> 0 bytes res/images/deckeditor/filter_red_y.png | Bin 2254 -> 0 bytes res/images/deckeditor/filter_sorcery_n.png | Bin 3508 -> 0 bytes res/images/deckeditor/filter_sorcery_y.png | Bin 3463 -> 0 bytes res/images/deckeditor/filter_white_n.png | Bin 2138 -> 0 bytes res/images/deckeditor/filter_white_y.png | Bin 2130 -> 0 bytes res/skins/default/grid_icons.png | Bin 6624 -> 6768 bytes res/skins/default/sprite_icons.png | Bin 572746 -> 598942 bytes res/sound/tap.mp3 | Bin 9344 -> 0 bytes src/main/java/forge/card/CardRules.java | 71 +- src/main/java/forge/control/FControl.java | 77 +- src/main/java/forge/deck/Deck.java | 2 +- .../java/forge/game/limited/BoosterDraft.java | 7 +- src/main/java/forge/game/player/Player.java | 4 +- .../forge/gui/deckeditor/CDeckEditorUI.java | 113 ++ .../forge/gui/deckeditor/DeckEditorBase.java | 358 ----- .../gui/deckeditor/DeckEditorConstructed.java | 414 ----- .../gui/deckeditor/DeckEditorLimited.java | 415 ----- .../forge/gui/deckeditor/DeckEditorQuest.java | 414 ----- .../java/forge/gui/deckeditor/DeckImport.java | 16 +- .../forge/gui/deckeditor/DraftingProcess.java | 392 ----- .../java/forge/gui/deckeditor/MenuBase.java | 454 ------ .../java/forge/gui/deckeditor/MenuCommon.java | 33 +- .../forge/gui/deckeditor/MenuLimited.java | 48 - .../java/forge/gui/deckeditor/MenuQuest.java | 226 --- .../forge/gui/deckeditor/PresetColumns.java | 227 --- .../forge/gui/deckeditor/QuestCardShop.java | 530 ------- .../java/forge/gui/deckeditor/SEditorIO.java | 303 ++++ .../forge/gui/deckeditor/SEditorUtil.java | 149 ++ .../forge/gui/deckeditor/SFilterUtil.java | 515 +++++++ .../forge/gui/deckeditor/VDeckEditorUI.java | 61 + .../deckeditor/controllers/ACEditorBase.java | 115 ++ .../gui/deckeditor/controllers/CAllDecks.java | 68 + .../deckeditor/controllers/CCardCatalog.java | 76 + .../deckeditor/controllers/CCurrentDeck.java | 202 +++ .../gui/deckeditor/controllers/CDeckgen.java | 120 ++ .../controllers/CEditorConstructed.java | 158 ++ .../controllers/CEditorDraftingProcess.java | 249 +++ .../controllers/CEditorLimited.java | 183 +++ .../controllers/CEditorPreferences.java | 151 ++ .../deckeditor/controllers/CEditorQuest.java | 204 +++ .../controllers/CEditorQuestCardShop.java | 368 +++++ .../gui/deckeditor/controllers/CFilters.java | 176 +++ .../controllers/CProbabilities.java | 100 ++ .../deckeditor/controllers/CStatistics.java | 191 +++ .../deckeditor/elements/CardPanelBase.java | 40 - .../deckeditor/elements/CardPanelHeavy.java | 251 --- .../deckeditor/elements/CardPanelLite.java | 183 --- .../deckeditor/elements/CheckBoxWithIcon.java | 65 - .../gui/deckeditor/elements/DeckAnalysis.java | 1357 ----------------- .../deckeditor/elements/FilterCheckBoxes.java | 327 ---- .../elements/FilterNameTypeSetPanel.java | 170 --- .../deckeditor/elements/TableColumnInfo.java | 247 --- .../gui/deckeditor/elements/TableModel.java | 451 ------ .../gui/deckeditor/elements/package-info.java | 3 - .../{ => tables}/DeckController.java | 52 +- .../deckeditor/tables/IntegerRenderer.java | 44 + .../ManaCostRenderer.java | 2 +- .../gui/deckeditor/tables/SColumnUtil.java | 530 +++++++ .../deckeditor/tables/TableColumnInfo.java | 142 ++ .../gui/deckeditor/tables/TableModel.java | 373 +++++ .../{elements => tables}/TableSorter.java | 2 +- .../TableSorterCascade.java | 2 +- .../{elements => tables}/TableView.java | 232 +-- .../gui/deckeditor/tables/package-info.java | 3 + .../gui/deckeditor/views/ITableContainer.java | 65 + .../forge/gui/deckeditor/views/VAllDecks.java | 110 ++ .../gui/deckeditor/views/VCardCatalog.java | 315 ++++ .../gui/deckeditor/views/VCurrentDeck.java | 406 +++++ .../forge/gui/deckeditor/views/VDeckgen.java | 128 ++ .../deckeditor/views/VEditorPreferences.java | 225 +++ .../forge/gui/deckeditor/views/VFilters.java | 306 ++++ .../gui/deckeditor/views/VProbabilities.java | 198 +++ .../gui/deckeditor/views/VStatistics.java | 271 ++++ .../java/forge/gui/framework/DragCell.java | 28 +- src/main/java/forge/gui/framework/EDocID.java | 19 +- src/main/java/forge/gui/framework/ICDoc.java | 6 +- .../forge/gui/framework/IVTopLevelUI.java | 8 +- .../{SIOUtil.java => SLayoutIO.java} | 77 +- .../forge/gui/framework/SRearrangingUtil.java | 15 +- .../forge/gui/framework/SResizingUtil.java | 2 +- src/main/java/forge/gui/home/VHomeUI.java | 25 +- .../gui/home/quest/CSubmenuChallenges.java | 10 +- .../forge/gui/home/quest/CSubmenuDuels.java | 10 +- .../gui/home/quest/CSubmenuQuestData.java | 2 +- .../gui/home/quest/CSubmenuQuestDecks.java | 22 +- ...uQuestUtil.java => SSubmenuQuestUtil.java} | 30 +- .../gui/home/quest/VSubmenuChallenges.java | 4 +- .../forge/gui/home/quest/VSubmenuDuels.java | 4 +- .../gui/home/sanctioned/CSubmenuDraft.java | 20 +- .../gui/home/sanctioned/CSubmenuSealed.java | 27 +- .../home/utilities/CSubmenuDeckEditor.java | 17 +- src/main/java/forge/gui/match/VMatchUI.java | 4 +- .../forge/gui/match/controllers/CDock.java | 14 +- .../java/forge/gui/toolbox/DeckLister.java | 119 +- src/main/java/forge/gui/toolbox/FLabel.java | 98 +- src/main/java/forge/gui/toolbox/FSkin.java | 46 +- .../java/forge/gui/toolbox/FTextArea.java | 1 + .../java/forge/gui/toolbox/FTextField.java | 20 + src/main/java/forge/item/CardPrinted.java | 13 +- src/main/java/forge/item/ItemPool.java | 5 + src/main/java/forge/model/FModel.java | 2 +- .../java/forge/properties/NewConstants.java | 52 +- src/main/java/forge/quest/QuestUtilCards.java | 2 +- .../java/forge/util/closures/Predicate.java | 83 +- .../forge/util/closures/PredicateInteger.java | 75 + src/main/java/forge/view/FView.java | 29 +- 130 files changed, 7477 insertions(+), 7233 deletions(-) create mode 100644 editor.preferences delete mode 100644 res/images/deckeditor/filter_artifact_n.png delete mode 100644 res/images/deckeditor/filter_artifact_y.png delete mode 100644 res/images/deckeditor/filter_black_n.png delete mode 100644 res/images/deckeditor/filter_black_y.png delete mode 100644 res/images/deckeditor/filter_blue_n.png delete mode 100644 res/images/deckeditor/filter_blue_y.png delete mode 100644 res/images/deckeditor/filter_colorless_n.png delete mode 100644 res/images/deckeditor/filter_colorless_y.png delete mode 100644 res/images/deckeditor/filter_creature_n.png delete mode 100644 res/images/deckeditor/filter_creature_y.png delete mode 100644 res/images/deckeditor/filter_enchant_n.png delete mode 100644 res/images/deckeditor/filter_enchant_y.png delete mode 100644 res/images/deckeditor/filter_green_n.png delete mode 100644 res/images/deckeditor/filter_green_y.png delete mode 100644 res/images/deckeditor/filter_instant_n.png delete mode 100644 res/images/deckeditor/filter_instant_y.png delete mode 100644 res/images/deckeditor/filter_land_n.png delete mode 100644 res/images/deckeditor/filter_land_y.png delete mode 100644 res/images/deckeditor/filter_planeswalker_n.png delete mode 100644 res/images/deckeditor/filter_planeswalker_y.png delete mode 100644 res/images/deckeditor/filter_red_n.png delete mode 100644 res/images/deckeditor/filter_red_y.png delete mode 100644 res/images/deckeditor/filter_sorcery_n.png delete mode 100644 res/images/deckeditor/filter_sorcery_y.png delete mode 100644 res/images/deckeditor/filter_white_n.png delete mode 100644 res/images/deckeditor/filter_white_y.png delete mode 100644 res/sound/tap.mp3 create mode 100644 src/main/java/forge/gui/deckeditor/CDeckEditorUI.java delete mode 100644 src/main/java/forge/gui/deckeditor/DeckEditorBase.java delete mode 100644 src/main/java/forge/gui/deckeditor/DeckEditorConstructed.java delete mode 100644 src/main/java/forge/gui/deckeditor/DeckEditorLimited.java delete mode 100644 src/main/java/forge/gui/deckeditor/DeckEditorQuest.java delete mode 100644 src/main/java/forge/gui/deckeditor/DraftingProcess.java delete mode 100644 src/main/java/forge/gui/deckeditor/MenuBase.java delete mode 100644 src/main/java/forge/gui/deckeditor/MenuLimited.java delete mode 100644 src/main/java/forge/gui/deckeditor/MenuQuest.java delete mode 100644 src/main/java/forge/gui/deckeditor/PresetColumns.java delete mode 100644 src/main/java/forge/gui/deckeditor/QuestCardShop.java create mode 100644 src/main/java/forge/gui/deckeditor/SEditorIO.java create mode 100644 src/main/java/forge/gui/deckeditor/SEditorUtil.java create mode 100644 src/main/java/forge/gui/deckeditor/SFilterUtil.java create mode 100644 src/main/java/forge/gui/deckeditor/VDeckEditorUI.java create mode 100644 src/main/java/forge/gui/deckeditor/controllers/ACEditorBase.java create mode 100644 src/main/java/forge/gui/deckeditor/controllers/CAllDecks.java create mode 100644 src/main/java/forge/gui/deckeditor/controllers/CCardCatalog.java create mode 100644 src/main/java/forge/gui/deckeditor/controllers/CCurrentDeck.java create mode 100644 src/main/java/forge/gui/deckeditor/controllers/CDeckgen.java create mode 100644 src/main/java/forge/gui/deckeditor/controllers/CEditorConstructed.java create mode 100644 src/main/java/forge/gui/deckeditor/controllers/CEditorDraftingProcess.java create mode 100644 src/main/java/forge/gui/deckeditor/controllers/CEditorLimited.java create mode 100644 src/main/java/forge/gui/deckeditor/controllers/CEditorPreferences.java create mode 100644 src/main/java/forge/gui/deckeditor/controllers/CEditorQuest.java create mode 100644 src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java create mode 100644 src/main/java/forge/gui/deckeditor/controllers/CFilters.java create mode 100644 src/main/java/forge/gui/deckeditor/controllers/CProbabilities.java create mode 100644 src/main/java/forge/gui/deckeditor/controllers/CStatistics.java delete mode 100644 src/main/java/forge/gui/deckeditor/elements/CardPanelBase.java delete mode 100644 src/main/java/forge/gui/deckeditor/elements/CardPanelHeavy.java delete mode 100644 src/main/java/forge/gui/deckeditor/elements/CardPanelLite.java delete mode 100644 src/main/java/forge/gui/deckeditor/elements/CheckBoxWithIcon.java delete mode 100644 src/main/java/forge/gui/deckeditor/elements/DeckAnalysis.java delete mode 100644 src/main/java/forge/gui/deckeditor/elements/FilterCheckBoxes.java delete mode 100644 src/main/java/forge/gui/deckeditor/elements/FilterNameTypeSetPanel.java delete mode 100644 src/main/java/forge/gui/deckeditor/elements/TableColumnInfo.java delete mode 100644 src/main/java/forge/gui/deckeditor/elements/TableModel.java delete mode 100644 src/main/java/forge/gui/deckeditor/elements/package-info.java rename src/main/java/forge/gui/deckeditor/{ => tables}/DeckController.java (83%) create mode 100644 src/main/java/forge/gui/deckeditor/tables/IntegerRenderer.java rename src/main/java/forge/gui/deckeditor/{elements => tables}/ManaCostRenderer.java (95%) create mode 100644 src/main/java/forge/gui/deckeditor/tables/SColumnUtil.java create mode 100644 src/main/java/forge/gui/deckeditor/tables/TableColumnInfo.java create mode 100644 src/main/java/forge/gui/deckeditor/tables/TableModel.java rename src/main/java/forge/gui/deckeditor/{elements => tables}/TableSorter.java (98%) rename src/main/java/forge/gui/deckeditor/{elements => tables}/TableSorterCascade.java (95%) rename src/main/java/forge/gui/deckeditor/{elements => tables}/TableView.java (52%) create mode 100644 src/main/java/forge/gui/deckeditor/tables/package-info.java create mode 100644 src/main/java/forge/gui/deckeditor/views/ITableContainer.java create mode 100644 src/main/java/forge/gui/deckeditor/views/VAllDecks.java create mode 100644 src/main/java/forge/gui/deckeditor/views/VCardCatalog.java create mode 100644 src/main/java/forge/gui/deckeditor/views/VCurrentDeck.java create mode 100644 src/main/java/forge/gui/deckeditor/views/VDeckgen.java create mode 100644 src/main/java/forge/gui/deckeditor/views/VEditorPreferences.java create mode 100644 src/main/java/forge/gui/deckeditor/views/VFilters.java create mode 100644 src/main/java/forge/gui/deckeditor/views/VProbabilities.java create mode 100644 src/main/java/forge/gui/deckeditor/views/VStatistics.java rename src/main/java/forge/gui/framework/{SIOUtil.java => SLayoutIO.java} (73%) rename src/main/java/forge/gui/home/quest/{SubmenuQuestUtil.java => SSubmenuQuestUtil.java} (93%) create mode 100644 src/main/java/forge/gui/toolbox/FTextField.java create mode 100644 src/main/java/forge/util/closures/PredicateInteger.java diff --git a/.gitattributes b/.gitattributes index 718320f9f77..d13e4cfbe8c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -9,6 +9,7 @@ /CHANGES.txt svneol=native#text/plain /LICENSE.txt svneol=native#text/plain /README.txt svneol=native#text/plain +/editor.preferences -text /forge.properties svneol=native#text/plain /pom.xml svneol=native#text/xml res/AllTokens.txt svneol=native#text/plain @@ -10854,32 +10855,6 @@ res/draft/rare.txt svneol=native#text/plain res/draft/uncommon.txt svneol=native#text/plain res/gamedata/NonStackingKWList.txt svneol=native#text/plain res/gamedata/TypeLists.txt svneol=native#text/plain -res/images/deckeditor/filter_artifact_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_artifact_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_black_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_black_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_blue_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_blue_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_colorless_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_colorless_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_creature_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_creature_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_enchant_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_enchant_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_green_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_green_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_instant_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_instant_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_land_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_land_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_planeswalker_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_planeswalker_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_red_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_red_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_sorcery_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_sorcery_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_white_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_white_y.png -text svneol=unset#image/png res/lang/de.properties svneol=native#text/plain res/lang/en.properties svneol=native#text/plain res/lang/howTo/de.properties svneol=native#text/plain @@ -11610,7 +11585,6 @@ res/skins/the_simpsons/bg_texture.jpg -text res/skins/the_simpsons/font1.ttf -text res/skins/the_simpsons/sprite_avatars.png -text res/skins/the_simpsons/sprite_icons.png -text -res/sound/tap.mp3 -text svneol=unset#audio/mpeg res/token-images.txt -text src/main/config/Forge.icns -text src/main/config/backgroundImage.jpg -text svneol=unset#image/jpeg @@ -11935,34 +11909,47 @@ src/main/java/forge/gui/MultiLineLabelUI.java svneol=native#text/plain src/main/java/forge/gui/MultiPhaseProgressMonitorWithETA.java svneol=native#text/plain src/main/java/forge/gui/SOverlayUtils.java -text src/main/java/forge/gui/WrapLayout.java -text -src/main/java/forge/gui/deckeditor/DeckController.java -text -src/main/java/forge/gui/deckeditor/DeckEditorBase.java -text -src/main/java/forge/gui/deckeditor/DeckEditorConstructed.java svneol=native#text/plain -src/main/java/forge/gui/deckeditor/DeckEditorLimited.java -text -src/main/java/forge/gui/deckeditor/DeckEditorQuest.java svneol=native#text/plain +src/main/java/forge/gui/deckeditor/CDeckEditorUI.java -text src/main/java/forge/gui/deckeditor/DeckImport.java -text -src/main/java/forge/gui/deckeditor/DraftingProcess.java svneol=native#text/plain -src/main/java/forge/gui/deckeditor/MenuBase.java -text src/main/java/forge/gui/deckeditor/MenuCommon.java svneol=native#text/plain -src/main/java/forge/gui/deckeditor/MenuLimited.java -text -src/main/java/forge/gui/deckeditor/MenuQuest.java svneol=native#text/plain -src/main/java/forge/gui/deckeditor/PresetColumns.java -text -src/main/java/forge/gui/deckeditor/QuestCardShop.java svneol=native#text/plain -src/main/java/forge/gui/deckeditor/elements/CardPanelBase.java -text -src/main/java/forge/gui/deckeditor/elements/CardPanelHeavy.java -text -src/main/java/forge/gui/deckeditor/elements/CardPanelLite.java -text -src/main/java/forge/gui/deckeditor/elements/CheckBoxWithIcon.java svneol=native#text/plain -src/main/java/forge/gui/deckeditor/elements/DeckAnalysis.java svneol=native#text/plain -src/main/java/forge/gui/deckeditor/elements/FilterCheckBoxes.java -text -src/main/java/forge/gui/deckeditor/elements/FilterNameTypeSetPanel.java -text -src/main/java/forge/gui/deckeditor/elements/ManaCostRenderer.java -text -src/main/java/forge/gui/deckeditor/elements/TableColumnInfo.java -text -src/main/java/forge/gui/deckeditor/elements/TableModel.java svneol=native#text/plain -src/main/java/forge/gui/deckeditor/elements/TableSorter.java svneol=native#text/plain -src/main/java/forge/gui/deckeditor/elements/TableSorterCascade.java -text -src/main/java/forge/gui/deckeditor/elements/TableView.java -text -src/main/java/forge/gui/deckeditor/elements/package-info.java -text +src/main/java/forge/gui/deckeditor/SEditorIO.java -text +src/main/java/forge/gui/deckeditor/SEditorUtil.java -text +src/main/java/forge/gui/deckeditor/SFilterUtil.java -text +src/main/java/forge/gui/deckeditor/VDeckEditorUI.java -text +src/main/java/forge/gui/deckeditor/controllers/ACEditorBase.java -text +src/main/java/forge/gui/deckeditor/controllers/CAllDecks.java -text +src/main/java/forge/gui/deckeditor/controllers/CCardCatalog.java -text +src/main/java/forge/gui/deckeditor/controllers/CCurrentDeck.java -text +src/main/java/forge/gui/deckeditor/controllers/CDeckgen.java -text +src/main/java/forge/gui/deckeditor/controllers/CEditorConstructed.java svneol=native#text/plain +src/main/java/forge/gui/deckeditor/controllers/CEditorDraftingProcess.java svneol=native#text/plain +src/main/java/forge/gui/deckeditor/controllers/CEditorLimited.java -text +src/main/java/forge/gui/deckeditor/controllers/CEditorPreferences.java -text +src/main/java/forge/gui/deckeditor/controllers/CEditorQuest.java svneol=native#text/plain +src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java -text +src/main/java/forge/gui/deckeditor/controllers/CFilters.java -text +src/main/java/forge/gui/deckeditor/controllers/CProbabilities.java -text +src/main/java/forge/gui/deckeditor/controllers/CStatistics.java -text src/main/java/forge/gui/deckeditor/package-info.java -text +src/main/java/forge/gui/deckeditor/tables/DeckController.java -text +src/main/java/forge/gui/deckeditor/tables/IntegerRenderer.java -text +src/main/java/forge/gui/deckeditor/tables/ManaCostRenderer.java -text +src/main/java/forge/gui/deckeditor/tables/SColumnUtil.java -text +src/main/java/forge/gui/deckeditor/tables/TableColumnInfo.java -text +src/main/java/forge/gui/deckeditor/tables/TableModel.java svneol=native#text/plain +src/main/java/forge/gui/deckeditor/tables/TableSorter.java svneol=native#text/plain +src/main/java/forge/gui/deckeditor/tables/TableSorterCascade.java -text +src/main/java/forge/gui/deckeditor/tables/TableView.java -text +src/main/java/forge/gui/deckeditor/tables/package-info.java -text +src/main/java/forge/gui/deckeditor/views/ITableContainer.java -text +src/main/java/forge/gui/deckeditor/views/VAllDecks.java -text +src/main/java/forge/gui/deckeditor/views/VCardCatalog.java -text +src/main/java/forge/gui/deckeditor/views/VCurrentDeck.java -text +src/main/java/forge/gui/deckeditor/views/VDeckgen.java -text +src/main/java/forge/gui/deckeditor/views/VEditorPreferences.java -text +src/main/java/forge/gui/deckeditor/views/VFilters.java -text +src/main/java/forge/gui/deckeditor/views/VProbabilities.java -text +src/main/java/forge/gui/deckeditor/views/VStatistics.java -text src/main/java/forge/gui/download/GuiDownloadPicturesLQ.java svneol=native#text/plain src/main/java/forge/gui/download/GuiDownloadPrices.java svneol=native#text/plain src/main/java/forge/gui/download/GuiDownloadQuestImages.java -text @@ -11978,8 +11965,8 @@ src/main/java/forge/gui/framework/ILocalRepaint.java -text src/main/java/forge/gui/framework/IVDoc.java -text src/main/java/forge/gui/framework/IVTopLevelUI.java -text src/main/java/forge/gui/framework/SDisplayUtil.java -text -src/main/java/forge/gui/framework/SIOUtil.java -text src/main/java/forge/gui/framework/SLayoutConstants.java -text +src/main/java/forge/gui/framework/SLayoutIO.java -text src/main/java/forge/gui/framework/SOverflowUtil.java -text src/main/java/forge/gui/framework/SRearrangingUtil.java -text src/main/java/forge/gui/framework/SResizingUtil.java -text @@ -11999,7 +11986,7 @@ src/main/java/forge/gui/home/quest/CSubmenuQuestPrefs.java -text src/main/java/forge/gui/home/quest/IStatsAndPet.java -text src/main/java/forge/gui/home/quest/QuestFileLister.java -text src/main/java/forge/gui/home/quest/QuestPreferencesHandler.java -text -src/main/java/forge/gui/home/quest/SubmenuQuestUtil.java -text +src/main/java/forge/gui/home/quest/SSubmenuQuestUtil.java -text src/main/java/forge/gui/home/quest/VSubmenuChallenges.java -text src/main/java/forge/gui/home/quest/VSubmenuDuels.java -text src/main/java/forge/gui/home/quest/VSubmenuQuestData.java -text @@ -12074,6 +12061,7 @@ src/main/java/forge/gui/toolbox/FRadioButton.java -text src/main/java/forge/gui/toolbox/FScrollPane.java -text src/main/java/forge/gui/toolbox/FSkin.java -text src/main/java/forge/gui/toolbox/FTextArea.java -text +src/main/java/forge/gui/toolbox/FTextField.java -text src/main/java/forge/gui/toolbox/SaveOpenDialog.java -text src/main/java/forge/gui/toolbox/package-info.java svneol=native#text/plain src/main/java/forge/item/BoosterPack.java -text @@ -12166,6 +12154,7 @@ src/main/java/forge/util/closures/Lambda.java svneol=native#text/plain src/main/java/forge/util/closures/Lambda0.java -text src/main/java/forge/util/closures/Lambda1.java svneol=native#text/plain src/main/java/forge/util/closures/Predicate.java -text +src/main/java/forge/util/closures/PredicateInteger.java -text src/main/java/forge/util/closures/PredicateString.java -text src/main/java/forge/util/closures/package-info.java -text svneol=native#text/plain src/main/java/forge/util/package-info.java -text diff --git a/.gitignore b/.gitignore index b0ce13d2b18..c348b8c8e8d 100644 --- a/.gitignore +++ b/.gitignore @@ -268,8 +268,6 @@ res/decks/Zemox's[!!-~]Mono-Green[!!-~]Infect.dck res/decks/Zvi[!!-~]Mowshowitz's[!!-~]Mono-Black[!!-~]Control.dck res/decks/constructed/*.dck res/decks/o1.bdk -res/images/icons -res/images/themes res/layouts/*.xml res/oracleScript.log res/pics diff --git a/editor.preferences b/editor.preferences new file mode 100644 index 00000000000..f6eca9389ec --- /dev/null +++ b/editor.preferences @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/images/deckeditor/filter_artifact_n.png b/res/images/deckeditor/filter_artifact_n.png deleted file mode 100644 index 2523d044c0a25c6604529fbbf4c37b31eb97a063..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3382 zcmV-64axF}P)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=00004XF*Lt006O$eEU(80000WV@Og>004R=004l4008;_004mL004C` z008P>0026e000+nl3&F}0006}Nkl1lm9=y8mzN%ZNPMurxXKP?12Cx!~ zvp$WF7{e<}bP7=Gu)Y%eF^rzS9AXyFaSI<7l3+WI7N>=&{QLz!(1%r6R_tlwIv)Kg z!5$ng{5QCd(ZEvL;y||>gT?v?ZnvDW{B1a1__uH=C!g&A%?CWeT#;lDlNc`(^y6&& zW*WFAy{H1qTv2romSY`uVl%!M-v-l{=@vw%u{H0Pvtdhd+L=JqjK2s=(Ax&*Gn|P3 z92cuJYq;3-5UbnZ=*@{6dHULdOPt4e9e)U`tGrZMyqhwY`gf}bo;wAULsgj2qT*=S zQFW1^mVd`WXBeo`NSVeN|7W$3VLbkdDy0cigbmFug3spUeMJxJB@`QQC>tlbNH88E zoJ*2lgSNAfg>~WoY}oQIHj}CD4;nR0RT-+*hKaChxQhxJ(Wd($3`|yGjxc8gSMa%u z1aEO3PYV$o?ZLOeRE7W7GBEFpQq411U-2pT!APFZI2mUCz_s28){DS0h+TLP5qpxv zb(|??<{d7~qp&-$KJPCvQ56#VJ?}?yi?wVnRlX?JUd|JIJ&qOqyiuy@bV_c?#!!NO z!dmQ&oYxE8X%xw~;ZyQQzpE>sHhoAjwSfJP62)n019`J1|kwXbN~PV M07*qoM6N<$f@$SSy8r+H diff --git a/res/images/deckeditor/filter_artifact_y.png b/res/images/deckeditor/filter_artifact_y.png deleted file mode 100644 index 0b551e67d935a71b2d0f3bfaed711638913846e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3346 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 diff --git a/res/images/deckeditor/filter_black_y.png b/res/images/deckeditor/filter_black_y.png deleted file mode 100644 index 6e4246a2bebe2dacc2e9838dad5b7acad6661b1e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2281 zcmaJ@c~nyQ9;eK5H1%n?r77OB$OX8#pd==8C9yD6G&RjZxCkm-1PmmbCN-Bzl9QQQ z)3ekx^VKwYMq8|0D5uq&HgmFEPK|4NTC|?kgC?8z$Lrm5?)@$2^Z9(Y&mXst6}HaQ zc&RZ8g)(J?KoPptR{t6;)P0{RC^NdnP97X1k3{%#1xE^_s5~SI#xO*jWHiDUu+^W_0_ z(WE>+IRc`8iKRPH0D)XCA>;81g#xGW#39mTJm}}=r`I47J#+{US*BRdQF@4F%jXmz zSjLqKC2}Dm#^@C}Nl1pA0_ZaRs|1nctE^b|rA@kq;guW-9>fv!CCveu%>NG+iN2y` z@(B3veE+AgjGZZg@e!~L$&hk&gX1sPhmw$KQkWx0q-+F9o9iM=fXES<0Fhv5k=~e1 zLNO0f$UdW)Ofo|(lXJvem;q4$9UmtY^2l@=)f@B!gFGQ32!g>Nl}d+bexR=}AqWEL zK3;QN2;pXkV6l9T%ln&4`zBX!1d&7+8G@z4tuT)+MMRj-1(Su}&c*MWdSAG_Z|6e& zCKs6`{wMymzVbrWI8%dV|Nqx zw~s{U|YjKj(!i!_^)$VLDyP4X+of+SrR~XSji9Q?ksfd8ad$b zcILrEUsQf~H<6dy)=ctuH|<=UuldDt=Ipq6+8;BT9k2007sqxq%s2j2+#Uu#y|jIi zb#(O6LFuZ;y}jutn`}xCl&m~ik$3UpYOLzK(JR;McU5N$H#do=v{|89Z=4L#m$GRs zWe*=Z<)zN64g0v;o^+}|z{9C%U)!7bwwz-rgd$X1zdITN>dF##3N`)>aS5Y062`Xy zR;-z`hZ8Zsm^(JCo25EjQ!mqw_qH^X(CsfaKcGgjy-0~c?V2S&r`c501GdJ_q*YFt z?;=^}1oJ}qXzr~zXZ!Rd$8_x`jCn2afeP8m5yyV_;9s%o!D?T%{ou@@;M{;i7f-td}QH*^KRayokLz*PQZnyKrqZk~E5&dxK| znUW1?6z9DT$HKCo`h3+UZt&ef+crB+-G=!OGipuDrB!#aHWNU3C`fa7RB8~FyFUmm zMq9?`-HR5iwmOdW?N_%(XceYM>f4Vum2$a~Nwb)#wh8wq)7q^Las5UnSa)*B9p0d(Ppx%X<`zD%ef###JO6Yixh>6bg&s>c9;u`USGz=I znh6={jj<+XgKaUz_`KYghYykWoJM{4@FD19LB+)Gd*i@b{Jur=S@Z1z1NSaoZs1m8 zw2VB69-5ZWQO^85M-8#}Dz)buX>98ZOi>(FTVv$Z@vi7rZX( zw%->dv^U2REpq4W3@lbLyE`aG#m+hOW}}VQuZ(r~2t=YccI2w+-m#atQ-d0M*4b&4 zc*_N~Z{%&j3dfwb_0@P(oQOC93>xH1ysek*+F!wX1ZBQ+$olyQN`1Zccl~OCjcda2 zv!UdvnyM;O6IZw5{fBaXtiH0MslFjDO4)vXGTvf2O;wkkklRP_f{aZjT{mlof3M9N z-QkRT*AmjW$2zH7@pPj7{zU3nHPiO|n!P-rl`Q40deiOFAgI4-7T(iZSs2oYLQcn< zJ@GnIAHDTnKD4WO_-fPWQnN)JS)VQ$6ln7#$4`_`2dFOxBbky}z2`Z=Z&4yt8gh6koe?MP!{6G-0wZr!I5a z)P2jvVl#N)R#VEg$XA9_J)aWFj~#t!8HMc|9T{N-G&#if^t^V>8yh1WS&b_--gqRX zEzi_`wrap^rflXt1NY%Y;X=UsV>aI1y`)Ss+&kQt_!c_&aRKsNTDKDFW7?3msD^i9 l0nH1D``#yO=+!=y0g99!TC3gHeog=L!3Yk6P6d6R{U2fmqU!(v diff --git a/res/images/deckeditor/filter_blue_n.png b/res/images/deckeditor/filter_blue_n.png deleted file mode 100644 index c2183dc0c50635451ca8faf1fa6ad8319b2fd946..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2305 zcmaJ@dpwi-AD_vJ-}niq(CukDh-}YBE^Bk!Ok3tMMAWZld(5)!+2xtJba8nV%IP?T zBf1IwP%2Jd6h)C$=cJoOh3YsJikw19?e*I_>HPlq^?P2g=lNb<@Avz2d;js|h6V?k zn%J74P$*O8S~^F!TI=6=7~S`YiaM=ZY>68j zAqom*2nZvhk!W@hnFovUTs;P#ESBonC=|sfS<2-lLI@BC34{_V?sao34iNIGxTw`^ zkS(P_3Bt9hawt4CID(g&$n)ake7pflGFc}eh7c~0EEY)=O7T2pAU4b}=*oMqot(ECp!ctAQw? zgb%9}pV4eKnJG~qTnP_i(y2HdA1@U0$*vwGB7+9{xzb4_A~AsI7vRUBk^G3Dn+NFc z??s>G(qW!b3`vk#F8^V4tzznzQM zH@O5|G6elt|7*;%S32+Lw_i=GJAAc0B++?Yt~0gcIYBTAWu#)#{UVYd=B?iVM@Cu= z3?3Y#HeS3~Y1e^X;yd4JYeDAx+}(3%Zj|>pc!kzruoN~UP)5pk`YqcARwd*+a%#dv zjtxo2EpHE`c)oaby`faWwuG8SdzxPl_b1lAj!hhGAf`^7v;^l286v2@i4<%V+8wnn z{r7h4lWa<3=RWilx|f$3nr_r~CjHF;PiupqbLC4GZ@aPmePLsBbDA36MJt*otf(4U z(+C%wuy1wL)C3$HTZif~aQ#s(wI1KU2|L>VqE)HQqW((?rl}(LaH=!*cR2CPRn}%S z#y<{ce%Gj7weyq4VQ(ReS>bMP(E90U7Pn2G-#OCoZui(nsN>CDi_?XB>AruA zD|u}hMB7-0gF$AdSmfTo5&Mhs_jgCH?y64R`f_WjF?-n`D8Z{2gAN1Nj#4JIm#$aG z)q_5?n!*z1oF5BJaNM7gWme(y)ttbaPSr)uj=}Xq<3HtQ$c2|SR*RymG51>N;<*l} z<_~kHngowOCQNkRWY^VG0)H=Ffl;~TU1yMF2k2gH?LQaq<}3aH|@h*#cDQl_oi!#icVt0fGSly}ZE#MV7yrsvTCN;8zX=wC^)Bi;R<>cDrUQECv@9uWFfD1zz0McES*yCP;x4Iep4ADePRz3~G0VFgdOV-gwQ(@b#**(pcz(n7 z=bF=-=4O9dOhUhTEdSK@^hoKkXO)SC-Ip=U*qEM|0bwg|4cvmLOV1XC9B|p}{<4F$ zs|m)^ozDtzqa%hqZt|c0J48tD%8lB(u)9rTX_uxHUbi-FZdFE|>=5;^A6{R72JfrY zb|RBc%5wWzALuLC*#62&`_LS#J=rCLgMQjq!&{^uH#Djsw#NHYOVc&s$^(DeJ{XV? z9?f6>o94CmrSb+BqjT7%T`FwxTa$_I;?&IdI`?KTF_jE&}(HE143+3(bfB3WhOi;|FmZQa)> z`N0jNW)8O(x7(drcp;5(1vv0--m9vfUvJL5i?31q^0**BY;^njqRps#A*6}7>Ac|| zGAZ#xr4#W)qu$iJu>muYy)v=!qf?^nhxV*9E_>5&X4^~$rW>F#d@C=vgx%@U|CBHT Lg6XIIw`BeYpJ~0W diff --git a/res/images/deckeditor/filter_blue_y.png b/res/images/deckeditor/filter_blue_y.png deleted file mode 100644 index ff5b7e7d35bcd9f72e834849dbb9febc4326fe7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2234 zcmaJ@X;f2p9!+IOC}0eR03}APqLAbz5Sl>PvOox6Byk8ROGq9`fGj2t6Bavy6^lwO z7$Yj60~Q?>S#>~B5D-SBRV)bhpio>8OQAXnSVfvxapuF&cg}nN<=lIJ+x_tJIguf@ z)+lQj3}(v;rAHZ7r17;hH+)Al)LFyg1Tpv!SCI^91S${~BvK@SXqHSM2BScMC}Z0V z&<_SPK}&gjh#wJ75h`R@ff0k%%9I8+4CWW0RSJZuAcRf=#ZoyHGj+KIgO-Y@m}u_^ ze1wt)N~EEgDv+BQ$rEO#3dtf&fIr$#OECz@KuCbr%F^U&ik6CbuS+rPjn_B~`aJ|n zrDFa}iXXv2(-bNY?Ty8I3h^X7ngn10qL+`4j|ZB72k?2wY zMS=g#_x}p3c^OI&7X_*n=_;XNaLKETp_CMw3KT#J6;Gi^Tj(N3qJR`?i9(5{alO&e zQn^T>QNKq=L{M0AH6)M=K^C2gG4Qccsfa=cNWsBAUQ8mL000032*%S1Ogw{0CVAn5 zNaQaTxO9auT?Wdb1+M5L*Biem*JuQp(h!*rs-)XN5mTj*q2CuwkuIJKeNnv+T+yPr zcrg~`;ta{)jAQ+uF)v&hykp#cG_B$A(e|L+;B}S3)I6bGA`E7RXVHUr+Mjfrx1=rK zjC}XxQvH4TIJo5>I(=Bs2{RP@&n`;*`K`ueJqJEwXk?cuef4Q|vD@_+t5KRuTWlNA|UBus;B|7+a;?uVrClxA-c@^dYzJ-`|(LGJkJX z`^>oN=?j@zrM%+CnZ&oFUXd;VmR+?%=Z)|;=b6fYZG5b`zPjsf)#bts5aw7t$HS>c zX8Vbm)sn+*2ti7H=o+>pVT2H7*X19OJM>sxTeW92w4t-}Re>nxrn&suMVZ~hHr|SN zC1C=};WqAp>7S=0Hb{5Ih95<4&2XKj-rL6&r!{9tPzh!0+QiHECIcwfvg#1>^C7~jrL~#; z_ROxUw2`F;r!VDeR$tp|p7Z6vU5CDoq>`56KshP@%|*@V1t09gr>8P{9-Xldrh^sF zD7w7HsEhd1D_`!b@i3`!Wdr2r+^zX;r{9i!hUx7|8SjP!mEQ*5h%9fZcFIa9X&tWz z8_)0AS&3jIA4%QxI5v*IA+N?kM8?Qez&sG!baz5$Hv4@}BkXwjM^XCYgkPolFnke>~sn2X=1tqm;L8 z+q`_N_?7G;k5{*dm~I5Cm10-=Zy^mH`rH2VzJ+69oWzy7j2{Bmmj+*o5x8YL!?P<$ zu|J(9gIl{17`vm$-IH@Utxl(AGnU=nnN+VH8`--I&T7oi#_L~q6Te6G^eurr!yooE z0i?3E1>B9zYkkQfHV(V)O;qzQ%c-_cl`Q1%Yd(9Tv$@BAkz%=~JDrsq!)%?gW)GxX zA1$+SOg}R_aWEQL)lhKY(cl4b@2!qqSASbZBpznf=?^8{VRzG(xqrg#qC37mJRe=m zd14l8eS_zlsTV09a)=LhWCfI@cufr24l+c-B~8Ab)ghOQXrwHw_V)IgB6sliq)GYAPPfyph zBfb$IBD#O=Ur3V;T-g9LS6aNWbGcsFeye5=J?&vk(o}YIWwS@TK8~+&ahw^J8zYQ(6i2jY(wb$%E-v9OBfi@Q$3+rk56vJ=PATHojz3EE|aX<-7SAaq(c# u(B~E_9PEx1rD0;mR8Qam?~diPm?B}Wt^S(9nUhP5e-kW5B>jAFV(uU6K#Pt5 diff --git a/res/images/deckeditor/filter_colorless_n.png b/res/images/deckeditor/filter_colorless_n.png deleted file mode 100644 index cf231becc4c3467902ff0192e9da69b9e7ba54f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2313 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 VN1t9?pQ-*iadYydmpcX}`~~7<))fE% diff --git a/res/images/deckeditor/filter_colorless_y.png b/res/images/deckeditor/filter_colorless_y.png deleted file mode 100644 index bce292d3086b9f2286b983bb71790e89859fe19d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2251 zcmaJ@dpuNmA0A7MT(?M=gTglTfV#Z@FuhPTr^XOK})y-1seu)-YyX^SqUHn#DH-e9tAnqaRmu**c4RV8miET8u~Yg>e|1larHD!@`vf2+02J|)ge=A2Vo}Oa0w z;%B)SMKT!WSpRFxt5*u|D7T+Xt2lhJJ;+mdU8pd%w*OKe47SFVPIV2EjOGW2B?bi> zF5li0+crF7$F**)*%6++p>Bt&KQ?b6YcUfS6LHMVe0|osim!|d;0*69Ddx|vbpMzv zGxU&#t}K{vxW?7rHWz)N?7*|zk6td6J-?hsr8*Cgrf!$vS6(fx{9$?saaOx`ON=FM zmwxph;6&&IVQy)w0`YPl+k^?v=tfj8&4&wtv#JgynTmb6U295DO-xtn8x zS;_faABzf{-O%fCy_tNAzKh)c7w_xs3Qh%ebx3V{a~_Zlk7pE&3Kt#U^*-^H9_o(N z&omIW5$-pb($dm&2M@37nB4Io3yT^`lGk7K3_qy-oRryChi{5NU-NN68L;4UXSy_N zCcBo?r^8R_J*<~@cY}sojAVIVHF^(?&$_MQ?TF0Qhk5|WxUlyAZ0;ix?@?BBoaK?J z)ODi>z{dujfP(imFX}|c$NNEI%iNh=tbJ+QV;cvV-^8we^KZuT0W}rGPSUgoH5&2I zB&aUfP-Y#{7-=z7wn(RzEjam3s361a-d3DFYdTXye_~xTY!va6K+3l5T*BVzn%cA; z5WpA@qRojlc=}Tfqx_p*S{3PsCRMKz7&GmSO-mJhIeRjyO~&SOWxQQ`NX!hiVj{c~ z_1I~PHvCH)0RyF`X(@%tv?}V&JqtO;(-+2aBgXp0z1huynfe(8?sbPv)vk&yYHZcd zT%XcCq-(G4=BQ=tphasOR!Pe*znNI1(_$v+ij!qr$dk)Qy1(AI!Pv^4l6rp8T`2e2)9;b#lSmeXA$;#0of5r^s6Wd?B~Ri5N~}W=40gR* zeZB$h$j|4r#7({^!i#zB?3D8K<8D8sCy%XbzWZI}v!#Y8)CoxrW1xhtd0M#fmyi=N zNRy|*CIuNf&nlB!fwtw$?K$!eUgl_R&$9*3CRgvkp7(AHT3}V9N8tJ^OW*jf)oSpD zzdmg<`?U3z)!5S(_tDbhdabopjH&Cnk+A+`d2Q>6E0HYBZJIu~rntB`L$4@Ar!&}B z@8oatgO~{8^0M$~eXrWRzY<0_>XNit*4%N<2sn?7iUn&sSUHPu>IcSTZ(RLP2WWGaI|e2ukufOL+1KslO zK`%Jhpe6Fh>fpd6eBRv6%9T?t8;|Xu8S$@l$ch~+A30>a={LQHayjwU^5T{aK4WpS z_xzkI*FqNdZ&NC6+)9*;G~Ky`X_t4@dlJQu7fSjkC%p>u8N`nMdyGxG9TqV@`|JvK z#VpU3Zbl%Uc;5i7&D&kD(z)@_)9`WW?8{pstGCg^GG<~M*F?v}1-VjGeq7bXbAQrh z%_;Ty6st?rFH%j%Y~k>bpF3sx=3m@5+q_XGoo_%)PG8rUpC1T(b^Uzkk@lIYH^%d? zvKt32r56h{dNkATz8Fm^jJTL=uW_x)%Ano)jI6Y1K_zPcyO!~3>B=DdGU P`Flb4@S!%kMSuGj{^zU+ diff --git a/res/images/deckeditor/filter_creature_n.png b/res/images/deckeditor/filter_creature_n.png deleted file mode 100644 index d577f01ef08b874c431462285e8ecd24d71af38f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3346 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 diff --git a/res/images/deckeditor/filter_enchant_n.png b/res/images/deckeditor/filter_enchant_n.png deleted file mode 100644 index b23e3122a68458c498f65b15c8949fccb21cf882..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3462 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 diff --git a/res/images/deckeditor/filter_enchant_y.png b/res/images/deckeditor/filter_enchant_y.png deleted file mode 100644 index 054bfbdbb4707bf66198d96af9d7470d32fd6aca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3462 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 Id4wka2OitPoB#j- diff --git a/res/images/deckeditor/filter_green_y.png b/res/images/deckeditor/filter_green_y.png deleted file mode 100644 index eb4a511254455ef8af333c82e0b9cad55a4d3191..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2243 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 DH|3xW diff --git a/res/images/deckeditor/filter_instant_n.png b/res/images/deckeditor/filter_instant_n.png deleted file mode 100644 index 7c25dd437a5d1138a84c0471984c13ee5ced8f5d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3383 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 N002ovPDHLkV1m_fNk{+y diff --git a/res/images/deckeditor/filter_instant_y.png b/res/images/deckeditor/filter_instant_y.png deleted file mode 100644 index 83cd0d9a9d329028c04befd109a4d31717464897..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3347 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 diff --git a/res/images/deckeditor/filter_land_n.png b/res/images/deckeditor/filter_land_n.png deleted file mode 100644 index f54f4f2864d2249fe404b2a01b2c8d17210d83ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3353 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 diff --git a/res/images/deckeditor/filter_land_y.png b/res/images/deckeditor/filter_land_y.png deleted file mode 100644 index 8cc194c53273f487f041d32dd00ef6194a52c9e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3315 zcmVKLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=00004XF*Lt006O$eEU(80000WV@Og>004R=004l4008;_004mL004C` z008P>0026e000+nl3&F}0006GNkl}2aj8_&&#CT_th{#r1 z3`vuuW-=0LQdY)_tn4IgHAx|2HVk2kg@u%&6rzx#X*_0(*ZA9W%;LNnH59wvvpA1`qa-FTu#nvX7gL%zcLj`MMus%R(rG9YhpE1Y)4{!K=w zAG<1nAIuot#a1*F(XGc8+|Jl^mIB|ADE&YOawYUyGqQacO6>o6$y|I&z&Dq;L`wp4 zAak}UaWa5~>EXG=u%iU{Onl6Qqa~xWCpo)Z5H?077rZzAxh76gE`ZpeN$BDOP=58H3~4UBh^pf-|unP7hwhb9#awjnh?zrPykV z*_4l5=qbbtD{$jK!1MT;%(7lM9L#X0-A7^_%f*;|92HXyeU7m*h(A%54N)wk61`!p zEHD?!+~OHdVjC7?S|oIOjE`Bd7Gy@wHOaJW#6wI7elVJ+D}Jk~SdFz!0N3Os=Q)pq3)T&yxQzi|c2 xivi^-IBJUDZ5`$$WBE&T>3v+qqf!8W2LPOF9kg$(;eG%B002ovPDHLkV1kM`E5rZ* diff --git a/res/images/deckeditor/filter_planeswalker_n.png b/res/images/deckeditor/filter_planeswalker_n.png deleted file mode 100644 index f7b4c8bd85b6568e425d3f06a094cfd59930490b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3460 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 a#|DUW@6`&^^bDHr|0Fmdj9y8N%l;FUHOzzn diff --git a/res/images/deckeditor/filter_red_y.png b/res/images/deckeditor/filter_red_y.png deleted file mode 100644 index 6c3f7b1c34f253f6b0e2fc6de98088c559ec5912..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2254 zcmaJ@d0Z1`8qUg5ghfgOM2a#5!EAw?AS47NB;f`j1Yre)91{{WnK&6tM2iJM608TF zAYxrWF5rkGbyda1o-c%Gk0GEn@%BeQ7V)u`A=QlIo@q3=%0%ZR0V(M+mac z8}nyUv0)Ja1A;-o9Y=8G6IKv_6+|47?B?O&;R28dL;{{b!V^iZL=P&NL?sY_PY*^L z4HgKgY^MLGSlX30MuZ?TDju&;C~yig4uX^ML<)tX(;$&twFp=FCMm*Ix=Q5^a|%pQ z&WFV^L<~s*og$Y9r6S%KZKi*gAd!8RmC8RIllH*yO0En~#1V8Q%>l#0{y$VA`HYq$ zZ1Asq|EI8=vq=Wx*`ORsh56dX2_1ByWK;$WauEpTK+yWRQ;ZNn2qYIlGJp}~4#bG1 z0!ShMhz<**21(@zSIP&2nBEvIA14+Is1yc+?#Cj#k(neSk;o$YQ7BBhKbhdqVA9gvu;PcJWWvas_=$aTe$D0(hh zw=beG4}0m7GW~2@EVXXY z5~03SL%$^Dz23cVGJV#q@|tk6*X`8K$yaOif3LvTv1ogd>PffV`PMv5_KiEw3Fz8iyB=9N!*L(bv~zt+U3}zd zO=nTdFKy(jvvOEFipTI?1duCq4U#2{uKa>d;k@6VP!c{@&~b zUXoGHmGGuf+P1f8>W6!i{#oeT(;#)2E_An9nftQeG2cw`eT{sP%_G~aXl%()nk+v$ z@yX0B`@o+^n#Q(-ZjSdasjqNW|LAl*=Rkc--(9DcVPS2@%cDCvT;qy%xBV=W$lmup z?Ip>Pk|`0f5NC%}Ff^z7=9}5bt)dKW9yP7uHoGSHuS&EkGb+8U`pU7{W@@DKk|t?? znYr_I-~rNSTj;BaSzK*)eNo1h$})O4N3w7Ck?L*2%-`d3YT2yb- z*PQ*%@r>+QTh7q@n%&AMxs<}KidBdGy-!`{MvZ-6XVyGfa?`S1MmWbpx*BneKE*-quZC`jaAoXvq zUFtlwdQVb3diYS4-auzl-}(wxu{F8a^MrMMhp0?^rUiYHaM^t4tVkUm)lMVF~HK**_-+eQh^*dGguRT|C z`)m=);UEr%u3mab^h*=$LKtvFpNZuK*^H*}d9qPmY(g<7m44dvMo^ENB>PPgjao9PU=H+FxiXZ1G^l-bIm zH34Nbm)?U3)`+M4!ivI6kB83<2B+E=1r;}Ax6;z*CH`QWF*C85T{)muKu>Sj?XR(o zDQkYS;JXtE>Q;}m!4Ko@<`WC+G|jAKJu~FfYC(~vVAbqcqTzdsB-HUC?5;i5UP9ds NBZw8wtoBRF`~zWCw_^YR diff --git a/res/images/deckeditor/filter_sorcery_n.png b/res/images/deckeditor/filter_sorcery_n.png deleted file mode 100644 index cbfb904f55a0216e5ff66971d0cf3126c9e320c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3508 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 Cpl|2^ diff --git a/res/images/deckeditor/filter_white_y.png b/res/images/deckeditor/filter_white_y.png deleted file mode 100644 index d6ed26b89b594ba017d21d2b09858139c37d2acb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2130 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 HP6F%9RmZ>*%uWN!p{D!` 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%0Dq0y=ytO7vBQgPsNTo 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 YNwf8{`&?_%J_lb)3TpBNvc_-z4-%G-RR910 delta 209238 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%0D!w)ySAIbjYeRTd#v1iisKo1V>bHRFVunoKnJB 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 - * CardOracle class. - *

+ * A collection of methods containing full + * meta and gameplay properties of a card. * * @author Forge - * @version $Id: CardOracle.java 9708 2011-08-09 19:34:12Z jendave $ + * @version $Id: CardRules.java 9708 2011-08-09 19:34:12Z jendave $ */ public final class CardRules { @@ -389,8 +388,31 @@ public final class CardRules { return new LeafNumber(LeafNumber.CardField.CMC, op, what); } - // Power - // Toughness + /** + * + * @param op + * the op + * @param what + * the what + * @return the predicate + */ + public static Predicate power(final ComparableOp op, final int what) { + return new LeafNumber(LeafNumber.CardField.POWER, op, what); + } + + /** + * + * @param op + * the op + * @param what + * the what + * @return the predicate + */ + public static Predicate toughness(final ComparableOp op, final int what) { + return new LeafNumber(LeafNumber.CardField.TOUGHNESS, op, what); + } + + // P/T /** * Rules. * @@ -462,7 +484,7 @@ public final class CardRules { * @return the predicate */ public static Predicate wasPrintedInSets(final List setCodes) { - return new PredicateExitsInSets(setCodes); + return new PredicateExistsInSets(setCodes); } /** @@ -568,7 +590,7 @@ public final class CardRules { * @return the predicate */ public static Predicate hasCntColors(final byte cntColors) { - return new LeafColor(LeafColor.ColorOperator.Equals, cntColors); + return new LeafColor(LeafColor.ColorOperator.CountColors, cntColors); } /** @@ -634,18 +656,18 @@ public final class CardRules { @Override public boolean isTrue(final CardRules subject) { switch (this.op) { - case CountColors: - return subject.getColor().countColors() == this.color; - case CountColorsGreaterOrEqual: - return subject.getColor().countColors() >= this.color; - case Equals: - return subject.getColor().isEqual(this.color); - case HasAllOf: - return subject.getColor().hasAllColors(this.color); - case HasAnyOf: - return subject.getColor().hasAnyColor(this.color); - default: - return false; + case CountColors: + return subject.getColor().countColors() == this.color; + case CountColorsGreaterOrEqual: + return subject.getColor().countColors() >= this.color; + case Equals: + return subject.getColor().isEqual(this.color); + case HasAllOf: + return subject.getColor().hasAllColors(this.color); + case HasAnyOf: + return subject.getColor().hasAnyColor(this.color); + default: + return false; } } } @@ -747,10 +769,10 @@ public final class CardRules { } } - private static class PredicateExitsInSets extends Predicate { + private static class PredicateExistsInSets extends Predicate { private final List sets; - public PredicateExitsInSets(final List wantSets) { + public PredicateExistsInSets(final List wantSets) { this.sets = wantSets; // maybe should make a copy here? } @@ -808,6 +830,9 @@ public final class CardRules { public static final Predicate IS_NON_CREATURE_SPELL = Predicate.compose(Presets.IS_CREATURE, PredicatesOp.NOR, Presets.IS_LAND); + /** + * + */ @SuppressWarnings("unchecked") public static final Predicate IS_NONCREATURE_SPELL_FOR_GENERATOR = Predicate.or(Arrays.asList( Presets.IS_SORCERY, Presets.IS_INSTANT, Presets.IS_PLANESWALKER, Presets.IS_ENCHANTMENT, diff --git a/src/main/java/forge/control/FControl.java b/src/main/java/forge/control/FControl.java index 7a7bad40025..33f37631c53 100644 --- a/src/main/java/forge/control/FControl.java +++ b/src/main/java/forge/control/FControl.java @@ -31,8 +31,12 @@ import javax.swing.WindowConstants; import forge.AllZone; import forge.Singletons; import forge.control.KeyboardShortcuts.Shortcut; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.VDeckEditorUI; +import forge.gui.framework.SOverflowUtil; +import forge.gui.framework.SResizingUtil; import forge.gui.home.VHomeUI; -import forge.gui.home.quest.SubmenuQuestUtil; +import forge.gui.home.quest.SSubmenuQuestUtil; import forge.gui.match.VMatchUI; import forge.gui.match.controllers.CDock; import forge.gui.toolbox.CardFaceSymbols; @@ -55,16 +59,24 @@ public enum FControl { private JLayeredPane display; private int state = -1; - private WindowListener waDefault, waConcede, waLeaveBazaar; + private WindowListener waDefault, waConcede, waLeaveBazaar, waLeaveEditor; /** */ public static final int HOME_SCREEN = 0; /** */ public static final int MATCH_SCREEN = 1; /** */ - public static final int DEFAULT_EDITOR = 2; + public static final int DECK_EDITOR_CONSTRUCTED = 2; /** */ public static final int QUEST_BAZAAR = 3; + /** */ + public static final int DECK_EDITOR_LIMITED = 4; + /** */ + public static final int DECK_EDITOR_QUEST = 5; + /** */ + public static final int QUEST_CARD_SHOP = 6; + /** */ + public static final int DRAFTING_PROCESS = 7; /** *

@@ -75,11 +87,21 @@ public enum FControl { * instantiated separately by each state's top level view class. */ private FControl() { + this.waDefault = new WindowAdapter() { + @Override + public void windowClosing(final WindowEvent e) { + Singletons.getView().getFrame().setDefaultCloseOperation( + WindowConstants.EXIT_ON_CLOSE); + } + }; + // "Close" button override during match this.waConcede = new WindowAdapter() { @Override public void windowClosing(final WindowEvent e) { - Singletons.getView().getFrame().setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); + Singletons.getView().getFrame().setDefaultCloseOperation( + WindowConstants.DO_NOTHING_ON_CLOSE); + CDock.SINGLETON_INSTANCE.concede(); } }; @@ -88,19 +110,28 @@ public enum FControl { this.waLeaveBazaar = new WindowAdapter() { @Override public void windowClosing(final WindowEvent e) { - Singletons.getView().getFrame().setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); - changeState(0); - SubmenuQuestUtil.updateStatsAndPet(); + Singletons.getView().getFrame().setDefaultCloseOperation( + WindowConstants.DO_NOTHING_ON_CLOSE); + + changeState(FControl.HOME_SCREEN); + SSubmenuQuestUtil.updateStatsAndPet(); } }; - // Default action on window close - this.waDefault = new WindowAdapter() { - @Override - public void windowClosing(final WindowEvent e) { - Singletons.getView().getFrame().setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - } + this.waLeaveEditor = new WindowAdapter() { + @Override + public void windowClosing(final WindowEvent ev) { + Singletons.getView().getFrame().setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); + + if (CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().exit()) { + changeState(FControl.HOME_SCREEN); + } + } }; + + FView.SINGLETON_INSTANCE.getLpnDocument().addMouseListener(SOverflowUtil.getHideOverflowListener()); + FView.SINGLETON_INSTANCE.getLpnDocument().addComponentListener(SResizingUtil.getWindowResizeListener()); + Singletons.getView().getFrame().setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); } /** After view and model have been initialized, control can start. */ @@ -117,8 +148,6 @@ public enum FControl { this.shortcuts = KeyboardShortcuts.attachKeyboardShortcuts(); this.display = FView.SINGLETON_INSTANCE.getLpnDocument(); - //Singletons.getView().initialize(); - // Handles resizing in null layouts of layers in JLayeredPane. Singletons.getView().getFrame().addComponentListener(new ComponentAdapter() { @Override @@ -141,17 +170,19 @@ public enum FControl { clearChildren(JLayeredPane.DEFAULT_LAYER); this.state = i0; - /// TODO should these be here? + Singletons.getView().getFrame().removeWindowListener(waDefault); Singletons.getView().getFrame().removeWindowListener(waConcede); Singletons.getView().getFrame().removeWindowListener(waLeaveBazaar); - Singletons.getView().getFrame().addWindowListener(waDefault); + Singletons.getView().getFrame().removeWindowListener(waLeaveEditor); // Fire up new state switch (i0) { case HOME_SCREEN: + Singletons.getView().getFrame().addWindowListener(waDefault); VHomeUI.SINGLETON_INSTANCE.populate(); FView.SINGLETON_INSTANCE.getPnlInsets().setVisible(false); - //sizeChildren(); + VHomeUI.SINGLETON_INSTANCE.updateLayout(); + sizeChildren(); break; case MATCH_SCREEN: @@ -160,8 +191,14 @@ public enum FControl { Singletons.getView().getFrame().addWindowListener(waConcede); break; - case DEFAULT_EDITOR: - display.add(Singletons.getView().getViewEditor(), JLayeredPane.DEFAULT_LAYER); + case DECK_EDITOR_CONSTRUCTED: + case DECK_EDITOR_LIMITED: + case DECK_EDITOR_QUEST: + case QUEST_CARD_SHOP: + case DRAFTING_PROCESS: + VDeckEditorUI.SINGLETON_INSTANCE.populate(); + FView.SINGLETON_INSTANCE.getPnlInsets().setVisible(true); + Singletons.getView().getFrame().addWindowListener(waLeaveEditor); break; case QUEST_BAZAAR: diff --git a/src/main/java/forge/deck/Deck.java b/src/main/java/forge/deck/Deck.java index ee4cf8a67aa..5413a3823e9 100644 --- a/src/main/java/forge/deck/Deck.java +++ b/src/main/java/forge/deck/Deck.java @@ -33,7 +33,7 @@ import org.apache.commons.lang3.StringUtils; import forge.deck.io.DeckFileHeader; import forge.deck.io.DeckSerializer; -import forge.gui.deckeditor.elements.TableSorter; +import forge.gui.deckeditor.tables.TableSorter; import forge.item.CardPrinted; import forge.item.ItemPoolView; import forge.util.FileSection; diff --git a/src/main/java/forge/game/limited/BoosterDraft.java b/src/main/java/forge/game/limited/BoosterDraft.java index 6daa597e514..ab08aae76c0 100644 --- a/src/main/java/forge/game/limited/BoosterDraft.java +++ b/src/main/java/forge/game/limited/BoosterDraft.java @@ -290,7 +290,12 @@ public final class BoosterDraft implements IBoosterDraft { } } // computerChoose() - private int getCurrentBoosterIndex() { + /** + * + * TODO: Write javadoc for this method. + * @return int + */ + public int getCurrentBoosterIndex() { return this.currentBoosterPick % BoosterDraft.N_PLAYERS; } diff --git a/src/main/java/forge/game/player/Player.java b/src/main/java/forge/game/player/Player.java index 99f4e7961bd..439b9dfcb66 100644 --- a/src/main/java/forge/game/player/Player.java +++ b/src/main/java/forge/game/player/Player.java @@ -49,7 +49,7 @@ import forge.game.zone.PlayerZone; import forge.game.zone.PlayerZoneComesIntoPlay; import forge.game.zone.ZoneType; import forge.gui.GuiUtils; -import forge.gui.match.VMatchUI; +import forge.gui.match.views.VDev; import forge.util.MyRandom; /** @@ -1838,7 +1838,7 @@ public abstract class Player extends GameEntity { * @return a boolean. */ public final boolean canPlayLand() { - if (VMatchUI.SINGLETON_INSTANCE.getViewDevMode().getLblUnlimitedLands().getEnabled() && this.isHuman() + if (VDev.SINGLETON_INSTANCE.getLblUnlimitedLands().getEnabled() && this.isHuman() && Constant.Runtime.DEV_MODE[0]) { return PhaseHandler.canCastSorcery(this); } diff --git a/src/main/java/forge/gui/deckeditor/CDeckEditorUI.java b/src/main/java/forge/gui/deckeditor/CDeckEditorUI.java new file mode 100644 index 00000000000..5fe830b5f6a --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/CDeckEditorUI.java @@ -0,0 +1,113 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package forge.gui.deckeditor; + +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import forge.Card; +import forge.gui.CardContainer; +import forge.gui.deckeditor.controllers.ACEditorBase; +import forge.gui.match.controllers.CDetail; +import forge.gui.match.controllers.CPicture; + +/** + * Constructs instance of deck editor UI controller, used as a single point of + * top-level control for child UIs. Tasks targeting the view of individual + * components are found in a separate controller for that component and + * should not be included here. + * + *

(C at beginning of class name denotes a control class.) + */ +public enum CDeckEditorUI implements CardContainer { + /** */ + SINGLETON_INSTANCE; + + private ACEditorBase childController; + + private CDeckEditorUI() { + } + + //========== Overridden from CardContainer + + @Override + public void setCard(final Card c) { + CDetail.SINGLETON_INSTANCE.showCard(c); + CPicture.SINGLETON_INSTANCE.showCard(c); + } + + @Override + public Card getCard() { + return CDetail.SINGLETON_INSTANCE.getCurrentCard(); + } + + //========= Accessor/mutator methods + /** + * @return ACEditorBase + */ + public ACEditorBase getCurrentEditorController() { + return childController; + } + + /** + * Set controller for current configuration of editor. + * @param editor0   {@link forge.gui.deckeditor.controllers.ACEditorBase} + */ + public void setCurrentEditorController(ACEditorBase editor0) { + this.childController = editor0; + updateController(); + } + + //========== Other methods + /** + * Updates listeners for current controller. + */ + private void updateController() { + childController.getTableCatalog().getTable().addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(final KeyEvent e) { + if (e.getKeyChar() == ' ') { childController.addCard(); } + } + }); + + childController.getTableDeck().getTable().addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(final KeyEvent e) { + if (e.getKeyChar() == ' ') { childController.removeCard(); } + } + }); + + childController.getTableCatalog().getTable().addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(final MouseEvent e) { + if (e.getClickCount() == 2) { childController.addCard(); } + } + }); + + childController.getTableDeck().getTable().addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(final MouseEvent e) { + if (e.getClickCount() == 2) { childController.removeCard(); } + } + }); + + childController.init(); + } +} diff --git a/src/main/java/forge/gui/deckeditor/DeckEditorBase.java b/src/main/java/forge/gui/deckeditor/DeckEditorBase.java deleted file mode 100644 index e2e586975e3..00000000000 --- a/src/main/java/forge/gui/deckeditor/DeckEditorBase.java +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.gui.deckeditor; - -import java.awt.event.ActionEvent; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import javax.swing.JDialog; -import javax.swing.JFrame; -import javax.swing.JOptionPane; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; - -import forge.Command; -import forge.deck.DeckBase; -import forge.gui.deckeditor.elements.CardPanelBase; -import forge.gui.deckeditor.elements.DeckAnalysis; -import forge.gui.deckeditor.elements.FilterCheckBoxes; -import forge.gui.deckeditor.elements.TableView; -import forge.item.CardPrinted; -import forge.item.InventoryItem; -import forge.item.ItemPool; -import forge.item.ItemPoolView; -import forge.util.closures.Predicate; - -/** - * The Class DeckEditorBase. - * - * @param the generic type - * @param the generic type - */ -public abstract class DeckEditorBase extends JDialog { - private static final long serialVersionUID = -401223933343539977L; - - /** The filter boxes. */ - private FilterCheckBoxes filterBoxes; - // set this to false when resetting filter from code (like - // "clearFiltersPressed"), reset when done. - /** The is filters change firing update. */ - private boolean isFiltersChangeFiringUpdate = true; - - /** The card view. */ - private CardPanelBase cardView; - - // CardPools and Table data for top and bottom lists - /** The top. */ - private TableView topTableWithCards; - - /** The bottom. */ - private TableView bottomTableWithCards; - /** - * Instantiates a new deck editor base. - * - * @param parent the parent frame for this deck editor - */ - public DeckEditorBase(JFrame parent) { - super(parent, ModalityType.APPLICATION_MODAL); - } - - // top shows available card pool - // if constructed, top shows all cards - // if sealed, top shows N booster packs - // if draft, top shows cards that were chosen - /** - * Gets the top table model. - * - * @return the top table model - */ - public final TableView getTopTableModel() { - return this.getTopTableWithCards(); - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckDisplay#getTop() - */ - /** - * Gets the top. - * - * @return the top - */ - public final ItemPoolView getTop() { - return this.getTopTableWithCards().getCards(); - } - - // bottom shows player's choice - be it deck or draft - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckDisplay#getBottom() - */ - /** - * Gets the bottom. - * - * @return the bottom - */ - public final ItemPoolView getBottom() { - return this.getBottomTableWithCards().getCards(); - } - - /** - * Gets the controller. - * - * @return the controller - */ - public abstract DeckController getController(); - - // THIS IS HERE FOR OVERLOADING!!!1 - // or may be return abstract getFilter from derived class + this filter ... - // virtual protected member, but later - /** - * Builds the filter. - * - * @return the predicate - */ - protected abstract Predicate buildFilter(); - - /** - * Show. - * - * @param exitCommand the exit command - */ - public abstract void show(final Command exitCommand); - - /** - * Analysis button_action performed. - * - * @param e - * the e - */ - final void analysisButtonActionPerformed(final ActionEvent e) { - final ItemPoolView deck = ItemPool.createFrom(this.getBottomTableWithCards().getCards(), - CardPrinted.class); - if (deck.isEmpty()) { - JOptionPane.showMessageDialog(null, "Cards in deck not found.", "Analysis Deck", - JOptionPane.INFORMATION_MESSAGE); - } else { - final DeckEditorBase g = DeckEditorBase.this; - final DeckAnalysis dAnalysis = new DeckAnalysis(g, deck); - dAnalysis.setVisible(true); - g.setEnabled(false); - } - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckDisplay#setItems(forge.item.ItemPoolView, - * forge.item.ItemPoolView, forge.game.GameType) - */ - /** - * Update view. - */ - public abstract void updateView(); - - /** - * Update display. - */ - public final void updateDisplay() { - this.getTopTableWithCards().setFilter(this.buildFilter()); - } - - /** The item listener updates display. */ - private ItemListener itemListenerUpdatesDisplay = new ItemListener() { - @Override - public void itemStateChanged(final ItemEvent e) { - if (DeckEditorBase.this.isFiltersChangeFiringUpdate()) { - DeckEditorBase.this.updateDisplay(); - } - } - }; - - /** - * This class is used for a feature: when you start typing card name, the - * list gets auto-filtered. - */ - protected class OnChangeTextUpdateDisplay implements DocumentListener { - private void onChange() { - if (DeckEditorBase.this.isFiltersChangeFiringUpdate()) { - DeckEditorBase.this.updateDisplay(); - } - } - - /* - * (non-Javadoc) - * - * @see - * javax.swing.event.DocumentListener#insertUpdate(javax.swing.event - * .DocumentEvent) - */ - @Override - public final void insertUpdate(final DocumentEvent e) { - this.onChange(); - } - - /* - * (non-Javadoc) - * - * @see - * javax.swing.event.DocumentListener#removeUpdate(javax.swing.event - * .DocumentEvent) - */ - @Override - public final void removeUpdate(final DocumentEvent e) { - this.onChange(); - } - - /* - * (non-Javadoc) - * - * @see - * javax.swing.event.DocumentListener#changedUpdate(javax.swing.event - * .DocumentEvent) - */ - @Override - public void changedUpdate(final DocumentEvent e) { - } // Happend only on ENTER pressed - } - - /** - * Gets the item listener updates display. - * - * @return the itemListenerUpdatesDisplay - */ - public ItemListener getItemListenerUpdatesDisplay() { - return this.itemListenerUpdatesDisplay; - } - - /** - * Sets the item listener updates display. - * - * @param itemListenerUpdatesDisplay - * the itemListenerUpdatesDisplay to set - */ - public void setItemListenerUpdatesDisplay(final ItemListener itemListenerUpdatesDisplay) { - this.itemListenerUpdatesDisplay = itemListenerUpdatesDisplay; // TODO: - // Add 0 - // to - // parameter's - // name. - } - - /** - * Checks if is filters change firing update. - * - * @return the isFiltersChangeFiringUpdate - */ - public boolean isFiltersChangeFiringUpdate() { - return this.isFiltersChangeFiringUpdate; - } - - /** - * Sets the filters change firing update. - * - * @param isFiltersChangeFiringUpdate - * the isFiltersChangeFiringUpdate to set - */ - public void setFiltersChangeFiringUpdate(final boolean isFiltersChangeFiringUpdate) { - this.isFiltersChangeFiringUpdate = isFiltersChangeFiringUpdate; // TODO: - // Add 0 - // to - // parameter's - // name. - } - - /** - * Gets the card view. - * - * @return the cardView - */ - public CardPanelBase getCardView() { - return this.cardView; - } - - /** - * Sets the card view. - * - * @param cardView0 - * the cardView to set - */ - protected void setCardView(final CardPanelBase cardView0) { - this.cardView = cardView0; - } - - /** - * Gets the filter boxes. - * - * @return the filterBoxes - */ - public FilterCheckBoxes getFilterBoxes() { - return this.filterBoxes; - } - - /** - * Sets the filter boxes. - * - * @param filterBoxes0 - * the filterBoxes to set - */ - public void setFilterBoxes(final FilterCheckBoxes filterBoxes0) { - this.filterBoxes = filterBoxes0; - } - - /** - * Gets the bottom table with cards. - * - * @return the bottomTableWithCards - */ - public TableView getBottomTableWithCards() { - return this.bottomTableWithCards; - } - - /** - * Sets the bottom table with cards. - * - * @param bottomTableWithCards0 - * the bottomTableWithCards to set - */ - public void setBottomTableWithCards(final TableView bottomTableWithCards0) { - this.bottomTableWithCards = bottomTableWithCards0; - } - - /** - * Gets the top table with cards. - * - * @return the topTableWithCards - */ - public TableView getTopTableWithCards() { - return this.topTableWithCards; - } - - /** - * Sets the top table with cards. - * - * @param topTableWithCards0 - * the topTableWithCards to set - */ - public void setTopTableWithCards(final TableView topTableWithCards0) { - this.topTableWithCards = topTableWithCards0; - } - -} diff --git a/src/main/java/forge/gui/deckeditor/DeckEditorConstructed.java b/src/main/java/forge/gui/deckeditor/DeckEditorConstructed.java deleted file mode 100644 index fa4058b03ce..00000000000 --- a/src/main/java/forge/gui/deckeditor/DeckEditorConstructed.java +++ /dev/null @@ -1,414 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.gui.deckeditor; - -import java.awt.Container; -import java.awt.Font; -import java.awt.event.ActionEvent; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.util.ArrayList; -import java.util.List; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JFrame; -import javax.swing.JLabel; - -import forge.Command; -import forge.Singletons; -import forge.deck.Deck; -import forge.error.ErrorViewer; -import forge.gui.deckeditor.elements.CardPanelHeavy; -import forge.gui.deckeditor.elements.FilterCheckBoxes; -import forge.gui.deckeditor.elements.FilterNameTypeSetPanel; -import forge.gui.deckeditor.elements.ManaCostRenderer; -import forge.gui.deckeditor.elements.TableColumnInfo; -import forge.gui.deckeditor.elements.TableView; -import forge.item.CardDb; -import forge.item.CardPrinted; -import forge.item.InventoryItem; -import forge.item.ItemPool; -import forge.util.closures.Lambda0; -import forge.util.closures.Predicate; -import net.miginfocom.swing.MigLayout; - -/** - *

- * Gui_DeckEditor class. - *

- * - * @author Forge - * @version $Id$ - */ -public final class DeckEditorConstructed extends DeckEditorBase { - /** Constant serialVersionUID=130339644136746796L. */ - private static final long serialVersionUID = 130339644136746796L; - - private final JButton removeButton = new JButton(); - private final JButton addButton = new JButton(); - private final JButton importButton = new JButton(); - - private final JButton analysisButton = new JButton(); - private final JButton clearFilterButton = new JButton(); - - private final JLabel jLabelAnalysisGap = new JLabel(""); - private FilterNameTypeSetPanel filterNameTypeSet; - - private final DeckController controller; - - /** - * Show. - * - * @param exitCommand - * the exit command - */ - @Override - public void show(final Command exitCommand) { - final Command exit = new Command() { - private static final long serialVersionUID = 5210924838133689758L; - - @Override - public void execute() { - DeckEditorConstructed.this.dispose(); - if (exitCommand != null) { - exitCommand.execute(); - } - } - }; - - final MenuCommon menu = new MenuCommon(this.getController(), exit); - this.setJMenuBar(menu); - - // do not change this!!!! - this.addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(final WindowEvent ev) { - menu.close(); - } - }); - - this.setup(); - - this.controller.newModel(); - - this.getTopTableWithCards().sort(1, true); - this.getBottomTableWithCards().sort(1, true); - - } // show(Command) - - private void setup() { - final List> columns = new ArrayList>(); - columns.add(new TableColumnInfo("Qty", 30, PresetColumns.FN_QTY_COMPARE, - PresetColumns.FN_QTY_GET)); - columns.add(new TableColumnInfo("Name", 175, PresetColumns.FN_NAME_COMPARE, - PresetColumns.FN_NAME_GET)); - columns.add(new TableColumnInfo("Cost", 75, PresetColumns.FN_COST_COMPARE, - PresetColumns.FN_COST_GET)); - columns.add(new TableColumnInfo("Color", 60, PresetColumns.FN_COLOR_COMPARE, - PresetColumns.FN_COLOR_GET)); - columns.add(new TableColumnInfo("Type", 100, PresetColumns.FN_TYPE_COMPARE, - PresetColumns.FN_TYPE_GET)); - columns.add(new TableColumnInfo("Stats", 60, PresetColumns.FN_STATS_COMPARE, - PresetColumns.FN_STATS_GET)); - columns.add(new TableColumnInfo("R", 25, PresetColumns.FN_RARITY_COMPARE, - PresetColumns.FN_RARITY_GET)); - columns.add(new TableColumnInfo("Set", 40, PresetColumns.FN_SET_COMPARE, - PresetColumns.FN_SET_GET)); - columns.add(new TableColumnInfo("AI", 30, PresetColumns.FN_AI_STATUS_COMPARE, - PresetColumns.FN_AI_STATUS_GET)); - columns.get(2).setCellRenderer(new ManaCostRenderer()); - - this.getTopTableWithCards().setup(columns, this.getCardView()); - this.getBottomTableWithCards().setup(columns, this.getCardView()); - - this.filterNameTypeSet.setListeners(new OnChangeTextUpdateDisplay(), this.getItemListenerUpdatesDisplay()); - - this.setSize(1024, 740); - } - - /** - * Instantiates a new deck editor common. - * - * @param parent the parent frame for this deck editor instance - */ - public DeckEditorConstructed(JFrame parent) { - super(parent); - try { - this.setFilterBoxes(new FilterCheckBoxes(true)); - this.setTopTableWithCards(new TableView("Available Cards", true, true, CardPrinted.class)); - this.setBottomTableWithCards(new TableView("Deck", true, CardPrinted.class)); - this.setCardView(new CardPanelHeavy()); - this.filterNameTypeSet = new FilterNameTypeSetPanel(); - - this.jbInit(); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - } - - final Lambda0 newCreator = new Lambda0() { - @Override - public Deck apply() { - return new Deck(); - } - }; - this.controller = new DeckController(Singletons.getModel().getDecks().getConstructed(), this, newCreator); - } - - private void jbInit() { - - final Font fButtons = new java.awt.Font("Dialog", 0, 13); - this.removeButton.setFont(fButtons); - this.addButton.setFont(fButtons); - this.importButton.setFont(fButtons); - this.clearFilterButton.setFont(fButtons); - this.analysisButton.setFont(fButtons); - - this.addButton.setText("Add to Deck"); - this.removeButton.setText("Remove from Deck"); - this.importButton.setText("Import a Deck"); - this.clearFilterButton.setText("Clear Filter"); - this.analysisButton.setText("Deck Analysis"); - - this.removeButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorConstructed.this.removeButtonClicked(e); - } - }); - this.addButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorConstructed.this.addButtonActionPerformed(e); - } - }); - this.importButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorConstructed.this.importButtonActionPerformed(e); - } - }); - this.clearFilterButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorConstructed.this.clearFilterButtonActionPerformed(e); - } - }); - this.analysisButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorConstructed.this.analysisButtonActionPerformed(e); - } - }); - - // Type filtering - final Font f = new Font("Tahoma", Font.PLAIN, 10); - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - box.setFont(f); - box.setOpaque(false); - } - - // Color filtering - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - box.setOpaque(false); - } - - // Do not lower statsLabel any lower, we want this to be visible at 1024 - // x 768 screen size - this.setTitle("Deck Editor"); - - final Container content = this.getContentPane(); - final MigLayout layout = new MigLayout("fill"); - content.setLayout(layout); - - boolean isFirst = true; - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - String growParameter = "grow"; - if (isFirst) { - growParameter = "cell 0 0, egx checkbox, grow, split 14"; - isFirst = false; - } - content.add(box, growParameter); - box.addItemListener(this.getItemListenerUpdatesDisplay()); - } - - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - content.add(box, "grow"); - box.addItemListener(this.getItemListenerUpdatesDisplay()); - } - - content.add(this.clearFilterButton, "wmin 100, hmin 25, wmax 140, hmax 25, grow"); - - content.add(this.filterNameTypeSet, "cell 0 1, grow"); - content.add(this.getTopTableWithCards().getTableDecorated(), "cell 0 2 1 2, push, grow"); - content.add(this.getTopTableWithCards().getLabel(), "cell 0 4"); - - content.add(this.addButton, "w 100, h 49, sg button, cell 0 5, split 5"); - content.add(this.removeButton, "w 100, h 49, sg button"); - content.add(this.importButton, "w 100, h 49, sg button, gapleft 40px"); - // Label is used to push the analysis button to the right to separate - // analysis button from add/remove card ones - content.add(this.jLabelAnalysisGap, "wmin 75, growx"); - content.add(this.analysisButton, "w 100, h 49, wrap"); - - content.add(this.getBottomTableWithCards().getTableDecorated(), "cell 0 6, grow"); - content.add(this.getBottomTableWithCards().getLabel(), "cell 0 7"); - - content.add(this.getCardView(), "cell 1 0 1 8, flowy, grow"); - - this.getTopTableWithCards().getTable().addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(final MouseEvent e) { - if (e.getClickCount() == 2) { - DeckEditorConstructed.this.addCardToDeck(); - } - } - }); - this.getTopTableWithCards().getTable().addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(final KeyEvent e) { - if (e.getKeyChar() == ' ') { - DeckEditorConstructed.this.addCardToDeck(); - } - } - }); - - // javax.swing.JRootPane rootPane = this.getRootPane(); - // rootPane.setDefaultButton(filterButton); - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#buildFilter() - */ - @Override - protected Predicate buildFilter() { - final Predicate cardFilter = Predicate.and(this.getFilterBoxes().buildFilter(), - this.filterNameTypeSet.buildFilter()); - return Predicate.instanceOf(cardFilter, CardPrinted.class); - } - - /** - * Clear filter button_action performed. - * - * @param e - * the e - */ - void clearFilterButtonActionPerformed(final ActionEvent e) { - // disable automatic update triggered by listeners - this.setFiltersChangeFiringUpdate(false); - - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - if (!box.isSelected()) { - box.doClick(); - } - } - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - if (!box.isSelected()) { - box.doClick(); - } - } - - this.filterNameTypeSet.clearFilters(); - - this.setFiltersChangeFiringUpdate(true); - - this.getTopTableWithCards().setFilter(null); - } - - /** - * Adds the button_action performed. - * - * @param e - * the e - */ - void addButtonActionPerformed(final ActionEvent e) { - this.addCardToDeck(); - } - - /** - * Adds the card to deck. - */ - void addCardToDeck() { - final InventoryItem item = this.getTopTableWithCards().getSelectedCard(); - if ((item == null) || !(item instanceof CardPrinted)) { - return; - } - - final CardPrinted card = (CardPrinted) item; - this.getBottomTableWithCards().addCard(card); - this.controller.notifyModelChanged(); - } - - /** - * Removes the button clicked. - * - * @param e - * the e - */ - void removeButtonClicked(final ActionEvent e) { - final InventoryItem item = this.getBottomTableWithCards().getSelectedCard(); - if ((item == null) || !(item instanceof CardPrinted)) { - return; - } - - final CardPrinted card = (CardPrinted) item; - this.getBottomTableWithCards().removeCard(card); - this.controller.notifyModelChanged(); - } - - /** - * Import button_action performed. - * - * @param e - * the e - */ - void importButtonActionPerformed(final ActionEvent e) { - final DeckEditorConstructed g = this; - final DeckImport dImport = new DeckImport(g); - dImport.setModalityType(ModalityType.APPLICATION_MODAL); - dImport.setVisible(true); - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#updateView() - */ - @Override - public void updateView() { - // if constructed, can add the all cards above - this.getTopTableWithCards().setDeck(ItemPool.createFrom(CardDb.instance().getAllCards(), CardPrinted.class)); - this.getBottomTableWithCards().setDeck(this.controller.getModel().getMain()); - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#getController() - */ - @Override - public DeckController getController() { - return this.controller; - } - -} diff --git a/src/main/java/forge/gui/deckeditor/DeckEditorLimited.java b/src/main/java/forge/gui/deckeditor/DeckEditorLimited.java deleted file mode 100644 index c96551c0b56..00000000000 --- a/src/main/java/forge/gui/deckeditor/DeckEditorLimited.java +++ /dev/null @@ -1,415 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.gui.deckeditor; - -import java.awt.Container; -import java.awt.Font; -import java.awt.event.ActionEvent; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.util.ArrayList; -import java.util.List; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JFrame; -import javax.swing.JLabel; - -import forge.Command; -import forge.deck.Deck; -import forge.deck.DeckGroup; -import forge.error.ErrorViewer; -import forge.gui.deckeditor.elements.CardPanelHeavy; -import forge.gui.deckeditor.elements.FilterCheckBoxes; -import forge.gui.deckeditor.elements.FilterNameTypeSetPanel; -import forge.gui.deckeditor.elements.ManaCostRenderer; -import forge.gui.deckeditor.elements.TableColumnInfo; -import forge.gui.deckeditor.elements.TableView; -import forge.item.CardPrinted; -import forge.item.InventoryItem; -import forge.util.IStorage; -import forge.util.closures.Lambda0; -import forge.util.closures.Predicate; -import net.miginfocom.swing.MigLayout; - -/** - *

- * Gui_DeckEditor class. - *

- * - * @author Forge - * @version $Id: DeckEditorCommon.java 12850 2011-12-26 14:55:09Z slapshot5 $ - */ -public final class DeckEditorLimited extends DeckEditorBase { - /** Constant serialVersionUID=130339644136746796L. */ - private static final long serialVersionUID = 130339644136746796L; - - private final JButton removeButton = new JButton(); - private final JButton addButton = new JButton(); - - private final JButton analysisButton = new JButton(); - private final JButton clearFilterButton = new JButton(); - - private final JLabel jLabelAnalysisGap = new JLabel(""); - private FilterNameTypeSetPanel filterNameTypeSet; - - private final DeckController controller; - - /** - * Show. - * - * @param exitCommand - * the exit command - */ - @Override - public void show(final Command exitCommand) { - final Command exit = new Command() { - private static final long serialVersionUID = 5210924838133689758L; - - @Override - public void execute() { - DeckEditorLimited.this.dispose(); - if (exitCommand != null) { - exitCommand.execute(); - } - } - }; - - final MenuLimited menu = new MenuLimited(this.getController(), exit); - - this.setJMenuBar(menu); - - // do not change this!!!! - this.addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(final WindowEvent ev) { - menu.close(); - } - }); - - this.setup(); - - this.getTopTableWithCards().sort(1, true); - this.getBottomTableWithCards().sort(1, true); - - } // show(Command) - - private void setup() { - final List> columns = new ArrayList>(); - columns.add(new TableColumnInfo("Qty", 30, PresetColumns.FN_QTY_COMPARE, - PresetColumns.FN_QTY_GET)); - columns.add(new TableColumnInfo("Name", 175, PresetColumns.FN_NAME_COMPARE, - PresetColumns.FN_NAME_GET)); - columns.add(new TableColumnInfo("Cost", 75, PresetColumns.FN_COST_COMPARE, - PresetColumns.FN_COST_GET)); - columns.add(new TableColumnInfo("Color", 60, PresetColumns.FN_COLOR_COMPARE, - PresetColumns.FN_COLOR_GET)); - columns.add(new TableColumnInfo("Type", 100, PresetColumns.FN_TYPE_COMPARE, - PresetColumns.FN_TYPE_GET)); - columns.add(new TableColumnInfo("Stats", 60, PresetColumns.FN_STATS_COMPARE, - PresetColumns.FN_STATS_GET)); - columns.add(new TableColumnInfo("R", 25, PresetColumns.FN_RARITY_COMPARE, - PresetColumns.FN_RARITY_GET)); - columns.add(new TableColumnInfo("Set", 40, PresetColumns.FN_SET_COMPARE, - PresetColumns.FN_SET_GET)); - columns.add(new TableColumnInfo("AI", 30, PresetColumns.FN_AI_STATUS_COMPARE, - PresetColumns.FN_AI_STATUS_GET)); - columns.get(2).setCellRenderer(new ManaCostRenderer()); - - this.getTopTableWithCards().setup(columns, this.getCardView()); - this.getBottomTableWithCards().setup(columns, this.getCardView()); - - this.filterNameTypeSet.setListeners(new OnChangeTextUpdateDisplay(), this.getItemListenerUpdatesDisplay()); - - this.setSize(1024, 740); - } - - /** - * Instantiates a new deck editor common. - * - * @param mainFrame the parent frame for this deck editor instance - * @param deckMap the deck map - */ - public DeckEditorLimited(JFrame mainFrame, final IStorage deckMap) { - super(mainFrame); - try { - this.setFilterBoxes(new FilterCheckBoxes(true)); - this.setTopTableWithCards(new TableView("Avaliable Cards", true, true, CardPrinted.class)); - this.setBottomTableWithCards(new TableView("Deck", true, CardPrinted.class)); - this.setCardView(new CardPanelHeavy()); - this.filterNameTypeSet = new FilterNameTypeSetPanel(); - - this.jbInit(); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - } - - final Lambda0 newCreator = new Lambda0() { - @Override - public DeckGroup apply() { - return new DeckGroup(""); - } - }; - this.controller = new DeckController(deckMap, this, newCreator); - } - - private void jbInit() { - - final Font fButtons = new java.awt.Font("Dialog", 0, 13); - this.removeButton.setFont(fButtons); - this.addButton.setFont(fButtons); - this.clearFilterButton.setFont(fButtons); - this.analysisButton.setFont(fButtons); - - this.addButton.setText("Add to Deck"); - this.removeButton.setText("Remove from Deck"); - this.clearFilterButton.setText("Clear Filter"); - this.analysisButton.setText("Deck Analysis"); - - this.removeButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorLimited.this.removeButtonClicked(e); - } - }); - this.addButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorLimited.this.addButtonActionPerformed(e); - } - }); - this.clearFilterButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorLimited.this.clearFilterButtonActionPerformed(e); - } - }); - this.analysisButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorLimited.this.analysisButtonActionPerformed(e); - } - }); - - // Type filtering - final Font f = new Font("Tahoma", Font.PLAIN, 10); - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - box.setFont(f); - box.setOpaque(false); - } - - // Color filtering - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - box.setOpaque(false); - } - - // Do not lower statsLabel any lower, we want this to be visible at 1024 - // x 768 screen size - this.setTitle("Deck Editor"); - - final Container content = this.getContentPane(); - final MigLayout layout = new MigLayout("fill"); - content.setLayout(layout); - - boolean isFirst = true; - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - String growParameter = "grow"; - if (isFirst) { - growParameter = "cell 0 0, egx checkbox, grow, split 14"; - isFirst = false; - } - content.add(box, growParameter); - box.addItemListener(this.getItemListenerUpdatesDisplay()); - } - - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - content.add(box, "grow"); - box.addItemListener(this.getItemListenerUpdatesDisplay()); - } - - content.add(this.clearFilterButton, "wmin 100, hmin 25, wmax 140, hmax 25, grow"); - - content.add(this.filterNameTypeSet, "cell 0 1, grow"); - content.add(this.getTopTableWithCards().getTableDecorated(), "cell 0 2 1 2, push, grow"); - content.add(this.getTopTableWithCards().getLabel(), "cell 0 4"); - - content.add(this.addButton, "w 100, h 49, sg button, cell 0 5, split 5"); - content.add(this.removeButton, "w 100, h 49, sg button"); - // Label is used to push the analysis button to the right to separate - // analysis button from add/remove card ones - content.add(this.jLabelAnalysisGap, "wmin 75, growx"); - content.add(this.analysisButton, "w 100, h 49, wrap"); - - content.add(this.getBottomTableWithCards().getTableDecorated(), "cell 0 6, grow"); - content.add(this.getBottomTableWithCards().getLabel(), "cell 0 7"); - - content.add(this.getCardView(), "cell 1 0 1 8, flowy, grow"); - - this.getTopTableWithCards().getTable().addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(final MouseEvent e) { - if (e.getClickCount() == 2) { - DeckEditorLimited.this.addCardToDeck(); - } - } - }); - this.getTopTableWithCards().getTable().addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(final KeyEvent e) { - if (e.getKeyChar() == ' ') { - DeckEditorLimited.this.addCardToDeck(); - } - } - }); - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#buildFilter() - */ - @Override - protected Predicate buildFilter() { - final Predicate cardFilter = Predicate.and(this.getFilterBoxes().buildFilter(), - this.filterNameTypeSet.buildFilter()); - return Predicate.instanceOf(cardFilter, CardPrinted.class); - } - - /** - * Clear filter button_action performed. - * - * @param e - * the e - */ - void clearFilterButtonActionPerformed(final ActionEvent e) { - // disable automatic update triggered by listeners - this.setFiltersChangeFiringUpdate(false); - - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - if (!box.isSelected()) { - box.doClick(); - } - } - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - if (!box.isSelected()) { - box.doClick(); - } - } - - this.filterNameTypeSet.clearFilters(); - - this.setFiltersChangeFiringUpdate(true); - - this.getTopTableWithCards().setFilter(null); - } - - /** - * Adds the button_action performed. - * - * @param e - * the e - */ - void addButtonActionPerformed(final ActionEvent e) { - this.addCardToDeck(); - } - - /** - * Adds the card to deck. - */ - void addCardToDeck() { - final InventoryItem item = this.getTopTableWithCards().getSelectedCard(); - if ((item == null) || !(item instanceof CardPrinted)) { - return; - } - - // update view - final CardPrinted card = (CardPrinted) item; - this.getBottomTableWithCards().addCard(card); - this.getTopTableWithCards().removeCard(card); - - /* - * update model Deck model = - * getSelectedDeck(getController().getModel()); - * model.getMain().add(card); model.getSideboard().remove(card); - */ - - this.getController().notifyModelChanged(); - } - - /** - * TODO: Write javadoc for this method. - * - * @param model - * @return - */ - private Deck getSelectedDeck(final DeckGroup model) { - return model.getHumanDeck(); - } - - /** - * Removes the button clicked. - * - * @param e - * the e - */ - void removeButtonClicked(final ActionEvent e) { - final InventoryItem item = this.getBottomTableWithCards().getSelectedCard(); - if ((item == null) || !(item instanceof CardPrinted)) { - return; - } - - // update view - final CardPrinted card = (CardPrinted) item; - this.getBottomTableWithCards().removeCard(card); - this.getTopTableWithCards().addCard(card); - - /* - * update model Deck model = - * getSelectedDeck(getController().getModel()); - * model.getMain().remove(card); model.getSideboard().add(card); - */ - - this.getController().notifyModelChanged(); - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#getController() - */ - @Override - public DeckController getController() { - return this.controller; - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#updateView() - */ - @Override - public void updateView() { - Deck toEdit = this.getSelectedDeck(this.controller.getModel()); - this.getTopTableWithCards().setDeck(toEdit.getSideboard()); - this.getBottomTableWithCards().setDeck(toEdit.getMain()); - } - -} diff --git a/src/main/java/forge/gui/deckeditor/DeckEditorQuest.java b/src/main/java/forge/gui/deckeditor/DeckEditorQuest.java deleted file mode 100644 index dac5ef7edd6..00000000000 --- a/src/main/java/forge/gui/deckeditor/DeckEditorQuest.java +++ /dev/null @@ -1,414 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.gui.deckeditor; - -// import java.awt.Font; -import java.awt.Container; -import java.awt.Font; -import java.awt.event.ActionEvent; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.util.ArrayList; -import java.util.List; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JLabel; -import javax.swing.JFrame; -import javax.swing.WindowConstants; - -import forge.Command; -import forge.Constant; -import forge.deck.Deck; -import forge.error.ErrorViewer; -import forge.gui.deckeditor.elements.CardPanelHeavy; -import forge.gui.deckeditor.elements.FilterCheckBoxes; -import forge.gui.deckeditor.elements.FilterNameTypeSetPanel; -import forge.gui.deckeditor.elements.ManaCostRenderer; -import forge.gui.deckeditor.elements.TableColumnInfo; -import forge.gui.deckeditor.elements.TableView; -import forge.item.CardPrinted; -import forge.item.InventoryItem; -import forge.item.ItemPool; -import forge.quest.QuestController; -import forge.util.closures.Lambda0; -import forge.util.closures.Predicate; -import net.miginfocom.swing.MigLayout; - -//import forge.quest.data.QuestBoosterPack; - -/** - *

- * Gui_Quest_DeckEditor class. - *

- * - * @author Forge - * @version $Id$ - */ -public final class DeckEditorQuest extends DeckEditorBase { - /** Constant serialVersionUID=152061168634545L. */ - private static final long serialVersionUID = 152061168634545L; - - /** The custom menu. */ - private final JButton clearFilterButton = new JButton(); - private final JButton addButton = new JButton(); - private final JButton removeButton = new JButton(); - private final JLabel jLabelAnalysisGap = new JLabel(""); - private final JButton analysisButton = new JButton(); - - private FilterNameTypeSetPanel filterNameTypeSet; - - private final QuestController questData; - private final DeckController controller; - - /** - * Show. - * - * @param exitCommand - * the exit command - */ - @Override - public void show(final Command exitCommand) { - final Command exit = new Command() { - private static final long serialVersionUID = -7428793574300520612L; - - @Override - public void execute() { - DeckEditorQuest.this.dispose(); - exitCommand.execute(); - } - }; - - this.setup(); - - final MenuQuest menu = new MenuQuest(this.getController(), exit); - this.setJMenuBar(menu); - - // do not change this!!!! - this.addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(final WindowEvent ev) { - menu.close(); - } - }); - - Deck deck = Constant.Runtime.HUMAN_DECK[0] == null ? null : this.questData.getMyDecks().get( - Constant.Runtime.HUMAN_DECK[0].getName()); - - if (deck == null) { - deck = new Deck(); - } - - // tell Gui_Quest_DeckEditor the name of the deck - - this.getController().setModel(deck); - - // this affects the card pool - this.getTopTableWithCards().sort(4, true); // sort by type - this.getTopTableWithCards().sort(3, true); // then sort by color - this.getBottomTableWithCards().sort(1, true); - } // show(Command) - - /** - *

- * setup. - *

- */ - public void setup() { - final List> columns = new ArrayList>(); - columns.add(new TableColumnInfo("Qty", 30, PresetColumns.FN_QTY_COMPARE, - PresetColumns.FN_QTY_GET)); - columns.add(new TableColumnInfo("Name", 180, PresetColumns.FN_NAME_COMPARE, - PresetColumns.FN_NAME_GET)); - columns.add(new TableColumnInfo("Cost", 70, PresetColumns.FN_COST_COMPARE, - PresetColumns.FN_COST_GET)); - columns.add(new TableColumnInfo("Color", 50, PresetColumns.FN_COLOR_COMPARE, - PresetColumns.FN_COLOR_GET)); - columns.add(new TableColumnInfo("Type", 100, PresetColumns.FN_TYPE_COMPARE, - PresetColumns.FN_TYPE_GET)); - columns.add(new TableColumnInfo("Stats", 40, PresetColumns.FN_STATS_COMPARE, - PresetColumns.FN_STATS_GET)); - columns.add(new TableColumnInfo("R", 35, PresetColumns.FN_RARITY_COMPARE, - PresetColumns.FN_RARITY_GET)); - columns.add(new TableColumnInfo("Set", 40, PresetColumns.FN_SET_COMPARE, - PresetColumns.FN_SET_GET)); - columns.add(new TableColumnInfo("New", 30, this.questData.getCards().getFnNewCompare(), - this.questData.getCards().getFnNewGet())); - - columns.get(2).setCellRenderer(new ManaCostRenderer()); - - this.getTopTableWithCards().setup(columns, this.getCardView()); - this.getBottomTableWithCards().setup(columns, this.getCardView()); - - this.filterNameTypeSet.setListeners(new OnChangeTextUpdateDisplay(), this.getItemListenerUpdatesDisplay()); - - setSize(1024, 740); - } - - /** - * Instantiates a new deck editor quest. - * - * @param parent - * the parent frame for this deck editor instance - * @param questData2 - * the quest data2 - */ - public DeckEditorQuest(JFrame parent, final QuestController questData2) { - super(parent); - this.questData = questData2; - try { - this.setFilterBoxes(new FilterCheckBoxes(true)); - this.setTopTableWithCards(new TableView("All Cards", true, true, CardPrinted.class)); - this.setBottomTableWithCards(new TableView("Your deck", true, CardPrinted.class)); - this.setCardView(new CardPanelHeavy()); - this.filterNameTypeSet = new FilterNameTypeSetPanel(); - this.jbInit(); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - } - - final Lambda0 newCreator = new Lambda0() { - @Override - public Deck apply() { - return new Deck(); - } - }; - this.controller = new DeckController(questData2.getMyDecks(), this, newCreator); - } - - private void jbInit() throws Exception { - - this.setTitle("Deck Editor"); - this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); - - final Font fButtons = new java.awt.Font("Dialog", 0, 13); - this.removeButton.setFont(fButtons); - this.addButton.setFont(fButtons); - this.clearFilterButton.setFont(fButtons); - this.analysisButton.setFont(fButtons); - - this.addButton.setText("Add to Deck"); - this.removeButton.setText("Remove from Deck"); - this.clearFilterButton.setText("Clear Filter"); - this.analysisButton.setText("Deck Analysis"); - - this.removeButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorQuest.this.removeButtonActionPerformed(e); - } - }); - this.addButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorQuest.this.addButtonActionPerformed(e); - } - }); - this.clearFilterButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorQuest.this.clearFilterButtonActionPerformed(e); - } - }); - this.analysisButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorQuest.this.analysisButtonActionPerformed(e); - } - }); - - // Type filtering - final Font f = new Font("Tahoma", Font.PLAIN, 10); - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - box.setFont(f); - box.setOpaque(false); - } - - // Color filtering - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - box.setOpaque(false); - } - - final Container content = this.getContentPane(); - final MigLayout layout = new MigLayout("fill"); - content.setLayout(layout); - - boolean isFirst = true; - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - String growParameter = "grow"; - if (isFirst) { - growParameter = "cell 0 0, egx checkbox, grow, split 14"; - isFirst = false; - } - content.add(box, growParameter); - box.addItemListener(this.getItemListenerUpdatesDisplay()); - } - - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - content.add(box, "grow"); - box.addItemListener(this.getItemListenerUpdatesDisplay()); - } - - content.add(this.clearFilterButton, "wmin 100, hmin 25, wmax 140, hmax 25, grow"); - - content.add(this.filterNameTypeSet, "cell 0 1, grow"); - content.add(this.getTopTableWithCards().getTableDecorated(), "cell 0 2 1 2, push, grow"); - content.add(this.getTopTableWithCards().getLabel(), "cell 0 4"); - - content.add(this.addButton, "w 100, h 49, sg button, cell 0 5, split 5"); - content.add(this.removeButton, "w 100, h 49, sg button"); - - content.add(this.jLabelAnalysisGap, "wmin 75, growx"); - content.add(this.analysisButton, "w 100, h 49, wrap"); - - content.add(this.getBottomTableWithCards().getTableDecorated(), "cell 0 6, grow"); - content.add(this.getBottomTableWithCards().getLabel(), "cell 0 7"); - - content.add(this.getCardView(), "cell 1 0 1 8, flowy, growy"); - - this.getTopTableWithCards().getTable().addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(final MouseEvent e) { - if (e.getClickCount() == 2) { - DeckEditorQuest.this.addCardToDeck(); - } - } - }); - this.getTopTableWithCards().getTable().addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(final KeyEvent e) { - if (e.getKeyChar() == ' ') { - DeckEditorQuest.this.addCardToDeck(); - } - } - }); - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#buildFilter() - */ - @Override - protected Predicate buildFilter() { - final Predicate cardFilter = Predicate.and(this.getFilterBoxes().buildFilter(), - this.filterNameTypeSet.buildFilter()); - return Predicate.instanceOf(cardFilter, CardPrinted.class); - } - - private void addButtonActionPerformed(final ActionEvent e) { - addCardToDeck(); - } - - /** - * Clear filter button_action performed. - * - * @param e - * the e - */ - void clearFilterButtonActionPerformed(final ActionEvent e) { - // disable automatic update triggered by listeners - this.setFiltersChangeFiringUpdate(false); - - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - if (!box.isSelected()) { - box.doClick(); - } - } - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - if (!box.isSelected()) { - box.doClick(); - } - } - - this.filterNameTypeSet.clearFilters(); - - this.setFiltersChangeFiringUpdate(true); - - this.getTopTableWithCards().setFilter(null); - } - - /** - * Adds the card to deck. - */ - void addCardToDeck() { - final InventoryItem item = this.getTopTableWithCards().getSelectedCard(); - if ((item == null) || !(item instanceof CardPrinted)) { - return; - } - - final CardPrinted card = (CardPrinted) item; - this.getTopTableWithCards().removeCard(card); - this.getBottomTableWithCards().addCard(card); - this.controller.notifyModelChanged(); - } - - private void removeButtonActionPerformed(final ActionEvent e) { - final InventoryItem item = this.getBottomTableWithCards().getSelectedCard(); - if ((item == null) || !(item instanceof CardPrinted)) { - return; - } - - final CardPrinted card = (CardPrinted) item; - this.getTopTableWithCards().addCard(card); - this.getBottomTableWithCards().removeCard(card); - } - - /** - * Adds the cheat card. - * - * @param card - * the card - */ - public void addCheatCard(final CardPrinted card) { - this.getTopTableWithCards().addCard(card); - this.questData.getCards().getCardpool().add(card); - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#getController() - */ - @Override - public DeckController getController() { - return this.controller; - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#updateView() - */ - @Override - public void updateView() { - final Deck deck = this.controller.getModel(); - - final ItemPool cardpool = new ItemPool(CardPrinted.class); - cardpool.addAll(this.questData.getCards().getCardpool()); - // remove bottom cards that are in the deck from the card pool - cardpool.removeAll(deck.getMain()); - // show cards, makes this user friendly - this.getTopTableWithCards().setDeck(cardpool); - this.getBottomTableWithCards().setDeck(deck.getMain()); - } - -} diff --git a/src/main/java/forge/gui/deckeditor/DeckImport.java b/src/main/java/forge/gui/deckeditor/DeckImport.java index 2e5ff3060a2..a5d9880caf5 100644 --- a/src/main/java/forge/gui/deckeditor/DeckImport.java +++ b/src/main/java/forge/gui/deckeditor/DeckImport.java @@ -41,15 +41,22 @@ import javax.swing.text.ElementIterator; import net.miginfocom.swing.MigLayout; import forge.deck.Deck; +import forge.deck.DeckBase; import forge.deck.DeckRecognizer; import forge.deck.DeckRecognizer.TokenType; import forge.gui.GuiUtils; +import forge.gui.deckeditor.controllers.ACEditorBase; import forge.item.CardPrinted; +import forge.item.InventoryItem; /** + * * Dialog for quick import of decks. + * + * @param + * @param */ -public class DeckImport extends JDialog { +public class DeckImport extends JDialog { private static final long serialVersionUID = -5837776824284093004L; private final JTextArea txtInput = new JTextArea(); @@ -83,7 +90,7 @@ public class DeckImport extends JDialog { /** The tokens. */ private final List tokens = new ArrayList(); - private final DeckEditorConstructed host; + private final ACEditorBase host; /** * Instantiates a new deck import. @@ -91,7 +98,7 @@ public class DeckImport extends JDialog { * @param g * the g */ - public DeckImport(final DeckEditorConstructed g) { + public DeckImport(final ACEditorBase g) { this.host = g; final int wWidth = 600; @@ -136,6 +143,7 @@ public class DeckImport extends JDialog { }); this.cmdAccept.addActionListener(new ActionListener() { + @SuppressWarnings("unchecked") @Override public void actionPerformed(final ActionEvent e) { final String warning = "This will replace contents of your currently open deck with whatever you are importing. Proceed?"; @@ -145,7 +153,7 @@ public class DeckImport extends JDialog { return; } final Deck toSet = DeckImport.this.buildDeck(); - DeckImport.this.host.getController().setModel(toSet); + DeckImport.this.host.getDeckController().setModel((TModel) toSet); DeckImport.this.processWindowEvent(new WindowEvent(DeckImport.this, WindowEvent.WINDOW_CLOSING)); } }); diff --git a/src/main/java/forge/gui/deckeditor/DraftingProcess.java b/src/main/java/forge/gui/deckeditor/DraftingProcess.java deleted file mode 100644 index 28ce286948a..00000000000 --- a/src/main/java/forge/gui/deckeditor/DraftingProcess.java +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.gui.deckeditor; - -import java.awt.Rectangle; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.InputEvent; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.util.ArrayList; -import java.util.List; -import javax.swing.JButton; -import javax.swing.JFrame; -import javax.swing.JOptionPane; -import javax.swing.JTable; -import javax.swing.WindowConstants; - -import forge.Command; -import forge.Constant; -import forge.Singletons; -import forge.deck.Deck; -import forge.deck.DeckGroup; -import forge.error.ErrorViewer; -import forge.game.limited.IBoosterDraft; -import forge.gui.GuiUtils; -import forge.gui.SOverlayUtils; -import forge.gui.deckeditor.elements.CardPanelLite; -import forge.gui.deckeditor.elements.ManaCostRenderer; -import forge.gui.deckeditor.elements.TableColumnInfo; -import forge.gui.deckeditor.elements.TableView; -import forge.gui.home.sanctioned.CSubmenuDraft; -import forge.item.CardDb; -import forge.item.CardPrinted; -import forge.item.InventoryItem; -import forge.item.ItemPoolView; -import forge.properties.ForgeProps; -import forge.properties.NewConstants.Lang.GuiBoosterDraft; -import forge.util.closures.Predicate; - -/** - *

- * DeckEditorDraft class. - *

- * - * @author Forge - * @version $Id$ - */ -public class DraftingProcess extends DeckEditorBase { - /** - * Constant serialVersionUID=-6055633915602448260L. - */ - private static final long serialVersionUID = -6055633915602448260L; - - private IBoosterDraft boosterDraft; - - private final JButton jButtonPick = new JButton(); - - private CardPanelLite cardView = new CardPanelLite(); - - private final MouseListener pickWithMouse = new MouseAdapter() { - @Override - public void mouseClicked(final MouseEvent e) { - // Pick on left-button double click - if (((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) && (e.getClickCount() == 2)) { - DraftingProcess.this.jButtonPickClicked(null); - } else if ((e.getModifiers() & InputEvent.BUTTON3_MASK) != 0) { - // pick on right click - final JTable table = DraftingProcess.this.getTopTableWithCards().getTable(); - final int rowNumber = table.rowAtPoint(e.getPoint()); - // after hittest - if it was outside of rows - discard this - // click - if (rowNumber == -1) { - return; - } - - // if row was not selected, select it. If it was, pick a card - if (rowNumber != table.getSelectedRow()) { - table.getSelectionModel().setSelectionInterval(rowNumber, rowNumber); - } else { - DraftingProcess.this.jButtonPickClicked(null); - } - } - } - }; - - /** - * Show gui. - * - * @param inBoosterDraft - * the in_booster draft - */ - public final void showGui(final IBoosterDraft inBoosterDraft) { - this.boosterDraft = inBoosterDraft; - this.show(null); - } - - /** - *

- * addListeners. - *

- */ - private void addListeners() { - this.addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(final WindowEvent ev) { - final int n = JOptionPane.showConfirmDialog(null, - ForgeProps.getLocalized(GuiBoosterDraft.CLOSE_MESSAGE), "", JOptionPane.YES_NO_OPTION); - if (n == JOptionPane.YES_OPTION) { - DraftingProcess.this.dispose(); - CSubmenuDraft.SINGLETON_INSTANCE.update(); - SOverlayUtils.hideOverlay(); - } - } // windowClosing() - }); - } // addListeners() - - /** - *

- * setup. - *

- */ - private void setup() { - this.addListeners(); - // setupMenu(); - - final List> columns = new ArrayList>(); - columns.add(new TableColumnInfo("Qty", 30, PresetColumns.FN_QTY_COMPARE, - PresetColumns.FN_QTY_GET)); - columns.add(new TableColumnInfo("Name", 180, PresetColumns.FN_NAME_COMPARE, - PresetColumns.FN_NAME_GET)); - columns.add(new TableColumnInfo("Cost", 70, PresetColumns.FN_COST_COMPARE, - PresetColumns.FN_COST_GET)); - columns.add(new TableColumnInfo("Color", 50, PresetColumns.FN_COLOR_COMPARE, - PresetColumns.FN_COLOR_GET)); - columns.add(new TableColumnInfo("Type", 100, PresetColumns.FN_TYPE_COMPARE, - PresetColumns.FN_TYPE_GET)); - columns.add(new TableColumnInfo("Stats", 40, PresetColumns.FN_STATS_COMPARE, - PresetColumns.FN_STATS_GET)); - columns.add(new TableColumnInfo("R", 35, PresetColumns.FN_RARITY_COMPARE, - PresetColumns.FN_RARITY_GET)); - columns.add(new TableColumnInfo("Set", 40, PresetColumns.FN_SET_COMPARE, - PresetColumns.FN_SET_GET)); - columns.add(new TableColumnInfo("AI", 30, PresetColumns.FN_AI_STATUS_COMPARE, - PresetColumns.FN_AI_STATUS_GET)); - columns.get(2).setCellRenderer(new ManaCostRenderer()); - - this.getTopTableWithCards().setup(columns, this.cardView); - this.getBottomTableWithCards().setup(columns, this.cardView); - - this.setSize(980, 740); - GuiUtils.centerFrame(this); - this.setResizable(false); - - this.getTopTableWithCards().getTable().addMouseListener(this.pickWithMouse); - this.getTopTableWithCards().getTable().addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(final KeyEvent e) { - if (e.getKeyChar() == ' ') { - DraftingProcess.this.jButtonPickClicked(null); - } - } - }); - - } - - /** - * Instantiates a new deck editor draft. - */ - public DraftingProcess(JFrame parent) { - super(parent); - try { - this.setTopTableWithCards(new TableView("Choose one card", false, CardPrinted.class)); - this.setBottomTableWithCards(new TableView("Previously picked cards", true, CardPrinted.class)); - this.setFilterBoxes(null); - this.cardView = new CardPanelLite(); - this.jbInit(); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - } - } - - /** - *

- * jbInit. - *

- * - * @throws java.lang.Exception - * if any. - */ - private void jbInit() throws Exception { - this.getContentPane().setLayout(null); - - this.getTopTableWithCards().getTableDecorated().setBounds(new Rectangle(19, 28, 680, 344)); - this.getBottomTableWithCards().getTableDecorated().setBounds(new Rectangle(19, 478, 680, 184)); - this.getBottomTableWithCards().getLabel().setBounds(new Rectangle(19, 680, 665, 31)); - - this.cardView.setBounds(new Rectangle(715, 23, 240, 666)); - - this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); - this.setTitle("Booster Draft"); - - this.jButtonPick.setBounds(new Rectangle(238, 418, 147, 44)); - this.jButtonPick.setFont(new java.awt.Font("Dialog", 0, 16)); - this.jButtonPick.setText("Choose Card"); - this.jButtonPick.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DraftingProcess.this.jButtonPickClicked(e); - } - }); - - this.getContentPane().add(this.cardView, null); - this.getContentPane().add(this.getTopTableWithCards().getTableDecorated(), null); - this.getContentPane().add(this.getBottomTableWithCards().getLabel(), null); - this.getContentPane().add(this.getBottomTableWithCards().getTableDecorated(), null); - this.getContentPane().add(this.jButtonPick, null); - } - - /** - *

- * jButton1_actionPerformed. - *

- * - * @param e - * a {@link java.awt.event.ActionEvent} object. - */ - final void jButtonPickClicked(final ActionEvent e) { - final InventoryItem item = this.getTopTableWithCards().getSelectedCard(); - if ((item == null) || !(item instanceof CardPrinted)) { - return; - } - - final CardPrinted card = (CardPrinted) item; - - this.getBottomTableWithCards().addCard(card); - - // get next booster pack - this.boosterDraft.setChoice(card); - if (this.boosterDraft.hasNextChoice()) { - this.showChoices(this.boosterDraft.nextChoice()); - } else { - this.boosterDraft.finishedDrafting(); - - // quit - this.saveDraft(); - this.dispose(); - } - } /* OK Button */ - - /** - *

- * showChoices. - *

- * - * @param list - * a {@link forge.CardList} object. - */ - private void showChoices(final ItemPoolView list) { - this.getTopTableWithCards().setDeck(list); - this.cardView.showCard(null); - this.getTopTableWithCards().fixSelection(0); - } // showChoices() - - /** - *

- * getPlayersDeck. - *

- * - * @return a {@link forge.deck.Deck} object. - */ - private Deck getPlayersDeck() { - final Deck deck = new Deck(); - Constant.Runtime.HUMAN_DECK[0] = deck; - - // add sideboard to deck - deck.getSideboard().addAll(this.getBottomTableWithCards().getCards()); - - final String landSet = IBoosterDraft.LAND_SET_CODE[0]; - final int landsCount = 20; - deck.getSideboard().add(CardDb.instance().getCard("Forest", landSet), landsCount); - deck.getSideboard().add(CardDb.instance().getCard("Mountain", landSet), landsCount); - deck.getSideboard().add(CardDb.instance().getCard("Swamp", landSet), landsCount); - deck.getSideboard().add(CardDb.instance().getCard("Island", landSet), landsCount); - deck.getSideboard().add(CardDb.instance().getCard("Plains", landSet), landsCount); - - return deck; - } // getPlayersDeck() - - /** - *

- * saveDraft. - *

- */ - private void saveDraft() { - String s = ""; - while ((s == null) || (s.length() == 0)) { - s = JOptionPane.showInputDialog(null, ForgeProps.getLocalized(GuiBoosterDraft.SAVE_DRAFT_MESSAGE), - ForgeProps.getLocalized(GuiBoosterDraft.SAVE_DRAFT_TITLE), JOptionPane.QUESTION_MESSAGE); - } - // TODO: check if overwriting the same name, and let the user delete old - // drafts - - // construct computer's decks - // save draft - final Deck[] computer = this.boosterDraft.getDecks(); - - final DeckGroup finishedDraft = new DeckGroup(s); - finishedDraft.setHumanDeck((Deck) this.getPlayersDeck().copyTo(s)); - finishedDraft.addAiDecks(computer); - - // DeckManager deckManager = new - // DeckManager(ForgeProps.getFile(NEW_DECKS)); - Singletons.getModel().getDecks().getDraft().add(finishedDraft); // write - // file - // right - // here - - // close and open next screen - DraftingProcess.this.dispose(); - - // This should be handled in the exit command of the editor, not here. - CSubmenuDraft.SINGLETON_INSTANCE.update(); - SOverlayUtils.hideOverlay(); - } /* saveDraft() */ - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#buildFilter() - */ - @Override - protected final Predicate buildFilter() { - return Predicate.getTrue(CardPrinted.class); - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#getController() - */ - @Override - public DeckController getController() { - return null; - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#updateView() - */ - @Override - public void updateView() { - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#show(forge.Command) - */ - @Override - public void show(final Command exitCommand) { - this.setup(); - this.showChoices(this.boosterDraft.nextChoice()); - this.getBottomTableWithCards().setDeck((Iterable) null); - - this.getTopTableWithCards().sort(1, true); - this.getBottomTableWithCards().sort(1, true); - - this.setVisible(true); - } -} diff --git a/src/main/java/forge/gui/deckeditor/MenuBase.java b/src/main/java/forge/gui/deckeditor/MenuBase.java deleted file mode 100644 index bc04ef9e7bc..00000000000 --- a/src/main/java/forge/gui/deckeditor/MenuBase.java +++ /dev/null @@ -1,454 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.gui.deckeditor; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.List; - -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.SwingUtilities; - -import org.apache.commons.lang3.StringUtils; - -import forge.Command; -import forge.deck.DeckBase; -import forge.error.ErrorViewer; -import forge.gui.GuiUtils; - -/** - *

- * Gui_DeckEditor_Menu class. - *

- * - * @param the generic type - * @author Forge - * @version $Id: DeckEditorCommonMenu.java 13590 2012-01-27 20:46:27Z Max mtg $ - */ -public class MenuBase extends JMenuBar { - - private static final long serialVersionUID = -4037993759604768755L; - private final Command exitCommand; - private final DeckController controller; - - /** - * Menu for Deck Editor. - * - * @param ctrl the ctrl - * @param exit a Command - */ - public MenuBase(final DeckController ctrl, final Command exit) { - this.controller = ctrl; - this.exitCommand = exit; - - this.setupMenu(); - } - - /** - * Gets the controller. - * - * @return the controller - */ - protected final DeckController getController() { - return this.controller; - } - - /** - * Setup menu. - */ - protected void setupMenu() { - this.add(this.getDefaultFileMenu()); - this.add(this.getSortMenu()); - } - - /** - * New constructed. - * - * @param careAboutOldDeck - * a boolean - */ - protected final void newDocument(final boolean careAboutOldDeck) { - if (careAboutOldDeck && !this.canLeaveCurrentDeck()) { - return; - } - - this.controller.newModel(); - } - - /** - * Gets the user input open deck. - * - * @return the user input open deck - */ - protected final String getUserInputOpenDeck() { - final List choices = this.controller.getSavedNames(); - if (choices.isEmpty()) { - JOptionPane.showMessageDialog(null, "No decks found", "Open Deck", JOptionPane.PLAIN_MESSAGE); - return null; - } - - final Object o = GuiUtils.chooseOneOrNone("Open Deck", choices.toArray()); - return o == null ? null : o.toString(); - } - - // deck.setName(currentDeckName); - - /** - * Open. - */ - protected final void open() { - if (!this.canLeaveCurrentDeck()) { - return; - } - final String name = this.getUserInputOpenDeck(); - if (StringUtils.isBlank(name)) { - return; - } - this.controller.load(name); - } - - /** - * Save. - */ - protected final void save() { - if (StringUtils.isBlank(this.controller.getModel().getName())) { - this.saveAs(); - return; - } - - this.controller.save(); - } - - /** - * Save as. - */ - protected final void saveAs() { - final String name = this.getDeckNameFromDialog(); - - if (StringUtils.isBlank(name)) { - final int n = JOptionPane.showConfirmDialog(null, "This name is incorrect. Enter another one?", - "Cannot save", JOptionPane.YES_NO_OPTION); - - if (n == JOptionPane.NO_OPTION) { - return; - } - } - - if (this.controller.fileExists(name)) { - final int m = JOptionPane.showConfirmDialog(null, "There is already saved an item named '" + name - + "'. Would you like to overwrite it?", "Confirm overwrite", JOptionPane.YES_NO_OPTION); - - if (m == JOptionPane.NO_OPTION) { - return; - } - } - - this.controller.saveAs(name); - } - - /** - * Delete. - */ - protected final void delete() { - if (!this.controller.isModelInStore()) { - return; - } - - final int n = JOptionPane.showConfirmDialog(null, "Do you want to delete this deck " - + this.controller.getModel().getName() + " ?", "Delete", JOptionPane.YES_NO_OPTION); - - if (n == JOptionPane.NO_OPTION) { - return; - } - - this.controller.delete(); - } - - /** - * - * close window. - */ - public final void close() { - if (!this.canLeaveCurrentDeck()) { - return; - } - this.exitCommand.execute(); - } - - /** - * Can leave current deck. - * - * @return true, if successful - */ - protected final boolean canLeaveCurrentDeck() { - if (this.controller.isSaved()) { - return true; - } - final String message = String.format("Do you wish to save changes you made to your current deck '%s'?", - this.controller.getModel().getName()); - final int choice = JOptionPane - .showConfirmDialog(this.controller.getOwnerWindow(), message, "You have unsaved changes in your deck", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); - if (JOptionPane.CANCEL_OPTION == choice) { - return false; - } - if (JOptionPane.NO_OPTION == choice) { - return true; - } - - this.save(); - return true; - } - - /** - *

- * getUserInput_GetDeckName. - *

- * - * @return a {@link java.lang.String} object. - */ - protected final String getDeckNameFromDialog() { - final Object o = JOptionPane.showInputDialog(null, "Save As", "Deck Name", JOptionPane.OK_CANCEL_OPTION); - - if (o == null) { - return ""; - } - - final String deckName = o.toString(); - final boolean isGoodName = this.controller.isGoodName(deckName); - - if (isGoodName) { - return deckName; - } - - JOptionPane.showMessageDialog(null, "Please pick another deck name, another deck currently has that name."); - return this.getDeckNameFromDialog(); - } - - /** - * Gets the default file menu. - * - * @return the default file menu - */ - protected JMenu getDefaultFileMenu() { - final JMenu fileMenu = new JMenu("Deck"); - - final JMenuItem newDoc = new JMenuItem("New"); - final JMenuItem open = new JMenuItem("Open"); - final JMenuItem save = new JMenuItem("Save"); - final JMenuItem saveAs = new JMenuItem("Save As..."); - final JMenuItem delete = new JMenuItem("Delete"); - - fileMenu.add(newDoc); - fileMenu.add(open); - fileMenu.addSeparator(); - - fileMenu.add(save); - fileMenu.add(saveAs); - fileMenu.add(delete); - - newDoc.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - try { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - MenuBase.this.newDocument(true); - } - }); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - throw new RuntimeException("Gui_DeckEditor_Menu : newConstructed() error - " + ex); - } - } - }); - - open.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - try { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - MenuBase.this.open(); - } - }); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - throw new RuntimeException("Gui_DeckEditor_Menu : open() error - " + ex); - } - } - }); - - save.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - try { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - MenuBase.this.save(); - } - }); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - throw new RuntimeException("Gui_DeckEditor_Menu : save() error - " + ex); - } - } - }); - - saveAs.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - try { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - MenuBase.this.saveAs(); - } - }); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - throw new RuntimeException("Gui_DeckEditor_Menu : saveAs() error - " + ex); - } - } - }); - - delete.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - try { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - MenuBase.this.delete(); - } - }); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - throw new RuntimeException("Gui_DeckEditor_Menu : delete() error - " + ex); - } - } - }); - return fileMenu; - } - - /** - * Append close menu item to. - * - * @param fileMenu the file menu - */ - protected void appendCloseMenuItemTo(final JMenu fileMenu) { - final JMenuItem close = new JMenuItem("Close"); - fileMenu.addSeparator(); - fileMenu.add(close); - - close.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - try { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - MenuBase.this.close(); - } - }); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - throw new RuntimeException("Gui_DeckEditor_Menu : close() error - " + ex); - } - } - }); - } // setupMenu() - - /** - *

- * setupSortMenu. - *

- * - * @return the sort menu - */ - protected final JMenuItem getSortMenu() { - final JMenuItem name = new JMenuItem("Card Name"); - final JMenuItem cost = new JMenuItem("Cost"); - final JMenuItem color = new JMenuItem("Color"); - final JMenuItem type = new JMenuItem("Type"); - final JMenuItem stats = new JMenuItem("Power/Toughness"); - final JMenuItem rarity = new JMenuItem("Rarity"); - - final JMenu menu = new JMenu("Sort By"); - menu.add(name); - menu.add(cost); - menu.add(color); - menu.add(type); - menu.add(stats); - menu.add(rarity); - - name.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - (MenuBase.this.controller).getView().getTopTableModel().sort(1, true); - } - }); - - // 0 1 2 3 4 5 6 - // private String column[] = {"Qty", "Name", "Cost", "Color", "Type", - // "Stats", "Rarity"}; - cost.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - (MenuBase.this.controller).getView().getTopTableModel().sort(4).sort(3).sort(2); - } - }); - - color.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - (MenuBase.this.controller).getView().getTopTableModel().sort(4).sort(2).sort(3); - } - }); - - type.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - (MenuBase.this.controller).getView().getTopTableModel().sort(2).sort(3).sort(4); - } - }); - - stats.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - (MenuBase.this.controller).getView().getTopTableModel().sort(4).sort(2).sort(3).sort(5); - } - }); - - rarity.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - // sort by cost, type, color, rarity - (MenuBase.this.controller).getView().getTopTableModel().sort(2).sort(4).sort(3).sort(6); - } - }); - - return menu; - } // setupSortMenu() -} diff --git a/src/main/java/forge/gui/deckeditor/MenuCommon.java b/src/main/java/forge/gui/deckeditor/MenuCommon.java index c779f98778b..9d74f5fd588 100644 --- a/src/main/java/forge/gui/deckeditor/MenuCommon.java +++ b/src/main/java/forge/gui/deckeditor/MenuCommon.java @@ -17,24 +17,6 @@ */ package forge.gui.deckeditor; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.File; -import javax.swing.JFileChooser; -import javax.swing.JMenu; -import javax.swing.JMenuItem; -import javax.swing.SwingUtilities; - -import forge.Command; -import forge.card.CardRules; -import forge.deck.Deck; -import forge.deck.generate.Generate2ColorDeck; -import forge.deck.io.DeckSerializer; -import forge.error.ErrorViewer; -import forge.game.player.PlayerType; -import forge.item.CardDb; -import forge.item.CardPrinted; -import forge.util.closures.Predicate; /** *

@@ -44,11 +26,11 @@ import forge.util.closures.Predicate; * @author Forge * @version $Id$ */ -public final class MenuCommon extends MenuBase { +public final class MenuCommon { - /** Constant serialVersionUID=-4037993759604768755L. */ + /** Constant serialVersionUID=-4037993759604768755L. * private static final long serialVersionUID = -4037993759604768755L; - /** Constant previousDirectory. */ + /** Constant previousDirectory. * private static File previousDirectory = null; /** @@ -58,7 +40,7 @@ public final class MenuCommon extends MenuBase { * the ctrl * @param exit * a Command - */ + * public MenuCommon(final DeckController ctrl, final Command exit) { super(ctrl, exit); @@ -132,7 +114,7 @@ public final class MenuCommon extends MenuBase { *

* exportDeck. *

- */ + * private void exportDeck() { final File filename = this.getExportFilename(); if (filename == null) { @@ -168,7 +150,7 @@ public final class MenuCommon extends MenuBase { *

* Generate Proxy for a Deck. *

- */ + * private void generateProxies() { final File filename = this.getProxiesFilename(); if (filename == null) { @@ -206,7 +188,7 @@ public final class MenuCommon extends MenuBase { * (non-Javadoc) * * @see forge.gui.deckeditor.MenuBase#getDefaultFileMenu() - */ + * @Override protected JMenu getDefaultFileMenu() { final JMenu fileMenu = super.getDefaultFileMenu(); @@ -327,4 +309,5 @@ public final class MenuCommon extends MenuBase { return fileMenu; } // setupMenu() + */ } diff --git a/src/main/java/forge/gui/deckeditor/MenuLimited.java b/src/main/java/forge/gui/deckeditor/MenuLimited.java deleted file mode 100644 index b13a388e92d..00000000000 --- a/src/main/java/forge/gui/deckeditor/MenuLimited.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.gui.deckeditor; - -import forge.Command; -import forge.deck.DeckGroup; - -/** - *

- * Gui_DeckEditor_Menu class. - *

- * - * @author Forge - * @version $Id: DeckEditorCommonMenu.java 13590 2012-01-27 20:46:27Z Max mtg $ - */ -public final class MenuLimited extends MenuBase { - - /** Constant serialVersionUID=-4037993759604768755L. */ - private static final long serialVersionUID = -4037993759604768755L; - - /** - * Menu for Deck Editor. - * - * @param ctrl the ctrl - * @param exit a Command - */ - public MenuLimited(final DeckController ctrl, final Command exit) { - super(ctrl, exit); - } - - // deck.setName(currentDeckName); - -} diff --git a/src/main/java/forge/gui/deckeditor/MenuQuest.java b/src/main/java/forge/gui/deckeditor/MenuQuest.java deleted file mode 100644 index a4c9d89b0a5..00000000000 --- a/src/main/java/forge/gui/deckeditor/MenuQuest.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.gui.deckeditor; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.File; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import javax.swing.JFileChooser; -import javax.swing.JMenu; -import javax.swing.JMenuItem; - -import forge.Command; -import forge.Constant; -import forge.deck.Deck; -import forge.deck.io.DeckSerializer; -import forge.error.ErrorViewer; -import forge.gui.ListChooser; -import forge.item.CardDb; -import forge.item.CardPrinted; - -//presumes AllZone.getQuestData() is not null -/** - *

- * Gui_Quest_DeckEditor_Menu class. - *

- * - * @author Forge - * @version $Id$ - */ -public class MenuQuest extends MenuBase { - /** Constant serialVersionUID=-4052319220021158574L. */ - private static final long serialVersionUID = -4052319220021158574L; - - // used for import and export, try to made the gui user friendly - /** Constant previousDirectory. */ - private static File previousDirectory = null; - - /** - *

- * Constructor for Gui_Quest_DeckEditor_Menu. - *

- * - * @param d - * a {@link forge.gui.deckeditor.IDeckDisplay} object. - * @param exit - * a {@link forge.Command} object. - */ - public MenuQuest(final DeckController d, final Command exit) { - super(d, exit); - } - - /** - *

- * importDeck. - *

- */ - private void importDeck() { - final File file = this.getImportFilename(); - - if ((file != null) && file.getName().endsWith(".dck")) { - try { - final Deck newDeck = Deck.fromFile(file); - this.getController().importDeck(newDeck); - - } catch (final Exception ex) { - ErrorViewer.showError(ex); - throw new RuntimeException("Gui_DeckEditor_Menu : importDeck() error, " + ex); - } - } - - } // importDeck() - - /** - *

- * getImportFilename. - *

- * - * @return a {@link java.io.File} object. - */ - private File getImportFilename() { - final JFileChooser chooser = new JFileChooser(MenuQuest.previousDirectory); - - chooser.addChoosableFileFilter(DeckSerializer.DCK_FILTER); - final int returnVal = chooser.showOpenDialog(null); - - if (returnVal == JFileChooser.APPROVE_OPTION) { - final File file = chooser.getSelectedFile(); - MenuQuest.previousDirectory = file.getParentFile(); - return file; - } - - return null; - } // openFileDialog() - - private final ActionListener addCardActionListener = new ActionListener() { - @Override - public void actionPerformed(final ActionEvent a) { - - // Provide a model here: all unique cards to be displayed by only - // name (unlike default toString) - final Iterable uniqueCards = CardDb.instance().getAllUniqueCards(); - final List cards = new ArrayList(); - for (final CardPrinted c : uniqueCards) { - cards.add(c.getName()); - } - Collections.sort(cards); - - // use standard forge's list selection dialog - final ListChooser c = new ListChooser("Cheat - Add Card to Your Cardpool", 0, 1, cards); - if (c.show()) { - ((DeckEditorQuest) MenuQuest.this.getController().getView()).addCheatCard(CardDb.instance().getCard( - c.getSelectedValue())); - } - } - }; - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.MenuBase#getDefaultFileMenu() - */ - @Override - protected JMenu getDefaultFileMenu() { - final JMenu deckMenu = super.getDefaultFileMenu(); - - final JMenuItem addCard = new JMenuItem("Cheat - Add Card"); - - addCard.addActionListener(this.addCardActionListener); - - if (Constant.Runtime.DEV_MODE[0]) { - deckMenu.addSeparator(); - deckMenu.add(addCard); - } - - deckMenu.addSeparator(); - this.addImportExport(deckMenu, true); - - this.appendCloseMenuItemTo(deckMenu); - return deckMenu; - - } - - /** - *

- * addImportExport. - *

- * - * @param menu - * a {@link javax.swing.JMenu} object. - * @param isHumanMenu - * a boolean. - */ - private void addImportExport(final JMenu menu, final boolean isHumanMenu) { - final JMenuItem import2 = new JMenuItem("Import"); - final JMenuItem export = new JMenuItem("Export"); - - import2.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent a) { - MenuQuest.this.importDeck(); // importDeck(isHumanMenu); - } - }); // import - - export.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent a) { - MenuQuest.this.exportDeck(); - } - }); // export - - menu.add(import2); - menu.add(export); - - } // addImportExport() - - private void exportDeck() { - final File filename = this.getExportFilename(); - if (filename == null) { - return; - } - - try { - DeckSerializer.writeDeck(this.getController().getModel(), filename); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - throw new RuntimeException("Gui_DeckEditor_Menu : exportDeck() error, " + ex); - } - } - - private File getExportFilename() { - final JFileChooser save = new JFileChooser(MenuQuest.previousDirectory); - save.setDialogTitle("Export Deck Filename"); - save.setDialogType(JFileChooser.SAVE_DIALOG); - save.setFileFilter(DeckSerializer.DCK_FILTER); - - if (save.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) { - final File file = save.getSelectedFile(); - final String check = file.getAbsolutePath(); - - MenuQuest.previousDirectory = file.getParentFile(); - - return check.endsWith(".dck") ? file : new File(check + ".dck"); - } - return null; - } - -} diff --git a/src/main/java/forge/gui/deckeditor/PresetColumns.java b/src/main/java/forge/gui/deckeditor/PresetColumns.java deleted file mode 100644 index 364039e3c68..00000000000 --- a/src/main/java/forge/gui/deckeditor/PresetColumns.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.gui.deckeditor; - -import java.util.Map.Entry; -import java.util.regex.Pattern; - -import forge.Singletons; -import forge.card.CardColor; -import forge.card.CardEdition; -import forge.card.CardManaCost; -import forge.card.CardRarity; -import forge.item.CardPrinted; -import forge.item.InventoryItem; -import forge.item.InventoryItemFromSet; -import forge.util.closures.Lambda1; - -/** - * TODO: Write javadoc for this type. - * - */ -public abstract class PresetColumns { - - private static final Pattern AE_FINDER = Pattern.compile("AE", Pattern.LITERAL); - - private static CardManaCost toManaCost(final InventoryItem i) { - return i instanceof CardPrinted ? ((CardPrinted) i).getCard().getManaCost() : CardManaCost.EMPTY; - } - - private static CardColor toColor(final InventoryItem i) { - return i instanceof CardPrinted ? ((CardPrinted) i).getCard().getColor() : CardColor.getNullColor(); - } - - private static String toPTL(final InventoryItem i) { - return i instanceof CardPrinted ? ((CardPrinted) i).getCard().getPTorLoyalty() : ""; - } - - private static CardRarity toRarity(final InventoryItem i) { - return i instanceof CardPrinted ? ((CardPrinted) i).getRarity() : CardRarity.Unknown; - } - - private static CardEdition toSetCmp(final InventoryItem i) { - return i instanceof InventoryItemFromSet ? Singletons.getModel().getEditions() - .get(((InventoryItemFromSet) i).getEdition()) : CardEdition.UNKNOWN; - } - - private static String toSetStr(final InventoryItem i) { - return i instanceof InventoryItemFromSet ? ((InventoryItemFromSet) i).getEdition() : "n/a"; - } - - private static Integer toAiCmp(final InventoryItem i) { - return i instanceof CardPrinted ? ((CardPrinted) i).getCard().getAiStatusComparable() : Integer.valueOf(-1); - } - - private static String toAiStr(final InventoryItem i) { - return i instanceof CardPrinted ? ((CardPrinted) i).getCard().getAiStatus() : "n/a"; - } - - /** The Constant fnQtyCompare. */ - @SuppressWarnings("rawtypes") - public static final Lambda1> FN_QTY_COMPARE = new Lambda1>() { - @Override - public Comparable apply(final Entry from) { - return from.getValue(); - } - }; - - /** The Constant fnQtyGet. */ - public static final Lambda1> FN_QTY_GET = new Lambda1>() { - @Override - public Object apply(final Entry from) { - return from.getValue(); - } - }; - - /** The Constant fnNameCompare. */ - @SuppressWarnings("rawtypes") - public static final Lambda1> FN_NAME_COMPARE = new Lambda1>() { - @Override - public Comparable apply(final Entry from) { - return from.getKey().getName(); - } - }; - - /** The Constant fnNameGet. */ - public static final Lambda1> FN_NAME_GET = new Lambda1>() { - @Override - public Object apply(final Entry from) { - final String name = from.getKey().getName(); - return name.contains("AE") ? PresetColumns.AE_FINDER.matcher(name).replaceAll("\u00C6") : name; - } - }; - - /** The Constant fnCostCompare. */ - @SuppressWarnings("rawtypes") - public static final Lambda1> FN_COST_COMPARE = new Lambda1>() { - @Override - public Comparable apply(final Entry from) { - return PresetColumns.toManaCost(from.getKey()); - } - }; - - /** The Constant fnCostGet. */ - public static final Lambda1> FN_COST_GET = new Lambda1>() { - @Override - public Object apply(final Entry from) { - return PresetColumns.toManaCost(from.getKey()); - } - }; - - /** The Constant fnColorCompare. */ - @SuppressWarnings("rawtypes") - public static final Lambda1> FN_COLOR_COMPARE = new Lambda1>() { - @Override - public Comparable apply(final Entry from) { - return PresetColumns.toColor(from.getKey()); - } - }; - - /** The Constant fnColorGet. */ - public static final Lambda1> FN_COLOR_GET = new Lambda1>() { - @Override - public Object apply(final Entry from) { - return PresetColumns.toColor(from.getKey()); - } - }; - - /** The Constant fnTypeCompare. */ - @SuppressWarnings("rawtypes") - public static final Lambda1> FN_TYPE_COMPARE = new Lambda1>() { - @Override - public Comparable apply(final Entry from) { - return from.getKey().getType(); - } - }; - - /** The Constant fnTypeGet. */ - public static final Lambda1> FN_TYPE_GET = new Lambda1>() { - @Override - public Object apply(final Entry from) { - return from.getKey().getType(); - } - }; - - /** The Constant fnStatsCompare. */ - @SuppressWarnings("rawtypes") - public static final Lambda1> FN_STATS_COMPARE = new Lambda1>() { - @Override - public Comparable apply(final Entry from) { - return PresetColumns.toPTL(from.getKey()); - } - }; - - /** The Constant fnStatsGet. */ - public static final Lambda1> FN_STATS_GET = new Lambda1>() { - @Override - public Object apply(final Entry from) { - return PresetColumns.toPTL(from.getKey()); - } - }; - - /** The Constant fnRarityCompare. */ - @SuppressWarnings("rawtypes") - public static final Lambda1> FN_RARITY_COMPARE = new Lambda1>() { - @Override - public Comparable apply(final Entry from) { - return PresetColumns.toRarity(from.getKey()); - } - }; - - /** The Constant fnRarityGet. */ - public static final Lambda1> FN_RARITY_GET = new Lambda1>() { - @Override - public Object apply(final Entry from) { - return PresetColumns.toRarity(from.getKey()); - } - }; - - /** The Constant fnSetCompare. */ - @SuppressWarnings("rawtypes") - public static final Lambda1> FN_SET_COMPARE = new Lambda1>() { - @Override - public Comparable apply(final Entry from) { - return PresetColumns.toSetCmp(from.getKey()); - } - }; - - /** The Constant fnSetGet. */ - public static final Lambda1> FN_SET_GET = new Lambda1>() { - @Override - public Object apply(final Entry from) { - return PresetColumns.toSetStr(from.getKey()); - } - }; - - /** The Constant fnAiStatusCompare. */ - @SuppressWarnings("rawtypes") - public static final Lambda1> FN_AI_STATUS_COMPARE = new Lambda1>() { - @Override - public Comparable apply(final Entry from) { - return PresetColumns.toAiCmp(from.getKey()); - } - }; - - /** The Constant fnAiStatusGet. */ - public static final Lambda1> FN_AI_STATUS_GET = new Lambda1>() { - @Override - public Object apply(final Entry from) { - return PresetColumns.toAiStr(from.getKey()); - } - }; -} diff --git a/src/main/java/forge/gui/deckeditor/QuestCardShop.java b/src/main/java/forge/gui/deckeditor/QuestCardShop.java deleted file mode 100644 index f75354c505f..00000000000 --- a/src/main/java/forge/gui/deckeditor/QuestCardShop.java +++ /dev/null @@ -1,530 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.gui.deckeditor; - -import java.awt.Container; -import java.awt.Font; -import java.awt.event.ActionEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.text.DecimalFormat; -import java.text.NumberFormat; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JOptionPane; - - -import forge.Command; -import forge.deck.Deck; -import forge.deck.DeckBase; -import forge.error.ErrorViewer; -import forge.gui.CardListViewer; -import forge.gui.deckeditor.elements.CardPanelLite; -import forge.gui.deckeditor.elements.FilterCheckBoxes; -import forge.gui.deckeditor.elements.FilterNameTypeSetPanel; -import forge.gui.deckeditor.elements.ManaCostRenderer; -import forge.gui.deckeditor.elements.TableColumnInfo; -import forge.gui.deckeditor.elements.TableView; -import forge.item.BoosterPack; -import forge.item.CardPrinted; -import forge.item.FatPack; -import forge.item.InventoryItem; -import forge.item.ItemPool; -import forge.item.ItemPoolView; -import forge.item.ItemPredicate; -import forge.item.OpenablePack; -import forge.item.PreconDeck; -import forge.item.TournamentPack; -import forge.quest.QuestController; -import forge.quest.io.ReadPriceList; -import forge.util.closures.Lambda1; -import forge.util.closures.Predicate; -import net.miginfocom.swing.MigLayout; - -/** - *

- * Gui_CardShop class. - *

- * - * @author Forge - * @version $Id$ - */ -public final class QuestCardShop extends DeckEditorBase { - /** Constant serialVersionUID=3988857075791576483L. */ - private static final long serialVersionUID = 3988857075791576483L; - - private final JButton clearFilterButton = new JButton(); - private FilterNameTypeSetPanel filterNameTypeSet; - - private final JButton buyButton = new JButton(); - private final JButton sellButton = new JButton(); - - private final JLabel creditsLabel = new JLabel(); - private final JLabel sellPercentageLabel = new JLabel(); - - private double multiplier; - - private final QuestController questData; - - // get pricelist: - private final ReadPriceList r = new ReadPriceList(); - private final Map mapPrices = this.r.getPriceList(); - private Map decksUsingMyCards; - - /** - * Show. - * - * @param exitCommand - * the exit command - */ - @Override - public void show(final Command exitCommand) { - final Command exit = new Command() { - private static final long serialVersionUID = -7428793574300520612L; - - @Override - public void execute() { - QuestCardShop.this.dispose(); - exitCommand.execute(); - } - }; - - // do not change this!!!! - this.addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(final WindowEvent ev) { - exit.execute(); - } - }); - - this.setup(); - - this.decksUsingMyCards = this.countDecksForEachCard(); - - this.multiplier = this.questData.getCards().getSellMutliplier(); - - ItemPoolView forSale = this.questData.getCards().getShopList(); - if (forSale.isEmpty()) { - this.questData.getCards().generateCardsInShop(); - forSale = this.questData.getCards().getShopList(); - } - // newCardsList = questData.getCards().getNewCards(); - final ItemPool ownedItems = new ItemPool(InventoryItem.class); - ownedItems.addAll(this.questData.getCards().getCardpool().getView()); - - this.getTopTableModel().setDeck(forSale); - this.getBottomTableWithCards().setDeck(ownedItems); - - this.creditsLabel.setText("Credits: " + this.questData.getAssets().getCredits()); - - final double multiPercent = this.multiplier * 100; - final NumberFormat formatter = new DecimalFormat("#0.00"); - String maxSellingPrice = ""; - final int maxSellPrice = this.questData.getCards().getSellPriceLimit(); - - if (maxSellPrice < Integer.MAX_VALUE) { - maxSellingPrice = String.format("Maximum selling price is %d credits.", maxSellPrice); - } - this.sellPercentageLabel.setText("Selling cards at " + formatter.format(multiPercent) - + "% of their value.
" + maxSellingPrice + ""); - - this.filterNameTypeSet.setListeners(new OnChangeTextUpdateDisplay(), this.getItemListenerUpdatesDisplay()); - - this.getTopTableWithCards().sort(1, true); - this.getBottomTableWithCards().sort(1, true); - } // show(Command) - - // fills number of decks using each card - private Map countDecksForEachCard() { - final Map result = new HashMap(); - for (final Deck deck : this.questData.getMyDecks()) { - for (final Entry e : deck.getMain()) { - final CardPrinted card = e.getKey(); - final Integer amount = result.get(card); - result.put(card, Integer.valueOf(amount == null ? 1 : 1 + amount.intValue())); - } - } - return result; - } - - /** - *

- * setup. - *

- */ - private void setup() { - final List> columns = new ArrayList>(); - columns.add(new TableColumnInfo("Qty", 30, PresetColumns.FN_QTY_COMPARE, - PresetColumns.FN_QTY_GET)); - columns.add(new TableColumnInfo("Name", 176, PresetColumns.FN_NAME_COMPARE, - PresetColumns.FN_NAME_GET)); - columns.add(new TableColumnInfo("Cost", 70, PresetColumns.FN_COST_COMPARE, - PresetColumns.FN_COST_GET)); - columns.add(new TableColumnInfo("Color", 50, PresetColumns.FN_COLOR_COMPARE, - PresetColumns.FN_COLOR_GET)); - columns.add(new TableColumnInfo("Type", 100, PresetColumns.FN_TYPE_COMPARE, - PresetColumns.FN_TYPE_GET)); - columns.add(new TableColumnInfo("Stats", 40, PresetColumns.FN_STATS_COMPARE, - PresetColumns.FN_STATS_GET)); - columns.add(new TableColumnInfo("R", 25, PresetColumns.FN_RARITY_COMPARE, - PresetColumns.FN_RARITY_GET)); - columns.add(new TableColumnInfo("Set", 35, PresetColumns.FN_SET_COMPARE, - PresetColumns.FN_SET_GET)); - columns.get(2).setCellRenderer(new ManaCostRenderer()); - - final List> columnsBelow = new ArrayList>(columns); - columns.add(new TableColumnInfo("Price", 45, this.fnPriceCompare, this.fnPriceGet)); - this.getTopTableWithCards().setup(columns, this.getCardView()); - - columnsBelow.add(new TableColumnInfo("Dks", 30, this.fnDeckCompare, this.fnDeckGet)); - columnsBelow.add(new TableColumnInfo("New", 35, this.questData.getCards().getFnNewCompare(), - this.questData.getCards().getFnNewGet())); - columnsBelow.add(new TableColumnInfo("Price", 45, this.fnPriceCompare, this.fnPriceSellGet)); - this.getBottomTableWithCards().setup(columnsBelow, this.getCardView()); - - this.setSize(1024, 740); - } - - /** - *

- * Constructor for Gui_CardShop. - *

- * - * @param parent the parent frame for this deck editor instance - * @param qd - * a {@link forge.quest.data.QuestData} object. - */ - public QuestCardShop(JFrame parent, final QuestController qd) { - super(parent); - this.questData = qd; - try { - this.setFilterBoxes(new FilterCheckBoxes(true)); - this.setTopTableWithCards(new TableView("Cards for sale", false, false, InventoryItem.class)); - this.setBottomTableWithCards(new TableView("Owned Cards", false, InventoryItem.class)); - this.setCardView(new CardPanelLite()); - this.filterNameTypeSet = new FilterNameTypeSetPanel(); - this.jbInit(); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - } - } - - /** - *

- * jbInit. - *

- * - * @throws java.lang.Exception - * if any. - */ - private void jbInit() throws Exception { - - final Font font = new java.awt.Font("Dialog", 0, 13); - this.clearFilterButton.setFont(font); - this.buyButton.setFont(font); - this.sellButton.setFont(font); - this.creditsLabel.setFont(font); - this.sellPercentageLabel.setFont(font); - - this.clearFilterButton.setText("Clear Filter"); - this.buyButton.setText("Buy Card"); - this.sellButton.setText("Sell Card"); - - this.clearFilterButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - QuestCardShop.this.clearFilterButtonActionPerformed(e); - } - }); - this.buyButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - QuestCardShop.this.buyButtonActionPerformed(e); - } - }); - this.sellButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - QuestCardShop.this.sellButtonActionPerformed(e); - } - }); - - // Type filtering - final Font f = new Font("Tahoma", Font.PLAIN, 10); - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - box.setFont(f); - box.setOpaque(false); - } - - // Color filtering - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - box.setOpaque(false); - } - - this.setTitle("Card Shop"); - - final Container content = this.getContentPane(); - final MigLayout layout = new MigLayout("fill"); - content.setLayout(layout); - - boolean isFirst = true; - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - String growParameter = "grow"; - if (isFirst) { - growParameter = "cell 0 0, egx checkbox, grow, split 14"; - isFirst = false; - } - content.add(box, growParameter); - box.addItemListener(this.getItemListenerUpdatesDisplay()); - } - - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - content.add(box, "grow"); - box.addItemListener(this.getItemListenerUpdatesDisplay()); - } - - content.add(this.clearFilterButton, "wmin 100, hmin 25, wmax 140, hmax 25, grow"); - - content.add(this.filterNameTypeSet, "cell 0 1, grow"); - content.add(this.getTopTableWithCards().getTableDecorated(), "cell 0 2 1 2, push, grow"); - - content.add(this.buyButton, "w 100, h 49, sg button, cell 0 5, split 5"); - content.add(this.sellButton, "w 100, h 49, sg button"); - - content.add(this.creditsLabel, "w 100, h 49"); - content.add(this.sellPercentageLabel, "w 300, h 49, wrap"); - - content.add(this.getBottomTableWithCards().getTableDecorated(), "cell 0 6, grow"); - - content.add(this.getCardView(), "cell 1 0 1 7, flowy, grow"); - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#buildFilter() - */ - @Override - protected Predicate buildFilter() { - final Predicate cardFilter = Predicate.and( - this.getFilterBoxes().buildFilter(), - this.filterNameTypeSet.buildFilter()); - - // Until this is filterable, always show packs and decks in the card shop - Predicate filter = Predicate.instanceOf(cardFilter, CardPrinted.class); - filter = Predicate.or(filter, ItemPredicate.Presets.IS_PACK); - filter = Predicate.or(filter, ItemPredicate.Presets.IS_DECK); - - return filter; - } - - /** - * Clear filter button_action performed. - * - * @param e - * the e - */ - void clearFilterButtonActionPerformed(final ActionEvent e) { - // disable automatic update triggered by listeners - this.setFiltersChangeFiringUpdate(false); - - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - if (!box.isSelected()) { - box.doClick(); - } - } - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - if (!box.isSelected()) { - box.doClick(); - } - } - - this.filterNameTypeSet.clearFilters(); - - this.setFiltersChangeFiringUpdate(true); - - this.getTopTableWithCards().setFilter(null); - } - - // TODO: move to cardshop - private Integer getCardValue(final InventoryItem card) { - if (this.mapPrices.containsKey(card.getName())) { - return this.mapPrices.get(card.getName()); - } else if (card instanceof CardPrinted) { - switch (((CardPrinted) card).getRarity()) { - case BasicLand: - return Integer.valueOf(4); - case Common: - return Integer.valueOf(6); - case Uncommon: - return Integer.valueOf(40); - case Rare: - return Integer.valueOf(120); - case MythicRare: - return Integer.valueOf(600); - default: - return Integer.valueOf(15); - } - } else if (card instanceof BoosterPack) { - return 395; - } else if (card instanceof TournamentPack) { - return 995; - } else if (card instanceof FatPack) { - return 2365; - } else if (card instanceof PreconDeck) { - return ((PreconDeck) card).getRecommendedDeals().getCost(); - } - return 1337; - } - - private void buyButtonActionPerformed(final ActionEvent e) { - final InventoryItem item = this.getTopTableWithCards().getSelectedCard(); - if (item == null) { - return; - } - - final int value = this.getCardValue(item); - - if (value <= this.questData.getAssets().getCredits()) { - - if (item instanceof CardPrinted) { - this.getTopTableWithCards().removeCard(item); - - final CardPrinted card = (CardPrinted) item; - this.getBottomTableWithCards().addCard(card); - this.questData.getCards().buyCard(card, value); - - } else if (item instanceof OpenablePack) { - this.getTopTableWithCards().removeCard(item); - - OpenablePack booster = null; - if (item instanceof BoosterPack) { - booster = (BoosterPack) ((BoosterPack) item).clone(); - } else if (item instanceof TournamentPack) { - booster = (TournamentPack) ((TournamentPack) item).clone(); - } else if (item instanceof FatPack) { - booster = (FatPack) ((FatPack) item).clone(); - } - this.questData.getCards().buyPack(booster, value); - final List newCards = booster.getCards(); - for (final CardPrinted card : newCards) { - this.getBottomTableWithCards().addCard(card); - } - final CardListViewer c = new CardListViewer(booster.getName(), - "You have found the following cards inside:", newCards); - c.show(); - } else if (item instanceof PreconDeck) { - this.getTopTableWithCards().removeCard(item); - final PreconDeck deck = (PreconDeck) item; - this.questData.getCards().buyPreconDeck(deck, value); - - for (final CardPrinted card : deck.getDeck().getMain().toFlatList()) { - this.getBottomTableWithCards().addCard(card); - } - JOptionPane.showMessageDialog(null, String.format( - "Deck '%s' was added to your decklist.%n%nCards from it were also added to your pool.", - deck.getName()), "Thanks for purchasing!", JOptionPane.INFORMATION_MESSAGE); - - } - - this.creditsLabel.setText("Credits: " + this.questData.getAssets().getCredits()); - } else { - JOptionPane.showMessageDialog(null, "Not enough credits!"); - } - } - - private void sellButtonActionPerformed(final ActionEvent e) { - final InventoryItem item = this.getBottomTableWithCards().getSelectedCard(); - if ((item == null) || !(item instanceof CardPrinted)) { - return; - } - - final CardPrinted card = (CardPrinted) item; - this.getBottomTableWithCards().removeCard(card); - this.getTopTableWithCards().addCard(card); - - final int price = Math.min((int) (this.multiplier * this.getCardValue(card)), this.questData.getCards() - .getSellPriceLimit()); - this.questData.getCards().sellCard(card, price); - - this.creditsLabel.setText("Credits: " + this.questData.getAssets().getCredits()); - } - - @SuppressWarnings("rawtypes") - private final Lambda1> fnPriceCompare = new Lambda1>() { - @Override - public Comparable apply(final Entry from) { - return QuestCardShop.this.getCardValue(from.getKey()); - } - }; - private final Lambda1> fnPriceGet = new Lambda1>() { - @Override - public Object apply(final Entry from) { - return QuestCardShop.this.getCardValue(from.getKey()); - } - }; - private final Lambda1> fnPriceSellGet = new Lambda1>() { - @Override - public Object apply(final Entry from) { - return (int) (QuestCardShop.this.multiplier * QuestCardShop.this.getCardValue(from.getKey())); - } - }; - - @SuppressWarnings("rawtypes") - private final Lambda1> fnDeckCompare = new Lambda1>() { - @Override - public Comparable apply(final Entry from) { - final Integer iValue = QuestCardShop.this.decksUsingMyCards.get(from.getKey()); - return iValue == null ? Integer.valueOf(0) : iValue; - } - }; - private final Lambda1> fnDeckGet = new Lambda1>() { - @Override - public Object apply(final Entry from) { - final Integer iValue = QuestCardShop.this.decksUsingMyCards.get(from.getKey()); - return iValue == null ? "" : iValue.toString(); - } - }; - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#getController() - */ - @Override - public DeckController getController() { - return null; - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#updateView() - */ - @Override - public void updateView() { - } - -} diff --git a/src/main/java/forge/gui/deckeditor/SEditorIO.java b/src/main/java/forge/gui/deckeditor/SEditorIO.java new file mode 100644 index 00000000000..568556cc2cf --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/SEditorIO.java @@ -0,0 +1,303 @@ +package forge.gui.deckeditor; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; + +import javax.swing.JOptionPane; +import javax.xml.stream.XMLEventFactory; +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLEventWriter; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.events.Attribute; +import javax.xml.stream.events.StartElement; +import javax.xml.stream.events.XMLEvent; + +import forge.deck.DeckBase; +import forge.gui.deckeditor.tables.DeckController; +import forge.gui.deckeditor.tables.SColumnUtil; +import forge.gui.deckeditor.tables.SColumnUtil.ColumnName; +import forge.gui.deckeditor.tables.SColumnUtil.SortState; +import forge.gui.deckeditor.tables.TableColumnInfo; +import forge.gui.deckeditor.views.VCurrentDeck; +import forge.item.InventoryItem; +import forge.properties.NewConstants; + +/** + * Handles editor preferences saving and loading. + * + *

(S at beginning of class name denotes a static factory.) + */ +public class SEditorIO { + /** Used in the XML IO to extract properties from PREFS file. */ + private enum ColumnProperty { /** */ + enumval, /** */ + identifier, /** */ + index, /** */ + show, /** */ + sortpriority, /** */ + sortstate, /** */ + width + } + + /** Preferences (must match with PREFS file). */ + public enum EditorPreference { /** */ + stats_deck, /** */ + stats_catalog + } + + private static final XMLEventFactory EVENT_FACTORY = XMLEventFactory.newInstance(); + private static final XMLEvent NEWLINE = EVENT_FACTORY.createDTD("\n"); + private static final XMLEvent TAB = EVENT_FACTORY.createDTD("\t"); + + private static final Map PREFS + = new HashMap(); + + private static final Map> COLS + = new TreeMap>(); + + /** + * Retrieve a preference from the editor preference map. + * + * @param name0   {@link forge.gui.deckeditor.SEditorUtil.EditorPreference} + * @return TableColumnInfo + */ + public static boolean getPref(final EditorPreference name0) { + return PREFS.get(name0); + } + + /** + * Set a preference in the editor preference map. + * + * @param name0   {@link forge.gui.deckeditor.SEditorUtil.EditorPreference} + * @param val0   boolean + */ + public static void setPref(final EditorPreference name0, final boolean val0) { + PREFS.put(name0, val0); + } + + /** + * Retrieve a custom column. + * + * @param name0   {@link forge.gui.deckeditor.SEditorUtil.CatalogColumnName} + * @return TableColumnInfo + */ + public static TableColumnInfo getColumn(final ColumnName name0) { + return COLS.get(name0); + } + + /** + * Saves the current deck, with various prompts depending on the + * current save environment. + * + * @return boolean, true if success + */ + @SuppressWarnings("unchecked") + public static boolean saveDeck() { + final DeckController controller = (DeckController) CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().getDeckController(); + final String name = VCurrentDeck.SINGLETON_INSTANCE.getTxfTitle().getText(); + + // Warn if no name + if (name.equals("[New Deck]") || name.isEmpty()) { + JOptionPane.showMessageDialog(null, + "Please name your deck using the 'Title' box.", + "Save Error!", + JOptionPane.ERROR_MESSAGE); + return false; + } + // Confirm if overwrite + else if (controller.fileExists(name)) { + final int m = JOptionPane.showConfirmDialog(null, + "There is already a deck named '" + name + "'. Overwrite?", + "Overwrite Deck?", + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE); + + if (m == JOptionPane.YES_OPTION) { controller.save(); } + VCurrentDeck.SINGLETON_INSTANCE.getTabLabel().setText("Current Deck"); + } + // Confirm if a new deck will be created + else { + final int m = JOptionPane.showConfirmDialog(null, + "This will create a new deck named '" + name + "'. Continue?", + "Create Deck?", + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE); + + if (m == JOptionPane.YES_OPTION) { controller.saveAs(name); } + VCurrentDeck.SINGLETON_INSTANCE.getTabLabel().setText("Current Deck"); + } + + return true; + } + + /** + * Prompts to save changes if necessary. + * + * @return boolean, true if success + */ + @SuppressWarnings("unchecked") + public static boolean confirmSaveChanges() { + if (!((DeckController) CDeckEditorUI + .SINGLETON_INSTANCE.getCurrentEditorController().getDeckController()).isSaved()) { + final int choice = JOptionPane.showConfirmDialog(null, + "Save changes to current deck?", + "Save Changes?", + JOptionPane.YES_NO_CANCEL_OPTION, + JOptionPane.QUESTION_MESSAGE); + + if (choice == JOptionPane.CANCEL_OPTION) { return false; } + + if (choice == JOptionPane.YES_OPTION && !saveDeck()) { return false; } + } + + return true; + } + + /** Publicly-accessible save method, to neatly handle exception handling. */ + public static void savePreferences() { + try { save(); } + catch (final Exception e) { e.printStackTrace(); } + } + + /** Publicly-accessible load method, to neatly handle exception handling. */ + public static void loadPreferences() { + try { load(); } + catch (final Exception e) { e.printStackTrace(); } + } + + /** + * + * TODO: Write javadoc for this method. + * + * @param extends InventoryItem + * @param extends DeckBase + */ + private static void save() throws Exception { + final XMLOutputFactory out = XMLOutputFactory.newInstance(); + final XMLEventWriter writer = out.createXMLEventWriter(new FileOutputStream(NewConstants.PREFERENCES_FILE_EDITOR)); + + writer.add(EVENT_FACTORY.createStartDocument()); + writer.add(NEWLINE); + writer.add(EVENT_FACTORY.createStartElement("", "", "preferences")); + writer.add(EVENT_FACTORY.createAttribute("type", "editor")); + writer.add(NEWLINE); + + for (final EditorPreference p : PREFS.keySet()) { + writer.add(TAB); + writer.add(EVENT_FACTORY.createStartElement("", "", "pref")); + writer.add(EVENT_FACTORY.createAttribute( + "name", p.toString())); + writer.add(EVENT_FACTORY.createAttribute( + "value", PREFS.get(p).toString())); + writer.add(EVENT_FACTORY.createEndElement("", "", "pref")); + writer.add(NEWLINE); + } + + for (final ColumnName c : COLS.keySet()) { + // If column is not in view, retain previous model index for the next time + // that the column will be in the view. + int index = SColumnUtil.getColumnViewIndex(c); + if (index == -1) { + index = COLS.get(c).getModelIndex(); + } + + writer.add(TAB); + writer.add(EVENT_FACTORY.createStartElement("", "", "col")); + writer.add(EVENT_FACTORY.createAttribute( + ColumnProperty.enumval.toString(), COLS.get(c).getEnumValue())); + writer.add(EVENT_FACTORY.createAttribute( + ColumnProperty.identifier.toString(), COLS.get(c).getIdentifier().toString())); + writer.add(EVENT_FACTORY.createAttribute( + ColumnProperty.index.toString(), String.valueOf(index))); + writer.add(EVENT_FACTORY.createAttribute( + ColumnProperty.show.toString(), String.valueOf(COLS.get(c).isShowing()))); + writer.add(EVENT_FACTORY.createAttribute( + ColumnProperty.sortpriority.toString(), String.valueOf(COLS.get(c).getSortPriority()))); + writer.add(EVENT_FACTORY.createAttribute( + ColumnProperty.sortstate.toString(), String.valueOf(COLS.get(c).getSortState()))); + writer.add(EVENT_FACTORY.createAttribute( + ColumnProperty.width.toString(), String.valueOf(COLS.get(c).getWidth()))); + writer.add(EVENT_FACTORY.createEndElement("", "", "col")); + writer.add(NEWLINE); + } + + writer.add(EVENT_FACTORY.createEndDocument()); + writer.flush(); + writer.close(); + } + + private static void load() throws Exception { + final XMLInputFactory inputFactory = XMLInputFactory.newInstance(); + final String fileAddress = NewConstants.PREFERENCES_FILE_EDITOR; + final XMLEventReader reader = inputFactory.createXMLEventReader(new FileInputStream(fileAddress)); + + PREFS.clear(); + COLS.clear(); + + XMLEvent event; + StartElement element; + Iterator attributes; + Attribute attribute; + EditorPreference pref; + TableColumnInfo tempcol; + String tagname; + + while (reader.hasNext()) { + event = reader.nextEvent(); + + if (event.isStartElement()) { + element = event.asStartElement(); + tagname = element.getName().getLocalPart(); + + // Assemble preferences + if (tagname.equals("pref")) { + // Retrieve name of pref + attributes = element.getAttributes(); + pref = EditorPreference.valueOf(((Attribute) attributes.next()).getValue()); + + // Add to map + PREFS.put(pref, Boolean.valueOf(((Attribute) attributes.next()).getValue())); + } + // Assemble columns + else if (tagname.equals("col")) { + attributes = element.getAttributes(); + tempcol = new TableColumnInfo(); + + while (attributes.hasNext()) { + attribute = (Attribute) attributes.next(); + if (attribute.getName().toString().equals(ColumnProperty.enumval.toString())) { + COLS.put(ColumnName.valueOf(attribute.getValue()), tempcol); + tempcol.setEnumValue(attribute.getValue()); + } + else if (attribute.getName().toString().equals(ColumnProperty.identifier.toString())) { + tempcol.setIdentifier(attribute.getValue()); + tempcol.setHeaderValue(attribute.getValue()); + } + else if (attribute.getName().toString().equals(ColumnProperty.width.toString())) { + tempcol.setPreferredWidth(Integer.valueOf(attribute.getValue())); + } + else if (attribute.getName().toString().equals(ColumnProperty.show.toString())) { + tempcol.setShowing(Boolean.valueOf(attribute.getValue())); + } + else if (attribute.getName().toString().equals(ColumnProperty.sortpriority.toString())) { + tempcol.setSortPriority(Integer.valueOf(attribute.getValue())); + } + else if (attribute.getName().toString().equals(ColumnProperty.sortstate.toString())) { + tempcol.setSortState(SortState.valueOf(attribute.getValue().toString())); + } + else if (attribute.getName().toString().equals(ColumnProperty.index.toString())) { + tempcol.setModelIndex(Integer.valueOf(attribute.getValue())); + } + } + } + } + } + + SColumnUtil.attachSortAndDisplayFunctions(); + } +} diff --git a/src/main/java/forge/gui/deckeditor/SEditorUtil.java b/src/main/java/forge/gui/deckeditor/SEditorUtil.java new file mode 100644 index 00000000000..081cfd21d71 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/SEditorUtil.java @@ -0,0 +1,149 @@ +package forge.gui.deckeditor; + +import javax.swing.ImageIcon; + +import forge.card.CardRules; +import forge.gui.deckeditor.views.ITableContainer; +import forge.gui.deckeditor.views.VCardCatalog; +import forge.gui.deckeditor.views.VCurrentDeck; +import forge.gui.toolbox.FSkin; +import forge.item.InventoryItem; +import forge.item.ItemPoolView; + +/** + * Static methods for working with top-level editor methods, + * included but not limited to preferences IO, icon generation, + * and stats analysis. + * + *

+ * (S at beginning of class name denotes a static factory.) + * + */ +public final class SEditorUtil { + /** Pre-cached resized version. */ + public static final ImageIcon ICO_ARTIFACT = + new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_ARTIFACT, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_CREATURE = + new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_CREATURE, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_ENCHANTMENT = + new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_ENCHANTMENT, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_INSTANT = + new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_INSTANT, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_LAND = + new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_LAND, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_PLANESWALKER = + new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_PLANESWALKER, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_SORCERY = + new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_SORCERY, 18, 18)); + + /** Pre-cached resized version. */ + public static final ImageIcon ICO_TOTAL = + new ImageIcon(FSkin.getImage(FSkin.ZoneImages.ICO_HAND, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_MULTI = + new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_MULTI, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_BLACK = + new ImageIcon(FSkin.getImage(FSkin.ManaImages.IMG_BLACK, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_BLUE = + new ImageIcon(FSkin.getImage(FSkin.ManaImages.IMG_BLUE, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_GREEN = + new ImageIcon(FSkin.getImage(FSkin.ManaImages.IMG_GREEN, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_RED = + new ImageIcon(FSkin.getImage(FSkin.ManaImages.IMG_RED, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_WHITE = + new ImageIcon(FSkin.getImage(FSkin.ManaImages.IMG_WHITE, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_COLORLESS = + new ImageIcon(FSkin.getImage(FSkin.ColorlessManaImages.IMG_X, 18, 18)); + + /** + * Divides X by Y, multiplies by 100, rounds, returns. + * + * @param x0   Numerator (int) + * @param y0   Denominator (int) + * @return rounded result (int) + */ + public static int calculatePercentage(final int x0, final int y0) { + return (int) Math.round((double) x0 / (double) y0 * 100); + } + + /** + * setStats. + * + * @param   the generic type + * @param deck   ItemPoolView + * @param view   {@link forge.gui.deckeditor.views.ITableContainer} + */ + public static void setStats(final ItemPoolView deck, final ITableContainer view) { + view.getLblTotal().setText(String.valueOf(deck.countAll())); + + view.getLblCreature().setText(String.valueOf(CardRules.Predicates.Presets + .IS_CREATURE.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblLand().setText(String.valueOf(CardRules.Predicates.Presets + .IS_LAND.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblEnchantment().setText(String.valueOf(CardRules.Predicates.Presets + .IS_ENCHANTMENT.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblArtifact().setText(String.valueOf(CardRules.Predicates.Presets + .IS_ARTIFACT.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblInstant().setText(String.valueOf(CardRules.Predicates.Presets + .IS_INSTANT.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblSorcery().setText(String.valueOf(CardRules.Predicates.Presets + .IS_SORCERY.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblPlaneswalker().setText(String.valueOf(CardRules.Predicates.Presets + .IS_PLANESWALKER.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblColorless().setText(String.valueOf(CardRules.Predicates.Presets + .IS_COLORLESS.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblBlack().setText(String.valueOf(CardRules.Predicates.Presets + .IS_BLACK.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblBlue().setText(String.valueOf(CardRules.Predicates.Presets + .IS_BLUE.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblGreen().setText(String.valueOf(CardRules.Predicates.Presets + .IS_GREEN.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblRed().setText(String.valueOf(CardRules.Predicates.Presets + .IS_RED.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblWhite().setText(String.valueOf(CardRules.Predicates.Presets + .IS_WHITE.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + } // getStats() + + /** + * Set all components visible that may have been hidden + * by various configurations of the deck editor. + */ + public static void resetUI() { + VCardCatalog.SINGLETON_INSTANCE.getBtnAdd4().setVisible(true); + VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove4().setVisible(true); + + VCurrentDeck.SINGLETON_INSTANCE.getBtnSaveAs().setVisible(true); + VCurrentDeck.SINGLETON_INSTANCE.getBtnNew().setVisible(true); + VCurrentDeck.SINGLETON_INSTANCE.getBtnOpen().setVisible(true); + + VCurrentDeck.SINGLETON_INSTANCE.getTxfTitle().setEnabled(true); + VCardCatalog.SINGLETON_INSTANCE.getLblTitle().setText(""); + + VCurrentDeck.SINGLETON_INSTANCE.getPnlHeader().setVisible(true); + VCardCatalog.SINGLETON_INSTANCE.getPnlHeader().setVisible(true); + } +} diff --git a/src/main/java/forge/gui/deckeditor/SFilterUtil.java b/src/main/java/forge/gui/deckeditor/SFilterUtil.java new file mode 100644 index 00000000000..705bbb7e50f --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/SFilterUtil.java @@ -0,0 +1,515 @@ +package forge.gui.deckeditor; + +import java.awt.Graphics; +import java.awt.Image; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.swing.JCheckBox; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import javax.swing.border.EmptyBorder; + +import forge.card.CardEdition; +import forge.card.CardRules; +import forge.game.GameFormat; +import forge.gui.WrapLayout; +import forge.gui.deckeditor.controllers.CFilters; +import forge.gui.deckeditor.views.VFilters; +import forge.item.CardPrinted; +import forge.util.closures.Predicate; +import forge.util.closures.Predicate.ComparableOp; +import forge.util.closures.PredicateString.StringOp; + +/** + * Static factory; holds blocks of form elements and predicates + * which are used in various editing environments. + *

+ * (S at beginning of class name denotes a static factory.) + */ +public class SFilterUtil { + /** An enum to reference checkbox objects in their respective maps. */ + private enum FilterProperty { /** */ + BLACK, /** */ + BLUE, /** */ + COLORLESS, /** */ + GREEN, /** */ + MULTICOLOR, /** */ + RED, /** */ + WHITE, /** */ + + ARTIFACT, /** */ + CREATURE, /** */ + ENCHANTMENT, /** */ + INSTANT, /** */ + LAND, /** */ + PLANESWALKER, /** */ + SORCERY + } + + private static final Map MAP_COLOR_CHECKBOXES = + new HashMap(); + + private static final Map MAP_TYPE_CHECKBOXES = + new HashMap(); + + /** + + */ + private static boolean preventFiltering = false; + + /** + * This will prevent a filter event on a checkbox state change. + * It's used for programmatic changes to the checkboxes when rebuilding + * the filter each time is expensive. + * + * @return boolean   true if filtering is prevented + */ + public static boolean isFilteringPrevented() { + return preventFiltering; + } + + /** + * This will prevent a filter event on a checkbox state change. + * It's used for programmatic changes to the checkboxes when rebuilding + * the filter each time is expensive. + * + * @param bool0   true to prevent filtering + */ + public static void setPreventFiltering(final boolean bool0) { + preventFiltering = bool0; + } + + /** + * Fills and returns a JPanel with checkboxes for color filter set. + * + * @return {@link javax.swing.JPanel} + */ + public static JPanel populateColorFilters() { + MAP_COLOR_CHECKBOXES.clear(); + + MAP_COLOR_CHECKBOXES.put(FilterProperty.BLACK, + new ChbPnl(SEditorUtil.ICO_BLACK.getImage())); + MAP_COLOR_CHECKBOXES.put(FilterProperty.MULTICOLOR, + new ChbPnl(SEditorUtil.ICO_MULTI.getImage())); + MAP_COLOR_CHECKBOXES.put(FilterProperty.BLUE, + new ChbPnl(SEditorUtil.ICO_BLUE.getImage())); + MAP_COLOR_CHECKBOXES.put(FilterProperty.BLACK, + new ChbPnl(SEditorUtil.ICO_BLACK.getImage())); + MAP_COLOR_CHECKBOXES.put(FilterProperty.GREEN, + new ChbPnl(SEditorUtil.ICO_GREEN.getImage())); + MAP_COLOR_CHECKBOXES.put(FilterProperty.RED, + new ChbPnl(SEditorUtil.ICO_RED.getImage())); + MAP_COLOR_CHECKBOXES.put(FilterProperty.WHITE, + new ChbPnl(SEditorUtil.ICO_WHITE.getImage())); + MAP_COLOR_CHECKBOXES.put(FilterProperty.COLORLESS, + new ChbPnl(SEditorUtil.ICO_COLORLESS.getImage())); + + + final JPanel pnl = new JPanel(new WrapLayout(SwingConstants.CENTER, 10, 5)); + pnl.setOpaque(false); + + for (FilterProperty p : MAP_COLOR_CHECKBOXES.keySet()) { + pnl.add(MAP_COLOR_CHECKBOXES.get(p)); + } + return pnl; + } + + /** + * Fills and returns a JPanel with checkboxes for color filter set. + * + * @return {@link javax.swing.JPanel} + */ + public static JPanel populateTypeFilters() { + MAP_TYPE_CHECKBOXES.clear(); + + MAP_TYPE_CHECKBOXES.put(FilterProperty.ARTIFACT, + new ChbPnl(SEditorUtil.ICO_ARTIFACT.getImage())); + MAP_TYPE_CHECKBOXES.put(FilterProperty.CREATURE, + new ChbPnl(SEditorUtil.ICO_CREATURE.getImage())); + MAP_TYPE_CHECKBOXES.put(FilterProperty.ENCHANTMENT, + new ChbPnl(SEditorUtil.ICO_ENCHANTMENT.getImage())); + MAP_TYPE_CHECKBOXES.put(FilterProperty.INSTANT, + new ChbPnl(SEditorUtil.ICO_INSTANT.getImage())); + MAP_TYPE_CHECKBOXES.put(FilterProperty.LAND, + new ChbPnl(SEditorUtil.ICO_LAND.getImage())); + MAP_TYPE_CHECKBOXES.put(FilterProperty.PLANESWALKER, + new ChbPnl(SEditorUtil.ICO_PLANESWALKER.getImage())); + MAP_TYPE_CHECKBOXES.put(FilterProperty.SORCERY, + new ChbPnl(SEditorUtil.ICO_SORCERY.getImage())); + + + final JPanel pnl = new JPanel(new WrapLayout(SwingConstants.CENTER, 10, 5)); + pnl.setOpaque(false); + + for (FilterProperty p : MAP_TYPE_CHECKBOXES.keySet()) { + pnl.add(MAP_TYPE_CHECKBOXES.get(p)); + } + return pnl; + } + + /** Turns all type checkboxes off or on. + * @param select0   boolean */ + public static void toggleTypeCheckboxes(final boolean select0) { + for (FilterProperty p : MAP_TYPE_CHECKBOXES.keySet()) { + ((ChbPnl) MAP_TYPE_CHECKBOXES.get(p)).getCheckBox().setSelected(select0); + } + } + + /** Turns all type checkboxes off or on. + * @param select0   boolean */ + public static void toggleColorCheckboxes(final boolean select0) { + for (FilterProperty p : MAP_COLOR_CHECKBOXES.keySet()) { + ((ChbPnl) MAP_COLOR_CHECKBOXES.get(p)).getCheckBox().setSelected(select0); + } + } + + /** + * Assembles checkboxes for color and returns a filter predicate. + *

+ * Handles "multicolor" label, which is quite tricky. + * + * @return Predicate + */ + public static Predicate buildColorFilter() { + if (MAP_COLOR_CHECKBOXES.isEmpty()) { return Predicate.getTrue(CardPrinted.class); } + + final List> ors = new ArrayList>(); + JCheckBox chbTemp; + + chbTemp = ((ChbPnl) MAP_COLOR_CHECKBOXES.get(FilterProperty.BLACK)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_BLACK); } + + chbTemp = ((ChbPnl) MAP_COLOR_CHECKBOXES.get(FilterProperty.BLUE)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_BLUE); } + + chbTemp = ((ChbPnl) MAP_COLOR_CHECKBOXES.get(FilterProperty.GREEN)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_GREEN); } + + chbTemp = ((ChbPnl) MAP_COLOR_CHECKBOXES.get(FilterProperty.RED)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_RED); } + + chbTemp = ((ChbPnl) MAP_COLOR_CHECKBOXES.get(FilterProperty.WHITE)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_WHITE); } + + chbTemp = ((ChbPnl) MAP_COLOR_CHECKBOXES.get(FilterProperty.COLORLESS)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_COLORLESS); } + + // Multi-colored needs special XOR treatment, since "not multi" when OR-ed + // with any other of its colors except colorless, will return true. + // Careful when changing this. + chbTemp = ((ChbPnl) MAP_COLOR_CHECKBOXES.get(FilterProperty.MULTICOLOR)).getCheckBox(); + final Predicate preMulti; + if (chbTemp.isSelected()) { + preMulti = Predicate.getTrue(CardPrinted.class); + } + else { + preMulti = Predicate.not(Predicate.brigde( + CardRules.Predicates.Presets.IS_MULTICOLOR, CardPrinted.FN_GET_RULES)); + } + + final Predicate preColors = + Predicate.brigde(Predicate.or(ors), CardPrinted.FN_GET_RULES); + + // Corner case: if multi is checked, and the rest are empty, AND won't work. + // This still doesn't work perfectly :/ + boolean allEmptyExceptMulti = true; + for (FilterProperty p : MAP_COLOR_CHECKBOXES.keySet()) { + if (p.equals(FilterProperty.MULTICOLOR)) { continue; } + if (((ChbPnl) MAP_COLOR_CHECKBOXES.get(p)).getCheckBox().isSelected()) { + allEmptyExceptMulti = false; + break; + } + } + + if (allEmptyExceptMulti) { + return Predicate.brigde( + CardRules.Predicates.Presets.IS_MULTICOLOR, CardPrinted.FN_GET_RULES); + } + else { + return Predicate.and(preColors, preMulti); + } + } + + /** + * Filters the set/format combo box. + * + * @return Predicate + */ + public static Predicate buildSetAndFormatFilter() { + // Set/Format filter + if (VFilters.SINGLETON_INSTANCE.getCbxSets().getSelectedIndex() == 0) { + return Predicate.getTrue(CardPrinted.class); + } + + final Object selected = VFilters.SINGLETON_INSTANCE.getCbxSets().getSelectedItem(); + final Predicate filter; + if (selected instanceof CardEdition) { + filter = CardPrinted.Predicates.printedInSets(((CardEdition) selected).getCode()); + } + else { + filter = ((GameFormat) selected).getFilterRules(); + } + + return filter; + } + + /** + * Assembles checkboxes for type and returns a filter predicate. + * + * @return Predicate + */ + public static Predicate buildTypeFilter() { + if (MAP_TYPE_CHECKBOXES.isEmpty()) { return Predicate.getTrue(CardPrinted.class); } + + final List> ors = new ArrayList>(); + JCheckBox chbTemp; + + chbTemp = ((ChbPnl) MAP_TYPE_CHECKBOXES.get(FilterProperty.ARTIFACT)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_ARTIFACT); } + + chbTemp = ((ChbPnl) MAP_TYPE_CHECKBOXES.get(FilterProperty.CREATURE)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_CREATURE); } + + chbTemp = ((ChbPnl) MAP_TYPE_CHECKBOXES.get(FilterProperty.ENCHANTMENT)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_ENCHANTMENT); } + + chbTemp = ((ChbPnl) MAP_TYPE_CHECKBOXES.get(FilterProperty.INSTANT)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_INSTANT); } + + chbTemp = ((ChbPnl) MAP_TYPE_CHECKBOXES.get(FilterProperty.LAND)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_LAND); } + + chbTemp = ((ChbPnl) MAP_TYPE_CHECKBOXES.get(FilterProperty.PLANESWALKER)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_PLANESWALKER); } + + chbTemp = ((ChbPnl) MAP_TYPE_CHECKBOXES.get(FilterProperty.SORCERY)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_SORCERY); } + + return Predicate.brigde(Predicate.or(ors), CardPrinted.FN_GET_RULES); + } + + /** + * Validates text field input (from txfContains and txfWithout), + * then assembles AND and NOT predicates accordingly, ANDs + * together, and returns. + * + * @return Predicate + */ + public static Predicate buildTextFilter() { + Predicate filterAnd = Predicate.getTrue(CardPrinted.class); + Predicate filterNot = Predicate.getTrue(CardPrinted.class); + + final String strContains = VFilters.SINGLETON_INSTANCE.getTxfContains().getText(); + final String strWithout = VFilters.SINGLETON_INSTANCE.getTxfWithout().getText(); + + if (!strContains.isEmpty()) { + final String[] splitContains = strContains + .replaceAll(",", "") + .replaceAll(" ", " ") + .toLowerCase().split(" "); + + final List> ands = new ArrayList>(); + + for (final String s : splitContains) { + final List> subands = new ArrayList>(); + subands.add(Predicate.brigde(CardRules.Predicates.name( + StringOp.CONTAINS, s), CardPrinted.FN_GET_RULES)); + subands.add(Predicate.brigde(CardRules.Predicates.joinedType( + StringOp.CONTAINS, s), CardPrinted.FN_GET_RULES)); + subands.add(Predicate.brigde(CardRules.Predicates.rules( + StringOp.CONTAINS, s), CardPrinted.FN_GET_RULES)); + + ands.add(Predicate.or(subands)); + } + + filterAnd = Predicate.and(ands); + } + + if (!strWithout.isEmpty()) { + final String[] splitWithout = strWithout + .replaceAll(" ", " ") + .replaceAll(",", "") + .toLowerCase().split(" "); + + final List> nots = new ArrayList>(); + + for (final String s : splitWithout) { + final List> subnots = new ArrayList>(); + + subnots.add(Predicate.brigde(CardRules.Predicates.name( + StringOp.CONTAINS, s), CardPrinted.FN_GET_RULES)); + subnots.add(Predicate.brigde(CardRules.Predicates.joinedType( + StringOp.CONTAINS, s), CardPrinted.FN_GET_RULES)); + subnots.add(Predicate.brigde(CardRules.Predicates.rules( + StringOp.CONTAINS, s), CardPrinted.FN_GET_RULES)); + + nots.add(Predicate.or(subnots)); + } + + filterNot = Predicate.not(Predicate.or(nots)); + } + + return Predicate.and(filterAnd, filterNot); + } + + /** + * Validates combo box input, assembles predicate filters for each case, + * stacks them all together, and returns the predicate. + * + * @return Predicate + */ + public static Predicate buildIntervalFilter() { + final VFilters view = VFilters.SINGLETON_INSTANCE; + Predicate filter = Predicate.getTrue(CardPrinted.class); + + // Must include -1 so non-creatures are included by default. + final int plow = view.getCbxPLow().getSelectedItem().toString().equals("*") + ? -1 : Integer.valueOf(view.getCbxPLow().getSelectedItem().toString()); + final int tlow = view.getCbxTLow().getSelectedItem().toString().equals("*") + ? -1 : Integer.valueOf(view.getCbxTLow().getSelectedItem().toString()); + final int clow = view.getCbxCMCLow().getSelectedItem().toString().equals("*") + ? -1 : Integer.valueOf(view.getCbxCMCLow().getSelectedItem().toString()); + + // If a power, toughness, or CMC is higher than 100, that's bad. + final int phigh = view.getCbxPHigh().getSelectedItem().toString().equals("10+") + ? 100 : Integer.valueOf(view.getCbxPHigh().getSelectedItem().toString()); + final int thigh = view.getCbxTHigh().getSelectedItem().toString().equals("10+") + ? 100 : Integer.valueOf(view.getCbxTHigh().getSelectedItem().toString()); + final int chigh = view.getCbxCMCHigh().getSelectedItem().toString().equals("10+") + ? 100 : Integer.valueOf(view.getCbxCMCHigh().getSelectedItem().toString()); + + // Assemble final predicates + final Predicate prePower; + final Predicate preToughness; + final Predicate preCMC; + + // Power: CardRules returns null if no power, which means extra + // filtering must be applied to allow all cards to be shown if * is chosen. + // (Without this, lands and such would be filtered out by default.) + if (plow > phigh) { prePower = Predicate.getFalse(CardPrinted.class); } + else { + // If * is selected in the combo box, cards without power + // will be included in the filter. + final Predicate preNotCreature; + if (plow == -1) { + preNotCreature = Predicate.not( + Predicate.brigde(CardRules.Predicates.Presets.IS_CREATURE, + CardPrinted.FN_GET_RULES)); + } + // Otherwise, if 0 or higher is selected, cards without power + // are excluded. + else { + preNotCreature = Predicate.getFalse(CardPrinted.class); + } + + final Predicate prePowerTemp = Predicate.and( + Predicate.brigde(CardRules.Predicates.power( + ComparableOp.GT_OR_EQUAL, plow), CardPrinted.FN_GET_RULES), + Predicate.brigde(CardRules.Predicates.power( + ComparableOp.LT_OR_EQUAL, phigh), CardPrinted.FN_GET_RULES)); + + prePower = Predicate.or(preNotCreature, prePowerTemp); + } + + // Toughness: CardRules returns null if no toughness, which means extra + // filtering must be applied to allow all cards to be shown if * is chosen. + // (Without this, lands and such would be filtered out by default.) + if (tlow > thigh) { preToughness = Predicate.getFalse(CardPrinted.class); } + else { + // If * is selected in the combo box, cards without toughness + // will be included in the filter. + final Predicate preNotCreature; + if (tlow == -1) { + preNotCreature = Predicate.not( + Predicate.brigde(CardRules.Predicates.Presets.IS_CREATURE, + CardPrinted.FN_GET_RULES)); + } + // Otherwise, if 0 or higher is selected, cards without toughness + // are excluded. + else { + preNotCreature = Predicate.getFalse(CardPrinted.class); + } + + final Predicate preToughnessTemp = Predicate.and( + Predicate.brigde(CardRules.Predicates.toughness( + ComparableOp.GT_OR_EQUAL, tlow), CardPrinted.FN_GET_RULES), + Predicate.brigde(CardRules.Predicates.toughness( + ComparableOp.LT_OR_EQUAL, thigh), CardPrinted.FN_GET_RULES)); + + preToughness = Predicate.or(preNotCreature, preToughnessTemp); + } + + // CMC, thankfully, will return -1 if the card doesn't have a CMC, + // so it can be compared directly against the low value, and non-CMC + // cards will still be included if * is chosen. + if (clow > chigh) { preCMC = Predicate.getFalse(CardPrinted.class); } + else { + preCMC = Predicate.and( + Predicate.brigde(CardRules.Predicates.cmc( + ComparableOp.GT_OR_EQUAL, clow), CardPrinted.FN_GET_RULES), + Predicate.brigde(CardRules.Predicates.cmc( + ComparableOp.LT_OR_EQUAL, chigh), CardPrinted.FN_GET_RULES)); + } + + // Stack them all together and return. + filter = Predicate.and(preCMC, Predicate.and(prePower, preToughness)); + return filter; + } + + //========== Custom class handling + + /** + * A panel with a checkbox and an icon, which will toggle the + * checkbox when anywhere in the panel is clicked. + */ + @SuppressWarnings("serial") + private static class ChbPnl extends JPanel implements ItemListener { + private final JCheckBox checkBox = new JCheckBox(); + private final Image img; + + public ChbPnl(final Image img0) { + super(); + this.img = img0; + this.setOpaque(false); + checkBox.setBorder(new EmptyBorder(0, 20, 0, 0)); + checkBox.setOpaque(false); + checkBox.setSelected(true); + checkBox.addItemListener(this); + add(checkBox); + + this.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(final MouseEvent me) { + checkBox.doClick(); + } + }); + } + + public JCheckBox getCheckBox() { + return this.checkBox; + } + + @Override + protected void paintComponent(final Graphics g) { + super.paintComponent(g); + g.drawImage(img, 0, 0, null); + } + + /* (non-Javadoc) + * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent) + */ + @Override + public void itemStateChanged(final ItemEvent arg0) { + if (!preventFiltering) { + ((CFilters) VFilters.SINGLETON_INSTANCE.getControl()).buildFilter(); + } + } + } +} diff --git a/src/main/java/forge/gui/deckeditor/VDeckEditorUI.java b/src/main/java/forge/gui/deckeditor/VDeckEditorUI.java new file mode 100644 index 00000000000..3cba129f285 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/VDeckEditorUI.java @@ -0,0 +1,61 @@ +package forge.gui.deckeditor; + +import javax.swing.SwingWorker; + +import forge.gui.framework.IVTopLevelUI; +import forge.gui.framework.SLayoutIO; + +/** +/** + * Top level view class; instantiates and assembles + * tabs used in deck editor UI drag layout.
+ * + *

(V at beginning of class name denotes a view class.) + * + */ +public enum VDeckEditorUI implements IVTopLevelUI { + /** */ + SINGLETON_INSTANCE; + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.IVTopLevelUI#instantiate() + */ + @Override + public void instantiate() { + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVTopLevelUI#populate() + */ + @Override + public void populate() { + final SwingWorker w = new SwingWorker() { + @Override + public Void doInBackground() { + SLayoutIO.loadLayout(null); + + /* this can be used for toggling panels in and out of the view (e.g. dev mode) + + make are separate + layout states for each deck editor state. + however, the empty cells should still be removed. + + VFilters.SINGLETON_INSTANCE.getParentCell().removeDoc(VFilters.SINGLETON_INSTANCE); + VProbabilities.SINGLETON_INSTANCE.getParentCell().removeDoc(VProbabilities.SINGLETON_INSTANCE); + + System.out.println(FView.SINGLETON_INSTANCE.getDragCells().size()); + + for (final DragCell c : FView.SINGLETON_INSTANCE.getDragCells()) { + if (c.getDocs().size() == 0) { + SRearrangingUtil.fillGap(c); + FView.SINGLETON_INSTANCE.removeDragCell(c); + } + } */ + return null; + } + }; + w.execute(); + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/ACEditorBase.java b/src/main/java/forge/gui/deckeditor/controllers/ACEditorBase.java new file mode 100644 index 00000000000..4c010d25833 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/ACEditorBase.java @@ -0,0 +1,115 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package forge.gui.deckeditor.controllers; + +import forge.deck.DeckBase; +import forge.gui.deckeditor.tables.DeckController; +import forge.gui.deckeditor.tables.TableView; +import forge.item.InventoryItem; + +/** + * Maintains a generically typed architecture for various editing + * environments. A basic editor instance requires a card catalog, the + * current deck being edited, and optional filters on the catalog. + *

+ * These requirements are collected in this class and manipulated + * in subclasses for different environments. There are two generic + * types for all card display and filter predicates. + * + *

(A at beginning of class name denotes an abstract class.) + *

(C at beginning of class name denotes a control class.) + * + * @param extends {@link forge.item.InventoryItem} + * @param extends {@link forge.deck.DeckBase} + */ +public abstract class ACEditorBase { + + private TableView tblCatalog; + private TableView tblDeck; + /** + * Operation to add one of selected card to current deck. + */ + public abstract void addCard(); + + /** + * Operation to remove one of selected card from current deck. + */ + public abstract void removeCard(); + + /** + * Resets the cards in the catalog table and current deck table. + */ + public abstract void resetTables(); + + /** + * Gets controller responsible for the current deck being edited. + * + * @return {@link forge.gui.deckeditor.tables.DeckController} + */ + public abstract DeckController getDeckController(); + + /** + * Called when an editor wants to exit. Should confirm save options, + * update next UI screen, etc. + * + * @return boolean   true if safe to exit + */ + public abstract boolean exit(); + + /** + * Resets and initializes the current editor. + */ + public abstract void init(); + + /** + * Gets the TableView holding the cards in the current deck. + * + * @return {@link forge.gui.deckeditor.tables.TableView} + */ + public TableView getTableDeck() { + return this.tblDeck; + } + + /** + * Sets the TableView holding the cards in the current deck. + * + * @param table0   {@link forge.gui.deckeditor.tables.TableView} + */ + public void setTableDeck(final TableView table0) { + this.tblDeck = table0; + } + + /** + * Gets the TableView holding the cards in the current catalog. + * + * @return {@link forge.gui.deckeditor.tables.TableView} + */ + public TableView getTableCatalog() { + return this.tblCatalog; + } + + /** + * Sets the TableView holding the cards in the current catalog. + * + * @param table0   {@link forge.gui.deckeditor.tables.TableView} + */ + public void setTableCatalog(final TableView table0) { + this.tblCatalog = table0; + } + +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CAllDecks.java b/src/main/java/forge/gui/deckeditor/controllers/CAllDecks.java new file mode 100644 index 00000000000..c8a9c886374 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CAllDecks.java @@ -0,0 +1,68 @@ +package forge.gui.deckeditor.controllers; + +import java.awt.Dialog.ModalityType; + +import forge.Command; +import forge.Singletons; +import forge.deck.DeckBase; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.DeckImport; +import forge.gui.deckeditor.views.VAllDecks; +import forge.gui.framework.ICDoc; +import forge.gui.toolbox.FLabel; +import forge.item.InventoryItem; + +/** + * Controls the "all decks" panel in the deck editor UI. + * + *

(C at beginning of class name denotes a control class.) + * + */ +public enum CAllDecks implements ICDoc { + /** */ + SINGLETON_INSTANCE; + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#getCommandOnSelect() + */ + @Override + public Command getCommandOnSelect() { + return null; + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#initialize() + */ + @SuppressWarnings("serial") + @Override + public void initialize() { + VAllDecks.SINGLETON_INSTANCE.getLstDecks().setDecks( + Singletons.getModel().getDecks().getConstructed()); + + ((FLabel) VAllDecks.SINGLETON_INSTANCE.getBtnImport()) + .setCommand(new Command() { @Override + public void execute() { importDeck(); } }); + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#update() + */ + @Override + public void update() { + } + + /** + * Opens dialog for importing a deck from a different MTG software. + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + private void importDeck() { + final ACEditorBase ed = (ACEditorBase) + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController(); + + final DeckImport dImport = new DeckImport(ed); + dImport.setModalityType(ModalityType.APPLICATION_MODAL); + dImport.setVisible(true); + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CCardCatalog.java b/src/main/java/forge/gui/deckeditor/controllers/CCardCatalog.java new file mode 100644 index 00000000000..ff785392165 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CCardCatalog.java @@ -0,0 +1,76 @@ +package forge.gui.deckeditor.controllers; + +import forge.Command; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.views.VCardCatalog; +import forge.gui.framework.ICDoc; +import forge.gui.toolbox.FLabel; +import forge.item.InventoryItem; + +/** + * Controls the "card catalog" panel in the deck editor UI. + * + *

(C at beginning of class name denotes a control class.) + * + */ +public enum CCardCatalog implements ICDoc { + /** */ + SINGLETON_INSTANCE; + + // refresh analysis on add + + private CCardCatalog() { + } + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#getCommandOnSelect() + */ + @Override + public Command getCommandOnSelect() { + return null; + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#initialize() + */ + @Override + @SuppressWarnings("serial") + public void initialize() { + // Add/remove buttons + ((FLabel) VCardCatalog.SINGLETON_INSTANCE.getBtnAdd()).setCommand(new Command() { + @Override + public void execute() { + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().addCard(); + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().getTableCatalog().getTable().requestFocusInWindow(); + CStatistics.SINGLETON_INSTANCE.update(); + CProbabilities.SINGLETON_INSTANCE.update(); + } + }); + + ((FLabel) VCardCatalog.SINGLETON_INSTANCE.getBtnAdd4()).setCommand(new Command() { + @Override + public void execute() { + final InventoryItem item = CDeckEditorUI.SINGLETON_INSTANCE + .getCurrentEditorController().getTableCatalog().getSelectedCard(); + + for (int i = 0; i < 4; i++) { + if (item.equals(CDeckEditorUI.SINGLETON_INSTANCE + .getCurrentEditorController().getTableCatalog().getSelectedCard())) { + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().addCard(); + } + } + CStatistics.SINGLETON_INSTANCE.update(); + CProbabilities.SINGLETON_INSTANCE.update(); + } + }); + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#update() + */ + @Override + public void update() { + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CCurrentDeck.java b/src/main/java/forge/gui/deckeditor/controllers/CCurrentDeck.java new file mode 100644 index 00000000000..dd5c1b6ced3 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CCurrentDeck.java @@ -0,0 +1,202 @@ +package forge.gui.deckeditor.controllers; + +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.io.File; + +import javax.swing.JFileChooser; +import javax.swing.JTextField; +import javax.swing.SwingUtilities; + +import forge.Command; +import forge.deck.Deck; +import forge.deck.DeckBase; +import forge.deck.io.DeckSerializer; +import forge.error.ErrorViewer; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.SEditorIO; +import forge.gui.deckeditor.tables.DeckController; +import forge.gui.deckeditor.views.VCurrentDeck; +import forge.gui.framework.ICDoc; +import forge.gui.toolbox.FLabel; +import forge.item.InventoryItem; + +/** + * Controls the "current deck" panel in the deck editor UI. + * + *

(C at beginning of class name denotes a control class.) + * + */ +public enum CCurrentDeck implements ICDoc { + /** */ + SINGLETON_INSTANCE; + + private static File previousDirectory = null; + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#getCommandOnSelect() + */ + @Override + public Command getCommandOnSelect() { + return null; + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#initialize() + */ + @Override + @SuppressWarnings("serial") + public void initialize() { + ((FLabel) VCurrentDeck.SINGLETON_INSTANCE.getBtnSave()) + .setCommand(new Command() { @Override + public void execute() { SEditorIO.saveDeck(); } }); + + ((FLabel) VCurrentDeck.SINGLETON_INSTANCE.getBtnSaveAs()) + .setCommand(new Command() { @Override + public void execute() { exportDeck(); } }); + + ((FLabel) VCurrentDeck.SINGLETON_INSTANCE.getBtnOpen()) + .setCommand(new Command() { @Override + public void execute() { openDeck(); } }); + + ((FLabel) VCurrentDeck.SINGLETON_INSTANCE.getBtnNew()) + .setCommand(new Command() { @Override + public void execute() { newDeck(); } }); + + VCurrentDeck.SINGLETON_INSTANCE.getTxfTitle().addFocusListener(new FocusAdapter() { + @Override + public void focusGained(final FocusEvent e) { + if (((JTextField) e.getSource()).getText().equals("[New Deck]")) { + ((JTextField) e.getSource()).setText(""); + } + } + + @Override + public void focusLost(final FocusEvent e) { + if (((JTextField) e.getSource()).getText().isEmpty()) { + ((JTextField) e.getSource()).setText("[New Deck]"); + } + } + }); + + ((FLabel) VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove()).setCommand(new Command() { + @Override public void execute() { + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().removeCard(); + } }); + + ((FLabel) VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove4()).setCommand(new Command() { + @Override public void execute() { + final InventoryItem item = CDeckEditorUI.SINGLETON_INSTANCE + .getCurrentEditorController().getTableDeck().getSelectedCard(); + + for (int i = 0; i < 4; i++) { + if (item.equals(CDeckEditorUI.SINGLETON_INSTANCE + .getCurrentEditorController().getTableDeck().getSelectedCard())) { + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().removeCard(); + } + } + } + }); + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#update() + */ + @Override + public void update() { + } + + // + + /** */ + @SuppressWarnings("unchecked") + private void newDeck() { + if (!SEditorIO.confirmSaveChanges()) { return; } + + try { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + ((DeckController) CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().getDeckController()).newModel(); + VCurrentDeck.SINGLETON_INSTANCE.getTxfTitle().setText(""); + VCurrentDeck.SINGLETON_INSTANCE.getTxfTitle().requestFocusInWindow(); + } + }); + } catch (final Exception ex) { + ErrorViewer.showError(ex); + throw new RuntimeException("Error creating new deck. " + ex); + } + } + + /** */ + @SuppressWarnings("unchecked") + private void openDeck() { + if (!SEditorIO.confirmSaveChanges()) { return; } + + final File file = this.getImportFilename(); + + if (file != null && file.getName().endsWith(".dck")) { + try { + ((DeckController) CDeckEditorUI.SINGLETON_INSTANCE + .getCurrentEditorController().getDeckController()) + .setModel(Deck.fromFile(file)); + + } catch (final Exception ex) { + ErrorViewer.showError(ex); + throw new RuntimeException("Error importing deck." + ex); + } + } + } + + /** */ + private File getImportFilename() { + final JFileChooser open = new JFileChooser(previousDirectory); + open.setDialogTitle("Import Deck"); + open.addChoosableFileFilter(DeckSerializer.DCK_FILTER); + final int returnVal = open.showOpenDialog(null); + + if (returnVal == JFileChooser.APPROVE_OPTION) { + final File file = open.getSelectedFile(); + previousDirectory = file.getParentFile(); + return file; + } + return null; + } + + /** */ + @SuppressWarnings("unchecked") + private void exportDeck() { + final File filename = this.getExportFilename(); + if (filename == null) { + return; + } + + try { + DeckSerializer.writeDeck( + ((DeckController) CDeckEditorUI.SINGLETON_INSTANCE + .getCurrentEditorController().getDeckController()).getModel(), filename); + } catch (final Exception ex) { + ErrorViewer.showError(ex); + throw new RuntimeException("Error exporting deck." + ex); + } + } + + private File getExportFilename() { + final JFileChooser save = new JFileChooser(previousDirectory); + save.setDialogTitle("Export Deck"); + save.setDialogType(JFileChooser.SAVE_DIALOG); + save.setFileFilter(DeckSerializer.DCK_FILTER); + + if (save.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) { + final File file = save.getSelectedFile(); + final String check = file.getAbsolutePath(); + + previousDirectory = file.getParentFile(); + + return check.endsWith(".dck") ? file : new File(check + ".dck"); + } + return null; + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CDeckgen.java b/src/main/java/forge/gui/deckeditor/controllers/CDeckgen.java new file mode 100644 index 00000000000..720b5162498 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CDeckgen.java @@ -0,0 +1,120 @@ +package forge.gui.deckeditor.controllers; + +import forge.Command; +import forge.card.CardRules; +import forge.deck.Deck; +import forge.deck.DeckBase; +import forge.deck.generate.Generate2ColorDeck; +import forge.deck.generate.Generate3ColorDeck; +import forge.deck.generate.Generate5ColorDeck; +import forge.game.player.PlayerType; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.SEditorIO; +import forge.gui.deckeditor.views.VDeckgen; +import forge.gui.framework.ICDoc; +import forge.gui.toolbox.FLabel; +import forge.item.CardDb; +import forge.item.CardPrinted; +import forge.item.InventoryItem; +import forge.util.closures.Predicate; + +/** + * Controls the "analysis" panel in the deck editor UI. + * + *

(C at beginning of class name denotes a control class.) + * + */ +public enum CDeckgen implements ICDoc { + /** */ + SINGLETON_INSTANCE; + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#getCommandOnSelect() + */ + @Override + public Command getCommandOnSelect() { + return null; + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#initialize() + */ + @SuppressWarnings("serial") + @Override + public void initialize() { + ((FLabel) VDeckgen.SINGLETON_INSTANCE.getBtnRandCardpool()).setCommand(new Command() { + @Override + public void execute() { + newRandomConstructed(); + } + }); + + ((FLabel) VDeckgen.SINGLETON_INSTANCE.getBtnRandDeck2()).setCommand(new Command() { + @Override public void execute() { newGenerateConstructed(2); } }); + + ((FLabel) VDeckgen.SINGLETON_INSTANCE.getBtnRandDeck3()).setCommand(new Command() { + @Override public void execute() { newGenerateConstructed(3); } }); + + ((FLabel) VDeckgen.SINGLETON_INSTANCE.getBtnRandDeck5()).setCommand(new Command() { + @Override public void execute() { newGenerateConstructed(5); } }); + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#update() + */ + @Override + public void update() { + } + + //========== Other methods + @SuppressWarnings("unchecked") + private void newRandomConstructed() { + if (!SEditorIO.confirmSaveChanges()) { return; } + + final Deck randomDeck = new Deck(); + + randomDeck.getMain().addAllFlat(Predicate.not(CardRules.Predicates.Presets.IS_BASIC_LAND) + .random(CardDb.instance().getAllUniqueCards(), CardPrinted.FN_GET_RULES, 15 * 5)); + randomDeck.getMain().add("Plains"); + randomDeck.getMain().add("Island"); + randomDeck.getMain().add("Swamp"); + randomDeck.getMain().add("Mountain"); + randomDeck.getMain().add("Forest"); + randomDeck.getMain().add("Terramorphic Expanse"); + + final ACEditorBase ed = (ACEditorBase) + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController(); + + ed.getDeckController().setModel((TModel) randomDeck); + } + + @SuppressWarnings("unchecked") + private void newGenerateConstructed(final int colorCount0) { + if (!SEditorIO.confirmSaveChanges()) { return; } + + final Deck genConstructed = new Deck(); + + switch (colorCount0) { + case 2: + genConstructed.getMain().addAll( + (new Generate2ColorDeck("AI", "AI")).get2ColorDeck(60, PlayerType.HUMAN)); + break; + case 3: + genConstructed.getMain().addAll( + (new Generate3ColorDeck("AI", "AI", "AI")).get3ColorDeck(60, PlayerType.HUMAN)); + break; + case 5: + genConstructed.getMain().addAll( + (new Generate5ColorDeck()).get5ColorDeck(60, PlayerType.HUMAN)); + break; + default: + } + + final ACEditorBase ed = (ACEditorBase) + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController(); + + ed.getDeckController().setModel((TModel) genConstructed); + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorConstructed.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorConstructed.java new file mode 100644 index 00000000000..2a58193b017 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorConstructed.java @@ -0,0 +1,158 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package forge.gui.deckeditor.controllers; + +import java.util.List; + +import forge.Singletons; +import forge.deck.Deck; +import forge.gui.deckeditor.SEditorIO; +import forge.gui.deckeditor.SEditorUtil; +import forge.gui.deckeditor.tables.DeckController; +import forge.gui.deckeditor.tables.SColumnUtil; +import forge.gui.deckeditor.tables.SColumnUtil.ColumnName; +import forge.gui.deckeditor.tables.TableColumnInfo; +import forge.gui.deckeditor.tables.TableView; +import forge.gui.deckeditor.views.VCardCatalog; +import forge.gui.deckeditor.views.VCurrentDeck; +import forge.item.CardDb; +import forge.item.CardPrinted; +import forge.item.InventoryItem; +import forge.item.ItemPool; +import forge.util.closures.Lambda0; + +/** + * Child controller for constructed deck editor UI. + * This is the least restrictive mode; + * all cards are available. + * + *

(C at beginning of class name denotes a control class.) + * + * @author Forge + * @version $Id$ + */ +public final class CEditorConstructed extends ACEditorBase { + private final DeckController controller; + + //=========== Constructor + /** + * Child controller for constructed deck editor UI. + * This is the least restrictive mode; + * all cards are available. + */ + public CEditorConstructed() { + super(); + + final TableView tblCatalog = new TableView(true, CardPrinted.class); + final TableView tblDeck = new TableView(true, CardPrinted.class); + + VCardCatalog.SINGLETON_INSTANCE.setTableView(tblCatalog.getTable()); + VCurrentDeck.SINGLETON_INSTANCE.setTableView(tblDeck.getTable()); + + this.setTableCatalog(tblCatalog); + this.setTableDeck(tblDeck); + + final Lambda0 newCreator = new Lambda0() { + @Override + public Deck apply() { + return new Deck(); + } + }; + this.controller = new DeckController(Singletons.getModel().getDecks().getConstructed(), this, newCreator); + } + + //=========== Overridden from ACEditorBase + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#addCard() + */ + @Override + public void addCard() { + final InventoryItem item = this.getTableCatalog().getSelectedCard(); + if ((item == null) || !(item instanceof CardPrinted)) { + return; + } + + final CardPrinted card = (CardPrinted) item; + this.getTableDeck().addCard(card); + this.controller.notifyModelChanged(); + VCurrentDeck.SINGLETON_INSTANCE.getTabLabel().setText("*Current Deck"); + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#removeCard() + */ + @Override + public void removeCard() { + final InventoryItem item = this.getTableDeck().getSelectedCard(); + if ((item == null) || !(item instanceof CardPrinted)) { + return; + } + + final CardPrinted card = (CardPrinted) item; + this.getTableDeck().removeCard(card); + this.controller.notifyModelChanged(); + VCurrentDeck.SINGLETON_INSTANCE.getTabLabel().setText("*Current Deck"); + } + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#updateView() + */ + @Override + public void resetTables() { + // Constructed mode can use all cards, no limitations. + this.getTableCatalog().setDeck(ItemPool.createFrom(CardDb.instance().getAllCards(), CardPrinted.class)); + this.getTableDeck().setDeck(this.controller.getModel().getMain()); + } + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#getController() + */ + @Override + public DeckController getDeckController() { + return this.controller; + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#show(forge.Command) + */ + @Override + public void init() { + final List> lstCatalogCols = SColumnUtil.getCatalogDefaultColumns(); + lstCatalogCols.remove(SColumnUtil.getColumn(ColumnName.CAT_QUANTITY)); + + this.getTableCatalog().setup(VCardCatalog.SINGLETON_INSTANCE, lstCatalogCols); + this.getTableDeck().setup(VCurrentDeck.SINGLETON_INSTANCE, SColumnUtil.getDeckDefaultColumns()); + + SEditorUtil.resetUI(); + + this.controller.newModel(); + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.controllers.ACEditorBase#exit() + */ + @Override + public boolean exit() { + return SEditorIO.confirmSaveChanges(); + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorDraftingProcess.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorDraftingProcess.java new file mode 100644 index 00000000000..80461fd50ec --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorDraftingProcess.java @@ -0,0 +1,249 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package forge.gui.deckeditor.controllers; + +import javax.swing.JOptionPane; + +import forge.Constant; +import forge.Singletons; +import forge.control.FControl; +import forge.deck.Deck; +import forge.deck.DeckGroup; +import forge.game.limited.BoosterDraft; +import forge.game.limited.IBoosterDraft; +import forge.gui.deckeditor.tables.DeckController; +import forge.gui.deckeditor.tables.SColumnUtil; +import forge.gui.deckeditor.tables.TableView; +import forge.gui.deckeditor.views.VCardCatalog; +import forge.gui.deckeditor.views.VCurrentDeck; +import forge.gui.home.sanctioned.CSubmenuDraft; +import forge.item.CardDb; +import forge.item.CardPrinted; +import forge.item.InventoryItem; +import forge.item.ItemPoolView; + +/** + * Updates the deck editor UI as necessary draft selection mode. + * + *

(C at beginning of class name denotes a control class.) + * + * @author Forge + * @version $Id$ + */ +public class CEditorDraftingProcess extends ACEditorBase { + private IBoosterDraft boosterDraft; + + //========== Constructor + + /** + * Updates the deck editor UI as necessary draft selection mode. + */ + public CEditorDraftingProcess() { + final TableView tblCatalog = new TableView(true, CardPrinted.class); + final TableView tblDeck = new TableView(true, CardPrinted.class); + + VCardCatalog.SINGLETON_INSTANCE.setTableView(tblCatalog.getTable()); + VCurrentDeck.SINGLETON_INSTANCE.setTableView(tblDeck.getTable()); + + this.setTableCatalog(tblCatalog); + this.setTableDeck(tblDeck); + } + + /** + * Show gui. + * + * @param inBoosterDraft + * the in_booster draft + */ + public final void showGui(final IBoosterDraft inBoosterDraft) { + this.boosterDraft = inBoosterDraft; + this.init(); + } + + /** + *

+ * setup. + *

+ */ + private void setup() { + this.getTableCatalog().setup(VCardCatalog.SINGLETON_INSTANCE, SColumnUtil.getCatalogDefaultColumns()); + this.getTableDeck().setup(VCurrentDeck.SINGLETON_INSTANCE, SColumnUtil.getDeckDefaultColumns()); + + /* + this.getTableCatalog().getTable().addMouseListener(this.pickWithMouse); + this.getTableCatalog().getTable().addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(final KeyEvent e) { + if (e.getKeyChar() == ' ') { + CEditorDraftingProcess.this.addCard(); + } + } + }); + */ + + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#addCard() + */ + @Override + public void addCard() { + final InventoryItem item = this.getTableCatalog().getSelectedCard(); + if ((item == null) || !(item instanceof CardPrinted)) { + return; + } + + final CardPrinted card = (CardPrinted) item; + + this.getTableDeck().addCard(card); + + // get next booster pack + this.boosterDraft.setChoice(card); + + if (this.boosterDraft.hasNextChoice()) { + this.showChoices(this.boosterDraft.nextChoice()); + } else { + this.boosterDraft.finishedDrafting(); + this.saveDraft(); + } + } + + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#removeCard() + */ + @Override + public void removeCard() { + } + + /** + *

+ * showChoices. + *

+ * + * @param list + * a {@link forge.CardList} object. + */ + private void showChoices(final ItemPoolView list) { + VCardCatalog.SINGLETON_INSTANCE.getLblTitle().setText("Select a card from pack number " + + (((BoosterDraft) boosterDraft).getCurrentBoosterIndex() + 1) + "."); + this.getTableCatalog().setDeck(list); + this.getTableCatalog().fixSelection(0); + } // showChoices() + + /** + *

+ * getPlayersDeck. + *

+ * + * @return a {@link forge.deck.Deck} object. + */ + private Deck getPlayersDeck() { + final Deck deck = new Deck(); + Constant.Runtime.HUMAN_DECK[0] = deck; + + // add sideboard to deck + deck.getSideboard().addAll(this.getTableDeck().getCards()); + + final String landSet = IBoosterDraft.LAND_SET_CODE[0]; + final int landsCount = 20; + deck.getSideboard().add(CardDb.instance().getCard("Forest", landSet), landsCount); + deck.getSideboard().add(CardDb.instance().getCard("Mountain", landSet), landsCount); + deck.getSideboard().add(CardDb.instance().getCard("Swamp", landSet), landsCount); + deck.getSideboard().add(CardDb.instance().getCard("Island", landSet), landsCount); + deck.getSideboard().add(CardDb.instance().getCard("Plains", landSet), landsCount); + + return deck; + } // getPlayersDeck() + + /** + *

+ * saveDraft. + *

+ */ + private void saveDraft() { + String s = ""; + while ((s == null) || (s.length() == 0)) { + s = JOptionPane.showInputDialog(null, + "Save this draft as:", + "Save draft", + JOptionPane.QUESTION_MESSAGE); + } + // TODO: check if overwriting the same name, and let the user delete old + // drafts + + // construct computer's decks + // save draft + final Deck[] computer = this.boosterDraft.getDecks(); + + final DeckGroup finishedDraft = new DeckGroup(s); + finishedDraft.setHumanDeck((Deck) this.getPlayersDeck().copyTo(s)); + finishedDraft.addAiDecks(computer); + + // DeckManager deckManager = new + // DeckManager(ForgeProps.getFile(NEW_DECKS)); + + // write the file + Singletons.getModel().getDecks().getDraft().add(finishedDraft); + + CSubmenuDraft.SINGLETON_INSTANCE.update(); + FControl.SINGLETON_INSTANCE.changeState(FControl.HOME_SCREEN); + } + + //========== Overridden from ACEditorBase + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#getController() + */ + @Override + public DeckController getDeckController() { + return null; + } + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#updateView() + */ + @Override + public void resetTables() { + } + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#show(forge.Command) + */ + @Override + public void init() { + this.setup(); + this.showChoices(this.boosterDraft.nextChoice()); + this.getTableDeck().setDeck((Iterable) null); + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.controllers.ACEditorBase#exit() + */ + @Override + public boolean exit() { + CSubmenuDraft.SINGLETON_INSTANCE.update(); + return true; + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorLimited.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorLimited.java new file mode 100644 index 00000000000..364fc2cd17e --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorLimited.java @@ -0,0 +1,183 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package forge.gui.deckeditor.controllers; + +import forge.deck.Deck; +import forge.deck.DeckGroup; +import forge.gui.deckeditor.SEditorIO; +import forge.gui.deckeditor.SEditorUtil; +import forge.gui.deckeditor.tables.DeckController; +import forge.gui.deckeditor.tables.SColumnUtil; +import forge.gui.deckeditor.tables.TableView; +import forge.gui.deckeditor.views.VCardCatalog; +import forge.gui.deckeditor.views.VCurrentDeck; +import forge.gui.home.sanctioned.CSubmenuDraft; +import forge.gui.home.sanctioned.CSubmenuSealed; +import forge.item.CardPrinted; +import forge.item.InventoryItem; +import forge.util.IStorage; +import forge.util.closures.Lambda0; + +/** + * Child controller for limited deck editor UI. + * + *

(C at beginning of class name denotes a control class.) + * + * @author Forge + * @version $Id: DeckEditorCommon.java 12850 2011-12-26 14:55:09Z slapshot5 $ + */ +public final class CEditorLimited extends ACEditorBase { + + private final DeckController controller; + + //========== Constructor + + /** + * Child controller for limited deck editor UI. + * + * @param deckMap0   {@link forge.deck.DeckGroup}<{@link forge.util.IStorage}> + */ + public CEditorLimited(final IStorage deckMap0) { + final TableView tblCatalog = new TableView(true, CardPrinted.class); + final TableView tblDeck = new TableView(true, CardPrinted.class); + + VCardCatalog.SINGLETON_INSTANCE.setTableView(tblCatalog.getTable()); + VCurrentDeck.SINGLETON_INSTANCE.setTableView(tblDeck.getTable()); + + this.setTableCatalog(tblCatalog); + this.setTableDeck(tblDeck); + + final Lambda0 newCreator = new Lambda0() { + @Override + public DeckGroup apply() { + return new DeckGroup(""); + } + }; + this.controller = new DeckController(deckMap0, this, newCreator); + } + + /** + * TODO: Write javadoc for this method. + * + * @param model + * @return + */ + private Deck getSelectedDeck(final DeckGroup model) { + return model.getHumanDeck(); + } + + //========== Overridden from ACEditorBase + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#addCard() + */ + @Override + public void addCard() { + final InventoryItem item = this.getTableCatalog().getSelectedCard(); + if ((item == null) || !(item instanceof CardPrinted)) { + return; + } + + // update view + final CardPrinted card = (CardPrinted) item; + this.getTableDeck().addCard(card); + this.getTableCatalog().removeCard(card); + + this.getDeckController().notifyModelChanged(); + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#removeCard() + */ + @Override + public void removeCard() { + final InventoryItem item = this.getTableDeck().getSelectedCard(); + if ((item == null) || !(item instanceof CardPrinted)) { + return; + } + + // update view + final CardPrinted card = (CardPrinted) item; + this.getTableDeck().removeCard(card); + this.getTableCatalog().addCard(card); + + Deck model = getSelectedDeck(getDeckController().getModel()); + model.getMain().remove(card); model.getSideboard().add(card); + + this.getDeckController().notifyModelChanged(); + } + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#updateView() + */ + @Override + public void resetTables() { + final Deck toEdit = this.getSelectedDeck(this.controller.getModel()); + this.getTableCatalog().setDeck(toEdit.getSideboard()); + this.getTableDeck().setDeck(toEdit.getMain()); + } + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#getController() + */ + @Override + public DeckController getDeckController() { + return this.controller; + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#show(forge.Command) + */ + @Override + public void init() { + this.getTableCatalog().setup(VCardCatalog.SINGLETON_INSTANCE, SColumnUtil.getCatalogDefaultColumns()); + this.getTableDeck().setup(VCurrentDeck.SINGLETON_INSTANCE, SColumnUtil.getDeckDefaultColumns()); + + SEditorUtil.resetUI(); + + VCardCatalog.SINGLETON_INSTANCE.getBtnAdd4().setVisible(false); + VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove4().setVisible(false); + + VCurrentDeck.SINGLETON_INSTANCE.getBtnSaveAs().setVisible(false); + VCurrentDeck.SINGLETON_INSTANCE.getBtnNew().setVisible(false); + VCurrentDeck.SINGLETON_INSTANCE.getBtnOpen().setVisible(false); + + VCurrentDeck.SINGLETON_INSTANCE.getTxfTitle().setEnabled(false); + + VCardCatalog.SINGLETON_INSTANCE.getLblTitle().setText("Deck Editor: Limited Mode"); + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.controllers.ACEditorBase#exit() + */ + @Override + public boolean exit() { + final boolean okToExit = SEditorIO.confirmSaveChanges(); + + if (okToExit) { + CSubmenuDraft.SINGLETON_INSTANCE.update(); + CSubmenuSealed.SINGLETON_INSTANCE.update(); + } + + return okToExit; + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorPreferences.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorPreferences.java new file mode 100644 index 00000000000..232d01703d1 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorPreferences.java @@ -0,0 +1,151 @@ +package forge.gui.deckeditor.controllers; + +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +import javax.swing.JCheckBox; + +import forge.Command; +import forge.gui.deckeditor.SEditorIO; +import forge.gui.deckeditor.SEditorIO.EditorPreference; +import forge.gui.deckeditor.tables.SColumnUtil; +import forge.gui.deckeditor.tables.SColumnUtil.ColumnName; +import forge.gui.deckeditor.views.VCardCatalog; +import forge.gui.deckeditor.views.VCurrentDeck; +import forge.gui.deckeditor.views.VEditorPreferences; +import forge.gui.framework.ICDoc; + +/** + * Controls the "analysis" panel in the deck editor UI. + * + *

(C at beginning of class name denotes a control class.) + * + */ +public enum CEditorPreferences implements ICDoc { + /** */ + SINGLETON_INSTANCE; + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#getCommandOnSelect() + */ + @Override + public Command getCommandOnSelect() { + return null; + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#initialize() + */ + @Override + public void initialize() { + SEditorIO.loadPreferences(); + + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogColor().setSelected( + SColumnUtil.getColumn(ColumnName.CAT_COLOR).isShowing()); + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogRarity().setSelected( + SColumnUtil.getColumn(ColumnName.CAT_RARITY).isShowing()); + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogCMC().setSelected( + SColumnUtil.getColumn(ColumnName.CAT_CMC).isShowing()); + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogSet().setSelected( + SColumnUtil.getColumn(ColumnName.CAT_SET).isShowing()); + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogAI().setSelected( + SColumnUtil.getColumn(ColumnName.CAT_AI).isShowing()); + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckColor().setSelected( + SColumnUtil.getColumn(ColumnName.DECK_COLOR).isShowing()); + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckRarity().setSelected( + SColumnUtil.getColumn(ColumnName.DECK_RARITY).isShowing()); + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckCMC().setSelected( + SColumnUtil.getColumn(ColumnName.DECK_CMC).isShowing()); + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckSet().setSelected( + SColumnUtil.getColumn(ColumnName.DECK_SET).isShowing()); + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckAI().setSelected( + SColumnUtil.getColumn(ColumnName.DECK_AI).isShowing()); + + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogStats().setSelected( + SEditorIO.getPref(EditorPreference.stats_catalog)); + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckStats().setSelected( + SEditorIO.getPref(EditorPreference.stats_deck)); + + if (!SEditorIO.getPref(EditorPreference.stats_deck)) { + VCurrentDeck.SINGLETON_INSTANCE.getPnlStats().setVisible(false); + } + if (!SEditorIO.getPref(EditorPreference.stats_catalog)) { + VCardCatalog.SINGLETON_INSTANCE.getPnlStats().setVisible(false); + } + + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogColor().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + SColumnUtil.toggleColumn(SColumnUtil.getColumn(ColumnName.CAT_COLOR)); + SEditorIO.savePreferences(); } }); + + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogRarity().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + SColumnUtil.toggleColumn(SColumnUtil.getColumn(ColumnName.CAT_RARITY)); + SEditorIO.savePreferences(); } }); + + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogCMC().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + SColumnUtil.toggleColumn(SColumnUtil.getColumn(ColumnName.CAT_CMC)); + SEditorIO.savePreferences(); } }); + + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogSet().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + SColumnUtil.toggleColumn(SColumnUtil.getColumn(ColumnName.CAT_SET)); + SEditorIO.savePreferences(); } }); + + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogAI().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + SColumnUtil.toggleColumn(SColumnUtil.getColumn(ColumnName.CAT_AI)); + SEditorIO.savePreferences(); } }); + + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckColor().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + SColumnUtil.toggleColumn(SColumnUtil.getColumn(ColumnName.DECK_COLOR)); + SEditorIO.savePreferences(); } }); + + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckRarity().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + SColumnUtil.toggleColumn(SColumnUtil.getColumn(ColumnName.DECK_RARITY)); + SEditorIO.savePreferences(); } }); + + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckCMC().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + SColumnUtil.toggleColumn(SColumnUtil.getColumn(ColumnName.DECK_CMC)); + SEditorIO.savePreferences(); } }); + + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckSet().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + SColumnUtil.toggleColumn(SColumnUtil.getColumn(ColumnName.DECK_SET)); + SEditorIO.savePreferences(); } }); + + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckAI().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + SColumnUtil.toggleColumn(SColumnUtil.getColumn(ColumnName.DECK_AI)); + SEditorIO.savePreferences(); } }); + + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogStats().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + VCardCatalog.SINGLETON_INSTANCE.getPnlStats().setVisible( + ((JCheckBox) e.getSource()).isSelected()); + SEditorIO.setPref(EditorPreference.stats_catalog, ((JCheckBox) e.getSource()).isSelected()); + SEditorIO.savePreferences(); } }); + + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckStats().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + VCurrentDeck.SINGLETON_INSTANCE.getPnlStats().setVisible( + ((JCheckBox) e.getSource()).isSelected()); + SEditorIO.setPref(EditorPreference.stats_deck, ((JCheckBox) e.getSource()).isSelected()); + SEditorIO.savePreferences(); } }); + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#update() + */ + @Override + public void update() { + } + + //========== Other methods +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorQuest.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorQuest.java new file mode 100644 index 00000000000..2210e6ccc5e --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorQuest.java @@ -0,0 +1,204 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package forge.gui.deckeditor.controllers; + +// import java.awt.Font; +import java.util.List; + +import forge.AllZone; +import forge.Constant; +import forge.deck.Deck; +import forge.gui.deckeditor.SEditorIO; +import forge.gui.deckeditor.tables.DeckController; +import forge.gui.deckeditor.tables.SColumnUtil; +import forge.gui.deckeditor.tables.SColumnUtil.ColumnName; +import forge.gui.deckeditor.tables.TableColumnInfo; +import forge.gui.deckeditor.tables.TableView; +import forge.gui.deckeditor.views.VCardCatalog; +import forge.gui.deckeditor.views.VCurrentDeck; +import forge.gui.home.quest.CSubmenuQuestDecks; +import forge.item.CardPrinted; +import forge.item.InventoryItem; +import forge.item.ItemPool; +import forge.quest.QuestController; +import forge.util.closures.Lambda0; + +//import forge.quest.data.QuestBoosterPack; + +/** + * Child controller for quest deck editor UI. + *

+ * Card catalog and decks are drawn from a QuestController object. + * + *

(C at beginning of class name denotes a control class.) + * + * @author Forge + * @version $Id$ + */ +public final class CEditorQuest extends ACEditorBase { + private final QuestController questData; + private final DeckController controller; + + /** + * Child controller for quest deck editor UI. + *

+ * Card catalog and decks are drawn from a QuestController object. + * + * @param questData0   {@link forge.quest.QuestController} + */ + public CEditorQuest(final QuestController questData0) { + this.questData = questData0; + + final TableView tblCatalog = new TableView(false, CardPrinted.class); + final TableView tblDeck = new TableView(false, CardPrinted.class); + + VCardCatalog.SINGLETON_INSTANCE.setTableView(tblCatalog.getTable()); + VCurrentDeck.SINGLETON_INSTANCE.setTableView(tblDeck.getTable()); + + this.setTableCatalog(tblCatalog); + this.setTableDeck(tblDeck); + + final Lambda0 newCreator = new Lambda0() { + @Override + public Deck apply() { + return new Deck(); + } + }; + this.controller = new DeckController(questData0.getMyDecks(), this, newCreator); + } + + /** + * Adds any card to the catalog and data pool. + * + * @param card {@link forge.item.CardPrinted} + */ + public void addCheatCard(final CardPrinted card) { + this.getTableCatalog().addCard(card); + this.questData.getCards().getCardpool().add(card); + } + + //=========== Overridden from ACEditorBase + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#addCard() + */ + @Override + public void addCard() { + final InventoryItem item = this.getTableCatalog().getSelectedCard(); + if ((item == null) || !(item instanceof CardPrinted)) { + return; + } + + final CardPrinted card = (CardPrinted) item; + this.getTableCatalog().removeCard(card); + this.getTableDeck().addCard(card); + this.controller.notifyModelChanged(); + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#removeCard() + */ + @Override + public void removeCard() { + final InventoryItem item = this.getTableDeck().getSelectedCard(); + if ((item == null) || !(item instanceof CardPrinted)) { + return; + } + + final CardPrinted card = (CardPrinted) item; + this.getTableCatalog().addCard(card); + this.getTableDeck().removeCard(card); + } + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#updateView() + */ + @Override + public void resetTables() { + final Deck deck = this.controller.getModel(); + + final ItemPool cardpool = new ItemPool(CardPrinted.class); + cardpool.addAll(this.questData.getCards().getCardpool()); + // remove bottom cards that are in the deck from the card pool + cardpool.removeAll(deck.getMain()); + // show cards, makes this user friendly + this.getTableCatalog().setDeck(cardpool); + this.getTableDeck().setDeck(deck.getMain()); + } + + //=========== Overridden from ACEditorBase + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#getController() + */ + @Override + public DeckController getDeckController() { + return this.controller; + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#show(forge.Command) + */ + @Override + public void init() { + final List> columnsCatalog = SColumnUtil.getCatalogDefaultColumns(); + final List> columnsDeck = SColumnUtil.getDeckDefaultColumns(); + + // Add "new" column in catalog and deck + columnsCatalog.add(SColumnUtil.getColumn(ColumnName.CAT_NEW)); + + columnsCatalog.get(columnsCatalog.size() - 1).setSortAndDisplayFunctions( + this.questData.getCards().getFnNewCompare(), + this.questData.getCards().getFnNewGet()); + + columnsDeck.add(SColumnUtil.getColumn(ColumnName.DECK_NEW)); + + columnsDeck.get(columnsDeck.size() - 1).setSortAndDisplayFunctions( + this.questData.getCards().getFnNewCompare(), + this.questData.getCards().getFnNewGet()); + + this.getTableCatalog().setup(VCardCatalog.SINGLETON_INSTANCE, columnsCatalog); + this.getTableDeck().setup(VCurrentDeck.SINGLETON_INSTANCE, columnsDeck); + + Deck deck = Constant.Runtime.HUMAN_DECK[0] == null ? null : this.questData.getMyDecks().get( + Constant.Runtime.HUMAN_DECK[0].getName()); + + if (deck == null) { + deck = new Deck(); + } + + this.getDeckController().setModel(deck); + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.controllers.ACEditorBase#exit() + */ + @Override + public boolean exit() { + final boolean okToExit = SEditorIO.confirmSaveChanges(); + if (okToExit) { + AllZone.getQuest().save(); + CSubmenuQuestDecks.SINGLETON_INSTANCE.update(); + } + return okToExit; + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java new file mode 100644 index 00000000000..6b2496a7116 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java @@ -0,0 +1,368 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package forge.gui.deckeditor.controllers; + +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.swing.JLabel; +import javax.swing.JOptionPane; + +import forge.AllZone; +import forge.deck.Deck; +import forge.deck.DeckBase; +import forge.gui.CardListViewer; +import forge.gui.deckeditor.SEditorIO; +import forge.gui.deckeditor.SEditorUtil; +import forge.gui.deckeditor.tables.DeckController; +import forge.gui.deckeditor.tables.SColumnUtil; +import forge.gui.deckeditor.tables.SColumnUtil.ColumnName; +import forge.gui.deckeditor.tables.TableColumnInfo; +import forge.gui.deckeditor.tables.TableView; +import forge.gui.deckeditor.views.VCardCatalog; +import forge.gui.deckeditor.views.VCurrentDeck; +import forge.gui.home.quest.CSubmenuQuestDecks; +import forge.gui.home.quest.SSubmenuQuestUtil; +import forge.item.BoosterPack; +import forge.item.CardPrinted; +import forge.item.FatPack; +import forge.item.InventoryItem; +import forge.item.ItemPool; +import forge.item.ItemPoolView; +import forge.item.OpenablePack; +import forge.item.PreconDeck; +import forge.item.TournamentPack; +import forge.quest.QuestController; +import forge.quest.io.ReadPriceList; +import forge.util.closures.Lambda1; + +/** + * Child controller for quest card shop UI. + * + *

(C at beginning of class name denotes a control class.) + * + * @author Forge + * @version $Id: CEditorQuestCardShop.java 15088 2012-04-07 11:34:05Z Max mtg $ + */ +public final class CEditorQuestCardShop extends ACEditorBase { + private final JLabel creditsLabel = new JLabel(); + private final JLabel sellPercentageLabel = new JLabel(); + private double multiplier; + private final QuestController questData; + + // get pricelist: + private final ReadPriceList r = new ReadPriceList(); + private final Map mapPrices = this.r.getPriceList(); + private Map decksUsingMyCards; + + /** + * Child controller for quest card shop UI. + * + * @param qd + * a {@link forge.quest.data.QuestData} object. + */ + public CEditorQuestCardShop(final QuestController qd) { + this.questData = qd; + + final TableView tblCatalog = new TableView(false, InventoryItem.class); + final TableView tblDeck = new TableView(false, InventoryItem.class); + + VCardCatalog.SINGLETON_INSTANCE.setTableView(tblCatalog.getTable()); + VCurrentDeck.SINGLETON_INSTANCE.setTableView(tblDeck.getTable()); + + this.setTableCatalog(tblCatalog); + this.setTableDeck(tblDeck); + } + + /** + *

+ * setup. + *

+ */ + private void setup() { + final List> columnsCatalog = SColumnUtil.getCatalogDefaultColumns(); + final List> columnsDeck = SColumnUtil.getDeckDefaultColumns(); + + // Add "price", "decks", and "new" column in catalog and deck + columnsCatalog.add(SColumnUtil.getColumn(ColumnName.CAT_PURCHASE_PRICE)); + columnsCatalog.get(columnsCatalog.size() - 1).setSortAndDisplayFunctions( + this.fnPriceCompare, this.fnPriceGet); + + columnsCatalog.add(SColumnUtil.getColumn(ColumnName.CAT_DECKS)); + columnsCatalog.get(columnsCatalog.size() - 1).setSortAndDisplayFunctions( + this.fnDeckCompare, this.fnDeckGet); + + columnsCatalog.add(SColumnUtil.getColumn(ColumnName.CAT_NEW)); + columnsCatalog.get(columnsCatalog.size() - 1).setSortAndDisplayFunctions( + this.questData.getCards().getFnNewCompare(), this.questData.getCards().getFnNewGet()); + + columnsDeck.add(SColumnUtil.getColumn(ColumnName.DECK_SALE_PRICE)); + columnsDeck.get(columnsDeck.size() - 1).setSortAndDisplayFunctions( + this.fnPriceCompare, this.fnPriceSellGet); + + columnsDeck.add(SColumnUtil.getColumn(ColumnName.DECK_NEW)); + columnsDeck.get(columnsDeck.size() - 1).setSortAndDisplayFunctions( + this.questData.getCards().getFnNewCompare(), this.questData.getCards().getFnNewGet()); + + // Setup with current column set + this.getTableCatalog().setup(VCardCatalog.SINGLETON_INSTANCE, columnsCatalog); + this.getTableDeck().setup(VCurrentDeck.SINGLETON_INSTANCE, columnsDeck); + + SEditorUtil.resetUI(); + VCardCatalog.SINGLETON_INSTANCE.getPnlHeader().setVisible(false); + VCurrentDeck.SINGLETON_INSTANCE.getPnlHeader().setVisible(false); + } + + // fills number of decks using each card + private Map countDecksForEachCard() { + final Map result = new HashMap(); + for (final Deck deck : this.questData.getMyDecks()) { + for (final Entry e : deck.getMain()) { + final CardPrinted card = e.getKey(); + final Integer amount = result.get(card); + result.put(card, Integer.valueOf(amount == null ? 1 : 1 + amount.intValue())); + } + } + return result; + } + + private Integer getCardValue(final InventoryItem card) { + if (this.mapPrices.containsKey(card.getName())) { + return this.mapPrices.get(card.getName()); + } else if (card instanceof CardPrinted) { + switch (((CardPrinted) card).getRarity()) { + case BasicLand: + return Integer.valueOf(4); + case Common: + return Integer.valueOf(6); + case Uncommon: + return Integer.valueOf(40); + case Rare: + return Integer.valueOf(120); + case MythicRare: + return Integer.valueOf(600); + default: + return Integer.valueOf(15); + } + } else if (card instanceof BoosterPack) { + return 395; + } else if (card instanceof TournamentPack) { + return 995; + } else if (card instanceof FatPack) { + return 2365; + } else if (card instanceof PreconDeck) { + return ((PreconDeck) card).getRecommendedDeals().getCost(); + } + return 1337; + } + + @SuppressWarnings("rawtypes") + private final Lambda1> fnPriceCompare = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return CEditorQuestCardShop.this.getCardValue(from.getKey()); + } + }; + private final Lambda1> fnPriceGet = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return CEditorQuestCardShop.this.getCardValue(from.getKey()); + } + }; + private final Lambda1> fnPriceSellGet = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return (int) (CEditorQuestCardShop.this.multiplier * CEditorQuestCardShop.this.getCardValue(from.getKey())); + } + }; + + @SuppressWarnings("rawtypes") + private final Lambda1> fnDeckCompare = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + final Integer iValue = CEditorQuestCardShop.this.decksUsingMyCards.get(from.getKey()); + return iValue == null ? Integer.valueOf(0) : iValue; + } + }; + private final Lambda1> fnDeckGet = new Lambda1>() { + @Override + public Object apply(final Entry from) { + final Integer iValue = CEditorQuestCardShop.this.decksUsingMyCards.get(from.getKey()); + return iValue == null ? "" : iValue.toString(); + } + }; + + //=========== Overridden from ACEditorBase + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#addCard() + */ + @Override + public void addCard() { + final InventoryItem item = this.getTableCatalog().getSelectedCard(); + if (item == null) { + return; + } + + final int value = this.getCardValue(item); + + if (value <= this.questData.getAssets().getCredits()) { + + if (item instanceof CardPrinted) { + this.getTableCatalog().removeCard(item); + + final CardPrinted card = (CardPrinted) item; + this.getTableDeck().addCard(card); + this.questData.getCards().buyCard(card, value); + + } else if (item instanceof OpenablePack) { + this.getTableCatalog().removeCard(item); + + OpenablePack booster = null; + if (item instanceof BoosterPack) { + booster = (BoosterPack) ((BoosterPack) item).clone(); + } else if (item instanceof TournamentPack) { + booster = (TournamentPack) ((TournamentPack) item).clone(); + } else if (item instanceof FatPack) { + booster = (FatPack) ((FatPack) item).clone(); + } + this.questData.getCards().buyPack(booster, value); + final List newCards = booster.getCards(); + for (final CardPrinted card : newCards) { + this.getTableDeck().addCard(card); + } + final CardListViewer c = new CardListViewer(booster.getName(), + "You have found the following cards inside:", newCards); + c.show(); + } else if (item instanceof PreconDeck) { + this.getTableCatalog().removeCard(item); + final PreconDeck deck = (PreconDeck) item; + this.questData.getCards().buyPreconDeck(deck, value); + + for (final CardPrinted card : deck.getDeck().getMain().toFlatList()) { + this.getTableDeck().addCard(card); + } + JOptionPane.showMessageDialog(null, String.format( + "Deck '%s' was added to your decklist.%n%nCards from it were also added to your pool.", + deck.getName()), "Thanks for purchasing!", JOptionPane.INFORMATION_MESSAGE); + + } + + this.creditsLabel.setText("Credits: " + this.questData.getAssets().getCredits()); + } else { + JOptionPane.showMessageDialog(null, "Not enough credits!"); + } + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#removeCard() + */ + @Override + public void removeCard() { + final InventoryItem item = this.getTableDeck().getSelectedCard(); + if ((item == null) || !(item instanceof CardPrinted)) { + return; + } + + final CardPrinted card = (CardPrinted) item; + this.getTableDeck().removeCard(card); + this.getTableCatalog().addCard(card); + + final int price = Math.min((int) (this.multiplier * this.getCardValue(card)), this.questData.getCards() + .getSellPriceLimit()); + this.questData.getCards().sellCard(card, price); + + this.creditsLabel.setText("Credits: " + this.questData.getAssets().getCredits()); + } + + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#resetTables() + */ + @Override + public void resetTables() { + } + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#getController() + */ + @Override + public DeckController getDeckController() { + return null; + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#show(forge.Command) + */ + @Override + public void init() { + this.setup(); + + this.decksUsingMyCards = this.countDecksForEachCard(); + + this.multiplier = this.questData.getCards().getSellMultiplier(); + + ItemPoolView forSale = this.questData.getCards().getShopList(); + if (forSale.isEmpty()) { + this.questData.getCards().generateCardsInShop(); + forSale = this.questData.getCards().getShopList(); + } + + // newCardsList = questData.getCards().getNewCards(); + final ItemPool ownedItems = new ItemPool(InventoryItem.class); + ownedItems.addAll(this.questData.getCards().getCardpool().getView()); + + this.getTableCatalog().setDeck(forSale); + this.getTableDeck().setDeck(ownedItems); + + this.creditsLabel.setText("Credits: " + this.questData.getAssets().getCredits()); + + final double multiPercent = this.multiplier * 100; + final NumberFormat formatter = new DecimalFormat("#0.00"); + String maxSellingPrice = ""; + final int maxSellPrice = this.questData.getCards().getSellPriceLimit(); + + if (maxSellPrice < Integer.MAX_VALUE) { + maxSellingPrice = String.format("Maximum selling price is %d credits.", maxSellPrice); + } + this.sellPercentageLabel.setText("Selling cards at " + formatter.format(multiPercent) + + "% of their value.
" + maxSellingPrice + ""); + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.controllers.ACEditorBase#exit() + */ + @Override + public boolean exit() { + final boolean okToExit = SEditorIO.confirmSaveChanges(); + if (okToExit) { + SSubmenuQuestUtil.updateStatsAndPet(); + AllZone.getQuest().save(); + CSubmenuQuestDecks.SINGLETON_INSTANCE.update(); + } + return okToExit; + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CFilters.java b/src/main/java/forge/gui/deckeditor/controllers/CFilters.java new file mode 100644 index 00000000000..4e26a9ca0e2 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CFilters.java @@ -0,0 +1,176 @@ +package forge.gui.deckeditor.controllers; + +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.util.ArrayList; +import java.util.List; + +import forge.Command; +import forge.deck.DeckBase; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.SFilterUtil; +import forge.gui.deckeditor.views.VFilters; +import forge.gui.framework.ICDoc; +import forge.gui.toolbox.FLabel; +import forge.item.CardPrinted; +import forge.item.InventoryItem; +import forge.util.closures.Predicate; + +/** + * Controls the "filters" panel in the deck editor UI. + * + *

(C at beginning of class name denotes a control class.) + * + */ +public enum CFilters implements ICDoc { + /** */ + SINGLETON_INSTANCE; + + private boolean filtersAllEnabled = true; + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#getCommandOnSelect() + */ + @Override + public Command getCommandOnSelect() { + return null; + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#initialize() + */ + @SuppressWarnings("serial") + @Override + public void initialize() { + final ItemListener iliFilter = new ItemListener() { + @Override + public void itemStateChanged(final ItemEvent arg0) { + if (!SFilterUtil.isFilteringPrevented()) { + buildFilter(); + } + } + }; + + VFilters.SINGLETON_INSTANCE.getCbxSets().addItemListener(iliFilter); + VFilters.SINGLETON_INSTANCE.getCbxPLow().addItemListener(iliFilter); + VFilters.SINGLETON_INSTANCE.getCbxPHigh().addItemListener(iliFilter); + VFilters.SINGLETON_INSTANCE.getCbxTLow().addItemListener(iliFilter); + VFilters.SINGLETON_INSTANCE.getCbxTHigh().addItemListener(iliFilter); + VFilters.SINGLETON_INSTANCE.getCbxCMCLow().addItemListener(iliFilter); + VFilters.SINGLETON_INSTANCE.getCbxCMCHigh().addItemListener(iliFilter); + + ((FLabel) VFilters.SINGLETON_INSTANCE.getBtnToggle()).setCommand(new Command() { + @Override + public void execute() { + SFilterUtil.setPreventFiltering(true); + toggleColorTypeSetFilter(); + SFilterUtil.setPreventFiltering(false); + buildFilter(); + } + }); + + ((FLabel) VFilters.SINGLETON_INSTANCE.getBtnResetIntervals()).setCommand(new Command() { + @Override + public void execute() { + SFilterUtil.setPreventFiltering(true); + VFilters.SINGLETON_INSTANCE.getCbxPLow().setSelectedIndex(0); + VFilters.SINGLETON_INSTANCE.getCbxTLow().setSelectedIndex(0); + VFilters.SINGLETON_INSTANCE.getCbxCMCLow().setSelectedIndex(0); + + VFilters.SINGLETON_INSTANCE.getCbxPHigh().setSelectedIndex( + VFilters.SINGLETON_INSTANCE.getCbxPHigh().getItemCount() - 1); + VFilters.SINGLETON_INSTANCE.getCbxTHigh().setSelectedIndex( + VFilters.SINGLETON_INSTANCE.getCbxTHigh().getItemCount() - 1); + VFilters.SINGLETON_INSTANCE.getCbxCMCHigh().setSelectedIndex( + VFilters.SINGLETON_INSTANCE.getCbxCMCHigh().getItemCount() - 1); + + SFilterUtil.setPreventFiltering(false); + buildFilter(); + } + }); + + ((FLabel) VFilters.SINGLETON_INSTANCE.getBtnResetText()).setCommand(new Command() { + @Override + public void execute() { + VFilters.SINGLETON_INSTANCE.getTxfContains().setText(""); + VFilters.SINGLETON_INSTANCE.getTxfWithout().setText(""); + buildFilter(); + } + }); + + VFilters.SINGLETON_INSTANCE.getTxfContains().addKeyListener(new KeyAdapter() { + @Override + public void keyReleased(final KeyEvent e) { + if (e.getKeyCode() == 10) { buildFilter(); } + } + }); + + VFilters.SINGLETON_INSTANCE.getTxfWithout().addKeyListener(new KeyAdapter() { + @Override + public void keyReleased(final KeyEvent e) { + if (e.getKeyCode() == 10) { buildFilter(); } + } + }); + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#update() + */ + @Override + public void update() { + } + + /** + * Clear filter button_action performed. + * + * @param e + * the e + */ + private void toggleColorTypeSetFilter() { + VFilters.SINGLETON_INSTANCE.getCbxSets().setSelectedIndex(0); + + if (filtersAllEnabled) { + filtersAllEnabled = false; + SFilterUtil.toggleColorCheckboxes(false); + SFilterUtil.toggleTypeCheckboxes(false); + } + else { + filtersAllEnabled = true; + SFilterUtil.toggleColorCheckboxes(true); + SFilterUtil.toggleTypeCheckboxes(true); + } + } + + //=========== + + /** + * + * Assembles filter from the ones available. To prevent a block + * of filters from being used, set its parent panel's visibility to false. + * + * @param   extends InventoryItem + * @param   extends DeckBase + */ + @SuppressWarnings("unchecked") + public void buildFilter() { + // The main trick here is to apply a CardPrinted predicate + // to the table. CardRules will lead to difficulties. + final List> lstFilters = new ArrayList>(); + + final ACEditorBase ed = (ACEditorBase) + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController(); + + lstFilters.add(SFilterUtil.buildColorFilter()); + lstFilters.add(SFilterUtil.buildTypeFilter()); + lstFilters.add(SFilterUtil.buildSetAndFormatFilter()); + lstFilters.add(SFilterUtil.buildTextFilter()); + lstFilters.add(SFilterUtil.buildIntervalFilter()); + + // Apply to table + ed.getTableCatalog().setFilter((Predicate) Predicate.and(lstFilters)); + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CProbabilities.java b/src/main/java/forge/gui/deckeditor/controllers/CProbabilities.java new file mode 100644 index 00000000000..63241562caa --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CProbabilities.java @@ -0,0 +1,100 @@ +package forge.gui.deckeditor.controllers; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import forge.Command; +import forge.deck.DeckBase; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.SEditorUtil; +import forge.gui.deckeditor.views.VProbabilities; +import forge.gui.framework.ICDoc; +import forge.gui.toolbox.FLabel; +import forge.item.CardPrinted; +import forge.item.InventoryItem; +import forge.item.ItemPool; +import forge.item.ItemPoolView; +import forge.util.MyRandom; + +/** + * Controls the "analysis" panel in the deck editor UI. + * + *

(C at beginning of class name denotes a control class.) + * + */ +public enum CProbabilities implements ICDoc { + /** */ + SINGLETON_INSTANCE; + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#getCommandOnSelect() + */ + @Override + public Command getCommandOnSelect() { + return null; + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#initialize() + */ + @Override + @SuppressWarnings("serial") + public void initialize() { + ((FLabel) VProbabilities.SINGLETON_INSTANCE.getLblReshuffle()).setCommand( + new Command() { @Override public void execute() { update(); } }); + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#update() + */ + @Override + public void update() { + VProbabilities.SINGLETON_INSTANCE.rebuildLabels(analyze()); + } + + //========== Other methods + @SuppressWarnings("unchecked") + private List analyze() { + final ACEditorBase ed = (ACEditorBase) + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController(); + + final ItemPoolView deck = ItemPool.createFrom( + ed.getTableDeck().getCards(), CardPrinted.class); + + final List cardProbabilities = new ArrayList(); + + final List shuffled = deck.toFlatList(); + Collections.shuffle(shuffled, MyRandom.getRandom()); + + // Log totals of each card for decrementing + final Map cardTotals = new HashMap(); + for (final CardPrinted c : shuffled) { + if (cardTotals.containsKey(c)) { cardTotals.put(c, cardTotals.get(c) + 1); } + else { cardTotals.put(c, 1); } + } + + // Run through shuffled deck and calculate probabilities. + // Formulas is (remaining instances of this card / total cards remaining) + final Iterator itr = shuffled.iterator(); + CardPrinted tmp; + int prob; + while (itr.hasNext()) { + tmp = itr.next(); + + prob = SEditorUtil.calculatePercentage( + cardTotals.get(tmp), shuffled.size()); + + cardTotals.put(tmp, cardTotals.get(tmp) - 1); + cardProbabilities.add(tmp.getName() + " (" + prob + "%)"); + itr.remove(); + } + + return cardProbabilities; + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CStatistics.java b/src/main/java/forge/gui/deckeditor/controllers/CStatistics.java new file mode 100644 index 00000000000..71e26e70f9f --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CStatistics.java @@ -0,0 +1,191 @@ +package forge.gui.deckeditor.controllers; + +import java.util.Map.Entry; + +import forge.Command; +import forge.card.CardColor; +import forge.card.CardRules; +import forge.card.CardRules.Predicates; +import forge.deck.DeckBase; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.SEditorUtil; +import forge.gui.deckeditor.views.VStatistics; +import forge.gui.framework.ICDoc; +import forge.item.CardPrinted; +import forge.item.InventoryItem; +import forge.item.ItemPool; +import forge.item.ItemPoolView; +import forge.util.closures.Predicate; + +/** + * Controls the "analysis" panel in the deck editor UI. + * + *

(C at beginning of class name denotes a control class.) + * + */ +public enum CStatistics implements ICDoc { + /** */ + SINGLETON_INSTANCE; + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#getCommandOnSelect() + */ + @Override + public Command getCommandOnSelect() { + return null; + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#initialize() + */ + @Override + public void initialize() { + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#update() + */ + @Override + public void update() { + analyze(); + } + + //========== Other methods + @SuppressWarnings("unchecked") + private void analyze() { + final ACEditorBase ed = (ACEditorBase) + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController(); + + if (ed == null) { return; } + + final ItemPoolView deck = ItemPool.createFrom( + ed.getTableDeck().getCards(), CardPrinted.class); + + int tmp = 0; + int total = deck.countAll(); + + // Hack-ish: avoid /0 cases, but still populate labels :) + if (total == 0) { total = 1; } + + tmp = CardRules.Predicates.Presets.IS_MULTICOLOR + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblMulti().setText(String.valueOf(tmp)); + + tmp = CardRules.Predicates.Presets.IS_CREATURE + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblCreature().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = CardRules.Predicates.Presets.IS_LAND + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblLand().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = CardRules.Predicates.Presets.IS_ENCHANTMENT + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblEnchantment().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = CardRules.Predicates.Presets.IS_ARTIFACT + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblArtifact().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = CardRules.Predicates.Presets.IS_INSTANT + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblInstant().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = CardRules.Predicates.Presets.IS_SORCERY + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblSorcery().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = CardRules.Predicates.Presets.IS_PLANESWALKER + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblPlaneswalker().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = CardRules.Predicates.Presets.IS_COLORLESS + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblColorless().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = Predicate.and( + Predicates.isColor(CardColor.BLACK), + Predicates.hasCntColors((byte) 1)) + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblBlack().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = Predicate.and( + Predicates.isColor(CardColor.BLUE), + Predicates.hasCntColors((byte) 1)) + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblBlue().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = Predicate.and( + Predicates.isColor(CardColor.GREEN), + Predicates.hasCntColors((byte) 1)) + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblGreen().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = Predicate.and( + Predicates.isColor(CardColor.RED), + Predicates.hasCntColors((byte) 1)) + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblRed().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = Predicate.and( + Predicates.isColor(CardColor.WHITE), + Predicates.hasCntColors((byte) 1)) + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblWhite().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + int cmc0 = 0, cmc1 = 0, cmc2 = 0, cmc3 = 0, cmc4 = 0, cmc5 = 0, cmc6 = 0; + int tmc = 0; + + for (final Entry e : deck) { + final CardRules cardRules = e.getKey().getCard(); + final int count = e.getValue(); + final int cmc = cardRules.getManaCost().getCMC(); + + if (cmc == 0) { cmc0 += count; } + else if (cmc == 1) { cmc1 += count; } + else if (cmc == 2) { cmc2 += count; } + else if (cmc == 3) { cmc3 += count; } + else if (cmc == 4) { cmc4 += count; } + else if (cmc == 5) { cmc5 += count; } + else if (cmc >= 6) { cmc6 += count; } + + tmc += (cmc * count); + } + + VStatistics.SINGLETON_INSTANCE.getLblCMC0().setText( + cmc0 + " (" + SEditorUtil.calculatePercentage(cmc0, total) + "%)"); + VStatistics.SINGLETON_INSTANCE.getLblCMC1().setText( + cmc1 + " (" + SEditorUtil.calculatePercentage(cmc1, total) + "%)"); + VStatistics.SINGLETON_INSTANCE.getLblCMC2().setText( + cmc2 + " (" + SEditorUtil.calculatePercentage(cmc2, total) + "%)"); + VStatistics.SINGLETON_INSTANCE.getLblCMC3().setText( + cmc3 + " (" + SEditorUtil.calculatePercentage(cmc3, total) + "%)"); + VStatistics.SINGLETON_INSTANCE.getLblCMC4().setText( + cmc4 + " (" + SEditorUtil.calculatePercentage(cmc4, total) + "%)"); + VStatistics.SINGLETON_INSTANCE.getLblCMC5().setText( + cmc5 + " (" + SEditorUtil.calculatePercentage(cmc5, total) + "%)"); + VStatistics.SINGLETON_INSTANCE.getLblCMC6().setText( + cmc6 + " (" + SEditorUtil.calculatePercentage(cmc6, total) + "%)"); + + double amc = (double) Math.round((double) tmc / (double) total * 100) / 100.0d; + + VStatistics.SINGLETON_INSTANCE.getLblTotal().setText("TOTAL CARDS: " + deck.countAll()); + VStatistics.SINGLETON_INSTANCE.getLblTMC().setText("TOTAL MANA COST: " + tmc); + VStatistics.SINGLETON_INSTANCE.getLblAMC().setText("AVERAGE MANA COST: " + amc); + } +} diff --git a/src/main/java/forge/gui/deckeditor/elements/CardPanelBase.java b/src/main/java/forge/gui/deckeditor/elements/CardPanelBase.java deleted file mode 100644 index 046831f4a48..00000000000 --- a/src/main/java/forge/gui/deckeditor/elements/CardPanelBase.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.gui.deckeditor.elements; - -import javax.swing.JPanel; - -import forge.item.InventoryItem; - -/** - * Base class for any cardView panel. - * - */ -public abstract class CardPanelBase extends JPanel { - private static final long serialVersionUID = -2230733670423143126L; - - /** - * - * showCard. - * - * @param card - * an InventoryItem - */ - public abstract void showCard(InventoryItem card); - -} diff --git a/src/main/java/forge/gui/deckeditor/elements/CardPanelHeavy.java b/src/main/java/forge/gui/deckeditor/elements/CardPanelHeavy.java deleted file mode 100644 index c43ad008062..00000000000 --- a/src/main/java/forge/gui/deckeditor/elements/CardPanelHeavy.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.gui.deckeditor.elements; - -import java.awt.event.ActionEvent; -import java.io.File; - -import javax.swing.JButton; -import javax.swing.JOptionPane; - -import net.miginfocom.swing.MigLayout; -import forge.Card; -import forge.CardCharactersticName; -import forge.gui.CardDetailPanel; -import forge.gui.GuiDisplayUtil; -import forge.item.CardPrinted; -import forge.item.InventoryItem; -import forge.properties.ForgeProps; -import forge.properties.NewConstants; -import forge.view.arcane.CardPanel; -import forge.view.arcane.ViewPanel; - -/** - * This panel is to be placed in the right part of a deck editor. - */ -public class CardPanelHeavy extends CardPanelBase { - - private static final long serialVersionUID = -7134546689397508597L; - - private final JButton changeStateButton = new JButton(); - - /* - * Removed Oct 25 2011 - Hellfish private JButton changePictureButton = new - * JButton(); private JButton removePictureButton = new JButton(); - */ - - // Controls to show card details - /** The detail. */ - private final CardDetailPanel detail = new CardDetailPanel(null); - - /** The picture. */ - private final CardPanel picture = new CardPanel(null); - - /** The picture view panel. */ - private final ViewPanel pictureViewPanel = new ViewPanel(); - - // fake card to allow picture changes - /** The c card hq. */ - private Card cCardHQ; - - /** Constant previousDirectory. */ - // private static File previousDirectory = null; - - /** - * Instantiates a new card panel heavy. - */ - public CardPanelHeavy() { - this.changeStateButton.setVisible(false); - this.changeStateButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - CardPanelHeavy.this.changeStateButtonActionPerformed(e); - } - }); - this.changeStateButton.setFont(new java.awt.Font("Dialog", 0, 10)); - - /* - * Removed Oct 25 2011 - Hellfish - * changePictureButton.setText("Change picture..."); - * changePictureButton.addActionListener(new - * java.awt.event.ActionListener() { public void - * actionPerformed(ActionEvent e) { - * changePictureButton_actionPerformed(e); } }); if - * (!Singletons.getModel().getPreferences().lafFonts) - * changePictureButton.setFont(new java.awt.Font("Dialog", 0, 10)); - * - * removePictureButton.setText("Remove picture..."); - * removePictureButton.addActionListener(new - * java.awt.event.ActionListener() { public void - * actionPerformed(ActionEvent e) { - * removePictureButton_actionPerformed(e); } }); if - * (!Singletons.getModel().getPreferences().lafFonts) - * removePictureButton.setFont(new java.awt.Font("Dialog", 0, 10)); - */ - - this.pictureViewPanel.setCardPanel(this.picture); - - this.setLayout(new MigLayout("fill, ins 0")); - this.add(this.detail, "w 239, h 323, grow, flowy, wrap"); - /* - * Removed Oct 25 2011 - Hellfish this.add(changeStateButton, - * "align 50% 0%, split 3, flowx"); this.add(changePictureButton, - * "align 50% 0%"); this.add(removePictureButton, "align 50% 0%, wrap"); - */ - this.add(this.changeStateButton, "align 50% 0%, flowx, wrap"); - this.add(this.pictureViewPanel, "wmin 239, hmin 323, grow"); - } - - /* - * (non-Javadoc) - * - * @see - * forge.gui.deckeditor.CardPanelBase#showCard(forge.item.InventoryItem) - */ - @Override - public final void showCard(final InventoryItem card) { - final Card card2 = card instanceof CardPrinted ? ((CardPrinted) card).toForgeCard() : null; - this.detail.setCard(card2); - this.setCard(card2); - } - - /** - * Sets the card. - * - * @param c - * the new card - */ - public final void setCard(final Card c) { - if (this.picture.getCard() != null) { - if (this.picture.getCard().isInAlternateState()) { - this.picture.getCard().setState(CardCharactersticName.Original); - } - } - this.picture.setCard(c); - - if (c.isFlip()) { - this.changeStateButton.setVisible(true); - this.changeStateButton.setText("Flip"); - } else if (c.isDoubleFaced()) { - this.changeStateButton.setVisible(true); - this.changeStateButton.setText("Transform"); - } else { - this.changeStateButton.setVisible(false); - } - } - - /** - *

- * changeStateButton_actionPerformed. - *

- * - * @param e - * a {@link java.awt.event.ActionEvent} object. - */ - final void changeStateButtonActionPerformed(final ActionEvent e) { - final Card cur = this.picture.getCard(); - if (cur.isInAlternateState()) { - cur.setState(CardCharactersticName.Original); - } else { - if (cur.isFlip()) { - cur.setState(CardCharactersticName.Flipped); - } - if (cur.isDoubleFaced()) { - cur.setState(CardCharactersticName.Transformed); - } - } - - this.picture.setCard(cur); - this.detail.setCard(cur); - } - - /** - *

- * getImportFilename. - *

- * - * @param e - * the e - * @return a {@link java.io.File} object. - */ - /* - * private File getImportFilename() { final JFileChooser chooser = new - * JFileChooser(CardPanelHeavy.previousDirectory); final ImagePreviewPanel - * preview = new ImagePreviewPanel(); chooser.setAccessory(preview); - * chooser.addPropertyChangeListener(preview); - * chooser.addChoosableFileFilter(this.dckFilter); final int returnVal = - * chooser.showOpenDialog(null); - * - * if (returnVal == JFileChooser.APPROVE_OPTION) { final File file = - * chooser.getSelectedFile(); CardPanelHeavy.previousDirectory = - * file.getParentFile(); return file; } - * - * return null; - * - * } - */ - - /** The dck filter. */ - /* - * private final FileFilter dckFilter = new FileFilter() { - * - * @Override public boolean accept(final File f) { return - * f.getName().endsWith(".jpg") || f.isDirectory(); } - * - * @Override public String getDescription() { return "*.jpg"; } - * - * }; - */ - - /** - *

- * removePictureButton_actionPerformed - *

- * . Removed Oct 25 2011 - Hellfish - * - * @param e - * the e - */ - final void removePictureButtonActionPerformed(final ActionEvent e) { - if (this.cCardHQ != null) { - final String[] options = { "Yes", "No" }; - final int value = JOptionPane.showOptionDialog(null, "Do you want delete " + this.cCardHQ.getName() - + " picture?", "Delete picture", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, - options, options[1]); - if (value == 0) { - final String fileName = GuiDisplayUtil.cleanString(this.cCardHQ.getName()) + ".jpg"; - final File base = ForgeProps.getFile(NewConstants.IMAGE_BASE); - final File f = new File(base, fileName); - f.delete(); - JOptionPane.showMessageDialog(null, "Picture " + this.cCardHQ.getName() + " deleted.", - "Delete picture", JOptionPane.INFORMATION_MESSAGE); - this.setCard(this.cCardHQ); - } - } - } - - /** - * Gets the card. - * - * @return the card - */ - public final Card getCard() { - return this.detail.getCard(); - } - -} diff --git a/src/main/java/forge/gui/deckeditor/elements/CardPanelLite.java b/src/main/java/forge/gui/deckeditor/elements/CardPanelLite.java deleted file mode 100644 index b6f927819bd..00000000000 --- a/src/main/java/forge/gui/deckeditor/elements/CardPanelLite.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.gui.deckeditor.elements; - -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -import javax.swing.JButton; -import javax.swing.JScrollPane; -import javax.swing.JTextPane; - -import net.miginfocom.swing.MigLayout; - -import org.apache.commons.lang3.StringUtils; - -import forge.Card; -import forge.CardCharactersticName; -import forge.Singletons; -import forge.card.CardEdition; -import forge.gui.CardDetailPanel; -import forge.gui.CardPicturePanel; -import forge.item.CardPrinted; -import forge.item.InventoryItem; -import forge.item.OpenablePack; -import forge.item.PreconDeck; - -/** - * This panel is to be placed in the right part of a deck editor. - * - */ -public class CardPanelLite extends CardPanelBase { - - private static final long serialVersionUID = -7134546689397508597L; - - // Controls to show card details - /** The detail. */ - private final CardDetailPanel detail = new CardDetailPanel(null); - private final CardPicturePanel picture = new CardPicturePanel(null); - private final JButton bChangeState = new JButton(); - private final JTextPane description = new JTextPane(); - private final JScrollPane descrScroll; - - /** - * - * Constructor. - */ - public CardPanelLite() { - this.bChangeState.setVisible(false); - this.bChangeState.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - CardPanelLite.this.bChangeStateActionPerformed(e); - } - }); - this.bChangeState.setFont(new java.awt.Font("Dialog", 0, 10)); - - this.descrScroll = new JScrollPane(this.description); - - this.setLayout(new MigLayout("fill, ins 0")); - this.add(this.detail, "w 239, h 303, grow, flowy, wrap"); - this.add(this.descrScroll, "w 239, h 303, grow, flowy, wrap"); - this.add(this.bChangeState, "align 50% 0%, wrap"); - this.add(this.picture, "wmin 239, hmin 323, grow"); - - this.description.setEditable(false); - this.description.setCursor(null); - this.description.setOpaque(false); - this.description.setFocusable(false); - } - - private static Dimension shrinkedComponent = new Dimension(239, 0); - private static Dimension expandedComponent = new Dimension(239, 303); - - /** - * - * ShowCard. - * - * @param card - * an InventoryItem - */ - @Override - public final void showCard(final InventoryItem card) { - this.picture.setCard(card); - final boolean isCard = (card != null) && (card instanceof CardPrinted); - this.detail.setVisible(isCard); - this.description.setVisible(!isCard); - this.descrScroll.setMaximumSize(isCard ? CardPanelLite.shrinkedComponent : CardPanelLite.expandedComponent); - this.detail.setMaximumSize(!isCard ? CardPanelLite.shrinkedComponent : CardPanelLite.expandedComponent); - if (isCard) { - final Card toSet = ((CardPrinted) card).toForgeCard(); - - this.detail.setCard(toSet); - if (toSet.hasAlternateState()) { - this.bChangeState.setVisible(true); - if (toSet.isFlip()) { - this.bChangeState.setText("Flip"); - } else { - this.bChangeState.setText("Transform"); - } - } - } else { - if (card instanceof OpenablePack) { - final OpenablePack booster = (OpenablePack) card; - final CardEdition set = Singletons.getModel().getEditions().getEditionByCodeOrThrow(booster.getEdition()); - final String tpl = "%s %s.%n%nContains %d cards.%n%nBuy it to reveal the cards and add them to your inventory."; - this.description.setText(String.format(tpl, set.getName(), booster.getType(), booster.getTotalCards())); - } else if (card instanceof PreconDeck) { - final PreconDeck deck = (PreconDeck) card; - final String desc = deck.getDescription(); - final String tpl = "%s%n%n%s%n%nThis deck contains the following cards:%n%s"; - final String decklist = StringUtils.join(deck.getDeck().getMain().toItemListString(), "\n"); - this.description.setText(String.format(tpl, deck.getName(), desc, decklist)); - this.description.setCaretPosition(0); - - } - } - } - - /** - * Sets the card. - * - * @param c - * the new card - */ - public final void setCard(final Card c) { - this.picture.setCard(c); - if (c != null) { - this.detail.setCard(c); - - if (c.isFlip()) { - this.bChangeState.setVisible(true); - this.bChangeState.setText("Flip"); - } else if (c.isDoubleFaced()) { - this.bChangeState.setVisible(true); - this.bChangeState.setText("Transform"); - } else { - this.bChangeState.setVisible(false); - } - } - } - - /** - * - * getCard. - * - * @return Card - */ - public final Card getCard() { - return this.detail.getCard(); - } - - private void bChangeStateActionPerformed(final ActionEvent e) { - final Card cur = this.detail.getCard(); - if (cur != null) { - if (cur.isDoubleFaced()) { - if (cur.getCurState() == CardCharactersticName.Transformed) { - cur.setState(CardCharactersticName.Original); - } else { - cur.setState(CardCharactersticName.Transformed); - } - } - - this.setCard(cur); - } - } - -} diff --git a/src/main/java/forge/gui/deckeditor/elements/CheckBoxWithIcon.java b/src/main/java/forge/gui/deckeditor/elements/CheckBoxWithIcon.java deleted file mode 100644 index 040481d1e1c..00000000000 --- a/src/main/java/forge/gui/deckeditor/elements/CheckBoxWithIcon.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.gui.deckeditor.elements; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -import javax.swing.ImageIcon; -import javax.swing.JCheckBox; - -/** - * Custom check box class for filter icon. - */ -public class CheckBoxWithIcon extends JCheckBox { - /* CHOPPIC */ - /* Custom check box class for filter icons */ - private static final long serialVersionUID = -8099263807219520120L; - - private final String imagePath = "res/images/deckeditor/"; - private final String iconYes; - private final String iconNo; - private final CheckBoxWithIcon cb; - - /** - * Instantiates a new check box with icon. - * - * @param filterName - * the filter name - * @param toolTip - * the tool tip - */ - CheckBoxWithIcon(final String filterName, final String toolTip) { - super("", true); - this.cb = this; - this.iconYes = this.imagePath + "filter_" + filterName + "_y.png"; - this.iconNo = this.imagePath + "filter_" + filterName + "_n.png"; - this.setIcon(new ImageIcon(this.iconYes)); - this.setToolTipText(toolTip); - this.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent actionEvent) { - if (CheckBoxWithIcon.this.cb.isSelected()) { - CheckBoxWithIcon.this.cb.setIcon(new ImageIcon(CheckBoxWithIcon.this.iconYes)); - } else { - CheckBoxWithIcon.this.cb.setIcon(new ImageIcon(CheckBoxWithIcon.this.iconNo)); - } - } - }); - } -} diff --git a/src/main/java/forge/gui/deckeditor/elements/DeckAnalysis.java b/src/main/java/forge/gui/deckeditor/elements/DeckAnalysis.java deleted file mode 100644 index 2d447c15627..00000000000 --- a/src/main/java/forge/gui/deckeditor/elements/DeckAnalysis.java +++ /dev/null @@ -1,1357 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.gui.deckeditor.elements; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.awt.event.MouseEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.math.BigDecimal; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map.Entry; -import javax.swing.BorderFactory; -import javax.swing.DefaultComboBoxModel; -import javax.swing.JButton; -import javax.swing.JDialog; -import javax.swing.JLabel; -import javax.swing.JList; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JSeparator; -import javax.swing.JTable; -import javax.swing.ListModel; -import javax.swing.SwingConstants; -import javax.swing.border.BevelBorder; -import javax.swing.event.MouseInputAdapter; -import javax.swing.table.DefaultTableModel; - -import forge.card.CardRules; -import forge.card.CardType; -import forge.item.CardPrinted; -import forge.item.ItemPoolView; -import forge.util.MyRandom; -import net.miginfocom.swing.MigLayout; - -/** - * This code was edited or generated using CloudGarden's Jigloo SWT/Swing GUI - * Builder, which is free for non-commercial use. If Jigloo is being used - * commercially (ie, by a corporation, company or business for any purpose - * whatever) then you should purchase a license for each developer using Jigloo. - * Please visit www.cloudgarden.com for details. Use of Jigloo implies - * acceptance of these licensing terms. A COMMERCIAL LICENSE HAS NOT BEEN - * PURCHASED FOR THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED LEGALLY FOR - * ANY CORPORATE OR COMMERCIAL PURPOSE. - * - * @author Forge - * @version $Id$ - */ -public class DeckAnalysis extends javax.swing.JDialog { - - /** Constant serialVersionUID=-8475271235196182185L. */ - private static final long serialVersionUID = -8475271235196182185L; - private JPanel jPanel1; - private JLabel jLabelColorless; - private JLabel jLabelMultiColor; - private JLabel jLabelWhite; - private JLabel jLabelSixMana; - private JLabel jLabelFiveMana; - private JLabel jLabelFourMana; - private JLabel jLabelThreeMana; - private JLabel jLabel1; - private JScrollPane jScrollPane1; - private JTable jTable1; - private JPanel jPanel5; - private JButton jButtonRegenerate; - private JLabel jLabel4; - private JSeparator jSeparator4; - private JPanel jPanel4; - private JList jListFirstHand; - private JLabel jLabelTwoMana; - private JLabel jLabelOneMana; - private JLabel jLabelManaCost; - private JSeparator jSeparator3; - private JLabel jLabelZeroMana; - private JPanel jPanel3; - private JLabel jLabelSorcery; - private JLabel jLabelPlaneswalker; - private JLabel jLabelRed; - private JLabel jLabelGreen; - private JLabel jLabelBlue; - private JLabel jLabelBlack; - private JLabel jLabelEnchant; - private JLabel jLabelLandType; - private JLabel jLabelInstant; - private JLabel jLabelCreature; - private JLabel jLabel3; - private JSeparator jSeparator2; - private JLabel jLabelArtifact; - private JPanel jPanel2; - private JLabel jLabelTotal; - private JLabel jLabelLand; - private JSeparator jSeparator1; - private JLabel jLabel2; - private JButton jButtonOk; - private final JDialog parentDialog; - - /** The deck. */ - private final ItemPoolView deck; - - /** - *

- * Constructor for GUI_DeckAnalysis. - *

- * - * @param g - * a {@link javax.swing.JFrame} object. - * @param deckView - * the deck view - */ - public DeckAnalysis(final JDialog g, final ItemPoolView deckView) { - super(g); - this.deck = deckView; - - this.parentDialog = g; - this.initGUI(); - } - - /** - *

- * initGUI. - *

- */ - private void initGUI() { - try { - - this.getContentPane().setLayout(null); - this.setVisible(true); - final int wWidth = 600; - final int wHeight = 600; - this.setPreferredSize(new java.awt.Dimension(wWidth, wHeight)); - - final Dimension screen = this.getToolkit().getScreenSize(); - final int x = (screen.width - wWidth) / 2; - final int y = (screen.height - wHeight) / 2; - this.setBounds(x, y, wWidth, wHeight); - this.setResizable(false); - this.setTitle("Deck Analysis"); - this.pack(); - // this.setIconImage(null); - - this.addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(final WindowEvent arg0) { - DeckAnalysis.this.parentDialog.setEnabled(true); - } - - @Override - public void windowOpened(final WindowEvent arg0) { - - int cBlack, cBlue, cGreen, cRed, cWhite, cMulticolor, cColorless, cLand; - int cArtifact, cCreature, cEnchant, cInstant, cLandType, cPlaneswalker, cSorcery; - int mZero, mOne, mTwo, mThree, mFour, mFive, mSixMore; - float tManaCost; - CardRules c; - cBlack = 0; - cBlue = 0; - cGreen = 0; - cRed = 0; - cWhite = 0; - cMulticolor = 0; - cColorless = 0; - cLand = 0; - cArtifact = 0; - cCreature = 0; - cEnchant = 0; - cInstant = 0; - cLandType = 0; - cPlaneswalker = 0; - cSorcery = 0; - mZero = 0; - mOne = 0; - mTwo = 0; - mThree = 0; - mFour = 0; - mFive = 0; - mSixMore = 0; - tManaCost = 0; - - for (final Entry e : DeckAnalysis.this.deck) { - c = e.getKey().getCard(); - final int cnt = e.getValue(); - - if (c.getColor().isMulticolor()) { - cMulticolor = cMulticolor + cnt; - } else { - if (c.getColor().isBlack()) { - cBlack = cBlack + cnt; - } - if (c.getColor().isBlue()) { - cBlue = cBlue + cnt; - } - if (c.getColor().isGreen()) { - cGreen = cGreen + cnt; - } - if (c.getColor().isRed()) { - cRed = cRed + cnt; - } - if (c.getColor().isWhite()) { - cWhite = cWhite + cnt; - } - if (c.getColor().isColorless()) { - if (c.getType().isLand()) { - cLand = cLand + cnt; - } else { - cColorless = cColorless + cnt; - } - } - } - - // count card types - final CardType cType = c.getType(); - if (cType.isArtifact()) { - cArtifact = cArtifact + cnt; - } - if (cType.isCreature()) { - cCreature = cCreature + cnt; - } - if (cType.isEnchantment()) { - cEnchant = cEnchant + cnt; - } - if (cType.isInstant()) { - cInstant = cInstant + cnt; - } - if (cType.isLand()) { - cLandType = cLandType + cnt; - } - if (cType.isPlaneswalker()) { - cPlaneswalker = cPlaneswalker + cnt; - } - if (cType.isSorcery()) { - cSorcery = cSorcery + cnt; - } - - final int cmc = c.getManaCost().getCMC(); - if (cmc == 0) { - mZero = mZero + cnt; - } else if (cmc == 1) { - mOne = mOne + cnt; - } else if (cmc == 2) { - mTwo = mTwo + cnt; - } else if (cmc == 3) { - mThree = mThree + cnt; - } else if (cmc == 4) { - mFour = mFour + cnt; - } else if (cmc == 5) { - mFive = mFive + 1; - } else if (cmc >= 6) { - mSixMore = mSixMore + 1; - } - - tManaCost = tManaCost + (cmc * cnt); - } - final int total = DeckAnalysis.this.deck.countAll(); - BigDecimal aManaCost = new BigDecimal(tManaCost / total); - aManaCost = aManaCost.setScale(2, BigDecimal.ROUND_HALF_UP); - - DeckAnalysis.this.jLabelTotal.setText("Information about deck (total cards: " + total + "):"); - DeckAnalysis.this.jLabelManaCost.setText("Mana cost (ACC:" + aManaCost + ")"); - final Color cr = new Color(100, 100, 100); - - if (cBlack == 0) { - DeckAnalysis.this.jLabelBlack.setForeground(cr); - } - DeckAnalysis.this.jLabelBlack.setText(DeckAnalysis.this.formatStat("Black", cBlack, total)); - if (cBlue == 0) { - DeckAnalysis.this.jLabelBlue.setForeground(cr); - } - DeckAnalysis.this.jLabelBlue.setText(DeckAnalysis.this.formatStat("Blue", cBlue, total)); - if (cGreen == 0) { - DeckAnalysis.this.jLabelGreen.setForeground(cr); - } - DeckAnalysis.this.jLabelGreen.setText(DeckAnalysis.this.formatStat("Green", cGreen, total)); - if (cRed == 0) { - DeckAnalysis.this.jLabelRed.setForeground(cr); - } - DeckAnalysis.this.jLabelRed.setText(DeckAnalysis.this.formatStat("Red", cRed, total)); - if (cWhite == 0) { - DeckAnalysis.this.jLabelWhite.setForeground(cr); - } - DeckAnalysis.this.jLabelWhite.setText(DeckAnalysis.this.formatStat("White", cWhite, total)); - if (cMulticolor == 0) { - DeckAnalysis.this.jLabelMultiColor.setForeground(cr); - } - DeckAnalysis.this.jLabelMultiColor.setText(DeckAnalysis.this.formatStat("Multicolor", cMulticolor, - total)); - if (cColorless == 0) { - DeckAnalysis.this.jLabelColorless.setForeground(cr); - } - DeckAnalysis.this.jLabelColorless.setText(DeckAnalysis.this.formatStat("Colorless", cColorless, - total)); - - if (cLand == 0) { - DeckAnalysis.this.jLabelLand.setForeground(cr); - } - DeckAnalysis.this.jLabelLand.setText(DeckAnalysis.this.formatStat("Land", cLand, total)); - if (cArtifact == 0) { - DeckAnalysis.this.jLabelArtifact.setForeground(cr); - } - DeckAnalysis.this.jLabelArtifact.setText(DeckAnalysis.this.formatStat("Artifact", cArtifact, total)); - if (cCreature == 0) { - DeckAnalysis.this.jLabelCreature.setForeground(cr); - } - DeckAnalysis.this.jLabelCreature.setText(DeckAnalysis.this.formatStat("Creature", cCreature, total)); - if (cEnchant == 0) { - DeckAnalysis.this.jLabelEnchant.setForeground(cr); - } - DeckAnalysis.this.jLabelEnchant.setText(DeckAnalysis.this.formatStat("Enchant", cEnchant, total)); - if (cInstant == 0) { - DeckAnalysis.this.jLabelInstant.setForeground(cr); - } - DeckAnalysis.this.jLabelInstant.setText(DeckAnalysis.this.formatStat("Instant", cInstant, total)); - if (cLandType == 0) { - DeckAnalysis.this.jLabelLandType.setForeground(cr); - } - DeckAnalysis.this.jLabelLandType.setText(DeckAnalysis.this.formatStat("Land", cLandType, total)); - if (cPlaneswalker == 0) { - DeckAnalysis.this.jLabelPlaneswalker.setForeground(cr); - } - DeckAnalysis.this.jLabelPlaneswalker.setText(DeckAnalysis.this.formatStat("Planeswalker", - cPlaneswalker, total)); - - if (cSorcery == 0) { - DeckAnalysis.this.jLabelSorcery.setForeground(cr); - } - DeckAnalysis.this.jLabelSorcery.setText(DeckAnalysis.this.formatStat("Sorcery", cSorcery, total)); - if (mZero == 0) { - DeckAnalysis.this.jLabelZeroMana.setForeground(cr); - } - DeckAnalysis.this.jLabelZeroMana.setText(DeckAnalysis.this.formatStat("Zero mana", mZero, total)); - if (mOne == 0) { - DeckAnalysis.this.jLabelOneMana.setForeground(cr); - } - DeckAnalysis.this.jLabelOneMana.setText(DeckAnalysis.this.formatStat("One mana", mOne, total)); - if (mTwo == 0) { - DeckAnalysis.this.jLabelTwoMana.setForeground(cr); - } - DeckAnalysis.this.jLabelTwoMana.setText(DeckAnalysis.this.formatStat("Two mana", mTwo, total)); - if (mThree == 0) { - DeckAnalysis.this.jLabelThreeMana.setForeground(cr); - } - DeckAnalysis.this.jLabelThreeMana.setText(DeckAnalysis.this.formatStat("Three mana", mThree, total)); - if (mFour == 0) { - DeckAnalysis.this.jLabelFourMana.setForeground(cr); - } - DeckAnalysis.this.jLabelFourMana.setText(DeckAnalysis.this.formatStat("Four mana", mFour, total)); - if (mFive == 0) { - DeckAnalysis.this.jLabelFiveMana.setForeground(cr); - } - DeckAnalysis.this.jLabelFiveMana.setText(DeckAnalysis.this.formatStat("Five mana", mFive, total)); - if (mSixMore == 0) { - DeckAnalysis.this.jLabelSixMana.setForeground(cr); - } - DeckAnalysis.this.jLabelSixMana.setText(DeckAnalysis.this.formatStat("Six and more", mSixMore, - total)); - } - }); - - this.getContentPane().add(this.getJButton1()); - this.getContentPane().add(this.getJLabel1xx()); - this.getContentPane().add(this.getJButtonOk()); - this.getContentPane().add(this.getJPanel1()); - this.getContentPane().add(this.getJPanel2()); - this.getContentPane().add(this.getJPanel3()); - this.getContentPane().add(this.getJPanel4()); - this.getContentPane().add(this.getJPanel5()); - this.getContentPane().add(this.getJLabel1xxxxx()); - - } catch (final Exception e) { - e.printStackTrace(); - } - } - - private String formatStat(final String statName, final int value, final int deckSize) { - return String.format("%s: %d (%f%%)", statName, value, (100f * value) / deckSize); - } - - /** - *

- * Getter for the field jPanel1. - *

- * - * @return a {@link javax.swing.JPanel} object. - */ - private JPanel getJPanel1() { - if (this.jPanel1 == null) { - this.jPanel1 = new JPanel(); - - this.jPanel1.setLayout(null); - this.jPanel1.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); - this.jPanel1.setBackground(new java.awt.Color(192, 192, 192)); - this.jPanel1.setBounds(5, 35, 137, 203); - this.jPanel1.add(this.getJLabel1()); - this.jPanel1.add(this.getJSeparator1()); - this.jPanel1.add(this.getJLabel2()); - this.jPanel1.add(this.getJLabel3()); - this.jPanel1.add(this.getJLabel4()); - this.jPanel1.add(this.getJLabel5()); - this.jPanel1.add(this.getJLabel6()); - this.jPanel1.add(this.getJLabel7()); - this.jPanel1.add(this.getJLabel8()); - this.jPanel1.add(this.getJLabel1x()); - } - return this.jPanel1; - } - - /** - *

- * Getter for the field jLabel2. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel2() { - if (this.jLabel2 == null) { - this.jLabel2 = new JLabel(); - this.jLabel2.setText("Color"); - this.jLabel2.setHorizontalAlignment(SwingConstants.CENTER); - this.jLabel2.setFont(new java.awt.Font("Segoe UI", 0, 14)); - this.jLabel2.setPreferredSize(new java.awt.Dimension(152, 39)); - this.jLabel2.setLayout(null); - this.jLabel2.setBounds(2, -3, 135, 26); - } - return this.jLabel2; - } - - /** - *

- * Getter for the field jSeparator1. - *

- * - * @return a {@link javax.swing.JSeparator} object. - */ - private JSeparator getJSeparator1() { - if (this.jSeparator1 == null) { - this.jSeparator1 = new JSeparator(); - this.jSeparator1.setPreferredSize(new java.awt.Dimension(117, 6)); - this.jSeparator1.setLayout(null); - this.jSeparator1.setBounds(1, 20, 136, 5); - } - return this.jSeparator1; - } - - /** - *

- * Getter for the field jButtonOk. - *

- * - * @return a {@link javax.swing.JButton} object. - */ - private JButton getJButtonOk() { - if (this.jButtonOk == null) { - this.jButtonOk = new JButton(); - this.jButtonOk.setLayout(null); - this.jButtonOk.setText("OK"); - this.jButtonOk.setBounds(206, 536, 168, 31); - this.jButtonOk.addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(final MouseEvent e) { - DeckAnalysis.this.parentDialog.setEnabled(true); - DeckAnalysis.this.dispose(); - } - }); - } - return this.jButtonOk; - } - - /** - *

- * Getter for the field jLabel1. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel1() { - if (this.jLabelBlack == null) { - this.jLabelBlack = new JLabel(); - this.jLabelBlack.setText("Black:"); - this.jLabelBlack.setPreferredSize(new java.awt.Dimension(105, 12)); - this.jLabelBlack.setLayout(null); - this.jLabelBlack.setBounds(10, 28, 127, 13); - } - return this.jLabelBlack; - } - - /** - *

- * Getter for the field jLabel3. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel3() { - if (this.jLabelBlue == null) { - this.jLabelBlue = new JLabel(); - this.jLabelBlue.setText("Blue:"); - this.jLabelBlue.setLayout(null); - this.jLabelBlue.setBounds(10, 50, 127, 13); - } - return this.jLabelBlue; - } - - /** - *

- * Getter for the field jLabel4. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel4() { - if (this.jLabelGreen == null) { - this.jLabelGreen = new JLabel(); - this.jLabelGreen.setText("Green:"); - this.jLabelGreen.setLayout(null); - this.jLabelGreen.setBounds(10, 72, 127, 13); - } - return this.jLabelGreen; - } - - /** - *

- * getJLabel5. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel5() { - if (this.jLabelRed == null) { - this.jLabelRed = new JLabel(); - this.jLabelRed.setText("Red:"); - this.jLabelRed.setLayout(null); - this.jLabelRed.setBounds(10, 94, 127, 14); - } - return this.jLabelRed; - } - - /** - *

- * getJLabel6. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel6() { - if (this.jLabelWhite == null) { - this.jLabelWhite = new JLabel(); - this.jLabelWhite.setText("White:"); - this.jLabelWhite.setLayout(null); - this.jLabelWhite.setBounds(10, 116, 127, 13); - } - return this.jLabelWhite; - } - - /** - *

- * getJLabel7. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel7() { - if (this.jLabelMultiColor == null) { - this.jLabelMultiColor = new JLabel(); - this.jLabelMultiColor.setText("Multicolor:"); - this.jLabelMultiColor.setLayout(null); - this.jLabelMultiColor.setBounds(10, 138, 127, 12); - } - return this.jLabelMultiColor; - } - - /** - *

- * getJLabel8. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel8() { - if (this.jLabelColorless == null) { - this.jLabelColorless = new JLabel(); - this.jLabelColorless.setText("Colorless:"); - this.jLabelColorless.setLayout(null); - this.jLabelColorless.setBounds(10, 160, 128, 11); - } - return this.jLabelColorless; - } - - /** - *

- * getJLabel1x. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel1x() { - if (this.jLabelLand == null) { - this.jLabelLand = new JLabel(); - this.jLabelLand.setText("Land: "); - this.jLabelLand.setLayout(null); - this.jLabelLand.setBounds(10, 182, 129, 10); - } - return this.jLabelLand; - } - - /** - *

- * getJLabel1xx. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel1xx() { - if (this.jLabelTotal == null) { - this.jLabelTotal = new JLabel(); - this.jLabelTotal.setText("Information about deck:"); - this.jLabelTotal.setLayout(null); - this.jLabelTotal.setBounds(5, 0, 454, 35); - } - return this.jLabelTotal; - } - - /** - *

- * Getter for the field jPanel2. - *

- * - * @return a {@link javax.swing.JPanel} object. - */ - private JPanel getJPanel2() { - if (this.jPanel2 == null) { - this.jPanel2 = new JPanel(); - - this.jPanel2.setBackground(new java.awt.Color(192, 192, 192)); - this.jPanel2.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); - this.jPanel2.setLayout(null); - this.jPanel2.setBounds(153, 35, 137, 203); - this.jPanel2.add(this.getJLabel1xxx()); - this.jPanel2.add(this.getJSeparator2()); - this.jPanel2.add(this.getJLabel3x()); - this.jPanel2.add(this.getJLabel4x()); - this.jPanel2.add(this.getJLabel5x()); - this.jPanel2.add(this.getJLabel6x()); - this.jPanel2.add(this.getJLabel7x()); - this.jPanel2.add(this.getJLabel8x()); - this.jPanel2.add(this.getJLabel10()); - } - return this.jPanel2; - } - - /** - *

- * getJLabel1xxx. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel1xxx() { - if (this.jLabelArtifact == null) { - this.jLabelArtifact = new JLabel(); - this.jLabelArtifact.setText("Artifact:"); - this.jLabelArtifact.setPreferredSize(new java.awt.Dimension(105, 12)); - this.jLabelArtifact.setLayout(null); - this.jLabelArtifact.setBounds(10, 28, 127, 13); - } - return this.jLabelArtifact; - } - - /** - *

- * Getter for the field jSeparator2. - *

- * - * @return a {@link javax.swing.JSeparator} object. - */ - private JSeparator getJSeparator2() { - if (this.jSeparator2 == null) { - this.jSeparator2 = new JSeparator(); - this.jSeparator2.setPreferredSize(new java.awt.Dimension(117, 6)); - this.jSeparator2.setLayout(null); - this.jSeparator2.setBounds(1, 20, 136, 5); - } - return this.jSeparator2; - } - - /** - *

- * getJLabel3x. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel3x() { - if (this.jLabel3 == null) { - this.jLabel3 = new JLabel(); - this.jLabel3.setText("Type"); - this.jLabel3.setHorizontalAlignment(SwingConstants.CENTER); - this.jLabel3.setFont(new java.awt.Font("Segoe UI", 0, 14)); - this.jLabel3.setPreferredSize(new java.awt.Dimension(152, 39)); - this.jLabel3.setLayout(null); - this.jLabel3.setBounds(2, -3, 135, 26); - } - return this.jLabel3; - } - - /** - *

- * getJLabel4x. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel4x() { - if (this.jLabelCreature == null) { - this.jLabelCreature = new JLabel(); - this.jLabelCreature.setText("Creature:"); - this.jLabelCreature.setLayout(null); - this.jLabelCreature.setBounds(10, 53, 127, 13); - } - return this.jLabelCreature; - } - - /** - *

- * getJLabel5x. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel5x() { - if (this.jLabelEnchant == null) { - this.jLabelEnchant = new JLabel(); - this.jLabelEnchant.setText("Enchant:"); - this.jLabelEnchant.setLayout(null); - this.jLabelEnchant.setBounds(10, 79, 127, 13); - } - return this.jLabelEnchant; - } - - /** - *

- * getJLabel6x. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel6x() { - if (this.jLabelInstant == null) { - this.jLabelInstant = new JLabel(); - this.jLabelInstant.setText("Instant:"); - this.jLabelInstant.setLayout(null); - this.jLabelInstant.setBounds(10, 105, 127, 14); - } - return this.jLabelInstant; - } - - /** - *

- * getJLabel7x. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel7x() { - if (this.jLabelLandType == null) { - this.jLabelLandType = new JLabel(); - this.jLabelLandType.setText("Land:"); - this.jLabelLandType.setLayout(null); - this.jLabelLandType.setBounds(10, 130, 127, 13); - } - return this.jLabelLandType; - } - - /** - *

- * getJLabel8x. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel8x() { - if (this.jLabelPlaneswalker == null) { - this.jLabelPlaneswalker = new JLabel(); - this.jLabelPlaneswalker.setText("Planeswalker:"); - this.jLabelPlaneswalker.setLayout(null); - this.jLabelPlaneswalker.setBounds(10, 156, 127, 13); - } - return this.jLabelPlaneswalker; - } - - /** - *

- * getJLabel10. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel10() { - if (this.jLabelSorcery == null) { - this.jLabelSorcery = new JLabel(); - this.jLabelSorcery.setText("Sorcery:"); - this.jLabelSorcery.setLayout(null); - this.jLabelSorcery.setBounds(10, 182, 127, 11); - } - return this.jLabelSorcery; - } - - /** - *

- * Getter for the field jPanel3. - *

- * - * @return a {@link javax.swing.JPanel} object. - */ - private JPanel getJPanel3() { - if (this.jPanel3 == null) { - this.jPanel3 = new JPanel(); - this.jPanel3.setBackground(new java.awt.Color(192, 192, 192)); - this.jPanel3.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); - this.jPanel3.setLayout(null); - this.jPanel3.setBounds(302, 35, 137, 203); - this.jPanel3.add(this.getJLabel1xxxx()); - this.jPanel3.add(this.getJSeparator3()); - this.jPanel3.add(this.getJLabel4xx()); - this.jPanel3.add(this.getJLabel5xx()); - this.jPanel3.add(this.getJLabel6xx()); - this.jPanel3.add(this.getJLabel7xx()); - this.jPanel3.add(this.getJLabel8xx()); - this.jPanel3.add(this.getJLabel9()); - this.jPanel3.add(this.getJLabel10x()); - } - return this.jPanel3; - } - - /** - *

- * getJLabel1xxxx. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel1xxxx() { - if (this.jLabelZeroMana == null) { - this.jLabelZeroMana = new JLabel(); - this.jLabelZeroMana.setText("Zero mana:"); - this.jLabelZeroMana.setPreferredSize(new java.awt.Dimension(105, 12)); - this.jLabelZeroMana.setLayout(null); - this.jLabelZeroMana.setBounds(10, 28, 127, 13); - } - return this.jLabelZeroMana; - } - - /** - *

- * Getter for the field jSeparator3. - *

- * - * @return a {@link javax.swing.JSeparator} object. - */ - private JSeparator getJSeparator3() { - if (this.jSeparator3 == null) { - this.jSeparator3 = new JSeparator(); - this.jSeparator3.setPreferredSize(new java.awt.Dimension(117, 6)); - this.jSeparator3.setLayout(null); - this.jSeparator3.setBounds(1, 20, 136, 5); - } - return this.jSeparator3; - } - - /** - *

- * getJLabel4xx. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel4xx() { - if (this.jLabelManaCost == null) { - this.jLabelManaCost = new JLabel(); - this.jLabelManaCost.setText("Mana cost"); - this.jLabelManaCost.setHorizontalAlignment(SwingConstants.CENTER); - this.jLabelManaCost.setFont(new java.awt.Font("Segoe UI", 0, 14)); - this.jLabelManaCost.setPreferredSize(new java.awt.Dimension(152, 39)); - this.jLabelManaCost.setLayout(null); - this.jLabelManaCost.setBounds(2, -3, 135, 26); - } - return this.jLabelManaCost; - } - - /** - *

- * getJLabel5xx. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel5xx() { - if (this.jLabelOneMana == null) { - this.jLabelOneMana = new JLabel(); - this.jLabelOneMana.setText("One mana:"); - this.jLabelOneMana.setLayout(null); - this.jLabelOneMana.setBounds(10, 53, 127, 13); - } - return this.jLabelOneMana; - } - - /** - *

- * getJLabel6xx. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel6xx() { - if (this.jLabelTwoMana == null) { - this.jLabelTwoMana = new JLabel(); - this.jLabelTwoMana.setText("Two mana:"); - this.jLabelTwoMana.setLayout(null); - this.jLabelTwoMana.setBounds(10, 79, 127, 13); - } - return this.jLabelTwoMana; - } - - /** - *

- * getJLabel7xx. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel7xx() { - if (this.jLabelThreeMana == null) { - this.jLabelThreeMana = new JLabel(); - this.jLabelThreeMana.setText("Three mana:"); - this.jLabelThreeMana.setLayout(null); - this.jLabelThreeMana.setBounds(10, 105, 127, 14); - } - return this.jLabelThreeMana; - } - - /** - *

- * getJLabel8xx. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel8xx() { - if (this.jLabelFourMana == null) { - this.jLabelFourMana = new JLabel(); - this.jLabelFourMana.setText("Four mana:"); - this.jLabelFourMana.setLayout(null); - this.jLabelFourMana.setBounds(10, 130, 127, 13); - } - return this.jLabelFourMana; - } - - /** - *

- * getJLabel9. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel9() { - if (this.jLabelFiveMana == null) { - this.jLabelFiveMana = new JLabel(); - this.jLabelFiveMana.setText("Five mana:"); - this.jLabelFiveMana.setLayout(null); - this.jLabelFiveMana.setBounds(10, 156, 127, 13); - } - return this.jLabelFiveMana; - } - - /** - *

- * getJLabel10x. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel10x() { - if (this.jLabelSixMana == null) { - this.jLabelSixMana = new JLabel(); - this.jLabelSixMana.setText("Six and more:"); - this.jLabelSixMana.setLayout(null); - this.jLabelSixMana.setBounds(10, 182, 127, 11); - } - return this.jLabelSixMana; - } - - /** - *

- * getJList1. - *

- * - * @return a {@link javax.swing.JList} object. - */ - private JList getJList1() { - final List rList = this.deck.toFlatList(); - - Collections.shuffle(rList, MyRandom.getRandom()); - Collections.shuffle(rList, MyRandom.getRandom()); - - ListModel jList1Model; - if (this.jListFirstHand == null) { - this.jListFirstHand = new JList(); - } - - if (rList.size() >= 40) { - jList1Model = new DefaultComboBoxModel(new String[] { rList.get(0).getName(), rList.get(1).getName(), - rList.get(2).getName(), rList.get(3).getName(), rList.get(4).getName(), rList.get(5).getName(), - rList.get(6).getName() }); - - } else { - jList1Model = new DefaultComboBoxModel(new String[] { "Few cards." }); - } - - this.jListFirstHand.setModel(jList1Model); - this.jListFirstHand.setLayout(null); - this.jListFirstHand.setBackground(new java.awt.Color(192, 192, 192)); - this.jListFirstHand.setSelectionBackground(new java.awt.Color(192, 192, 192)); - this.jListFirstHand.setSelectionForeground(new java.awt.Color(0, 0, 0)); - this.jListFirstHand.setFixedCellHeight(24); - this.jListFirstHand.setBounds(2, 21, 133, 167); - - return this.jListFirstHand; - } - - /** - *

- * Getter for the field jPanel4. - *

- * - * @return a {@link javax.swing.JPanel} object. - */ - private JPanel getJPanel4() { - if (this.jPanel4 == null) { - this.jPanel4 = new JPanel(); - this.jPanel4.setBackground(new java.awt.Color(192, 192, 192)); - this.jPanel4.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); - this.jPanel4.setLayout(null); - this.jPanel4.setBounds(451, 35, 137, 202); - this.jPanel4.add(this.getJSeparator4()); - this.jPanel4.add(this.getJLabel4xxx()); - this.jPanel4.add(this.getJList1()); - this.jPanel4.add(this.getJButton1()); - } else { - this.jPanel4.removeAll(); - final MigLayout jPanel4Layout = new MigLayout(); - this.jPanel4.setBackground(new java.awt.Color(192, 192, 192)); - this.jPanel4.setPreferredSize(new java.awt.Dimension(139, 201)); - this.jPanel4.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); - this.jPanel4.setLayout(jPanel4Layout); - this.jPanel4.add(this.getJSeparator4()); - this.jPanel4.add(this.getJLabel4xxx()); - this.jPanel4.add(this.getJList1()); - this.jPanel4.add(this.getJButton1()); - } - return this.jPanel4; - - } - - /** - *

- * Getter for the field jSeparator4. - *

- * - * @return a {@link javax.swing.JSeparator} object. - */ - private JSeparator getJSeparator4() { - if (this.jSeparator4 == null) { - this.jSeparator4 = new JSeparator(); - this.jSeparator4.setPreferredSize(new java.awt.Dimension(138, 8)); - this.jSeparator4.setLayout(null); - this.jSeparator4.setBounds(0, 19, 137, 7); - } - return this.jSeparator4; - } - - /** - *

- * getJLabel4xxx. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel4xxx() { - if (this.jLabel4 == null) { - this.jLabel4 = new JLabel(); - this.jLabel4.setText("Random start hand"); - this.jLabel4.setHorizontalAlignment(SwingConstants.CENTER); - this.jLabel4.setFont(new java.awt.Font("Segoe UI", 0, 14)); - this.jLabel4.setPreferredSize(new java.awt.Dimension(136, 24)); - this.jLabel4.setLayout(null); - this.jLabel4.setBounds(2, 0, 135, 20); - } - return this.jLabel4; - } - - /** - *

- * getJButton1. - *

- * - * @return a {@link javax.swing.JButton} object. - */ - private JButton getJButton1() { - - if (this.jButtonRegenerate == null) { - if (this.deck.countAll() >= 40) { - this.jButtonRegenerate = new JButton(); - this.jButtonRegenerate.setLayout(null); - this.jButtonRegenerate.setText("Regenerate hand"); - this.jButtonRegenerate.setPreferredSize(new java.awt.Dimension(139, 21)); - this.jButtonRegenerate.setBounds(2, 189, 133, 13); - this.jButtonRegenerate.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckAnalysis.this.jButtonRegenerateActionPerformed(e); - } - }); - } else { - this.jButtonRegenerate = new JButton(); - this.jButtonRegenerate.setBounds(2, 189, 133, 13); - this.jButtonRegenerate.setVisible(false); - } - } - return this.jButtonRegenerate; - } - - /** - *

- * jButtonRegenerate_actionPerformed. - *

- * - * @param e - * a {@link java.awt.event.ActionEvent} object. - */ - final void jButtonRegenerateActionPerformed(final ActionEvent e) { - this.getContentPane().removeAll(); - this.getContentPane().add(this.getJPanel5()); - this.getContentPane().add(this.getJLabel1xx()); - this.getContentPane().add(this.getJButtonOk()); - this.getContentPane().add(this.getJPanel1()); - this.getContentPane().add(this.getJPanel2()); - this.getContentPane().add(this.getJPanel3()); - this.getContentPane().add(this.getJPanel4()); - this.getContentPane().add(this.getJPanel5()); - this.getContentPane().add(this.getJLabel1xxxxx()); - this.getContentPane().repaint(); - - } - - /** - *

- * Getter for the field jPanel5. - *

- * - * @return a {@link javax.swing.JPanel} object. - */ - private JPanel getJPanel5() { - if (this.jPanel5 == null) { - this.jPanel5 = new JPanel(); - this.jPanel5.setLayout(null); - this.jPanel5.setBounds(5, 262, 583, 270); - this.jPanel5.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); - this.jPanel5.add(this.getJScrollPane1()); - } - return this.jPanel5; - } - - /** - *

- * Getter for the field jTable1. - *

- * - * @return a {@link javax.swing.JTable} object. - */ - private JTable getJTable1() { - if (this.jTable1 == null) { - final DefaultTableModel dm = new DefaultTableModel(); - dm.setDataVector(new Object[][] { {} }, new Object[] { "Card", "Qty", "1st", "2nd", "3rd", "4th", "5th", - "6th", "7th" }); - - this.jTable1 = new JTable(dm); - final List rList = this.deck.toFlatList(); - final String[] cardsName = new String[rList.size()]; - int cCount; - float fCount; - float firstTurnF, secondTurnF, thirdTurnF, fourthTurnF, fivethTurnF, sixthTurnF, seventhTurnF; - - for (int i = 0; i < rList.size(); i++) { - cardsName[i] = rList.get(i).getName(); - } - Arrays.sort(cardsName); - this.jTable1.setValueAt("Few cards.", 0, 0); - - if (rList.size() >= 40) { - this.jTable1.setValueAt(cardsName[0], 0, 0); - cCount = 1; - for (int i = 1; i < cardsName.length; i++) { - if (cardsName[i].equals(cardsName[i - 1])) { - cCount = cCount + 1; - - } else { - dm.addRow(new Object[][] { {} }); - this.jTable1.setValueAt(cardsName[i], dm.getRowCount() - 1, 0); - this.jTable1.setValueAt(cCount, dm.getRowCount() - 2, 1); - fCount = cCount; - - firstTurnF = fCount / rList.size(); - BigDecimal firstTurn = new BigDecimal(firstTurnF * 100); - firstTurn = firstTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(firstTurn.toString() + " %", dm.getRowCount() - 2, 2); - - secondTurnF = (((1 - firstTurnF) * fCount) / (rList.size() - 1)) + firstTurnF; - BigDecimal secondTurn = new BigDecimal(secondTurnF * 100); - secondTurn = secondTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(secondTurn.toString() + " %", dm.getRowCount() - 2, 3); - - thirdTurnF = (((1 - secondTurnF) * fCount) / (rList.size() - 2)) + secondTurnF; - BigDecimal thirdTurn = new BigDecimal(thirdTurnF * 100); - thirdTurn = thirdTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(thirdTurn.toString() + " %", dm.getRowCount() - 2, 4); - - fourthTurnF = (((1 - thirdTurnF) * fCount) / (rList.size() - 3)) + thirdTurnF; - BigDecimal fourthTurn = new BigDecimal(fourthTurnF * 100); - fourthTurn = fourthTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(fourthTurn.toString() + " %", dm.getRowCount() - 2, 5); - - fivethTurnF = (((1 - fourthTurnF) * fCount) / (rList.size() - 4)) + fourthTurnF; - BigDecimal fivethTurn = new BigDecimal(fivethTurnF * 100); - fivethTurn = fivethTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(fivethTurn.toString() + " %", dm.getRowCount() - 2, 6); - - sixthTurnF = (((1 - fivethTurnF) * fCount) / (rList.size() - 5)) + fivethTurnF; - BigDecimal sixthTurn = new BigDecimal(sixthTurnF * 100); - sixthTurn = sixthTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(sixthTurn.toString() + " %", dm.getRowCount() - 2, 7); - - seventhTurnF = (((1 - sixthTurnF) * fCount) / (rList.size() - 6)) + sixthTurnF; - BigDecimal seventhTurn = new BigDecimal(seventhTurnF * 100); - seventhTurn = seventhTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(seventhTurn.toString() + " %", dm.getRowCount() - 2, 8); - - cCount = 1; - } - if (i == (cardsName.length - 1)) { - this.jTable1.setValueAt(cCount, dm.getRowCount() - 1, 1); - fCount = cCount; - - firstTurnF = fCount / rList.size(); - BigDecimal firstTurn = new BigDecimal(firstTurnF * 100); - firstTurn = firstTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(firstTurn.toString() + " %", dm.getRowCount() - 1, 2); - - secondTurnF = (((1 - firstTurnF) * fCount) / (rList.size() - 1)) + firstTurnF; - BigDecimal secondTurn = new BigDecimal(secondTurnF * 100); - secondTurn = secondTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(secondTurn.toString() + " %", dm.getRowCount() - 1, 3); - - thirdTurnF = (((1 - secondTurnF) * fCount) / (rList.size() - 2)) + secondTurnF; - BigDecimal thirdTurn = new BigDecimal(thirdTurnF * 100); - thirdTurn = thirdTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(thirdTurn.toString() + " %", dm.getRowCount() - 1, 4); - - fourthTurnF = (((1 - thirdTurnF) * fCount) / (rList.size() - 3)) + thirdTurnF; - BigDecimal fourthTurn = new BigDecimal(fourthTurnF * 100); - fourthTurn = fourthTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(fourthTurn.toString() + " %", dm.getRowCount() - 1, 5); - - fivethTurnF = (((1 - fourthTurnF) * fCount) / (rList.size() - 4)) + fourthTurnF; - BigDecimal fivethTurn = new BigDecimal(fivethTurnF * 100); - fivethTurn = fivethTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(fivethTurn.toString() + " %", dm.getRowCount() - 1, 6); - - sixthTurnF = (((1 - fivethTurnF) * fCount) / (rList.size() - 5)) + fivethTurnF; - BigDecimal sixthTurn = new BigDecimal(sixthTurnF * 100); - sixthTurn = sixthTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(sixthTurn.toString() + " %", dm.getRowCount() - 1, 7); - - seventhTurnF = (((1 - sixthTurnF) * fCount) / (rList.size() - 6)) + sixthTurnF; - BigDecimal seventhTurn = new BigDecimal(seventhTurnF * 100); - seventhTurn = seventhTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(seventhTurn.toString() + " %", dm.getRowCount() - 1, 8); - - } - - } - } - - this.jTable1.getColumn("Qty").setMaxWidth(50); - this.jTable1.getColumn("1st").setMaxWidth(50); - this.jTable1.getColumn("2nd").setMaxWidth(50); - this.jTable1.getColumn("3rd").setMaxWidth(50); - this.jTable1.getColumn("4th").setMaxWidth(50); - this.jTable1.getColumn("5th").setMaxWidth(50); - this.jTable1.getColumn("6th").setMaxWidth(50); - this.jTable1.getColumn("7th").setMaxWidth(50); - this.jTable1.setRowHeight(18); - this.jTable1.setPreferredSize(new java.awt.Dimension(576, (18 * dm.getRowCount()) + 3)); - } - return this.jTable1; - } - - /** - *

- * Getter for the field jScrollPane1. - *

- * - * @return a {@link javax.swing.JScrollPane} object. - */ - private JScrollPane getJScrollPane1() { - if (this.jScrollPane1 == null) { - this.jScrollPane1 = new JScrollPane(); - this.jScrollPane1.setBounds(2, 2, 582, 268); - this.jScrollPane1.setSize(580, 268); - this.jScrollPane1.setViewportView(this.getJTable1()); - } - return this.jScrollPane1; - } - - /** - *

- * getJLabel1xxxxx. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel1xxxxx() { - if (this.jLabel1 == null) { - this.jLabel1 = new JLabel(); - this.jLabel1.setText("Draw Probabilities:"); - this.jLabel1.setLayout(null); - this.jLabel1.setBounds(7, 237, 447, 25); - } - return this.jLabel1; - } - -} diff --git a/src/main/java/forge/gui/deckeditor/elements/FilterCheckBoxes.java b/src/main/java/forge/gui/deckeditor/elements/FilterCheckBoxes.java deleted file mode 100644 index e3b45d7977d..00000000000 --- a/src/main/java/forge/gui/deckeditor/elements/FilterCheckBoxes.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.gui.deckeditor.elements; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import javax.swing.JCheckBox; - - -import forge.card.CardRules; -import forge.item.CardPrinted; -import forge.util.closures.Predicate; - -/** - * A structural class for some checkboxes need for a deck editor, contains no - * JPanel to store boxes on Checkboxes are public so the using class should - * place them in some container. - */ -public class FilterCheckBoxes { - - /** The white. */ - private final JCheckBox white; - - /** The blue. */ - private final JCheckBox blue; - - /** The black. */ - private final JCheckBox black; - - /** The red. */ - private final JCheckBox red; - - /** The green. */ - private final JCheckBox green; - - /** The colorless. */ - private final JCheckBox colorless; - - /** The land. */ - private final JCheckBox land; - - /** The creature. */ - private final JCheckBox creature; - - /** The sorcery. */ - private final JCheckBox sorcery; - - /** The instant. */ - private final JCheckBox instant; - - /** The planeswalker. */ - private final JCheckBox planeswalker; - - /** The artifact. */ - private final JCheckBox artifact; - - /** The enchantment. */ - private final JCheckBox enchantment; - - // Very handy for classes using mass operations on an array of checkboxes - /** The all colors. */ - private final List allColors; - - /** The all types. */ - private final List allTypes; - - /** - * Instantiates a new filter check boxes. - * - * @param useGraphicalBoxes - * the use graphical boxes - */ - public FilterCheckBoxes(final boolean useGraphicalBoxes) { - if (useGraphicalBoxes) { - this.white = new CheckBoxWithIcon("white", "White"); - this.blue = new CheckBoxWithIcon("blue", "Blue"); - this.black = new CheckBoxWithIcon("black", "Black"); - this.red = new CheckBoxWithIcon("red", "Red"); - this.green = new CheckBoxWithIcon("green", "Green"); - this.colorless = new CheckBoxWithIcon("colorless", "Colorless"); - - this.land = new CheckBoxWithIcon("land", "Land"); - this.creature = new CheckBoxWithIcon("creature", "Creature"); - this.sorcery = new CheckBoxWithIcon("sorcery", "Sorcery"); - this.instant = new CheckBoxWithIcon("instant", "Instant"); - this.planeswalker = new CheckBoxWithIcon("planeswalker", "Planeswalker"); - this.artifact = new CheckBoxWithIcon("artifact", "Artifact"); - this.enchantment = new CheckBoxWithIcon("enchant", "Enchantment"); - } else { - // We moved the filters and now have room for the full name. - // this.white = new JCheckBox("W", true); - // this.blue = new JCheckBox("U", true); - // this.black = new JCheckBox("B", true); - // this.red = new JCheckBox("R", true); - // this.green = new JCheckBox("G", true); - // this.colorless = new JCheckBox("C", true); - this.white = new JCheckBox("White", true); - this.blue = new JCheckBox("Blue", true); - this.black = new JCheckBox("Black", true); - this.red = new JCheckBox("Red", true); - this.green = new JCheckBox("Green", true); - this.colorless = new JCheckBox("Colorless", true); - - this.land = new JCheckBox("Land", true); - this.creature = new JCheckBox("Creature", true); - this.sorcery = new JCheckBox("Sorcery", true); - this.instant = new JCheckBox("Instant", true); - this.planeswalker = new JCheckBox("Planeswalker", true); - this.artifact = new JCheckBox("Artifact", true); - this.enchantment = new JCheckBox("Enchantment", true); - } - - this.allColors = Arrays.asList(new JCheckBox[] { this.getWhite(), this.getBlue(), this.getBlack(), - this.getRed(), this.getGreen(), this.getColorless() }); - this.allTypes = Arrays.asList(new JCheckBox[] { this.getLand(), this.getCreature(), this.getSorcery(), - this.getInstant(), this.getPlaneswalker(), this.getArtifact(), this.getEnchantment() }); - } - - /** - * Builds the filter. - * - * @return the predicate - */ - public final Predicate buildFilter() { - final List> colors = new ArrayList>(); - if (this.getWhite().isSelected()) { - colors.add(CardRules.Predicates.Presets.IS_WHITE); - } - if (this.getBlue().isSelected()) { - colors.add(CardRules.Predicates.Presets.IS_BLUE); - } - if (this.getBlack().isSelected()) { - colors.add(CardRules.Predicates.Presets.IS_BLACK); - } - if (this.getRed().isSelected()) { - colors.add(CardRules.Predicates.Presets.IS_RED); - } - if (this.getGreen().isSelected()) { - colors.add(CardRules.Predicates.Presets.IS_GREEN); - } - if (this.getColorless().isSelected()) { - colors.add(CardRules.Predicates.Presets.IS_COLORLESS); - } - final Predicate filterByColor = colors.size() == 6 ? CardRules.Predicates.Presets.CONSTANT_TRUE - : Predicate.or(colors); - - final List> types = new ArrayList>(); - if (this.getLand().isSelected()) { - types.add(CardRules.Predicates.Presets.IS_LAND); - } - if (this.getCreature().isSelected()) { - types.add(CardRules.Predicates.Presets.IS_CREATURE); - } - if (this.getSorcery().isSelected()) { - types.add(CardRules.Predicates.Presets.IS_SORCERY); - } - if (this.getInstant().isSelected()) { - types.add(CardRules.Predicates.Presets.IS_INSTANT); - } - if (this.getPlaneswalker().isSelected()) { - types.add(CardRules.Predicates.Presets.IS_PLANESWALKER); - } - if (this.getArtifact().isSelected()) { - types.add(CardRules.Predicates.Presets.IS_ARTIFACT); - } - if (this.getEnchantment().isSelected()) { - types.add(CardRules.Predicates.Presets.IS_ENCHANTMENT); - } - final Predicate filterByType = types.size() == 7 ? CardRules.Predicates.Presets.CONSTANT_TRUE - : Predicate.or(types); - - return Predicate.brigde(Predicate.and(filterByColor, filterByType), CardPrinted.FN_GET_RULES); - } - - /** - * Gets the all types. - * - * @return the allTypes - */ - public List getAllTypes() { - return this.allTypes; - } - - /** - * Gets the white. - * - * @return the white - */ - public JCheckBox getWhite() { - return this.white; - } - - /** - * Gets the blue. - * - * @return the blue - */ - public JCheckBox getBlue() { - return this.blue; - } - - /** - * Gets the black. - * - * @return the black - */ - public JCheckBox getBlack() { - return this.black; - } - - /** - * Gets the red. - * - * @return the red - */ - public JCheckBox getRed() { - return this.red; - } - - /** - * Gets the colorless. - * - * @return the colorless - */ - public JCheckBox getColorless() { - return this.colorless; - } - - /** - * Gets the green. - * - * @return the green - */ - public JCheckBox getGreen() { - return this.green; - } - - /** - * Gets the land. - * - * @return the land - */ - public JCheckBox getLand() { - return this.land; - } - - /** - * Gets the all colors. - * - * @return the allColors - */ - public List getAllColors() { - return this.allColors; - } - - /** - * Gets the creature. - * - * @return the creature - */ - public JCheckBox getCreature() { - return this.creature; - } - - /** - * Gets the sorcery. - * - * @return the sorcery - */ - public JCheckBox getSorcery() { - return this.sorcery; - } - - /** - * Gets the instant. - * - * @return the instant - */ - public JCheckBox getInstant() { - return this.instant; - } - - /** - * Gets the planeswalker. - * - * @return the planeswalker - */ - public JCheckBox getPlaneswalker() { - return this.planeswalker; - } - - /** - * Gets the artifact. - * - * @return the artifact - */ - public JCheckBox getArtifact() { - return this.artifact; - } - - /** - * Gets the enchantment. - * - * @return the enchantment - */ - public JCheckBox getEnchantment() { - return this.enchantment; - } - -} diff --git a/src/main/java/forge/gui/deckeditor/elements/FilterNameTypeSetPanel.java b/src/main/java/forge/gui/deckeditor/elements/FilterNameTypeSetPanel.java deleted file mode 100644 index b9e1cb29e1c..00000000000 --- a/src/main/java/forge/gui/deckeditor/elements/FilterNameTypeSetPanel.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.gui.deckeditor.elements; - -import java.awt.event.ItemListener; -import java.util.ArrayList; -import java.util.List; - -import javax.swing.JComboBox; -import javax.swing.JComponent; -import javax.swing.JLabel; -import javax.swing.JTextField; -import javax.swing.event.DocumentListener; - -import net.miginfocom.swing.MigLayout; - -import org.apache.commons.lang3.StringUtils; - -import forge.Singletons; -import forge.card.CardRules; -import forge.card.CardEdition; -import forge.game.GameFormat; -import forge.item.CardPrinted; -import forge.util.closures.Predicate; -import forge.util.closures.PredicateString.StringOp; - -/** - * A panel that holds Name, Type, Rules text fields aligned horizontally - * together with set filter. - */ -public class FilterNameTypeSetPanel extends JComponent { - - private static final long serialVersionUID = -6409564625432765430L; - - /** The label filter name. */ - private final JLabel labelFilterName = new JLabel(); - - /** The label filter type. */ - private final JLabel labelFilterType = new JLabel(); - - /** The label filter rules. */ - private final JLabel labelFilterRules = new JLabel(); - - /** The txt card name. */ - private final JTextField txtCardName = new JTextField(); - - /** The txt card type. */ - private final JTextField txtCardType = new JTextField(); - - /** The txt card rules. */ - private final JTextField txtCardRules = new JTextField(); - - /** The search set combo. */ - private final JComboBox searchSetCombo = new JComboBox(); - - /** - * Instantiates a new filter name type set panel. - */ - public FilterNameTypeSetPanel() { - this.setLayout(new MigLayout("fill, ins 0")); - - this.labelFilterName.setText("Name:"); - this.labelFilterName.setToolTipText("Card names must include the text in this field"); - this.add(this.labelFilterName, "cell 0 1, split 7"); - this.add(this.txtCardName, "wmin 100, grow"); - - this.labelFilterType.setText("Type:"); - this.labelFilterType.setToolTipText("Card types must include the text in this field"); - this.add(this.labelFilterType, ""); - this.add(this.txtCardType, "wmin 100, grow"); - - this.labelFilterRules.setText("Text:"); - this.labelFilterRules.setToolTipText("Card descriptions must include the text in this field"); - this.add(this.labelFilterRules, ""); - this.add(this.txtCardRules, "wmin 200, grow"); - - this.searchSetCombo.removeAllItems(); - this.searchSetCombo.addItem("(all sets and formats)"); - for (final GameFormat s : Singletons.getModel().getFormats()) { - this.searchSetCombo.addItem(s); - } - for (final CardEdition s : Singletons.getModel().getEditions()) { - this.searchSetCombo.addItem(s); - } - - this.add(this.searchSetCombo, "wmin 150, grow"); - } - - /** - * Sets the listeners. - * - * @param onTextChange - * the on text change - * @param onComboChange - * the on combo change - */ - public final void setListeners(final DocumentListener onTextChange, final ItemListener onComboChange) { - this.txtCardType.getDocument().addDocumentListener(onTextChange); - this.txtCardRules.getDocument().addDocumentListener(onTextChange); - this.txtCardName.getDocument().addDocumentListener(onTextChange); - this.searchSetCombo.addItemListener(onComboChange); - } - - /** - * Builds the filter. - * - * @return the predicate - */ - public final Predicate buildFilter() { - final List> rules = new ArrayList>(4); - if (StringUtils.isNotBlank(this.txtCardName.getText())) { - rules.add(CardPrinted.Predicates.name(StringOp.CONTAINS, this.txtCardName.getText())); - } - - if (StringUtils.isNotBlank(this.txtCardType.getText())) { - rules.add(Predicate.brigde(CardRules.Predicates.joinedType(StringOp.CONTAINS, this.txtCardType.getText()), - CardPrinted.FN_GET_RULES)); - } - - if (StringUtils.isNotBlank(this.txtCardRules.getText())) { - rules.add(Predicate.brigde(CardRules.Predicates.rules(StringOp.CONTAINS, this.txtCardRules.getText()), - CardPrinted.FN_GET_RULES)); - } - - if (this.searchSetCombo.getSelectedIndex() != 0) { - final Object selected = this.searchSetCombo.getSelectedItem(); - if (selected instanceof CardEdition) { - rules.add(CardPrinted.Predicates.printedInSets(((CardEdition) selected).getCode())); - } else if (selected instanceof GameFormat) { - rules.add(((GameFormat) selected).getFilterRules()); - } - } - - switch (rules.size()) { - case 0: - return Predicate.getTrue(CardPrinted.class); - case 1: - return rules.get(0); - case 2: - return Predicate.and(rules.get(0), rules.get(1)); - default: - return Predicate.and(rules); - } - } - - /** - * TODO: Write javadoc for this method. - */ - public final void clearFilters() { - this.txtCardName.setText(""); - this.txtCardType.setText(""); - this.txtCardRules.setText(""); - this.searchSetCombo.setSelectedIndex(0); - } -} diff --git a/src/main/java/forge/gui/deckeditor/elements/TableColumnInfo.java b/src/main/java/forge/gui/deckeditor/elements/TableColumnInfo.java deleted file mode 100644 index 4db0f5d82ed..00000000000 --- a/src/main/java/forge/gui/deckeditor/elements/TableColumnInfo.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.gui.deckeditor.elements; - -import java.util.Map.Entry; - -import javax.swing.table.TableCellRenderer; - -import forge.util.closures.Lambda1; - - -/** - * Holds single column set up for TableModel. Contains name, width + functions - * to retrieve column's value for compare and for display (they are different, - * in case of sets for instance) - * - * @param - * the generic type - */ - -@SuppressWarnings("rawtypes") -public class TableColumnInfo { - private final String name; - - /** The min width. */ - private int minWidth; - - /** The max width. */ - private int maxWidth; - - /** The nominal width. */ - private int nominalWidth; - - /** The is min max applied. */ - private boolean isMinMaxApplied = true; - - /** The fn sort. */ - private final Lambda1> fnSort; // this will be - // used for - // sorting - - /** The fn display. */ - private final Lambda1> fnDisplay; // this is used - // to display - - private TableCellRenderer cellRenderer = null; - - /** - * Gets the name. - * - * @return the name - */ - public final String getName() { - return this.name; - } - - /** - * Instantiates a new table column info. - * - * @param colName - * the col name - * @param fieldSort - * the field sort - * @param fieldDisplay - * the field display - */ - public TableColumnInfo(final String colName, final Lambda1> fieldSort, - final Lambda1> fieldDisplay) { - this.fnSort = fieldSort; - this.fnDisplay = fieldDisplay; - this.name = colName; - } - - /** - * Instantiates a new table column info. - * - * @param colName - * the col name - * @param width - * the width - * @param fieldSort - * the field sort - * @param fieldDisplay - * the field display - */ - public TableColumnInfo(final String colName, final int width, - final Lambda1> fieldSort, - final Lambda1> fieldDisplay) { - this(colName, fieldSort, fieldDisplay); - this.setMaxWidth(width); - this.setMinWidth(width); - this.setNominalWidth(width); - } - - /** - * Instantiates a new table column info. - * - * @param colName - * the col name - * @param wMin - * the w min - * @param width - * the width - * @param wMax - * the w max - * @param fieldSort - * the field sort - * @param fieldDisplay - * the field display - */ - public TableColumnInfo(final String colName, final int wMin, final int width, final int wMax, - final Lambda1> fieldSort, - final Lambda1> fieldDisplay) { - this(colName, fieldSort, fieldDisplay); - this.setMaxWidth(wMax); - this.setMinWidth(wMin); - this.setNominalWidth(width); - } - - /** - * Sets the cell renderer. - * - * @param renderer - * the new cell renderer - */ - public final void setCellRenderer(final TableCellRenderer renderer) { - this.cellRenderer = renderer; - } - - /** - * Gets the cell renderer. - * - * @return the cell renderer - */ - public final TableCellRenderer getCellRenderer() { - return this.cellRenderer; - } - - /** - * Gets the min width. - * - * @return the minWidth - */ - public int getMinWidth() { - return this.minWidth; - } - - /** - * Sets the min width. - * - * @param minWidth0 - * the minWidth to set - */ - public void setMinWidth(final int minWidth0) { - this.minWidth = minWidth0; - } - - /** - * Gets the max width. - * - * @return the maxWidth - */ - public int getMaxWidth() { - return this.maxWidth; - } - - /** - * Sets the max width. - * - * @param maxWidth0 - * the maxWidth to set - */ - public void setMaxWidth(final int maxWidth0) { - this.maxWidth = maxWidth0; - } - - /** - * Gets the nominal width. - * - * @return the nominalWidth - */ - public int getNominalWidth() { - return this.nominalWidth; - } - - /** - * Sets the nominal width. - * - * @param nominalWidth0 - * the nominalWidth to set - */ - public void setNominalWidth(final int nominalWidth0) { - this.nominalWidth = nominalWidth0; - } - - /** - * Checks if is min max applied. - * - * @return the isMinMaxApplied - */ - public boolean isMinMaxApplied() { - return this.isMinMaxApplied; - } - - /** - * Sets the min max applied. - * - * @param isMinMaxApplied0 - * the isMinMaxApplied to set - */ - public void setMinMaxApplied(final boolean isMinMaxApplied0) { - this.isMinMaxApplied = isMinMaxApplied0; - } - - /** - * Gets the fn sort. - * - * @return the fnSort - */ - public Lambda1> getFnSort() { - return this.fnSort; - } - - /** - * Gets the fn display. - * - * @return the fnDisplay - */ - public Lambda1> getFnDisplay() { - return this.fnDisplay; - } -} diff --git a/src/main/java/forge/gui/deckeditor/elements/TableModel.java b/src/main/java/forge/gui/deckeditor/elements/TableModel.java deleted file mode 100644 index 04f48d0ffee..00000000000 --- a/src/main/java/forge/gui/deckeditor/elements/TableModel.java +++ /dev/null @@ -1,451 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.gui.deckeditor.elements; - -import java.awt.event.FocusEvent; -import java.awt.event.FocusListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Map.Entry; - -import javax.swing.JTable; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; -import javax.swing.event.TableModelEvent; -import javax.swing.table.AbstractTableModel; -import javax.swing.table.TableColumn; -import javax.swing.table.TableColumnModel; - -import forge.item.InventoryItem; -import forge.item.ItemPool; -import forge.item.ItemPoolView; - -/** - *

- * TableModel class. - *

- * - * @param - * the generic type - * @author Forge - * @version $Id$ - */ -public final class TableModel extends AbstractTableModel { - /** - * - */ - private static final long serialVersionUID = -6896726613116254828L; - - private final class SortOrders { - private class Order { - private final int sortColumn; - private boolean isSortAsc = true; - - public Order(final int col) { - this.sortColumn = col; - } - }; - - private final int maxDepth = 3; - private final List orders = new ArrayList(3); - private TableSorterCascade sorter = null; - private boolean isSorterReady = false; - - private int indexOfColumn(final int column) { - int posColumn = this.orders.size() - 1; - for (; posColumn >= 0; posColumn--) { - if ((this.orders.get(posColumn) != null) && (this.orders.get(posColumn).sortColumn == column)) { - break; - } - } - return posColumn; - } - - // index of column to sort by, desired direction - public void add(final int column, final boolean wantAsc) { - this.add(column); - this.orders.get(0).isSortAsc = wantAsc; - this.isSorterReady = false; - } - - // puts desired direction on top, set "asc"; if already was on top, - // inverts direction; - public void add(final int column) { - final int posColumn = this.indexOfColumn(column); - switch (posColumn) { - case -1: // no such column here - let's add then - this.orders.add(0, new Order(column)); - break; - case 0: // found at top-level, should invert - this.orders.get(0).isSortAsc ^= true; // invert - break; - default: // found somewhere, move down others, set this one onto - // top; - this.orders.remove(posColumn); - this.orders.add(0, new Order(column)); - break; - } - if (this.orders.size() > this.maxDepth) { - this.orders.remove(this.maxDepth); - } - this.isSorterReady = false; - } - - public TableSorterCascade getSorter() { - if (!this.isSorterReady) { - final List> oneColSorters = new ArrayList>(this.maxDepth); - for (final Order order : this.orders) { - oneColSorters.add(new TableSorter(TableModel.this.columns.get(order.sortColumn).getFnSort(), - order.isSortAsc)); - } - this.sorter = new TableSorterCascade(oneColSorters); - } - return this.sorter; - } - } - - private final ItemPool data; - private final CardPanelBase cardDisplay; - private final List> columns; - private final SortOrders sortOrders = new SortOrders(); - - /** - * Instantiates a new table model. - * - * @param cd - * the cd - * @param columnsToShow - * the columns to show - * @param cls - * the cls - */ - public TableModel(final CardPanelBase cd, final List> columnsToShow, final Class cls) { - this.data = new ItemPool(cls); - this.cardDisplay = cd; - this.columns = columnsToShow; - this.columns.get(4).setMinMaxApplied(false); - } - - /** - * Resize cols. - * - * @param table - * the table - */ - public void resizeCols(final JTable table) { - TableColumn tableColumn = null; - for (int i = 0; i < table.getColumnCount(); i++) { - tableColumn = table.getColumnModel().getColumn(i); - final TableColumnInfo colInfo = this.columns.get(i); - - tableColumn.setPreferredWidth(colInfo.getNominalWidth()); - if (colInfo.isMinMaxApplied()) { - tableColumn.setMinWidth(colInfo.getMinWidth()); - tableColumn.setMaxWidth(colInfo.getMaxWidth()); - } - } - } - - /** - * Clear. - */ - public void clear() { - this.data.clear(); - } - - /** - * Gets the cards. - * - * @return the cards - */ - public ItemPoolView getCards() { - return this.data.getView(); - } - - /** - *

- * removeCard. - *

- * - * @param c - * a {@link forge.Card} object. - */ - public void removeCard(final T c) { - final boolean wasThere = this.data.count(c) > 0; - if (wasThere) { - this.data.remove(c); - this.fireTableDataChanged(); - } - } - - /** - * Adds the card. - * - * @param c - * the c - */ - public void addCard(final T c) { - this.data.add(c); - this.fireTableDataChanged(); - } - - /** - * Adds the card. - * - * @param c - * the c - * @param count - * the count - */ - public void addCard(final T c, final int count) { - this.data.add(c, count); - this.fireTableDataChanged(); - } - - /** - * Adds the card. - * - * @param e - * the e - */ - public void addCard(final Entry e) { - this.data.add(e.getKey(), e.getValue()); - this.fireTableDataChanged(); - } - - /** - * Adds the cards. - * - * @param c - * the c - */ - public void addCards(final Iterable> c) { - this.data.addAll(c); - this.fireTableDataChanged(); - } - - /** - * Adds the all cards. - * - * @param c - * the c - */ - public void addAllCards(final Iterable c) { - this.data.addAllFlat(c); - this.fireTableDataChanged(); - } - - /** - * Row to card. - * - * @param row - * the row - * @return the entry - */ - public Entry rowToCard(final int row) { - final List> model = this.data.getOrderedList(); - return (row >= 0) && (row < model.size()) ? model.get(row) : null; - } - - /* - * (non-Javadoc) - * - * @see javax.swing.table.TableModel#getRowCount() - */ - /** - * Gets the row count. - * - * @return int - */ - @Override - public int getRowCount() { - return this.data.countDistinct(); - } - - /* - * (non-Javadoc) - * - * @see javax.swing.table.TableModel#getColumnCount() - */ - /** - * Gets the column count. - * - * @return int - */ - @Override - public int getColumnCount() { - return this.columns.size(); - } - - /** {@inheritDoc} */ - @Override - public String getColumnName(final int n) { - return this.columns.get(n).getName(); - } - - /** {@inheritDoc} */ - @SuppressWarnings("unchecked") - @Override - public Object getValueAt(final int row, final int column) { - return this.columns.get(column).getFnDisplay().apply((Entry) this.rowToCard(row)); - } - - /** - * The listener interface for receiving column events. The class that is - * interested in processing a column event implements this interface, and - * the object created with that class is registered with a component using - * the component's addColumnListener method. When the column event occurs, - * that object's appropriate method is invoked. - * - */ - class ColumnListener extends MouseAdapter { - - /** The table. */ - private final JTable table; - - /** - * Instantiates a new column listener. - * - * @param t - * the t - */ - public ColumnListener(final JTable t) { - this.table = t; - } - - /* - * (non-Javadoc) - * - * @see - * java.awt.event.MouseAdapter#mouseClicked(java.awt.event.MouseEvent) - */ - /** - * Mouse clicked. - * - * @param e - * MouseEvent - */ - @Override - public void mouseClicked(final MouseEvent e) { - final TableColumnModel colModel = this.table.getColumnModel(); - final int columnModelIndex = colModel.getColumnIndexAtX(e.getX()); - final int modelIndex = colModel.getColumn(columnModelIndex).getModelIndex(); - - if (modelIndex < 0) { - return; - } - - // This will invert if needed - TableModel.this.sortOrders.add(modelIndex); - - for (int i = 0; i < TableModel.this.columns.size(); i++) { - final TableColumn column = colModel.getColumn(i); - column.setHeaderValue(TableModel.this.getColumnName(column.getModelIndex())); - } - this.table.getTableHeader().repaint(); - - TableModel.this.resort(); - this.table.tableChanged(new TableModelEvent(TableModel.this)); - this.table.repaint(); - } - } - - /** - * Show selected card. - * - * @param table - * the table - */ - public void showSelectedCard(final JTable table) { - final int row = table.getSelectedRow(); - if (row != -1) { - final T cp = this.rowToCard(row).getKey(); - this.cardDisplay.showCard(cp); - } - } - - /** - *

- * addListeners. - *

- * - * @param table - * a {@link javax.swing.JTable} object. - */ - public void addListeners(final JTable table) { - // updates card detail, listens to any key strokes - table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { - - @Override - public void valueChanged(final ListSelectionEvent arg0) { - TableModel.this.showSelectedCard(table); - } - }); - table.addFocusListener(new FocusListener() { - - @Override - public void focusLost(final FocusEvent e) { - } - - @Override - public void focusGained(final FocusEvent e) { - TableModel.this.showSelectedCard(table); - } - }); - - table.getTableHeader().addMouseListener(new ColumnListener(table)); - - } // addCardListener() - - private class MyComparator implements Comparator> { - /* (non-Javadoc) - * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) - */ - private TableSorterCascade sorter = TableModel.this.sortOrders.getSorter(); - @SuppressWarnings("unchecked") - @Override - public int compare(Entry o1, Entry o2) { - return sorter.compare((Entry) o1, (Entry) o2); - } - } - - /** - * Resort. - */ - public void resort() { - Collections.sort(this.data.getOrderedList(), new MyComparator()); - } - - /** - * Sort. - * - * @param iCol - * the i col - * @param isAsc - * the is asc - */ - public void sort(final int iCol, final boolean isAsc) { - this.sortOrders.add(iCol, isAsc); - this.resort(); - } - -} // CardTableModel diff --git a/src/main/java/forge/gui/deckeditor/elements/package-info.java b/src/main/java/forge/gui/deckeditor/elements/package-info.java deleted file mode 100644 index 00dba87a7f2..00000000000 --- a/src/main/java/forge/gui/deckeditor/elements/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Forge Card Game. */ -package forge.gui.deckeditor.elements; - diff --git a/src/main/java/forge/gui/deckeditor/DeckController.java b/src/main/java/forge/gui/deckeditor/tables/DeckController.java similarity index 83% rename from src/main/java/forge/gui/deckeditor/DeckController.java rename to src/main/java/forge/gui/deckeditor/tables/DeckController.java index 132ca046c2f..197984b0cd7 100644 --- a/src/main/java/forge/gui/deckeditor/DeckController.java +++ b/src/main/java/forge/gui/deckeditor/tables/DeckController.java @@ -15,15 +15,17 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package forge.gui.deckeditor; +package forge.gui.deckeditor.tables; -import java.awt.Component; import java.util.ArrayList; - import org.apache.commons.lang3.StringUtils; import forge.deck.DeckBase; +import forge.gui.deckeditor.controllers.ACEditorBase; +import forge.gui.deckeditor.controllers.CProbabilities; +import forge.gui.deckeditor.controllers.CStatistics; +import forge.gui.deckeditor.views.VCurrentDeck; import forge.util.IStorage; import forge.util.closures.Lambda0; @@ -38,7 +40,7 @@ public class DeckController { private boolean saved; private boolean modelInStore; private final IStorage folder; - private final DeckEditorBase view; + private final ACEditorBase view; private final Lambda0 newModelCreator; /** @@ -48,7 +50,7 @@ public class DeckController { * @param view0 the view0 * @param newModelCreator0 the new model creator0 */ - public DeckController(final IStorage folder0, final DeckEditorBase view0, + public DeckController(final IStorage folder0, final ACEditorBase view0, final Lambda0 newModelCreator0) { this.folder = folder0; this.view = view0; @@ -85,7 +87,12 @@ public class DeckController { public void setModel(final T document, final boolean isStored) { this.modelInStore = isStored; this.model = document; - this.view.updateView(); + this.view.resetTables(); + + VCurrentDeck.SINGLETON_INSTANCE.getTxfTitle().setText(model.getName()); + CStatistics.SINGLETON_INSTANCE.update(); + CProbabilities.SINGLETON_INSTANCE.update(); + this.saved = true; // unless set to false in notify if (!this.isModelInSyncWithFolder()) { this.notifyModelChanged(); @@ -110,7 +117,7 @@ public class DeckController { * * @return the view */ - public DeckEditorBase getView() { + public ACEditorBase getView() { return this.view; } @@ -127,20 +134,6 @@ public class DeckController { // view.setTitle(); } - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.IDeckController#getOwnerWindow() - */ - /** - * Gets the owner window. - * - * @return the owner window - */ - public Component getOwnerWindow() { - return this.getView(); - } - /* * (non-Javadoc) * @@ -187,6 +180,7 @@ public class DeckController { if (null == model) { return; } + this.folder.add(this.model); // copy to new instance which will be edited and left if unsaved this.setModel((T) this.model.copyTo(this.model.getName()), true); @@ -258,20 +252,6 @@ public class DeckController { return !this.folder.isUnique(deckName); } - /* (non-Javadoc) - * @see forge.gui.deckeditor.IDeckController#isGoodName(java.lang.String) - */ - - /** - * Checks if is good name. - * - * @param deckName the deck name - * @return true, if is good name - */ - public boolean isGoodName(final String deckName) { - return StringUtils.isNotBlank(deckName) && this.folder.isUnique(deckName); - } - /* * (non-Javadoc) * @@ -314,6 +294,6 @@ public class DeckController { public void newModel() { this.model = this.newModelCreator.apply(); this.saved = true; - this.view.updateView(); + this.view.resetTables(); } } diff --git a/src/main/java/forge/gui/deckeditor/tables/IntegerRenderer.java b/src/main/java/forge/gui/deckeditor/tables/IntegerRenderer.java new file mode 100644 index 00000000000..de1fcb9b2f0 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/tables/IntegerRenderer.java @@ -0,0 +1,44 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package forge.gui.deckeditor.tables; + +import java.awt.Component; + +import javax.swing.JTable; +import javax.swing.table.DefaultTableCellRenderer; + +/** + * A quick converter to avoid -1 being displayed for unapplicable values. + */ +@SuppressWarnings("serial") +public class IntegerRenderer extends DefaultTableCellRenderer { + /* + * (non-Javadoc) + * + * @see + * javax.swing.table.DefaultTableCellRenderer#getTableCellRendererComponent + * (javax.swing.JTable, java.lang.Object, boolean, boolean, int, int) + */ + @Override + public final Component getTableCellRendererComponent(final JTable table, Object value0, + final boolean isSelected, final boolean hasFocus, final int row, final int column) { + + if ((Integer) value0 == -1) { value0 = "-"; } + return super.getTableCellRendererComponent(table, value0, isSelected, hasFocus, row, column); + } +} diff --git a/src/main/java/forge/gui/deckeditor/elements/ManaCostRenderer.java b/src/main/java/forge/gui/deckeditor/tables/ManaCostRenderer.java similarity index 95% rename from src/main/java/forge/gui/deckeditor/elements/ManaCostRenderer.java rename to src/main/java/forge/gui/deckeditor/tables/ManaCostRenderer.java index 25a9536c35f..c0f90471380 100644 --- a/src/main/java/forge/gui/deckeditor/elements/ManaCostRenderer.java +++ b/src/main/java/forge/gui/deckeditor/tables/ManaCostRenderer.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package forge.gui.deckeditor.elements; +package forge.gui.deckeditor.tables; import java.awt.Component; import java.awt.Graphics; diff --git a/src/main/java/forge/gui/deckeditor/tables/SColumnUtil.java b/src/main/java/forge/gui/deckeditor/tables/SColumnUtil.java new file mode 100644 index 00000000000..cbac7c9b425 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/tables/SColumnUtil.java @@ -0,0 +1,530 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package forge.gui.deckeditor.tables; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; +import java.util.regex.Pattern; + +import javax.swing.JTable; +import javax.swing.table.TableColumnModel; + +import forge.Singletons; +import forge.card.CardColor; +import forge.card.CardEdition; +import forge.card.CardManaCost; +import forge.card.CardRarity; +import forge.deck.DeckBase; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.SEditorIO; +import forge.gui.deckeditor.controllers.ACEditorBase; +import forge.item.CardPrinted; +import forge.item.InventoryItem; +import forge.item.InventoryItemFromSet; +import forge.util.closures.Lambda1; + +/** + * A collection of methods pertaining to columns in card catalog and + * current deck tables, for use in the deck editor. + *

+ * (S at beginning of class name denotes a static factory.) + * + */ +public final class SColumnUtil { + /** + * Each catalog column identified in the XML file is + * referenced using these names. Its name in the XML + * should match the name in the enum. Underscores + * will be replaced with spaces in the display. + *

+ * Note: To add a new column, put an enum here, and also add in the XML prefs file. + */ + public enum ColumnName { /** */ + CAT_QUANTITY, /** */ + CAT_NAME, /** */ + CAT_COST, /** */ + CAT_COLOR, /** */ + CAT_TYPE, /** */ + CAT_POWER, /** */ + CAT_TOUGHNESS, /** */ + CAT_CMC, /** */ + CAT_RARITY, /** */ + CAT_SET, /** */ + CAT_AI, /** */ + CAT_NEW, /** */ + CAT_PURCHASE_PRICE, /** */ + CAT_DECKS, /** */ + DECK_QUANTITY, /** */ + DECK_NAME, /** */ + DECK_COST, /** */ + DECK_COLOR, /** */ + DECK_TYPE, /** */ + DECK_POWER, /** */ + DECK_TOUGHNESS, /** */ + DECK_CMC, /** */ + DECK_RARITY, /** */ + DECK_SET, /** */ + DECK_AI, /** */ + DECK_NEW, /** */ + DECK_SALE_PRICE; + } + + /** Possible states of data sorting in a column: none, ascending, or descending. */ + public enum SortState { /** */ + NONE, /** */ + ASC, /** */ + DESC + } + + /** @return List> */ + public static List> getCatalogDefaultColumns() { + final List> columns = new ArrayList>(); + + columns.add(SColumnUtil.getColumn(ColumnName.CAT_QUANTITY)); + columns.add(SColumnUtil.getColumn(ColumnName.CAT_NAME)); + columns.add(SColumnUtil.getColumn(ColumnName.CAT_COST)); + columns.add(SColumnUtil.getColumn(ColumnName.CAT_COLOR)); + columns.add(SColumnUtil.getColumn(ColumnName.CAT_TYPE)); + columns.add(SColumnUtil.getColumn(ColumnName.CAT_POWER)); + columns.add(SColumnUtil.getColumn(ColumnName.CAT_TOUGHNESS)); + columns.add(SColumnUtil.getColumn(ColumnName.CAT_CMC)); + columns.add(SColumnUtil.getColumn(ColumnName.CAT_RARITY)); + columns.add(SColumnUtil.getColumn(ColumnName.CAT_SET)); + columns.add(SColumnUtil.getColumn(ColumnName.CAT_AI)); + + return columns; + } + + /** @return List> */ + public static List> getDeckDefaultColumns() { + final List> columns = new ArrayList>(); + + columns.add(SColumnUtil.getColumn(ColumnName.DECK_QUANTITY)); + columns.add(SColumnUtil.getColumn(ColumnName.DECK_NAME)); + columns.add(SColumnUtil.getColumn(ColumnName.DECK_COST)); + columns.add(SColumnUtil.getColumn(ColumnName.DECK_COLOR)); + columns.add(SColumnUtil.getColumn(ColumnName.DECK_TYPE)); + columns.add(SColumnUtil.getColumn(ColumnName.DECK_POWER)); + columns.add(SColumnUtil.getColumn(ColumnName.DECK_TOUGHNESS)); + columns.add(SColumnUtil.getColumn(ColumnName.DECK_CMC)); + columns.add(SColumnUtil.getColumn(ColumnName.DECK_RARITY)); + columns.add(SColumnUtil.getColumn(ColumnName.DECK_SET)); + columns.add(SColumnUtil.getColumn(ColumnName.DECK_AI)); + + return columns; + } + + /** Should be called after column preferences has run, which has created a new column list. */ + public static void attachSortAndDisplayFunctions() { + SColumnUtil.getColumn(ColumnName.CAT_QUANTITY).setSortAndDisplayFunctions( + SColumnUtil.FN_QTY_COMPARE, SColumnUtil.FN_QTY_GET); + SColumnUtil.getColumn(ColumnName.CAT_NAME).setSortAndDisplayFunctions( + SColumnUtil.FN_NAME_COMPARE, SColumnUtil.FN_NAME_GET); + SColumnUtil.getColumn(ColumnName.CAT_COST).setSortAndDisplayFunctions( + SColumnUtil.FN_COST_COMPARE, SColumnUtil.FN_COST_GET); + SColumnUtil.getColumn(ColumnName.CAT_COLOR).setSortAndDisplayFunctions( + SColumnUtil.FN_COLOR_COMPARE, SColumnUtil.FN_COLOR_GET); + SColumnUtil.getColumn(ColumnName.CAT_TYPE).setSortAndDisplayFunctions( + SColumnUtil.FN_TYPE_COMPARE, SColumnUtil.FN_TYPE_GET); + SColumnUtil.getColumn(ColumnName.CAT_POWER).setSortAndDisplayFunctions( + SColumnUtil.FN_POWER_COMPARE, SColumnUtil.FN_POWER_GET); + SColumnUtil.getColumn(ColumnName.CAT_TOUGHNESS).setSortAndDisplayFunctions( + SColumnUtil.FN_TOUGHNESS_COMPARE, SColumnUtil.FN_TOUGHNESS_GET); + SColumnUtil.getColumn(ColumnName.CAT_CMC).setSortAndDisplayFunctions( + SColumnUtil.FN_CMC_COMPARE, SColumnUtil.FN_CMC_GET); + SColumnUtil.getColumn(ColumnName.CAT_RARITY).setSortAndDisplayFunctions( + SColumnUtil.FN_RARITY_COMPARE, SColumnUtil.FN_RARITY_GET); + SColumnUtil.getColumn(ColumnName.CAT_SET).setSortAndDisplayFunctions( + SColumnUtil.FN_SET_COMPARE, SColumnUtil.FN_SET_GET); + SColumnUtil.getColumn(ColumnName.CAT_AI).setSortAndDisplayFunctions( + SColumnUtil.FN_AI_STATUS_COMPARE, SColumnUtil.FN_AI_STATUS_GET); + + SColumnUtil.getColumn(ColumnName.DECK_QUANTITY).setSortAndDisplayFunctions( + SColumnUtil.FN_QTY_COMPARE, SColumnUtil.FN_QTY_GET); + SColumnUtil.getColumn(ColumnName.DECK_NAME).setSortAndDisplayFunctions( + SColumnUtil.FN_NAME_COMPARE, SColumnUtil.FN_NAME_GET); + SColumnUtil.getColumn(ColumnName.DECK_COST).setSortAndDisplayFunctions( + SColumnUtil.FN_COST_COMPARE, SColumnUtil.FN_COST_GET); + SColumnUtil.getColumn(ColumnName.DECK_COLOR).setSortAndDisplayFunctions( + SColumnUtil.FN_COLOR_COMPARE, SColumnUtil.FN_COLOR_GET); + SColumnUtil.getColumn(ColumnName.DECK_TYPE).setSortAndDisplayFunctions( + SColumnUtil.FN_TYPE_COMPARE, SColumnUtil.FN_TYPE_GET); + SColumnUtil.getColumn(ColumnName.DECK_POWER).setSortAndDisplayFunctions( + SColumnUtil.FN_POWER_COMPARE, SColumnUtil.FN_POWER_GET); + SColumnUtil.getColumn(ColumnName.DECK_TOUGHNESS).setSortAndDisplayFunctions( + SColumnUtil.FN_TOUGHNESS_COMPARE, SColumnUtil.FN_TOUGHNESS_GET); + SColumnUtil.getColumn(ColumnName.DECK_CMC).setSortAndDisplayFunctions( + SColumnUtil.FN_CMC_COMPARE, SColumnUtil.FN_CMC_GET); + SColumnUtil.getColumn(ColumnName.DECK_RARITY).setSortAndDisplayFunctions( + SColumnUtil.FN_RARITY_COMPARE, SColumnUtil.FN_RARITY_GET); + SColumnUtil.getColumn(ColumnName.DECK_SET).setSortAndDisplayFunctions( + SColumnUtil.FN_SET_COMPARE, SColumnUtil.FN_SET_GET); + SColumnUtil.getColumn(ColumnName.DECK_AI).setSortAndDisplayFunctions( + SColumnUtil.FN_AI_STATUS_COMPARE, SColumnUtil.FN_AI_STATUS_GET); + + SColumnUtil.getColumn(ColumnName.CAT_COST).setCellRenderer(new ManaCostRenderer()); + SColumnUtil.getColumn(ColumnName.CAT_POWER).setCellRenderer(new IntegerRenderer()); + SColumnUtil.getColumn(ColumnName.CAT_TOUGHNESS).setCellRenderer(new IntegerRenderer()); + SColumnUtil.getColumn(ColumnName.CAT_CMC).setCellRenderer(new IntegerRenderer()); + + SColumnUtil.getColumn(ColumnName.DECK_COST).setCellRenderer(new ManaCostRenderer()); + SColumnUtil.getColumn(ColumnName.DECK_POWER).setCellRenderer(new IntegerRenderer()); + SColumnUtil.getColumn(ColumnName.DECK_TOUGHNESS).setCellRenderer(new IntegerRenderer()); + SColumnUtil.getColumn(ColumnName.DECK_CMC).setCellRenderer(new IntegerRenderer()); + } + + /** + * Hides/shows a table column. + * + * @param col0 TableColumnInfo + * @param extends InventoryItem + * @param extends DeckBase + */ + @SuppressWarnings("unchecked") + public static + void toggleColumn(final TableColumnInfo col0) { + + final ACEditorBase ed = (ACEditorBase) + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController(); + + final JTable tbl = (col0.getEnumValue().substring(0, 4).equals("DECK")) + ? ed.getTableDeck().getTable() + : ed.getTableCatalog().getTable(); + + final TableColumnModel colmodel = tbl.getColumnModel(); + + if (col0.isShowing()) { + col0.setShowing(false); + colmodel.removeColumn(col0); + } + else { + col0.setShowing(true); + colmodel.addColumn(col0); + if (col0.getModelIndex() < colmodel.getColumnCount()) { + colmodel.moveColumn(colmodel.getColumnIndex(col0.getIdentifier()), col0.getModelIndex()); + } + } + } + + /** + * Retrieve a custom column (uses identical method in SEditorIO). + * + * @param id0   {@link forge.gui.deckeditor.SEditorUtil.CatalogColumnName} + * @return TableColumnInfo + */ + public static TableColumnInfo getColumn(final ColumnName id0) { + return SEditorIO.getColumn(id0); + } + + /** + * Convenience method to get a column's index in the view (that is, + * in the TableColumnModel). + * + * @param id0   {@link forge.gui.deckeditor.SEditorUtil.CatalogColumnName} + * @return int + * @param extends InventoryItem + * @param extends InventoryItem + */ + @SuppressWarnings("unchecked") + public static + int getColumnViewIndex(final ColumnName id0) { + + final ACEditorBase ed = (ACEditorBase) + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController(); + + final JTable tbl = (id0.toString().substring(0, 4).equals("DECK")) + ? ed.getTableDeck().getTable() + : ed.getTableCatalog().getTable(); + + int index = -1; + + try { + index = tbl.getColumnModel().getColumnIndex(SColumnUtil.getColumn(id0).getIdentifier()); + } + catch (final Exception e) { } + + return index; + } + + /** + * Convenience method to get a column's index in the model (that is, + * in the TableModel, NOT the TableColumnModel). + * + * @param id0   {@link forge.gui.deckeditor.SEditorUtil.CatalogColumnName} + * @return int + * @param extends InventoryItem + * @param extends InventoryItem + */ + @SuppressWarnings("unchecked") + public static + int getColumnModelIndex(final ColumnName id0) { + + final ACEditorBase ed = (ACEditorBase) + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController(); + + final JTable tbl = (id0.toString().substring(0, 4) == "DECK") + ? ed.getTableDeck().getTable() + : ed.getTableCatalog().getTable(); + + return tbl.getColumn(SColumnUtil.getColumn(id0).getIdentifier()).getModelIndex(); + } + + //========== Display functions + + private static final Pattern AE_FINDER = Pattern.compile("AE", Pattern.LITERAL); + + private static CardManaCost toManaCost(final InventoryItem i) { + return i instanceof CardPrinted ? ((CardPrinted) i).getCard().getManaCost() : CardManaCost.EMPTY; + } + + private static CardColor toColor(final InventoryItem i) { + return i instanceof CardPrinted ? ((CardPrinted) i).getCard().getColor() : CardColor.getNullColor(); + } + + private static Integer toPower(final InventoryItem i) { + Integer result = -1; + if (i instanceof CardPrinted) { + result = ((CardPrinted) i).getCard().getIntPower(); + if (result == null) { + result = Integer.valueOf(((CardPrinted) i).getCard().getLoyalty()); + if (result == null) { result = -1; } + } + } + return result; + } + + private static Integer toToughness(final InventoryItem i) { + return i instanceof CardPrinted ? ((CardPrinted) i).getCard().getIntToughness() : -1; + } + + private static Integer toCMC(final InventoryItem i) { + return i instanceof CardPrinted ? ((CardPrinted) i).getCard().getManaCost().getCMC() : -1; + } + + private static CardRarity toRarity(final InventoryItem i) { + return i instanceof CardPrinted ? ((CardPrinted) i).getRarity() : CardRarity.Unknown; + } + + private static CardEdition toSetCmp(final InventoryItem i) { + return i instanceof InventoryItemFromSet ? Singletons.getModel().getEditions() + .get(((InventoryItemFromSet) i).getEdition()) : CardEdition.UNKNOWN; + } + + private static String toSetStr(final InventoryItem i) { + return i instanceof InventoryItemFromSet ? ((InventoryItemFromSet) i).getEdition() : "n/a"; + } + + private static Integer toAiCmp(final InventoryItem i) { + return i instanceof CardPrinted ? ((CardPrinted) i).getCard().getAiStatusComparable() : Integer.valueOf(-1); + } + + private static String toAiStr(final InventoryItem i) { + return i instanceof CardPrinted ? ((CardPrinted) i).getCard().getAiStatus() : "n/a"; + } + + //========== + + /** Lamda sort fnQtyCompare. */ + @SuppressWarnings("rawtypes") + private static final Lambda1> FN_QTY_COMPARE = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return from.getValue(); + } + }; + + /** Lamda sort fnQtyGet. */ + private static final Lambda1> FN_QTY_GET = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return from.getValue(); + } + }; + + /** Lamda sort fnNameCompare. */ + @SuppressWarnings("rawtypes") + private static final Lambda1> FN_NAME_COMPARE = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return from.getKey().getName(); + } + }; + + /** Lamda sort fnNameGet. */ + private static final Lambda1> FN_NAME_GET = new Lambda1>() { + @Override + public Object apply(final Entry from) { + final String name = from.getKey().getName(); + return name.contains("AE") ? SColumnUtil.AE_FINDER.matcher(name).replaceAll("\u00C6") : name; + } + }; + + /** Lamda sort fnCostCompare. */ + @SuppressWarnings("rawtypes") + private static final Lambda1> FN_COST_COMPARE = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return SColumnUtil.toManaCost(from.getKey()); + } + }; + + /** Lamda sort fnCostGet. */ + private static final Lambda1> FN_COST_GET = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return SColumnUtil.toManaCost(from.getKey()); + } + }; + + /** Lamda sort fnColorCompare. */ + @SuppressWarnings("rawtypes") + private static final Lambda1> FN_COLOR_COMPARE = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return SColumnUtil.toColor(from.getKey()); + } + }; + + /** Lamda sort fnColorGet. */ + private static final Lambda1> FN_COLOR_GET = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return SColumnUtil.toColor(from.getKey()); + } + }; + + /** Lamda sort fnTypeCompare. */ + @SuppressWarnings("rawtypes") + private static final Lambda1> FN_TYPE_COMPARE = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return from.getKey().getType(); + } + }; + + /** Lamda sort fnTypeGet. */ + private static final Lambda1> FN_TYPE_GET = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return from.getKey().getType(); + } + }; + + /** Lamda sort fnPowerCompare. */ + @SuppressWarnings("rawtypes") + private static final Lambda1> FN_POWER_COMPARE = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return SColumnUtil.toPower(from.getKey()); + } + }; + + /** Lamda sort fnPowerGet. */ + private static final Lambda1> FN_POWER_GET = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return SColumnUtil.toPower(from.getKey()); + } + }; + + /** Lamda sort fnToughnessCompare. */ + @SuppressWarnings("rawtypes") + private static final Lambda1> FN_TOUGHNESS_COMPARE = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return SColumnUtil.toToughness(from.getKey()); + } + }; + + /** Lamda sort fnToughnessGet. */ + private static final Lambda1> FN_TOUGHNESS_GET = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return SColumnUtil.toToughness(from.getKey()); + } + }; + + /** Lamda sort fnCMCCompare. */ + @SuppressWarnings("rawtypes") + private static final Lambda1> FN_CMC_COMPARE = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return SColumnUtil.toCMC(from.getKey()); + } + }; + + /** Lamda sort fnCMCGet. */ + private static final Lambda1> FN_CMC_GET = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return SColumnUtil.toCMC(from.getKey()); + } + }; + + /** Lamda sort fnRarityCompare. */ + @SuppressWarnings("rawtypes") + private static final Lambda1> FN_RARITY_COMPARE = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return SColumnUtil.toRarity(from.getKey()); + } + }; + + /** Lamda sort fnRarityGet. */ + private static final Lambda1> FN_RARITY_GET = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return SColumnUtil.toRarity(from.getKey()); + } + }; + + /** Lamda sort fnSetCompare. */ + @SuppressWarnings("rawtypes") + private static final Lambda1> FN_SET_COMPARE = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return SColumnUtil.toSetCmp(from.getKey()); + } + }; + + /** Lamda sort fnSetGet. */ + private static final Lambda1> FN_SET_GET = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return SColumnUtil.toSetStr(from.getKey()); + } + }; + + /** Lamda sort fnAiStatusCompare. */ + @SuppressWarnings("rawtypes") + private static final Lambda1> FN_AI_STATUS_COMPARE = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return SColumnUtil.toAiCmp(from.getKey()); + } + }; + + /** Lamda sort fnAiStatusGet. */ + private static final Lambda1> FN_AI_STATUS_GET = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return SColumnUtil.toAiStr(from.getKey()); + } + }; +} diff --git a/src/main/java/forge/gui/deckeditor/tables/TableColumnInfo.java b/src/main/java/forge/gui/deckeditor/tables/TableColumnInfo.java new file mode 100644 index 00000000000..2af9cb02aff --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/tables/TableColumnInfo.java @@ -0,0 +1,142 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package forge.gui.deckeditor.tables; + +import java.util.Map.Entry; + +import javax.swing.table.TableColumn; + +import forge.gui.deckeditor.tables.SColumnUtil.SortState; +import forge.util.closures.Lambda1; + +/** + * A column object in a TableModel in the card editor. + * Requires a sorting function and a display function + * (to extract information as appropriate for table row data). + * + * @param a generic type + */ + +@SuppressWarnings({ "rawtypes", "serial" }) +public class TableColumnInfo extends TableColumn { + private SortState sortstate = SortState.NONE; + private int sortPriority = 0; + private boolean show = true; + private String enumval; + + private Lambda1> fnSort; + private Lambda1> fnDisplay; + + /** */ + public TableColumnInfo() { + super(); + } + + /** + * Unique identifier in SColumnUtil.ColumnName enum. + * + * @return {@link java.lang.String} + */ + public String getEnumValue() { + return enumval; + } + + /** + * Unique identifier in SColumnUtil.ColumnName enum. + * + * @param val0   {@link java.lang.String} + */ + public void setEnumValue(final String val0) { + this.enumval = val0; + } + + /** + * Position in sort cascade, 0 for no priority. + * + * @return int + */ + public int getSortPriority() { + return sortPriority; + } + + /** + * Position in sort cascade, 0 for no priority. + * + * @param position0   int + */ + public void setSortPriority(final int position0) { + this.sortPriority = position0; + } + + /** @return {@link forge.gui.deckeditor.tables.TableModel.SortState} */ + public SortState getSortState() { + return this.sortstate; + } + + /** @param state0   {@link forge.gui.deckeditor.tables.TableColumnInfo.SortState} */ + public void setSortState(final SortState state0) { + this.sortstate = state0; + } + + /** @return boolean */ + public boolean isShowing() { + return this.show; + } + + /** @param boolean0   show/hide this column */ + public void setShowing(final boolean boolean0) { + this.show = boolean0; + } + + /** + * Lambda closure used to sort this column. + * + * @return the fnSort + */ + public Lambda1> getFnSort() { + if (fnSort.equals(null)) { + throw new NullPointerException("A sort function hasn't been set for " + + "Column " + TableColumnInfo.this.getIdentifier()); + } + return this.fnSort; + } + + /** + * Gets the fn display. + * + * @return the fnDisplay + */ + public Lambda1> getFnDisplay() { + if (fnSort.equals(null)) { + throw new NullPointerException("A display function hasn't been set for " + + "Column " + TableColumnInfo.this.getIdentifier()); + } + return this.fnDisplay; + } + + /** + * Lambda closure used to sort this column, and fn display. + * + * @param lambda0 the fnSort + * @param lambda1 the fnDisplay + */ + public void setSortAndDisplayFunctions(final Lambda1> lambda0, final Lambda1> lambda1) { + this.fnSort = lambda0; + this.fnDisplay = lambda1; + } +} diff --git a/src/main/java/forge/gui/deckeditor/tables/TableModel.java b/src/main/java/forge/gui/deckeditor/tables/TableModel.java new file mode 100644 index 00000000000..e9f171a9f10 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/tables/TableModel.java @@ -0,0 +1,373 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 +import forge.gui.deckeditor.views.VDeckEditorUI; +Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package forge.gui.deckeditor.tables; + +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Enumeration; +import java.util.List; +import java.util.Map.Entry; + +import javax.swing.JTable; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.event.TableModelEvent; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableColumn; +import javax.swing.table.TableColumnModel; + +import org.apache.commons.lang3.ArrayUtils; + +import forge.Card; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.SEditorIO; +import forge.gui.deckeditor.tables.SColumnUtil.ColumnName; +import forge.gui.deckeditor.tables.SColumnUtil.SortState; +import forge.item.CardPrinted; +import forge.item.InventoryItem; +import forge.item.ItemPool; +import forge.item.ItemPoolView; + +/** + *

+ * TableModel class. + *

+ * + * @param + * the generic type + * @author Forge + * @version $Id$ + */ +@SuppressWarnings("serial") +public final class TableModel extends AbstractTableModel { + private final ItemPool data; + private final JTable table; + private final CascadeManager cascadeManager = new CascadeManager(); + private final int maxSortDepth = 3; + + /** + * Instantiates a new table model, using a JTable, + * a column set, and a data set of generic type . + * + * @param table0   {@link javax.swing.JTable} + * @param class0   Generic type + */ + public TableModel(final JTable table0, final Class class0) { + this.table = table0; + this.data = new ItemPool(class0); + } + + /** */ + @SuppressWarnings("unchecked") + public void setup() { + final Enumeration e = table.getColumnModel().getColumns(); + final TableColumn[] sortcols = new TableColumn[table.getColumnCount()]; + + // Assemble priority sort. + while (e.hasMoreElements()) { + final TableColumnInfo col = (TableColumnInfo) e.nextElement(); + + if (col.getSortPriority() > 0) { + sortcols[col.getSortPriority()] = col; + } + } + + final boolean isDeckTable = ((TableColumnInfo) table.getColumnModel() + .getColumn(0)).getEnumValue().substring(0, 4).equals("DECK") + ? true : false; + + if (sortcols[1] == null) { + if (isDeckTable) { + cascadeManager.add((TableColumnInfo) SColumnUtil.getColumn(ColumnName.DECK_NAME)); + } + else { + cascadeManager.add((TableColumnInfo) SColumnUtil.getColumn(ColumnName.CAT_NAME)); + } + } + else { + ArrayUtils.reverse(sortcols); + for (int i = 1; i < sortcols.length; i++) { + if (sortcols[i] != null) { + cascadeManager.add((TableColumnInfo) sortcols[i]); + } + } + } + } + + /** + * Clears all data in the model. + */ + public void clear() { + this.data.clear(); + } + + /** + * Gets all cards in the model. + * + * @return the cards + */ + public ItemPoolView getCards() { + return this.data.getView(); + } + + /** + * Removes a card from the model. + * + * @param card0   {@link forge.Card} object + */ + public void removeCard(final T card0) { + final boolean wasThere = this.data.count(card0) > 0; + if (wasThere) { + this.data.remove(card0); + this.fireTableDataChanged(); + } + } + + /** + * Adds a card to the model. + * + * @param card0   {@link forge.Card} object. + */ + public void addCard(final T card0) { + this.data.add(card0); + this.fireTableDataChanged(); + } + + /** + * Adds multiple copies of multiple cards to the model. + * + * @param cards0   {@link java.lang.Iterable}> + */ + public void addCards(final Iterable> cards0) { + this.data.addAll(cards0); + this.fireTableDataChanged(); + } + + /** + * Row to card. + * + * @param row + * the row + * @return the entry + */ + public Entry rowToCard(final int row) { + final List> model = this.data.getOrderedList(); + return (row >= 0) && (row < model.size()) ? model.get(row) : null; + } + + /** + * Show selected card. + * + * @param table + * the table + */ + public void showSelectedCard(final JTable table) { + final int row = table.getSelectedRow(); + if (row != -1) { + final T cp = this.rowToCard(row).getKey(); + + final Card card2 = cp instanceof CardPrinted ? ((CardPrinted) cp).toForgeCard() : null; + + CDeckEditorUI.SINGLETON_INSTANCE.setCard(card2); + } + } + + /** + *

+ * addListeners. + *

+ */ + public void addListeners() { + // updates card detail, listens to any key strokes + table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + + @Override + public void valueChanged(final ListSelectionEvent arg0) { + TableModel.this.showSelectedCard(table); + } + }); + table.addFocusListener(new FocusListener() { + + @Override + public void focusLost(final FocusEvent e) { + } + + @Override + public void focusGained(final FocusEvent e) { + TableModel.this.showSelectedCard(table); + } + }); + + table.getTableHeader().addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(final MouseEvent e) { + headerClicked(e); + } + + @Override + public void mouseReleased(MouseEvent e) { + SEditorIO.savePreferences(); + } + }); + } // addCardListener() + + /** + * Resort. + */ + public void refreshSort() { + if (this.data.getOrderedList().size() == 0) { return; } + + Collections.sort(this.data.getOrderedList(), new MyComparator()); + } + + @SuppressWarnings("unchecked") + private void headerClicked(final MouseEvent e) { + final TableColumnModel colModel = TableModel.this.table.getColumnModel(); + final int columnModelIndex = colModel.getColumnIndexAtX(e.getX()); + final int modelIndex = colModel.getColumn(columnModelIndex).getModelIndex(); + + if (modelIndex < 0) { + return; + } + + // This will invert if needed + TableModel.this.cascadeManager.add((TableColumnInfo) this.table.getColumnModel().getColumn(modelIndex)); + TableModel.this.refreshSort(); + TableModel.this.table.tableChanged(new TableModelEvent(TableModel.this)); + TableModel.this.table.repaint(); + TableModel.this.table.setRowSelectionInterval(0, 0); + SEditorIO.savePreferences(); + } + + //========== Overridden from AbstractTableModel + /** {@inheritDoc} */ + @Override + public int findColumn(final String name0) { + return table.getColumnModel().getColumnIndex(name0); + } + + /* (non-Javadoc) + * @see javax.swing.table.TableModel#getColumnCount() + */ + @Override + public int getColumnCount() { + return table.getColumnCount(); + } + + /* (non-Javadoc) + * @see javax.swing.table.TableModel#getRowCount() + */ + @Override + public int getRowCount() { + return this.data.countDistinct(); + } + + /* (non-Javadoc) + * @see javax.swing.table.TableModel#getValueAt(int, int) + */ + @Override + @SuppressWarnings("unchecked") + public Object getValueAt(int iRow, int iCol) { + return ((TableColumnInfo) table.getColumnModel().getColumn(table.convertColumnIndexToView(iCol))).getFnDisplay().apply((Entry) this.rowToCard(iRow)); + } + + //========= Custom class handling + + /** + * Manages sorting orders for multiple depths of sorting. + */ + private final class CascadeManager { + private final List> colsToSort = new ArrayList>(3); + private TableSorterCascade sorter = null; + + // Adds a column to sort cascade list. + // If column is first in the cascade, inverts direction of sort. + // Otherwise, sorts in ascending direction. + @SuppressWarnings("unchecked") + public void add(final TableColumnInfo col0) { + // Found at top level, should invert + if (colsToSort.size() > 0 && colsToSort.get(0).equals(col0)) { + this.colsToSort.get(0).setSortState( + this.colsToSort.get(0).getSortState() == SortState.ASC + ? SortState.DESC : SortState.ASC); + this.colsToSort.get(0).setSortPriority(1); + } + // Found somewhere: move down others, this one to top. + else if (colsToSort.contains(col0)) { + col0.setSortState(SortState.ASC); + this.colsToSort.remove(col0); + this.colsToSort.add(0, (TableColumnInfo) col0); + } + // No column in list; add directly. + else { + col0.setSortState(SortState.ASC); + this.colsToSort.add(0, (TableColumnInfo) col0); + this.colsToSort.get(0).setSortPriority(1); + } + + // Decrement sort priority on remaining columns + for (int i = 1; i < maxSortDepth; i++) { + if (colsToSort.size() == i) { break; } + + if (colsToSort.get(i).getSortPriority() != 0) { + colsToSort.get(i).setSortPriority(i + 1); + } + } + + // Unset and remove boundary columns. + if (this.colsToSort.size() > maxSortDepth) { + this.colsToSort.get(maxSortDepth).setSortState(SortState.NONE); + this.colsToSort.get(maxSortDepth).setSortPriority(0); + this.colsToSort.remove(maxSortDepth); + } + } + + public TableSorterCascade getSorter() { + final List> oneColSorters + = new ArrayList>(maxSortDepth); + + for (final TableColumnInfo col : this.colsToSort) { + oneColSorters.add(new TableSorter( + col.getFnSort(), + col.getSortState().equals(SortState.ASC) ? true : false)); + } + + this.sorter = new TableSorterCascade(oneColSorters); + return this.sorter; + } + } + + private class MyComparator implements Comparator> { + /* (non-Javadoc) + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + */ + @SuppressWarnings("unchecked") + @Override + public int compare(Entry o1, Entry o2) { + return TableModel.this.cascadeManager.getSorter().compare( + (Entry) o1, (Entry) o2); + } + } +} // CardTableModel diff --git a/src/main/java/forge/gui/deckeditor/elements/TableSorter.java b/src/main/java/forge/gui/deckeditor/tables/TableSorter.java similarity index 98% rename from src/main/java/forge/gui/deckeditor/elements/TableSorter.java rename to src/main/java/forge/gui/deckeditor/tables/TableSorter.java index 9504a987fee..620ee1ddccf 100644 --- a/src/main/java/forge/gui/deckeditor/elements/TableSorter.java +++ b/src/main/java/forge/gui/deckeditor/tables/TableSorter.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package forge.gui.deckeditor.elements; +package forge.gui.deckeditor.tables; import java.util.Comparator; import java.util.Map.Entry; diff --git a/src/main/java/forge/gui/deckeditor/elements/TableSorterCascade.java b/src/main/java/forge/gui/deckeditor/tables/TableSorterCascade.java similarity index 95% rename from src/main/java/forge/gui/deckeditor/elements/TableSorterCascade.java rename to src/main/java/forge/gui/deckeditor/tables/TableSorterCascade.java index 9165df95145..83614cd00eb 100644 --- a/src/main/java/forge/gui/deckeditor/elements/TableSorterCascade.java +++ b/src/main/java/forge/gui/deckeditor/tables/TableSorterCascade.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package forge.gui.deckeditor.elements; +package forge.gui.deckeditor.tables; import java.util.Comparator; import java.util.List; diff --git a/src/main/java/forge/gui/deckeditor/elements/TableView.java b/src/main/java/forge/gui/deckeditor/tables/TableView.java similarity index 52% rename from src/main/java/forge/gui/deckeditor/elements/TableView.java rename to src/main/java/forge/gui/deckeditor/tables/TableView.java index bb588a1d2d5..32fbd4043cc 100644 --- a/src/main/java/forge/gui/deckeditor/elements/TableView.java +++ b/src/main/java/forge/gui/deckeditor/tables/TableView.java @@ -15,24 +15,23 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package forge.gui.deckeditor.elements; +package forge.gui.deckeditor.tables; import java.awt.Color; +import java.util.ArrayList; import java.util.List; -import javax.swing.BorderFactory; -import javax.swing.JComponent; -import javax.swing.JLabel; -import javax.swing.JScrollPane; import javax.swing.JTable; -import javax.swing.border.TitledBorder; import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelListener; -import javax.swing.table.TableCellRenderer; +import javax.swing.table.DefaultTableColumnModel; +import javax.swing.table.TableColumn; - -import forge.Constant; import forge.card.CardRules; +import forge.gui.deckeditor.SEditorUtil; +import forge.gui.deckeditor.views.ITableContainer; +import forge.gui.toolbox.FSkin; +import forge.item.CardPrinted; import forge.item.InventoryItem; import forge.item.ItemPool; import forge.item.ItemPoolView; @@ -45,44 +44,14 @@ import forge.util.closures.Predicate; * the generic type */ public final class TableView { - - /** The pool. */ private ItemPool pool; - - /** The model. */ private TableModel model; - - /** The table. */ private final JTable table = new JTable(); - - /** The j scroll pane. */ - private final JScrollPane jScrollPane = new JScrollPane(); - - /** The stats label. */ - private final JLabel statsLabel = new JLabel(); - - /** The filter. */ private Predicate filter = null; - - /** The is tracking stats. */ - private boolean isTrackingStats = false; - - /** The want unique. */ private boolean wantUnique = false; private final Class genericType; - // need this to allow users place its contents - /** - * - * getTableDecorated. - * - * @return JComponent - */ - public JComponent getTableDecorated() { - return this.jScrollPane; - } - /** * * getTable. @@ -93,149 +62,104 @@ public final class TableView { return this.table; } - /** - * - * getLabel. - * - * @return JComponent - */ - public JComponent getLabel() { - return this.statsLabel; - } - /** * TableWithCards. * - * @param title - * a String - * @param showStats - * a boolean * @param cls * the cls */ - public TableView(final String title, final boolean showStats, final Class cls) { - this(title, showStats, false, cls); + public TableView(final Class cls) { + this(false, cls); } /** * TableWithCards Constructor. * - * @param title - * a String - * @param showStats - * a boolean * @param forceUnique * a boolean - * @param cls - * the cls + * @param type0 the cls */ - public TableView(final String title, final boolean showStats, final boolean forceUnique, final Class cls) { - // components - this.genericType = cls; - - final Color gray = new Color(148, 145, 140); - final TitledBorder titledBorder = new TitledBorder(BorderFactory.createEtchedBorder(Color.white, gray), title); - - final String tableToolTip = "Click on the column name (like name or color) to sort the cards"; - this.jScrollPane.setBorder(titledBorder); - this.jScrollPane.setToolTipText(tableToolTip); - this.jScrollPane.getViewport().add(this.table, null); - - this.statsLabel.setFont(new java.awt.Font("Dialog", 0, 13)); - this.statsLabel.setText("Total: 0, Creatures: 0, Land: 0"); - - // class data - this.isTrackingStats = showStats; + public TableView(final boolean forceUnique, final Class type0) { + this.genericType = type0; this.wantUnique = forceUnique; + + table.setFont(FSkin.getFont(12)); + table.setBorder(null); + table.getTableHeader().setBorder(null); + table.setRowHeight(18); } /** + * Applies a TableModel and a model listener to this instance's JTable. * - * setup. - * - * @param columns - * a List> - * @param cardView - * a CardPanelBase + * @param view0   the {@link javax.gui.deckeditor.views.ITableCOntainer} + * @param cols0   List> of additional columns for this */ - public void setup(final List> columns, final CardPanelBase cardView) { - this.model = new TableModel(cardView, columns, this.genericType); - this.model.addListeners(this.table); - this.table.setModel(this.model); - this.model.resizeCols(this.table); + @SuppressWarnings("unchecked") + public void setup(final ITableContainer view0, final List> cols0) { + final DefaultTableColumnModel colmodel = new DefaultTableColumnModel(); - for (int idx = columns.size() - 1; idx >= 0; idx--) { - final TableCellRenderer renderer = columns.get(idx).getCellRenderer(); - if (null != renderer) { - this.table.getColumnModel().getColumn(idx).setCellRenderer(renderer); + // Add columns whose indices are inside the view indices, as long as there's not one there already. + final TableColumn[] knownCols = new TableColumn[cols0.size()]; + final List unknownCols = new ArrayList(); + + for (final TableColumn c : cols0) { + if (!((TableColumnInfo) c).isShowing()) { continue; } + if (c.getModelIndex() < knownCols.length && knownCols[c.getModelIndex()] == null) { + knownCols[c.getModelIndex()] = c; + } + else { + unknownCols.add(c); } } - if (this.isTrackingStats) { - // get stats from deck - this.model.addTableModelListener(new TableModelListener() { - @Override - public void tableChanged(final TableModelEvent ev) { - final ItemPoolView deck = TableView.this.model.getCards(); - TableView.this.statsLabel.setText(TableView.getStats(deck)); + // Columns outside the bounds of the view indices must be + // resolved by inserting into empty slots. + for (final TableColumn c : unknownCols) { + for (int i = 0; i < knownCols.length; i++) { + if (knownCols[i] == null) { + knownCols[i] = c; + break; } - }); - } - } - - // This should not be here, but still found no better place - /** - * getStats. - * - * @param - * the generic type - * @param deck - * an ItemPoolView - * @return String - */ - public static String getStats(final ItemPoolView deck) { - final int total = deck.countAll(); - final int creature = CardRules.Predicates.Presets.IS_CREATURE.aggregate(deck, deck.getFnToCard(), - deck.getFnToCount()); - final int land = CardRules.Predicates.Presets.IS_LAND.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); - - final StringBuffer show = new StringBuffer(); - show.append("Total - ").append(total).append(", Creatures - ").append(creature).append(", Land - ") - .append(land); - final String[] color = Constant.Color.ONLY_COLORS; - final List> predicates = CardRules.Predicates.Presets.COLORS; - for (int i = 0; i < color.length; ++i) { - show.append(String.format(", %s - %d", color[i], predicates.get(i).count(deck, deck.getFnToCard()))); + } } - return show.toString(); - } // getStats() + // Put columns into model in preferred order (much easier than moving dynamically). + for (final TableColumn c : knownCols) { + if (c == null) { continue; } + c.setMinWidth(15); + c.setPreferredWidth(c.getPreferredWidth()); + c.setMaxWidth(350); + colmodel.addColumn(c); + } - /** - * - * sort. - * - * @param iCol - * an int - * @return TableWithCards - */ - public TableView sort(final int iCol) { - return this.sort(iCol, true); - } + this.model = new TableModel(this.table, this.genericType); + this.model.addListeners(); + this.table.setModel(this.model); + this.table.setColumnModel(colmodel); - /** - * - * sort. - * - * @param iCol - * an int - * @param isAsc - * a boolean - * @return TableWithCards - */ - public TableView sort(final int iCol, final boolean isAsc) { - this.model.sort(iCol, isAsc); - return this; + this.model.setup(); + this.model.refreshSort(); + + this.table.getTableHeader().setBackground(new Color(200, 200, 200)); + + // Update stats each time table changes + this.model.addTableModelListener(new TableModelListener() { + @Override + public void tableChanged(final TableModelEvent ev) { + final List deck = TableView.this.model.getCards().toFlatList(); + final ItemPool filteredDeck = new ItemPool((Class) CardPrinted.class); + + // Filter out non-card items (booster packs, etc.) + for (T item : deck) { + if (item instanceof CardPrinted) { + filteredDeck.add(item); + } + } + + SEditorUtil.setStats(filteredDeck, view0); + } + }); } /** @@ -388,7 +312,7 @@ public final class TableView { this.model.addCards(this.pool); } - this.model.resort(); + this.model.refreshSort(); } /** diff --git a/src/main/java/forge/gui/deckeditor/tables/package-info.java b/src/main/java/forge/gui/deckeditor/tables/package-info.java new file mode 100644 index 00000000000..5eccba35a34 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/tables/package-info.java @@ -0,0 +1,3 @@ +/** Forge Card Game. */ +package forge.gui.deckeditor.tables; + diff --git a/src/main/java/forge/gui/deckeditor/views/ITableContainer.java b/src/main/java/forge/gui/deckeditor/views/ITableContainer.java new file mode 100644 index 00000000000..f96d1ba5923 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/views/ITableContainer.java @@ -0,0 +1,65 @@ +package forge.gui.deckeditor.views; + +import javax.swing.JLabel; +import javax.swing.JTable; + +/** + * Dictates methods needed for a class to act as a container for + * a TableView deck editing component. + * + *

(I at beginning of class name denotes an interface.) + * + */ +public interface ITableContainer { + /** + * Sets the table used for displaying cards in this + * deck editor container. + * + * @param tbl0   {@link forge.gui.deckeditor.tables.TableView} + */ + void setTableView(JTable tbl0); + + // Various card count total labels + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblTotal(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblBlack(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblBlue(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblGreen(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblRed(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblWhite(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblColorless(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblArtifact(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblEnchantment(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblCreature(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblSorcery(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblInstant(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblPlaneswalker(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblLand(); +} diff --git a/src/main/java/forge/gui/deckeditor/views/VAllDecks.java b/src/main/java/forge/gui/deckeditor/views/VAllDecks.java new file mode 100644 index 00000000000..850eda35a9d --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/views/VAllDecks.java @@ -0,0 +1,110 @@ +package forge.gui.deckeditor.views; + +import javax.swing.JLabel; +import javax.swing.JScrollPane; + +import net.miginfocom.swing.MigLayout; +import forge.game.GameType; +import forge.gui.deckeditor.controllers.CAllDecks; +import forge.gui.framework.DragCell; +import forge.gui.framework.DragTab; +import forge.gui.framework.EDocID; +import forge.gui.framework.ICDoc; +import forge.gui.framework.IVDoc; +import forge.gui.toolbox.DeckLister; +import forge.gui.toolbox.FLabel; + +/** + * Assembles Swing components of all deck viewer in deck editor. + * + *

(V at beginning of class name denotes a view class.) + */ +public enum VAllDecks implements IVDoc { + /** */ + SINGLETON_INSTANCE; + + // Fields used with interface IVDoc + private DragCell parentCell; + private final DragTab tab = new DragTab("All Decks"); + + private final DeckLister lstDecks = new DeckLister(GameType.Constructed); + private JScrollPane scroller = new JScrollPane(lstDecks); + + private final JLabel btnImport = new FLabel.Builder() + .fontScaleAuto(false).fontSize(14) + .text("Import Deck").tooltip("Attempt to import a deck from a non-Forge format") + .opaque(true).hoverable(true).build(); + + //========== Constructor + private VAllDecks() { + scroller.setOpaque(false); + scroller.getViewport().setOpaque(false); + scroller.setBorder(null); + scroller.getViewport().setBorder(null); + } + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getDocumentID() + */ + @Override + public EDocID getDocumentID() { + return EDocID.EDITOR_ALLDECKS; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getTabLabel() + */ + @Override + public DragTab getTabLabel() { + return tab; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getControl() + */ + @Override + public ICDoc getControl() { + return CAllDecks.SINGLETON_INSTANCE; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#setParentCell(forge.gui.framework.DragCell) + */ + @Override + public void setParentCell(DragCell cell0) { + this.parentCell = cell0; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getParentCell() + */ + @Override + public DragCell getParentCell() { + return this.parentCell; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#populate() + */ + @Override + public void populate() { + parentCell.getBody().setLayout(new MigLayout("insets 0, gap 0, wrap, ax center")); + + parentCell.getBody().add(btnImport, "w 120px!, h 30px!, gap 0 0 5px 5px"); + + //parentCell.getBody().add(scroller, "w 96%!, h 96%!, gap 2% 0 2% 0"); + } + + //========== Retrieval methods + /** @return {@link javax.swing.JPanel} */ + public DeckLister getLstDecks() { + return lstDecks; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnImport() { + return btnImport; + } +} diff --git a/src/main/java/forge/gui/deckeditor/views/VCardCatalog.java b/src/main/java/forge/gui/deckeditor/views/VCardCatalog.java new file mode 100644 index 00000000000..d02ea373e65 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/views/VCardCatalog.java @@ -0,0 +1,315 @@ +package forge.gui.deckeditor.views; + +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; + +import net.miginfocom.swing.MigLayout; +import forge.gui.deckeditor.SEditorUtil; +import forge.gui.deckeditor.controllers.CCardCatalog; +import forge.gui.framework.DragCell; +import forge.gui.framework.DragTab; +import forge.gui.framework.EDocID; +import forge.gui.framework.ICDoc; +import forge.gui.framework.IVDoc; +import forge.gui.toolbox.FLabel; +import forge.gui.toolbox.FSkin; + +/** + * Assembles Swing components of card catalog in deck editor. + * + *

(V at beginning of class name denotes a view class.) + * + */ +public enum VCardCatalog implements IVDoc, ITableContainer { + /** */ + SINGLETON_INSTANCE; + + // Fields used with interface IVDoc + private DragCell parentCell; + private final DragTab tab = new DragTab("Card Catalog"); + + // Total and color count labels + private final JPanel pnlStats = new JPanel(); + private final JLabel lblTotal = buildLabel(SEditorUtil.ICO_TOTAL); + private final JLabel lblBlack = buildLabel(SEditorUtil.ICO_BLACK); + private final JLabel lblBlue = buildLabel(SEditorUtil.ICO_BLUE); + private final JLabel lblGreen = buildLabel(SEditorUtil.ICO_GREEN); + private final JLabel lblRed = buildLabel(SEditorUtil.ICO_RED); + private final JLabel lblWhite = buildLabel(SEditorUtil.ICO_WHITE); + private final JLabel lblColorless = buildLabel(SEditorUtil.ICO_COLORLESS); + + // Card type labels + private final JLabel lblArtifact = buildLabel(SEditorUtil.ICO_ARTIFACT); + private final JLabel lblCreature = buildLabel(SEditorUtil.ICO_CREATURE); + private final JLabel lblEnchantment = buildLabel(SEditorUtil.ICO_ENCHANTMENT); + private final JLabel lblInstant = buildLabel(SEditorUtil.ICO_INSTANT); + private final JLabel lblLand = buildLabel(SEditorUtil.ICO_LAND); + private final JLabel lblPlaneswalker = buildLabel(SEditorUtil.ICO_PLANESWALKER); + private final JLabel lblSorcery = buildLabel(SEditorUtil.ICO_SORCERY); + + private final JLabel lblTitle = new FLabel.Builder() + .fontScaleAuto(false).fontSize(14).build(); + + private final JPanel pnlHeader = new JPanel(new MigLayout("insets 0, gap 0")); + + private final JPanel pnlAddButtons = + new JPanel(new MigLayout("insets 0, gap 0, ax center, hidemode 3")); + + private final JLabel btnAdd = new FLabel.Builder() + .fontScaleAuto(false).fontSize(14) + .text("Add card") + .tooltip("Add selected card to current deck (or double click the row)") + .icon(FSkin.getIcon(FSkin.ForgeIcons.ICO_PLUS)) + .iconScaleAuto(false).hoverable(true).build(); + + private final JLabel btnAdd4 = new FLabel.Builder() + .fontScaleAuto(false).fontSize(14) + .text("Add 4 of card") + .tooltip("Add up to 4 of selected card to current deck") + .icon(FSkin.getIcon(FSkin.ForgeIcons.ICO_PLUS)) + .iconScaleAuto(false).hoverable(true).build(); + + private JTable tblCards = null; + private final JScrollPane scroller = new JScrollPane(); + + //========== Constructor + /** */ + private VCardCatalog() { + scroller.setOpaque(false); + scroller.getViewport().setOpaque(false); + scroller.setBorder(null); + scroller.getViewport().setBorder(null); + + lblTotal.setToolTipText("Total Card Count"); + lblBlack.setToolTipText("Black Card Count"); + lblBlue.setToolTipText("Blue Card Count"); + lblGreen.setToolTipText("Green Card Count"); + lblRed.setToolTipText("Red Card Count"); + lblWhite.setToolTipText("White Card Count"); + lblColorless.setToolTipText("Total Card Count"); + lblArtifact.setToolTipText("Artiface Card Count"); + lblCreature.setToolTipText("Creature Card Count"); + lblColorless.setToolTipText("Colorless Card Count"); + lblEnchantment.setToolTipText("Enchantment Card Count"); + lblInstant.setToolTipText("Instant Card Count"); + lblLand.setToolTipText("Land Card Count"); + lblPlaneswalker.setToolTipText("Planeswalker Card Count"); + lblSorcery.setToolTipText("Sorcery Card Count"); + + pnlStats.setOpaque(false); + pnlStats.setLayout(new MigLayout("insets 0, gap 5px, ax center, wrap 7")); + + final String constraints = "w 55px!, h 20px!"; + pnlStats.add(lblTotal, constraints); + pnlStats.add(lblBlack, constraints); + pnlStats.add(lblBlue, constraints); + pnlStats.add(lblGreen, constraints); + pnlStats.add(lblRed, constraints); + pnlStats.add(lblWhite, constraints); + pnlStats.add(lblColorless, constraints); + + pnlStats.add(lblArtifact, constraints); + pnlStats.add(lblCreature, constraints); + pnlStats.add(lblEnchantment, constraints); + pnlStats.add(lblInstant, constraints); + pnlStats.add(lblLand, constraints); + pnlStats.add(lblPlaneswalker, constraints); + pnlStats.add(lblSorcery, constraints); + + pnlAddButtons.setOpaque(false); + pnlAddButtons.add(btnAdd, "w 42%!, h 30px!, gap 0 0 5px 5px"); + pnlAddButtons.add(btnAdd4, "w 42%!, h 30px!, gap 5% 5% 5px 5px"); + + pnlHeader.setOpaque(false); + pnlHeader.add(lblTitle, "w 100%!, h 100%!"); + } + + //========== Overridden from IVDoc + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getDocumentID() + */ + @Override + public EDocID getDocumentID() { + return EDocID.EDITOR_CATALOG; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getTabLabel() + */ + @Override + public DragTab getTabLabel() { + return tab; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getControl() + */ + @Override + public ICDoc getControl() { + return CCardCatalog.SINGLETON_INSTANCE; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#setParentCell(forge.gui.framework.DragCell) + */ + @Override + public void setParentCell(DragCell cell0) { + this.parentCell = cell0; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getParentCell() + */ + @Override + public DragCell getParentCell() { + return this.parentCell; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#populate() + */ + @Override + public void populate() { + parentCell.getBody().setLayout(new MigLayout("insets 0, gap 0, wrap, hidemode 3")); + parentCell.getBody().add(pnlHeader, "w 98%!, h 30px!, gap 1% 0 1% 10px"); + parentCell.getBody().add(pnlStats, "w 96%, h 50px!, gap 2% 0 1% 1%"); + parentCell.getBody().add(pnlAddButtons, "w 96%!, gap 2% 0 0 0"); + parentCell.getBody().add(scroller, "w 98%!, h 100% - 35px, gap 1% 0 1% 1%"); + } + + //========== Overridden from ITableContainer + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#setTableView() + */ + @Override + public void setTableView(final JTable tbl0) { + this.tblCards = tbl0; + scroller.setViewportView(tblCards); + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblTotal() + */ + @Override + public JLabel getLblTotal() { return lblTotal; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblBlack() + */ + @Override + public JLabel getLblBlack() { return lblBlack; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblBlue() + */ + @Override + public JLabel getLblBlue() { return lblBlue; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblGreen() + */ + @Override + public JLabel getLblGreen() { return lblGreen; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblRed() + */ + @Override + public JLabel getLblRed() { return lblRed; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblWhite() + */ + @Override + public JLabel getLblWhite() { return lblWhite; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblColorless() + */ + @Override + public JLabel getLblColorless() { return lblColorless; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblArtifact() + */ + @Override + public JLabel getLblArtifact() { return lblArtifact; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblEnchantment() + */ + @Override + public JLabel getLblEnchantment() { return lblEnchantment; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblCreature() + */ + @Override + public JLabel getLblCreature() { return lblCreature; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblSorcery() + */ + @Override + public JLabel getLblSorcery() { return lblSorcery; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblInstant() + */ + @Override + public JLabel getLblInstant() { return lblInstant; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblPlaneswalker() + */ + @Override + public JLabel getLblPlaneswalker() { return lblPlaneswalker; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblLand() + */ + @Override + public JLabel getLblLand() { return lblLand; } + + //========== Accessor/mutator methods + + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblTitle() { + return lblTitle; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnAdd() { + return btnAdd; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnAdd4() { + return btnAdd4; + } + + /** @return {@link javax.swing.JPanel} */ + public JPanel getPnlHeader() { + return pnlHeader; + } + + /** @return {@link javax.swing.JPanel} */ + public JPanel getPnlStats() { + return pnlStats; + } + + //========== Other methods + + private JLabel buildLabel(final ImageIcon icon0) { + final JLabel lbl = new FLabel.Builder().text("0") + .icon(icon0).iconScaleAuto(false) + .fontSize(11).fontScaleAuto(false) + .build(); + + return lbl; + } +} diff --git a/src/main/java/forge/gui/deckeditor/views/VCurrentDeck.java b/src/main/java/forge/gui/deckeditor/views/VCurrentDeck.java new file mode 100644 index 00000000000..039efe3d44e --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/views/VCurrentDeck.java @@ -0,0 +1,406 @@ +package forge.gui.deckeditor.views; + +import java.awt.Insets; + +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.SwingConstants; + +import net.miginfocom.swing.MigLayout; +import forge.gui.deckeditor.SEditorUtil; +import forge.gui.deckeditor.controllers.CCurrentDeck; +import forge.gui.framework.DragCell; +import forge.gui.framework.DragTab; +import forge.gui.framework.EDocID; +import forge.gui.framework.ICDoc; +import forge.gui.framework.IVDoc; +import forge.gui.toolbox.FLabel; +import forge.gui.toolbox.FSkin; +import forge.gui.toolbox.FTextField; + + +/** + * Assembles Swing components of current deck being edited in deck editor. + * + *

(V at beginning of class name denotes a view class.) + */ +public enum VCurrentDeck implements IVDoc, ITableContainer { + /** */ + SINGLETON_INSTANCE; + + // Fields used with interface IVDoc + private DragCell parentCell; + private final DragTab tab = new DragTab("Current Deck"); + + // Other fields + + private final JLabel btnSave = new FLabel.Builder() + .fontScaleAuto(false).fontSize(14) + .tooltip("Save (in default directory)") + .iconInBackground(true) + .iconAlignX(SwingConstants.CENTER).iconAlpha(1.0f) + .icon(FSkin.getIcon(FSkin.ForgeIcons.ICO_SAVE)) + .text(" ").hoverable(true).build(); + + private final JLabel btnExport = new FLabel.Builder() + .fontScaleAuto(false).fontSize(14) + .tooltip("Export...") + .iconInBackground(true) + .iconAlignX(SwingConstants.CENTER).iconAlpha(1.0f) + .icon(FSkin.getIcon(FSkin.ForgeIcons.ICO_SAVEAS)) + .text(" ").hoverable(true).build(); + + private final JLabel btnImport = new FLabel.Builder() + .fontScaleAuto(false).fontSize(14) + .tooltip("Import...") + .iconInBackground(true) + .iconAlignX(SwingConstants.CENTER).iconAlpha(1.0f) + .icon(FSkin.getIcon(FSkin.ForgeIcons.ICO_OPEN)) + .text(" ").hoverable(true).build(); + + private final JLabel btnNew = new FLabel.Builder() + .fontScaleAuto(false).fontSize(14) + .tooltip("New Deck") + .iconInBackground(true) + .iconAlignX(SwingConstants.CENTER).iconAlpha(1.0f) + .icon(FSkin.getIcon(FSkin.ForgeIcons.ICO_NEW)) + .text(" ").hoverable(true).build(); + + private final JPanel pnlRemoveButtons = + new JPanel(new MigLayout("insets 0, gap 0, ax center, hidemode 3")); + + private final JLabel btnRemove = new FLabel.Builder() + .fontScaleAuto(false).fontSize(14) + .text("Remove card") + .tooltip("Remove selected card to current deck (or double click the row)") + .icon(FSkin.getIcon(FSkin.ForgeIcons.ICO_MINUS)) + .iconScaleAuto(false).hoverable(true).build(); + + private final JLabel btnRemove4 = new FLabel.Builder() + .fontScaleAuto(false).fontSize(14) + .text("Remove 4 of card") + .tooltip("Remove up to 4 of selected card to current deck") + .icon(FSkin.getIcon(FSkin.ForgeIcons.ICO_MINUS)) + .iconScaleAuto(false).hoverable(true).build(); + + private final JTextField txfTitle = new FTextField(); + + private final JPanel pnlRemove = new JPanel(); + private final JPanel pnlHeader = new JPanel(); + + private final JLabel lblTitle = new FLabel.Builder().text("Title") + .fontScaleAuto(false).fontSize(14).build(); + + private final JPanel pnlStats = new JPanel(); + private final JLabel lblTotal = buildLabel(SEditorUtil.ICO_TOTAL); + private final JLabel lblBlack = buildLabel(SEditorUtil.ICO_BLACK); + private final JLabel lblBlue = buildLabel(SEditorUtil.ICO_BLUE); + private final JLabel lblGreen = buildLabel(SEditorUtil.ICO_GREEN); + private final JLabel lblRed = buildLabel(SEditorUtil.ICO_RED); + private final JLabel lblWhite = buildLabel(SEditorUtil.ICO_WHITE); + private final JLabel lblColorless = buildLabel(SEditorUtil.ICO_COLORLESS); + + private final JLabel lblArtifact = buildLabel(SEditorUtil.ICO_ARTIFACT); + private final JLabel lblCreature = buildLabel(SEditorUtil.ICO_CREATURE); + private final JLabel lblEnchantment = buildLabel(SEditorUtil.ICO_ENCHANTMENT); + private final JLabel lblInstant = buildLabel(SEditorUtil.ICO_INSTANT); + private final JLabel lblLand = buildLabel(SEditorUtil.ICO_LAND); + private final JLabel lblPlaneswalker = buildLabel(SEditorUtil.ICO_PLANESWALKER); + private final JLabel lblSorcery = buildLabel(SEditorUtil.ICO_SORCERY); + + private JTable tblCards = null; + private final JScrollPane scroller = new JScrollPane(tblCards); + + //========== Constructor + + private VCurrentDeck() { + // Title text area + txfTitle.setText("[New Deck]"); + txfTitle.setMargin(new Insets(5, 5, 5, 5)); + txfTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + txfTitle.setOpaque(true); + txfTitle.setEditable(true); + txfTitle.setFocusable(true); + txfTitle.setOpaque(true); + txfTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + + // Header area + pnlHeader.setOpaque(false); + pnlHeader.setLayout(new MigLayout("insets 0, gap 0, ax center, hidemode 3")); + + pnlHeader.add(lblTitle, "w 80px!, h 30px!, gap 5px 5px 0 0"); + pnlHeader.add(txfTitle, "pushx, growx, gap 0 5px 0 0"); + pnlHeader.add(btnSave, "w 26px!, h 26px!, gap 0 5px 0 0"); + pnlHeader.add(btnNew, "w 26px!, h 26px!, gap 0 5px 0 0"); + + pnlHeader.add(btnImport, "w 26px!, h 26px!, gap 0 5px 0 0"); + pnlHeader.add(btnExport, "w 26px!, h 26px!, gap 0 20px 0 0"); + + pnlRemove.setOpaque(false); + pnlRemove.setLayout(new MigLayout("insets 0, gap 0, ax center")); + pnlRemove.add(btnRemove, "w 40%!, h 100%!, gap 5% 5% 0 0"); + pnlRemove.add(btnRemove4, "w 40%!, h 100%!"); + + scroller.setOpaque(false); + scroller.getViewport().setOpaque(false); + scroller.setBorder(null); + scroller.getViewport().setBorder(null); + + lblTotal.setToolTipText("Total Card Count"); + lblBlack.setToolTipText("Black Card Count"); + lblBlue.setToolTipText("Blue Card Count"); + lblGreen.setToolTipText("Green Card Count"); + lblRed.setToolTipText("Red Card Count"); + lblWhite.setToolTipText("White Card Count"); + lblColorless.setToolTipText("Total Card Count"); + lblArtifact.setToolTipText("Artiface Card Count"); + lblCreature.setToolTipText("Creature Card Count"); + lblColorless.setToolTipText("Colorless Card Count"); + lblEnchantment.setToolTipText("Enchantment Card Count"); + lblInstant.setToolTipText("Instant Card Count"); + lblLand.setToolTipText("Land Card Count"); + lblPlaneswalker.setToolTipText("Planeswalker Card Count"); + lblSorcery.setToolTipText("Sorcery Card Count"); + + pnlStats.setOpaque(false); + pnlStats.setLayout(new MigLayout("insets 0, gap 5px, ax center, wrap 7")); + + final String constraints = "w 55px!, h 20px!"; + pnlStats.add(lblTotal, constraints); + pnlStats.add(lblBlack, constraints); + pnlStats.add(lblBlue, constraints); + pnlStats.add(lblGreen, constraints); + pnlStats.add(lblRed, constraints); + pnlStats.add(lblWhite, constraints); + pnlStats.add(lblColorless, constraints); + + pnlStats.add(lblArtifact, constraints); + pnlStats.add(lblCreature, constraints); + pnlStats.add(lblEnchantment, constraints); + pnlStats.add(lblInstant, constraints); + pnlStats.add(lblLand, constraints); + pnlStats.add(lblPlaneswalker, constraints); + pnlStats.add(lblSorcery, constraints); + + pnlRemoveButtons.setOpaque(false); + pnlRemoveButtons.add(btnRemove, "w 42%!, h 30px!, gap 0 0 5px 5px"); + pnlRemoveButtons.add(btnRemove4, "w 42%!, h 30px!, gap 5% 5% 5px 5px"); + } + + //========== Overridden from IVDoc + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getDocumentID() + */ + @Override + public EDocID getDocumentID() { + return EDocID.EDITOR_CURRENTDECK; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getTabLabel() + */ + @Override + public DragTab getTabLabel() { + return tab; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getControl() + */ + @Override + public ICDoc getControl() { + return CCurrentDeck.SINGLETON_INSTANCE; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#setParentCell(forge.gui.framework.DragCell) + */ + @Override + public void setParentCell(final DragCell cell0) { + this.parentCell = cell0; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getParentCell() + */ + @Override + public DragCell getParentCell() { + return this.parentCell; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#populate() + */ + @Override + public void populate() { + final JPanel pnl = parentCell.getBody(); + pnl.setLayout(new MigLayout("insets 0, gap 0, wrap, hidemode 3")); + + parentCell.getBody().add(pnlHeader, "w 98%!, h 30px!, gap 1% 0 1% 10px"); + parentCell.getBody().add(pnlStats, "w 96%, h 50px!, gap 2% 0 1% 1%"); + parentCell.getBody().add(pnlRemoveButtons, "w 96%!, gap 2% 0 0 0"); + parentCell.getBody().add(scroller, "w 98%!, h 100% - 35px, gap 1% 0 1% 1%"); + } + + //========== Retrieval methods + + //========== Custom class handling + + //========== Overridden from ITableContainer + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#setTableView() + */ + @Override + public void setTableView(final JTable tbl0) { + this.tblCards = tbl0; + scroller.setViewportView(tblCards); + } + + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblTotal() + */ + @Override + public JLabel getLblTotal() { return lblTotal; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblBlack() + */ + @Override + public JLabel getLblBlack() { return lblBlack; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblBlue() + */ + @Override + public JLabel getLblBlue() { return lblBlue; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblGreen() + */ + @Override + public JLabel getLblGreen() { return lblGreen; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblRed() + */ + @Override + public JLabel getLblRed() { return lblRed; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblWhite() + */ + @Override + public JLabel getLblWhite() { return lblWhite; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblColorless() + */ + @Override + public JLabel getLblColorless() { return lblColorless; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblArtifact() + */ + @Override + public JLabel getLblArtifact() { return lblArtifact; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblEnchantment() + */ + @Override + public JLabel getLblEnchantment() { return lblEnchantment; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblCreature() + */ + @Override + public JLabel getLblCreature() { return lblCreature; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblSorcery() + */ + @Override + public JLabel getLblSorcery() { return lblSorcery; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblInstant() + */ + @Override + public JLabel getLblInstant() { return lblInstant; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblPlaneswalker() + */ + @Override + public JLabel getLblPlaneswalker() { return lblPlaneswalker; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblLand() + */ + @Override + public JLabel getLblLand() { return lblLand; } + + //========== Retrieval + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnRemove() { + return btnRemove; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnRemove4() { + return btnRemove4; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnSave() { + return btnSave; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnSaveAs() { + return btnExport; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnOpen() { + return btnImport; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnNew() { + return btnNew; + } + + /** @return {@link javax.swing.JTextField} */ + public JTextField getTxfTitle() { + return txfTitle; + } + + /** @return {@link javax.swing.JPanel} */ + public JPanel getPnlHeader() { + return pnlHeader; + } + + /** @return {@link javax.swing.JPanel} */ + public JPanel getPnlStats() { + return pnlStats; + } + + //========== Other methods + + private JLabel buildLabel(final ImageIcon icon0) { + final JLabel lbl = new FLabel.Builder().text("0") + .icon(icon0).iconScaleAuto(false) + .fontSize(11).fontScaleAuto(false) + .build(); + + return lbl; + } +} diff --git a/src/main/java/forge/gui/deckeditor/views/VDeckgen.java b/src/main/java/forge/gui/deckeditor/views/VDeckgen.java new file mode 100644 index 00000000000..1be730d1dc1 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/views/VDeckgen.java @@ -0,0 +1,128 @@ +package forge.gui.deckeditor.views; + +import javax.swing.JLabel; + +import net.miginfocom.swing.MigLayout; +import forge.gui.deckeditor.controllers.CDeckgen; +import forge.gui.framework.DragCell; +import forge.gui.framework.DragTab; +import forge.gui.framework.EDocID; +import forge.gui.framework.ICDoc; +import forge.gui.framework.IVDoc; +import forge.gui.toolbox.FLabel; + +/** + * Assembles Swing components of deck editor analysis tab. + * + *

(V at beginning of class name denotes a view class.) + */ +public enum VDeckgen implements IVDoc { + /** */ + SINGLETON_INSTANCE; + + // Fields used with interface IVDoc + private DragCell parentCell; + private final DragTab tab = new DragTab("Deck Generation"); + + // Deckgen buttons + private final JLabel btnRandCardpool = new FLabel.Builder() + .tooltip("Generate random constructed cardpool in current deck area") + .text("Random Cardpool").fontScaleAuto(false).fontSize(14) + .opaque(true).hoverable(true).build(); + + private final JLabel btnRandDeck2 = new FLabel.Builder() + .tooltip("Generate 2 color constructed deck in current deck area") + .text("Constructed (2 color)").fontScaleAuto(false).fontSize(14) + .opaque(true).hoverable(true).build(); + + private final JLabel btnRandDeck3 = new FLabel.Builder() + .tooltip("Generate 3 color constructed deck in current deck area") + .text("Constructed (3 color)").fontScaleAuto(false).fontSize(14) + .opaque(true).hoverable(true).build(); + + private final JLabel btnRandDeck5 = new FLabel.Builder() + .tooltip("Generate 5 color constructed deck in current deck area") + .text("Constructed (5 color)").fontScaleAuto(false).fontSize(14) + .opaque(true).hoverable(true).build(); + + //========== Constructor + private VDeckgen() { + } + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getDocumentID() + */ + @Override + public EDocID getDocumentID() { + return EDocID.EDITOR_DECKGEN; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getTabLabel() + */ + @Override + public DragTab getTabLabel() { + return tab; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getControl() + */ + @Override + public ICDoc getControl() { + return CDeckgen.SINGLETON_INSTANCE; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#setParentCell(forge.gui.framework.DragCell) + */ + @Override + public void setParentCell(final DragCell cell0) { + this.parentCell = cell0; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getParentCell() + */ + @Override + public DragCell getParentCell() { + return this.parentCell; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#populate() + */ + @Override + public void populate() { + parentCell.getBody().setLayout(new MigLayout("insets 0, gap 0, wrap, ax center")); + + final String constraints = "w 80%!, h 30px!, gap 0 0 10px 0"; + parentCell.getBody().add(btnRandCardpool, constraints); + parentCell.getBody().add(btnRandDeck2, constraints); + parentCell.getBody().add(btnRandDeck3, constraints); + parentCell.getBody().add(btnRandDeck5, constraints); + } + + //========== Retrieval methods + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnRandCardpool() { + return btnRandCardpool; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnRandDeck2() { + return btnRandDeck2; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnRandDeck3() { + return btnRandDeck3; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnRandDeck5() { + return btnRandDeck5; + } +} diff --git a/src/main/java/forge/gui/deckeditor/views/VEditorPreferences.java b/src/main/java/forge/gui/deckeditor/views/VEditorPreferences.java new file mode 100644 index 00000000000..4d60ee515b5 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/views/VEditorPreferences.java @@ -0,0 +1,225 @@ +package forge.gui.deckeditor.views; + +import javax.swing.JCheckBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.border.MatteBorder; + +import net.miginfocom.swing.MigLayout; +import forge.gui.deckeditor.controllers.CEditorPreferences; +import forge.gui.framework.DragCell; +import forge.gui.framework.DragTab; +import forge.gui.framework.EDocID; +import forge.gui.framework.ICDoc; +import forge.gui.framework.IVDoc; +import forge.gui.toolbox.FCheckBox; +import forge.gui.toolbox.FLabel; +import forge.gui.toolbox.FSkin; + +/** + * Assembles Swing components of deck editor analysis tab. + * + *

(V at beginning of class name denotes a view class.) + */ +public enum VEditorPreferences implements IVDoc { + /** */ + SINGLETON_INSTANCE; + + // Fields used with interface IVDoc + private DragCell parentCell; + private final DragTab tab = new DragTab("Preferences"); + + private JLabel lblStats = new FLabel.Builder() + .text("Stat Bars").tooltip("Toggle statistics bars") + .fontScaleAuto(false).fontSize(12).build(); + + private JLabel lblCatalog = new FLabel.Builder() + .text("Card Catalog Columns").tooltip("Toggle columns in card catalog panel") + .fontScaleAuto(false).fontSize(12).build(); + + private JLabel lblDeck = new FLabel.Builder() + .text("Current Deck Columns").tooltip("Toggle columns in current deck panel") + .fontScaleAuto(false).fontSize(12).build(); + + private JCheckBox chbCatalogColor = new FCheckBox("Color"); + private JCheckBox chbCatalogRarity = new FCheckBox("Rarity"); + private JCheckBox chbCatalogCMC = new FCheckBox("CMC"); + private JCheckBox chbCatalogSet = new FCheckBox("Set"); + private JCheckBox chbCatalogAI = new FCheckBox("AI"); + + private JCheckBox chbDeckColor = new FCheckBox("Color"); + private JCheckBox chbDeckRarity = new FCheckBox("Rarity"); + private JCheckBox chbDeckCMC = new FCheckBox("CMC"); + private JCheckBox chbDeckSet = new FCheckBox("Set"); + private JCheckBox chbDeckAI = new FCheckBox("AI"); + + private JCheckBox chbDeckStats = new FCheckBox("Show stats in current deck"); + private JCheckBox chbCatalogStats = new FCheckBox("Show stats in card catalog"); + + private JPanel pnl = new JPanel(new MigLayout("insets 0, gap 0, wrap 2, ax center")); + private JScrollPane scroller = new JScrollPane(pnl); + + //========== Constructor + private VEditorPreferences() { + lblStats.setBorder(new MatteBorder(0, 0, 1, 0, FSkin.getColor(FSkin.Colors.CLR_BORDERS))); + lblCatalog.setBorder(new MatteBorder(0, 0, 1, 0, FSkin.getColor(FSkin.Colors.CLR_BORDERS))); + lblDeck.setBorder(new MatteBorder(0, 0, 1, 0, FSkin.getColor(FSkin.Colors.CLR_BORDERS))); + + chbCatalogColor.setFont(FSkin.getFont(12)); + chbCatalogRarity.setFont(FSkin.getFont(12)); + chbCatalogCMC.setFont(FSkin.getFont(12)); + chbCatalogSet.setFont(FSkin.getFont(12)); + chbCatalogAI.setFont(FSkin.getFont(12)); + + chbDeckColor.setFont(FSkin.getFont(12)); + chbDeckRarity.setFont(FSkin.getFont(12)); + chbDeckCMC.setFont(FSkin.getFont(12)); + chbDeckSet.setFont(FSkin.getFont(12)); + chbDeckAI.setFont(FSkin.getFont(12)); + + chbDeckStats.setFont(FSkin.getFont(12)); + chbCatalogStats.setFont(FSkin.getFont(12)); + chbDeckStats.setSelected(true); + chbCatalogStats.setSelected(true); + + pnl.add(lblStats, "h 25px!, gap 5px 5px 5px 5px, ax center, span 2 1"); + pnl.add(chbCatalogStats, "h 25px!, gap 5px 5px 5px 5px, ax center, span 2 1"); + pnl.add(chbDeckStats, "h 25px!, gap 5px 5px 5px 5px, ax center, span 2 1"); + + final String constraints = "w 75px, h 25px!, gap 5px 5px 5px 5px, ax center"; + pnl.add(lblCatalog, constraints + ", span 2 1"); + pnl.add(chbCatalogColor, constraints); + pnl.add(chbCatalogRarity, constraints); + pnl.add(chbCatalogCMC, constraints); + pnl.add(chbCatalogSet, constraints); + pnl.add(chbCatalogAI, constraints + ", wrap"); + + pnl.add(lblDeck, constraints + ", span 2 1"); + pnl.add(chbDeckColor, constraints); + pnl.add(chbDeckRarity, constraints); + pnl.add(chbDeckCMC, constraints); + pnl.add(chbDeckSet, constraints); + pnl.add(chbDeckAI, constraints); + + pnl.setOpaque(false); + scroller.setOpaque(false); + scroller.getViewport().setOpaque(false); + scroller.setBorder(null); + scroller.getViewport().setBorder(null); + } + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getDocumentID() + */ + @Override + public EDocID getDocumentID() { + return EDocID.EDITOR_PREFERENCES; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getTabLabel() + */ + @Override + public DragTab getTabLabel() { + return tab; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getControl() + */ + @Override + public ICDoc getControl() { + return CEditorPreferences.SINGLETON_INSTANCE; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#setParentCell(forge.gui.framework.DragCell) + */ + @Override + public void setParentCell(final DragCell cell0) { + this.parentCell = cell0; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getParentCell() + */ + @Override + public DragCell getParentCell() { + return this.parentCell; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#populate() + */ + @Override + public void populate() { + parentCell.getBody().setLayout(new MigLayout("insets 0, gap 0, wrap")); + parentCell.getBody().add(scroller, "w 96%!, h 96%, gap 2% 0 2% 0"); + } + + //========== Retrieval methods + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbCatalogColor() { + return chbCatalogColor; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbCatalogRarity() { + return chbCatalogRarity; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbCatalogCMC() { + return chbCatalogCMC; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbCatalogSet() { + return chbCatalogSet; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbCatalogAI() { + return chbCatalogAI; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbDeckColor() { + return chbDeckColor; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbDeckRarity() { + return chbDeckRarity; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbDeckCMC() { + return chbDeckCMC; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbDeckSet() { + return chbDeckSet; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbDeckAI() { + return chbDeckAI; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbDeckStats() { + return chbDeckStats; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbCatalogStats() { + return chbCatalogStats; + } + //========== Other methods + +} diff --git a/src/main/java/forge/gui/deckeditor/views/VFilters.java b/src/main/java/forge/gui/deckeditor/views/VFilters.java new file mode 100644 index 00000000000..51217423478 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/views/VFilters.java @@ -0,0 +1,306 @@ +package forge.gui.deckeditor.views; + +import java.awt.Insets; + +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextField; +import javax.swing.border.MatteBorder; + +import net.miginfocom.swing.MigLayout; +import forge.Singletons; +import forge.card.CardEdition; +import forge.game.GameFormat; +import forge.gui.deckeditor.SFilterUtil; +import forge.gui.deckeditor.controllers.CFilters; +import forge.gui.framework.DragCell; +import forge.gui.framework.DragTab; +import forge.gui.framework.EDocID; +import forge.gui.framework.ICDoc; +import forge.gui.framework.IVDoc; +import forge.gui.toolbox.FLabel; +import forge.gui.toolbox.FSkin; +import forge.gui.toolbox.FTextField; + +/** + * Assembles Swing components of deck editor filter tab. + * + *

(V at beginning of class name denotes a view class.) + */ +public enum VFilters implements IVDoc { + /** */ + SINGLETON_INSTANCE; + + // Fields used with interface IVDoc + private DragCell parentCell; + private final DragTab tab = new DragTab("Filters"); + + // Text filter components + private final JTextField txfContains = new FTextField(); + private final JTextField txfWithout = new FTextField(); + private final JLabel lblContains = new FLabel.Builder() + .text("Contains:").fontScaleAuto(false).fontSize(14).build(); + private final JLabel lblWithout = new FLabel.Builder() + .text("Without:").fontScaleAuto(false).fontSize(14).build(); + + // Interval filter components + private final JComboBox cbxSets = new JComboBox(); + private final JComboBox cbxPLow = new JComboBox(); + private final JComboBox cbxPHigh = new JComboBox(); + private final JComboBox cbxTLow = new JComboBox(); + private final JComboBox cbxTHigh = new JComboBox(); + private final JComboBox cbxCMCLow = new JComboBox(); + private final JComboBox cbxCMCHigh = new JComboBox(); + + private final JLabel lblP = new FLabel.Builder() + .fontScaleAuto(false).fontSize(12).text(" <= Power <= ").build(); + + private final JLabel lblT = new FLabel.Builder() + .fontScaleAuto(false).fontSize(12).text(" <= Toughness <= ").build(); + + private final JLabel lblCMC = new FLabel.Builder() + .fontScaleAuto(false).fontSize(12).text(" <= CMC <= ").build(); + + // Title labels + private final JLabel lblProperties = new FLabel.Builder() + .text("Properties").tooltip("Filter by color, type, set, or format. Click to toggle.") + .hoverable(true).fontScaleAuto(false).fontSize(14).build(); + + private final JLabel lblText = new FLabel.Builder() + .text("Card Text").tooltip("Filter by card name, type, and text, space delimited. Click to reset.") + .hoverable(true).fontScaleAuto(false).fontSize(14).build(); + + private final JLabel lblIntervals = new FLabel.Builder() + .text("Intervals").tooltip("Filter by power, toughness, or converted mana cost. Click to reset.") + .hoverable(true).fontScaleAuto(false).fontSize(14).build(); + + // Container components + private final JPanel pnlText = new JPanel(new MigLayout( + "insets 0, gap 0, wrap 2, ax center")); + private final JPanel pnlIntervals = new JPanel(new MigLayout( + "insets 0, gap 0, wrap 3, ax center")); + + private JPanel pnlContainer = new JPanel(new MigLayout("insets 0, gap 0, wrap")); + private JScrollPane scroller = new JScrollPane(pnlContainer); + + //========== Constructor + private VFilters() { + String constraints = ""; + + // Sets/formats combo box + cbxSets.addItem("All sets and formats"); + for (final GameFormat s : Singletons.getModel().getFormats()) { + cbxSets.addItem(s); + } + for (final CardEdition s : Singletons.getModel().getEditions()) { + cbxSets.addItem(s); + } + + // Color/type searches + lblProperties.setBorder(new MatteBorder(0, 0, 1, 0, + FSkin.getColor(FSkin.Colors.CLR_BORDERS))); + lblText.setBorder(new MatteBorder(0, 0, 1, 0, + FSkin.getColor(FSkin.Colors.CLR_BORDERS))); + lblIntervals.setBorder(new MatteBorder(0, 0, 1, 0, + FSkin.getColor(FSkin.Colors.CLR_BORDERS))); + + // Text search + txfContains.setMargin(new Insets(5, 5, 5, 5)); + txfContains.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + txfContains.setOpaque(true); + txfContains.setEditable(true); + txfContains.setFocusable(true); + txfContains.setOpaque(true); + txfContains.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + + txfWithout.setMargin(new Insets(5, 5, 5, 5)); + txfWithout.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + txfWithout.setOpaque(true); + txfWithout.setEditable(true); + txfWithout.setFocusable(true); + txfWithout.setOpaque(true); + txfWithout.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + + pnlText.setOpaque(false); + pnlText.add(lblText, "w 210px!, span 2 1, h 25px!"); + pnlText.add(lblContains, "w 80px!, h 30px!"); + pnlText.add(txfContains, "pushx, growx, gap 5px 5px 2px 2px, h 30px!"); + pnlText.add(lblWithout, "w 80px!, h 30px!"); + pnlText.add(txfWithout, "pushx, growx, gap 5px 5px 2px 2px, h 30px!"); + + cbxPLow.addItem("*"); + cbxTLow.addItem("*"); + cbxCMCLow.addItem("*"); + + // Interval search + for (int i = 0; i < 10; i++) { + cbxPLow.addItem(i); + cbxTLow.addItem(i); + cbxCMCLow.addItem(i); + cbxPHigh.addItem(i); + cbxTHigh.addItem(i); + cbxCMCHigh.addItem(i); + } + + cbxPHigh.addItem("10+"); + cbxTHigh.addItem("10+"); + cbxCMCHigh.addItem("10+"); + + cbxPLow.setSelectedItem("*"); + cbxTLow.setSelectedItem("*"); + cbxCMCLow.setSelectedItem("*"); + cbxPHigh.setSelectedItem("10+"); + cbxTHigh.setSelectedItem("10+"); + cbxCMCHigh.setSelectedItem("10+"); + + constraints = "w 60px!, h 25px!, gap 0 0 0 0"; + pnlIntervals.add(cbxPLow, constraints); + pnlIntervals.add(lblP, "w 100px!, h 25px!"); + pnlIntervals.add(cbxPHigh, constraints); + + pnlIntervals.add(cbxTLow, constraints); + pnlIntervals.add(lblT, "w 100px!, h 25px!"); + pnlIntervals.add(cbxTHigh, constraints); + + pnlIntervals.add(cbxCMCLow, constraints); + pnlIntervals.add(lblCMC, "w 100px!, h 25px!"); + pnlIntervals.add(cbxCMCHigh, constraints); + + pnlIntervals.setOpaque(false); + + // Core layout + final String constraints2 = "w 90%!, gap 5% 0 1% 0"; + pnlContainer.add(lblProperties, "w 90%!, h 25px!, gap 5% 0 1% 0"); + pnlContainer.add(SFilterUtil.populateColorFilters(), constraints2); + pnlContainer.add(SFilterUtil.populateTypeFilters(), constraints2); + pnlContainer.add(cbxSets, constraints2 + ", h 25px!"); + + pnlContainer.add(lblText, "w 90%!, h 25px!, gap 5% 0 15px 0"); + pnlContainer.add(pnlText, constraints2); + + pnlContainer.add(lblIntervals, "w 90%!, h 25px!, gap 5% 0 15px 0"); + pnlContainer.add(pnlIntervals, constraints2); + + pnlContainer.setOpaque(false); + scroller.setOpaque(false); + scroller.getViewport().setOpaque(false); + scroller.setBorder(null); + scroller.getViewport().setBorder(null); + } + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getDocumentID() + */ + @Override + public EDocID getDocumentID() { + return EDocID.EDITOR_FILTERS; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getTabLabel() + */ + @Override + public DragTab getTabLabel() { + return tab; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getControl() + */ + @Override + public ICDoc getControl() { + return CFilters.SINGLETON_INSTANCE; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#setParentCell(forge.gui.framework.DragCell) + */ + @Override + public void setParentCell(final DragCell cell0) { + this.parentCell = cell0; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getParentCell() + */ + @Override + public DragCell getParentCell() { + return this.parentCell; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#populate() + */ + @Override + public void populate() { + parentCell.getBody().setLayout(new MigLayout("insets 0, gap 0, wrap")); + parentCell.getBody().add(scroller, "w 96%!, h 96%, gap 2% 0 2% 0"); + } + + //========== Retrieval methods + /** @return {javax.swing.JLabel} */ + public JLabel getBtnToggle() { + return lblProperties; + } + + /** @return {javax.swing.JLabel} */ + public JLabel getBtnResetText() { + return lblText; + } + + /** @return {javax.swing.JLabel} */ + public JLabel getBtnResetIntervals() { + return lblIntervals; + } + + /** @return {javax.swing.JComboBox} */ + public JComboBox getCbxSets() { + return cbxSets; + } + + /** @return {javax.swing.JTextField} */ + public JTextField getTxfContains() { + return txfContains; + } + + /** @return {javax.swing.JTextField} */ + public JTextField getTxfWithout() { + return txfWithout; + } + + /** @return {javax.swing.JComboBox} */ + public JComboBox getCbxPLow() { + return cbxPLow; + } + + /** @return {javax.swing.JComboBox} */ + public JComboBox getCbxPHigh() { + return cbxPHigh; + } + + /** @return {javax.swing.JComboBox} */ + public JComboBox getCbxTLow() { + return cbxTLow; + } + + /** @return {javax.swing.JComboBox} */ + public JComboBox getCbxTHigh() { + return cbxTHigh; + } + + /** @return {javax.swing.JComboBox} */ + public JComboBox getCbxCMCLow() { + return cbxCMCLow; + } + + /** @return {javax.swing.JComboBox} */ + public JComboBox getCbxCMCHigh() { + return cbxCMCHigh; + } + //========== Custom class handling + +} diff --git a/src/main/java/forge/gui/deckeditor/views/VProbabilities.java b/src/main/java/forge/gui/deckeditor/views/VProbabilities.java new file mode 100644 index 00000000000..98433d93a91 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/views/VProbabilities.java @@ -0,0 +1,198 @@ +package forge.gui.deckeditor.views; + +import java.awt.Font; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.List; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingConstants; +import javax.swing.border.MatteBorder; + +import net.miginfocom.swing.MigLayout; +import forge.deck.DeckBase; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.controllers.ACEditorBase; +import forge.gui.deckeditor.controllers.CProbabilities; +import forge.gui.framework.DragCell; +import forge.gui.framework.DragTab; +import forge.gui.framework.EDocID; +import forge.gui.framework.ICDoc; +import forge.gui.framework.IVDoc; +import forge.gui.toolbox.FLabel; +import forge.gui.toolbox.FSkin; +import forge.item.CardPrinted; +import forge.item.InventoryItem; + +/** + * Assembles Swing components of deck editor analysis tab. + * + *

(V at beginning of class name denotes a view class.) + */ +public enum VProbabilities implements IVDoc { + /** */ + SINGLETON_INSTANCE; + + // Fields used with interface IVDoc + private DragCell parentCell; + private final DragTab tab = new DragTab("Draw Order"); + + // Title labels + private final JLabel lblReshuffle = new FLabel.Builder() + .hoverable(true).text("RE-SHUFFLE").tooltip("See a new sample shuffle") + .fontScaleAuto(false).fontSize(12).build(); + private final JLabel lblSampleHand = new FLabel.Builder().fontStyle(Font.BOLD) + .fontSize(14).fontScaleAuto(false).text("SAMPLE HAND").build(); + private final JLabel lblRemainingDraws = new FLabel.Builder().fontStyle(Font.BOLD) + .fontSize(14).fontScaleAuto(false).text("REMAINING DRAWS").build(); + private final JLabel lblExplanation = new FLabel.Builder() + .fontSize(11).fontScaleAuto(false).text("XX % = frequency that card will appear at that position").build(); + + // Layout containers + private final JPanel pnlContent = new JPanel(new MigLayout("insets 0, gap 0, wrap")); + private final JScrollPane scroller = new JScrollPane(pnlContent); + private final JPanel pnlHand = new JPanel(new MigLayout("insets 0, gap 0, wrap")); + private final JPanel pnlLibrary = new JPanel(new MigLayout("insets 0, gap 0, wrap")); + + //========== Constructor + private VProbabilities() { + pnlContent.setOpaque(false); + pnlHand.setOpaque(false); + pnlLibrary.setOpaque(false); + scroller.setOpaque(false); + scroller.getViewport().setOpaque(false); + scroller.setBorder(null); + scroller.getViewport().setBorder(null); + scroller.getVerticalScrollBar().setUnitIncrement(16); + + // Sample hand + lblExplanation.setBorder(new MatteBorder(0, 0, 1, 0, FSkin.getColor(FSkin.Colors.CLR_BORDERS))); + lblRemainingDraws.setBorder(new MatteBorder(1, 0, 1, 0, FSkin.getColor(FSkin.Colors.CLR_BORDERS))); + + // Core layout + final String constraints = "w 96%!, h 25px!, gap 2% 0 0 0"; + + pnlContent.add(lblReshuffle, constraints); + pnlContent.add(lblSampleHand, constraints); + pnlContent.add(lblExplanation, constraints); + pnlContent.add(pnlHand, "w 96%!, gap 2% 0 0 0"); + pnlContent.add(lblRemainingDraws, constraints); + pnlContent.add(pnlLibrary, "w 96%!, gap 2% 0 0 0"); + } + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getDocumentID() + */ + @Override + public EDocID getDocumentID() { + return EDocID.EDITOR_PROBABILITIES; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getTabLabel() + */ + @Override + public DragTab getTabLabel() { + return tab; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getControl() + */ + @Override + public ICDoc getControl() { + return CProbabilities.SINGLETON_INSTANCE; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#setParentCell(forge.gui.framework.DragCell) + */ + @Override + public void setParentCell(final DragCell cell0) { + this.parentCell = cell0; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getParentCell() + */ + @Override + public DragCell getParentCell() { + return this.parentCell; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#populate() + */ + @Override + public void populate() { + parentCell.getBody().setLayout(new MigLayout("insets 0, gap 0")); + parentCell.getBody().add(scroller, "w 96%!, h 96%!, gap 2% 0 2% 0"); + } + + //========== Retrieval methods + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblReshuffle() { + return lblReshuffle; + } + + //========== Other methods + /** @param shuffledVals   A map of card names and their positional probability. */ + public void rebuildLabels(final List shuffledVals) { + pnlHand.removeAll(); + pnlLibrary.removeAll(); + + JLabel lbl; + final String constraints = "w 96%, h 25px!, gap 2% 0 0 0"; + + for (int i = 0; i < shuffledVals.size(); i++) { + lbl = (i % 2 == 1 ? buildLabel(true) : buildLabel(false)); + lbl.setText(shuffledVals.get(i)); + + if (i < 7) { pnlHand.add(lbl, constraints); } + else { pnlLibrary.add(lbl, constraints); } + } + + pnlHand.validate(); + pnlLibrary.validate(); + } + + private JLabel buildLabel(final boolean zebra) { + final JLabel lbl = new FLabel.Builder().text("--") + .fontAlign(SwingConstants.CENTER).fontSize(13).fontScaleAuto(false) + .build(); + + lbl.addMouseListener(new MouseAdapter() { + @Override + @SuppressWarnings("unchecked") + public void mouseEntered(final MouseEvent e) { + final ACEditorBase ed = (ACEditorBase) + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController(); + + final List cards = (List) ed.getTableDeck().getCards().toFlatList(); + final String name1 = lbl.getText(); + String name2; + + for (CardPrinted c : cards) { + name2 = c.getName(); + if (name2.length() > name1.length()) { continue; } + + if (name2.equals(name1.substring(0, name2.length()))) { + CDeckEditorUI.SINGLETON_INSTANCE.setCard(c.toForgeCard()); + break; + } + } + } + }); + + if (zebra) { + lbl.setOpaque(true); + lbl.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + } + + return lbl; + } +} diff --git a/src/main/java/forge/gui/deckeditor/views/VStatistics.java b/src/main/java/forge/gui/deckeditor/views/VStatistics.java new file mode 100644 index 00000000000..0b8b3cfb298 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/views/VStatistics.java @@ -0,0 +1,271 @@ +package forge.gui.deckeditor.views; + +import java.awt.Font; + +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; + +import net.miginfocom.swing.MigLayout; +import forge.gui.deckeditor.SEditorUtil; +import forge.gui.deckeditor.controllers.CStatistics; +import forge.gui.framework.DragCell; +import forge.gui.framework.DragTab; +import forge.gui.framework.EDocID; +import forge.gui.framework.ICDoc; +import forge.gui.framework.IVDoc; +import forge.gui.toolbox.FLabel; +import forge.gui.toolbox.FSkin; + +/** + * Assembles Swing components of deck editor analysis tab. + * + *

(V at beginning of class name denotes a view class.) + */ +public enum VStatistics implements IVDoc { + /** */ + SINGLETON_INSTANCE; + + // Fields used with interface IVDoc + private DragCell parentCell; + private final DragTab tab = new DragTab("Statistics"); + + // Global stats + private JLabel lblTotal = new FLabel.Builder() + .text("Total cards: 0").tooltip("TOTAL CARDS") + .fontStyle(Font.BOLD).fontSize(11).fontStyle(Font.BOLD) + .fontScaleAuto(false).build(); + private JLabel lblTMC = new FLabel.Builder() + .text("Total mana cost: 0").tooltip("TOTAL MANA COST") + .fontStyle(Font.BOLD).fontSize(11).fontStyle(Font.BOLD) + .fontScaleAuto(false).build(); + private JLabel lblAMC = new FLabel.Builder() + .text("Average mana cost: 0.00").tooltip("AVERAGE MANA COST") + .fontStyle(Font.BOLD).fontSize(11).fontStyle(Font.BOLD) + .fontScaleAuto(false).build(); + + // Total and color count labels + private final JPanel pnlStats = new JPanel(); + private final JLabel lblMulti = buildLabel(SEditorUtil.ICO_MULTI, true); + private final JLabel lblBlack = buildLabel(SEditorUtil.ICO_BLACK, false); + private final JLabel lblBlue = buildLabel(SEditorUtil.ICO_BLUE, true); + private final JLabel lblGreen = buildLabel(SEditorUtil.ICO_GREEN, false); + private final JLabel lblRed = buildLabel(SEditorUtil.ICO_RED, true); + private final JLabel lblWhite = buildLabel(SEditorUtil.ICO_WHITE, false); + private final JLabel lblColorless = buildLabel(SEditorUtil.ICO_COLORLESS, true); + + // Card type labels + private final JLabel lblArtifact = buildLabel(SEditorUtil.ICO_ARTIFACT, true); + private final JLabel lblCreature = buildLabel(SEditorUtil.ICO_CREATURE, false); + private final JLabel lblEnchantment = buildLabel(SEditorUtil.ICO_ENCHANTMENT, true); + private final JLabel lblInstant = buildLabel(SEditorUtil.ICO_INSTANT, false); + private final JLabel lblLand = buildLabel(SEditorUtil.ICO_LAND, true); + private final JLabel lblPlaneswalker = buildLabel(SEditorUtil.ICO_PLANESWALKER, false); + private final JLabel lblSorcery = buildLabel(SEditorUtil.ICO_SORCERY, true); + + // CMC labels + private final JLabel lblCMC0 = buildLabel( + new ImageIcon(FSkin.getImage(FSkin.ColorlessManaImages.IMG_0, 16, 16)), true); + private final JLabel lblCMC1 = buildLabel( + new ImageIcon(FSkin.getImage(FSkin.ColorlessManaImages.IMG_1, 16, 16)), false); + private final JLabel lblCMC2 = buildLabel( + new ImageIcon(FSkin.getImage(FSkin.ColorlessManaImages.IMG_2, 16, 16)), true); + private final JLabel lblCMC3 = buildLabel( + new ImageIcon(FSkin.getImage(FSkin.ColorlessManaImages.IMG_3, 16, 16)), false); + private final JLabel lblCMC4 = buildLabel( + new ImageIcon(FSkin.getImage(FSkin.ColorlessManaImages.IMG_4, 16, 16)), true); + private final JLabel lblCMC5 = buildLabel( + new ImageIcon(FSkin.getImage(FSkin.ColorlessManaImages.IMG_5, 16, 16)), false); + private final JLabel lblCMC6 = buildLabel( + new ImageIcon(FSkin.getImage(FSkin.ColorlessManaImages.IMG_6, 16, 16)), true); + + // Layout containers + private final JScrollPane scroller = new JScrollPane(pnlStats); + + //========== Constructor + private VStatistics() { + scroller.setOpaque(false); + scroller.getViewport().setOpaque(false); + scroller.setBorder(null); + scroller.getViewport().setBorder(null); + scroller.getVerticalScrollBar().setUnitIncrement(16); + + // Color stats + lblMulti.setToolTipText("Total Card Count"); + lblBlack.setToolTipText("Black Card Count"); + lblBlue.setToolTipText("Blue Card Count"); + lblGreen.setToolTipText("Green Card Count"); + lblRed.setToolTipText("Red Card Count"); + lblWhite.setToolTipText("White Card Count"); + lblColorless.setToolTipText("Total Card Count"); + + // Type stats + lblArtifact.setToolTipText("Artiface Card Count"); + lblCreature.setToolTipText("Creature Card Count"); + lblColorless.setToolTipText("Colorless Card Count"); + lblEnchantment.setToolTipText("Enchantment Card Count"); + lblInstant.setToolTipText("Instant Card Count"); + lblLand.setToolTipText("Land Card Count"); + lblPlaneswalker.setToolTipText("Planeswalker Card Count"); + lblSorcery.setToolTipText("Sorcery Card Count"); + + // Stats container + pnlStats.setOpaque(false); + pnlStats.setLayout(new MigLayout("insets 0, gap 0, ax center, wrap 3")); + + pnlStats.add(lblTotal, "w 96%!, h 20px!, span 3 1, gap 2% 0 0 0"); + pnlStats.add(lblTMC, "w 96%!, h 20px!, span 3 1, gap 2% 0 0 0"); + pnlStats.add(lblAMC, "w 96%!, h 20px!, span 3 1, gap 2% 0 0 0"); + + // Add labels to container + final String constraints = "w 32%!, h 35px!"; + pnlStats.add(lblMulti, constraints); + pnlStats.add(lblArtifact, constraints); + pnlStats.add(lblCMC0, constraints); + + pnlStats.add(lblBlack, constraints); + pnlStats.add(lblCreature, constraints); + pnlStats.add(lblCMC1, constraints); + + pnlStats.add(lblBlue, constraints); + pnlStats.add(lblEnchantment, constraints); + pnlStats.add(lblCMC2, constraints); + + pnlStats.add(lblGreen, constraints); + pnlStats.add(lblInstant, constraints); + pnlStats.add(lblCMC3, constraints); + + pnlStats.add(lblRed, constraints); + pnlStats.add(lblLand, constraints); + pnlStats.add(lblCMC4, constraints); + + pnlStats.add(lblWhite, constraints); + pnlStats.add(lblPlaneswalker, constraints); + pnlStats.add(lblCMC5, constraints); + + pnlStats.add(lblColorless, constraints); + pnlStats.add(lblSorcery, constraints); + pnlStats.add(lblCMC6, constraints); + } + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getDocumentID() + */ + @Override + public EDocID getDocumentID() { + return EDocID.EDITOR_STATISTICS; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getTabLabel() + */ + @Override + public DragTab getTabLabel() { + return tab; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getControl() + */ + @Override + public ICDoc getControl() { + return CStatistics.SINGLETON_INSTANCE; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#setParentCell(forge.gui.framework.DragCell) + */ + @Override + public void setParentCell(final DragCell cell0) { + this.parentCell = cell0; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getParentCell() + */ + @Override + public DragCell getParentCell() { + return this.parentCell; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#populate() + */ + @Override + public void populate() { + parentCell.getBody().setLayout(new MigLayout("insets 0, gap 0")); + parentCell.getBody().add(scroller, "w 96%!, h 96%!, gap 2% 0 2% 0"); + } + + //========== Retrieval methods + + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblMulti() { return lblMulti; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblBlack() { return lblBlack; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblBlue() { return lblBlue; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblGreen() { return lblGreen; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblRed() { return lblRed; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblWhite() { return lblWhite; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblColorless() { return lblColorless; } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblArtifact() { return lblArtifact; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblEnchantment() { return lblEnchantment; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblCreature() { return lblCreature; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblSorcery() { return lblSorcery; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblInstant() { return lblInstant; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblPlaneswalker() { return lblPlaneswalker; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblLand() { return lblLand; } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblCMC0() { return lblCMC0; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblCMC1() { return lblCMC1; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblCMC2() { return lblCMC2; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblCMC3() { return lblCMC3; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblCMC4() { return lblCMC4; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblCMC5() { return lblCMC5; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblCMC6() { return lblCMC6; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblTotal() { return lblTotal; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblTMC() { return lblTMC; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblAMC() { return lblAMC; } + + //========== Other methods + + private JLabel buildLabel(final ImageIcon icon0, final boolean zebra) { + final JLabel lbl = new FLabel.Builder().text("0") + .icon(icon0).iconScaleAuto(false) + .fontSize(11).fontScaleAuto(false) + .build(); + + if (zebra) { + lbl.setOpaque(true); + lbl.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + } + + return lbl; + } +} diff --git a/src/main/java/forge/gui/framework/DragCell.java b/src/main/java/forge/gui/framework/DragCell.java index 504e98aa5cc..8b788a47e70 100644 --- a/src/main/java/forge/gui/framework/DragCell.java +++ b/src/main/java/forge/gui/framework/DragCell.java @@ -147,7 +147,12 @@ public final class DragCell extends JPanel implements ILocalRepaint { * @return int */ public int getAbsX() { - return (int) this.getLocationOnScreen().getX(); + int i = 0; + + try { i = (int) this.getLocationOnScreen().getX(); } + catch (final Exception e) { } + + return i; } /** @@ -155,7 +160,12 @@ public final class DragCell extends JPanel implements ILocalRepaint { * @return int */ public int getAbsX2() { - return this.getAbsX() + this.getW(); + int i = 0; + + try { i = this.getAbsX() + this.getW(); } + catch (final Exception e) { } + + return i; } /** @@ -163,7 +173,12 @@ public final class DragCell extends JPanel implements ILocalRepaint { * @return int */ public int getAbsY() { - return (int) this.getLocationOnScreen().getY(); + int i = 0; + + try { i = (int) this.getLocationOnScreen().getY(); } + catch (final Exception e) { } + + return i; } /** @@ -171,7 +186,12 @@ public final class DragCell extends JPanel implements ILocalRepaint { * @return int */ public int getAbsY2() { - return this.getAbsY() + this.getH(); + int i = 0; + + try { i = this.getAbsY() + this.getH(); } + catch (final Exception e) { } + + return i; } /** diff --git a/src/main/java/forge/gui/framework/EDocID.java b/src/main/java/forge/gui/framework/EDocID.java index 3e68ad6de2e..ed395026456 100644 --- a/src/main/java/forge/gui/framework/EDocID.java +++ b/src/main/java/forge/gui/framework/EDocID.java @@ -3,6 +3,14 @@ */ package forge.gui.framework; +import forge.gui.deckeditor.views.VAllDecks; +import forge.gui.deckeditor.views.VCardCatalog; +import forge.gui.deckeditor.views.VCurrentDeck; +import forge.gui.deckeditor.views.VDeckgen; +import forge.gui.deckeditor.views.VEditorPreferences; +import forge.gui.deckeditor.views.VFilters; +import forge.gui.deckeditor.views.VProbabilities; +import forge.gui.deckeditor.views.VStatistics; import forge.gui.match.views.VAntes; import forge.gui.match.views.VCombat; import forge.gui.match.views.VDetail; @@ -21,6 +29,15 @@ import forge.gui.match.views.VStack; *

(E at beginning of class name denotes an enum.) */ public enum EDocID { /** */ + EDITOR_FILTERS (VFilters.SINGLETON_INSTANCE), /** */ + EDITOR_PREFERENCES (VEditorPreferences.SINGLETON_INSTANCE), /** */ + EDITOR_ALLDECKS (VAllDecks.SINGLETON_INSTANCE), /** */ + EDITOR_STATISTICS (VStatistics.SINGLETON_INSTANCE), /** */ + EDITOR_PROBABILITIES (VProbabilities.SINGLETON_INSTANCE), /** */ + EDITOR_CATALOG (VCardCatalog.SINGLETON_INSTANCE), /** */ + EDITOR_CURRENTDECK (VCurrentDeck.SINGLETON_INSTANCE), /** */ + EDITOR_DECKGEN (VDeckgen.SINGLETON_INSTANCE), /** */ + CARD_PICTURE (VPicture.SINGLETON_INSTANCE), /** */ CARD_DETAIL (VDetail.SINGLETON_INSTANCE), /** */ CARD_ANTES (VAntes.SINGLETON_INSTANCE), /** */ @@ -61,7 +78,7 @@ public enum EDocID { /** */ /** @return {@link forge.gui.framework.IVDoc} */ public IVDoc getDoc() { - if (vDoc == null) { throw new NullPointerException("No document found!"); } + if (vDoc == null) { throw new NullPointerException("No document found for " + this.name() + "."); } return vDoc; } } diff --git a/src/main/java/forge/gui/framework/ICDoc.java b/src/main/java/forge/gui/framework/ICDoc.java index 9dc42a9c282..162f1b4b932 100644 --- a/src/main/java/forge/gui/framework/ICDoc.java +++ b/src/main/java/forge/gui/framework/ICDoc.java @@ -20,10 +20,10 @@ public interface ICDoc { Command getCommandOnSelect(); /** - * Call this method after the view singleton has been fully realized + * This method is called once, after the view singleton has been fully realized * for the first time. It should execute operations which should only - * be done once, but require non-null view components.

- * + * be done once, but require non-null view components. + *

* This method should only be called once, in FView, after singletons are populated. */ void initialize(); diff --git a/src/main/java/forge/gui/framework/IVTopLevelUI.java b/src/main/java/forge/gui/framework/IVTopLevelUI.java index 651de1ef11b..076750cd2f3 100644 --- a/src/main/java/forge/gui/framework/IVTopLevelUI.java +++ b/src/main/java/forge/gui/framework/IVTopLevelUI.java @@ -10,14 +10,18 @@ package forge.gui.framework; */ public interface IVTopLevelUI { /** Called during the preload sequence, this method caches - * all of the children singletons and instances. */ + * all of the view singletons and component instances, + * before any operations are performed on them. + *

+ * Although this is sometimes empty, it's important, since in many cases + * non-lazy components must be prepared before each panel is populated. + */ void instantiate(); /** * Removes all children and (re)populates top level content, * independent of constructor. Expected to provide * a completely fresh layout on the component. - * */ void populate(); } diff --git a/src/main/java/forge/gui/framework/SIOUtil.java b/src/main/java/forge/gui/framework/SLayoutIO.java similarity index 73% rename from src/main/java/forge/gui/framework/SIOUtil.java rename to src/main/java/forge/gui/framework/SLayoutIO.java index caf5cf34482..8f661d6700e 100644 --- a/src/main/java/forge/gui/framework/SIOUtil.java +++ b/src/main/java/forge/gui/framework/SLayoutIO.java @@ -18,6 +18,8 @@ import javax.xml.stream.events.Attribute; import javax.xml.stream.events.StartElement; import javax.xml.stream.events.XMLEvent; +import forge.control.FControl; +import forge.properties.NewConstants; import forge.view.FView; @@ -26,7 +28,7 @@ import forge.view.FView; * *

(S at beginning of class name denotes a static factory.) */ -public final class SIOUtil { +public final class SLayoutIO { /** Each cell must save these elements of its display. */ private enum Property { x, @@ -36,15 +38,22 @@ public final class SIOUtil { doc }; - /** */ - public static final String FILE_DEFAULT = "res/layouts/match_default.xml"; - public static final String FILE_PREFERRED = "res/layouts/match_preferred.xml"; + private static String fileDefault = null; + private static String filePreferred = null; private static final XMLEventFactory EF = XMLEventFactory.newInstance(); private static final XMLEvent NEWLINE = EF.createDTD("\n"); private static final XMLEvent TAB = EF.createDTD("\t"); + /** + * Gets preferred layout file corresponding to current state of UI. + * @return {@link java.lang.String} + */ + public static String getFilePreferred() { + return filePreferred; + } + /** Publicly-accessible save method, to neatly handle exception handling. - * @param f0 file to save layout to, if null, saves to FILE_PREFERRED + * @param f0 file to save layout to, if null, saves to filePreferred * * */ @@ -52,9 +61,9 @@ public final class SIOUtil { if (SwingUtilities.isEventDispatchThread()) { throw new IllegalThreadStateException("This operation should be independent of the EDT."); } - - try { save(f0); } - catch (final Exception e) { e.printStackTrace(); } + + try { save(f0); } + catch (final Exception e) { e.printStackTrace(); } } @@ -72,15 +81,16 @@ public final class SIOUtil { } private static void save(final File f0) throws Exception { - final String fWriteTo; - if (f0==null) { - fWriteTo = FILE_PREFERRED; + SLayoutIO.setFilesForState(); + + if (f0 == null) { + fWriteTo = filePreferred; } else { fWriteTo = f0.getPath(); - } - + } + final XMLOutputFactory out = XMLOutputFactory.newInstance(); final XMLEventWriter writer = out.createXMLEventWriter(new FileOutputStream(fWriteTo)); final List cells = FView.SINGLETON_INSTANCE.getDragCells(); @@ -125,16 +135,17 @@ public final class SIOUtil { private static void load(final File f) throws Exception { final FView view = FView.SINGLETON_INSTANCE; final XMLInputFactory inputFactory = XMLInputFactory.newInstance(); + SLayoutIO.setFilesForState(); final XMLEventReader reader; if (f != null && f.exists()) { reader = inputFactory.createXMLEventReader(new FileInputStream(f)); } - else if (new File(FILE_PREFERRED).exists()) { - reader = inputFactory.createXMLEventReader(new FileInputStream(FILE_PREFERRED)); + else if (new File(filePreferred).exists()) { + reader = inputFactory.createXMLEventReader(new FileInputStream(filePreferred)); } else { - reader = inputFactory.createXMLEventReader(new FileInputStream(FILE_DEFAULT)); + reader = inputFactory.createXMLEventReader(new FileInputStream(fileDefault)); } view.removeAllDragCells(); @@ -149,7 +160,6 @@ public final class SIOUtil { event = reader.nextEvent(); if (event.isStartElement()) { - //&& event.asStartElement().getName().getLocalPart().equals("cell")) { element = event.asStartElement(); if (element.getName().getLocalPart().equals("cell")) { @@ -195,4 +205,37 @@ public final class SIOUtil { writer0.add(EF.createEndElement("", "", name0.toString())); writer0.add(NEWLINE); } + + /** + * Updates preferred / default layout addresses particular to each UI state. + * Always called before a load or a save, to ensure file addresses are correct. + */ + private static void setFilesForState() { + final String dir = NewConstants.LAYOUT_DIR; + + switch(FControl.SINGLETON_INSTANCE.getState()) { + case FControl.HOME_SCREEN: + fileDefault = dir + "home_default.xml"; + filePreferred = dir + "home_preferred.xml"; + break; + case FControl.MATCH_SCREEN: + fileDefault = dir + "match_default.xml"; + filePreferred = dir + "match_preferred.xml"; + break; + case FControl.DECK_EDITOR_CONSTRUCTED: + case FControl.DECK_EDITOR_LIMITED: + case FControl.DECK_EDITOR_QUEST: + case FControl.DRAFTING_PROCESS: + case FControl.QUEST_CARD_SHOP: + fileDefault = dir + "editor_default.xml"; + filePreferred = dir + "editor_preferred.xml"; + break; + case FControl.QUEST_BAZAAR: + fileDefault = dir + "bazaar_default.xml"; + filePreferred = dir + "bazaar_preferred.xml"; + break; + default: + throw new IllegalStateException("Layout load failed; UI state unknown."); + } + } } diff --git a/src/main/java/forge/gui/framework/SRearrangingUtil.java b/src/main/java/forge/gui/framework/SRearrangingUtil.java index 22f8732deea..50d6a23f484 100644 --- a/src/main/java/forge/gui/framework/SRearrangingUtil.java +++ b/src/main/java/forge/gui/framework/SRearrangingUtil.java @@ -307,7 +307,7 @@ public final class SRearrangingUtil { updateBorders(); final Thread t = new Thread() { @Override - public void run() { SIOUtil.saveLayout(null); } }; + public void run() { SLayoutIO.saveLayout(null); } }; t.start(); } @@ -439,6 +439,19 @@ public final class SRearrangingUtil { throw new UnsupportedOperationException("Gap was not filled."); } + /** + * Fills a gap left by a source cell. + *

+ * Cell will not be removed, but its coordinates will be filled + * by its neighbors. + * + * @param sourceCell0   {@link forge.gui.framework.DragCell} + */ + public static void fillGap(final DragCell sourceCell0) { + cellSrc = sourceCell0; + fillGap(); + } + /** Hides outer borders for components on edges, * preventing illegal resizing (and misleading cursor). */ public static void updateBorders() { diff --git a/src/main/java/forge/gui/framework/SResizingUtil.java b/src/main/java/forge/gui/framework/SResizingUtil.java index d59630a7524..50c5eb9074c 100644 --- a/src/main/java/forge/gui/framework/SResizingUtil.java +++ b/src/main/java/forge/gui/framework/SResizingUtil.java @@ -332,7 +332,7 @@ public final class SResizingUtil { /** */ public static void endResize() { final Thread t = new Thread() { @Override - public void run() { SIOUtil.saveLayout(null); } }; + public void run() { SLayoutIO.saveLayout(null); } }; t.start(); } diff --git a/src/main/java/forge/gui/home/VHomeUI.java b/src/main/java/forge/gui/home/VHomeUI.java index 6429ae72cf6..015e405a180 100644 --- a/src/main/java/forge/gui/home/VHomeUI.java +++ b/src/main/java/forge/gui/home/VHomeUI.java @@ -202,16 +202,7 @@ public enum VHomeUI implements IVTopLevelUI { pnlParent.addComponentListener(new ComponentAdapter() { @Override public void componentResized(final ComponentEvent e) { - final int w = pnlParent.getWidth(); - final int h = pnlParent.getHeight(); - pnlRight.setBounds(new Rectangle( - 2 * insets + leftWidthPx, insets, - w - leftWidthPx - 3 * insets, h - 2 * insets)); - pnlLeft.setBounds(new Rectangle( - insets, insets, - leftWidthPx, h - 2 * insets - )); - pnlParent.revalidate(); + updateLayout(); } }); } @@ -313,4 +304,18 @@ public enum VHomeUI implements IVTopLevelUI { public JPanel getPanel() { return pnlParent; } + + /** Updates the null layout percentage dimensions. */ + public void updateLayout() { + final int w = pnlParent.getWidth(); + final int h = pnlParent.getHeight(); + pnlRight.setBounds(new Rectangle( + 2 * insets + leftWidthPx, insets, + w - leftWidthPx - 3 * insets, h - 2 * insets)); + pnlLeft.setBounds(new Rectangle( + insets, insets, + leftWidthPx, h - 2 * insets + )); + pnlParent.revalidate(); + } } diff --git a/src/main/java/forge/gui/home/quest/CSubmenuChallenges.java b/src/main/java/forge/gui/home/quest/CSubmenuChallenges.java index d6998d03836..46534ed609f 100644 --- a/src/main/java/forge/gui/home/quest/CSubmenuChallenges.java +++ b/src/main/java/forge/gui/home/quest/CSubmenuChallenges.java @@ -13,7 +13,7 @@ import forge.Command; import forge.gui.home.EMenuItem; import forge.gui.home.ICSubmenu; import forge.gui.home.VHomeUI; -import forge.gui.home.quest.SubmenuQuestUtil.SelectablePanel; +import forge.gui.home.quest.SSubmenuQuestUtil.SelectablePanel; import forge.gui.toolbox.FLabel; import forge.quest.QuestController; import forge.quest.QuestEventChallenge; @@ -59,15 +59,15 @@ public enum CSubmenuChallenges implements ICSubmenu { view.getBtnSpellShop().setCommand( new Command() { @Override - public void execute() { SubmenuQuestUtil.showSpellShop(); } }); + public void execute() { SSubmenuQuestUtil.showSpellShop(); } }); view.getBtnBazaar().setCommand( new Command() { @Override - public void execute() { SubmenuQuestUtil.showBazaar(); } }); + public void execute() { SSubmenuQuestUtil.showBazaar(); } }); view.getBtnStart().addActionListener( new ActionListener() { @Override - public void actionPerformed(final ActionEvent e) { SubmenuQuestUtil.startGame(); } }); + public void actionPerformed(final ActionEvent e) { SSubmenuQuestUtil.startGame(); } }); ((FLabel) view.getLblZep()).setCommand( new Command() { @@ -111,7 +111,7 @@ public enum CSubmenuChallenges implements ICSubmenu { */ @Override public void update() { - SubmenuQuestUtil.updateStatsAndPet(); + SSubmenuQuestUtil.updateStatsAndPet(); final VSubmenuChallenges view = VSubmenuChallenges.SINGLETON_INSTANCE; final QuestController qCtrl = AllZone.getQuest(); diff --git a/src/main/java/forge/gui/home/quest/CSubmenuDuels.java b/src/main/java/forge/gui/home/quest/CSubmenuDuels.java index e4d0e083ab4..925bc9dc0a2 100644 --- a/src/main/java/forge/gui/home/quest/CSubmenuDuels.java +++ b/src/main/java/forge/gui/home/quest/CSubmenuDuels.java @@ -9,7 +9,7 @@ import forge.Command; import forge.gui.home.EMenuItem; import forge.gui.home.ICSubmenu; import forge.gui.home.VHomeUI; -import forge.gui.home.quest.SubmenuQuestUtil.SelectablePanel; +import forge.gui.home.quest.SSubmenuQuestUtil.SelectablePanel; import forge.quest.QuestController; import forge.quest.QuestEventDuel; import forge.quest.bazaar.QuestPetController; @@ -52,15 +52,15 @@ public enum CSubmenuDuels implements ICSubmenu { view.getBtnSpellShop().setCommand( new Command() { @Override - public void execute() { SubmenuQuestUtil.showSpellShop(); } }); + public void execute() { SSubmenuQuestUtil.showSpellShop(); } }); view.getBtnBazaar().setCommand( new Command() { @Override - public void execute() { SubmenuQuestUtil.showBazaar(); } }); + public void execute() { SSubmenuQuestUtil.showBazaar(); } }); view.getBtnStart().addActionListener( new ActionListener() { @Override - public void actionPerformed(final ActionEvent e) { SubmenuQuestUtil.startGame(); } }); + public void actionPerformed(final ActionEvent e) { SSubmenuQuestUtil.startGame(); } }); view.getBtnCurrentDeck().setCommand( new Command() { @Override @@ -94,7 +94,7 @@ public enum CSubmenuDuels implements ICSubmenu { */ @Override public void update() { - SubmenuQuestUtil.updateStatsAndPet(); + SSubmenuQuestUtil.updateStatsAndPet(); final VSubmenuDuels view = VSubmenuDuels.SINGLETON_INSTANCE; diff --git a/src/main/java/forge/gui/home/quest/CSubmenuQuestData.java b/src/main/java/forge/gui/home/quest/CSubmenuQuestData.java index 78cf30dfbea..6566217b4ff 100644 --- a/src/main/java/forge/gui/home/quest/CSubmenuQuestData.java +++ b/src/main/java/forge/gui/home/quest/CSubmenuQuestData.java @@ -189,7 +189,7 @@ public enum CSubmenuQuestData implements ICSubmenu { AllZone.getQuest().getName() + ".dat"); Singletons.getModel().getQuestPreferences().save(); - SubmenuQuestUtil.updateStatsAndPet(); + SSubmenuQuestUtil.updateStatsAndPet(); CSubmenuDuels.SINGLETON_INSTANCE.update(); CSubmenuChallenges.SINGLETON_INSTANCE.update(); diff --git a/src/main/java/forge/gui/home/quest/CSubmenuQuestDecks.java b/src/main/java/forge/gui/home/quest/CSubmenuQuestDecks.java index 90915a50dbc..81c5afb7db2 100644 --- a/src/main/java/forge/gui/home/quest/CSubmenuQuestDecks.java +++ b/src/main/java/forge/gui/home/quest/CSubmenuQuestDecks.java @@ -5,9 +5,10 @@ import java.util.ArrayList; import forge.AllZone; import forge.Command; import forge.Singletons; +import forge.control.FControl; import forge.deck.Deck; -import forge.gui.SOverlayUtils; -import forge.gui.deckeditor.DeckEditorQuest; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.controllers.CEditorQuest; import forge.gui.home.EMenuItem; import forge.gui.home.ICSubmenu; import forge.gui.home.VHomeUI; @@ -26,15 +27,6 @@ public enum CSubmenuQuestDecks implements ICSubmenu { private Deck currentDeck; - private final Command cmdDeckExit = new Command() { - @Override - public void execute() { - AllZone.getQuest().save(); - SOverlayUtils.hideOverlay(); - update(); - } - }; - private final Command cmdDeckSelect = new Command() { @Override public void execute() { @@ -76,11 +68,8 @@ public enum CSubmenuQuestDecks implements ICSubmenu { VSubmenuQuestDecks.SINGLETON_INSTANCE.getBtnNewDeck().setCommand(new Command() { @Override public void execute() { - final DeckEditorQuest editor = - new DeckEditorQuest(Singletons.getView().getFrame(), AllZone.getQuest()); - editor.show(cmdDeckExit); - SOverlayUtils.showOverlay(); - editor.setVisible(true); + CDeckEditorUI.SINGLETON_INSTANCE.setCurrentEditorController(new CEditorQuest(AllZone.getQuest())); + FControl.SINGLETON_INSTANCE.changeState(FControl.DECK_EDITOR_QUEST); } }); } @@ -116,7 +105,6 @@ public enum CSubmenuQuestDecks implements ICSubmenu { view.getLstDecks().setSelectCommand(cmdDeckSelect); view.getLstDecks().setDeleteCommand(cmdDeckDelete); - view.getLstDecks().setExitCommand(cmdDeckExit); if (view.getLstDecks().getSelectedDeck() != null) { Singletons.getModel().getQuestPreferences().setPreference(QPref.CURRENT_DECK, view.getLstDecks().getSelectedDeck().getName()); diff --git a/src/main/java/forge/gui/home/quest/SubmenuQuestUtil.java b/src/main/java/forge/gui/home/quest/SSubmenuQuestUtil.java similarity index 93% rename from src/main/java/forge/gui/home/quest/SubmenuQuestUtil.java rename to src/main/java/forge/gui/home/quest/SSubmenuQuestUtil.java index 45337c82ad6..6e192c0d871 100644 --- a/src/main/java/forge/gui/home/quest/SubmenuQuestUtil.java +++ b/src/main/java/forge/gui/home/quest/SSubmenuQuestUtil.java @@ -20,7 +20,8 @@ import forge.deck.Deck; import forge.game.GameNew; import forge.game.GameType; import forge.gui.SOverlayUtils; -import forge.gui.deckeditor.QuestCardShop; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.controllers.CEditorQuestCardShop; import forge.gui.toolbox.FLabel; import forge.gui.toolbox.FPanel; import forge.gui.toolbox.FSkin; @@ -41,8 +42,10 @@ import forge.quest.data.QuestPreferences.QPref; /** * Utilities for the quest submenu, all over the MVC spectrum. * If a piece of code can be reused, it's dumped here. + * + *

(S at beginning of class name denotes a static factory.) */ -public class SubmenuQuestUtil { +public class SSubmenuQuestUtil { private static SelectablePanel selectedOpponent; /** @@ -140,7 +143,7 @@ public class SubmenuQuestUtil { view.getLblLosses().setText("Losses: " + qA.getLost()); view.updateCurrentDeckStatus(); - final int num = SubmenuQuestUtil.nextChallengeInWins(); + final int num = SSubmenuQuestUtil.nextChallengeInWins(); if (num == 0) { view.getLblNextChallengeInWins().setText("Next challenge available now."); } @@ -186,19 +189,10 @@ public class SubmenuQuestUtil { } /** */ - @SuppressWarnings("serial") public static void showSpellShop() { - final Command exit = new Command() { - @Override - public void execute() { - AllZone.getQuest().save(); - updateStatsAndPet(); - } - }; - - final QuestCardShop g = new QuestCardShop(Singletons.getView().getFrame(), AllZone.getQuest()); - g.show(exit); - g.setVisible(true); + CDeckEditorUI.SINGLETON_INSTANCE.setCurrentEditorController( + new CEditorQuestCardShop(AllZone.getQuest())); + FControl.SINGLETON_INSTANCE.changeState(FControl.DECK_EDITOR_QUEST); } /** */ @@ -223,7 +217,7 @@ public class SubmenuQuestUtil { final SwingWorker worker = new SwingWorker() { @Override public Object doInBackground() { - Constant.Runtime.HUMAN_DECK[0] = SubmenuQuestUtil.getCurrentDeck(); + Constant.Runtime.HUMAN_DECK[0] = SSubmenuQuestUtil.getCurrentDeck(); Constant.Runtime.COMPUTER_DECK[0] = event.getEventDeck(); Constant.Runtime.setGameType(GameType.Quest); @@ -255,7 +249,7 @@ public class SubmenuQuestUtil { event.getIconFilename()); } // End isFantasy else { - GameNew.newGame(SubmenuQuestUtil.getCurrentDeck(), event.getEventDeck()); + GameNew.newGame(SSubmenuQuestUtil.getCurrentDeck(), event.getEventDeck()); } return null; } @@ -297,7 +291,7 @@ public class SubmenuQuestUtil { VSubmenuChallenges.SINGLETON_INSTANCE.getBtnStart().setEnabled(true); } - selectedOpponent = SubmenuQuestUtil.SelectablePanel.this; + selectedOpponent = SSubmenuQuestUtil.SelectablePanel.this; } }); diff --git a/src/main/java/forge/gui/home/quest/VSubmenuChallenges.java b/src/main/java/forge/gui/home/quest/VSubmenuChallenges.java index 51088dbbec5..7a1e371b3b8 100644 --- a/src/main/java/forge/gui/home/quest/VSubmenuChallenges.java +++ b/src/main/java/forge/gui/home/quest/VSubmenuChallenges.java @@ -144,14 +144,14 @@ public enum VSubmenuChallenges implements IVSubmenu, IStatsAndPet { @Override public void updateCurrentDeckStatus() { final JLabel btnCurrentDeck = VSubmenuChallenges.SINGLETON_INSTANCE.getBtnCurrentDeck(); - if (SubmenuQuestUtil.getCurrentDeck() == null) { + if (SSubmenuQuestUtil.getCurrentDeck() == null) { btnCurrentDeck.setBackground(Color.red.darker()); btnCurrentDeck.setText(" Build, then select a deck in the \"Decks\" submenu. "); } else { btnCurrentDeck.setBackground(FSkin.getColor(FSkin.Colors.CLR_INACTIVE)); btnCurrentDeck.setText("Current deck: " - + SubmenuQuestUtil.getCurrentDeck().getName()); + + SSubmenuQuestUtil.getCurrentDeck().getName()); } } diff --git a/src/main/java/forge/gui/home/quest/VSubmenuDuels.java b/src/main/java/forge/gui/home/quest/VSubmenuDuels.java index 978cbfd39f8..f9959cda2ed 100644 --- a/src/main/java/forge/gui/home/quest/VSubmenuDuels.java +++ b/src/main/java/forge/gui/home/quest/VSubmenuDuels.java @@ -144,14 +144,14 @@ public enum VSubmenuDuels implements IVSubmenu, IStatsAndPet { @Override public void updateCurrentDeckStatus() { final JLabel btnCurrentDeck = VSubmenuDuels.SINGLETON_INSTANCE.getBtnCurrentDeck(); - if (SubmenuQuestUtil.getCurrentDeck() == null) { + if (SSubmenuQuestUtil.getCurrentDeck() == null) { btnCurrentDeck.setBackground(Color.red.darker()); btnCurrentDeck.setText(" Build, then select a deck in the \"Decks\" submenu. "); } else { btnCurrentDeck.setBackground(FSkin.getColor(FSkin.Colors.CLR_INACTIVE)); btnCurrentDeck.setText("Current deck: " - + SubmenuQuestUtil.getCurrentDeck().getName()); + + SSubmenuQuestUtil.getCurrentDeck().getName()); } } diff --git a/src/main/java/forge/gui/home/sanctioned/CSubmenuDraft.java b/src/main/java/forge/gui/home/sanctioned/CSubmenuDraft.java index a10b9e10460..4122a4bd4e7 100644 --- a/src/main/java/forge/gui/home/sanctioned/CSubmenuDraft.java +++ b/src/main/java/forge/gui/home/sanctioned/CSubmenuDraft.java @@ -13,6 +13,7 @@ import javax.swing.SwingWorker; import forge.Command; import forge.Constant; import forge.Singletons; +import forge.control.FControl; import forge.deck.Deck; import forge.deck.DeckGroup; import forge.game.GameNew; @@ -21,7 +22,8 @@ import forge.game.limited.BoosterDraft; import forge.game.limited.CardPoolLimitation; import forge.gui.GuiUtils; import forge.gui.SOverlayUtils; -import forge.gui.deckeditor.DraftingProcess; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.controllers.CEditorDraftingProcess; import forge.gui.home.ICSubmenu; import forge.gui.toolbox.FSkin; @@ -77,14 +79,6 @@ public enum CSubmenuDraft implements ICSubmenu { "Walter", "Wilfred", "William", "Winston" }; - private final Command cmdDeckExit = new Command() { - @Override - public void execute() { - update(); - SOverlayUtils.hideOverlay(); - } - }; - private final Command cmdDeckSelect = new Command() { @Override public void execute() { @@ -102,7 +96,6 @@ public enum CSubmenuDraft implements ICSubmenu { view.populate(); CSubmenuDraft.SINGLETON_INSTANCE.update(); - view.getLstHumanDecks().setExitCommand(cmdDeckExit); view.getLstHumanDecks().setSelectCommand(cmdDeckSelect); view.getBtnBuildDeck().addMouseListener( @@ -220,9 +213,7 @@ public enum CSubmenuDraft implements ICSubmenu { /** */ private void setupDraft() { - SOverlayUtils.showOverlay(); - - final DraftingProcess draft = new DraftingProcess(Singletons.getView().getFrame()); + final CEditorDraftingProcess draft = new CEditorDraftingProcess(); // Determine what kind of booster draft to run final ArrayList draftTypes = new ArrayList(); @@ -244,6 +235,9 @@ public enum CSubmenuDraft implements ICSubmenu { else if (o.toString().equals(draftTypes.get(2))) { draft.showGui(new BoosterDraft(CardPoolLimitation.Custom)); } + + CDeckEditorUI.SINGLETON_INSTANCE.setCurrentEditorController(draft); + FControl.SINGLETON_INSTANCE.changeState(FControl.DECK_EDITOR_LIMITED); } private String[] generateNames() { diff --git a/src/main/java/forge/gui/home/sanctioned/CSubmenuSealed.java b/src/main/java/forge/gui/home/sanctioned/CSubmenuSealed.java index 0e6cfe5b4a0..0d6f6640025 100644 --- a/src/main/java/forge/gui/home/sanctioned/CSubmenuSealed.java +++ b/src/main/java/forge/gui/home/sanctioned/CSubmenuSealed.java @@ -16,6 +16,7 @@ import org.apache.commons.lang3.StringUtils; import forge.Command; import forge.Constant; import forge.Singletons; +import forge.control.FControl; import forge.deck.Deck; import forge.deck.DeckBase; import forge.deck.DeckGroup; @@ -23,8 +24,9 @@ import forge.game.GameNew; import forge.game.limited.SealedDeck; import forge.gui.GuiUtils; import forge.gui.SOverlayUtils; -import forge.gui.deckeditor.DeckEditorBase; -import forge.gui.deckeditor.DeckEditorLimited; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.controllers.ACEditorBase; +import forge.gui.deckeditor.controllers.CEditorLimited; import forge.gui.home.ICSubmenu; import forge.gui.toolbox.FSkin; import forge.item.CardPrinted; @@ -46,14 +48,6 @@ public enum CSubmenuSealed implements ICSubmenu { private Map aiDecks; - private final Command cmdExit = new Command() { - @Override - public void execute() { - update(); - SOverlayUtils.hideOverlay(); - } - }; - private final Command cmdDeckSelect = new Command() { @Override public void execute() { @@ -71,7 +65,6 @@ public enum CSubmenuSealed implements ICSubmenu { view.populate(); CSubmenuSealed.SINGLETON_INSTANCE.update(); - VSubmenuSealed.SINGLETON_INSTANCE.getLstDecks().setExitCommand(cmdExit); VSubmenuSealed.SINGLETON_INSTANCE.getLstDecks().setSelectCommand(cmdDeckSelect); VSubmenuSealed.SINGLETON_INSTANCE.getBtnBuildDeck().addMouseListener( @@ -225,15 +218,13 @@ public enum CSubmenuSealed implements ICSubmenu { final DeckGroup sealed = new DeckGroup(sDeckName); sealed.setHumanDeck(deck); sealed.addAiDeck(sd.buildAIDeck(sDeck.toForgeCardList())); - Singletons.getModel().getDecks().getSealed().add(sealed); + Singletons.getModel().getDecks().getSealed().add(sealed); - final DeckEditorBase editor = (DeckEditorBase) new DeckEditorLimited( - Singletons.getView().getFrame(), + final ACEditorBase editor = (ACEditorBase) new CEditorLimited( Singletons.getModel().getDecks().getSealed()); - editor.show(cmdExit); - editor.getController().setModel((T) sealed); - editor.setAlwaysOnTop(true); - editor.setVisible(true); + CDeckEditorUI.SINGLETON_INSTANCE.setCurrentEditorController(editor); + FControl.SINGLETON_INSTANCE.changeState(FControl.DECK_EDITOR_LIMITED); + editor.getDeckController().setModel((T) sealed); } } diff --git a/src/main/java/forge/gui/home/utilities/CSubmenuDeckEditor.java b/src/main/java/forge/gui/home/utilities/CSubmenuDeckEditor.java index 0e3c35af824..492a0e9d8b8 100644 --- a/src/main/java/forge/gui/home/utilities/CSubmenuDeckEditor.java +++ b/src/main/java/forge/gui/home/utilities/CSubmenuDeckEditor.java @@ -1,10 +1,9 @@ package forge.gui.home.utilities; import forge.Command; -import forge.Singletons; -import forge.deck.DeckBase; -import forge.gui.deckeditor.DeckEditorBase; -import forge.gui.deckeditor.DeckEditorConstructed; +import forge.control.FControl; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.controllers.CEditorConstructed; import forge.gui.home.ICSubmenu; /** @@ -44,13 +43,9 @@ public enum CSubmenuDeckEditor implements ICSubmenu { /** * Shows constructed mode editor. - * @param extends DeckBase */ - @SuppressWarnings("unchecked") - private void showDeckEditor() { - DeckEditorBase editor = - (DeckEditorBase) new DeckEditorConstructed(Singletons.getView().getFrame()); - editor.show(null); - editor.setVisible(true); + private void showDeckEditor() { + CDeckEditorUI.SINGLETON_INSTANCE.setCurrentEditorController(new CEditorConstructed()); + FControl.SINGLETON_INSTANCE.changeState(FControl.DECK_EDITOR_CONSTRUCTED); } } diff --git a/src/main/java/forge/gui/match/VMatchUI.java b/src/main/java/forge/gui/match/VMatchUI.java index 95ee255085c..8e67b545dea 100644 --- a/src/main/java/forge/gui/match/VMatchUI.java +++ b/src/main/java/forge/gui/match/VMatchUI.java @@ -10,7 +10,7 @@ import forge.gui.framework.DragCell; import forge.gui.framework.EDocID; import forge.gui.framework.IVDoc; import forge.gui.framework.IVTopLevelUI; -import forge.gui.framework.SIOUtil; +import forge.gui.framework.SLayoutIO; import forge.gui.framework.SResizingUtil; import forge.gui.match.nonsingleton.VField; import forge.gui.match.nonsingleton.VHand; @@ -71,7 +71,7 @@ public enum VMatchUI implements IVTopLevelUI { if (isPopulated) { return; } else { isPopulated = true; } - SIOUtil.loadLayout(null); + SLayoutIO.loadLayout(null); } /** NEVER ACTUALLY CALLED; could be removed... */ diff --git a/src/main/java/forge/gui/match/controllers/CDock.java b/src/main/java/forge/gui/match/controllers/CDock.java index e54ed4109cd..a995809ab71 100644 --- a/src/main/java/forge/gui/match/controllers/CDock.java +++ b/src/main/java/forge/gui/match/controllers/CDock.java @@ -39,7 +39,7 @@ import forge.deck.Deck; import forge.gui.ForgeAction; import forge.gui.SOverlayUtils; import forge.gui.framework.ICDoc; -import forge.gui.framework.SIOUtil; +import forge.gui.framework.SLayoutIO; import forge.gui.match.views.VDock; import forge.gui.toolbox.SaveOpenDialog; import forge.gui.toolbox.SaveOpenDialog.Filetypes; @@ -76,7 +76,7 @@ public enum CDock implements ICDoc { final SwingWorker w = new SwingWorker() { @Override public Void doInBackground() { - SIOUtil.loadLayout(new File(SIOUtil.FILE_DEFAULT)); + SLayoutIO.loadLayout(null); SOverlayUtils.hideOverlay(); return null; } @@ -89,10 +89,10 @@ public enum CDock implements ICDoc { @Override public Void doInBackground() { final SaveOpenDialog dlgSave = new SaveOpenDialog(); - final File defFile = new File(SIOUtil.FILE_PREFERRED); + final File defFile = new File(SLayoutIO.getFilePreferred()); final File saveFile = dlgSave.SaveDialog(defFile, Filetypes.LAYOUT); if (saveFile != null) { - SIOUtil.saveLayout(saveFile); + SLayoutIO.saveLayout(saveFile); } return null; } @@ -108,12 +108,12 @@ public enum CDock implements ICDoc { @Override public Void doInBackground() { final SaveOpenDialog dlgOpen = new SaveOpenDialog(); - final File defFile = new File(SIOUtil.FILE_PREFERRED); + final File defFile = new File(SLayoutIO.getFilePreferred()); final File loadFile = dlgOpen.OpenDialog(defFile, Filetypes.LAYOUT); if (loadFile != null) { - SIOUtil.loadLayout(loadFile); - SIOUtil.saveLayout(null); + SLayoutIO.loadLayout(loadFile); + SLayoutIO.saveLayout(null); } SOverlayUtils.hideOverlay(); diff --git a/src/main/java/forge/gui/toolbox/DeckLister.java b/src/main/java/forge/gui/toolbox/DeckLister.java index 3b7d7115040..af48ece66d3 100644 --- a/src/main/java/forge/gui/toolbox/DeckLister.java +++ b/src/main/java/forge/gui/toolbox/DeckLister.java @@ -2,7 +2,9 @@ * Forge: Play Magic: the Gathering. * Copyright (C) 2011 Nate * - * This program is free software: you can redistribute it and/or modify + * This prog +import forge.gui.deckeditor.CDeckEditorUI; +ram 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. @@ -24,27 +26,31 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; + import javax.swing.ImageIcon; import javax.swing.JButton; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.SwingConstants; import javax.swing.border.MatteBorder; +import net.miginfocom.swing.MigLayout; import forge.AllZone; import forge.Command; import forge.Constant; import forge.Singletons; +import forge.control.FControl; import forge.deck.CardCollections; import forge.deck.Deck; +import forge.deck.DeckBase; import forge.game.GameType; -import forge.gui.SOverlayUtils; -import forge.gui.deckeditor.DeckEditorConstructed; -import forge.gui.deckeditor.DeckEditorLimited; -import forge.gui.deckeditor.DeckEditorQuest; -import net.miginfocom.swing.MigLayout; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.controllers.ACEditorBase; +import forge.gui.deckeditor.controllers.CEditorConstructed; +import forge.gui.deckeditor.controllers.CEditorLimited; +import forge.gui.deckeditor.controllers.CEditorQuest; +import forge.gui.framework.ILocalRepaint; /** * Creates deck list for selected decks for quick deleting, editing, and basic @@ -52,7 +58,7 @@ import net.miginfocom.swing.MigLayout; * */ @SuppressWarnings("serial") -public class DeckLister extends JPanel { +public class DeckLister extends JPanel implements ILocalRepaint { private final ImageIcon icoDelete; private final ImageIcon icoDeleteOver; private final ImageIcon icoEdit; @@ -60,7 +66,7 @@ public class DeckLister extends JPanel { private RowPanel previousSelect; private RowPanel[] rows; private final GameType gametype; - private Command cmdEditorExit, cmdDelete, cmdRowSelect; + private Command cmdDelete, cmdRowSelect; private final Color clrDefault, clrHover, clrActive, clrBorders; /** @@ -87,7 +93,6 @@ public class DeckLister extends JPanel { public DeckLister(final GameType gt0, final Command cmd0) { super(); this.gametype = gt0; - this.cmdEditorExit = cmd0; this.clrDefault = new Color(0, 0, 0, 0); this.clrHover = FSkin.getColor(FSkin.Colors.CLR_HOVER); @@ -118,18 +123,22 @@ public class DeckLister extends JPanel { // scroll panes will have difficulty dynamically resizing if 100% width // is set. final JPanel rowTitle = new TitlePanel(); - rowTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_ZEBRA)); + rowTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); rowTitle.setLayout(new MigLayout("insets 0, gap 0")); rowTitle.add(new FLabel.Builder().text("Delete").fontAlign(SwingConstants.CENTER).build(), "w 10%!, h 20px!, gaptop 5px"); - rowTitle.add(new FLabel.Builder().text("Edit").fontAlign(SwingConstants.CENTER).build(), + rowTitle.add(new FLabel.Builder().text("Edit") + .fontScaleAuto(false).fontSize(14).fontAlign(SwingConstants.CENTER).build(), "w 10%!, h 20px!, gaptop 5px"); - rowTitle.add(new FLabel.Builder().text("Deck Name").fontAlign(SwingConstants.CENTER).build(), - "w 60%!, h 20px!, gaptop 5px"); - rowTitle.add(new FLabel.Builder().text("Main").fontAlign(SwingConstants.CENTER).build(), + rowTitle.add(new FLabel.Builder().text("Deck Name") + .fontScaleAuto(false).fontSize(14).fontAlign(SwingConstants.CENTER).build(), + "w 58%!, h 20px!, gaptop 5px"); + rowTitle.add(new FLabel.Builder().text("Main") + .fontScaleAuto(false).fontSize(14).fontAlign(SwingConstants.CENTER).build(), "w 10%!, h 20px!, gaptop 5px"); - rowTitle.add(new FLabel.Builder().text("Side").fontAlign(SwingConstants.CENTER).build(), + rowTitle.add(new FLabel.Builder().text("Side") + .fontScaleAuto(false).fontSize(14).fontAlign(SwingConstants.CENTER).build(), "w 10%!, h 20px!, gaptop 5px"); this.add(rowTitle, "w 98%!, h 30px!, gapleft 1%"); @@ -142,7 +151,7 @@ public class DeckLister extends JPanel { row = new RowPanel(d); row.add(new DeleteButton(row), "w 10%!, h 20px!, gaptop 5px"); row.add(new EditButton(row), "w 10%!, h 20px!, gaptop 5px"); - row.add(new GenericLabel(d.getName()), "w 60%!, h 20px!, gaptop 5px"); + row.add(new GenericLabel(d.getName()), "w 58%!, h 20px!, gaptop 5px"); row.add(new MainLabel(String.valueOf(d.getMain().countAll())), "w 10%, h 20px!, gaptop 5px"); row.add(new GenericLabel(String.valueOf(d.getSideboard().countAll())), "w 10%!, h 20px!, gaptop 5px"); this.add(row, "w 98%!, h 30px!, gapleft 1%"); @@ -169,7 +178,8 @@ public class DeckLister extends JPanel { } /** Prevent panel from repainting the whole screen. */ - public void repaintOnlyThisPanel() { + @Override + public void repaintThis() { final Dimension d = DeckLister.this.getSize(); this.repaint(0, 0, d.width, d.height); } @@ -400,15 +410,6 @@ public class DeckLister extends JPanel { this.cmdRowSelect = c0; } - /** - * Sets the exit command. - * - * @param c0   {@link forge.Command} command executed on editor exit. - */ - public void setExitCommand(final Command c0) { - this.cmdEditorExit = c0; - } - private void selectHandler(final RowPanel r0) { if (this.previousSelect != null) { this.previousSelect.setSelected(false); @@ -420,41 +421,39 @@ public class DeckLister extends JPanel { this.cmdRowSelect.execute(); } } - - private void editDeck(final Deck d0) { - SOverlayUtils.showOverlay(); - - JFrame mainFrame = Singletons.getView().getFrame(); + @SuppressWarnings("unchecked") + private void editDeck(final Deck d0) { switch (this.gametype) { case Quest: - Constant.Runtime.HUMAN_DECK[0] = d0; - final DeckEditorQuest editor = new DeckEditorQuest(mainFrame, AllZone.getQuest()); - editor.show(this.cmdEditorExit); - editor.setVisible(true); - break; + Constant.Runtime.HUMAN_DECK[0] = d0; + final CEditorQuest qEditor = new CEditorQuest(AllZone.getQuest()); + CDeckEditorUI.SINGLETON_INSTANCE.setCurrentEditorController(qEditor); + FControl.SINGLETON_INSTANCE.changeState(FControl.DECK_EDITOR_QUEST); + break; case Constructed: - final DeckEditorConstructed cEditor = - new DeckEditorConstructed(mainFrame); - cEditor.show(this.cmdEditorExit); - cEditor.getController().load(d0.getName()); - cEditor.setVisible(true); - break; - case Sealed: - final DeckEditorLimited sEditor = - new DeckEditorLimited(mainFrame, Singletons.getModel().getDecks().getSealed()); - sEditor.show(this.cmdEditorExit); - sEditor.getController().load(d0.getName()); - sEditor.setVisible(true); - break; - case Draft: - final DeckEditorLimited dEditor = - new DeckEditorLimited(mainFrame, Singletons.getModel().getDecks().getDraft()); - dEditor.show(this.cmdEditorExit); - dEditor.getController().load(d0.getName()); - dEditor.setVisible(true); - break; - default: - break; + CDeckEditorUI.SINGLETON_INSTANCE.setCurrentEditorController(new CEditorConstructed()); + FControl.SINGLETON_INSTANCE.changeState(FControl.DECK_EDITOR_CONSTRUCTED); + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().getDeckController().load(d0.getName()); + break; + case Sealed: + final ACEditorBase sEditor = (ACEditorBase) + new CEditorLimited(Singletons.getModel().getDecks().getSealed()); + + CDeckEditorUI.SINGLETON_INSTANCE.setCurrentEditorController(sEditor); + + sEditor.getDeckController().load(d0.getName()); + FControl.SINGLETON_INSTANCE.changeState(FControl.DECK_EDITOR_LIMITED); + break; + case Draft: + final ACEditorBase dEditor = (ACEditorBase) + new CEditorLimited(Singletons.getModel().getDecks().getDraft()); + CDeckEditorUI.SINGLETON_INSTANCE.setCurrentEditorController(dEditor); + + dEditor.getDeckController().load(d0.getName()); + FControl.SINGLETON_INSTANCE.changeState(FControl.DECK_EDITOR_LIMITED); + break; + default: + break; } } @@ -482,7 +481,7 @@ public class DeckLister extends JPanel { } this.remove(r0); - this.repaintOnlyThisPanel(); + this.repaintThis(); this.revalidate(); if (this.cmdDelete != null) { diff --git a/src/main/java/forge/gui/toolbox/FLabel.java b/src/main/java/forge/gui/toolbox/FLabel.java index 3129295760a..90724d6c3ed 100644 --- a/src/main/java/forge/gui/toolbox/FLabel.java +++ b/src/main/java/forge/gui/toolbox/FLabel.java @@ -7,6 +7,7 @@ import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; +import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentAdapter; @@ -54,6 +55,8 @@ public class FLabel extends JLabel { private int bldFontStyle = Font.PLAIN; private int bldFontSize = 14; private float bldIconAlpha = 1.0f; + private int bldIconAlignX = SwingConstants.LEFT; + private Point bldIconInsets = new Point(0, 0); private boolean bldSelectable = false; private boolean bldHoverable = false; @@ -74,71 +77,81 @@ public class FLabel extends JLabel { // Begin builder methods. /**@param s0   {@link java.lang.String} * @return {@link forge.gui.toolbox.Builder} */ - public Builder text(String s0) { this.bldText = s0; return this; } + public Builder text(final String s0) { this.bldText = s0; return this; } /**@param s0   {@link java.lang.String} * @return {@link forge.gui.toolbox.Builder} */ - public Builder tooltip(String s0) { this.bldToolTip = s0; return this; } + public Builder tooltip(final String s0) { this.bldToolTip = s0; return this; } /**@param i0   {@link javax.swing.ImageIcon} * @return {@link forge.gui.toolbox.Builder} */ - public Builder icon(ImageIcon i0) { this.bldIcon = i0; return this; } + public Builder icon(final ImageIcon i0) { this.bldIcon = i0; return this; } /**@param i0   SwingConstants.CENTER, .LEFT, or .RIGHT * @return {@link forge.gui.toolbox.Builder} */ - public Builder fontAlign(int i0) { this.bldFontAlign = i0; return this; } + public Builder fontAlign(final int i0) { this.bldFontAlign = i0; return this; } /**@param b0   boolean * @return {@link forge.gui.toolbox.Builder} */ - public Builder opaque(boolean b0) { this.bldOpaque = b0; return this; } + public Builder opaque(final boolean b0) { this.bldOpaque = b0; return this; } /**@param b0   boolean * @return {@link forge.gui.toolbox.Builder} */ - public Builder hoverable(boolean b0) { this.bldHoverable = b0; return this; } + public Builder hoverable(final boolean b0) { this.bldHoverable = b0; return this; } /**@param b0   boolean * @return {@link forge.gui.toolbox.Builder} */ - public Builder selectable(boolean b0) { this.bldSelectable = b0; return this; } + public Builder selectable(final boolean b0) { this.bldSelectable = b0; return this; } /**@param c0   {@link forge.Command} to execute if clicked * @return {@link forge.gui.toolbox.Builder} */ - public Builder cmdClick(Command c0) { this.bldCmd = c0; return this; } + public Builder cmdClick(final Command c0) { this.bldCmd = c0; return this; } /**@param i0   int * @return {@link forge.gui.toolbox.Builder} */ - public Builder fontSize(int i0) { this.bldFontSize = i0; return this; } + public Builder fontSize(final int i0) { this.bldFontSize = i0; return this; } /**@param i0   Font.PLAIN, Font.BOLD, or Font.ITALIC * @return {@link forge.gui.toolbox.Builder} */ - public Builder fontStyle(int i0) { this.bldFontStyle = i0; return this; } + public Builder fontStyle(final int i0) { this.bldFontStyle = i0; return this; } /**@param b0   boolean * @return {@link forge.gui.toolbox.Builder} */ - public Builder fontScaleAuto(boolean b0) { this.bldFontScaleAuto = b0; return this; } + public Builder fontScaleAuto(final boolean b0) { this.bldFontScaleAuto = b0; return this; } /**@param d0   double between 0 and 1, 0.6 by default * @return {@link forge.gui.toolbox.Builder} */ - public Builder fontScaleFactor(double d0) { this.bldFontScaleFactor = d0; return this; } + public Builder fontScaleFactor(final double d0) { this.bldFontScaleFactor = d0; return this; } /**@param i0   SwingConstants.HORIZONTAL or .VERTICAL * @return {@link forge.gui.toolbox.Builder} */ - public Builder fontScaleBy(int i0) { this.bldFontScaleBy = i0; return this; } + public Builder fontScaleBy(final int i0) { this.bldFontScaleBy = i0; return this; } /**@param b0   boolean * @return {@link forge.gui.toolbox.Builder} */ - public Builder iconScaleAuto(boolean b0) { this.bldIconScaleAuto = b0; return this; } + public Builder iconScaleAuto(final boolean b0) { this.bldIconScaleAuto = b0; return this; } /**@param d0   double between 0 and 1, 0.8 by default * @return {@link forge.gui.toolbox.Builder} */ - public Builder iconScaleFactor(double d0) { this.bldIconScaleFactor = d0; return this; } + public Builder iconScaleFactor(final double d0) { this.bldIconScaleFactor = d0; return this; } /**@param b0   boolean, icon will be drawn independent of text * @return {@link forge.gui.toolbox.Builder} */ - public Builder iconInBackground(boolean b0) { this.bldIconInBackground = b0; return this; } + public Builder iconInBackground(final boolean b0) { this.bldIconInBackground = b0; return this; } /**@param f0   0.0f - 1.0f. If icon is in background, this alpha is applied. * @return {@link forge.gui.toolbox.Builder} */ - public Builder iconAlpha(float f0) { this.bldIconAlpha = f0; return this; } + public Builder iconAlpha(final float f0) { this.bldIconAlpha = f0; return this; } + + /**@param i0   Int. Only available for background icon. + * SwingConstants.HORIZONTAL .VERTICAL or .CENTER + * @return {@link forge.gui.toolbox.Builder} */ + public Builder iconAlignX(final int i0) { this.bldIconAlignX = i0; return this; } + + /**@param i0   Point. Only available for background icon. + * Additional padding to top left corner of icon, after alignX. + * @return {@link forge.gui.toolbox.Builder} */ + public Builder iconInsets(final Point i0) { this.bldIconInsets = i0; return this; } } //========== Constructors @@ -146,7 +159,7 @@ public class FLabel extends JLabel { protected FLabel() { } // Call this using FLabel.Builder()... - private FLabel(Builder b0) { + private FLabel(final Builder b0) { super(b0.bldText); // Init fields from builder @@ -158,6 +171,8 @@ public class FLabel extends JLabel { this.fontScaleAuto = b0.bldFontScaleAuto; this.iconScaleAuto = b0.bldIconScaleAuto; this.selectable = b0.bldSelectable; + this.iconAlignX = b0.bldIconAlignX; + this.iconInsets = b0.bldIconInsets; this.setFontScaleBy(b0.bldFontScaleBy); this.setFontStyle(b0.bldFontStyle); @@ -194,9 +209,10 @@ public class FLabel extends JLabel { // Custom properties, assigned either at realization (using builder) // or dynamically (using methods below). private double fontScaleFactor, iconScaleFactor; - private int fontScaleBy, fontStyle; + private int fontScaleBy, fontStyle, iconAlignX; private boolean selectable, selected, hoverable, hovered, opaque, iconInBackground, fontScaleAuto, iconScaleAuto; + private Point iconInsets; // Various variables used in image rendering. private Image img; @@ -209,30 +225,30 @@ public class FLabel extends JLabel { private final ActionListener fireResize = new ActionListener() { @Override - public void actionPerformed(ActionEvent evt) { resize(); resizeTimer.stop(); } + public void actionPerformed(final ActionEvent evt) { resize(); resizeTimer.stop(); } }; - private Timer resizeTimer = new Timer(10, fireResize); + private final Timer resizeTimer = new Timer(10, fireResize); // Resize adapter; on a timer to prevent resizing while "sliding" between sizes private final ComponentAdapter cadResize = new ComponentAdapter() { @Override - public void componentResized(ComponentEvent e) { resizeTimer.restart(); } + public void componentResized(final ComponentEvent e) { resizeTimer.restart(); } }; // Mouse event handler private final MouseAdapter madEvents = new MouseAdapter() { @Override - public void mouseEntered(MouseEvent e) { + public void mouseEntered(final MouseEvent e) { hovered = true; repaintOnlyThisLabel(); } @Override - public void mouseExited(MouseEvent e) { + public void mouseExited(final MouseEvent e) { hovered = false; repaintOnlyThisLabel(); } @Override - public void mouseClicked(MouseEvent e) { + public void mouseClicked(final MouseEvent e) { if (cmdClick != null && FLabel.this.isEnabled()) { cmdClick.execute(); } if (!selectable) { return; } if (selected) { setSelected(false); } @@ -243,7 +259,7 @@ public class FLabel extends JLabel { //========== Methods /** @param b0   boolean */ // Must be public. - public void setHoverable(boolean b0) { + public void setHoverable(final boolean b0) { this.hoverable = b0; if (!b0) { this.removeMouseListener(madEvents); } else { this.addMouseListener(madEvents); } @@ -251,7 +267,7 @@ public class FLabel extends JLabel { /** @param b0   boolean */ // Must be public. - public void setSelected(boolean b0) { + public void setSelected(final boolean b0) { this.selected = b0; repaintOnlyThisLabel(); } @@ -259,14 +275,14 @@ public class FLabel extends JLabel { /** Sets alpha if icon is in background. * @param f0   float */ // NOT public; must be set when label is built. - private void setIconAlpha(float f0) { + private void setIconAlpha(final float f0) { this.alphaDim = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, f0); this.alphaStrong = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f); } /** @param i0   int, must be SwingConstants.HORIZONTAL or VERTICAL */ // NOT public; must be set when label is built. - private void setFontScaleBy(int i0) { + private void setFontScaleBy(final int i0) { if (i0 != SwingConstants.HORIZONTAL && i0 != SwingConstants.VERTICAL) { throw new IllegalArgumentException("FLabel$setScaleBy " + "must be passed either SwingConstants.HORIZONTAL " @@ -276,7 +292,7 @@ public class FLabel extends JLabel { this.fontScaleBy = i0; } - private void setFontSize(int i0) { + private void setFontSize(final int i0) { switch(this.fontStyle) { case Font.BOLD: this.setFont(FSkin.getBoldFont(i0)); break; case Font.ITALIC: this.setFont(FSkin.getItalicFont(i0)); break; @@ -286,7 +302,7 @@ public class FLabel extends JLabel { /** @param i0   Font.PLAIN, .BOLD, or .ITALIC */ // NOT public; must be set when label is built. - private void setFontStyle(int i0) { + private void setFontStyle(final int i0) { if (i0 != Font.PLAIN && i0 != Font.BOLD && i0 != Font.ITALIC) { throw new IllegalArgumentException("FLabel$setFontStyle " + "must be passed either Font.PLAIN, Font.BOLD, or Font.ITALIC."); @@ -296,7 +312,7 @@ public class FLabel extends JLabel { /** @param i0   SwingConstants.CENTER, .LEFT or .RIGHT */ // NOT public; must be set when label is built. - private void setFontAlign(int i0) { + private void setFontAlign(final int i0) { if (i0 != SwingConstants.CENTER && i0 != SwingConstants.LEFT && i0 != SwingConstants.RIGHT) { throw new IllegalArgumentException("FLabel$setFontStyle " + "must be passed either SwingConstants.CENTER, " @@ -345,7 +361,7 @@ public class FLabel extends JLabel { } /** @param c0   {@link forge.Command} on click */ - public void setCommand(Command c0) { + public void setCommand(final Command c0) { this.cmdClick = c0; } @@ -363,7 +379,7 @@ public class FLabel extends JLabel { } @Override - public void paintComponent(Graphics g) { + public void paintComponent(final Graphics g) { g2d = (Graphics2D) g.create(); w = getWidth(); h = getHeight(); @@ -388,10 +404,16 @@ public class FLabel extends JLabel { // Icon in background if (iconInBackground) { - x = 3; - sh = (int) ((h - 2 * x) * iconScaleFactor); + sh = (int) (h * iconScaleFactor); sw = (int) (sh * iar); - y = (int) ((h - sh) / 2); + + if (iconAlignX == SwingConstants.CENTER) { + x = (int) ((w - sw) / 2 + iconInsets.getX()); + } + else { + x = (int) iconInsets.getX(); + } + y = (int) (((h - sh) / 2) + iconInsets.getY()); if (hoverable && hovered && !selected) { g2d.setComposite(alphaStrong); @@ -423,7 +445,7 @@ public class FLabel extends JLabel { // Non-background icon if (img != null && iconScaleAuto && !iconInBackground) { h = (int) (getHeight() * iconScaleFactor); - w = (int) (h * iar * iconScaleFactor); + w = (int) (h * iar); if (w == 0 || h == 0) { return; } FLabel.super.setIcon(new ImageIcon(img.getScaledInstance(w, h, Image.SCALE_SMOOTH))); diff --git a/src/main/java/forge/gui/toolbox/FSkin.java b/src/main/java/forge/gui/toolbox/FSkin.java index 2d5ec0dbdb1..c3feb9e69d4 100644 --- a/src/main/java/forge/gui/toolbox/FSkin.java +++ b/src/main/java/forge/gui/toolbox/FSkin.java @@ -214,8 +214,8 @@ public enum FSkin { ICO_ENDTURN (new int[] {320, 640, 80, 80}), /** */ ICO_CONCEDE (new int[] {240, 640, 80, 80}), /** */ ICO_REVERTLAYOUT (new int[] {400, 720, 80, 80}), /** */ - ICO_OPENLAYOUT (new int[] {480, 640, 80, 80}), - ICO_SAVELAYOUT (new int[] {480, 720, 80, 80}), + ICO_OPENLAYOUT (new int[] {480, 640, 80, 80}), /** */ + ICO_SAVELAYOUT (new int[] {480, 720, 80, 80}), /** */ ICO_DECKLIST (new int[] {400, 640, 80, 80}); private int[] coords; @@ -258,10 +258,16 @@ public enum FSkin { /** */ public enum ForgeIcons implements SkinProp { /** */ - ICO_EDIT (new int[] {640, 500, 20, 20}), /** */ - ICO_EDIT_OVER (new int[] {660, 500, 20, 20}), /** */ ICO_DELETE (new int[] {640, 480, 20, 20}), /** */ ICO_DELETE_OVER (new int[] {660, 480, 20, 20}), /** */ + ICO_EDIT (new int[] {640, 500, 20, 20}), /** */ + ICO_EDIT_OVER (new int[] {660, 500, 20, 20}), /** */ + ICO_OPEN (new int[] {660, 520, 20, 20}), /** */ + ICO_MINUS (new int[] {660, 620, 20, 20}), /** */ + ICO_NEW (new int[] {660, 540, 20, 20}), /** */ + ICO_PLUS (new int[] {660, 600, 20, 20}), /** */ + ICO_SAVE (new int[] {660, 560, 20, 20}), /** */ + ICO_SAVEAS (new int[] {660, 580, 20, 20}), /** */ ICO_UNKNOWN (new int[] {80, 720, 80, 80}), /** */ ICO_LOGO (new int[] {480, 0, 200, 200}), /** */ ICO_DEFAULT_MAGE (new int[] {0, 720, 80, 80}), /** */ @@ -277,11 +283,11 @@ public enum FSkin { /** */ public enum LayoutImages implements SkinProp { /** */ IMG_HANDLE (new int[] {320, 450, 80, 20}), /** */ - IMG_CUR_L (new int[] {644, 524, 32, 32}), /** */ - IMG_CUR_R (new int[] {644, 564, 32, 32}), /** */ - IMG_CUR_T (new int[] {644, 604, 32, 32}), /** */ - IMG_CUR_B (new int[] {644, 644, 32, 32}), /** */ - IMG_CUR_TAB (new int[] {644, 684, 32, 32}); + IMG_CUR_L (new int[] {564, 724, 32, 32}), /** */ + IMG_CUR_R (new int[] {564, 764, 32, 32}), /** */ + IMG_CUR_T (new int[] {604, 724, 32, 32}), /** */ + IMG_CUR_B (new int[] {604, 764, 32, 32}), /** */ + IMG_CUR_TAB (new int[] {644, 764, 32, 32}); private int[] coords; /** @param xy   int[] coordinates */ @@ -290,6 +296,24 @@ public enum FSkin { public int[] getCoords() { return coords; } } + /** */ + public enum EditorImages implements SkinProp { /** */ + IMG_ARTIFACT (new int[] {280, 720, 40, 40}), /** */ + IMG_CREATURE (new int[] {240, 720, 40, 40}), /** */ + IMG_ENCHANTMENT (new int[] {320, 720, 40, 40}), /** */ + IMG_INSTANT (new int[] {360, 720, 40, 40}), /** */ + IMG_LAND (new int[] {120, 720, 40, 40}), /** */ + IMG_MULTI (new int[] {80, 720, 40, 40}), /** */ + IMG_PLANESWALKER (new int[] {200, 720, 40, 40}), /** */ + IMG_SORCERY (new int[] {160, 720, 40, 40}); + + private int[] coords; + /** @param xy   int[] coordinates */ + EditorImages(final int[] xy) { this.coords = xy; } + /** @return int[] */ + public int[] getCoords() { return coords; } + } + /** */ public enum ButtonImages implements SkinProp { /** */ IMG_BTN_START_UP (new int[] {480, 200, 160, 80}), /** */ @@ -504,6 +528,7 @@ public enum FSkin { for (final ButtonImages e : ButtonImages.values()) { FSkin.setIcon(e); } for (final QuestIcons e : QuestIcons.values()) { FSkin.setIcon(e); } + for (final EditorImages e : EditorImages.values()) { FSkin.setImage(e); } for (final ManaImages e : ManaImages.values()) { FSkin.setImage(e); } for (final ColorlessManaImages e : ColorlessManaImages.values()) { FSkin.setImage(e); } for (final GameplayImages e : GameplayImages.values()) { FSkin.setImage(e); } @@ -515,6 +540,9 @@ public enum FSkin { // Assemble avatar images FSkin.assembleAvatars(); + // Table zebra striping + UIManager.put("Table.alternateRowColor", new Color(240, 240, 240)); + // Images loaded; can start UI init. SwingUtilities.invokeLater(new Runnable() { @Override diff --git a/src/main/java/forge/gui/toolbox/FTextArea.java b/src/main/java/forge/gui/toolbox/FTextArea.java index aca88632543..64f230bbb00 100644 --- a/src/main/java/forge/gui/toolbox/FTextArea.java +++ b/src/main/java/forge/gui/toolbox/FTextArea.java @@ -12,6 +12,7 @@ public class FTextArea extends JTextArea { public FTextArea() { super(); this.setForeground(FSkin.getColor(FSkin.Colors.CLR_TEXT)); + this.setCaretColor(FSkin.getColor(FSkin.Colors.CLR_TEXT)); this.setOpaque(false); this.setWrapStyleWord(true); this.setLineWrap(true); diff --git a/src/main/java/forge/gui/toolbox/FTextField.java b/src/main/java/forge/gui/toolbox/FTextField.java new file mode 100644 index 00000000000..1228bd0d554 --- /dev/null +++ b/src/main/java/forge/gui/toolbox/FTextField.java @@ -0,0 +1,20 @@ +package forge.gui.toolbox; + +import javax.swing.JTextField; + +/** + * A custom instance of JTextArea using Forge skin properties. + * + */ +@SuppressWarnings("serial") +public class FTextField extends JTextField { + /** */ + public FTextField() { + super(); + this.setForeground(FSkin.getColor(FSkin.Colors.CLR_TEXT)); + this.setCaretColor(FSkin.getColor(FSkin.Colors.CLR_TEXT)); + this.setOpaque(false); + this.setFocusable(false); + this.setEditable(false); + } +} diff --git a/src/main/java/forge/item/CardPrinted.java b/src/main/java/forge/item/CardPrinted.java index e7e03cf2502..425e0f05671 100644 --- a/src/main/java/forge/item/CardPrinted.java +++ b/src/main/java/forge/item/CardPrinted.java @@ -36,9 +36,10 @@ import forge.util.closures.Predicate; import forge.util.closures.PredicateString; /** - *

- * CardReference class. - *

+ * A viciously lightweight version of a card, for instances + * where a full set of meta and rules is not needed. + *

+ * The full set of rules is in the CardRules class. * * @author Forge * @version $Id: CardReference.java 9708 2011-08-09 19:34:12Z jendave $ @@ -164,8 +165,10 @@ public final class CardPrinted implements Comparable, InventoryItem return this.card.getType().toString(); } - // Lambda to get rules for selects from list of printed cards - /** The Constant fnGetRules. */ + /** + * Lambda to get rules for selects from list of printed cards. + * + */ public static final Lambda1 FN_GET_RULES = new Lambda1() { @Override public CardRules apply(final CardPrinted from) { diff --git a/src/main/java/forge/item/ItemPool.java b/src/main/java/forge/item/ItemPool.java index f7ba8d3271e..3a90bf2e643 100644 --- a/src/main/java/forge/item/ItemPool.java +++ b/src/main/java/forge/item/ItemPool.java @@ -227,6 +227,11 @@ public class ItemPool extends ItemPoolView { // need not set out-of-sync: either remove did set, or nothing was removed } + /** + * + * TODO: Write javadoc for this method. + * @param flat Iterable + */ public void removeAllFlat(final Iterable flat) { for (final T e : flat) { this.remove(e); diff --git a/src/main/java/forge/model/FModel.java b/src/main/java/forge/model/FModel.java index 1d7e6b15a4b..b660f262695 100644 --- a/src/main/java/forge/model/FModel.java +++ b/src/main/java/forge/model/FModel.java @@ -419,7 +419,7 @@ public enum FModel { fp.setPref(FPref.PHASE_HUMAN_EOT, String.valueOf(fieldViews.get(1).getLblEndTurn().getEnabled())); fp.setPref(FPref.PHASE_HUMAN_CLEANUP, String.valueOf(fieldViews.get(1).getLblCleanup().getEnabled())); - final VDev v = VMatchUI.SINGLETON_INSTANCE.getViewDevMode(); + final VDev v = VDev.SINGLETON_INSTANCE; Constant.Runtime.MILL[0] = v.getLblMilling().getEnabled(); fp.setPref(FPref.DEV_MILLING_LOSS, String.valueOf(Constant.Runtime.MILL[0])); diff --git a/src/main/java/forge/properties/NewConstants.java b/src/main/java/forge/properties/NewConstants.java index 5d6954cfc08..b0f09dfa2b4 100644 --- a/src/main/java/forge/properties/NewConstants.java +++ b/src/main/java/forge/properties/NewConstants.java @@ -43,8 +43,13 @@ public final class NewConstants { /** Constant CARDFORGE_URL = "program/cardforgeURL". */ public static final String CARDFORGE_URL = "program/cardforgeURL"; - /** Constant CARDFORGE_URL = "program/cardforgeURL". */ + /** Constant PREFERENCE_FILE = "forge.preferences". */ public static final String PREFERENCE_FILE = "forge.preferences"; + /** Constant PREFERENCE_FILE = "forge.preferences". */ + public static final String PREFERENCES_FILE_EDITOR = "editor.preferences"; + + /** Constant LAYOUT_DIR = "res/layouts/". */ + public static final String LAYOUT_DIR = "res/layouts/"; /** Constant DECKS="decks". */ public static final String DECKS = "decks"; @@ -60,6 +65,7 @@ public final class NewConstants { /** Constant CARD_PICTURES_A="card-pictures_a". */ public static final class CardPicturesByLetter { + /** */ public static final String CARD_PICTURES_A = "card-pictures_a"; /** Constant CARD_PICTURES_B="card-pictures_b". */ public static final String CARD_PICTURES_B = "card-pictures_b"; @@ -112,22 +118,15 @@ public final class NewConstants { /** Constant CARD_PICTURES_Z="card-pictures_z". */ public static final String CARD_PICTURES_Z = "card-pictures_z"; } - /** Constant CARD_PICTURES_OTHER="card-pictures_other". */ - public static final String CARD_PICTURES_OTHER = "card-pictures_other"; - /** Constant CARD_PICTURES_TOKEN_HQ="card-pictures_token_hq". */ - public static final String CARD_PICTURES_TOKEN_HQ = "card-pictures_token_hq"; + /** Constant TOKEN_IMAGES="token-images". */ public static final String TOKEN_IMAGES = "token-images"; - /** Constant CARDS="cards". */ - public static final String CARDS = "cards"; /** Constant CARDSFOLDER="cardsfolder". */ public static final String CARDSFOLDER = "cardsfolder"; /** Constant REMOVED="removed-cards". */ public static final String REMOVED = "removed-cards"; /** Constant NAME_MUTATOR="name-mutator". */ public static final String NAME_MUTATOR = "name-mutator"; - /** Constant BOOSTERDATA="boosterdata". */ - public static final String BOOSTERDATA = "boosterdata"; /** The file name of the image for face down cards on the battlefield. */ public static final String MORPH_IMAGE_FILE_NAME = "morph"; @@ -143,12 +142,10 @@ public final class NewConstants { public static final String IMAGE_TOKEN = "image/token"; /** Constant IMAGE_ICON="image/icon". */ public static final String IMAGE_ICON = "image/icon"; + /** Constant IMAGE_SEALED_PRODUCT="image/product". */ public static final String IMAGE_SEALED_PRODUCT = "image/product"; /** Constant PICS_BOOSTER_IMAGES="pics/booster/images". */ public static final String PICS_BOOSTER_IMAGES = "pics/booster/images"; - /** Constant SOUND_BASE="sound/base". */ - public static final String SOUND_BASE = "sound/base"; - /** * These properties are for a regular game. @@ -199,6 +196,7 @@ public final class NewConstants { /** The DECKS. */ public static final String DUELS = "quest/duels-dir"; + /** */ public static final String CHALLENGES = "quest/challenges-dir"; /** The XMLDATA. */ @@ -222,38 +220,12 @@ public final class NewConstants { /** */ public static final String PRECONS = "quest/precons-dir"; + /** */ public static final String BAZAAR = "quest/bazaar"; + /** */ public static final String BAZAAR_DIR = "quest/bazaar-dir"; } - /** - * These are GUI-related properties. - */ - public static class Gui { - - /** - * The Interface GuiDisplay. - */ - public static class GuiDisplay { - - /** The LAYOUT. */ - public static final String LAYOUT = "gui/Display"; - - /** The LAYOUT_NEW. */ - public static final String LAYOUT_NEW = "gui/Display/new"; - } - - /** - * The Interface GuiDeckEditor. - */ - public static class GuiDeckEditor { - - /** The LAYOUT. */ - public static final String LAYOUT = "gui/DeckEditor"; - - } - } - /** * These are localization properties. */ diff --git a/src/main/java/forge/quest/QuestUtilCards.java b/src/main/java/forge/quest/QuestUtilCards.java index ccf9a600297..e53ae18e44e 100644 --- a/src/main/java/forge/quest/QuestUtilCards.java +++ b/src/main/java/forge/quest/QuestUtilCards.java @@ -279,7 +279,7 @@ public final class QuestUtilCards { * * @return the sell mutliplier */ - public double getSellMutliplier() { + public double getSellMultiplier() { double multi = 0.20 + (0.001 * this.qc.getAchievements().getWin()); if (multi > 0.6) { multi = 0.6; diff --git a/src/main/java/forge/util/closures/Predicate.java b/src/main/java/forge/util/closures/Predicate.java index 9126cf68c3b..caf4971be01 100644 --- a/src/main/java/forge/util/closures/Predicate.java +++ b/src/main/java/forge/util/closures/Predicate.java @@ -26,7 +26,7 @@ import java.util.Map; /** * Predicate class allows to select items or type , which are or contain an * object of type , matching to some criteria set by predicate. No need to - * write that simple operations by hand. + * write that simple operation by hand. * * PS: com.google.common.base.Predicates contains almost the same functionality, * except for they keep filtering, transformations aside from the predicate in @@ -58,7 +58,9 @@ public abstract class Predicate { NOR, /** The NAND. */ NAND, + /** */ GT, + /** */ LT } @@ -84,9 +86,8 @@ public abstract class Predicate { LT_OR_EQUAL } - // This is the main method, predicates were made for. /** - * Checks if is true. + * This is the main method, predicates were made for. * * @param subject * the subject @@ -94,11 +95,10 @@ public abstract class Predicate { */ public abstract boolean isTrue(T subject); - // These are checks against constants, they will let build simpler - // expressions // Overloaded only in LeafConstant /** - * Checks if is 1. + * These are checks against constants, they will let simpler + * expressions be built. * * @return true, if is 1 */ @@ -675,7 +675,8 @@ public abstract class Predicate { // Static builder methods - they choose concrete implementation by // themselves /** - * Brigde. + * Brigde (transforms a predicate of type T into a predicate + * of type U, using a bridge function passed as an argument). * * @param * the generic type @@ -708,19 +709,6 @@ public abstract class Predicate { return new BridgeToInstance(predicate, clsTarget); } - /** - * Not. - * - * @param - * the generic type - * @param operand1 - * the operand1 - * @return the predicate - */ - public static Predicate not(final Predicate operand1) { - return new Not(operand1); - } - /** * Compose. * @@ -842,6 +830,32 @@ public abstract class Predicate { return new NodeOrBridged(operand1, operand2, bridge); } + /** + * Not. + * + * @param + * the generic type + * @param operand1 + * the operand1 + * @return the predicate + */ + public static Predicate not(final Predicate operand1) { + return new Not(operand1); + } + + /** + * Not. + * + * @param + * the generic type + * @param operand + * the operand + * @return the predicate + */ + public static Predicate not(final Iterable> operand) { + return new MultiNodeNot(operand); + } + /** * Gets the true. * @@ -1252,6 +1266,35 @@ final class MultiNodeOr extends MultiNode { } } + +/** + * + * TODO: Write javadoc for this type. + * + * @param + */ +final class MultiNodeNot extends MultiNode { + /** + * + * TODO: Write javadoc for Constructor. + * @param filters Iterable> + */ + public MultiNodeNot(final Iterable> filters) { + super(filters); + } + + @Override + public boolean isTrue(final T subject) { + for (final Predicate p : this.getOperands()) { + if (!p.isTrue(subject)) { + return true; + } + } + return false; + } +} + + /** * * TODO: Write javadoc for this type. diff --git a/src/main/java/forge/util/closures/PredicateInteger.java b/src/main/java/forge/util/closures/PredicateInteger.java new file mode 100644 index 00000000000..09278cb7896 --- /dev/null +++ b/src/main/java/forge/util/closures/PredicateInteger.java @@ -0,0 +1,75 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 MaxMtg + * + * 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 . + */ +package forge.util.closures; + +/** + * Special predicate class to perform integer operations. + * + * @param + * the generic type + */ +public abstract class PredicateInteger extends Predicate { + + /** The operator. */ + private final ComparableOp operator; + + /** + * Op. + * + * @param op1 + * the op1 + * @param op2 + * the op2 + * @return true, if successful + */ + protected final boolean op(final int op1, final int op2) { + switch (this.getOperator()) { + case GREATER_THAN: + return op1 > op2; + case LESS_THAN: + return op1 < op2; + case GT_OR_EQUAL: + return op1 >= op2; + case LT_OR_EQUAL: + return op1 <= op2; + case EQUALS: + return op1 == op2; + case NOT_EQUALS: + return op1 != op2; + default: + return false; + } + } + + /** + * Instantiates a new integer predicate. + * + * @param operator + * the operator + */ + public PredicateInteger(final ComparableOp operator) { + this.operator = operator; + } + + /** + * @return the operator + */ + public ComparableOp getOperator() { + return operator; + } +} diff --git a/src/main/java/forge/view/FView.java b/src/main/java/forge/view/FView.java index 0b11d767f21..b667c98ebb8 100644 --- a/src/main/java/forge/view/FView.java +++ b/src/main/java/forge/view/FView.java @@ -19,11 +19,10 @@ import net.miginfocom.swing.MigLayout; import forge.AllZone; import forge.Singletons; import forge.control.FControl; +import forge.gui.deckeditor.VDeckEditorUI; import forge.gui.framework.DragCell; import forge.gui.framework.EDocID; import forge.gui.framework.SLayoutConstants; -import forge.gui.framework.SOverflowUtil; -import forge.gui.framework.SResizingUtil; import forge.gui.home.VHomeUI; import forge.gui.match.VMatchUI; import forge.gui.toolbox.FOverlay; @@ -38,7 +37,6 @@ public enum FView { private SplashFrame splash; // Non-singleton instances (deprecated, but not updated yet) - private ViewEditorUI editor = null; private ViewBazaarUI bazaar = null; // Top-level UI components; all have getters. @@ -63,7 +61,6 @@ public enum FView { /** */ public void initialize() { SplashFrame.PROGRESS_BAR.setDescription("Creating display components."); - Singletons.getView().cacheUIStates(); // Frame styling frmDocument.setMinimumSize(new Dimension(800, 600)); @@ -91,10 +88,12 @@ public enum FView { FOverlay.SINGLETON_INSTANCE.getPanel().setBackground(FSkin.getColor(FSkin.Colors.CLR_OVERLAY)); - // Populate all drag tabs. After they are realized, - // their controller can initialize actions on their components. + // Populate all drag tab components. + this.cacheUIStates(); + + // Initialize actions on all drag tab components (which should + // be realized / populated already). for (EDocID doc : EDocID.values()) { - if (doc.getDoc().getControl() == null) { continue; } doc.getDoc().getControl().initialize(); } @@ -105,11 +104,6 @@ public enum FView { FView.this.splash = null; frmDocument.setVisible(true); - - // TODO MOVE TO CONTROL! - // TODO delete FViewOld - lpnDocument.addMouseListener(SOverflowUtil.getHideOverflowListener()); - lpnDocument.addComponentListener(SResizingUtil.getWindowResizeListener()); } /** @return {@link javax.swing.JFrame} */ @@ -190,15 +184,6 @@ public enum FView { } } - /** @return {@link forge.view.ViewEditorUI} */ - public ViewEditorUI getViewEditor() { - if (Singletons.getControl().getState() != FControl.DEFAULT_EDITOR) { - throw new IllegalArgumentException("FView$getViewEditor\n" - + "may only be called while the editor UI is showing."); - } - return FView.this.editor; - } - /** @return {@link forge.view.ViewBazaarUI} */ public ViewBazaarUI getViewBazaar() { if (Singletons.getControl().getState() != FControl.QUEST_BAZAAR) { @@ -210,9 +195,9 @@ public enum FView { /** */ private void cacheUIStates() { - FView.this.editor = new ViewEditorUI(); FView.this.bazaar = new ViewBazaarUI(AllZone.getQuest().getBazaar()); VMatchUI.SINGLETON_INSTANCE.instantiate(); VHomeUI.SINGLETON_INSTANCE.instantiate(); + VDeckEditorUI.SINGLETON_INSTANCE.instantiate(); } }