From 035976d165979407becdd04e6f25db329f5ee58d Mon Sep 17 00:00:00 2001 From: Grimm Date: Mon, 18 Oct 2021 20:11:06 +0200 Subject: [PATCH] - Removed copy of libgdx gui - added shaders to adventure module - changed build order to build adventure module before desktop to pack it in the same zip but not add it as dependency - adjusted mobile gui module to support adventure module. --- forge-adventure/pom.xml | 20 + forge-adventure/shaders/grayscale.frag | 15 + forge-adventure/shaders/grayscale.vert | 14 + forge-adventure/shaders/outline.frag | 40 + forge-adventure/shaders/outline.vert | 16 + forge-adventure/shaders/underwater.frag | 23 + forge-adventure/shaders/warp.frag | 57 + .../AdventureApplicationAdapter.java | 2 +- .../src/main/java/forge/adventure/Main.java | 21 +- .../adventure/libgdxgui/CachedCardImage.java | 45 - .../java/forge/adventure/libgdxgui/Forge.java | 920 -------- .../forge/adventure/libgdxgui/FrameRate.java | 62 - .../forge/adventure/libgdxgui/Graphics.java | 887 -------- .../forge/adventure/libgdxgui/GuiMobile.java | 329 --- .../libgdxgui/animation/AbilityEffect.java | 37 - .../libgdxgui/animation/ForgeAnimation.java | 69 - .../libgdxgui/animation/ForgeTransition.java | 101 - .../libgdxgui/animation/GifAnimation.java | 40 - .../libgdxgui/animation/GifDecoder.java | 737 ------- .../libgdxgui/assets/AssetsDownloader.java | 179 -- .../libgdxgui/assets/BitmapFontWriter.java | 391 ---- .../libgdxgui/assets/FBufferedImage.java | 99 - .../libgdxgui/assets/FDelayLoadImage.java | 48 - .../adventure/libgdxgui/assets/FImage.java | 10 - .../libgdxgui/assets/FImageComplex.java | 9 - .../adventure/libgdxgui/assets/FLanguage.java | 42 - .../libgdxgui/assets/FRotatedImage.java | 60 - .../adventure/libgdxgui/assets/FSkin.java | 475 ----- .../libgdxgui/assets/FSkinBorder.java | 29 - .../libgdxgui/assets/FSkinColor.java | 268 --- .../adventure/libgdxgui/assets/FSkinFont.java | 476 ----- .../libgdxgui/assets/FSkinImage.java | 575 ----- .../libgdxgui/assets/FSkinTexture.java | 190 -- .../libgdxgui/assets/FTextureImage.java | 42 - .../libgdxgui/assets/FTextureRegionImage.java | 43 - .../libgdxgui/assets/ImageCache.java | 337 --- .../libgdxgui/assets/ImageLoader.java | 163 -- .../libgdxgui/assets/OtherImageLoader.java | 34 - .../libgdxgui/assets/TextRenderer.java | 649 ------ .../libgdxgui/card/CardAvatarImage.java | 60 - .../libgdxgui/card/CardFaceSymbols.java | 248 --- .../adventure/libgdxgui/card/CardImage.java | 64 - .../libgdxgui/card/CardImageRenderer.java | 587 ----- .../libgdxgui/card/CardListPreview.java | 51 - .../libgdxgui/card/CardRenderer.java | 1271 ----------- .../adventure/libgdxgui/card/CardZoom.java | 384 ---- .../libgdxgui/card/ColorSetImage.java | 38 - .../libgdxgui/card/GameEntityPicker.java | 135 -- .../libgdxgui/deck/AddBasicLandsDialog.java | 424 ---- .../libgdxgui/deck/FDeckChooser.java | 1475 ------------- .../adventure/libgdxgui/deck/FDeckEditor.java | 1887 ----------------- .../libgdxgui/deck/FDeckImportDialog.java | 184 -- .../adventure/libgdxgui/deck/FDeckViewer.java | 175 -- .../libgdxgui/deck/FSideboardDialog.java | 211 -- .../libgdxgui/deck/FVanguardChooser.java | 111 - .../libgdxgui/error/BugReportDialog.java | 158 -- .../libgdxgui/itemmanager/CardManager.java | 92 - .../libgdxgui/itemmanager/DeckManager.java | 181 -- .../libgdxgui/itemmanager/ItemManager.java | 984 --------- .../itemmanager/SpellShopManager.java | 121 -- .../filters/AdvancedSearchFilter.java | 328 --- .../itemmanager/filters/CardCMCFilter.java | 34 - .../itemmanager/filters/CardColorFilter.java | 35 - .../filters/CardColorlessCostFilter.java | 34 - .../itemmanager/filters/CardFormatFilter.java | 31 - .../itemmanager/filters/CardPowerFilter.java | 35 - .../itemmanager/filters/CardRarityFilter.java | 37 - .../itemmanager/filters/CardSearchFilter.java | 49 - .../filters/CardToughnessFilter.java | 35 - .../itemmanager/filters/CardTypeFilter.java | 58 - .../itemmanager/filters/ComboBoxFilter.java | 95 - .../itemmanager/filters/DeckColorFilter.java | 35 - .../itemmanager/filters/DeckFolderFilter.java | 71 - .../itemmanager/filters/DeckFormatFilter.java | 33 - .../filters/DeckStatTypeFilter.java | 16 - .../itemmanager/filters/FormatFilter.java | 269 --- .../filters/HistoricFormatSelect.java | 142 -- .../itemmanager/filters/ItemFilter.java | 86 - .../itemmanager/filters/ListLabelFilter.java | 72 - .../itemmanager/filters/StatTypeFilter.java | 48 - .../itemmanager/filters/TextSearchFilter.java | 107 - .../filters/ToggleButtonsFilter.java | 96 - .../itemmanager/filters/ValueRangeFilter.java | 111 - .../itemmanager/views/ImageView.java | 1066 ---------- .../itemmanager/views/ItemListView.java | 331 --- .../libgdxgui/itemmanager/views/ItemView.java | 283 --- .../libgdxgui/menu/FCheckBoxMenuItem.java | 47 - .../adventure/libgdxgui/menu/FDropDown.java | 244 --- .../libgdxgui/menu/FDropDownMenu.java | 76 - .../libgdxgui/menu/FMagnifyView.java | 70 - .../adventure/libgdxgui/menu/FMenuBar.java | 62 - .../adventure/libgdxgui/menu/FMenuItem.java | 176 -- .../adventure/libgdxgui/menu/FMenuTab.java | 103 - .../adventure/libgdxgui/menu/FPopupMenu.java | 111 - .../adventure/libgdxgui/menu/FSubMenu.java | 53 - .../adventure/libgdxgui/menu/FTooltip.java | 72 - .../adventure/libgdxgui/screens/FScreen.java | 397 ---- .../libgdxgui/screens/LaunchScreen.java | 103 - .../libgdxgui/screens/LoadingOverlay.java | 110 - .../libgdxgui/screens/SplashScreen.java | 107 - .../libgdxgui/screens/TabPageScreen.java | 425 ---- .../screens/match/MatchController.java | 666 ------ .../libgdxgui/screens/match/MatchScreen.java | 785 ------- .../screens/match/TargetingOverlay.java | 121 -- .../match/views/VAssignCombatDamage.java | 468 ---- .../match/views/VAssignGenericAmount.java | 356 ---- .../screens/match/views/VAutoYields.java | 93 - .../screens/match/views/VAvatar.java | 84 - .../screens/match/views/VCardDisplayArea.java | 486 ----- .../screens/match/views/VDevMenu.java | 286 --- .../screens/match/views/VDisplayArea.java | 11 - .../libgdxgui/screens/match/views/VField.java | 206 -- .../screens/match/views/VGameMenu.java | 113 - .../libgdxgui/screens/match/views/VLog.java | 113 - .../screens/match/views/VManaPool.java | 153 -- .../screens/match/views/VPhaseIndicator.java | 165 -- .../screens/match/views/VPlayerPanel.java | 662 ------ .../screens/match/views/VPlayers.java | 74 - .../screens/match/views/VPrompt.java | 130 -- .../libgdxgui/screens/match/views/VStack.java | 428 ---- .../screens/match/views/VZoneDisplay.java | 210 -- .../match/winlose/ConquestWinLose.java | 39 - .../screens/match/winlose/ControlWinLose.java | 119 -- .../match/winlose/GauntletWinLose.java | 86 - .../screens/match/winlose/LimitedWinLose.java | 81 - .../match/winlose/QuestDraftWinLose.java | 126 -- .../screens/match/winlose/QuestWinLose.java | 69 - .../screens/match/winlose/ViewWinLose.java | 250 --- .../libgdxgui/screens/settings/FilesPage.java | 272 --- .../screens/settings/GuiDownloader.java | 153 -- .../screens/settings/SettingsPage.java | 768 ------- .../screens/settings/SettingsScreen.java | 73 - .../adventure/libgdxgui/sound/AudioClip.java | 81 - .../adventure/libgdxgui/sound/AudioMusic.java | 49 - .../libgdxgui/toolbox/DualListBox.java | 238 --- .../adventure/libgdxgui/toolbox/FButton.java | 350 --- .../libgdxgui/toolbox/FCardPanel.java | 107 - .../libgdxgui/toolbox/FCheckBox.java | 70 - .../libgdxgui/toolbox/FChoiceList.java | 594 ------ .../libgdxgui/toolbox/FComboBox.java | 298 --- .../libgdxgui/toolbox/FContainer.java | 159 -- .../adventure/libgdxgui/toolbox/FDialog.java | 303 --- .../libgdxgui/toolbox/FDisplayObject.java | 168 -- .../adventure/libgdxgui/toolbox/FEvent.java | 42 - .../libgdxgui/toolbox/FFileChooser.java | 449 ---- .../libgdxgui/toolbox/FGestureAdapter.java | 336 --- .../libgdxgui/toolbox/FGroupBox.java | 53 - .../libgdxgui/toolbox/FGroupList.java | 286 --- .../adventure/libgdxgui/toolbox/FLabel.java | 449 ---- .../adventure/libgdxgui/toolbox/FList.java | 361 ---- .../libgdxgui/toolbox/FNumericTextField.java | 69 - .../libgdxgui/toolbox/FOptionPane.java | 371 ---- .../adventure/libgdxgui/toolbox/FOverlay.java | 210 -- .../adventure/libgdxgui/toolbox/FPanel.java | 27 - .../libgdxgui/toolbox/FProgressBar.java | 178 -- .../libgdxgui/toolbox/FRadioButton.java | 98 - .../libgdxgui/toolbox/FScrollPane.java | 323 --- .../adventure/libgdxgui/toolbox/FSpinner.java | 61 - .../libgdxgui/toolbox/FTextArea.java | 83 - .../libgdxgui/toolbox/FTextField.java | 459 ---- .../adventure/libgdxgui/toolbox/FTimer.java | 33 - .../libgdxgui/toolbox/FToggleSwitch.java | 171 -- .../libgdxgui/toolbox/GuiChoose.java | 340 --- .../libgdxgui/toolbox/GuiDialog.java | 52 - .../libgdxgui/toolbox/ListChooser.java | 320 --- .../libgdxgui/util/LayoutHelper.java | 195 -- .../libgdxgui/util/LibGDXImageFetcher.java | 85 - .../libgdxgui/util/PhysicsObject.java | 80 - .../adventure/libgdxgui/util/TextBounds.java | 15 - .../forge/adventure/libgdxgui/util/Utils.java | 117 - .../forge/adventure/scene/DeckEditScene.java | 19 +- .../java/forge/adventure/scene/DuelScene.java | 6 +- .../forge/adventure/scene/ForgeInput.java | 14 +- .../forge/adventure/scene/ForgeScene.java | 14 +- .../forge/adventure/scene/RewardScene.java | 2 +- .../forge/adventure/util/RewardActor.java | 4 +- forge-gui-desktop/pom.xml | 5 - forge-gui-mobile/src/forge/GuiMobile.java | 26 +- forge-gui-mobile/src/forge/assets/FSkin.java | 54 +- .../src/forge/deck/FDeckEditor.java | 49 +- .../src/forge/screens/TabPageScreen.java | 25 +- pom.xml | 4 +- 182 files changed, 307 insertions(+), 37329 deletions(-) create mode 100644 forge-adventure/shaders/grayscale.frag create mode 100644 forge-adventure/shaders/grayscale.vert create mode 100644 forge-adventure/shaders/outline.frag create mode 100644 forge-adventure/shaders/outline.vert create mode 100644 forge-adventure/shaders/underwater.frag create mode 100644 forge-adventure/shaders/warp.frag delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/CachedCardImage.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/Forge.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/FrameRate.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/Graphics.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/GuiMobile.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/animation/AbilityEffect.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/animation/ForgeAnimation.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/animation/ForgeTransition.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/animation/GifAnimation.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/animation/GifDecoder.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/AssetsDownloader.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/BitmapFontWriter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FBufferedImage.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FDelayLoadImage.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FImage.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FImageComplex.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FLanguage.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FRotatedImage.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkin.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkinBorder.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkinColor.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkinFont.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkinImage.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkinTexture.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FTextureImage.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FTextureRegionImage.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/ImageCache.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/ImageLoader.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/OtherImageLoader.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/TextRenderer.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardAvatarImage.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardFaceSymbols.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardImage.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardImageRenderer.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardListPreview.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardRenderer.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardZoom.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/card/ColorSetImage.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/card/GameEntityPicker.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/AddBasicLandsDialog.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FDeckChooser.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FDeckEditor.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FDeckImportDialog.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FDeckViewer.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FSideboardDialog.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FVanguardChooser.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/error/BugReportDialog.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/CardManager.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/DeckManager.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/ItemManager.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/SpellShopManager.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/AdvancedSearchFilter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardCMCFilter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardColorFilter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardColorlessCostFilter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardFormatFilter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardPowerFilter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardRarityFilter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardSearchFilter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardToughnessFilter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardTypeFilter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/ComboBoxFilter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/DeckColorFilter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/DeckFolderFilter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/DeckFormatFilter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/DeckStatTypeFilter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/FormatFilter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/HistoricFormatSelect.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/ItemFilter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/ListLabelFilter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/StatTypeFilter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/TextSearchFilter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/ToggleButtonsFilter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/ValueRangeFilter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/views/ImageView.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/views/ItemListView.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/views/ItemView.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FCheckBoxMenuItem.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FDropDown.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FDropDownMenu.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FMagnifyView.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FMenuBar.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FMenuItem.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FMenuTab.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FPopupMenu.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FSubMenu.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FTooltip.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/FScreen.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/LaunchScreen.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/LoadingOverlay.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/SplashScreen.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/TabPageScreen.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/MatchController.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/MatchScreen.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/TargetingOverlay.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VAssignCombatDamage.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VAssignGenericAmount.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VAutoYields.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VAvatar.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VCardDisplayArea.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VDevMenu.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VDisplayArea.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VField.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VGameMenu.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VLog.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VManaPool.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VPhaseIndicator.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VPlayerPanel.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VPlayers.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VPrompt.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VStack.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VZoneDisplay.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/ConquestWinLose.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/ControlWinLose.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/GauntletWinLose.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/LimitedWinLose.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/QuestDraftWinLose.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/QuestWinLose.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/ViewWinLose.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/settings/FilesPage.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/settings/GuiDownloader.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/settings/SettingsPage.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/settings/SettingsScreen.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/sound/AudioClip.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/sound/AudioMusic.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/DualListBox.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FButton.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FCardPanel.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FCheckBox.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FChoiceList.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FComboBox.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FContainer.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FDialog.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FDisplayObject.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FEvent.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FFileChooser.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FGestureAdapter.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FGroupBox.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FGroupList.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FLabel.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FList.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FNumericTextField.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FOptionPane.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FOverlay.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FPanel.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FProgressBar.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FRadioButton.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FScrollPane.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FSpinner.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FTextArea.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FTextField.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FTimer.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FToggleSwitch.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/GuiChoose.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/GuiDialog.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/ListChooser.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/util/LayoutHelper.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/util/LibGDXImageFetcher.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/util/PhysicsObject.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/util/TextBounds.java delete mode 100644 forge-adventure/src/main/java/forge/adventure/libgdxgui/util/Utils.java diff --git a/forge-adventure/pom.xml b/forge-adventure/pom.xml index c800d407037..3b168315eb7 100644 --- a/forge-adventure/pom.xml +++ b/forge-adventure/pom.xml @@ -18,6 +18,15 @@ src + + + ${project.basedir} + + **/*.vert + **/*.frag + + + maven-compiler-plugin @@ -164,6 +173,11 @@ forge-gui ${project.version} + + forge + forge-gui-mobile + ${project.version} + com.github.raeleus.TenPatch tenpatch @@ -176,6 +190,12 @@ 22.0.0 compile + + forge + forge-gui-mobile + 1.6.46-SNAPSHOT + compile + diff --git a/forge-adventure/shaders/grayscale.frag b/forge-adventure/shaders/grayscale.frag new file mode 100644 index 00000000000..aa5fd3ef8ec --- /dev/null +++ b/forge-adventure/shaders/grayscale.frag @@ -0,0 +1,15 @@ +#ifdef GL_ES +precision mediump float; +#endif + +varying vec4 v_color; +varying vec2 v_texCoords; +uniform sampler2D u_texture; +uniform float u_grayness; + +void main() { + vec4 c = v_color * texture2D(u_texture, v_texCoords); + float grey = dot( c.rgb, vec3(0.22, 0.707, 0.071) ); + vec3 blendedColor = mix(c.rgb, vec3(grey), u_grayness); + gl_FragColor = vec4(blendedColor.rgb, c.a); +} \ No newline at end of file diff --git a/forge-adventure/shaders/grayscale.vert b/forge-adventure/shaders/grayscale.vert new file mode 100644 index 00000000000..17d96ca8dde --- /dev/null +++ b/forge-adventure/shaders/grayscale.vert @@ -0,0 +1,14 @@ +attribute vec4 a_position; +attribute vec4 a_color; +attribute vec2 a_texCoord0; + +uniform mat4 u_projTrans; + +varying vec4 v_color; +varying vec2 v_texCoords; + +void main() { + v_color = a_color; + v_texCoords = a_texCoord0; + gl_Position = u_projTrans * a_position; +} \ No newline at end of file diff --git a/forge-adventure/shaders/outline.frag b/forge-adventure/shaders/outline.frag new file mode 100644 index 00000000000..738d23c1f71 --- /dev/null +++ b/forge-adventure/shaders/outline.frag @@ -0,0 +1,40 @@ +#ifdef GL_ES +precision mediump float; +precision mediump int; +#endif + +uniform sampler2D u_texture; +uniform vec2 u_viewportInverse; +uniform vec3 u_color; +uniform float u_offset; +uniform float u_step; + +varying vec4 v_color; +varying vec2 v_texCoord; + +#define ALPHA_VALUE_BORDER 0.5 + +void main() { + vec2 T = v_texCoord.xy; + + float alpha = 0.0; + bool allin = true; + for( float ix = -u_offset; ix < u_offset; ix += u_step ) + { + for( float iy = -u_offset; iy < u_offset; iy += u_step ) + { + float newAlpha = texture2D(u_texture, T + vec2(ix, iy) * u_viewportInverse).a; + allin = allin && newAlpha > ALPHA_VALUE_BORDER; + if (newAlpha > ALPHA_VALUE_BORDER && newAlpha >= alpha) + { + alpha = newAlpha; + } + } + } + if (allin) + { + alpha = 0.0; + } + + gl_FragColor = vec4(u_color,alpha); +} \ No newline at end of file diff --git a/forge-adventure/shaders/outline.vert b/forge-adventure/shaders/outline.vert new file mode 100644 index 00000000000..1b6e438116d --- /dev/null +++ b/forge-adventure/shaders/outline.vert @@ -0,0 +1,16 @@ +uniform mat4 u_projTrans; + +attribute vec4 a_position; +attribute vec2 a_texCoord0; +attribute vec4 a_color; + +varying vec4 v_color; +varying vec2 v_texCoord; + +uniform vec2 u_viewportInverse; + +void main() { + gl_Position = u_projTrans * a_position; + v_texCoord = a_texCoord0; + v_color = a_color; +} \ No newline at end of file diff --git a/forge-adventure/shaders/underwater.frag b/forge-adventure/shaders/underwater.frag new file mode 100644 index 00000000000..974a1e8ae92 --- /dev/null +++ b/forge-adventure/shaders/underwater.frag @@ -0,0 +1,23 @@ +#ifdef GL_ES +#define PRECISION mediump +precision PRECISION float; +precision PRECISION int; +#else +#define PRECISION +#endif + +varying vec2 v_texCoords; +uniform sampler2D u_texture; +uniform float u_amount; +uniform float u_speed; +uniform float u_time; + +void main () { + vec2 uv = v_texCoords; + + uv.y += (cos((uv.y + (u_time * 0.04 * u_speed)) * 45.0) * 0.0019 * u_amount) + (cos((uv.y + (u_time * 0.1 * u_speed)) * 10.0) * 0.002 * u_amount); + + uv.x += (sin((uv.y + (u_time * 0.07 * u_speed)) * 15.0) * 0.0029 * u_amount) + (sin((uv.y + (u_time * 0.1 * u_speed)) * 15.0) * 0.002 * u_amount); + + gl_FragColor = texture2D(u_texture, uv); +} \ No newline at end of file diff --git a/forge-adventure/shaders/warp.frag b/forge-adventure/shaders/warp.frag new file mode 100644 index 00000000000..f8a7022fa2c --- /dev/null +++ b/forge-adventure/shaders/warp.frag @@ -0,0 +1,57 @@ +#ifdef GL_ES +precision mediump float; +#endif + +varying vec2 v_texCoords; +uniform sampler2D u_texture; + +uniform float u_time; +uniform float u_speed; +uniform float u_amount; +uniform vec2 u_viewport; +uniform vec2 u_position; + +float random2d(vec2 n) { + return fract(sin(dot(n, vec2(12.9898, 4.1414))) * 43758.5453); +} + +float randomRange (in vec2 seed, in float min, in float max) { + return min + random2d(seed) * (max - min); +} + +float insideRange(float v, float bottom, float top) { + return step(bottom, v) - step(top, v); +} + +void main() +{ + float time = floor(u_time * u_speed * 60.0); + + vec3 outCol = texture2D(u_texture, v_texCoords).rgb; + + float maxOffset = u_amount/2.0; + for (float i = 0.0; i < 2.0; i += 1.0) { + float sliceY = random2d(vec2(time, 2345.0 + float(i))); + float sliceH = random2d(vec2(time, 9035.0 + float(i))) * 0.25; + float hOffset = randomRange(vec2(time, 9625.0 + float(i)), -maxOffset, maxOffset); + vec2 uvOff = v_texCoords; + uvOff.x += hOffset; + if (insideRange(v_texCoords.y, sliceY, fract(sliceY+sliceH)) == 1.0){ + outCol = texture2D(u_texture, uvOff).rgb; + } + } + + float maxColOffset = u_amount / 6.0; + float rnd = random2d(vec2(time , 9545.0)); + vec2 colOffset = vec2(randomRange(vec2(time , 9545.0), -maxColOffset, maxColOffset), + randomRange(vec2(time , 7205.0), -maxColOffset, maxColOffset)); + if (rnd < 0.33) { + outCol.r = texture2D(u_texture, v_texCoords + colOffset).r; + } else if (rnd < 0.66) { + outCol.g = texture2D(u_texture, v_texCoords + colOffset).g; + } else { + outCol.b = texture2D(u_texture, v_texCoords + colOffset).b; + } + + gl_FragColor = vec4(outCol, 1.0); +} \ No newline at end of file diff --git a/forge-adventure/src/main/java/forge/adventure/AdventureApplicationAdapter.java b/forge-adventure/src/main/java/forge/adventure/AdventureApplicationAdapter.java index 39eff712728..24ef1836c55 100644 --- a/forge-adventure/src/main/java/forge/adventure/AdventureApplicationAdapter.java +++ b/forge-adventure/src/main/java/forge/adventure/AdventureApplicationAdapter.java @@ -10,7 +10,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.ScreenUtils; -import forge.adventure.libgdxgui.Graphics; +import forge.Graphics; import forge.adventure.scene.ForgeScene; import forge.adventure.scene.Scene; import forge.adventure.scene.SceneType; diff --git a/forge-adventure/src/main/java/forge/adventure/Main.java b/forge-adventure/src/main/java/forge/adventure/Main.java index 13446ed11ea..edf0ddd0466 100644 --- a/forge-adventure/src/main/java/forge/adventure/Main.java +++ b/forge-adventure/src/main/java/forge/adventure/Main.java @@ -7,17 +7,15 @@ import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration; import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Clipboard; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.utils.Clipboard; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.FrameRate; -import forge.adventure.libgdxgui.GuiMobile; -import forge.adventure.libgdxgui.assets.AssetsDownloader; -import forge.adventure.libgdxgui.assets.FSkin; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.ImageCache; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.screens.SplashScreen; +import forge.Forge; +import forge.FrameRate; +import forge.GuiMobile; import forge.adventure.scene.SettingsScene; import forge.adventure.util.Config; +import forge.assets.AssetsDownloader; +import forge.assets.FSkin; +import forge.assets.FSkinFont; +import forge.assets.ImageCache; import forge.error.ExceptionHandler; import forge.gui.FThreads; import forge.gui.GuiBase; @@ -25,6 +23,8 @@ import forge.interfaces.IDeviceAdapter; import forge.localinstance.properties.ForgeConstants; import forge.localinstance.properties.ForgePreferences; import forge.model.FModel; +import forge.screens.FScreen; +import forge.screens.SplashScreen; import forge.sound.MusicPlaylist; import forge.sound.SoundSystem; import forge.util.BuildInfo; @@ -155,7 +155,7 @@ class StartAdventure extends AdventureApplicationAdapter { } else { skinName = "default"; //use default skin if preferences file doesn't exist yet } - FSkin.loadLight(skinName, splashScreen); + FSkin.loadLight(skinName, splashScreen,Config.instance().getFile("skin")); textureFiltering = prefs.getPrefBoolean(ForgePreferences.FPref.UI_LIBGDX_TEXTURE_FILTERING); showFPS = prefs.getPrefBoolean(ForgePreferences.FPref.UI_SHOW_FPS); @@ -293,6 +293,7 @@ public class Main { } config.setWindowIcon(Config.instance().getFilePath("forge-adventure.png")); + new Lwjgl3Application(start, config); } diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/CachedCardImage.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/CachedCardImage.java deleted file mode 100644 index 31b894db3e5..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/CachedCardImage.java +++ /dev/null @@ -1,45 +0,0 @@ -package forge.adventure.libgdxgui; - -import com.badlogic.gdx.graphics.Texture; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.assets.ImageCache; -import forge.game.card.CardView; -import forge.gui.GuiBase; -import forge.item.InventoryItem; -import forge.util.ImageFetcher; - -public abstract class CachedCardImage implements ImageFetcher.Callback { - protected final String key; - static final ImageFetcher fetcher = GuiBase.getInterface().getImageFetcher(); - - public CachedCardImage(final CardView card) { - key = card.getCurrentState().getImageKey(MatchController.instance.getLocalPlayers()); - fetch(); - } - - public CachedCardImage(final InventoryItem ii) { - key = ii.getImageKey(false); - fetch(); - } - - public CachedCardImage(String key) { - this.key = key; - fetch(); - } - - public void fetch() { - if (!ImageCache.imageKeyFileExists(key)) { - fetcher.fetchImage(key, this); - } - } - - public Texture getImage() { - return ImageCache.getImage(key, true); - } - - public Texture getImage(String mykey) { - return ImageCache.getImage(mykey, true); - } - - public abstract void onImageFetched(); -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/Forge.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/Forge.java deleted file mode 100644 index c9937e31348..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/Forge.java +++ /dev/null @@ -1,920 +0,0 @@ -package forge.adventure.libgdxgui; - -import com.badlogic.gdx.Application; -import com.badlogic.gdx.ApplicationListener; -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.Input.Keys; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.utils.Clipboard; -import forge.adventure.libgdxgui.animation.ForgeAnimation; -import forge.adventure.libgdxgui.assets.AssetsDownloader; -import forge.adventure.libgdxgui.assets.FSkin; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.ImageCache; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.screens.SplashScreen; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.toolbox.*; -import forge.adventure.libgdxgui.util.Utils; -import forge.error.ExceptionHandler; -import forge.gui.FThreads; -import forge.gui.GuiBase; -import forge.gui.error.BugReporter; -import forge.interfaces.IDeviceAdapter; -import forge.localinstance.properties.ForgeConstants; -import forge.localinstance.properties.ForgePreferences; -import forge.localinstance.properties.ForgePreferences.FPref; -import forge.model.FModel; -import forge.sound.MusicPlaylist; -import forge.sound.SoundSystem; -import forge.util.Callback; -import forge.util.CardTranslation; -import forge.util.FileUtil; -import forge.util.Localizer; - -import java.io.File; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Deque; -import java.util.List; - -public class Forge implements ApplicationListener { - public static final String CURRENT_VERSION = "1.6.42.001"; - - public static final Forge app = new Forge(); - private static final Deque Dscreens = new ArrayDeque<>(); - public static String extrawide = "default"; - public static float heigtModifier = 0.0f; - public static boolean showFPS = false; - public static boolean altPlayerLayout = false; - public static boolean altZoneTabs = false; - public static String enableUIMask = "Full"; - public static boolean enablePreloadExtendedArt = false; - public static boolean isTabletDevice = false; - public static String locale = "en-US"; - public static boolean hdbuttons = false; - public static boolean hdstart = false; - public static boolean isPortraitMode = false; - public static boolean gameInProgress = false; - public static boolean disposeTextures = false; - public static int cacheSize = 400; - public static int totalDeviceRAM = 0; - public static int androidVersion = 0; - public static boolean autoCache = false; - public static int lastButtonIndex = 0; - public static String CJK_Font = ""; - private static Clipboard clipboard; - private static IDeviceAdapter deviceAdapter; - private static int screenWidth; - private static int screenHeight; - private static forge.adventure.libgdxgui.Graphics graphics; - private static forge.adventure.libgdxgui.FrameRate frameRate; - private static FScreen currentScreen; - private static SplashScreen splashScreen; - private static KeyInputAdapter keyInputAdapter; - private static boolean exited; - private static int continuousRenderingCount = 1; //initialize to 1 since continuous rendering is the default - private static boolean textureFiltering = false; - private static boolean destroyThis = false; - private static boolean isloadingaMatch = false; - private MainInputProcessor input; - - private Forge() { - } - - public static ApplicationListener getApp(Clipboard clipboard0, IDeviceAdapter deviceAdapter0, String assetDir0, boolean value, boolean androidOrientation, int totalRAM, boolean isTablet, int AndroidAPI, String AndroidRelease, String deviceName) { - if (GuiBase.getInterface() == null) { - clipboard = clipboard0; - deviceAdapter = deviceAdapter0; - GuiBase.setUsingAppDirectory(assetDir0.contains("forge.app")); //obb directory on android uses the package name as entrypoint - GuiBase.setInterface(new forge.adventure.libgdxgui.GuiMobile(assetDir0)); - GuiBase.enablePropertyConfig(value); - isPortraitMode = androidOrientation; - totalDeviceRAM = totalRAM; - isTabletDevice = isTablet; - androidVersion = AndroidAPI; - } - GuiBase.setDeviceInfo(deviceName, AndroidRelease, AndroidAPI, totalRAM); - return app; - } - - public static void openHomeScreen(int index) { - } - - public static Clipboard getClipboard() { - return clipboard; - } - - public static IDeviceAdapter getDeviceAdapter() { - return deviceAdapter; - } - - public static void startContinuousRendering() { - if (++continuousRenderingCount == 1) { - //only set continuous rendering to true if needed - Gdx.graphics.setContinuousRendering(true); - } - } - - public static void stopContinuousRendering() { - if (continuousRenderingCount > 0 && --continuousRenderingCount == 0) { - //only set continuous rendering to false if all continuous rendering requests have been ended - Gdx.graphics.setContinuousRendering(false); - } - } - - public static float getHeightModifier() { - return heigtModifier; - } - - public static void setHeightModifier(float height) { - heigtModifier = height; - } - - public static void adjustHeightModifier(float DisplayW, float DisplayH) { - if (isLandscapeMode()) {//TODO: Fullscreen support for Display without screen controls - float aspectratio = DisplayW / DisplayH; - if (aspectratio > 1.82f) {/* extra wide */ - setHeightModifier(200.0f); - extrawide = "extrawide"; - } else if (aspectratio > 1.7f) {/* wide */ - setHeightModifier(100.0f); - extrawide = "wide"; - } - } - } - - public static void showMenu() { - if (currentScreen == null) { - return; - } - endKeyInput(); //end key input before menu shown - if (FOverlay.getTopOverlay() == null) { //don't show menu if overlay open - currentScreen.showMenu(); - } - } - - public static boolean onHomeScreen() { - return Dscreens.size() == 1; - } - - public static void back() { - - } - - //set screen that will be gone to on pressing Back before going to current Back screen - public static void setBackScreen(final FScreen screen0, boolean replace) { - Dscreens.remove(screen0); //remove screen from previous position in navigation history - int index = Dscreens.size() - 1; - if (index > 0) { - Dscreens.addLast(screen0); - if (replace) { //remove previous back screen if replacing back screen - Dscreens.removeFirst(); - } - } - } - - public static void restart(boolean silent) { - if (exited) { - return; - } //don't allow exiting multiple times - - Callback callback = new Callback() { - @Override - public void run(Boolean result) { - if (result) { - exited = true; - deviceAdapter.restart(); - } - } - }; - - final Localizer localizer = Localizer.getInstance(); - - if (silent) { - callback.run(true); - } else { - FOptionPane.showConfirmDialog( - localizer.getMessage("lblAreYouSureYouWishRestartForge"), localizer.getMessage("lblRestartForge"), - localizer.getMessage("lblRestart"), localizer.getMessage("lblCancel"), callback); - } - } - - public static void exit(boolean silent) { - if (exited) { - return; - } //don't allow exiting multiple times - - Callback callback = new Callback() { - @Override - public void run(Boolean result) { - if (result) { - exited = true; - deviceAdapter.exit(); - } - } - }; - - final Localizer localizer = Localizer.getInstance(); - - if (silent) { - callback.run(true); - } else { - FOptionPane.showConfirmDialog( - localizer.getMessage("lblAreYouSureYouWishExitForge"), localizer.getMessage("lblExitForge"), - localizer.getMessage("lblExit"), localizer.getMessage("lblCancel"), callback); - } - } - - public static void openScreen(final FScreen screen0) { - openScreen(screen0, false); - } - - public static void openScreen(final FScreen screen0, final boolean replaceBackScreen) { - if (currentScreen == screen0) { - return; - } - - if (currentScreen == null) { - Dscreens.addFirst(screen0); - setCurrentScreen(screen0); - return; - } - - currentScreen.onSwitchAway(new Callback() { - @Override - public void run(Boolean result) { - if (result) { - if (replaceBackScreen && !Dscreens.isEmpty()) { - Dscreens.removeFirst(); - } - if (Dscreens.peekFirst() != screen0) { //prevent screen being its own back screen - Dscreens.addFirst(screen0); - } - setCurrentScreen(screen0); - } - } - }); - } - - public static boolean isTextureFilteringEnabled() { - return textureFiltering; - } - - public static boolean isLandscapeMode() { - if (GuiBase.isAndroid()) - return !isPortraitMode; - return screenWidth > screenHeight; - } - - public static boolean isLoadingaMatch() { - return isloadingaMatch; - } - - public static void setLoadingaMatch(boolean value) { - isloadingaMatch = value; - } - - public static int getScreenWidth() { - return screenWidth; - } - - public static int getScreenHeight() { - return screenHeight; - } - - public static FScreen getCurrentScreen() { - return currentScreen; - } - - private static void setCurrentScreen(FScreen screen0) { - String toNewScreen = screen0 != null ? screen0.toString() : ""; - String previousScreen = currentScreen != null ? currentScreen.toString() : ""; - - gameInProgress = toNewScreen.toLowerCase().contains("match") || previousScreen.toLowerCase().contains("match"); - boolean dispose = toNewScreen.toLowerCase().contains("homescreen") && disposeTextures; - try { - endKeyInput(); //end key input before switching screens - ForgeAnimation.endAll(); //end all active animations before switching screens - - currentScreen = screen0; - currentScreen.setSize(screenWidth, screenHeight); - currentScreen.onActivate(); - /*keep Dscreens growing - if (Dscreens.size() > 3) { - for(int x = Dscreens.size(); x > 3; x--) { - Dscreens.removeLast(); - } - }*/ - /* for checking only - if (!Dscreens.isEmpty()) { - int x = 0; - for(FScreen fScreen : Dscreens) { - System.out.println("Screen ["+x+"]: "+fScreen.toString()); - x++; - } - System.out.println("---------------"); - }*/ - } catch (Exception ex) { - graphics.end(); - //check if sentry is enabled, if not it will call the gui interface but here we end the graphics so we only send it via sentry.. - if (BugReporter.isSentryEnabled()) - BugReporter.reportException(ex); - } finally { - if (dispose) - ImageCache.disposeTexture(); - } - } - - //log message to Forge.log file - public static void log(Object message) { - System.out.println(message); - } - - public static void startKeyInput(KeyInputAdapter adapter) { - if (keyInputAdapter == adapter) { - return; - } - if (keyInputAdapter != null) { - keyInputAdapter.onInputEnd(); //make sure previous adapter is ended - } - keyInputAdapter = adapter; - Gdx.input.setOnscreenKeyboardVisible(true); - } - - public static boolean endKeyInput() { - if (keyInputAdapter == null) { - return false; - } - keyInputAdapter.onInputEnd(); - keyInputAdapter = null; - MainInputProcessor.keyTyped = false; - MainInputProcessor.lastKeyTyped = '\0'; - Gdx.input.setOnscreenKeyboardVisible(false); - return true; - } - - @Override - public void create() { - //install our error handler - ExceptionHandler.registerErrorHandling(); - - GuiBase.setIsAndroid(Gdx.app.getType() == Application.ApplicationType.Android); - - graphics = new Graphics(); - splashScreen = new SplashScreen(); - frameRate = new FrameRate(); - input=new MainInputProcessor(); - Gdx.input.setInputProcessor(input); - /* - Set CatchBackKey here and exit the app when you hit the - back button while the textures,fonts,etc are still loading, - to prevent rendering issue when you try to restart - the app again (seems it doesnt dispose correctly...?!?) - */ - Gdx.input.setCatchKey(Keys.BACK, true); - destroyThis = true; //Prevent back() - ForgePreferences prefs = new ForgePreferences(); - - String skinName; - if (FileUtil.doesFileExist(ForgeConstants.MAIN_PREFS_FILE)) { - skinName = prefs.getPref(FPref.UI_SKIN); - } else { - skinName = "default"; //use default skin if preferences file doesn't exist yet - } - FSkin.loadLight(skinName, splashScreen); - - textureFiltering = prefs.getPrefBoolean(FPref.UI_LIBGDX_TEXTURE_FILTERING); - showFPS = prefs.getPrefBoolean(FPref.UI_SHOW_FPS); - altPlayerLayout = prefs.getPrefBoolean(FPref.UI_ALT_PLAYERINFOLAYOUT); - altZoneTabs = prefs.getPrefBoolean(FPref.UI_ALT_PLAYERZONETABS); - enableUIMask = prefs.getPref(FPref.UI_ENABLE_BORDER_MASKING); - if (prefs.getPref(FPref.UI_ENABLE_BORDER_MASKING).equals("true")) //override old settings if not updated - enableUIMask = "Full"; - else if (prefs.getPref(FPref.UI_ENABLE_BORDER_MASKING).equals("false")) - enableUIMask = "Off"; - enableUIMask = "Full"; - enablePreloadExtendedArt = prefs.getPrefBoolean(FPref.UI_ENABLE_PRELOAD_EXTENDED_ART); - locale = prefs.getPref(FPref.UI_LANGUAGE); - autoCache = prefs.getPrefBoolean(FPref.UI_AUTO_CACHE_SIZE); - disposeTextures = prefs.getPrefBoolean(FPref.UI_ENABLE_DISPOSE_TEXTURES); - CJK_Font = prefs.getPref(FPref.UI_CJK_FONT); - - if (autoCache) { - //increase cacheSize for devices with RAM more than 5GB, default is 400. Some phones have more than 10GB RAM (Mi 10, OnePlus 8, S20, etc..) - if (totalDeviceRAM > 5000) //devices with more than 10GB RAM will have 800 Cache size, 600 Cache size for morethan 5GB RAM - cacheSize = totalDeviceRAM > 10000 ? 800 : 600; - } - //init cache - ImageCache.initCache(cacheSize); - final Localizer localizer = Localizer.getInstance(); - - //load model on background thread (using progress bar to report progress) - FThreads.invokeInBackgroundThread(new Runnable() { - @Override - public void run() { - //see if app or assets need updating - AssetsDownloader.checkForUpdates(splashScreen); - if (exited) { - return; - } //don't continue if user chose to exit or couldn't download required assets - - FModel.initialize(splashScreen.getProgressBar(), null); - - splashScreen.getProgressBar().setDescription(localizer.getMessage("lblLoadingFonts")); - FSkinFont.preloadAll(locale); - - splashScreen.getProgressBar().setDescription(localizer.getMessage("lblLoadingCardTranslations")); - CardTranslation.preloadTranslation(locale, ForgeConstants.LANG_DIR); - - splashScreen.getProgressBar().setDescription(localizer.getMessage("lblFinishingStartup")); - - //add reminder to preload - if (enablePreloadExtendedArt) { - if (autoCache) - splashScreen.getProgressBar().setDescription(localizer.getMessage("lblPreloadExtendedArt") + "\nDetected RAM: " + totalDeviceRAM + "MB. Cache size: " + cacheSize); - else - splashScreen.getProgressBar().setDescription(localizer.getMessage("lblPreloadExtendedArt")); - } else { - if (autoCache) - splashScreen.getProgressBar().setDescription(localizer.getMessage("lblFinishingStartup") + "\nDetected RAM: " + totalDeviceRAM + "MB. Cache size: " + cacheSize); - else - splashScreen.getProgressBar().setDescription(localizer.getMessage("lblFinishingStartup")); - } - - Gdx.app.postRunnable(new Runnable() { - @Override - public void run() { - afterDbLoaded(); - /* call preloadExtendedArt here, if we put it above we will * - * get error: No OpenGL context found in the current thread. */ - preloadExtendedArt(); - } - }); - } - }); - } - - private void preloadExtendedArt() { - if (!enablePreloadExtendedArt) - return; - List borderlessCardlistkeys = FileUtil.readFile(ForgeConstants.BORDERLESS_CARD_LIST_FILE); - if (borderlessCardlistkeys.isEmpty()) - return; - List filteredkeys = new ArrayList<>(); - for (String cardname : borderlessCardlistkeys) { - File image = new File(ForgeConstants.CACHE_CARD_PICS_DIR + ForgeConstants.PATH_SEPARATOR + cardname + ".jpg"); - if (image.exists()) - filteredkeys.add(cardname); - } - if (!filteredkeys.isEmpty()) - ImageCache.preloadCache(filteredkeys); - } - - private void afterDbLoaded() { - stopContinuousRendering(); //save power consumption by disabling continuous rendering once assets loaded - - FSkin.loadFull(splashScreen); - - SoundSystem.instance.setBackgroundMusic(MusicPlaylist.MENUS); //start background music - destroyThis = false; //Allow back() - Gdx.input.setCatchKey(Keys.MENU, true); - openHomeScreen(-1); //default for startup - splashScreen = null; - - boolean isLandscapeMode = isLandscapeMode(); - - - //adjust height modifier - adjustHeightModifier(getScreenWidth(), getScreenHeight()); - - //update landscape mode preference if it doesn't match what the app loaded as - if (FModel.getPreferences().getPrefBoolean(FPref.UI_LANDSCAPE_MODE) != isLandscapeMode) { - FModel.getPreferences().setPref(FPref.UI_LANDSCAPE_MODE, isLandscapeMode); - FModel.getPreferences().save(); - } - } - - @Override - public void render() { - if (showFPS) - frameRate.update(); - - try { - ImageCache.allowSingleLoad(); - ForgeAnimation.advanceAll(); - - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); // Clear the screen. - - FContainer screen = currentScreen; - if (screen == null) { - screen = splashScreen; - if (screen == null) { - return; - } - } - - graphics.begin(screenWidth, screenHeight); - screen.screenPos.setSize(screenWidth, screenHeight); - if (screen.getRotate180()) { - graphics.startRotateTransform(screenWidth / 2, screenHeight / 2, 180); - } - screen.draw(graphics); - if (screen.getRotate180()) { - graphics.endTransform(); - } - for (FOverlay overlay : FOverlay.getOverlays()) { - if (overlay.isVisibleOnScreen(currentScreen)) { - overlay.screenPos.setSize(screenWidth, screenHeight); - overlay.setSize(screenWidth, screenHeight); //update overlay sizes as they're rendered - if (overlay.getRotate180()) { - graphics.startRotateTransform(screenWidth / 2, screenHeight / 2, 180); - } - overlay.draw(graphics); - if (overlay.getRotate180()) { - graphics.endTransform(); - } - } - } - graphics.end(); - } catch (Exception ex) { - graphics.end(); - //check if sentry is enabled, if not it will call the gui interface but here we end the graphics so we only send it via sentry.. - if (BugReporter.isSentryEnabled()) - BugReporter.reportException(ex); - } - if (showFPS) - frameRate.render(); - } - - @Override - public void resize(int width, int height) { - try { - screenWidth = width; - screenHeight = height; - if (currentScreen != null) { - currentScreen.setSize(width, height); - } else if (splashScreen != null) { - splashScreen.setSize(width, height); - } - } catch (Exception ex) { - graphics.end(); - //check if sentry is enabled, if not it will call the gui interface but here we end the graphics so we only send it via sentry.. - if (BugReporter.isSentryEnabled()) - BugReporter.reportException(ex); - } - } - - @Override - public void pause() { - if (MatchController.getHostedMatch() != null) { - MatchController.getHostedMatch().pause(); - } - } - - @Override - public void resume() { - if (MatchController.getHostedMatch() != null) { - MatchController.getHostedMatch().resume(); - } - } - - @Override - public void dispose() { - if (currentScreen != null) { - FOverlay.hideAll(); - currentScreen.onClose(null); - currentScreen = null; - } - Dscreens.clear(); - graphics.dispose(); - SoundSystem.instance.dispose(); - try { - ExceptionHandler.unregisterErrorHandling(); - } catch (Exception e) { - } - } - - public static abstract class KeyInputAdapter { - public static boolean isCtrlKeyDown() { - return Gdx.input.isKeyPressed(Keys.CONTROL_LEFT) || Gdx.input.isKeyPressed(Keys.CONTROL_RIGHT); - } - - public static boolean isShiftKeyDown() { - return Gdx.input.isKeyPressed(Keys.SHIFT_LEFT) || Gdx.input.isKeyPressed(Keys.SHIFT_RIGHT); - } - - public static boolean isAltKeyDown() { - return Gdx.input.isKeyPressed(Keys.ALT_LEFT) || Gdx.input.isKeyPressed(Keys.ALT_RIGHT); - } - - public static boolean isModifierKey(int keyCode) { - switch (keyCode) { - case Keys.CONTROL_LEFT: - case Keys.CONTROL_RIGHT: - case Keys.SHIFT_LEFT: - case Keys.SHIFT_RIGHT: - case Keys.ALT_LEFT: - case Keys.ALT_RIGHT: - return true; - } - return false; - } - - public abstract FDisplayObject getOwner(); - - public abstract boolean allowTouchInput(); - - public abstract boolean keyTyped(char ch); - - public abstract boolean keyDown(int keyCode); - - public abstract void onInputEnd(); - - //also allow handling of keyUp but don't require it - public boolean keyUp(int keyCode) { - return false; - } - } - - private static class MainInputProcessor extends FGestureAdapter { - private static final List potentialListeners = new ArrayList<>(); - private static char lastKeyTyped; - private static boolean keyTyped, shiftKeyDown; - //mouseMoved and scrolled events for desktop version - private int mouseMovedX, mouseMovedY; - - @Override - public boolean keyDown(int keyCode) { - if (keyCode == Keys.MENU) { - showMenu(); - return true; - } - if (keyCode == Keys.SHIFT_LEFT || keyCode == Keys.SHIFT_RIGHT) { - shiftKeyDown = true; - } - - // Cursor keys emulate swipe gestures - // First we touch the screen and later swipe (fling) in the direction of the key pressed - if (keyCode == Keys.LEFT) { - touchDown(0, 0, 0, 0); - return fling(1000, 0); - } - if (keyCode == Keys.RIGHT) { - touchDown(0, 0, 0, 0); - return fling(-1000, 0); - } - if (keyCode == Keys.UP) { - touchDown(0, 0, 0, 0); - return fling(0, -1000); - } - if (keyCode == Keys.DOWN) { - touchDown(0, 0, 0, 0); - return fling(0, 1000); - } - if (keyCode == Keys.BACK) { - if (destroyThis) - deviceAdapter.exit(); - else if (onHomeScreen() && isLandscapeMode()) - back(); - } - if (keyInputAdapter == null) { - if (KeyInputAdapter.isModifierKey(keyCode)) { - return false; //don't process modifiers keys for unknown adapter - } - //if no active key input adapter, give current screen or overlay a chance to handle key - FContainer container = FOverlay.getTopOverlay(); - if (container == null) { - container = currentScreen; - if (container == null) { - return false; - } - } - return container.keyDown(keyCode); - } - return keyInputAdapter.keyDown(keyCode); - } - - @Override - public boolean keyUp(int keyCode) { - keyTyped = false; //reset on keyUp - if (keyCode == Keys.SHIFT_LEFT || keyCode == Keys.SHIFT_RIGHT) { - shiftKeyDown = false; - } - if (keyInputAdapter != null) { - return keyInputAdapter.keyUp(keyCode); - } - return false; - } - - @Override - public boolean keyTyped(char ch) { - if (keyInputAdapter != null) { - if (ch >= ' ' && ch <= '~') { //only process this event if character is printable - //prevent firing this event more than once for the same character on the same key down, otherwise it fires too often - if (lastKeyTyped != ch || !keyTyped) { - keyTyped = true; - lastKeyTyped = ch; - return keyInputAdapter.keyTyped(ch); - } - } - } - return false; - } - - private void updatePotentialListeners(int x, int y) { - potentialListeners.clear(); - - //base potential listeners on object containing touch down point - for (FOverlay overlay : FOverlay.getOverlaysTopDown()) { - if (overlay.isVisibleOnScreen(currentScreen)) { - overlay.buildTouchListeners(x, y, potentialListeners); - if (overlay.preventInputBehindOverlay()) { - return; - } - } - } - if (currentScreen != null) { - currentScreen.buildTouchListeners(x, y, potentialListeners); - } - } - - @Override - public boolean touchDown(int x, int y, int pointer, int button) { - if (pointer == 0) { //don't change listeners when second finger goes down for zoom - updatePotentialListeners(x, y); - if (keyInputAdapter != null) { - if (!keyInputAdapter.allowTouchInput() || !potentialListeners.contains(keyInputAdapter.getOwner())) { - endKeyInput(); //end key input if needed - } - } - } - return super.touchDown(x, y, pointer, button); - } - - @Override - public boolean press(float x, float y) { - try { - for (FDisplayObject listener : potentialListeners) { - if (listener.press(listener.screenToLocalX(x), listener.screenToLocalY(y))) { - return true; - } - } - return false; - } catch (Exception ex) { - BugReporter.reportException(ex); - return true; - } - } - - @Override - public boolean release(float x, float y) { - try { - for (FDisplayObject listener : potentialListeners) { - if (listener.release(listener.screenToLocalX(x), listener.screenToLocalY(y))) { - return true; - } - } - return false; - } catch (Exception ex) { - BugReporter.reportException(ex); - return true; - } - } - - @Override - public boolean longPress(float x, float y) { - try { - for (FDisplayObject listener : potentialListeners) { - if (listener.longPress(listener.screenToLocalX(x), listener.screenToLocalY(y))) { - return true; - } - } - return false; - } catch (Exception ex) { - BugReporter.reportException(ex); - return true; - } - } - - @Override - public boolean tap(float x, float y, int count) { - if (shiftKeyDown && flick(x, y)) { - return true; //give flick logic a chance to handle Shift+click - } - try { - for (FDisplayObject listener : potentialListeners) { - if (listener.tap(listener.screenToLocalX(x), listener.screenToLocalY(y), count)) { - return true; - } - } - return false; - } catch (Exception ex) { - BugReporter.reportException(ex); - return true; - } - } - - @Override - public boolean flick(float x, float y) { - try { - for (FDisplayObject listener : potentialListeners) { - if (listener.flick(listener.screenToLocalX(x), listener.screenToLocalY(y))) { - return true; - } - } - return false; - } catch (Exception ex) { - BugReporter.reportException(ex); - return true; - } - } - - @Override - public boolean fling(float velocityX, float velocityY) { - try { - for (FDisplayObject listener : potentialListeners) { - if (listener.fling(velocityX, velocityY)) { - return true; - } - } - return false; - } catch (Exception ex) { - BugReporter.reportException(ex); - return true; - } - } - - @Override - public boolean pan(float x, float y, float deltaX, float deltaY, boolean moreVertical) { - try { - for (FDisplayObject listener : potentialListeners) { - if (listener.pan(listener.screenToLocalX(x), listener.screenToLocalY(y), deltaX, deltaY, moreVertical)) { - return true; - } - } - return false; - } catch (Exception ex) { - BugReporter.reportException(ex); - return true; - } - } - - @Override - public boolean panStop(float x, float y) { - try { - for (FDisplayObject listener : potentialListeners) { - if (listener.panStop(listener.screenToLocalX(x), listener.screenToLocalY(y))) { - return true; - } - } - return false; - } catch (Exception ex) { - BugReporter.reportException(ex); - return true; - } - } - - @Override - public boolean zoom(float x, float y, float amount) { - try { - for (FDisplayObject listener : potentialListeners) { - if (listener.zoom(listener.screenToLocalX(x), listener.screenToLocalY(y), amount)) { - return true; - } - } - return false; - } catch (Exception ex) { - BugReporter.reportException(ex); - return true; - } - } - - @Override - public boolean mouseMoved(int x, int y) { - mouseMovedX = x; - mouseMovedY = y; - return true; - } - - @Override - public boolean scrolled(float amountX, float amountY) { - updatePotentialListeners(mouseMovedX, mouseMovedY); - - if (KeyInputAdapter.isCtrlKeyDown()) { //zoom in or out based on amount - return zoom(mouseMovedX, mouseMovedY, -Utils.AVG_FINGER_WIDTH * amountY); - } - - boolean handled; - if (KeyInputAdapter.isShiftKeyDown()) { - handled = pan(mouseMovedX, mouseMovedY, -Utils.AVG_FINGER_WIDTH * amountX, 0, false); - } else { - handled = pan(mouseMovedX, mouseMovedY, 0, -Utils.AVG_FINGER_HEIGHT * amountY, true); - } - if (panStop(mouseMovedX, mouseMovedY)) { - handled = true; - } - return handled; - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/FrameRate.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/FrameRate.java deleted file mode 100644 index cd811d179b4..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/FrameRate.java +++ /dev/null @@ -1,62 +0,0 @@ -package forge.adventure.libgdxgui; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.OrthographicCamera; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.utils.Disposable; -import com.badlogic.gdx.utils.TimeUtils; - -/** - * A nicer class for showing framerate that doesn't spam the console - * like Logger.log() - * - * @author William Hartman - */ - -public class FrameRate implements Disposable{ - long lastTimeCounted; - private float sinceChange; - private float frameRate; - private final BitmapFont font; - private final SpriteBatch batch; - private OrthographicCamera cam; - - public FrameRate() { - lastTimeCounted = TimeUtils.millis(); - sinceChange = 0; - frameRate = Gdx.graphics.getFramesPerSecond(); - font = new BitmapFont(); - batch = new SpriteBatch(); - cam = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); - } - - public void resize(int screenWidth, int screenHeight) { - cam = new OrthographicCamera(screenWidth, screenHeight); - cam.translate(screenWidth / 2, screenHeight / 2); - cam.update(); - batch.setProjectionMatrix(cam.combined); - } - - public void update() { - long delta = TimeUtils.timeSinceMillis(lastTimeCounted); - lastTimeCounted = TimeUtils.millis(); - sinceChange += delta; - if(sinceChange >= 1000) { - sinceChange = 0; - frameRate = Gdx.graphics.getFramesPerSecond(); - } - } - - public void render() { - batch.begin(); - font.draw(batch, (int)frameRate + " fps", 3, Gdx.graphics.getHeight() - 3); - batch.end(); - } - - public void dispose() { - font.dispose(); - batch.dispose(); - } - -} \ No newline at end of file diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/Graphics.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/Graphics.java deleted file mode 100644 index 3c4590b189a..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/Graphics.java +++ /dev/null @@ -1,887 +0,0 @@ -package forge.adventure.libgdxgui; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.Batch; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.graphics.glutils.ShaderProgram; -import com.badlogic.gdx.graphics.glutils.ShapeRenderer; -import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; -import com.badlogic.gdx.math.Matrix4; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.math.Vector3; -import com.badlogic.gdx.scenes.scene2d.utils.ScissorStack; -import forge.adventure.libgdxgui.assets.FImage; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.util.TextBounds; -import forge.adventure.libgdxgui.util.Utils; - -import java.util.ArrayDeque; -import java.util.Deque; - -public class Graphics { - private static final int GL_BLEND = GL20.GL_BLEND; - private static final int GL_LINE_SMOOTH = 2848; //create constant here since not in GL20 - - private final Batch batch; - private final ShapeRenderer shapeRenderer = new ShapeRenderer(); - private final Deque Dtransforms = new ArrayDeque<>(); - private final Vector3 tmp = new Vector3(); - private float regionHeight; - private Rectangle bounds; - private Rectangle visibleBounds; - private int failedClipCount; - private float alphaComposite = 1; - private int transformCount = 0; - private final String sVertex = "uniform mat4 u_projTrans;\n" + - "\n" + - "attribute vec4 a_position;\n" + - "attribute vec2 a_texCoord0;\n" + - "attribute vec4 a_color;\n" + - "\n" + - "varying vec4 v_color;\n" + - "varying vec2 v_texCoord;\n" + - "\n" + - "uniform vec2 u_viewportInverse;\n" + - "\n" + - "void main() {\n" + - " gl_Position = u_projTrans * a_position;\n" + - " v_texCoord = a_texCoord0;\n" + - " v_color = a_color;\n" + - "}"; - private final String sFragment = "#ifdef GL_ES\n" + - "precision mediump float;\n" + - "precision mediump int;\n" + - "#endif\n" + - "\n" + - "uniform sampler2D u_texture;\n" + - "\n" + - "// The inverse of the viewport dimensions along X and Y\n" + - "uniform vec2 u_viewportInverse;\n" + - "\n" + - "// Color of the outline\n" + - "uniform vec3 u_color;\n" + - "\n" + - "// Thickness of the outline\n" + - "uniform float u_offset;\n" + - "\n" + - "// Step to check for neighbors\n" + - "uniform float u_step;\n" + - "\n" + - "varying vec4 v_color;\n" + - "varying vec2 v_texCoord;\n" + - "\n" + - "#define ALPHA_VALUE_BORDER 0.5\n" + - "\n" + - "void main() {\n" + - " vec2 T = v_texCoord.xy;\n" + - "\n" + - " float alpha = 0.0;\n" + - " bool allin = true;\n" + - " for( float ix = -u_offset; ix < u_offset; ix += u_step )\n" + - " {\n" + - " for( float iy = -u_offset; iy < u_offset; iy += u_step )\n" + - " {\n" + - " float newAlpha = texture2D(u_texture, T + vec2(ix, iy) * u_viewportInverse).a;\n" + - " allin = allin && newAlpha > ALPHA_VALUE_BORDER;\n" + - " if (newAlpha > ALPHA_VALUE_BORDER && newAlpha >= alpha)\n" + - " {\n" + - " alpha = newAlpha;\n" + - " }\n" + - " }\n" + - " }\n" + - " if (allin)\n" + - " {\n" + - " alpha = 0.0;\n" + - " }\n" + - "\n" + - " gl_FragColor = vec4(u_color,alpha);\n" + - "}"; - - private final ShaderProgram shaderOutline = new ShaderProgram(sVertex, sFragment); - - public Graphics() { - batch = new SpriteBatch(); - ShaderProgram.pedantic = false; - } - public Graphics(Batch batch,float regionWidth0, float regionHeight0) { - this.batch=batch;bound(regionWidth0, regionHeight0); - } - public void bound(float regionWidth0, float regionHeight0) { - bounds = new Rectangle(0, 0, regionWidth0, regionHeight0); - regionHeight = regionHeight0; - visibleBounds = new Rectangle(bounds); - } - - public void begin(float regionWidth0, float regionHeight0) { - batch.begin(); - bounds = new Rectangle(0, 0, regionWidth0, regionHeight0); - regionHeight = regionHeight0; - visibleBounds = new Rectangle(bounds); - } - - public void end() { - if (batch.isDrawing()) { - batch.end(); - } - if (shapeRenderer.getCurrentType() != null) { - shapeRenderer.end(); - } - } - - public void dispose() { - batch.dispose(); - shapeRenderer.dispose(); - shaderOutline.dispose(); - } - - public SpriteBatch getBatch() { - return (SpriteBatch)batch; - } - - public boolean startClip() { - return startClip(0, 0, bounds.width, bounds.height); - } - public boolean startClip(float x, float y, float w, float h) { - batch.flush(); //must flush batch to prevent other things not rendering - - Rectangle clip = new Rectangle(adjustX(x), adjustY(y, h), w, h); - if (!Dtransforms.isEmpty()) { //transform position if needed - tmp.set(clip.x, clip.y, 0); - tmp.mul(batch.getTransformMatrix()); - float minX = tmp.x; - float maxX = minX; - float minY = tmp.y; - float maxY = minY; - tmp.set(clip.x + clip.width, clip.y, 0); - tmp.mul(batch.getTransformMatrix()); - if (tmp.x < minX) { minX = tmp.x; } - else if (tmp.x > maxX) { maxX = tmp.x; } - if (tmp.y < minY) { minY = tmp.y; } - else if (tmp.y > maxY) { maxY = tmp.y; } - tmp.set(clip.x + clip.width, clip.y + clip.height, 0); - tmp.mul(batch.getTransformMatrix()); - if (tmp.x < minX) { minX = tmp.x; } - else if (tmp.x > maxX) { maxX = tmp.x; } - if (tmp.y < minY) { minY = tmp.y; } - else if (tmp.y > maxY) { maxY = tmp.y; } - tmp.set(clip.x, clip.y + clip.height, 0); - tmp.mul(batch.getTransformMatrix()); - if (tmp.x < minX) { minX = tmp.x; } - else if (tmp.x > maxX) { maxX = tmp.x; } - if (tmp.y < minY) { minY = tmp.y; } - else if (tmp.y > maxY) { maxY = tmp.y; } - - clip.set(minX, minY, maxX - minX, maxY - minY); - } - if (!ScissorStack.pushScissors(clip)) { - failedClipCount++; //tracked failed clips to prevent calling popScissors on endClip - return false; - } - return true; - } - public void endClip() { - if (failedClipCount == 0) { - batch.flush(); //must flush batch to ensure stuffed rendered during clip respects that clip - ScissorStack.popScissors(); - } - else { - failedClipCount--; - } - } - - public void draw(FDisplayObject displayObj) { - if (displayObj.getWidth() <= 0 || displayObj.getHeight() <= 0) { - return; - } - - final Rectangle parentBounds = bounds; - bounds = new Rectangle(parentBounds.x + displayObj.getLeft(), parentBounds.y + displayObj.getTop(), displayObj.getWidth(), displayObj.getHeight()); - if (!Dtransforms.isEmpty()) { //transform screen position if needed by applying transform matrix to rectangle - updateScreenPosForRotation(displayObj); - } - else { - displayObj.screenPos.set(bounds); - } - - Rectangle intersection = Utils.getIntersection(bounds, visibleBounds); - if (intersection != null) { //avoid drawing object if it's not within visible region - final Rectangle backup = visibleBounds; - visibleBounds = intersection; - - if (displayObj.getRotate90()) { //use top-right corner of bounds as pivot point - startRotateTransform(displayObj.getWidth(), 0, -90); - updateScreenPosForRotation(displayObj); - } - else if (displayObj.getRotate180()) { //use center of bounds as pivot point - startRotateTransform(displayObj.getWidth() / 2, displayObj.getHeight() / 2, 180); - //screen position won't change for this object from a 180 degree rotation - } - - displayObj.draw(this); - - if (displayObj.getRotate90() || displayObj.getRotate180()) { - endTransform(); - } - - visibleBounds = backup; - } - - bounds = parentBounds; - } - - private void updateScreenPosForRotation(FDisplayObject displayObj) { - tmp.set(bounds.x, regionHeight - bounds.y, 0); - tmp.mul(batch.getTransformMatrix()); - tmp.y = regionHeight - tmp.y; - float minX = tmp.x; - float maxX = minX; - float minY = tmp.y; - float maxY = minY; - tmp.set(bounds.x + bounds.width, regionHeight - bounds.y, 0); - tmp.mul(batch.getTransformMatrix()); - tmp.y = regionHeight - tmp.y; - if (tmp.x < minX) { minX = tmp.x; } - else if (tmp.x > maxX) { maxX = tmp.x; } - if (tmp.y < minY) { minY = tmp.y; } - else if (tmp.y > maxY) { maxY = tmp.y; } - tmp.set(bounds.x + bounds.width, regionHeight - bounds.y - bounds.height, 0); - tmp.mul(batch.getTransformMatrix()); - tmp.y = regionHeight - tmp.y; - if (tmp.x < minX) { minX = tmp.x; } - else if (tmp.x > maxX) { maxX = tmp.x; } - if (tmp.y < minY) { minY = tmp.y; } - else if (tmp.y > maxY) { maxY = tmp.y; } - tmp.set(bounds.x, regionHeight - bounds.y - bounds.height, 0); - tmp.mul(batch.getTransformMatrix()); - tmp.y = regionHeight - tmp.y; - if (tmp.x < minX) { minX = tmp.x; } - else if (tmp.x > maxX) { maxX = tmp.x; } - if (tmp.y < minY) { minY = tmp.y; } - else if (tmp.y > maxY) { maxY = tmp.y; } - - displayObj.screenPos.set(minX, minY, maxX - minX, maxY - minY); - } - - public void drawLine(float thickness, FSkinColor skinColor, float x1, float y1, float x2, float y2) { - drawLine(thickness, skinColor.getColor(), x1, y1, x2, y2); - } - public void drawLine(float thickness, Color color, float x1, float y1, float x2, float y2) { - batch.end(); //must pause batch while rendering shapes - - if (thickness > 1) { - Gdx.gl.glLineWidth(thickness); - } - if (alphaComposite < 1) { - color = FSkinColor.alphaColor(color, color.a * alphaComposite); - } - boolean needSmoothing = (x1 != x2 && y1 != y2); - if (color.a < 1 || needSmoothing) { //enable blending so alpha colored shapes work properly - Gdx.gl.glEnable(GL_BLEND); - } - if (needSmoothing) { - Gdx.gl.glEnable(GL_LINE_SMOOTH); - } - - startShape(ShapeType.Line); - shapeRenderer.setColor(color); - shapeRenderer.line(adjustX(x1), adjustY(y1, 0), adjustX(x2), adjustY(y2, 0)); - endShape(); - - if (needSmoothing) { - Gdx.gl.glDisable(GL_LINE_SMOOTH); - } - if (color.a < 1 || needSmoothing) { - Gdx.gl.glDisable(GL_BLEND); - } - if (thickness > 1) { - Gdx.gl.glLineWidth(1); - } - - batch.begin(); - } - - public void drawArrow(float borderThickness, float arrowThickness, float arrowSize, FSkinColor skinColor, float x1, float y1, float x2, float y2) { - drawArrow(borderThickness, arrowThickness, arrowSize, skinColor.getColor(), x1, y1, x2, y2); - } - public void drawArrow(float borderThickness, float arrowThickness, float arrowSize, Color color, float x1, float y1, float x2, float y2) { - batch.end(); //must pause batch while rendering shapes - - if (alphaComposite < 1) { - color = FSkinColor.alphaColor(color, color.a * alphaComposite); - } - Gdx.gl.glEnable(GL_BLEND); - Gdx.gl.glEnable(GL_LINE_SMOOTH); - - float angle = new Vector2(x2 - x1, y2 - y1).angleRad(); - float perpRotation = (float)(Math.PI * 0.5f); - float arrowHeadRotation = (float)(Math.PI * 0.8f); - float arrowTipAngle = (float)(Math.PI - arrowHeadRotation); - float halfThickness = arrowThickness / 2; - - int index = 0; - float[] vertices = new float[14]; - Vector2 arrowCorner1 = new Vector2(x2 + arrowSize * (float)Math.cos(angle + arrowHeadRotation), y2 + arrowSize * (float)Math.sin(angle + arrowHeadRotation)); - Vector2 arrowCorner2 = new Vector2(x2 + arrowSize * (float)Math.cos(angle - arrowHeadRotation), y2 + arrowSize * (float)Math.sin(angle - arrowHeadRotation)); - float arrowCornerLen = (arrowCorner1.dst(arrowCorner2) - arrowThickness) / 2; - float arrowHeadLen = arrowSize * (float)Math.cos(arrowTipAngle); - index = addVertex(arrowCorner1.x, arrowCorner1.y, vertices, index); - index = addVertex(x2, y2, vertices, index); - index = addVertex(arrowCorner2.x, arrowCorner2.y, vertices, index); - index = addVertex(arrowCorner2.x + arrowCornerLen * (float)Math.cos(angle + perpRotation), arrowCorner2.y + arrowCornerLen * (float)Math.sin(angle + perpRotation), vertices, index); - index = addVertex(x1 + halfThickness * (float)Math.cos(angle - perpRotation), y1 + halfThickness * (float)Math.sin(angle - perpRotation), vertices, index); - index = addVertex(x1 + halfThickness * (float)Math.cos(angle + perpRotation), y1 + halfThickness * (float)Math.sin(angle + perpRotation), vertices, index); - index = addVertex(arrowCorner1.x + arrowCornerLen * (float)Math.cos(angle - perpRotation), arrowCorner1.y + arrowCornerLen * (float)Math.sin(angle - perpRotation), vertices, index); - - //draw arrow tail - startShape(ShapeType.Filled); - shapeRenderer.setColor(color); - shapeRenderer.rectLine(adjustX(x1), adjustY(y1, 0), - adjustX(x2 - arrowHeadLen * (float)Math.cos(angle)), //shorten tail to make room for arrow head - adjustY(y2 - arrowHeadLen * (float)Math.sin(angle), 0), arrowThickness); - - //draw arrow head - shapeRenderer.triangle(vertices[0], vertices[1], vertices[2], vertices[3], vertices[4], vertices[5]); - endShape(); - - //draw border around arrow - if (borderThickness > 1) { - Gdx.gl.glLineWidth(borderThickness); - } - startShape(ShapeType.Line); - shapeRenderer.setColor(Color.BLACK); - shapeRenderer.polygon(vertices); - endShape(); - if (borderThickness > 1) { - Gdx.gl.glLineWidth(1); - } - - Gdx.gl.glDisable(GL_LINE_SMOOTH); - Gdx.gl.glDisable(GL_BLEND); - - batch.begin(); - } - - private int addVertex(float x, float y, float[] vertices, int index) { - vertices[index] = adjustX(x); - vertices[index + 1] = adjustY(y, 0); - return index + 2; - } - - public void drawfillBorder(float thickness, Color color, float x, float y, float w, float h, float cornerRadius) { - drawRoundRect(thickness, color, x, y, w, h, cornerRadius); - fillRoundRect(color, x, y, w, h, cornerRadius); - } - - public void drawRoundRect(float thickness, FSkinColor skinColor, float x, float y, float w, float h, float cornerRadius) { - drawRoundRect(thickness, skinColor.getColor(), x, y, w, h, cornerRadius); - } - public void drawRoundRect(float thickness, Color color, float x, float y, float w, float h, float cornerRadius) { - batch.end(); //must pause batch while rendering shapes - - if (thickness > 1) { - Gdx.gl.glLineWidth(thickness); - } - if (alphaComposite < 1) { - color = FSkinColor.alphaColor(color, color.a * alphaComposite); - } - if (color.a < 1 || cornerRadius > 0) { //enable blending so alpha colored shapes work properly - Gdx.gl.glEnable(GL_BLEND); - } - if (cornerRadius > 0) { - Gdx.gl.glEnable(GL_LINE_SMOOTH); - } - - //adjust width/height so rectangle covers equivalent filled area - w = Math.round(w + 1); - h = Math.round(h + 1); - - startShape(ShapeType.Line); - shapeRenderer.setColor(color); - - shapeRenderer.arc(adjustX(x) + cornerRadius, adjustY(y + cornerRadius, 0), cornerRadius, 90f, 90f); - shapeRenderer.arc(adjustX(x) + w - cornerRadius, adjustY(y + cornerRadius, 0), cornerRadius, 0f, 90f); - shapeRenderer.arc(adjustX(x) + w - cornerRadius, adjustY(y + h - cornerRadius, 0), cornerRadius, 270, 90f); - shapeRenderer.arc(adjustX(x) + cornerRadius, adjustY(y + h - cornerRadius, 0), cornerRadius, 180, 90f); - shapeRenderer.rect(adjustX(x), adjustY(y+cornerRadius, h-cornerRadius*2), w, h-cornerRadius*2); - shapeRenderer.rect(adjustX(x+cornerRadius), adjustY(y, h), w-cornerRadius*2, h); - - endShape(); - - if (cornerRadius > 0) { - Gdx.gl.glDisable(GL_LINE_SMOOTH); - } - if (color.a < 1 || cornerRadius > 0) { - Gdx.gl.glDisable(GL_BLEND); - } - if (thickness > 1) { - Gdx.gl.glLineWidth(1); - } - - batch.begin(); - } - - public void fillRoundRect(FSkinColor skinColor, float x, float y, float w, float h, float cornerRadius) { - fillRoundRect(skinColor.getColor(), x, y, w, h, cornerRadius); - } - public void fillRoundRect(Color color, float x, float y, float w, float h, float cornerRadius) { - batch.end(); //must pause batch while rendering shapes - if (alphaComposite < 1) { - color = FSkinColor.alphaColor(color, color.a * alphaComposite); - } - if (color.a < 1) { //enable blending so alpha colored shapes work properly - Gdx.gl.glEnable(GL_BLEND); - } - startShape(ShapeType.Filled); - shapeRenderer.setColor(color); - shapeRenderer.arc(adjustX(x) + cornerRadius, adjustY(y + cornerRadius, 0), cornerRadius, 90f, 90f); - shapeRenderer.arc(adjustX(x) + w - cornerRadius, adjustY(y + cornerRadius, 0), cornerRadius, 0f, 90f); - shapeRenderer.arc(adjustX(x) + w - cornerRadius, adjustY(y + h - cornerRadius, 0), cornerRadius, 270, 90f); - shapeRenderer.arc(adjustX(x) + cornerRadius, adjustY(y + h - cornerRadius, 0), cornerRadius, 180, 90f); - shapeRenderer.rect(adjustX(x), adjustY(y+cornerRadius, h-cornerRadius*2), w, h-cornerRadius*2); - shapeRenderer.rect(adjustX(x+cornerRadius), adjustY(y, h), w-cornerRadius*2, h); - endShape(); - if (color.a < 1) { - Gdx.gl.glDisable(GL_BLEND); - } - batch.begin(); - } - - public void drawRect(float thickness, FSkinColor skinColor, float x, float y, float w, float h) { - drawRect(thickness, skinColor.getColor(), x, y, w, h); - } - public void drawRect(float thickness, Color color, float x, float y, float w, float h) { - batch.end(); //must pause batch while rendering shapes - - if (thickness > 1) { - Gdx.gl.glLineWidth(thickness); - } - if (alphaComposite < 1) { - color = FSkinColor.alphaColor(color, color.a * alphaComposite); - } - Gdx.gl.glEnable(GL_BLEND); - Gdx.gl.glEnable(GL_LINE_SMOOTH); //must be smooth to ensure edges aren't missed - - startShape(ShapeType.Line); - shapeRenderer.setColor(color); - shapeRenderer.rect(adjustX(x), adjustY(y, h), w, h); - endShape(); - - Gdx.gl.glDisable(GL_LINE_SMOOTH); - Gdx.gl.glDisable(GL_BLEND); - if (thickness > 1) { - Gdx.gl.glLineWidth(1); - } - - batch.begin(); - } - - public void fillRect(FSkinColor skinColor, float x, float y, float w, float h) { - fillRect(skinColor.getColor(), x, y, w, h); - } - public void fillRect(Color color, float x, float y, float w, float h) { - batch.end(); //must pause batch while rendering shapes - - if (alphaComposite < 1) { - color = FSkinColor.alphaColor(color, color.a * alphaComposite); - } - if (color.a < 1) { //enable blending so alpha colored shapes work properly - Gdx.gl.glEnable(GL_BLEND); - } - - startShape(ShapeType.Filled); - shapeRenderer.setColor(color); - shapeRenderer.rect(adjustX(x), adjustY(y, h), w, h); - endShape(); - - if (color.a < 1) { - Gdx.gl.glDisable(GL_BLEND); - } - - batch.begin(); - } - - public void drawCircle(float thickness, FSkinColor skinColor, float x, float y, float radius) { - drawCircle(thickness, skinColor.getColor(), x, y, radius); - } - public void drawCircle(float thickness, Color color, float x, float y, float radius) { - batch.end(); //must pause batch while rendering shapes - - if (thickness > 1) { - Gdx.gl.glLineWidth(thickness); - } - if (alphaComposite < 1) { - color = FSkinColor.alphaColor(color, color.a * alphaComposite); - } - Gdx.gl.glEnable(GL_BLEND); - Gdx.gl.glEnable(GL_LINE_SMOOTH); - - startShape(ShapeType.Line); - shapeRenderer.setColor(color); - shapeRenderer.circle(adjustX(x), adjustY(y, 0), radius); - endShape(); - - Gdx.gl.glDisable(GL_LINE_SMOOTH); - Gdx.gl.glDisable(GL_BLEND); - if (thickness > 1) { - Gdx.gl.glLineWidth(1); - } - - batch.begin(); - } - - public void fillCircle(FSkinColor skinColor, float x, float y, float radius) { - fillCircle(skinColor.getColor(), x, y, radius); - } - public void fillCircle(Color color, float x, float y, float radius) { - batch.end(); //must pause batch while rendering shapes - - if (alphaComposite < 1) { - color = FSkinColor.alphaColor(color, color.a * alphaComposite); - } - if (color.a < 1) { //enable blending so alpha colored shapes work properly - Gdx.gl.glEnable(GL_BLEND); - } - - startShape(ShapeType.Filled); - shapeRenderer.setColor(color); - shapeRenderer.circle(adjustX(x), adjustY(y, 0), radius); //TODO: Make smoother - endShape(); - - if (color.a < 1) { - Gdx.gl.glDisable(GL_BLEND); - } - - batch.begin(); - } - - public void fillTriangle(FSkinColor skinColor, float x1, float y1, float x2, float y2, float x3, float y3) { - fillTriangle(skinColor.getColor(), x1, y1, x2, y2, x3, y3); - } - public void fillTriangle(Color color, float x1, float y1, float x2, float y2, float x3, float y3) { - batch.end(); //must pause batch while rendering shapes - - if (alphaComposite < 1) { - color = FSkinColor.alphaColor(color, color.a * alphaComposite); - } - if (color.a < 1) { //enable blending so alpha colored shapes work properly - Gdx.gl.glEnable(GL_BLEND); - } - - startShape(ShapeType.Filled); - shapeRenderer.setColor(color); - shapeRenderer.triangle(adjustX(x1), adjustY(y1, 0), adjustX(x2), adjustY(y2, 0), adjustX(x3), adjustY(y3, 0)); - endShape(); - - if (color.a < 1) { - Gdx.gl.glDisable(GL_BLEND); - } - - batch.begin(); - } - - public void fillGradientRect(FSkinColor skinColor1, FSkinColor skinColor2, boolean vertical, float x, float y, float w, float h) { - fillGradientRect(skinColor1.getColor(), skinColor2.getColor(), vertical, x, y, w, h); - } - public void fillGradientRect(FSkinColor skinColor1, Color color2, boolean vertical, float x, float y, float w, float h) { - fillGradientRect(skinColor1.getColor(), color2, vertical, x, y, w, h); - } - public void fillGradientRect(Color color1, FSkinColor skinColor2, boolean vertical, float x, float y, float w, float h) { - fillGradientRect(color1, skinColor2.getColor(), vertical, x, y, w, h); - } - public void fillGradientRect(Color color1, Color color2, boolean vertical, float x, float y, float w, float h) { - batch.end(); //must pause batch while rendering shapes - - if (alphaComposite < 1) { - color1 = FSkinColor.alphaColor(color1, color1.a * alphaComposite); - color2 = FSkinColor.alphaColor(color2, color2.a * alphaComposite); - } - boolean needBlending = (color1.a < 1 || color2.a < 1); - if (needBlending) { //enable blending so alpha colored shapes work properly - Gdx.gl.glEnable(GL_BLEND); - } - - Color topLeftColor = color1; - Color topRightColor = vertical ? color1 : color2; - Color bottomLeftColor = vertical ? color2 : color1; - Color bottomRightColor = color2; - - startShape(ShapeType.Filled); - shapeRenderer.rect(adjustX(x), adjustY(y, h), w, h, bottomLeftColor, bottomRightColor, topRightColor, topLeftColor); - endShape(); - - if (needBlending) { - Gdx.gl.glDisable(GL_BLEND); - } - - batch.begin(); - } - - private void startShape(ShapeType shapeType) { - if (!Dtransforms.isEmpty()) { - //must copy matrix before starting shape if transformed - shapeRenderer.setTransformMatrix(batch.getTransformMatrix()); - } - shapeRenderer.begin(shapeType); - } - - private void endShape() { - shapeRenderer.end(); - } - - public void setAlphaComposite(float alphaComposite0) { - alphaComposite = alphaComposite0; - batch.setColor(new Color(1, 1, 1, alphaComposite)); - } - public void resetAlphaComposite() { - alphaComposite = 1; - batch.setColor(Color.WHITE); - } - public float getfloatAlphaComposite() { return alphaComposite; } - - public void drawBorderImage(FImage image, Color borderColor, Color tintColor, float x, float y, float w, float h, boolean tint) { - float oldalpha = alphaComposite; - if(tint && !tintColor.equals(borderColor)){ - drawRoundRect(2f, borderLining(borderColor.toString()), x, y, w, h, (h-w)/12); - fillRoundRect(tintColor, x, y, w, h, (h-w)/12); - } else { - image.draw(this, x, y, w, h); - fillRoundRect(borderColor, x, y, w, h, (h-w)/10);//show corners edges - } - setAlphaComposite(oldalpha); - } - public void drawborderImage(Color borderColor, float x, float y, float w, float h) { - float oldalpha = alphaComposite; - fillRoundRect(borderColor, x, y, w, h, (h-w)/12); - setAlphaComposite(oldalpha); - } - public void drawImage(FImage image, Color borderColor, float x, float y, float w, float h) { - image.draw(this, x, y, w, h); - fillRoundRect(borderColor, x+1, y+1, w-1.5f, h-1.5f, (h-w)/10);//used by zoom let some edges show... - } - public void drawImage(FImage image, float x, float y, float w, float h) { - drawImage(image, x, y, w, h, false); - } - public void drawImage(FImage image, float x, float y, float w, float h, boolean withDarkOverlay) { - image.draw(this, x, y, w, h); - if(withDarkOverlay){ - float oldalpha = alphaComposite; - setAlphaComposite(0.4f); - fillRect(Color.BLACK, x, y, w, h); - setAlphaComposite(oldalpha); - } - } - public void drawImage(Texture image, float x, float y, float w, float h) { - batch.draw(image, adjustX(x), adjustY(y, h), w, h); - } - public void drawImage(TextureRegion image, float x, float y, float w, float h) { - if (image != null) - batch.draw(image, adjustX(x), adjustY(y, h), w, h); - } - public void drawImage(TextureRegion image, TextureRegion glowImageReference, float x, float y, float w, float h, Color glowColor, boolean selected) { - if (image == null || glowImageReference == null) - return; - //1st image is the image on top of the shader, 2nd image is for the outline reference for the shader glow... - // if the 1st image don't have transparency in the middle (only on the sides, top and bottom, use the 1st image as outline reference... - if (!selected) { - batch.draw(image, adjustX(x), adjustY(y, h), w, h); - } else { - batch.end(); - shaderOutline.bind(); - shaderOutline.setUniformf("u_viewportInverse", new Vector2(1f / w, 1f / h)); - shaderOutline.setUniformf("u_offset", 3f); - shaderOutline.setUniformf("u_step", Math.min(1f, w / 70f)); - shaderOutline.setUniformf("u_color", new Vector3(glowColor.r, glowColor.g, glowColor.b)); - batch.setShader(shaderOutline); - batch.begin(); - //glow - batch.draw(glowImageReference, adjustX(x), adjustY(y, h), w, h); - batch.end(); - batch.setShader(null); - batch.begin(); - //img - batch.draw(image, adjustX(x), adjustY(y, h), w, h); - } - } - public void drawDeckBox(FImage cardArt, float scale, TextureRegion image, TextureRegion glowImageReference, float x, float y, float w, float h, Color glowColor, boolean selected) { - if (image == null || glowImageReference == null) - return; - float yBox = y-(h*0.25f); - if (!selected) { - cardArt.draw(this,x+((w-w*scale)/2), y+((h-h*scale)/3f), w*scale, h*scale/1.85f); - batch.draw(image, adjustX(x), adjustY(yBox, h), w, h); - } else { - batch.end(); - shaderOutline.bind(); - shaderOutline.setUniformf("u_viewportInverse", new Vector2(1f / w, 1f / h)); - shaderOutline.setUniformf("u_offset", 3f); - shaderOutline.setUniformf("u_step", Math.min(1f, w / 70f)); - shaderOutline.setUniformf("u_color", new Vector3(glowColor.r, glowColor.g, glowColor.b)); - batch.setShader(shaderOutline); - batch.begin(); - //glow - batch.draw(glowImageReference, adjustX(x), adjustY(yBox, h), w, h); - batch.end(); - batch.setShader(null); - batch.begin(); - //cardart - cardArt.draw(this,x+((w-w*scale)/2), y+((h-h*scale)/3f), w*scale, h*scale/1.85f); - //deckbox - batch.draw(image, adjustX(x), adjustY(yBox, h), w, h); - } - } - - public void drawRepeatingImage(Texture image, float x, float y, float w, float h) { - if (startClip(x, y, w, h)) { //only render if clip successful, otherwise it will escape bounds - int tilesW = (int)(w / image.getWidth()) + 1; - int tilesH = (int)(h / image.getHeight()) + 1; - batch.draw(image, adjustX(x), adjustY(y, h), - image.getWidth() * tilesW, - image.getHeight() * tilesH, - 0, tilesH, tilesW, 0); - } - endClip(); - } - - //draw vertically flipped image - public void drawFlippedImage(Texture image, float x, float y, float w, float h) { - batch.draw(image, adjustX(x), adjustY(y, h), w, h, 0, 0, image.getWidth(), image.getHeight(), false, true); - } - - public void drawImageWithTransforms(TextureRegion image, float x, float y, float w, float h, float rotation, boolean flipX, boolean flipY) { - float originX = x + w / 2; - float originY = y + h / 2; - batch.draw(image.getTexture(), adjustX(x), adjustY(y, h), originX - x, h - (originY - y), w, h, 1, 1, rotation, image.getRegionX(), image.getRegionY(), image.getRegionWidth(), image.getRegionHeight(), flipX, flipY); - } - - public void setProjectionMatrix(Matrix4 matrix) { - batch.setProjectionMatrix(matrix); - shapeRenderer.setProjectionMatrix(matrix); - } - - public void startRotateTransform(float originX, float originY, float rotation) { - batch.end(); - Dtransforms.addFirst(new Matrix4(batch.getTransformMatrix().idt())); //startshape is using this above as reference - transformCount++; - batch.getTransformMatrix().idt().translate(adjustX(originX), adjustY(originY, 0), 0).rotate(Vector3.Z, rotation).translate(-adjustX(originX), -adjustY(originY, 0), 0); - batch.begin(); - } - - public void endTransform() { - batch.end(); - shapeRenderer.setTransformMatrix(batch.getTransformMatrix().idt()); - Dtransforms.removeFirst(); - transformCount--; - if(transformCount != Dtransforms.size()) { - System.err.println(String.format("Stack count: %d, transformCount: %d", Dtransforms.size(), transformCount)); - transformCount = 0; - Dtransforms.clear(); - } - batch.getTransformMatrix().idt(); //reset - shapeRenderer.getTransformMatrix().idt(); //reset - batch.begin(); - } - - public void drawRotatedImage(Texture image, float x, float y, float w, float h, float originX, float originY, float rotation) { - drawRotatedImage(image, x, y, w, h, originX, originY, 0, 0, image.getWidth(), image.getHeight(), rotation); - } - public void drawRotatedImage(TextureRegion image, float x, float y, float w, float h, float originX, float originY, float rotation) { - drawRotatedImage(image.getTexture(), x, y, w, h, originX, originY, image.getRegionX(), image.getRegionY(), image.getRegionWidth(), image.getRegionHeight(), rotation); - } - public void drawRotatedImage(Texture image, float x, float y, float w, float h, float originX, float originY, int srcX, int srcY, int srcWidth, int srcHeight, float rotation) { - batch.draw(image, adjustX(x), adjustY(y, h), originX - x, h - (originY - y), w, h, 1, 1, rotation, srcX, srcY, srcWidth, srcHeight, false, false); - } - - public void drawText(String text, FSkinFont font, FSkinColor skinColor, float x, float y, float w, float h, boolean wrap, int horzAlignment, boolean centerVertically) { - drawText(text, font, skinColor.getColor(), x, y, w, h, wrap, horzAlignment, centerVertically); - } - public void drawText(String text, FSkinFont font, Color color, float x, float y, float w, float h, boolean wrap, int horzAlignment, boolean centerVertically) { - if (text == null) - return; - if (alphaComposite < 1) { - color = FSkinColor.alphaColor(color, color.a * alphaComposite); - } - if (color.a < 1) { //enable blending so alpha colored shapes work properly - Gdx.gl.glEnable(GL_BLEND); - } - - TextBounds textBounds; - if (wrap) { - textBounds = font.getWrappedBounds(text, w); - } - else { - textBounds = font.getMultiLineBounds(text); - } - - boolean needClip = false; - - while (textBounds.width > w || textBounds.height > h) { - if (font.canShrink()) { //shrink font to fit if possible - font = font.shrink(); - if (wrap) { - textBounds = font.getWrappedBounds(text, w); - } - else { - textBounds = font.getMultiLineBounds(text); - } - } - else { - needClip = true; - break; - } - } - - if (needClip) { //prevent text flowing outside region if couldn't shrink it to fit - startClip(x, y, w, h); - } - - float textHeight = textBounds.height; - if (h > textHeight && centerVertically) { - y += (h - textHeight) / 2; - } - - font.draw(batch, text, color, adjustX(x), adjustY(y, 0), w, wrap, horzAlignment); - - if (needClip) { - endClip(); - } - - if (color.a < 1) { - Gdx.gl.glDisable(GL_BLEND); - } - } - - //use nifty trick with multiple text renders to draw outlined text - public void drawOutlinedText(String text, FSkinFont skinFont, Color textColor, Color outlineColor, float x, float y, float w, float h, boolean wrap, int horzAlignment, boolean centerVertically) { - drawText(text, skinFont, outlineColor, x - 1, y, w, h, wrap, horzAlignment, centerVertically); - drawText(text, skinFont, outlineColor, x, y - 1, w, h, wrap, horzAlignment, centerVertically); - drawText(text, skinFont, outlineColor, x - 1, y - 1, w, h, wrap, horzAlignment, centerVertically); - drawText(text, skinFont, outlineColor, x + 1, y, w, h, wrap, horzAlignment, centerVertically); - drawText(text, skinFont, outlineColor, x, y + 1, w, h, wrap, horzAlignment, centerVertically); - drawText(text, skinFont, outlineColor, x + 1, y + 1, w, h, wrap, horzAlignment, centerVertically); - drawText(text, skinFont, textColor, x, y, w, h, wrap, horzAlignment, centerVertically); - } - - public float adjustX(float x) { - return x + bounds.x; - } - - public float adjustY(float y, float height) { - return regionHeight - y - bounds.y - height; //flip y-axis - } - public Color borderLining(String c){ - if (c == null || c == "") - return Color.valueOf("#fffffd"); - int c_r = Integer.parseInt(c.substring(0,2),16); - int c_g = Integer.parseInt(c.substring(2,4),16); - int c_b = Integer.parseInt(c.substring(4,6),16); - int brightness = ((c_r * 299) + (c_g * 587) + (c_b * 114)) / 1000; - return brightness > 155 ? Color.valueOf("#171717") : Color.valueOf("#fffffd"); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/GuiMobile.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/GuiMobile.java deleted file mode 100644 index 70c9eda9579..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/GuiMobile.java +++ /dev/null @@ -1,329 +0,0 @@ -package forge.adventure.libgdxgui; - -import com.badlogic.gdx.Application.ApplicationType; -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.Texture; -import com.google.common.base.Function; -import forge.adventure.libgdxgui.assets.*; -import forge.adventure.libgdxgui.card.CardRenderer; -import forge.adventure.libgdxgui.deck.FDeckViewer; -import forge.adventure.libgdxgui.error.BugReportDialog; -import forge.adventure.libgdxgui.screens.LoadingOverlay; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.screens.settings.GuiDownloader; -import forge.adventure.libgdxgui.sound.AudioClip; -import forge.adventure.libgdxgui.sound.AudioMusic; -import forge.adventure.libgdxgui.toolbox.FOptionPane; -import forge.adventure.libgdxgui.toolbox.GuiChoose; -import forge.adventure.libgdxgui.util.LibGDXImageFetcher; -import forge.deck.Deck; -import forge.gamemodes.match.HostedMatch; -import forge.gui.download.GuiDownloadService; -import forge.gui.interfaces.IGuiBase; -import forge.gui.interfaces.IGuiGame; -import forge.item.PaperCard; -import forge.localinstance.properties.ForgeConstants; -import forge.localinstance.skin.FSkinProp; -import forge.localinstance.skin.ISkinImage; -import forge.sound.IAudioClip; -import forge.sound.IAudioMusic; -import forge.util.*; - -import java.io.File; -import java.util.Collection; -import java.util.List; - -public class GuiMobile implements IGuiBase { - private final String assetsDir; - private final ImageFetcher imageFetcher = new LibGDXImageFetcher(); - - public GuiMobile(final String assetsDir0) { - assetsDir = assetsDir0; - } - - @Override - public boolean isRunningOnDesktop() { - if(Gdx.app==null) - return true; - return Gdx.app.getType() == ApplicationType.Desktop; - } - - @Override - public boolean isLibgdxPort() { - return true; - } - - @Override - public String getCurrentVersion() { - return Forge.CURRENT_VERSION; - } - - @Override - public String getAssetsDir() { - return assetsDir; - } - - @Override - public ImageFetcher getImageFetcher() { - return imageFetcher; - } - - @Override - public void invokeInEdtNow(final Runnable proc) { - proc.run(); - Gdx.graphics.requestRendering(); //must request rendering in case this procedure wasn't triggered by a local event - } - - @Override - public void invokeInEdtLater(final Runnable proc) { - Gdx.app.postRunnable(proc); - } - - @Override - public void invokeInEdtAndWait(final Runnable proc) { - if (isGuiThread()) { - proc.run(); - } - else { - new WaitRunnable() { - @Override - public void run() { - proc.run(); - } - }.invokeAndWait(); - } - } - - @Override - public boolean isGuiThread() { - return !ThreadUtil.isGameThread(); - } - - @Override - public ISkinImage getSkinIcon(final FSkinProp skinProp) { - if (skinProp == null) { return null; } - return FSkin.getImages().get(skinProp); - } - - @Override - public ISkinImage getUnskinnedIcon(final String path) { - if (isGuiThread()) { - return new FTextureImage(new Texture(Gdx.files.absolute(path))); - } - - //use a delay load image to avoid an error if called from background thread - return new FDelayLoadImage(path); - } - - @Override - public ISkinImage getCardArt(final PaperCard card) { - return CardRenderer.getCardArt(card); - } - - @Override - public ISkinImage getCardArt(final PaperCard card, final boolean backFace) { - return CardRenderer.getCardArt(card, backFace); - } - - @Override - public ISkinImage createLayeredImage(final FSkinProp background, final String overlayFilename, final float opacity) { - return new FBufferedImage(background.getWidth(), background.getHeight(), opacity) { - @Override - protected void draw(final Graphics g, final float w, final float h) { - g.drawImage(FSkin.getImages().get(background), 0, 0, background.getWidth(), background.getHeight()); - - if (FileUtil.doesFileExist(overlayFilename)) { - try { - final Texture overlay = new Texture(Gdx.files.absolute(overlayFilename)); - g.drawImage(overlay, (background.getWidth() - overlay.getWidth()) / 2, (background.getHeight() - overlay.getHeight()) / 2, overlay.getWidth(), overlay.getHeight()); - } catch (final Exception e) { - } - } - - Gdx.graphics.requestRendering(); //ensure image appears right away - } - }; - } - - @Override - public void showImageDialog(final ISkinImage image, final String message, final String title) { - new WaitCallback() { - @Override - public void run() { - FOptionPane.showMessageDialog(message, title, (FImage)image, this); - } - }.invokeAndWait(); - } - - @Override - public int showOptionDialog(final String message, final String title, final FSkinProp icon, final List options, final int defaultOption) { - return new WaitCallback() { - @Override - public void run() { - FOptionPane.showOptionDialog(message, title, icon == null ? null : FSkin.getImages().get(icon), options, defaultOption, this); - } - }.invokeAndWait(); - } - - @Override - public String showInputDialog(final String message, final String title, final FSkinProp icon, final String initialInput, final List inputOptions) { - return new WaitCallback() { - @Override - public void run() { - FOptionPane.showInputDialog(message, title, initialInput, inputOptions, this); - } - }.invokeAndWait(); - } - - @Override - public List getChoices(final String message, final int min, final int max, final Collection choices, final T selected, final Function display) { - return new WaitCallback>() { - @Override - public void run() { - GuiChoose.getChoices(message, min, max, choices, selected, display, this); - } - }.invokeAndWait(); - } - - @Override - public List order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax, - final List sourceChoices, final List destChoices) { - return new WaitCallback>() { - @Override - public void run() { - GuiChoose.order(title, top, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices, null, this); - } - }.invokeAndWait(); - } - - @Override - public void showBugReportDialog(final String title, final String text, final boolean showExitAppBtn) { - BugReportDialog.show(title, text, showExitAppBtn); - } - - @Override - public void showCardList(final String title, final String message, final List list) { - final Deck deck = new Deck(title + " - " + message); - deck.getMain().addAllFlat(list); - FDeckViewer.show(deck, true); - } - - @Override - public boolean showBoxedProduct(final String title, final String message, final List list) { - final Deck deck = new Deck(title + " - " + message); //TODO: Make this nicer - deck.getMain().addAllFlat(list); - FDeckViewer.show(deck); - return false; - } - - @Override - public PaperCard chooseCard(final String title, final String message, final List list) { - return new WaitCallback() { - @Override - public void run() { - GuiChoose.one(title + " - " + message, list, this); - } - }.invokeAndWait(); - } - - @Override - public int getAvatarCount() { - if (FSkin.isLoaded()) { - return FSkin.getAvatars().size(); - } - return 0; - } - - @Override - public int getSleevesCount() { - if (FSkin.isLoaded()) { - return FSkin.getSleeves().size(); - } - return 0; - } - - @Override - public String showFileDialog(final String title, final String defaultDir) { - return ForgeConstants.USER_GAMES_DIR + "Test.fgs"; //TODO: Show dialog - } - - @Override - public File getSaveFile(final File defaultFile) { - return defaultFile; //TODO: Show dialog - } - - @Override - public void download(final GuiDownloadService service, final Callback callback) { - new GuiDownloader(service, callback).show(); - } - - @Override - public void refreshSkin() { - //todo refresh skin selector - } - - @Override - public void copyToClipboard(final String text) { - Forge.getClipboard().setContents(text); - } - - @Override - public void browseToUrl(final String url) { - Gdx.net.openURI(url); - } - - @Override - public IAudioClip createAudioClip(final String filename) { - return AudioClip.createClip(ForgeConstants.SOUND_DIR + filename); - } - - @Override - public IAudioMusic createAudioMusic(final String filename) { - return new AudioMusic(filename); - } - - @Override - public void startAltSoundSystem(final String filename, final boolean isSynchronized) { - //TODO: Support alt sound system - } - - @Override - public void clearImageCache() { - ImageCache.clear(); - } - - @Override - public void showSpellShop() { - - } - - @Override - public void showBazaar() { - - } - - @Override - public IGuiGame getNewGuiGame() { - return MatchController.instance; - } - - @Override - public HostedMatch hostMatch() { - return MatchController.hostMatch(); - } - - @Override - public void runBackgroundTask(String message, Runnable task) { - LoadingOverlay.runBackgroundTask(message, task); - } - - @Override - public String encodeSymbols(String str, boolean formatReminderText) { - return str; //not needed for mobile - } - - @Override - public void preventSystemSleep(boolean preventSleep) { - Forge.getDeviceAdapter().preventSystemSleep(preventSleep); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/animation/AbilityEffect.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/animation/AbilityEffect.java deleted file mode 100644 index 852321dc7c5..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/animation/AbilityEffect.java +++ /dev/null @@ -1,37 +0,0 @@ -package forge.adventure.libgdxgui.animation; - -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.sound.AudioClip; -import forge.localinstance.properties.ForgeConstants; -import forge.localinstance.properties.ForgePreferences; -import forge.model.FModel; - -public enum AbilityEffect { - LIGHTNING("lightning.gif", "lightning.wav"); - - private final String gif, wav; - private forge.adventure.libgdxgui.animation.GifAnimation animation; - private AudioClip soundClip; - - AbilityEffect(String gif0, String wav0) { - gif = gif0; - wav = wav0; - } - - public void start() { - if (animation == null) { - animation = new GifAnimation(ForgeConstants.EFFECTS_DIR + gif); - } - if (soundClip == null) { - soundClip = AudioClip.createClip(ForgeConstants.EFFECTS_DIR + wav); - } - soundClip.play(FModel.getPreferences().getPrefInt(ForgePreferences.FPref.UI_VOL_SOUNDS)/100f); - animation.start(); - } - - public void draw(Graphics g, float x, float y, float w, float h) { - if (animation != null) { - animation.draw(g, x, y, w, h); - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/animation/ForgeAnimation.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/animation/ForgeAnimation.java deleted file mode 100644 index 1b3211a9388..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/animation/ForgeAnimation.java +++ /dev/null @@ -1,69 +0,0 @@ -package forge.adventure.libgdxgui.animation; - -import com.badlogic.gdx.Gdx; -import forge.adventure.libgdxgui.Forge; - -import java.util.ArrayList; -import java.util.List; - -public abstract class ForgeAnimation { - private static final List activeAnimations = new ArrayList<>(); - // A guard against inspecting activeAnimations while it's in the process of being edited - private static boolean changingActiveAnimations = false; - - public void start() { - if (activeAnimations.contains(this)) { return; } //prevent starting the same animation multiple times - - activeAnimations.add(this); - if (activeAnimations.size() == 1 && !changingActiveAnimations) { //if first animation being started, ensure continuous rendering turned on - Forge.startContinuousRendering(); - } - } - - public void stop() { - if (!activeAnimations.contains(this)) { return; } //prevent stopping the same animation multiple times - - activeAnimations.remove(this); - onEnd(false); - if (activeAnimations.isEmpty()) { //when all animations have stopped, turn continuous rendering back off - Forge.stopContinuousRendering(); - } - } - - public static void advanceAll() { - if (activeAnimations.isEmpty()) { return; } - - float dt = Gdx.graphics.getDeltaTime(); - for (int i = 0; i < activeAnimations.size(); i++) { - if (!activeAnimations.get(i).advance(dt)) { - // Without this guard, there is leaky behavior when a new animation is started - // via the onEnd callback of a finishing animation; this is because the length - // of the list is in the process of changing from 1 to 0 to 1 again, so - // stopContinuousRendering() won't be called in this function (so it's - // important to not allow startContinuousRendering() to be called either). - changingActiveAnimations = true; - activeAnimations.remove(i).onEnd(false); - changingActiveAnimations = false; - i--; - } - } - - if (activeAnimations.isEmpty()) { //when all animations have ended, turn continuous rendering back off - Forge.stopContinuousRendering(); - } - } - - public static void endAll() { - if (activeAnimations.isEmpty()) { return; } - - for (ForgeAnimation animation : activeAnimations) { - animation.onEnd(true); - } - activeAnimations.clear(); - Forge.stopContinuousRendering(); - } - - //return true if animation should continue, false to stop the animation - protected abstract boolean advance(float dt); - protected abstract void onEnd(boolean endingAll); -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/animation/ForgeTransition.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/animation/ForgeTransition.java deleted file mode 100644 index 795a84963f2..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/animation/ForgeTransition.java +++ /dev/null @@ -1,101 +0,0 @@ -package forge.adventure.libgdxgui.animation; - -import com.badlogic.gdx.math.Rectangle; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.toolbox.FOverlay; - -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.Map; - -public class ForgeTransition extends ForgeAnimation { - private static final FOverlay overlay = new FOverlay(null) { - @Override protected void doLayout(final float width, final float height) { - } - }; - private static final Map transitionLookup = new LinkedHashMap<>(); - - public static void queue(final FDisplayObject obj, final Rectangle destBounds, final float duration, final Runnable onFinished) { - queue(obj, destBounds, duration, 0, false, onFinished); - } - public static void queue(final FDisplayObject obj, final Rectangle destBounds, final float duration, final float arcAmount, final boolean arcOriginBelow, final Runnable onFinished) { - TransitionObject transitionObj = transitionLookup.get(obj); - if (transitionObj == null) { - transitionObj = new TransitionObject(obj); - transitionLookup.put(obj, transitionObj); - overlay.add(transitionObj); - obj.setVisible(false); //hide original object while transition in progress - } - final ForgeTransition transition = new ForgeTransition(transitionObj, destBounds, duration, arcAmount, arcOriginBelow, onFinished); - transitionObj.transitions.add(transition); - if (transitionObj.transitions.size() == 1) { - transition.start(); //start transition right away if first transition added - overlay.setVisible(true); - } - } - - private final TransitionObject obj; - /*private final Rectangle destBounds; - private final float duration; - private final float arcAmount; - private final boolean arcOriginBelow;*/ - private final Runnable onFinished; - - private ForgeTransition(final TransitionObject obj0, final Rectangle destBounds0, final float duration0, final float arcAmount0, final boolean arcOriginBelow0, final Runnable onFinished0) { - obj = obj0; - /*destBounds = destBounds0; - duration = duration0; - arcAmount = arcAmount0; - arcOriginBelow = arcOriginBelow0;*/ - onFinished = onFinished0; - } - - @Override - protected boolean advance(final float dt) { - return false; - } - - @Override - protected void onEnd(final boolean endingAll) { - if (onFinished != null) { - onFinished.run(); - } - - if (endingAll) { - transitionLookup.clear(); - return; - } - - final int index = obj.transitions.indexOf(this); - obj.transitions.remove(index); - if (index == 0) { - if (obj.transitions.isEmpty()) { - transitionLookup.remove(obj.originalObj); - overlay.remove(obj); - obj.originalObj.setVisible(true); - if (transitionLookup.isEmpty()) { - overlay.setVisible(false); - } - } - else { - obj.transitions.getFirst().start(); //start next transition if needed - } - } - } - - private static class TransitionObject extends FDisplayObject { - private final FDisplayObject originalObj; - private final LinkedList transitions = new LinkedList<>(); - - private TransitionObject(final FDisplayObject originalObj0) { - originalObj = originalObj0; - setBounds(originalObj.screenPos.x, originalObj.screenPos.y, originalObj.getWidth(), originalObj.getHeight()); - } - - @Override - public void draw(final Graphics g) { - originalObj.draw(g); - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/animation/GifAnimation.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/animation/GifAnimation.java deleted file mode 100644 index bd7dff8d919..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/animation/GifAnimation.java +++ /dev/null @@ -1,40 +0,0 @@ -package forge.adventure.libgdxgui.animation; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.g2d.Animation; -import com.badlogic.gdx.graphics.g2d.Animation.PlayMode; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import forge.adventure.libgdxgui.Graphics; - -public class GifAnimation extends ForgeAnimation { - private final Animation animation; - private TextureRegion currentFrame; - private float stateTime; - - public GifAnimation(String filename) { - animation = GifDecoder.loadGIFAnimation(PlayMode.NORMAL, Gdx.files.absolute(filename).read()); - } - - @Override - public void start() { - currentFrame = animation.getKeyFrame(0); - super.start(); - } - - @Override - protected boolean advance(float dt) { - stateTime += dt; - currentFrame = animation.getKeyFrame(stateTime); - return currentFrame != null; - } - - public void draw(Graphics g, float x, float y, float w, float h) { - if (currentFrame != null) { - g.drawImage(currentFrame, x, y, w, h); - } - } - - @Override - protected void onEnd(boolean endingAll) { - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/animation/GifDecoder.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/animation/GifDecoder.java deleted file mode 100644 index 1eb44dea6fc..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/animation/GifDecoder.java +++ /dev/null @@ -1,737 +0,0 @@ -package forge.adventure.libgdxgui.animation; - -/* Copyright by Johannes Borchardt */ -/* LibGdx conversion 2014 by Anton Persson */ -/* Released under Apache 2.0 */ -/* https://code.google.com/p/animated-gifs-in-android/ */ - -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.Animation; -import com.badlogic.gdx.graphics.g2d.Animation.PlayMode; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.utils.Array; - -import java.io.InputStream; -import java.util.Vector; - -public class GifDecoder { - /** - * File read status: No errors. - */ - public static final int STATUS_OK = 0; - /** - * File read status: Error decoding file (may be partially decoded) - */ - public static final int STATUS_FORMAT_ERROR = 1; - /** - * File read status: Unable to open source. - */ - public static final int STATUS_OPEN_ERROR = 2; - /** max decoder pixel stack size */ - protected static final int MAX_STACK_SIZE = 4096; - protected InputStream in; - protected int status; - protected int width; // full image width - protected int height; // full image height - protected boolean gctFlag; // global color table used - protected int gctSize; // size of global color table - protected int loopCount = 1; // iterations; 0 = repeat forever - protected int[] gct; // global color table - protected int[] lct; // local color table - protected int[] act; // active color table - protected int bgIndex; // background color index - protected int bgColor; // background color - protected int lastBgColor; // previous bg color - protected int pixelAspect; // pixel aspect ratio - protected boolean lctFlag; // local color table flag - protected boolean interlace; // interlace flag - protected int lctSize; // local color table size - protected int ix, iy, iw, ih; // current image rectangle - protected int lrx, lry, lrw, lrh; - protected DixieMap image; // current frame - protected DixieMap lastPixmap; // previous frame - protected byte[] block = new byte[256]; // current data block - protected int blockSize = 0; // block size last graphic control extension info - protected int dispose = 0; // 0=no action; 1=leave in place; 2=restore to bg; 3=restore to prev - protected int lastDispose = 0; - protected boolean transparency = false; // use transparent color - protected int delay = 0; // delay in milliseconds - protected int transIndex; // transparent color index - // LZW decoder working arrays - protected short[] prefix; - protected byte[] suffix; - protected byte[] pixelStack; - protected byte[] pixels; - protected Vector frames; // frames read from current file - protected int frameCount; - - private static class DixieMap extends Pixmap { - DixieMap(int w, int h, Format f) { - super(w, h, f); - } - - DixieMap(int[] data, int w, int h, Format f) { - super(w, h, f); - - int x, y; - - for(y = 0; y < h; y++) { - for(x = 0; x < w; x++) { - int pxl_ARGB8888 = data[x + y * w]; - int pxl_RGBA8888 = - ((pxl_ARGB8888 >> 24) & 0x000000ff) | ((pxl_ARGB8888 << 8) & 0xffffff00); - // convert ARGB8888 > RGBA8888 - drawPixel(x, y, pxl_RGBA8888); - } - } - } - - void getPixels(int[] pixels, int offset, int stride, int x, int y, int width, int height) { - java.nio.ByteBuffer bb = getPixels(); - - int k, l; - - for(k = y; k < y + height; k++) { - int _offset = offset; - for(l = x; l < x + width; l++) { - int pxl = bb.getInt(4 * (l + k * width)); - - // convert RGBA8888 > ARGB8888 - pixels[_offset++] = ((pxl >> 8) & 0x00ffffff) | ((pxl << 24) & 0xff000000); - } - offset += stride; - } - } - } - - private static class GifFrame { - public GifFrame(DixieMap im, int del) { - image = im; - delay = del; - } - - public DixieMap image; - public int delay; - } - - /** - * Gets display duration for specified frame. - * - * @param n - * int index of frame - * @return delay in milliseconds - */ - public int getDelay(int n) { - delay = -1; - if ((n >= 0) && (n < frameCount)) { - delay = frames.elementAt(n).delay; - } - return delay; - } - - /** - * Gets the number of frames read from file. - * - * @return frame count - */ - public int getFrameCount() { - return frameCount; - } - - /** - * Gets the first (or only) image read. - * - * @return BufferedPixmap containing first frame, or null if none. - */ - public Pixmap getPixmap() { - return getFrame(0); - } - - /** - * Gets the "Netscape" iteration count, if any. A count of 0 means repeat indefinitely. - * - * @return iteration count if one was specified, else 1. - */ - public int getLoopCount() { - return loopCount; - } - - /** - * Creates new frame image from current data (and previous frames as specified by their disposition codes). - */ - protected void setPixels() { - // expose destination image's pixels as int array - int[] dest = new int[width * height]; - // fill in starting image contents based on last image's dispose code - if (lastDispose > 0) { - if (lastDispose == 3) { - // use image before last - int n = frameCount - 2; - if (n > 0) { - lastPixmap = getFrame(n - 1); - } else { - lastPixmap = null; - } - } - if (lastPixmap != null) { - lastPixmap.getPixels(dest, 0, width, 0, 0, width, height); - // copy pixels - if (lastDispose == 2) { - // fill last image rect area with background color - int c = 0; - if (!transparency) { - c = lastBgColor; - } - for (int i = 0; i < lrh; i++) { - int n1 = (lry + i) * width + lrx; - int n2 = n1 + lrw; - for (int k = n1; k < n2; k++) { - dest[k] = c; - } - } - } - } - } - // copy each source line to the appropriate place in the destination - int pass = 1; - int inc = 8; - int iline = 0; - for (int i = 0; i < ih; i++) { - int line = i; - if (interlace) { - if (iline >= ih) { - pass++; - switch (pass) { - case 2: - iline = 4; - break; - case 3: - iline = 2; - inc = 4; - break; - case 4: - iline = 1; - inc = 2; - break; - default: - break; - } - } - line = iline; - iline += inc; - } - line += iy; - if (line < height) { - int k = line * width; - int dx = k + ix; // start of line in dest - int dlim = dx + iw; // end of dest line - if ((k + width) < dlim) { - dlim = k + width; // past dest edge - } - int sx = i * iw; // start of line in source - while (dx < dlim) { - // map color and insert in destination - int index = ((int) pixels[sx++]) & 0xff; - int c = act[index]; - if (c != 0) { - dest[dx] = c; - } - dx++; - } - } - } - image = new DixieMap(dest, width, height, Pixmap.Format.RGBA8888); - //Pixmap.createPixmap(dest, width, height, Config.ARGB_4444); - } - - /** - * Gets the image contents of frame n. - * - * @return BufferedPixmap representation of frame, or null if n is invalid. - */ - public DixieMap getFrame(int n) { - if (frameCount <= 0) - return null; - n = n % frameCount; - return frames.elementAt(n).image; - } - - /** - * Reads GIF image from stream - * - * @param is - * containing GIF file. - * @return read status code (0 = no errors) - */ - public int read(InputStream is) { - init(); - if (is != null) { - in = is; - readHeader(); - if (!err()) { - readContents(); - if (frameCount < 0) { - status = STATUS_FORMAT_ERROR; - } - } - } else { - status = STATUS_OPEN_ERROR; - } - try { - is.close(); - } catch (Exception e) { - } - return status; - } - - /** - * Decodes LZW image data into pixel array. Adapted from John Cristy's BitmapMagick. - */ - protected void decodeBitmapData() { - int nullCode = -1; - int npix = iw * ih; - int available, clear, code_mask, code_size, end_of_information, in_code, old_code, bits, code, count, i, datum, data_size, first, top, bi, pi; - if ((pixels == null) || (pixels.length < npix)) { - pixels = new byte[npix]; // allocate new pixel array - } - if (prefix == null) { - prefix = new short[MAX_STACK_SIZE]; - } - if (suffix == null) { - suffix = new byte[MAX_STACK_SIZE]; - } - if (pixelStack == null) { - pixelStack = new byte[MAX_STACK_SIZE + 1]; - } - // Initialize GIF data stream decoder. - data_size = read(); - clear = 1 << data_size; - end_of_information = clear + 1; - available = clear + 2; - old_code = nullCode; - code_size = data_size + 1; - code_mask = (1 << code_size) - 1; - for (code = 0; code < clear; code++) { - prefix[code] = 0; // XXX ArrayIndexOutOfBoundsException - suffix[code] = (byte) code; - } - // Decode GIF pixel stream. - datum = bits = count = first = top = pi = bi = 0; - for (i = 0; i < npix;) { - if (top == 0) { - if (bits < code_size) { - // Load bytes until there are enough bits for a code. - if (count == 0) { - // Read a new data block. - count = readBlock(); - if (count <= 0) { - break; - } - bi = 0; - } - datum += (((int) block[bi]) & 0xff) << bits; - bits += 8; - bi++; - count--; - continue; - } - // Get the next code. - code = datum & code_mask; - datum >>= code_size; - bits -= code_size; - // Interpret the code - if ((code > available) || (code == end_of_information)) { - break; - } - if (code == clear) { - // Reset decoder. - code_size = data_size + 1; - code_mask = (1 << code_size) - 1; - available = clear + 2; - old_code = nullCode; - continue; - } - if (old_code == nullCode) { - pixelStack[top++] = suffix[code]; - old_code = code; - first = code; - continue; - } - in_code = code; - if (code == available) { - pixelStack[top++] = (byte) first; - code = old_code; - } - while (code > clear) { - pixelStack[top++] = suffix[code]; - code = prefix[code]; - } - first = ((int) suffix[code]) & 0xff; - // Add a new string to the string table, - if (available >= MAX_STACK_SIZE) { - break; - } - pixelStack[top++] = (byte) first; - prefix[available] = (short) old_code; - suffix[available] = (byte) first; - available++; - if (((available & code_mask) == 0) && (available < MAX_STACK_SIZE)) { - code_size++; - code_mask += available; - } - old_code = in_code; - } - // Pop a pixel off the pixel stack. - top--; - pixels[pi++] = pixelStack[top]; - i++; - } - for (i = pi; i < npix; i++) { - pixels[i] = 0; // clear missing pixels - } - } - - /** - * Returns true if an error was encountered during reading/decoding - */ - protected boolean err() { - return status != STATUS_OK; - } - - /** - * Initializes or re-initializes reader - */ - protected void init() { - status = STATUS_OK; - frameCount = 0; - frames = new Vector<>(); - gct = null; - lct = null; - } - - /** - * Reads a single byte from the input stream. - */ - protected int read() { - int curByte = 0; - try { - curByte = in.read(); - } catch (Exception e) { - status = STATUS_FORMAT_ERROR; - } - return curByte; - } - - /** - * Reads next variable length block from input. - * - * @return number of bytes stored in "buffer" - */ - protected int readBlock() { - blockSize = read(); - int n = 0; - if (blockSize > 0) { - try { - int count = 0; - while (n < blockSize) { - count = in.read(block, n, blockSize - n); - if (count == -1) { - break; - } - n += count; - } - } catch (Exception e) { - e.printStackTrace(); - } - if (n < blockSize) { - status = STATUS_FORMAT_ERROR; - } - } - return n; - } - - /** - * Reads color table as 256 RGB integer values - * - * @param ncolors - * int number of colors to read - * @return int array containing 256 colors (packed ARGB with full alpha) - */ - protected int[] readColorTable(int ncolors) { - int nbytes = 3 * ncolors; - int[] tab = null; - byte[] c = new byte[nbytes]; - int n = 0; - try { - n = in.read(c); - } catch (Exception e) { - e.printStackTrace(); - } - if (n < nbytes) { - status = STATUS_FORMAT_ERROR; - } else { - tab = new int[256]; // max size to avoid bounds checks - int i = 0; - int j = 0; - while (i < ncolors) { - int r = ((int) c[j++]) & 0xff; - int g = ((int) c[j++]) & 0xff; - int b = ((int) c[j++]) & 0xff; - tab[i++] = 0xff000000 | (r << 16) | (g << 8) | b; - } - } - return tab; - } - - /** - * Main file parser. Reads GIF content blocks. - */ - protected void readContents() { - // read GIF file content blocks - boolean done = false; - while (!(done || err())) { - int code = read(); - switch (code) { - case 0x2C: // image separator - readBitmap(); - break; - case 0x21: // extension - code = read(); - switch (code) { - case 0xf9: // graphics control extension - readGraphicControlExt(); - break; - case 0xff: // application extension - readBlock(); - StringBuilder app = new StringBuilder(); - for (int i = 0; i < 11; i++) { - app.append((char) block[i]); - } - if (app.toString().equals("NETSCAPE2.0")) { - readNetscapeExt(); - } else { - skip(); // don't care - } - break; - case 0xfe:// comment extension - skip(); - break; - case 0x01:// plain text extension - skip(); - break; - default: // uninteresting extension - skip(); - } - break; - case 0x3b: // terminator - done = true; - break; - case 0x00: // bad byte, but keep going and see what happens break; - default: - status = STATUS_FORMAT_ERROR; - } - } - } - - /** - * Reads Graphics Control Extension values - */ - protected void readGraphicControlExt() { - read(); // block size - int packed = read(); // packed fields - dispose = (packed & 0x1c) >> 2; // disposal method - if (dispose == 0) { - dispose = 1; // elect to keep old image if discretionary - } - transparency = (packed & 1) != 0; - delay = readShort() * 10; // delay in milliseconds - transIndex = read(); // transparent color index - read(); // block terminator - } - - /** - * Reads GIF file header information. - */ - protected void readHeader() { - StringBuilder id = new StringBuilder(); - for (int i = 0; i < 6; i++) { - id.append((char) read()); - } - if (!id.toString().startsWith("GIF")) { - status = STATUS_FORMAT_ERROR; - return; - } - readLSD(); - if (gctFlag && !err()) { - gct = readColorTable(gctSize); - bgColor = gct[bgIndex]; - } - } - - /** - * Reads next frame image - */ - protected void readBitmap() { - ix = readShort(); // (sub)image position & size - iy = readShort(); - iw = readShort(); - ih = readShort(); - int packed = read(); - lctFlag = (packed & 0x80) != 0; // 1 - local color table flag interlace - lctSize = (int) Math.pow(2, (packed & 0x07) + 1); - // 3 - sort flag - // 4-5 - reserved lctSize = 2 << (packed & 7); // 6-8 - local color - // table size - interlace = (packed & 0x40) != 0; - if (lctFlag) { - lct = readColorTable(lctSize); // read table - act = lct; // make local table active - } else { - act = gct; // make global table active - if (bgIndex == transIndex) { - bgColor = 0; - } - } - int save = 0; - if (transparency) { - save = act[transIndex]; - act[transIndex] = 0; // set transparent color if specified - } - if (act == null) { - status = STATUS_FORMAT_ERROR; // no color table defined - } - if (err()) { - return; - } - decodeBitmapData(); // decode pixel data - skip(); - if (err()) { - return; - } - frameCount++; - // create new image to receive frame data - image = new DixieMap(width, height, Pixmap.Format.RGBA8888); - setPixels(); // transfer pixel data to image - frames.addElement(new GifFrame(image, delay)); // add image to frame - // list - if (transparency) { - act[transIndex] = save; - } - resetFrame(); - } - - /** - * Reads Logical Screen Descriptor - */ - protected void readLSD() { - // logical screen size - width = readShort(); - height = readShort(); - // packed fields - int packed = read(); - gctFlag = (packed & 0x80) != 0; // 1 : global color table flag - // 2-4 : color resolution - // 5 : gct sort flag - gctSize = 2 << (packed & 7); // 6-8 : gct size - bgIndex = read(); // background color index - pixelAspect = read(); // pixel aspect ratio - } - - /** - * Reads Netscape extenstion to obtain iteration count - */ - protected void readNetscapeExt() { - do { - readBlock(); - if (block[0] == 1) { - // loop count sub-block - int b1 = ((int) block[1]) & 0xff; - int b2 = ((int) block[2]) & 0xff; - loopCount = (b2 << 8) | b1; - } - } while ((blockSize > 0) && !err()); - } - - /** - * Reads next 16-bit value, LSB first - */ - protected int readShort() { - // read 16-bit value, LSB first - return read() | (read() << 8); - } - - /** - * Resets frame state for reading next image. - */ - protected void resetFrame() { - lastDispose = dispose; - lrx = ix; - lry = iy; - lrw = iw; - lrh = ih; - lastPixmap = image; - lastBgColor = bgColor; - dispose = 0; - transparency = false; - delay = 0; - lct = null; - } - - /** - * Skips variable length blocks up to and including next zero length block. - */ - protected void skip() { - do { - readBlock(); - } while ((blockSize > 0) && !err()); - } - - private Animation getAnimation(PlayMode playType) { - int nrFrames = getFrameCount(); - Pixmap frame = getFrame(0); - int width = frame.getWidth(); - int height = frame.getHeight(); - int vzones = (int)Math.sqrt(nrFrames); - int hzones = vzones; - - while(vzones * hzones < nrFrames) vzones++; - - int v, h; - - Pixmap target = new Pixmap(width * hzones, height * vzones, Pixmap.Format.RGBA8888); - - for(h = 0; h < hzones; h++) { - for(v = 0; v < vzones; v++) { - int frameID = v + h * vzones; - if(frameID < nrFrames) { - frame = getFrame(frameID); - target.drawPixmap(frame, h * width, v * height); - } - } - } - - Texture texture = new Texture(target); - Array texReg = new Array<>(); - - for(h = 0; h < hzones; h++) { - for(v = 0; v < vzones; v++) { - int frameID = v + h * vzones; - if(frameID < nrFrames) { - TextureRegion tr = new TextureRegion(texture, h * width, v * height, width, height); - texReg.add(tr); - } - } - } - float frameDuration = (float)getDelay(0); - frameDuration /= 1000; // convert milliseconds into seconds - - return new Animation<>(frameDuration, texReg, playType); - } - - public static Animation loadGIFAnimation(PlayMode playType, InputStream is) { - GifDecoder gdec = new GifDecoder(); - gdec.read(is); - return gdec.getAnimation(playType); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/AssetsDownloader.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/AssetsDownloader.java deleted file mode 100644 index d690fc587f5..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/AssetsDownloader.java +++ /dev/null @@ -1,179 +0,0 @@ -package forge.adventure.libgdxgui.assets; - -import com.badlogic.gdx.Application.ApplicationType; -import com.badlogic.gdx.Gdx; -import com.google.common.collect.ImmutableList; -import forge.adventure.libgdxgui.Forge; -import forge.gui.FThreads; -import forge.gui.GuiBase; -import forge.gui.download.GuiDownloadZipService; -import forge.gui.util.SOptionPane; -import forge.localinstance.properties.ForgeConstants; -import forge.adventure.libgdxgui.screens.SplashScreen; -import forge.util.FileUtil; -import org.apache.commons.lang3.StringUtils; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.util.List; - -public class AssetsDownloader { - public static final boolean SHARE_DESKTOP_ASSETS = true; //change to false to test downloading separate assets for desktop version - - private final static ImmutableList downloadIgnoreExit = ImmutableList.of("Download", "Ignore", "Exit"); - private final static ImmutableList downloadExit = ImmutableList.of("Download", "Exit"); - - //if not sharing desktop assets, check whether assets are up to date - public static void checkForUpdates(final SplashScreen splashScreen) { - if (Gdx.app.getType() == ApplicationType.Desktop && SHARE_DESKTOP_ASSETS) { return; } - - final boolean isSnapshots = Forge.CURRENT_VERSION.contains("SNAPSHOT"); - final String snapsURL = "https://downloads.cardforge.org/dailysnapshots/"; - final String releaseURL = "https://releases.cardforge.org/forge/forge-gui-android/"; - final String versionText = isSnapshots ? snapsURL + "version.txt" : releaseURL + "version.txt"; - - splashScreen.getProgressBar().setDescription("Checking for updates..."); - - String message; - boolean connectedToInternet = Forge.getDeviceAdapter().isConnectedToInternet(); - if (connectedToInternet) { - try { - URL versionUrl = new URL(versionText); - String version = FileUtil.readFileToString(versionUrl); - String filename = "forge-android-" + version + "-signed-aligned.apk"; - String apkURL = isSnapshots ? snapsURL + filename : releaseURL + version + "/" + filename; - if (!StringUtils.isEmpty(version) && !Forge.CURRENT_VERSION.equals(version)) { - splashScreen.prepareForDialogs(); - - message = "A new version of Forge is available (" + version + ").\n" + - "You are currently on an older version (" + Forge.CURRENT_VERSION + ").\n\n" + - "Would you like to update to the new version now?"; - if (!Forge.getDeviceAdapter().isConnectedToWifi()) { - message += " If so, you may want to connect to wifi first. The download is around 6.5MB."; - } - if (SOptionPane.showConfirmDialog(message, "New Version Available", "Update Now", "Update Later", true, true)) { - String apkFile = new GuiDownloadZipService("", "update", apkURL, - Forge.getDeviceAdapter().getDownloadsDir(), null, splashScreen.getProgressBar()).download(filename); - if (apkFile != null) { - /* FileUriExposedException was added on API 24, Forge now targets API 26 so Android 10 and above runs, - most user thinks Forge crashes but in reality, the method below just can't open the apk when Forge - exits silently to run the downloaded apk. Some devices allow the apk to run but most users are annoyed when - Forge didn't open the apk so I downgrade the check so it will run only on target devices without FileUriExposedException */ - if (Forge.androidVersion < 24) { - Forge.getDeviceAdapter().openFile(apkFile); - Forge.exit(true); - return; - } - // API 24 and above needs manual apk installation unless we provide a FileProvider for FileUriExposedException - switch (SOptionPane.showOptionDialog("Download Successful. Go to your downloads folder and install " + filename +" to update Forge. Forge will now exit.", "", null, ImmutableList.of("Ok"))) { - default: - Forge.exit(true); - } - return; - } - SOptionPane.showMessageDialog("Could not download update. " + - "Press OK to proceed without update.", "Update Failed"); - } - } - } - catch (Exception e) { - e.printStackTrace(); - } - } - - //see if assets need updating - File versionFile = new File(ForgeConstants.ASSETS_DIR + "version.txt"); - if (!versionFile.exists()) { - try { - versionFile.createNewFile(); - } - catch (IOException e) { - e.printStackTrace(); - Forge.exit(true); //can't continue if this fails - return; - } - } - else if (Forge.CURRENT_VERSION.equals(FileUtil.readFileToString(versionFile)) && FSkin.getSkinDir() != null) { - return; //if version matches what had been previously saved and FSkin isn't requesting assets download, no need to download assets - } - - splashScreen.prepareForDialogs(); //ensure colors set up for showing message dialogs - - boolean canIgnoreDownload = FSkin.getAllSkins() != null; //don't allow ignoring download if resource files haven't been previously loaded - - if (!connectedToInternet) { - message = "Updated resource files cannot be downloaded due to lack of internet connection.\n\n"; - if (canIgnoreDownload) { - message += "You can continue without this download, but you may miss out on card fixes or experience other problems."; - } - else { - message += "You cannot start the app since you haven't previously downloaded these files."; - } - SOptionPane.showMessageDialog(message, "No Internet Connection"); - if (!canIgnoreDownload) { - Forge.exit(true); //exit if can't ignore download - } - return; - } - - //prompt user whether they wish to download the updated resource files - message = "There are updated resource files to download. " + - "This download is around 50MB, "; - if (Forge.getDeviceAdapter().isConnectedToWifi()) { - message += "which shouldn't take long if your wifi connection is good."; - } - else { - message += "so it's highly recommended that you connect to wifi first."; - } - final List options; - message += "\n\n"; - if (canIgnoreDownload) { - message += "If you choose to ignore this download, you may miss out on card fixes or experience other problems."; - options = downloadIgnoreExit; - } else { - message += "This download is mandatory to start the app since you haven't previously downloaded these files."; - options = downloadExit; - } - - switch (SOptionPane.showOptionDialog(message, "", null, options)) { - case 1: - if (!canIgnoreDownload) { - Forge.exit(true); //exit if can't ignore download - } - return; - case 2: - Forge.exit(true); - return; - } - - //allow deletion on Android 10 or if using app-specific directory - boolean allowDeletion = Forge.androidVersion < 30 || GuiBase.isUsingAppDirectory(); - String assetURL = isSnapshots ? snapsURL + "assets.zip" : releaseURL + Forge.CURRENT_VERSION + "/" + "assets.zip"; - new GuiDownloadZipService("", "resource files", assetURL, - ForgeConstants.ASSETS_DIR, ForgeConstants.RES_DIR, splashScreen.getProgressBar(), allowDeletion).downloadAndUnzip(); - - if (allowDeletion) - FSkinFont.deleteCachedFiles(); //delete cached font files in case any skin's .ttf file changed - - //reload light version of skin after assets updated - FThreads.invokeInEdtAndWait(new Runnable() { - @Override - public void run() { - FSkinFont.updateAll(); //update all fonts used by splash screen - FSkin.loadLight(FSkin.getName(), splashScreen); - } - }); - - //save version string to file once assets finish downloading - //so they don't need to be re-downloaded until you upgrade again - FileUtil.writeFile(versionFile, Forge.CURRENT_VERSION); - - //add restart after assets update - String msg = allowDeletion ? "Resource update finished..." : "Forge misses some files for deletion.\nIf you encounter issues, try deleting the Forge/res folder and/or deleting Forge/cache/fonts folder and try to download and update the assets."; - switch (SOptionPane.showOptionDialog(msg, "", null, ImmutableList.of("Restart"))) { - default: - Forge.restart(true); - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/BitmapFontWriter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/BitmapFontWriter.java deleted file mode 100644 index 8fd76eb6675..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/BitmapFontWriter.java +++ /dev/null @@ -1,391 +0,0 @@ -/******************************************************************************* - * Copyright 2011 See AUTHORS file. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package forge.adventure.libgdxgui.assets; - -import com.badlogic.gdx.files.FileHandle; -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.graphics.PixmapIO; -import com.badlogic.gdx.graphics.g2d.BitmapFont.BitmapFontData; -import com.badlogic.gdx.graphics.g2d.BitmapFont.Glyph; -import com.badlogic.gdx.graphics.g2d.PixmapPacker.Page; -import com.badlogic.gdx.utils.Array; -import forge.util.TextUtil; - -/** - * This file is 'borrowed' from gdx-tools in the libgdx source - */ - -/** A utility to output BitmapFontData to a FNT file. This can be useful for caching the result from TrueTypeFont, for faster load - * times. - *

- * The font file format is from the AngelCodeFont BMFont tool. - *

- * Output is nearly identical to the FreeType settting in the Hiero tool {@Link com.badlogic.gdx.tools.hiero.Hiero}. BitmapFontWriter gives more flexibility, eg - * borders and shadows can be used. Hiero is able to avoid outputting the same glyph image more than once if multiple character - * codes have the exact same glyph. - * @author mattdesl AKA davedes */ -public class BitmapFontWriter { - - /** The output format. */ - public enum OutputFormat { - - /** AngelCodeFont text format */ - Text, - /** AngelCodeFont XML format */ - XML - } - - /** The output format */ - private static OutputFormat format = OutputFormat.Text; - - /** Sets the AngelCodeFont output format for subsequent writes; can be text (for LibGDX) or XML (for other engines, like - * Pixi.js). - * - * @param fmt the output format to use */ - public static void setOutputFormat (OutputFormat fmt) { - if (fmt == null) throw new NullPointerException("format cannot be null"); - format = fmt; - } - - /** Returns the currently used output format. - * @return the output format */ - public static OutputFormat getOutputFormat () { - return format; - } - - /** The Padding parameter for FontInfo. */ - public static class Padding { - public int up, down, left, right; - - public Padding () { - } - - public Padding (int up, int down, int left, int right) { - this.up = up; - this.down = down; - this.left = left; - this.right = right; - } - } - - /** The spacing parameter for FontInfo. */ - public static class Spacing { - public int horizontal, vertical; - } - - /** The font "info" line; everything except padding and override metrics are ignored by LibGDX's BitmapFont reader, it is otherwise just useful for - * clean and organized output. */ - public static class FontInfo { - /** Face name */ - public String face; - /** Font size (pt) */ - public int size = 12; - /** Whether the font is bold */ - public boolean bold; - /** Whether the font is italic */ - public boolean italic; - /** The charset; or null/empty for default */ - public String charset; - /** Whether the font uses unicode glyphs */ - public boolean unicode = true; - /** Stretch for height; default to 100% */ - public int stretchH = 100; - /** Whether smoothing is applied */ - public boolean smooth = true; - /** Amount of anti-aliasing that was applied to the font */ - public int aa = 2; - /** Padding that was applied to the font */ - public Padding padding = new Padding(); - /** Horizontal/vertical spacing that was applied to font */ - public Spacing spacing = new Spacing(); - public int outline = 0; - - /** Override metrics */ - public boolean hasOverrideMetrics; - public float ascent; - public float descent; - public float down; - public float capHeight; - public float lineHeight; - public float spaceXAdvance; - public float xHeight; - - public FontInfo () { - } - - public FontInfo (String face, int size) { - this.face = face; - this.size = size; - } - - public void overrideMetrics (BitmapFontData data) { - hasOverrideMetrics = true; - ascent = data.ascent; - descent = data.descent; - down = data.down; - capHeight = data.capHeight; - lineHeight = data.lineHeight; - spaceXAdvance = data.spaceXadvance; - xHeight = data.xHeight; - } - - } - - private static String quote (Object params) { - return quote(params, false); - } - - private static String quote (Object params, boolean spaceAfter) { - if (BitmapFontWriter.getOutputFormat() == OutputFormat.XML) - return "\"" + params.toString().trim() + "\"" + (spaceAfter ? " " : ""); - else - return params.toString(); - } - - /** Writes the given BitmapFontData to a file, using the specified pageRefs strings as the image paths for each - * texture page. The glyphs in BitmapFontData have a "page" id, which references the index of the pageRef you specify here. - * - * The FontInfo parameter is useful for cleaner output; such as including a size and font face name hint. However, it can be - * null to use default values. LibGDX ignores most of the "info" line when reading back fonts, only padding is used. Padding - * also affects the size, location, and offset of the glyphs that are output. - * - * Likewise, the scaleW and scaleH are only for cleaner output. They are currently ignored by LibGDX's reader. For maximum - * compatibility with other BMFont tools, you should use the width and height of your texture pages (each page should be the - * same size). - * - * @param fontData the bitmap font - * @param pageRefs the references to each texture page image file, generally in the same folder as outFntFile - * @param outFntFile the font file to save to (typically ends with '.fnt') - * @param info the optional info for the file header; can be null - * @param scaleW the width of your texture pages - * @param scaleH the height of your texture pages */ - public static void writeFont (BitmapFontData fontData, String[] pageRefs, FileHandle outFntFile, FontInfo info, int scaleW, - int scaleH) { - if (info == null) { - info = new FontInfo(); - info.face = outFntFile.nameWithoutExtension(); - } - - int lineHeight = (int)fontData.lineHeight; - int pages = pageRefs.length; - int packed = 0; - int base = (int)((fontData.capHeight) + (fontData.flipped ? -fontData.ascent : fontData.ascent)); - OutputFormat fmt = BitmapFontWriter.getOutputFormat(); - boolean xml = fmt == OutputFormat.XML; - - StringBuilder buf = new StringBuilder(); - - if (xml) { - buf.append("\n"); - } - String xmlOpen = xml ? "\t<" : ""; - String xmlCloseSelf = xml ? "/>" : ""; - String xmlTab = xml ? "\t" : ""; - String xmlClose = xml ? ">" : ""; - - String xmlQuote = xml ? "\"" : ""; - String alphaChnlParams = xml ? " alphaChnl=\"0\" redChnl=\"0\" greenChnl=\"0\" blueChnl=\"0\"" - : " alphaChnl=0 redChnl=0 greenChnl=0 blueChnl=0"; - - // INFO LINE - buf.append(xmlOpen).append("info face=\"").append(info.face == null ? "" : TextUtil.fastReplace(info.face,"\"", "'")) - .append("\" size=").append(quote(info.size)).append(" bold=").append(quote(info.bold ? 1 : 0)).append(" italic=") - .append(quote(info.italic ? 1 : 0)).append(" charset=\"").append(info.charset == null ? "" : info.charset) - .append("\" unicode=").append(quote(info.unicode ? 1 : 0)).append(" stretchH=").append(quote(info.stretchH)) - .append(" smooth=").append(quote(info.smooth ? 1 : 0)).append(" aa=").append(quote(info.aa)).append(" padding=") - .append(xmlQuote).append(info.padding.up).append(",").append(info.padding.right).append(",").append(info.padding.down) - .append(",").append(info.padding.left).append(xmlQuote).append(" spacing=").append(xmlQuote) - .append(info.spacing.horizontal).append(",").append(info.spacing.vertical).append(xmlQuote).append(xmlCloseSelf) - .append("\n"); - - // COMMON line - buf.append(xmlOpen).append("common lineHeight=").append(quote(lineHeight)).append(" base=").append(quote(base)) - .append(" scaleW=").append(quote(scaleW)).append(" scaleH=").append(quote(scaleH)).append(" pages=").append(quote(pages)) - .append(" packed=").append(quote(packed)).append(alphaChnlParams).append(xmlCloseSelf).append("\n"); - - if (xml) buf.append("\t\n"); - - // PAGES - for (int i = 0; i < pageRefs.length; i++) { - buf.append(xmlTab).append(xmlOpen).append("page id=").append(quote(i)).append(" file=\"").append(pageRefs[i]) - .append("\"").append(xmlCloseSelf).append("\n"); - } - - if (xml) buf.append("\t\n"); - - // CHARS - Array glyphs = new Array(256); - for (int i = 0; i < fontData.glyphs.length; i++) { - if (fontData.glyphs[i] == null) continue; - - for (int j = 0; j < fontData.glyphs[i].length; j++) { - if (fontData.glyphs[i][j] != null) { - glyphs.add(fontData.glyphs[i][j]); - } - } - } - - buf.append(xmlOpen).append("chars count=").append(quote(glyphs.size)).append(xmlClose).append("\n"); - - int padLeft = 0, padRight = 0, padTop = 0, padX = 0, padY = 0; - if (info != null) { - padTop = info.padding.up; - padLeft = info.padding.left; - padRight = info.padding.right; - padX = padLeft + padRight; - padY = info.padding.up + info.padding.down; - } - - // CHAR definitions - for (int i = 0; i < glyphs.size; i++) { - Glyph g = glyphs.get(i); - boolean empty = g.width == 0 || g.height == 0; - buf.append(xmlTab).append(xmlOpen).append("char id=").append(quote(String.format("%-6s", g.id), true)).append("x=") - .append(quote(String.format("%-5s", empty ? 0 : g.srcX), true)).append("y=") - .append(quote(String.format("%-5s", empty ? 0 : g.srcY), true)).append("width=") - .append(quote(String.format("%-5s", empty ? 0 : g.width), true)).append("height=") - .append(quote(String.format("%-5s", empty ? 0 : g.height), true)).append("xoffset=") - .append(quote(String.format("%-5s", g.xoffset - padLeft), true)).append("yoffset=") - .append(quote(String.format("%-5s", fontData.flipped ? g.yoffset + padTop : -(g.height + (g.yoffset + padTop))), true)) - .append("xadvance=").append(quote(String.format("%-5s", g.xadvance), true)).append("page=") - .append(quote(String.format("%-5s", g.page), true)).append("chnl=").append(quote(0, true)).append(xmlCloseSelf) - .append("\n"); - } - - if (xml) buf.append("\t\n"); - - // KERNINGS - int kernCount = 0; - StringBuilder kernBuf = new StringBuilder(); - for (int i = 0; i < glyphs.size; i++) { - for (int j = 0; j < glyphs.size; j++) { - Glyph first = glyphs.get(i); - Glyph second = glyphs.get(j); - int kern = first.getKerning((char)second.id); - if (kern != 0) { - kernCount++; - kernBuf.append(xmlTab).append(xmlOpen).append("kerning first=").append(quote(first.id)).append(" second=") - .append(quote(second.id)).append(" amount=").append(quote(kern, true)).append(xmlCloseSelf).append("\n"); - } - } - } - - // KERN info - buf.append(xmlOpen).append("kernings count=").append(quote(kernCount)).append(xmlClose).append("\n"); - buf.append(kernBuf); - - if (xml) { - buf.append("\t\n"); - } - - // Override metrics - if (info.hasOverrideMetrics) { - if (xml) buf.append("\t\n"); - - buf.append(xmlTab).append(xmlOpen) - .append("metrics ascent=").append(quote(info.ascent, true)) - .append(" descent=").append(quote(info.descent, true)) - .append(" down=").append(quote(info.down, true)) - .append(" capHeight=").append(quote(info.capHeight, true)) - .append(" lineHeight=").append(quote(info.lineHeight, true)) - .append(" spaceXAdvance=").append(quote(info.spaceXAdvance, true)) - .append(" xHeight=").append(quote(info.xHeight, true)) - .append(xmlCloseSelf).append("\n"); - - if (xml) buf.append("\t\n"); - } - - if (xml) { - buf.append(""); - } - - String charset = info.charset; - if (charset != null && charset.length() == 0) charset = null; - - outFntFile.writeString(buf.toString(), false, charset); - } - - /** A utility method which writes the given font data to a file. - * - * The specified pixmaps are written to the parent directory of outFntFile, using that file's name without an - * extension for the PNG file name(s). - * - * The specified FontInfo is optional, and can be null. - * - * Typical usage looks like this: - * - *

-     * BitmapFontWriter.writeFont(myFontData, myFontPixmaps, Gdx.files.external("fonts/output.fnt"), new FontInfo("Arial", 16));
-     * 
- * - * @param fontData the font data - * @param pages the pixmaps to write as PNGs - * @param outFntFile the output file for the font definition - * @param info the optional font info for the header file, can be null */ - public static void writeFont (BitmapFontData fontData, Pixmap[] pages, FileHandle outFntFile, FontInfo info) { - String[] pageRefs = writePixmaps(pages, outFntFile.parent(), outFntFile.nameWithoutExtension()); - - // write the font data - writeFont(fontData, pageRefs, outFntFile, info, pages[0].getWidth(), pages[0].getHeight()); - } - - /** A utility method to write the given array of pixmaps to the given output directory, with the specified file name. If the - * pages array is of length 1, then the resulting file ref will look like: "fileName.png". - * - * If the pages array is greater than length 1, the resulting file refs will be appended with "_N", such as "fileName_0.png", - * "fileName_1.png", "fileName_2.png" etc. - * - * The returned string array can then be passed to the writeFont method. - * - * Note: None of the pixmaps will be disposed. - * - * @param pages the pages of pixmap data to write - * @param outputDir the output directory - * @param fileName the file names for the output images - * @return the array of string references to be used with writeFont */ - public static String[] writePixmaps (Pixmap[] pages, FileHandle outputDir, String fileName) { - if (pages == null || pages.length == 0) throw new IllegalArgumentException("no pixmaps supplied to BitmapFontWriter.write"); - - String[] pageRefs = new String[pages.length]; - - for (int i = 0; i < pages.length; i++) { - String ref = pages.length == 1 ? (fileName + ".png") : (fileName + "_" + i + ".png"); - - // the ref for this image - pageRefs[i] = ref; - - // write the PNG in that directory - PixmapIO.writePNG(outputDir.child(ref), pages[i]); - } - return pageRefs; - } - - /** A convenience method to write pixmaps by page; typically returned from a PixmapPacker when used alongside - * FreeTypeFontGenerator. - * - * @param pages the pages containing the Pixmaps - * @param outputDir the output directory - * @param fileName the file name - * @return the file refs */ - public static String[] writePixmaps (Array pages, FileHandle outputDir, String fileName) { - Pixmap[] pix = new Pixmap[pages.size]; - for (int i = 0; i < pages.size; i++) { - pix[i] = pages.get(i).getPixmap(); - } - return writePixmaps(pix, outputDir, fileName); - } -} \ No newline at end of file diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FBufferedImage.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FBufferedImage.java deleted file mode 100644 index 9ea9a667fbf..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FBufferedImage.java +++ /dev/null @@ -1,99 +0,0 @@ -package forge.adventure.libgdxgui.assets; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.Pixmap.Format; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.glutils.FrameBuffer; -import com.badlogic.gdx.math.Matrix4; -import forge.adventure.libgdxgui.Graphics; -import forge.gui.FThreads; - -//Special graphics object for rendering to a texture -public abstract class FBufferedImage extends FImageComplex { - private final float width, height, opacity; - private FrameBuffer frameBuffer; - - public FBufferedImage(float width0, float height0) { - this(width0, height0, 1); - } - public FBufferedImage(float width0, float height0, float opacity0) { - width = width0; - height = height0; - opacity = opacity0; - } - - @Override - public float getWidth() { - return width; - } - - @Override - public float getHeight() { - return height; - } - - @Override - public int getRegionX() { - return 0; - } - - @Override - public int getRegionY() { - return 0; - } - - @Override - public Texture getTexture() { - if (frameBuffer == null) { - Gdx.gl.glDisable(GL20.GL_SCISSOR_TEST); //prevent buffered image being clipped - - //render texture to frame buffer if needed - frameBuffer = new FrameBuffer(Format.RGBA8888, (int)width, (int)height, false); - frameBuffer.begin(); - - //frame graphics must be given a projection matrix - //so stuff is rendered properly to custom sized frame buffer - Graphics frameGraphics = new Graphics(); - Matrix4 matrix = new Matrix4(); - matrix.setToOrtho2D(0, 0, width, height); - frameGraphics.setProjectionMatrix(matrix); - - frameGraphics.begin(width, height); - draw(frameGraphics, width, height); - frameGraphics.end(); - - frameBuffer.end(); - frameGraphics.dispose(); - - Gdx.gl.glEnable(GL20.GL_SCISSOR_TEST); - } - return frameBuffer.getColorBufferTexture(); - } - - public void clear() { - final FrameBuffer fb = frameBuffer; - if (fb != null) { - frameBuffer = null; - FThreads.invokeInEdtNowOrLater(new Runnable() { - @Override - public void run() { - fb.dispose(); //must be disposed on EDT thread - } - }); - } - } - - protected abstract void draw(Graphics g, float w, float h); - - @Override - public void draw(Graphics g, float x, float y, float w, float h) { - if (opacity < 1) { - g.setAlphaComposite(opacity); - } - g.drawFlippedImage(getTexture(), x, y, w, h); //need to draw image flipped because of how FrameBuffer works - if (opacity < 1) { - g.resetAlphaComposite(); - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FDelayLoadImage.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FDelayLoadImage.java deleted file mode 100644 index 235300d6402..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FDelayLoadImage.java +++ /dev/null @@ -1,48 +0,0 @@ -package forge.adventure.libgdxgui.assets; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.Texture; -import forge.adventure.libgdxgui.Graphics; - -//Special wrapper for a texture to be loaded later when it's needed -public class FDelayLoadImage extends FImageComplex { - private final String filename; - private Texture texture; - - public FDelayLoadImage(String filename0) { - filename = filename0; - } - - @Override - public float getWidth() { - return getTexture().getWidth(); - } - - @Override - public float getHeight() { - return getTexture().getHeight(); - } - - @Override - public Texture getTexture() { - if (texture == null) { - texture = new Texture(Gdx.files.absolute(filename)); - } - return texture; - } - - @Override - public int getRegionX() { - return 0; - } - - @Override - public int getRegionY() { - return 0; - } - - @Override - public void draw(Graphics g, float x, float y, float w, float h) { - g.drawImage(getTexture(), x, y, w, h); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FImage.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FImage.java deleted file mode 100644 index 0654ecb00c5..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FImage.java +++ /dev/null @@ -1,10 +0,0 @@ -package forge.adventure.libgdxgui.assets; - -import forge.adventure.libgdxgui.Graphics; -import forge.localinstance.skin.ISkinImage; - -public interface FImage extends ISkinImage { - float getWidth(); - float getHeight(); - void draw(Graphics g, float x, float y, float w, float h); -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FImageComplex.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FImageComplex.java deleted file mode 100644 index b996b94cad0..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FImageComplex.java +++ /dev/null @@ -1,9 +0,0 @@ -package forge.adventure.libgdxgui.assets; - -import com.badlogic.gdx.graphics.Texture; - -public abstract class FImageComplex implements FImage { - public abstract Texture getTexture(); - public abstract int getRegionX(); - public abstract int getRegionY(); -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FLanguage.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FLanguage.java deleted file mode 100644 index b32645150b9..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FLanguage.java +++ /dev/null @@ -1,42 +0,0 @@ -package forge.adventure.libgdxgui.assets; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.files.FileHandle; -import forge.localinstance.properties.ForgeConstants; -import forge.localinstance.properties.ForgePreferences; -import forge.localinstance.properties.ForgePreferences.FPref; -import forge.model.FModel; - -import java.util.ArrayList; -import java.util.List; - -public class FLanguage { - - public static void changeLanguage(final String languageName) { - final ForgePreferences prefs = FModel.getPreferences(); - if (languageName.equals(prefs.getPref(FPref.UI_LANGUAGE))) { return; } - - //save language preference - prefs.setPref(FPref.UI_LANGUAGE, languageName); - prefs.save(); - } - - /** - * Gets the languages. - * - * @return the languages - */ - public static Iterable getAllLanguages() { - final List allLanguages = new ArrayList<>(); - - final FileHandle dir = Gdx.files.absolute(ForgeConstants.LANG_DIR); - for (FileHandle languageFile : dir.list()) { - String languageName = languageFile.name(); - if (!languageName.endsWith(".properties")) { continue; } - allLanguages.add(languageName.replace(".properties", "")); - } - - return allLanguages; - } - -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FRotatedImage.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FRotatedImage.java deleted file mode 100644 index b62ffb0f762..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FRotatedImage.java +++ /dev/null @@ -1,60 +0,0 @@ -package forge.adventure.libgdxgui.assets; - -import com.badlogic.gdx.graphics.Texture; -import forge.adventure.libgdxgui.Graphics; - -public class FRotatedImage extends FImageComplex { - private final Texture texture; - private final int srcX, srcY, srcWidth, srcHeight; - private final boolean clockwise; - - public FRotatedImage(Texture texture0, int srcX0, int srcY0, int srcWidth0, int srcHeight0, boolean clockwise0) { - texture = texture0; - srcX = srcX0; - srcY = srcY0; - srcWidth = srcWidth0; - srcHeight = srcHeight0; - clockwise = clockwise0; - } - - @Override - public float getWidth() { - return srcHeight; //width and height are swapped since image rotated - } - - @Override - public float getHeight() { - return srcWidth; - } - - @Override - public Texture getTexture() { - return texture; - } - - @Override - public int getRegionX() { - return srcX; - } - - @Override - public int getRegionY() { - return srcY; - } - - @Override - public void draw(Graphics g, float x, float y, float w, float h) { - float originX, originY, rotation; - if (clockwise) { - originX = x + w / 2; - originY = y + w / 2; - rotation = -90; - } - else { - originX = x + h / 2; - originY = y + h / 2; - rotation = 90; - } - g.drawRotatedImage(texture, x, y, h, w, originX, originY, srcX, srcY, srcWidth, srcHeight, rotation); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkin.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkin.java deleted file mode 100644 index 8eec220f595..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkin.java +++ /dev/null @@ -1,475 +0,0 @@ -package forge.adventure.libgdxgui.assets; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.files.FileHandle; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.utils.Array; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.assets.FSkinImage.SourceFile; -import forge.adventure.libgdxgui.card.CardFaceSymbols; -import forge.adventure.util.Config; -import forge.gui.FThreads; -import forge.gui.GuiBase; -import forge.localinstance.properties.ForgeConstants; -import forge.localinstance.properties.ForgePreferences; -import forge.localinstance.properties.ForgePreferences.FPref; -import forge.localinstance.skin.FSkinProp; -import forge.model.FModel; -import forge.adventure.libgdxgui.screens.LoadingOverlay; -import forge.adventure.libgdxgui.screens.SplashScreen; -import forge.adventure.libgdxgui.toolbox.FProgressBar; -import forge.util.WordUtil; - -import java.util.HashMap; -import java.util.Map; - -public class FSkin { - private static final Map images = new HashMap<>(512); - private static final Map avatars = new HashMap<>(150); - private static final Map sleeves = new HashMap<>(64); - private static final Map borders = new HashMap<>(); - private static final Map deckbox = new HashMap<>(); - - private static Array allSkins; - private static FileHandle preferredDir; - private static String preferredName; - private static boolean loaded = false; - public static Texture hdLogo = null; - - public static void changeSkin(final String skinName) { - final ForgePreferences prefs = FModel.getPreferences(); - if (skinName.equals(prefs.getPref(FPref.UI_SKIN))) { return; } - - //save skin preference - prefs.setPref(FPref.UI_SKIN, skinName); - prefs.save(); - - //load skin - loaded = false; //reset this temporarily until end of loadFull() - - final LoadingOverlay loader = new LoadingOverlay("Loading new theme..."); - loader.show(); //show loading overlay then delay running remaining logic so UI can respond - FThreads.invokeInBackgroundThread(new Runnable() { - @Override - public void run() { - FThreads.invokeInEdtLater(new Runnable() { - @Override - public void run() { - loadLight(skinName, null); - loadFull(null); - loader.setCaption("Loading fonts..."); - FThreads.invokeInBackgroundThread(new Runnable() { - @Override - public void run() { - FSkinFont.deleteCachedFiles(); //delete cached font files so font can be update for new skin - FSkinFont.updateAll(); - //CardImageRenderer.forceStaticFieldUpdate(); - FThreads.invokeInEdtLater(new Runnable() { - @Override - public void run() { - loader.hide(); - } - }); - } - }); - } - }); - } - }); - } - - /* - * Loads a "light" version of FSkin, just enough for the splash screen: - * skin name. Generates custom skin settings, fonts, and backgrounds. - * - * - * @param skinName - * the skin name - */ - public static void loadLight(String skinName, final SplashScreen splashScreen) { - preferredName = skinName.toLowerCase().replace(' ', '_'); - - //reset hd buttons/icons - Forge.hdbuttons = false; - Forge.hdstart = false; - preferredDir = Config.instance().getFile("skin"); - - FSkinTexture.BG_TEXTURE.load(); //load background texture early for splash screen - - if (splashScreen != null) { - final FileHandle f = getSkinFile("bg_splash.png"); - final FileHandle f2 = getSkinFile("bg_splash_hd.png"); //HD Splashscreen - final FileHandle f3 = getSkinFile("hd_logo.png"); - - if (!f.exists()) { - if (!skinName.equals("default")) { - FSkin.loadLight("default", splashScreen); - } - return; - } - - try { - Texture txSplash = new Texture(f); - final int w = txSplash.getWidth(); - final int h = txSplash.getHeight(); - - if (f2.exists()) { - Texture txSplashHD = new Texture(f2, true); - txSplashHD.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear); - splashScreen.setBackground(new TextureRegion(txSplashHD)); - } else { - splashScreen.setBackground(new TextureRegion(txSplash, 0, 0, w, h - 100)); - } - - if (f3.exists()) { - Texture txOverlay = new Texture(f3, true); - txOverlay.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear); - hdLogo = txOverlay; - } else { - hdLogo = null; - } - - Pixmap pxSplash = new Pixmap(f); - FProgressBar.BACK_COLOR = new Color(pxSplash.getPixel(25, h - 75)); - FProgressBar.FORE_COLOR = new Color(pxSplash.getPixel(75, h - 75)); - FProgressBar.SEL_BACK_COLOR = new Color(pxSplash.getPixel(25, h - 25)); - FProgressBar.SEL_FORE_COLOR = new Color(pxSplash.getPixel(75, h - 25)); - } - catch (final Exception e) { - e.printStackTrace(); - } - loaded = true; - } - } - - /** - * Loads two sprites: the default (which should be a complete - * collection of all symbols) and the preferred (which may be - * incomplete). - * - * Font must be present in the skin folder, and will not - * be replaced by default. The fonts are pre-derived - * in this method and saved in a HashMap for future access. - * - * Color swatches must be present in the preferred - * sprite, and will not be replaced by default. - * - * Background images must be present in skin folder, - * and will not be replaced by default. - * - * Icons, however, will be pulled from the two sprites. Obviously, - * preferred takes precedence over default, but if something is - * missing, the default picture is retrieved. - */ - public static void loadFull(final SplashScreen splashScreen) { - if (splashScreen != null) { - // Preferred skin name must be called via loadLight() method, - // which does some cleanup and init work. - if (FSkin.preferredName.isEmpty()) { FSkin.loadLight("default", splashScreen); } - } - - avatars.clear(); - sleeves.clear(); - - boolean textureFilter = Forge.isTextureFilteringEnabled(); - - final Map textures = new HashMap<>(); - - // Grab and test various sprite files. - final FileHandle f1 = getDefaultSkinFile(SourceFile.ICONS.getFilename()); - final FileHandle f2 = getSkinFile(SourceFile.ICONS.getFilename()); - final FileHandle f3 = getDefaultSkinFile(SourceFile.FOILS.getFilename()); - final FileHandle f4 = getDefaultSkinFile(ForgeConstants.SPRITE_AVATARS_FILE); - final FileHandle f5 = getSkinFile(ForgeConstants.SPRITE_AVATARS_FILE); - final FileHandle f6 = getDefaultSkinFile(SourceFile.OLD_FOILS.getFilename()); - final FileHandle f7 = getSkinFile(ForgeConstants.SPRITE_MANAICONS_FILE); - final FileHandle f8 = getDefaultSkinFile(ForgeConstants.SPRITE_SLEEVES_FILE); - final FileHandle f9 = getDefaultSkinFile(ForgeConstants.SPRITE_SLEEVES2_FILE); - final FileHandle f10 = getDefaultSkinFile(ForgeConstants.SPRITE_BORDER_FILE); - final FileHandle f11 = getSkinFile(ForgeConstants.SPRITE_BUTTONS_FILE); - final FileHandle f12 = getSkinFile(ForgeConstants.SPRITE_START_FILE); - final FileHandle f13 = getDefaultSkinFile(ForgeConstants.SPRITE_DECKBOX_FILE); - - try { - textures.put(f1.path(), new Texture(f1)); - Pixmap preferredIcons = new Pixmap(f1); - if (f2.exists()) { - textures.put(f2.path(), new Texture(f2)); - preferredIcons = new Pixmap(f2); - } - - textures.put(f3.path(), new Texture(f3)); - if (f6.exists()) { - textures.put(f6.path(), new Texture(f6)); - } - else { - textures.put(f6.path(), textures.get(f3.path())); - } - if (f7.exists()){ - Texture t = new Texture(f7, true); - //t.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear); - textures.put(f7.path(), t); - } - - //hdbuttons - if (f11.exists()) { - if (GuiBase.isAndroid() && Forge.totalDeviceRAM <5000) { - Forge.hdbuttons = false; - } else { - Texture t = new Texture(f11, true); - t.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear); - textures.put(f11.path(), t); - Forge.hdbuttons = true; - } - } else { Forge.hdbuttons = false; } //how to refresh buttons when a theme don't have hd buttons? - if (f12.exists()) { - if (GuiBase.isAndroid() && Forge.totalDeviceRAM <5000) { - Forge.hdstart = false; - } else { - Texture t = new Texture(f12, true); - t.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear); - textures.put(f12.path(), t); - Forge.hdstart = true; - } - } else { Forge.hdstart = false; } - //update colors - for (final FSkinColor.Colors c : FSkinColor.Colors.values()) { - c.setColor(new Color(preferredIcons.getPixel(c.getX(), c.getY()))); - } - - //load images - for (FSkinImage image : FSkinImage.values()) { - if (GuiBase.isAndroid()) { - if (Forge.totalDeviceRAM>5000) - image.load(textures, preferredIcons); - else if (image.toString().equals("HDMULTI")) - image.load(textures, preferredIcons); - else if (!image.toString().startsWith("HD")) - image.load(textures, preferredIcons); - } else { - image.load(textures, preferredIcons); - } - } - for (FSkinTexture texture : FSkinTexture.values()) { - if (texture != FSkinTexture.BG_TEXTURE) { - texture.load(); - } - } - - //assemble avatar textures - int counter = 0; - int scount = 0; - Color pxTest; - Pixmap pxDefaultAvatars, pxPreferredAvatars, pxDefaultSleeves; - Texture txDefaultAvatars, txPreferredAvatars, txDefaultSleeves; - - pxDefaultAvatars = new Pixmap(f4); - pxDefaultSleeves = new Pixmap(f8); - txDefaultAvatars = new Texture(f4, textureFilter); - if (textureFilter) - txDefaultAvatars.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear); - txDefaultSleeves = new Texture(f8, textureFilter); - if (textureFilter) - txDefaultSleeves.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear); - - if (f5.exists()) { - pxPreferredAvatars = new Pixmap(f5); - txPreferredAvatars = new Texture(f5, textureFilter); - if (textureFilter) - txPreferredAvatars.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear); - - final int pw = pxPreferredAvatars.getWidth(); - final int ph = pxPreferredAvatars.getHeight(); - - for (int j = 0; j < ph; j += 100) { - for (int i = 0; i < pw; i += 100) { - if (i == 0 && j == 0) { continue; } - pxTest = new Color(pxPreferredAvatars.getPixel(i + 50, j + 50)); - if (pxTest.a == 0) { continue; } - FSkin.avatars.put(counter++, new TextureRegion(txPreferredAvatars, i, j, 100, 100)); - } - } - pxPreferredAvatars.dispose(); - } else if (!FSkin.preferredName.isEmpty()){ - //workaround bug crash fix if missing sprite avatar on preferred theme for quest tournament... - //i really don't know why it needs to populate the avatars twice.... needs investigation - final int pw = pxDefaultAvatars.getWidth(); - final int ph = pxDefaultAvatars.getHeight(); - - for (int j = 0; j < ph; j += 100) { - for (int i = 0; i < pw; i += 100) { - if (i == 0 && j == 0) { continue; } - pxTest = new Color(pxDefaultAvatars.getPixel(i + 50, j + 50)); - if (pxTest.a == 0) { continue; } - FSkin.avatars.put(counter++, new TextureRegion(txDefaultAvatars, i, j, 100, 100)); - } - } - } - - final int aw = pxDefaultAvatars.getWidth(); - final int ah = pxDefaultAvatars.getHeight(); - - for (int j = 0; j < ah; j += 100) { - for (int i = 0; i < aw; i += 100) { - if (i == 0 && j == 0) { continue; } - pxTest = new Color(pxDefaultAvatars.getPixel(i + 50, j + 50)); - if (pxTest.a == 0) { continue; } - FSkin.avatars.put(counter++, new TextureRegion(txDefaultAvatars, i, j, 100, 100)); - } - } - - - final int sw = pxDefaultSleeves.getWidth(); - final int sh = pxDefaultSleeves.getHeight(); - - for (int j = 0; j < sh; j += 500) { - for (int i = 0; i < sw; i += 360) { - pxTest = new Color(pxDefaultSleeves.getPixel(i + 180, j + 250)); - if (pxTest.a == 0) { continue; } - FSkin.sleeves.put(scount++, new TextureRegion(txDefaultSleeves, i, j, 360, 500)); - } - } - - //re init second set of sleeves - pxDefaultSleeves = new Pixmap(f9); - txDefaultSleeves = new Texture(f9, textureFilter); - if (textureFilter) - txDefaultSleeves.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear); - - final int sw2 = pxDefaultSleeves.getWidth(); - final int sh2 = pxDefaultSleeves.getHeight(); - - for (int j = 0; j < sh2; j += 500) { - for (int i = 0; i < sw2; i += 360) { - pxTest = new Color(pxDefaultSleeves.getPixel(i + 180, j + 250)); - if (pxTest.a == 0) { continue; } - FSkin.sleeves.put(scount++, new TextureRegion(txDefaultSleeves, i, j, 360, 500)); - } - } - //borders - Texture bordersBW = new Texture(f10); - FSkin.borders.put(0, new TextureRegion(bordersBW, 2, 2, 672, 936)); - FSkin.borders.put(1, new TextureRegion(bordersBW, 676, 2, 672, 936)); - //deckboxes - Texture deckboxes = new Texture(f13, textureFilter); - if (textureFilter) - deckboxes.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear); - //gold bg - FSkin.deckbox.put(0, new TextureRegion(deckboxes, 2, 2, 488, 680)); - //deck box for card art - FSkin.deckbox.put(1, new TextureRegion(deckboxes, 492, 2, 488, 680)); - //generic deck box - FSkin.deckbox.put(2, new TextureRegion(deckboxes, 982, 2, 488, 680)); - - preferredIcons.dispose(); - pxDefaultAvatars.dispose(); - pxDefaultSleeves.dispose(); - } - catch (final Exception e) { - System.err.println("FSkin$loadFull: Missing a sprite (default icons, " - + "preferred icons, or foils."); - e.printStackTrace(); - } - - // Run through enums and load their coords. - FSkinColor.updateAll(); - - // Images loaded; can start UI init. - loaded = true; - - if (splashScreen != null) { - CardFaceSymbols.loadImages(); - } - } - - /** - * Gets the name. - * - * @return Name of the current skin. - */ - public static String getName() { - return FSkin.preferredName; - } - - /** - * Gets a FileHandle for a file within the directory where skin files should be stored - */ - public static FileHandle getSkinFile(String filename) { - return preferredDir.child(filename); - } - - /** - * Gets a FileHandle for a file within the directory where the default skin files should be stored - */ - public static FileHandle getDefaultSkinFile(String filename) { - return Gdx.files.absolute(ForgeConstants.DEFAULT_SKINS_DIR + filename); - } - - /** - * Gets a FileHandle for a file within the planechase cache directory - */ - public static FileHandle getCachePlanechaseFile(String filename) { - return Gdx.files.absolute(ForgeConstants.CACHE_PLANECHASE_PICS_DIR + filename); - } - - public static FileHandle getSkinDir() { - return preferredDir; - } - - /** - * Gets the skins. - * - * @return the skins - */ - public static Array getSkinDirectoryNames() { - final Array mySkins = new Array<>(); - - final FileHandle dir = Gdx.files.absolute(ForgeConstants.CACHE_SKINS_DIR); - for (FileHandle skinFile : dir.list()) { - String skinName = skinFile.name(); - if (skinName.equalsIgnoreCase(".svn")) { continue; } - if (skinName.equalsIgnoreCase(".DS_Store")) { continue; } - mySkins.add(skinName); - } - - return mySkins; - } - - public static Iterable getAllSkins() { - if (allSkins != null) { - allSkins.clear(); - allSkins.add("Default"); //init default - final Array skinDirectoryNames = getSkinDirectoryNames(); - for (final String skinDirectoryName : skinDirectoryNames) { - allSkins.add(WordUtil.capitalize(skinDirectoryName.replace('_', ' '))); - } - allSkins.sort(); - } - return allSkins; - } - - public static Map getImages() { - return images; - } - - public static Map getAvatars() { - return avatars; - } - - public static Map getSleeves() { - return sleeves; - } - - public static Map getBorders() { - return borders; - } - - public static Map getDeckbox() { - return deckbox; - } - - public static boolean isLoaded() { return loaded; } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkinBorder.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkinBorder.java deleted file mode 100644 index 3054c1d68bc..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkinBorder.java +++ /dev/null @@ -1,29 +0,0 @@ -package forge.adventure.libgdxgui.assets; - -import forge.adventure.libgdxgui.Graphics; - -public class FSkinBorder { - private final FSkinColor color; - private final float thickness; - - public FSkinBorder(FSkinColor color0, float thickness0) { - color = color0; - thickness = thickness0; - } - - public FSkinColor getColor() { - return color; - } - - public float getThickness() { - return thickness; - } - - public void draw(Graphics g, float x, float y, float w, float h) { - x -= thickness; - y -= thickness; - w += 2 * thickness; - h += 2 * thickness; - g.fillRect(color, x, y, w, h); //draw filled rectangle behind object - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkinColor.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkinColor.java deleted file mode 100644 index b08d23c2552..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkinColor.java +++ /dev/null @@ -1,268 +0,0 @@ -package forge.adventure.libgdxgui.assets; - -import com.badlogic.gdx.graphics.Color; -import forge.localinstance.skin.FSkinProp; -import forge.adventure.libgdxgui.screens.match.TargetingOverlay; - -import java.util.HashMap; - -public class FSkinColor { - public enum Colors { - CLR_THEME (FSkinProp.CLR_THEME), - CLR_BORDERS (FSkinProp.CLR_BORDERS), - CLR_ZEBRA (FSkinProp.CLR_ZEBRA), - CLR_HOVER (FSkinProp.CLR_HOVER), - CLR_ACTIVE (FSkinProp.CLR_ACTIVE), - CLR_INACTIVE (FSkinProp.CLR_INACTIVE), - CLR_TEXT (FSkinProp.CLR_TEXT), - CLR_PHASE_INACTIVE_ENABLED (FSkinProp.CLR_PHASE_INACTIVE_ENABLED), - CLR_PHASE_INACTIVE_DISABLED (FSkinProp.CLR_PHASE_INACTIVE_DISABLED), - CLR_PHASE_ACTIVE_ENABLED (FSkinProp.CLR_PHASE_ACTIVE_ENABLED), - CLR_PHASE_ACTIVE_DISABLED (FSkinProp.CLR_PHASE_ACTIVE_DISABLED), - CLR_THEME2 (FSkinProp.CLR_THEME2), - CLR_OVERLAY (FSkinProp.CLR_OVERLAY), - CLR_COMBAT_TARGETING_ARROW (FSkinProp.CLR_COMBAT_TARGETING_ARROW), - CLR_NORMAL_TARGETING_ARROW (FSkinProp.CLR_NORMAL_TARGETING_ARROW), - CLR_PWATTK_TARGETING_ARROW (FSkinProp.CLR_PWATTK_TARGETING_ARROW); - - private Color color; - private final int x, y; - private final FSkinProp skinProp; - - Colors(final FSkinProp skinProp0) { - skinProp = skinProp0; - int[] coords = skinProp.getCoords(); - x = coords[0]; - y = coords[1]; - } - - public int getX() { - return x; - } - - public int getY() { - return y; - } - - public void setColor(Color color0) { - color = color0; - } - - public static Colors fromSkinProp(FSkinProp skinProp) { - for (final Colors c : Colors.values()) { - if (c.skinProp == skinProp) { - return c; - } - } - return null; - } - } - - public static FSkinColor get(final Colors c0) { - return baseColors.get(c0); - } - - public static FSkinColor getStandardColor(int r, int g, int b) { - return getStandardColor(fromRGB(r, g, b)); - } - public static FSkinColor getStandardColor(final Color c0) { - return new FSkinColor(c0, NO_BRIGHTNESS_DELTA, NO_STEP, NO_STEP, NO_ALPHA); - } - - private static final HashMap baseColors = new HashMap<>(); - private static final HashMap derivedColors = new HashMap<>(); - private static final int NO_BRIGHTNESS_DELTA = 0; - private static final int NO_STEP = -999; //needs to be large negative since small negative values are valid - private static final int NO_ALPHA = -1; - - private final Colors baseColor; - private final int brightnessDelta; - private final int step; - private final int contrastStep; - private final float alpha; - protected Color color; - - public Color getColor() { return color; } - - private FSkinColor(Colors baseColor0) { - this(baseColor0, NO_BRIGHTNESS_DELTA, NO_STEP, NO_STEP, NO_ALPHA); - } - private FSkinColor(Colors baseColor0, int brightnessDelta0, int step0, int contrastStep0, float alpha0) { - baseColor = baseColor0; - brightnessDelta = brightnessDelta0; - step = step0; - contrastStep = contrastStep0; - alpha = alpha0; - updateColor(); - } - private FSkinColor(Color color0, int brightnessDelta0, int step0, int contrastStep0, float alpha0) { - color = color0; - baseColor = null; - brightnessDelta = brightnessDelta0; - step = step0; - contrastStep = contrastStep0; - alpha = alpha0; - updateColor(); - } - - private FSkinColor getDerivedColor(int brightnessDelta0, int step0, int contrastStep0, float alpha0) { - if (baseColor == null) { //handle deriving from standard color - return new FSkinColor(color, brightnessDelta0, step0, contrastStep0, alpha0); - } - String key = baseColor.name() + "|" + brightnessDelta0 + "|" + step0 + "|" + contrastStep0 + "|" + alpha0; - FSkinColor derivedColor = derivedColors.get(key); - if (derivedColor == null) { - derivedColor = new FSkinColor(baseColor, brightnessDelta0, step0, contrastStep0, alpha0); - derivedColors.put(key, derivedColor); - } - return derivedColor; - } - - public FSkinColor brighter() { - return getDerivedColor(brightnessDelta + 1, step, contrastStep, alpha); - } - - public FSkinColor darker() { - return getDerivedColor(brightnessDelta - 1, step, contrastStep, alpha); - } - - public FSkinColor stepColor(int step0) { - if (step != NO_STEP) { - step0 += step; - } - return getDerivedColor(brightnessDelta, step0, contrastStep, alpha); - } - - public FSkinColor getContrastColor(int contrastStep0) { - if (contrastStep != NO_STEP) { - contrastStep0 += contrastStep; - } - return getDerivedColor(brightnessDelta, step, contrastStep0, alpha); - } - - public FSkinColor getHighContrastColor() { - return getContrastColor(255); - } - - public FSkinColor alphaColor(float alpha0) { - return getDerivedColor(brightnessDelta, step, contrastStep, alpha0); - } - - protected void updateColor() { - if (baseColor != null) { - color = baseColor.color; - } - if (brightnessDelta != NO_BRIGHTNESS_DELTA) { - if (brightnessDelta < 0) { - for (int i = 0; i > brightnessDelta; i--) { - color = FSkinColor.stepColor(color, -20); - } - } - else { - for (int i = 0; i < brightnessDelta; i++) { - color = FSkinColor.stepColor(color, 20); - } - } - } - if (step != NO_STEP) { - color = FSkinColor.stepColor(color, step); - } - if (contrastStep != NO_STEP) { - color = FSkinColor.stepColor(color, FSkinColor.isColorBright(color) ? -contrastStep : contrastStep); - } - if (alpha != NO_ALPHA) { - color = FSkinColor.alphaColor(color, alpha); - } - } - - /** Steps RGB components of a color up or down. - * Returns opaque (non-alpha) stepped color. - * Plus for lighter, minus for darker. - * - * @param clr0 {Color} - * @param step int - * @return {@link Color} - */ - public static Color stepColor(Color clr0, int step) { - float r = clr0.r * 255; - float g = clr0.g * 255; - float b = clr0.b * 255; - - // Darker - if (step < 0) { - r = ((r + step > 0) ? r + step : 0); - g = ((g + step > 0) ? g + step : 0); - b = ((b + step > 0) ? b + step : 0); - } - else { - r = ((r + step < 255) ? r + step : 255); - g = ((g + step < 255) ? g + step : 255); - b = ((b + step < 255) ? b + step : 255); - } - - return new Color(r / 255, g / 255, b / 255, clr0.a); - } - - /** - * Returns RGB components of a color, with a new - * value for alpha. 0f = transparent, 1f = opaque. - */ - public static Color alphaColor(Color clr0, float alpha) { - return new Color(clr0.r, clr0.g, clr0.b, alpha); - } - - /** - * see http://www.nbdtech.com/Blog/archive/2008/04/27/Calculating-the-Perceived-Brightness-of-a-Color.aspx - */ - public static boolean isColorBright(Color c) { - double v = Math.sqrt( - c.r * c.r * 0.241 + - c.g * c.g * 0.691 + - c.b * c.b * 0.068); - return v > 0.5; - } - - public static Color getHighContrastColor(Color c) { - return isColorBright(c) ? Color.BLACK : Color.WHITE; - } - - public static Color tintColor(Color source, Color tint, float alpha) { - float r = (tint.r - source.r) * alpha + source.r; - float g = (tint.g - source.g) * alpha + source.g; - float b = (tint.b - source.b) * alpha + source.b; - return new Color(r, g, b, 1f); - } - - public static Color[] tintColors(Color source, Color[] tints, float alpha) { - Color[] tintedColors = new Color[tints.length]; - for (int i = 0; i < tints.length; i++) { - tintedColors[i] = tintColor(source, tints[i], alpha); - } - return tintedColors; - } - - public static Color fromRGB(int r, int g, int b) { - return new Color((float)r / 255f, (float)g / 255f, (float)b / 255f, 1f); - } - - public static void updateAll() { - if (FSkinColor.baseColors.size() == 0) { //initialize base skin colors if needed - for (final Colors c : Colors.values()) { - FSkinColor.baseColors.put(c, new FSkinColor(c)); - } - } - else { //update existing FSkinColors if baseColors already initialized - for (final FSkinColor c : FSkinColor.baseColors.values()) { - c.updateColor(); - } - for (final FSkinColor c : FSkinColor.derivedColors.values()) { - c.updateColor(); - } - } - TargetingOverlay.updateColors(); - } - - public float getAlpha() { - return color.a; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkinFont.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkinFont.java deleted file mode 100644 index 5b47b7b13ab..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkinFont.java +++ /dev/null @@ -1,476 +0,0 @@ -package forge.adventure.libgdxgui.assets; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.files.FileHandle; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.Batch; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.BitmapFont.BitmapFontData; -import com.badlogic.gdx.graphics.g2d.BitmapFont.Glyph; -import com.badlogic.gdx.graphics.g2d.PixmapPacker; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; -import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter; -import com.badlogic.gdx.graphics.glutils.PixmapTextureData; -import com.badlogic.gdx.utils.Array; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.util.TextBounds; -import forge.adventure.libgdxgui.util.Utils; -import forge.gui.FThreads; -import forge.localinstance.properties.ForgeConstants; -import forge.util.FileUtil; -import forge.util.LineReader; - -import java.io.FileInputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.*; - -public class FSkinFont { - private static final int MIN_FONT_SIZE = 8; - private static int MAX_FONT_SIZE = 72; - - private static final int MAX_FONT_SIZE_LESS_GLYPHS = 72; - private static final int MAX_FONT_SIZE_MANY_GLYPHS = 36; - - private static final String TTF_FILE = "font1.ttf"; - private static final Map fonts = new HashMap<>(); - - private static final String commonCharacterSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm" - + "nopqrstuvwxyz1234567890\"!?'.,;:()[]{}<>|/@\\^$-%+=#_&*\u2014" - + "\u2022ÁÉÍÓÚáéíóúÀÈÌÒÙàèìòùÑñÄËÏÖÜäëïöüẞß¿¡"; - private static final Map langUniqueCharacterSet = new HashMap<>(); - - static { - FileUtil.ensureDirectoryExists(ForgeConstants.FONTS_DIR); - } - - public static FSkinFont get(final int unscaledSize) { - return _get((int) Utils.scale(unscaledSize)); - } - public static FSkinFont _get(final int scaledSize) { - FSkinFont skinFont = fonts.get(scaledSize); - if (skinFont == null) { - skinFont = new FSkinFont(scaledSize); - fonts.put(scaledSize, skinFont); - } - return skinFont; - } - - public static FSkinFont forHeight(final float height) { - int size = MIN_FONT_SIZE + 1; - while (true) { - if (_get(size).getLineHeight() > height) { - return _get(size - 1); - } - size++; - } - } - - //pre-load all supported font sizes - public static void preloadAll(String language) { - //todo:really check the language glyph is a lot - MAX_FONT_SIZE = (language.equals("zh-CN") || language.equals("ja-JP")) ? MAX_FONT_SIZE_MANY_GLYPHS : MAX_FONT_SIZE_LESS_GLYPHS; - for (int size = MIN_FONT_SIZE; size <= MAX_FONT_SIZE; size++) { - _get(size); - } - } - - //delete all cached font files - public static void deleteCachedFiles() { - final FileHandle dir = Gdx.files.absolute(ForgeConstants.FONTS_DIR); - for (FileHandle fontFile : dir.list()) { - String name = fontFile.name(); - if (name.endsWith(".fnt") || name.endsWith(".png")) { - fontFile.delete(); - } - } - } - - public static void updateAll() { - for (FSkinFont skinFont : fonts.values()) { - skinFont.updateFont(); - } - } - - private final int fontSize; - private final float scale; - private BitmapFont font; - - private FSkinFont(int fontSize0) { - if (fontSize0 > MAX_FONT_SIZE) { - scale = (float)fontSize0 / MAX_FONT_SIZE; - } - else if (fontSize0 < MIN_FONT_SIZE) { - scale = (float)fontSize0 / MIN_FONT_SIZE; - } - else { - scale = 1; - } - fontSize = fontSize0; - updateFont(); - } - static int indexOf (CharSequence text, char ch, int start) { - final int n = text.length(); - for (; start < n; start++) - if (text.charAt(start) == ch) return start; - return n; - - } - public int computeVisibleGlyphs (CharSequence str, int start, int end, float availableWidth) { - BitmapFontData data = font.getData(); - int index = start; - float width = 0; - Glyph lastGlyph = null; - availableWidth /= data.scaleX; - - for (; index < end; index++) { - char ch = str.charAt(index); - if (ch == '[' && data.markupEnabled) { - index++; - if (!(index < end && str.charAt(index) == '[')) { // non escaped '[' - while (index < end && str.charAt(index) != ']') - index++; - continue; - } - } - - Glyph g = data.getGlyph(ch); - - if (g != null) { - if (lastGlyph != null) width += lastGlyph.getKerning(ch); - if ((width + g.xadvance) - availableWidth > 0.001f) break; - width += g.xadvance; - lastGlyph = g; - } - } - - return index - start; - } - public boolean isBreakChar (char c) { - BitmapFontData data = font.getData(); - if (data.breakChars == null) return false; - for (char br : data.breakChars) - if (c == br) return true; - return false; - } - static boolean isWhitespace (char c) { - switch (c) { - case '\n': - case '\r': - case '\t': - case ' ': - return true; - default: - return false; - } - } - // Expose methods from font that updates scale as needed - public TextBounds getBounds(CharSequence str) { - updateScale(); //must update scale before measuring text - return getBounds(str, 0, str.length()); - } - public TextBounds getBounds(CharSequence str, int start, int end) { - BitmapFontData data = font.getData(); - //int start = 0; - //int end = str.length(); - int width = 0; - Glyph lastGlyph = null; - - while (start < end) { - char ch = str.charAt(start++); - if (ch == '[' && data.markupEnabled) { - if (!(start < end && str.charAt(start) == '[')) { // non escaped '[' - while (start < end && str.charAt(start) != ']') - start++; - start++; - continue; - } - start++; - } - lastGlyph = data.getGlyph(ch); - if (lastGlyph != null) { - width = lastGlyph.xadvance; - break; - } - } - while (start < end) { - char ch = str.charAt(start++); - if (ch == '[' && data.markupEnabled) { - if (!(start < end && str.charAt(start) == '[')) { // non escaped '[' - while (start < end && str.charAt(start) != ']') - start++; - start++; - continue; - } - start++; - } - - Glyph g = data.getGlyph(ch); - if (g != null) { - width += lastGlyph.getKerning(ch); - lastGlyph = g; - width += g.xadvance; - } - } - - return new TextBounds(width * data.scaleX, data.capHeight); - - } - public TextBounds getMultiLineBounds(CharSequence str) { - updateScale(); - BitmapFontData data = font.getData(); - int start = 0; - float maxWidth = 0; - int numLines = 0; - int length = str.length(); - - while (start < length) { - int lineEnd = indexOf(str, '\n', start); - float lineWidth = getBounds(str, start, lineEnd).width; - maxWidth = Math.max(maxWidth, lineWidth); - start = lineEnd + 1; - numLines++; - } - - return new TextBounds(maxWidth, data.capHeight + (numLines - 1) * data.lineHeight); - - } - public TextBounds getWrappedBounds(CharSequence str, float wrapWidth) { - updateScale(); - BitmapFontData data = font.getData(); - if (wrapWidth <= 0) wrapWidth = Integer.MAX_VALUE; - int start = 0; - int numLines = 0; - int length = str.length(); - float maxWidth = 0; - while (start < length) { - int newLine = indexOf(str, '\n', start); - int lineEnd = start + computeVisibleGlyphs(str, start, newLine, wrapWidth); - int nextStart = lineEnd + 1; - if (lineEnd < newLine) { - // Find char to break on. - while (lineEnd > start) { - if (isWhitespace(str.charAt(lineEnd))) break; - if (isBreakChar(str.charAt(lineEnd - 1))) break; - lineEnd--; - } - - if (lineEnd == start) { - - if (nextStart > start + 1) nextStart--; - - lineEnd = nextStart; // If no characters to break, show all. - - } else { - nextStart = lineEnd; - - // Eat whitespace at start of wrapped line. - - while (nextStart < length) { - char c = str.charAt(nextStart); - if (!isWhitespace(c)) break; - nextStart++; - if (c == '\n') break; // Eat only the first wrapped newline. - } - - // Eat whitespace at end of line. - while (lineEnd > start) { - - if (!isWhitespace(str.charAt(lineEnd - 1))) break; - lineEnd--; - } - } - } - - if (lineEnd > start) { - float lineWidth = getBounds(str, start, lineEnd).width; - maxWidth = Math.max(maxWidth, lineWidth); - } - start = nextStart; - numLines++; - } - - return new TextBounds(maxWidth, data.capHeight + (numLines - 1) * data.lineHeight); - } - public float getAscent() { - updateScale(); - return font.getAscent(); - } - public float getCapHeight() { - updateScale(); - return font.getCapHeight(); - } - public float getLineHeight() { - updateScale(); - return font.getLineHeight(); - } - - public void draw(Batch batch, String text, Color color, float x, float y, float w, boolean wrap, int horzAlignment) { - updateScale(); - font.setColor(color); - font.draw(batch, text, x, y, w, horzAlignment, wrap); - } - - //update scale of font if needed - private void updateScale() { - if (font.getScaleX() != scale) { - font.getData().setScale(scale); - } - } - - public boolean canShrink() { - return fontSize > MIN_FONT_SIZE; - } - - public FSkinFont shrink() { - return _get(fontSize - 1); - } - - public String getCharacterSet(String langCode) { - if (langUniqueCharacterSet.containsKey(langCode)) { - return langUniqueCharacterSet.get(langCode); - } - StringBuilder characters = new StringBuilder(commonCharacterSet); - Set characterSet = new HashSet<>(); - for (int offset = 0; offset < commonCharacterSet.length();) { - final int codePoint = commonCharacterSet.codePointAt(offset); - characterSet.add(codePoint); - offset += Character.charCount(codePoint); - } - String[] translationFilePaths = { ForgeConstants.LANG_DIR + "cardnames-" + langCode + ".txt", - ForgeConstants.LANG_DIR + langCode + ".properties" }; - for (int i = 0; i < translationFilePaths.length; i++) { - try (LineReader translationFile = new LineReader(new FileInputStream(translationFilePaths[i]), - StandardCharsets.UTF_8)) { - for (String fileLine : translationFile.readLines()) { - final int stringLength = fileLine.length(); - for (int offset = 0; offset < stringLength;) { - final int codePoint = fileLine.codePointAt(offset); - if (!characterSet.contains(codePoint)) { - characterSet.add(codePoint); - characters.append(Character.toChars(codePoint)); - } - offset += Character.charCount(codePoint); - } - } - translationFile.close(); - } catch (IOException e) { - System.err.println("Error reading translation file: " + translationFilePaths[i]); - } - } - langUniqueCharacterSet.put(langCode, characters.toString()); - - return characters.toString(); - } - - private void updateFont() { - if (scale != 1) { //re-use font inside range if possible - if (fontSize > MAX_FONT_SIZE) { - font = _get(MAX_FONT_SIZE).font; - } else { - font = _get(MIN_FONT_SIZE).font; - } - return; - } - - String fontName = "f" + fontSize; - if (Forge.locale.equals("zh-CN") || Forge.locale.equals("ja-JP")) { - fontName += Forge.locale; - } - FileHandle fontFile = Gdx.files.absolute(ForgeConstants.FONTS_DIR + fontName + ".fnt"); - if (fontFile != null && fontFile.exists()) { - final BitmapFontData data = new BitmapFontData(fontFile, false); - FThreads.invokeInEdtNowOrLater(new Runnable() { - @Override - public void run() { //font must be initialized on UI thread - font = new BitmapFont(data, (TextureRegion)null, true); - } - }); - } else { - if (Forge.locale.equals("zh-CN") || Forge.locale.equals("ja-JP")) { - String ttfName = Forge.CJK_Font; - FileHandle ttfFile = Gdx.files.absolute(ForgeConstants.FONTS_DIR + ttfName + ".ttf"); - if (ttfFile != null && ttfFile.exists()) { - generateFont(ttfFile, fontName, fontSize); - } - } else { - generateFont(FSkin.getSkinFile(TTF_FILE), fontName, fontSize); - } - } - } - - private void generateFont(final FileHandle ttfFile, final String fontName, final int fontSize) { - if (!ttfFile.exists()) { return; } - - final FreeTypeFontGenerator generator = new FreeTypeFontGenerator(ttfFile); - - //approximate optimal page size - int pageSize; - if (fontSize >= 28) { - pageSize = 256; - } - else { - pageSize = 128; - } - - final PixmapPacker packer = new PixmapPacker(pageSize, pageSize, Pixmap.Format.RGBA8888, 2, false); - final FreeTypeFontParameter parameter = new FreeTypeFontParameter(); - parameter.characters = getCharacterSet(Forge.locale); - parameter.size = fontSize; - parameter.packer = packer; - final FreeTypeFontGenerator.FreeTypeBitmapFontData fontData = generator.generateData(parameter); - final Array pages = packer.getPages(); - - //finish generating font on UI thread - FThreads.invokeInEdtNowOrLater(new Runnable() { - @Override - public void run() { - Array textureRegions = new Array<>(); - for (int i = 0; i < pages.size; i++) { - PixmapPacker.Page p = pages.get(i); - Texture texture = new Texture(new PixmapTextureData(p.getPixmap(), p.getPixmap().getFormat(), false, false)) { - @Override - public void dispose() { - super.dispose(); - getTextureData().consumePixmap().dispose(); - } - }; - texture.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest); - textureRegions.addAll(new TextureRegion(texture)); - } - - font = new BitmapFont(fontData, textureRegions, true); - - //create .fnt and .png files for font - FileHandle pixmapDir = Gdx.files.absolute(ForgeConstants.FONTS_DIR); - if (pixmapDir != null) { - FileHandle fontFile = pixmapDir.child(fontName + ".fnt"); - BitmapFontWriter.setOutputFormat(BitmapFontWriter.OutputFormat.Text); - - String[] pageRefs = BitmapFontWriter.writePixmaps(packer.getPages(), pixmapDir, fontName); - BitmapFontWriter.writeFont(font.getData(), pageRefs, fontFile, new BitmapFontWriter.FontInfo(fontName, fontSize), 1, 1); - } - - generator.dispose(); - packer.dispose(); - } - }); - } - - public static Iterable getAllCJKFonts() { - final List allCJKFonts = new ArrayList<>(); - - allCJKFonts.add("None"); - final FileHandle dir = Gdx.files.absolute(ForgeConstants.FONTS_DIR); - for (FileHandle fontFile : dir.list()) { - String fontName = fontFile.name(); - if (!fontName.endsWith(".ttf")) { continue; } - allCJKFonts.add(fontName.replace(".ttf", "")); - } - - return allCJKFonts; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkinImage.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkinImage.java deleted file mode 100644 index 02aaa797414..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkinImage.java +++ /dev/null @@ -1,575 +0,0 @@ -package forge.adventure.libgdxgui.assets; - -import com.badlogic.gdx.files.FileHandle; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.localinstance.properties.ForgeConstants; -import forge.localinstance.skin.FSkinProp; -import forge.util.ImageUtil; - -import java.util.Map; - -/** Properties of various components that make up the skin. - * This interface allows all enums to be under the same roof. - * It also enforces a getter for coordinate locations in sprites. */ -public enum FSkinImage implements FImage { - //Zones - HAND (FSkinProp.IMG_ZONE_HAND, SourceFile.ICONS), - HDHAND (FSkinProp.IMG_HDZONE_HAND, SourceFile.BUTTONS), - - LIBRARY (FSkinProp.IMG_ZONE_LIBRARY, SourceFile.ICONS), - HDLIBRARY (FSkinProp.IMG_HDZONE_LIBRARY, SourceFile.BUTTONS), - - EXILE (FSkinProp.IMG_ZONE_EXILE, SourceFile.ICONS), - HDEXILE (FSkinProp.IMG_HDZONE_EXILE, SourceFile.BUTTONS), - - FLASHBACK (FSkinProp.IMG_ZONE_FLASHBACK, SourceFile.ICONS), - HDFLASHBACK (FSkinProp.IMG_HDZONE_FLASHBACK, SourceFile.BUTTONS), - - GRAVEYARD (FSkinProp.IMG_ZONE_GRAVEYARD, SourceFile.ICONS), - HDGRAVEYARD (FSkinProp.IMG_HDZONE_GRAVEYARD, SourceFile.BUTTONS), - - HDMANAPOOL (FSkinProp.IMG_HDZONE_MANAPOOL, SourceFile.BUTTONS), - - POISON (FSkinProp.IMG_ZONE_POISON, SourceFile.ICONS), - - //Mana symbols - MANA_COLORLESS (FSkinProp.IMG_MANA_COLORLESS, SourceFile.MANAICONS), - MANA_B (FSkinProp.IMG_MANA_B, SourceFile.MANAICONS), - MANA_R (FSkinProp.IMG_MANA_R, SourceFile.MANAICONS), - MANA_U (FSkinProp.IMG_MANA_U, SourceFile.MANAICONS), - MANA_G (FSkinProp.IMG_MANA_G, SourceFile.MANAICONS), - MANA_W (FSkinProp.IMG_MANA_W, SourceFile.MANAICONS), - MANA_2B (FSkinProp.IMG_MANA_2B, SourceFile.MANAICONS), - MANA_2G (FSkinProp.IMG_MANA_2G, SourceFile.MANAICONS), - MANA_2R (FSkinProp.IMG_MANA_2R, SourceFile.MANAICONS), - MANA_2U (FSkinProp.IMG_MANA_2U, SourceFile.MANAICONS), - MANA_2W (FSkinProp.IMG_MANA_2W, SourceFile.MANAICONS), - MANA_HYBRID_BG (FSkinProp.IMG_MANA_HYBRID_BG, SourceFile.MANAICONS), - MANA_HYBRID_BR (FSkinProp.IMG_MANA_HYBRID_BR, SourceFile.MANAICONS), - MANA_HYBRID_GU (FSkinProp.IMG_MANA_HYBRID_GU, SourceFile.MANAICONS), - MANA_HYBRID_GW (FSkinProp.IMG_MANA_HYBRID_GW, SourceFile.MANAICONS), - MANA_HYBRID_RG (FSkinProp.IMG_MANA_HYBRID_RG, SourceFile.MANAICONS), - MANA_HYBRID_RW (FSkinProp.IMG_MANA_HYBRID_RW, SourceFile.MANAICONS), - MANA_HYBRID_UB (FSkinProp.IMG_MANA_HYBRID_UB, SourceFile.MANAICONS), - MANA_HYBRID_UR (FSkinProp.IMG_MANA_HYBRID_UR, SourceFile.MANAICONS), - MANA_HYBRID_WB (FSkinProp.IMG_MANA_HYBRID_WB, SourceFile.MANAICONS), - MANA_HYBRID_WU (FSkinProp.IMG_MANA_HYBRID_WU, SourceFile.MANAICONS), - MANA_PHRYX_U (FSkinProp.IMG_MANA_PHRYX_U, SourceFile.MANAICONS), - MANA_PHRYX_W (FSkinProp.IMG_MANA_PHRYX_W, SourceFile.MANAICONS), - MANA_PHRYX_R (FSkinProp.IMG_MANA_PHRYX_R, SourceFile.MANAICONS), - MANA_PHRYX_G (FSkinProp.IMG_MANA_PHRYX_G, SourceFile.MANAICONS), - MANA_PHRYX_B (FSkinProp.IMG_MANA_PHRYX_B, SourceFile.MANAICONS), - MANA_SNOW (FSkinProp.IMG_MANA_SNOW, SourceFile.MANAICONS), - MANA_0 (FSkinProp.IMG_MANA_0, SourceFile.MANAICONS), - MANA_1 (FSkinProp.IMG_MANA_1, SourceFile.MANAICONS), - MANA_2 (FSkinProp.IMG_MANA_2, SourceFile.MANAICONS), - MANA_3 (FSkinProp.IMG_MANA_3, SourceFile.MANAICONS), - MANA_4 (FSkinProp.IMG_MANA_4, SourceFile.MANAICONS), - MANA_5 (FSkinProp.IMG_MANA_5, SourceFile.MANAICONS), - MANA_6 (FSkinProp.IMG_MANA_6, SourceFile.MANAICONS), - MANA_7 (FSkinProp.IMG_MANA_7, SourceFile.MANAICONS), - MANA_8 (FSkinProp.IMG_MANA_8, SourceFile.MANAICONS), - MANA_9 (FSkinProp.IMG_MANA_9, SourceFile.MANAICONS), - MANA_10 (FSkinProp.IMG_MANA_10, SourceFile.MANAICONS), - MANA_11 (FSkinProp.IMG_MANA_11, SourceFile.MANAICONS), - MANA_12 (FSkinProp.IMG_MANA_12, SourceFile.MANAICONS), - MANA_13 (FSkinProp.IMG_MANA_13, SourceFile.MANAICONS), - MANA_14 (FSkinProp.IMG_MANA_14, SourceFile.MANAICONS), - MANA_15 (FSkinProp.IMG_MANA_15, SourceFile.MANAICONS), - MANA_16 (FSkinProp.IMG_MANA_16, SourceFile.MANAICONS), - MANA_17 (FSkinProp.IMG_MANA_17, SourceFile.MANAICONS), - MANA_18 (FSkinProp.IMG_MANA_18, SourceFile.MANAICONS), - MANA_19 (FSkinProp.IMG_MANA_19, SourceFile.MANAICONS), - MANA_20 (FSkinProp.IMG_MANA_20, SourceFile.MANAICONS), - MANA_X (FSkinProp.IMG_MANA_X, SourceFile.MANAICONS), - MANA_Y (FSkinProp.IMG_MANA_Y, SourceFile.MANAICONS), - MANA_Z (FSkinProp.IMG_MANA_Z, SourceFile.MANAICONS), - - //CMC ranges - CMC_LOW (FSkinProp.IMG_CMC_LOW, SourceFile.MANAICONS), - CMC_LOW_MID (FSkinProp.IMG_CMC_LOW_MID, SourceFile.MANAICONS), - CMC_MID_HIGH (FSkinProp.IMG_CMC_MID_HIGH, SourceFile.MANAICONS), - CMC_HIGH (FSkinProp.IMG_CMC_HIGH, SourceFile.MANAICONS), - - //Gameplay - TAP (FSkinProp.IMG_TAP, SourceFile.MANAICONS), - UNTAP (FSkinProp.IMG_UNTAP, SourceFile.MANAICONS), - CHAOS (FSkinProp.IMG_CHAOS, SourceFile.ICONS), - SLASH (FSkinProp.IMG_SLASH, SourceFile.ICONS), - ATTACK (FSkinProp.IMG_ATTACK, SourceFile.ICONS), - DEFEND (FSkinProp.IMG_DEFEND, SourceFile.ICONS), - SUMMONSICK (FSkinProp.IMG_SUMMONSICK, SourceFile.ICONS), - PHASING (FSkinProp.IMG_PHASING, SourceFile.ICONS), - COSTRESERVED (FSkinProp.IMG_COSTRESERVED, SourceFile.ICONS), - COUNTERS1 (FSkinProp.IMG_COUNTERS1, SourceFile.ICONS), - COUNTERS2 (FSkinProp.IMG_COUNTERS2, SourceFile.ICONS), - COUNTERS3 (FSkinProp.IMG_COUNTERS3, SourceFile.ICONS), - COUNTERS_MULTI (FSkinProp.IMG_COUNTERS_MULTI, SourceFile.ICONS), - ENERGY (FSkinProp.IMG_ENERGY, SourceFile.ICONS), - - //Dock Icons - SHORTCUTS (FSkinProp.ICO_SHORTCUTS, SourceFile.ICONS), - SETTINGS (FSkinProp.ICO_SETTINGS, SourceFile.ICONS), - ENDTURN (FSkinProp.ICO_ENDTURN, SourceFile.ICONS), - CONCEDE (FSkinProp.ICO_CONCEDE, SourceFile.ICONS), - REVERTLAYOUT (FSkinProp.ICO_REVERTLAYOUT, SourceFile.ICONS), - OPENLAYOUT (FSkinProp.ICO_OPENLAYOUT, SourceFile.ICONS), - SAVELAYOUT (FSkinProp.ICO_SAVELAYOUT, SourceFile.ICONS), - DECKLIST (FSkinProp.ICO_DECKLIST, SourceFile.ICONS), - ALPHASTRIKE (FSkinProp.ICO_ALPHASTRIKE, SourceFile.ICONS), - ARCSOFF (FSkinProp.ICO_ARCSOFF, SourceFile.ICONS), - ARCSON (FSkinProp.ICO_ARCSON, SourceFile.ICONS), - ARCSHOVER (FSkinProp.ICO_ARCSHOVER, SourceFile.ICONS), - - //choice-search-misc - HDCHOICE (FSkinProp.ICO_HDCHOICE, SourceFile.BUTTONS), - HDSIDEBOARD (FSkinProp.ICO_HDSIDEBOARD, SourceFile.BUTTONS), - HDPREFERENCE (FSkinProp.ICO_HDPREFERENCE, SourceFile.BUTTONS), - HDIMPORT (FSkinProp.ICO_HDIMPORT, SourceFile.BUTTONS), - HDEXPORT (FSkinProp.ICO_HDEXPORT, SourceFile.BUTTONS), - HDYIELD (FSkinProp.ICO_HDYIELD, SourceFile.BUTTONS), - BLANK (FSkinProp.ICO_BLANK, SourceFile.ICONS), - - //Achievement Trophies - COMMON_TROPHY (FSkinProp.IMG_COMMON_TROPHY, SourceFile.TROPHIES), - UNCOMMON_TROPHY (FSkinProp.IMG_UNCOMMON_TROPHY, SourceFile.TROPHIES), - RARE_TROPHY (FSkinProp.IMG_RARE_TROPHY, SourceFile.TROPHIES), - MYTHIC_TROPHY (FSkinProp.IMG_MYTHIC_TROPHY, SourceFile.TROPHIES), - SPECIAL_TROPHY (FSkinProp.IMG_SPECIAL_TROPHY, SourceFile.TROPHIES), - TROPHY_PLATE (FSkinProp.IMG_TROPHY_PLATE, SourceFile.TROPHIES), - TROPHY_CASE_TOP (FSkinProp.IMG_TROPHY_CASE_TOP, SourceFile.TROPHIES), - TROPHY_SHELF (FSkinProp.IMG_TROPHY_SHELF, SourceFile.TROPHIES), - - //Planar Conquest Images - PLANE_MONITOR (FSkinProp.IMG_PLANE_MONITOR, SourceFile.PLANAR_CONQUEST), - AETHER_SHARD (FSkinProp.IMG_AETHER_SHARD, SourceFile.PLANAR_CONQUEST), - MULTIVERSE (FSkinProp.IMG_MULTIVERSE, SourceFile.PLANAR_CONQUEST), - SPELLBOOK (FSkinProp.IMG_SPELLBOOK, SourceFile.PLANAR_CONQUEST), - PW_BADGE_COMMON (FSkinProp.IMG_PW_BADGE_COMMON, SourceFile.PLANAR_CONQUEST), - PW_BADGE_UNCOMMON (FSkinProp.IMG_PW_BADGE_UNCOMMON, SourceFile.PLANAR_CONQUEST), - PW_BADGE_RARE (FSkinProp.IMG_PW_BADGE_RARE, SourceFile.PLANAR_CONQUEST), - PW_BADGE_MYTHIC (FSkinProp.IMG_PW_BADGE_MYTHIC, SourceFile.PLANAR_CONQUEST), - - //Quest Icons - QUEST_ZEP (FSkinProp.ICO_QUEST_ZEP, SourceFile.ICONS), - QUEST_GEAR (FSkinProp.ICO_QUEST_GEAR, SourceFile.ICONS), - QUEST_GOLD (FSkinProp.ICO_QUEST_GOLD, SourceFile.ICONS), - QUEST_ELIXIR (FSkinProp.ICO_QUEST_ELIXIR, SourceFile.ICONS), - QUEST_BOOK (FSkinProp.ICO_QUEST_BOOK, SourceFile.ICONS), - QUEST_BOTTLES (FSkinProp.ICO_QUEST_BOTTLES, SourceFile.ICONS), - QUEST_BOX (FSkinProp.ICO_QUEST_BOX, SourceFile.ICONS), - QUEST_COIN (FSkinProp.ICO_QUEST_COIN, SourceFile.ICONS), - QUEST_CHARM (FSkinProp.ICO_QUEST_CHARM, SourceFile.ICONS), - QUEST_FOX (FSkinProp.ICO_QUEST_FOX, SourceFile.ICONS), - QUEST_LEAF (FSkinProp.ICO_QUEST_LEAF, SourceFile.ICONS), - QUEST_LIFE (FSkinProp.ICO_QUEST_LIFE, SourceFile.ICONS), - QUEST_COINSTACK (FSkinProp.ICO_QUEST_COINSTACK, SourceFile.ICONS), - QUEST_MAP (FSkinProp.ICO_QUEST_MAP, SourceFile.ICONS), - QUEST_NOTES (FSkinProp.ICO_QUEST_NOTES, SourceFile.ICONS), - QUEST_HEART (FSkinProp.ICO_QUEST_HEART, SourceFile.ICONS), - QUEST_BREW (FSkinProp.ICO_QUEST_BREW, SourceFile.ICONS), - QUEST_STAKES (FSkinProp.ICO_QUEST_STAKES, SourceFile.ICONS), - QUEST_MINUS (FSkinProp.ICO_QUEST_MINUS, SourceFile.ICONS), - QUEST_PLUS (FSkinProp.ICO_QUEST_PLUS, SourceFile.ICONS), - QUEST_PLUSPLUS (FSkinProp.ICO_QUEST_PLUSPLUS, SourceFile.ICONS), - QUEST_BIG_ELIXIR (FSkinProp.ICO_QUEST_BIG_ELIXIR, SourceFile.ICONS), - QUEST_BIG_BREW (FSkinProp.ICO_QUEST_BIG_BREW, SourceFile.ICONS), - QUEST_BIG_BM (FSkinProp.ICO_QUEST_BIG_BM, SourceFile.ICONS), - QUEST_BIG_STAKES (FSkinProp.ICO_QUEST_BIG_STAKES, SourceFile.ICONS), - QUEST_BIG_HOUSE (FSkinProp.ICO_QUEST_BIG_HOUSE, SourceFile.ICONS), - QUEST_BIG_COIN (FSkinProp.ICO_QUEST_BIG_COIN, SourceFile.ICONS), - QUEST_BIG_BOOK (FSkinProp.ICO_QUEST_BIG_BOOK, SourceFile.ICONS), - QUEST_BIG_MAP (FSkinProp.ICO_QUEST_BIG_MAP, SourceFile.ICONS), - QUEST_BIG_ZEP (FSkinProp.ICO_QUEST_BIG_ZEP, SourceFile.ICONS), - QUEST_BIG_CHARM (FSkinProp.ICO_QUEST_BIG_CHARM, SourceFile.ICONS), - QUEST_BIG_BOOTS (FSkinProp.ICO_QUEST_BIG_BOOTS, SourceFile.ICONS), - QUEST_BIG_SHIELD (FSkinProp.ICO_QUEST_BIG_SHIELD, SourceFile.ICONS), - QUEST_BIG_ARMOR (FSkinProp.ICO_QUEST_BIG_ARMOR, SourceFile.ICONS), - QUEST_BIG_AXE (FSkinProp.ICO_QUEST_BIG_AXE, SourceFile.ICONS), - QUEST_BIG_SWORD (FSkinProp.ICO_QUEST_BIG_SWORD, SourceFile.ICONS), - QUEST_BIG_BAG (FSkinProp.ICO_QUEST_BIG_BAG, SourceFile.ICONS), - - //menu icon - MENU_GALAXY (FSkinProp.ICO_MENU_GALAXY, SourceFile.ICONS), - MENU_STATS (FSkinProp.ICO_MENU_STATS, SourceFile.ICONS), - MENU_PUZZLE (FSkinProp.ICO_MENU_PUZZLE, SourceFile.ICONS), - MENU_GAUNTLET (FSkinProp.ICO_MENU_GAUNTLET, SourceFile.ICONS), - MENU_SEALED (FSkinProp.ICO_MENU_SEALED, SourceFile.ICONS), - MENU_DRAFT (FSkinProp.ICO_MENU_DRAFT, SourceFile.ICONS), - MENU_CONSTRUCTED (FSkinProp.ICO_MENU_CONSTRUCTED, SourceFile.ICONS), - - //Interface icons - QUESTION (FSkinProp.ICO_QUESTION, SourceFile.ICONS), - INFORMATION (FSkinProp.ICO_INFORMATION, SourceFile.ICONS), - WARNING (FSkinProp.ICO_WARNING, SourceFile.ICONS), - ERROR (FSkinProp.ICO_ERROR, SourceFile.ICONS), - - DELETE (FSkinProp.ICO_DELETE, SourceFile.ICONS), - HDDELETE (FSkinProp.ICO_HDDELETE, SourceFile.BUTTONS), - - DELETE_OVER (FSkinProp.ICO_DELETE_OVER, SourceFile.ICONS), - - EDIT (FSkinProp.ICO_EDIT, SourceFile.ICONS), - HDEDIT (FSkinProp.ICO_HDEDIT, SourceFile.BUTTONS), - - EDIT_OVER (FSkinProp.ICO_EDIT_OVER, SourceFile.ICONS), - - OPEN (FSkinProp.ICO_OPEN, SourceFile.ICONS), - HDOPEN (FSkinProp.ICO_HDOPEN, SourceFile.BUTTONS), - - MINUS (FSkinProp.ICO_MINUS, SourceFile.ICONS), - HDMINUS (FSkinProp.ICO_HDMINUS, SourceFile.BUTTONS), - - NEW (FSkinProp.ICO_NEW, SourceFile.ICONS), - - PLUS (FSkinProp.ICO_PLUS, SourceFile.ICONS), - HDPLUS (FSkinProp.ICO_HDPLUS, SourceFile.BUTTONS), - - PRINT (FSkinProp.ICO_PRINT, SourceFile.ICONS), - - SAVE (FSkinProp.ICO_SAVE, SourceFile.ICONS), - HDSAVE (FSkinProp.ICO_HDSAVE, SourceFile.BUTTONS), - SAVEAS (FSkinProp.ICO_SAVEAS, SourceFile.ICONS), - HDSAVEAS (FSkinProp.ICO_HDSAVEAS, SourceFile.BUTTONS), - - CLOSE (FSkinProp.ICO_CLOSE, SourceFile.ICONS), - LIST (FSkinProp.ICO_LIST, SourceFile.ICONS), - CARD_IMAGE (FSkinProp.ICO_CARD_IMAGE, SourceFile.ICONS), - - FOLDER (FSkinProp.ICO_FOLDER, SourceFile.ICONS), - HDFOLDER (FSkinProp.ICO_HDFOLDER, SourceFile.BUTTONS), - - SEARCH (FSkinProp.ICO_SEARCH, SourceFile.ICONS), - HDSEARCH (FSkinProp.ICO_HDSEARCH, SourceFile.BUTTONS), - - UNKNOWN (FSkinProp.ICO_UNKNOWN, SourceFile.ICONS), - LOGO (FSkinProp.ICO_LOGO, SourceFile.ICONS), - - FLIPCARD (FSkinProp.ICO_FLIPCARD, SourceFile.ICONS), - HDFLIPCARD (FSkinProp.ICO_HDFLIPCARD, SourceFile.BUTTONS), - - FAVICON (FSkinProp.ICO_FAVICON, SourceFile.ICONS), - LOCK (FSkinProp.ICO_LOCK, SourceFile.ICONS), - - //Layout images - HANDLE (FSkinProp.IMG_HANDLE, SourceFile.ICONS), - CUR_L (FSkinProp.IMG_CUR_L, SourceFile.ICONS), - CUR_R (FSkinProp.IMG_CUR_R, SourceFile.ICONS), - CUR_T (FSkinProp.IMG_CUR_T, SourceFile.ICONS), - CUR_B (FSkinProp.IMG_CUR_B, SourceFile.ICONS), - CUR_TAB (FSkinProp.IMG_CUR_TAB, SourceFile.ICONS), - - //Editor images - STAR_OUTLINE (FSkinProp.IMG_STAR_OUTLINE, SourceFile.ICONS), - HDSTAR_OUTLINE (FSkinProp.IMG_HDSTAR_OUTLINE, SourceFile.BUTTONS), - STAR_FILLED (FSkinProp.IMG_STAR_FILLED, SourceFile.ICONS), - HDSTAR_FILLED (FSkinProp.IMG_HDSTAR_FILLED, SourceFile.BUTTONS), - - ARTIFACT (FSkinProp.IMG_ARTIFACT, SourceFile.MANAICONS), - CREATURE (FSkinProp.IMG_CREATURE, SourceFile.MANAICONS), - ENCHANTMENT (FSkinProp.IMG_ENCHANTMENT, SourceFile.MANAICONS), - INSTANT (FSkinProp.IMG_INSTANT, SourceFile.MANAICONS), - LAND (FSkinProp.IMG_LAND, SourceFile.MANAICONS), - LANDLOGO (FSkinProp.IMG_LANDLOGO, SourceFile.MANAICONS), - MULTI (FSkinProp.IMG_MULTI, SourceFile.ICONS), - HDMULTI (FSkinProp.IMG_HDMULTI, SourceFile.MANAICONS), - PLANESWALKER (FSkinProp.IMG_PLANESWALKER, SourceFile.MANAICONS), - PACK (FSkinProp.IMG_PACK, SourceFile.ICONS), - SORCERY (FSkinProp.IMG_SORCERY, SourceFile.MANAICONS), - COMMANDER (FSkinProp.IMG_COMMANDER, SourceFile.ICONS), - - //Buttons - BTN_START_UP (FSkinProp.IMG_BTN_START_UP, SourceFile.ICONS), - BTN_START_OVER (FSkinProp.IMG_BTN_START_OVER, SourceFile.ICONS), - BTN_START_DOWN (FSkinProp.IMG_BTN_START_DOWN, SourceFile.ICONS), - BTN_UP_LEFT (FSkinProp.IMG_BTN_UP_LEFT, SourceFile.ICONS), - BTN_UP_CENTER (FSkinProp.IMG_BTN_UP_CENTER, SourceFile.ICONS), - BTN_UP_RIGHT (FSkinProp.IMG_BTN_UP_RIGHT, SourceFile.ICONS), - BTN_OVER_LEFT (FSkinProp.IMG_BTN_OVER_LEFT, SourceFile.ICONS), - BTN_OVER_CENTER (FSkinProp.IMG_BTN_OVER_CENTER, SourceFile.ICONS), - BTN_OVER_RIGHT (FSkinProp.IMG_BTN_OVER_RIGHT, SourceFile.ICONS), - BTN_DOWN_LEFT (FSkinProp.IMG_BTN_DOWN_LEFT, SourceFile.ICONS), - BTN_DOWN_CENTER (FSkinProp.IMG_BTN_DOWN_CENTER, SourceFile.ICONS), - BTN_DOWN_RIGHT (FSkinProp.IMG_BTN_DOWN_RIGHT, SourceFile.ICONS), - BTN_FOCUS_LEFT (FSkinProp.IMG_BTN_FOCUS_LEFT, SourceFile.ICONS), - BTN_FOCUS_CENTER (FSkinProp.IMG_BTN_FOCUS_CENTER, SourceFile.ICONS), - BTN_FOCUS_RIGHT (FSkinProp.IMG_BTN_FOCUS_RIGHT, SourceFile.ICONS), - BTN_TOGGLE_LEFT (FSkinProp.IMG_BTN_TOGGLE_LEFT, SourceFile.ICONS), - BTN_TOGGLE_CENTER (FSkinProp.IMG_BTN_TOGGLE_CENTER, SourceFile.ICONS), - BTN_TOGGLE_RIGHT (FSkinProp.IMG_BTN_TOGGLE_RIGHT, SourceFile.ICONS), - BTN_DISABLED_LEFT (FSkinProp.IMG_BTN_DISABLED_LEFT, SourceFile.ICONS), - BTN_DISABLED_CENTER (FSkinProp.IMG_BTN_DISABLED_CENTER, SourceFile.ICONS), - BTN_DISABLED_RIGHT (FSkinProp.IMG_BTN_DISABLED_RIGHT, SourceFile.ICONS), - //Hdbuttons - HDBTN_START_UP (FSkinProp.IMG_HDBTN_START_UP, SourceFile.BTNSTART), - HDBTN_START_OVER (FSkinProp.IMG_HDBTN_START_OVER, SourceFile.BTNSTART), - HDBTN_START_DOWN (FSkinProp.IMG_HDBTN_START_DOWN, SourceFile.BTNSTART), - HDBTN_UP_LEFT (FSkinProp.IMG_HDBTN_UP_LEFT, SourceFile.BUTTONS), - HDBTN_UP_CENTER (FSkinProp.IMG_HDBTN_UP_CENTER, SourceFile.BUTTONS), - HDBTN_UP_RIGHT (FSkinProp.IMG_HDBTN_UP_RIGHT, SourceFile.BUTTONS), - HDBTN_OVER_LEFT (FSkinProp.IMG_HDBTN_OVER_LEFT, SourceFile.BUTTONS), - HDBTN_OVER_CENTER (FSkinProp.IMG_HDBTN_OVER_CENTER, SourceFile.BUTTONS), - HDBTN_OVER_RIGHT (FSkinProp.IMG_HDBTN_OVER_RIGHT, SourceFile.BUTTONS), - HDBTN_DOWN_LEFT (FSkinProp.IMG_HDBTN_DOWN_LEFT, SourceFile.BUTTONS), - HDBTN_DOWN_CENTER (FSkinProp.IMG_HDBTN_DOWN_CENTER, SourceFile.BUTTONS), - HDBTN_DOWN_RIGHT (FSkinProp.IMG_HDBTN_DOWN_RIGHT, SourceFile.BUTTONS), - HDBTN_FOCUS_LEFT (FSkinProp.IMG_HDBTN_FOCUS_LEFT, SourceFile.BUTTONS), - HDBTN_FOCUS_CENTER (FSkinProp.IMG_HDBTN_FOCUS_CENTER, SourceFile.BUTTONS), - HDBTN_FOCUS_RIGHT (FSkinProp.IMG_HDBTN_FOCUS_RIGHT, SourceFile.BUTTONS), - HDBTN_TOGGLE_LEFT (FSkinProp.IMG_HDBTN_TOGGLE_LEFT, SourceFile.BUTTONS), - HDBTN_TOGGLE_CENTER (FSkinProp.IMG_HDBTN_TOGGLE_CENTER, SourceFile.BUTTONS), - HDBTN_TOGGLE_RIGHT (FSkinProp.IMG_HDBTN_TOGGLE_RIGHT, SourceFile.BUTTONS), - HDBTN_DISABLED_LEFT (FSkinProp.IMG_HDBTN_DISABLED_LEFT, SourceFile.BUTTONS), - HDBTN_DISABLED_CENTER (FSkinProp.IMG_HDBTN_DISABLED_CENTER, SourceFile.BUTTONS), - HDBTN_DISABLED_RIGHT (FSkinProp.IMG_HDBTN_DISABLED_RIGHT, SourceFile.BUTTONS), - - //Foils - FOIL_01 (FSkinProp.FOIL_01, SourceFile.FOILS), - FOIL_02 (FSkinProp.FOIL_02, SourceFile.FOILS), - FOIL_03 (FSkinProp.FOIL_03, SourceFile.FOILS), - FOIL_04 (FSkinProp.FOIL_04, SourceFile.FOILS), - FOIL_05 (FSkinProp.FOIL_05, SourceFile.FOILS), - FOIL_06 (FSkinProp.FOIL_06, SourceFile.FOILS), - FOIL_07 (FSkinProp.FOIL_07, SourceFile.FOILS), - FOIL_08 (FSkinProp.FOIL_08, SourceFile.FOILS), - FOIL_09 (FSkinProp.FOIL_09, SourceFile.FOILS), - FOIL_10 (FSkinProp.FOIL_10, SourceFile.FOILS), - - //Old Foils - FOIL_11 (FSkinProp.FOIL_11, SourceFile.OLD_FOILS), - FOIL_12 (FSkinProp.FOIL_12, SourceFile.OLD_FOILS), - FOIL_13 (FSkinProp.FOIL_13, SourceFile.OLD_FOILS), - FOIL_14 (FSkinProp.FOIL_14, SourceFile.OLD_FOILS), - FOIL_15 (FSkinProp.FOIL_15, SourceFile.OLD_FOILS), - FOIL_16 (FSkinProp.FOIL_16, SourceFile.OLD_FOILS), - FOIL_17 (FSkinProp.FOIL_17, SourceFile.OLD_FOILS), - FOIL_18 (FSkinProp.FOIL_18, SourceFile.OLD_FOILS), - FOIL_19 (FSkinProp.FOIL_19, SourceFile.OLD_FOILS), - FOIL_20 (FSkinProp.FOIL_20, SourceFile.OLD_FOILS), - - //COMMANDER - IMG_ABILITY_COMMANDER (FSkinProp.IMG_ABILITY_COMMANDER, SourceFile.ABILITIES), - //ABILITY ICONS - IMG_ABILITY_DEATHTOUCH (FSkinProp.IMG_ABILITY_DEATHTOUCH, SourceFile.ABILITIES), - IMG_ABILITY_DEFENDER (FSkinProp.IMG_ABILITY_DEFENDER, SourceFile.ABILITIES), - IMG_ABILITY_DOUBLE_STRIKE (FSkinProp.IMG_ABILITY_DOUBLE_STRIKE, SourceFile.ABILITIES), - IMG_ABILITY_FIRST_STRIKE (FSkinProp.IMG_ABILITY_FIRST_STRIKE, SourceFile.ABILITIES), - IMG_ABILITY_FEAR (FSkinProp.IMG_ABILITY_FEAR, SourceFile.ABILITIES), - IMG_ABILITY_FLASH (FSkinProp.IMG_ABILITY_FLASH, SourceFile.ABILITIES), - IMG_ABILITY_FLYING (FSkinProp.IMG_ABILITY_FLYING, SourceFile.ABILITIES), - IMG_ABILITY_HASTE (FSkinProp.IMG_ABILITY_HASTE, SourceFile.ABILITIES), - IMG_ABILITY_HEXPROOF (FSkinProp.IMG_ABILITY_HEXPROOF, SourceFile.ABILITIES), - IMG_ABILITY_HORSEMANSHIP (FSkinProp.IMG_ABILITY_HORSEMANSHIP, SourceFile.ABILITIES), - IMG_ABILITY_INDESTRUCTIBLE (FSkinProp.IMG_ABILITY_INDESTRUCTIBLE, SourceFile.ABILITIES), - IMG_ABILITY_INTIMIDATE (FSkinProp.IMG_ABILITY_INTIMIDATE, SourceFile.ABILITIES), - IMG_ABILITY_LANDWALK (FSkinProp.IMG_ABILITY_LANDWALK, SourceFile.ABILITIES), - IMG_ABILITY_LIFELINK (FSkinProp.IMG_ABILITY_LIFELINK, SourceFile.ABILITIES), - IMG_ABILITY_MENACE (FSkinProp.IMG_ABILITY_MENACE, SourceFile.ABILITIES), - IMG_ABILITY_REACH (FSkinProp.IMG_ABILITY_REACH, SourceFile.ABILITIES), - IMG_ABILITY_SHADOW (FSkinProp.IMG_ABILITY_SHADOW, SourceFile.ABILITIES), - IMG_ABILITY_SHROUD (FSkinProp.IMG_ABILITY_SHROUD, SourceFile.ABILITIES), - IMG_ABILITY_TRAMPLE (FSkinProp.IMG_ABILITY_TRAMPLE, SourceFile.ABILITIES), - IMG_ABILITY_VIGILANCE (FSkinProp.IMG_ABILITY_VIGILANCE, SourceFile.ABILITIES), - //HEXPROOF FROM - IMG_ABILITY_HEXPROOF_R (FSkinProp.IMG_ABILITY_HEXPROOF_R, SourceFile.ABILITIES), - IMG_ABILITY_HEXPROOF_G (FSkinProp.IMG_ABILITY_HEXPROOF_G, SourceFile.ABILITIES), - IMG_ABILITY_HEXPROOF_B (FSkinProp.IMG_ABILITY_HEXPROOF_B, SourceFile.ABILITIES), - IMG_ABILITY_HEXPROOF_U (FSkinProp.IMG_ABILITY_HEXPROOF_U, SourceFile.ABILITIES), - IMG_ABILITY_HEXPROOF_W (FSkinProp.IMG_ABILITY_HEXPROOF_W, SourceFile.ABILITIES), - IMG_ABILITY_HEXPROOF_C (FSkinProp.IMG_ABILITY_HEXPROOF_C, SourceFile.ABILITIES), - IMG_ABILITY_HEXPROOF_UB (FSkinProp.IMG_ABILITY_HEXPROOF_UB, SourceFile.ABILITIES), - //token icon - IMG_ABILITY_TOKEN (FSkinProp.IMG_ABILITY_TOKEN, SourceFile.ABILITIES), - //border - IMG_BORDER_BLACK (FSkinProp.IMG_BORDER_BLACK, SourceFile.BORDERS), - IMG_BORDER_WHITE (FSkinProp.IMG_BORDER_WHITE, SourceFile.BORDERS), - //PROTECT ICONS - IMG_ABILITY_PROTECT_ALL (FSkinProp.IMG_ABILITY_PROTECT_ALL, SourceFile.ABILITIES), - IMG_ABILITY_PROTECT_B (FSkinProp.IMG_ABILITY_PROTECT_B, SourceFile.ABILITIES), - IMG_ABILITY_PROTECT_BU (FSkinProp.IMG_ABILITY_PROTECT_BU, SourceFile.ABILITIES), - IMG_ABILITY_PROTECT_BW (FSkinProp.IMG_ABILITY_PROTECT_BW, SourceFile.ABILITIES), - IMG_ABILITY_PROTECT_COLOREDSPELLS (FSkinProp.IMG_ABILITY_PROTECT_COLOREDSPELLS, SourceFile.ABILITIES), - IMG_ABILITY_PROTECT_G (FSkinProp.IMG_ABILITY_PROTECT_G, SourceFile.ABILITIES), - IMG_ABILITY_PROTECT_GB (FSkinProp.IMG_ABILITY_PROTECT_GB, SourceFile.ABILITIES), - IMG_ABILITY_PROTECT_GU (FSkinProp.IMG_ABILITY_PROTECT_GU, SourceFile.ABILITIES), - IMG_ABILITY_PROTECT_GW (FSkinProp.IMG_ABILITY_PROTECT_GW, SourceFile.ABILITIES), - IMG_ABILITY_PROTECT_GENERIC (FSkinProp.IMG_ABILITY_PROTECT_GENERIC, SourceFile.ABILITIES), - IMG_ABILITY_PROTECT_R (FSkinProp.IMG_ABILITY_PROTECT_R, SourceFile.ABILITIES), - IMG_ABILITY_PROTECT_RB (FSkinProp.IMG_ABILITY_PROTECT_RB, SourceFile.ABILITIES), - IMG_ABILITY_PROTECT_RG (FSkinProp.IMG_ABILITY_PROTECT_RG, SourceFile.ABILITIES), - IMG_ABILITY_PROTECT_RU (FSkinProp.IMG_ABILITY_PROTECT_RU, SourceFile.ABILITIES), - IMG_ABILITY_PROTECT_RW (FSkinProp.IMG_ABILITY_PROTECT_RW, SourceFile.ABILITIES), - IMG_ABILITY_PROTECT_U (FSkinProp.IMG_ABILITY_PROTECT_U, SourceFile.ABILITIES), - IMG_ABILITY_PROTECT_UW (FSkinProp.IMG_ABILITY_PROTECT_UW, SourceFile.ABILITIES), - IMG_ABILITY_PROTECT_W (FSkinProp.IMG_ABILITY_PROTECT_W, SourceFile.ABILITIES); - - public enum SourceFile { - ICONS(ForgeConstants.SPRITE_ICONS_FILE), - FOILS(ForgeConstants.SPRITE_FOILS_FILE), - OLD_FOILS(ForgeConstants.SPRITE_OLD_FOILS_FILE), - TROPHIES(ForgeConstants.SPRITE_TROPHIES_FILE), - ABILITIES(ForgeConstants.SPRITE_ABILITY_FILE), - BORDERS(ForgeConstants.SPRITE_BORDER_FILE), - BUTTONS(ForgeConstants.SPRITE_BUTTONS_FILE), - BTNSTART(ForgeConstants.SPRITE_START_FILE), - MANAICONS(ForgeConstants.SPRITE_MANAICONS_FILE), - PLANAR_CONQUEST(ForgeConstants.SPRITE_PLANAR_CONQUEST_FILE); - - private final String filename; - - SourceFile(String filename0) { - filename = filename0; - } - - public String getFilename() { - return filename; - } - } - - private final int x, y, w, h; - private final SourceFile sourceFile; - private TextureRegion textureRegion; - - FSkinImage(FSkinProp skinProp, SourceFile sourceFile0) { - int[] coords = skinProp.getCoords(); - x = coords[0]; - y = coords[1]; - w = coords[2]; - h = coords[3]; - sourceFile = sourceFile0; - FSkin.getImages().put(skinProp, this); - } - - public void load(Map textures, Pixmap preferredIcons) { - String filename = sourceFile.getFilename(); - FileHandle preferredFile = FSkin.getSkinFile(filename); - Texture texture = textures.get(preferredFile.path()); - if (texture == null) { - if (preferredFile.exists()) { - try { - if (Forge.isTextureFilteringEnabled()){ - texture = new Texture(preferredFile, true); - texture.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear); - } else { - texture = new Texture(preferredFile); - } - } - catch (final Exception e) { - System.err.println("Failed to load skin file: " + preferredFile); - e.printStackTrace(); - } - } - } - if (texture != null) { - if (!(sourceFile == SourceFile.ICONS || sourceFile == SourceFile.MANAICONS)) { //just return region for preferred file if not icons file - textureRegion = new TextureRegion(texture, x, y, w, h); - return; - } - - int fullWidth = texture.getWidth(); - int fullHeight = texture.getHeight(); - - // Test if requested sub-image in inside bounds of preferred sprite. - // (Height and width of preferred sprite were set in loadFontAndImages.) - if (x + w <= fullWidth && y + h <= fullHeight) { - // Test if various points of requested sub-image are transparent. - // If any return true, image exists. - int x0 = 0, y0 = 0; - Color c; - - // Center - x0 = (x + w / 2); - y0 = (y + h / 2); - c = new Color(preferredIcons.getPixel(x0, y0)); - if (c.a != 0) { - textureRegion = new TextureRegion(texture, x, y, w, h); - return; - } - - x0 += 2; - y0 += 2; - c = new Color(preferredIcons.getPixel(x0, y0)); - if (c.a != 0) { - textureRegion = new TextureRegion(texture, x, y, w, h); - return; - } - - x0 -= 4; - c = new Color(preferredIcons.getPixel(x0, y0)); - if (c.a != 0) { - textureRegion = new TextureRegion(texture, x, y, w, h); - return; - } - - y0 -= 4; - c = new Color(preferredIcons.getPixel(x0, y0)); - if (c.a != 0) { - textureRegion = new TextureRegion(texture, x, y, w, h); - return; - } - - x0 += 4; - c = new Color(preferredIcons.getPixel(x0, y0)); - if (c.a != 0) { - textureRegion = new TextureRegion(texture, x, y, w, h); - return; - } - } - } - - //use default file if can't use preferred file - FileHandle defaultFile = FSkin.getDefaultSkinFile(filename); - texture = textures.get(defaultFile.path()); - if (texture == null) { - if (defaultFile.exists()) { - try { - if (Forge.isTextureFilteringEnabled()){ - texture = new Texture(defaultFile, true); - texture.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear); - } else { - texture = new Texture(defaultFile); - } - } - catch (final Exception e) { - System.err.println("Failed to load skin file: " + defaultFile); - e.printStackTrace(); - } - } - } - if (texture != null) { - textureRegion = new TextureRegion(texture, x, y, w, h); - } - } - - @Override - public float getWidth() { - return w; - } - - @Override - public float getHeight() { - return h; - } - - public TextureRegion getTextureRegion() { - return textureRegion; - } - - public float getNearestHQWidth(float baseWidth) { - return ImageUtil.getNearestHQSize(baseWidth, w); - } - - public float getNearestHQHeight(float baseHeight) { - return ImageUtil.getNearestHQSize(baseHeight, h); - } - - @Override - public void draw(Graphics g, float x, float y, float w, float h) { - g.drawImage(textureRegion, x, y, w, h); - } -} \ No newline at end of file diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkinTexture.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkinTexture.java deleted file mode 100644 index 6e65d68352e..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FSkinTexture.java +++ /dev/null @@ -1,190 +0,0 @@ -package forge.adventure.libgdxgui.assets; - -import com.badlogic.gdx.files.FileHandle; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.Texture.TextureWrap; -import forge.adventure.libgdxgui.Graphics; -import forge.localinstance.properties.ForgeConstants; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public enum FSkinTexture implements FImage { - BG_TEXTURE(ForgeConstants.TEXTURE_BG_FILE, true, false), - BG_MATCH(ForgeConstants.MATCH_BG_FILE, false, false), - BG_SPACE(ForgeConstants.SPACE_BG_FILE, false, false), - BG_CHAOS_WHEEL(ForgeConstants.CHAOS_WHEEL_IMG_FILE, false, false), - Academy_at_Tolaria_West(ForgeConstants.BG_1, false, true), - Agyrem(ForgeConstants.BG_2, false, true), - Akoum(ForgeConstants.BG_3, false, true), - Aretopolis(ForgeConstants.BG_4, false, true), - Astral_Arena(ForgeConstants.BG_5, false, true), - Bant(ForgeConstants.BG_6, false, true), - Bloodhill_Bastion(ForgeConstants.BG_7, false, true), - Cliffside_Market(ForgeConstants.BG_8, false, true), - Edge_of_Malacol(ForgeConstants.BG_9, false, true), - Eloren_Wilds(ForgeConstants.BG_10, false, true), - Feeding_Grounds(ForgeConstants.BG_11, false, true), - Fields_of_Summer(ForgeConstants.BG_12, false, true), - Furnace_Layer(ForgeConstants.BG_13, false, true), - Gavony(ForgeConstants.BG_14, false, true), - Glen_Elendra(ForgeConstants.BG_15, false, true), - Glimmervoid_Basin(ForgeConstants.BG_16, false, true), - Goldmeadow(ForgeConstants.BG_17, false, true), - Grand_Ossuary(ForgeConstants.BG_18, false, true), - Grixis(ForgeConstants.BG_19, false, true), - Grove_of_the_Dreampods(ForgeConstants.BG_20, false, true), - Hedron_Fields_of_Agadeem(ForgeConstants.BG_21, false, true), - Immersturm(ForgeConstants.BG_22, false, true), - Isle_of_Vesuva(ForgeConstants.BG_23, false, true), - Izzet_Steam_Maze(ForgeConstants.BG_24, false, true), - Jund(ForgeConstants.BG_25, false, true), - Kessig(ForgeConstants.BG_26, false, true), - Kharasha_Foothills(ForgeConstants.BG_27, false, true), - Kilnspire_District(ForgeConstants.BG_28, false, true), - Krosa(ForgeConstants.BG_29, false, true), - Lair_of_the_Ashen_Idol(ForgeConstants.BG_30, false, true), - Lethe_Lake(ForgeConstants.BG_31, false, true), - Llanowar(ForgeConstants.BG_32, false, true), - Minamo(ForgeConstants.BG_33, false, true), - Mount_Keralia(ForgeConstants.BG_34, false, true), - Murasa(ForgeConstants.BG_35, false, true), - Naar_Isle(ForgeConstants.BG_36, false, true), - Naya(ForgeConstants.BG_37, false, true), - Nephalia(ForgeConstants.BG_38, false, true), - Norns_Dominion(ForgeConstants.BG_39, false, true), - Onakke_Catacomb(ForgeConstants.BG_40, false, true), - Orochi_Colony(ForgeConstants.BG_41, false, true), - Orzhova(ForgeConstants.BG_42, false, true), - Otaria(ForgeConstants.BG_43, false, true), - Panopticon(ForgeConstants.BG_44, false, true), - Pools_of_Becoming(ForgeConstants.BG_45, false, true), - Prahv(ForgeConstants.BG_46, false, true), - Quicksilver_Sea(ForgeConstants.BG_47, false, true), - Ravens_Run(ForgeConstants.BG_48, false, true), - Sanctum_of_Serra(ForgeConstants.BG_49, false, true), - Sea_of_Sand(ForgeConstants.BG_50, false, true), - Selesnya_Loft_Gardens(ForgeConstants.BG_51, false, true), - Shiv(ForgeConstants.BG_52, false, true), - Skybreen(ForgeConstants.BG_53, false, true), - Sokenzan(ForgeConstants.BG_54, false, true), - Stairs_to_Infinity(ForgeConstants.BG_55, false, true), - Stensia(ForgeConstants.BG_56, false, true), - Stronghold_Furnace(ForgeConstants.BG_57, false, true), - Takenuma(ForgeConstants.BG_58, false, true), - Tazeem(ForgeConstants.BG_59, false, true), - The_Aether_Flues(ForgeConstants.BG_60, false, true), - The_Dark_Barony(ForgeConstants.BG_61, false, true), - The_Eon_Fog(ForgeConstants.BG_62, false, true), - The_Fourth_Sphere(ForgeConstants.BG_63, false, true), - The_Great_Forest(ForgeConstants.BG_64, false, true), - The_Hippodrome(ForgeConstants.BG_65, false, true), - The_Maelstrom(ForgeConstants.BG_66, false, true), - The_Zephyr_Maze(ForgeConstants.BG_67, false, true), - Trail_of_the_MageRings(ForgeConstants.BG_68, false, true), - Truga_Jungle(ForgeConstants.BG_69, false, true), - Turri_Island(ForgeConstants.BG_70, false, true), - Undercity_Reaches(ForgeConstants.BG_71, false, true), - Velis_Vel(ForgeConstants.BG_72, false, true), - Windriddle_Palaces(ForgeConstants.BG_73, false, true), - Tember_City(ForgeConstants.BG_74, false, true), - Celestine_Reef(ForgeConstants.BG_75, false, true), - Horizon_Boughs(ForgeConstants.BG_76, false, true), - Mirrored_Depths(ForgeConstants.BG_77, false, true), - Talon_Gates(ForgeConstants.BG_78, false, true); - - private final String filename; - private final boolean repeat; - private Texture texture; - private final boolean isPlane; - private static final List PlanesValue; - - FSkinTexture(String filename0, boolean repeat0, boolean isPlane0) { - filename = filename0; - repeat = repeat0; - isPlane = isPlane0; - } - - static { - PlanesValue = new ArrayList<>(); - for (FSkinTexture PlanesEnum : FSkinTexture.values()) { - PlanesValue.add(PlanesEnum.filename - .replace(".jpg", "") - .replace("'", "") - .replace("-", "")); - } - } - - public static List getValues() { - return Collections.unmodifiableList(PlanesValue); - } - - public void load() { - FileHandle preferredFile = isPlane ? FSkin.getCachePlanechaseFile(filename) : FSkin.getSkinFile(filename); - if (preferredFile.exists()) { - try { - texture = new Texture(preferredFile); - } - catch (final Exception e) { - System.err.println("Failed to load skin file: " + preferredFile); - e.printStackTrace(); - } - } - if (texture == null) { - //use default file if can't use preferred file - FileHandle defaultFile = FSkin.getDefaultSkinFile(filename); - if(isPlane) { - defaultFile = FSkin.getSkinFile(ForgeConstants.MATCH_BG_FILE); - if(!defaultFile.exists()) - defaultFile = FSkin.getDefaultSkinFile(ForgeConstants.MATCH_BG_FILE); - } - - if (defaultFile.exists()) { - try { - texture = new Texture(defaultFile); - } - catch (final Exception e) { - System.err.println("Failed to load skin file: " + defaultFile); - e.printStackTrace(); - return; - } - } - else { - System.err.println("Failed to load skin file: " + defaultFile); - return; - } - } - if (repeat) { - texture.setWrap(TextureWrap.Repeat, TextureWrap.Repeat); - } - } - - @Override - public float getWidth() { - return texture.getWidth(); - } - - @Override - public float getHeight() { - return texture.getHeight(); - } - - @Override - public void draw(Graphics g, float x, float y, float w, float h) { - if (repeat) { - g.drawRepeatingImage(texture, x, y, w, h); - } - else { - g.drawImage(texture, x, y, w, h); - } - } - - public void drawRotated(Graphics g, float x, float y, float w, float h, float rotation) { - g.drawRotatedImage(texture, x, y, w, h, x + w / 2, y + h / 2, rotation); - } - - public void drawFlipped(Graphics g, float x, float y, float w, float h) { - g.drawFlippedImage(texture, x, y, w, h); - } -} \ No newline at end of file diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FTextureImage.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FTextureImage.java deleted file mode 100644 index a24abbc3900..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FTextureImage.java +++ /dev/null @@ -1,42 +0,0 @@ -package forge.adventure.libgdxgui.assets; - -import com.badlogic.gdx.graphics.Texture; -import forge.adventure.libgdxgui.Graphics; - -public class FTextureImage extends FImageComplex { - private final Texture texture; - - public FTextureImage(Texture texture0) { - texture = texture0; - } - - @Override - public float getWidth() { - return texture.getWidth(); - } - - @Override - public float getHeight() { - return texture.getHeight(); - } - - @Override - public Texture getTexture() { - return texture; - } - - @Override - public int getRegionX() { - return 0; - } - - @Override - public int getRegionY() { - return 0; - } - - @Override - public void draw(Graphics g, float x, float y, float w, float h) { - g.drawImage(texture, x, y, w, h); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FTextureRegionImage.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FTextureRegionImage.java deleted file mode 100644 index b993e2bd2b1..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/FTextureRegionImage.java +++ /dev/null @@ -1,43 +0,0 @@ -package forge.adventure.libgdxgui.assets; - -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import forge.adventure.libgdxgui.Graphics; - -public class FTextureRegionImage extends FImageComplex { - private final TextureRegion textureRegion; - - public FTextureRegionImage(TextureRegion textureRegion0) { - textureRegion = textureRegion0; - } - - @Override - public float getWidth() { - return textureRegion.getRegionWidth(); - } - - @Override - public float getHeight() { - return textureRegion.getRegionHeight(); - } - - @Override - public Texture getTexture() { - return textureRegion.getTexture(); - } - - @Override - public int getRegionX() { - return textureRegion.getRegionX(); - } - - @Override - public int getRegionY() { - return textureRegion.getRegionY(); - } - - @Override - public void draw(Graphics g, float x, float y, float w, float h) { - g.drawImage(textureRegion, x, y, w, h); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/ImageCache.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/ImageCache.java deleted file mode 100644 index 51559895598..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/ImageCache.java +++ /dev/null @@ -1,337 +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.adventure.libgdxgui.assets; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.Pixmap.Format; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.LoadingCache; -import com.google.common.cache.RemovalListener; -import com.google.common.cache.RemovalNotification; -import forge.adventure.libgdxgui.Forge; -import forge.ImageKeys; -import forge.adventure.libgdxgui.card.CardRenderer; -import forge.card.CardEdition; -import forge.deck.Deck; -import forge.game.card.CardView; -import forge.game.player.IHasIcon; -import forge.item.InventoryItem; -import forge.item.PaperCard; -import forge.localinstance.properties.ForgeConstants; -import forge.localinstance.properties.ForgePreferences; -import forge.model.FModel; -import forge.util.ImageUtil; -import forge.util.TextUtil; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.Pair; - -import java.io.File; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -/** - * This class stores ALL card images in a cache with soft values. this means - * that the images may be collected when they are not needed any more, but will - * be kept as long as possible. - *

- * The keys are the following: - *

    - *
  • Keys start with the file name, extension is skipped
  • - *
  • The key without suffix belongs to the unmodified image from the file
  • - *
- * - * @author Forge - * @version $Id: ImageCache.java 24769 2014-02-09 13:56:04Z Hellfish $ - */ -public class ImageCache { - // short prefixes to save memory - - private static final Set missingIconKeys = new HashSet<>(); - private static LoadingCache cache; - public static void initCache(int capacity) { - cache = CacheBuilder.newBuilder() - .maximumSize(capacity) - .expireAfterAccess(15, TimeUnit.MINUTES) - .removalListener(new RemovalListener() { - @Override - public void onRemoval(RemovalNotification removalNotification) { - if (removalNotification.wasEvicted()) { - if (removalNotification.getValue() != ImageCache.defaultImage) - removalNotification.getValue().dispose(); - - CardRenderer.clearcardArtCache(); - } - } - }) - .build(new ImageLoader()); - System.out.println("Card Texture Cache Size: "+capacity); - } - private static final LoadingCache otherCache = CacheBuilder.newBuilder().build(new OtherImageLoader()); - public static final Texture defaultImage; - public static FImage BlackBorder = FSkinImage.IMG_BORDER_BLACK; - public static FImage WhiteBorder = FSkinImage.IMG_BORDER_WHITE; - private static final Map> imageBorder = new HashMap<>(1024); - - private static boolean imageLoaded, delayLoadRequested; - public static void allowSingleLoad() { - imageLoaded = false; //reset at the beginning of each render - delayLoadRequested = false; - } - - static { - Texture defImage = null; - try { - defImage = new Texture(Gdx.files.absolute(ForgeConstants.NO_CARD_FILE)); - } catch (Exception ex) { - System.err.println("could not load default card image"); - } finally { - defaultImage = (null == defImage) ? new Texture(10, 10, Format.RGBA8888) : defImage; - } - } - - public static void clear() { - cache.invalidateAll(); - cache.cleanUp(); - missingIconKeys.clear(); - } - - public static void disposeTexture(){ - CardRenderer.clearcardArtCache(); - clear(); - } - - public static Texture getImage(InventoryItem ii) { - String imageKey = ii.getImageKey(false); - if (imageKey != null) { - if(imageKey.startsWith(ImageKeys.CARD_PREFIX) || imageKey.startsWith(ImageKeys.TOKEN_PREFIX)) - return getImage(ii.getImageKey(false), true, false); - } - return getImage(ii.getImageKey(false), true, true); - } - - /** - * retrieve an icon from the cache. returns the current skin's ICO_UNKNOWN if the icon image is not found - * in the cache and cannot be loaded from disk. - */ - public static FImage getIcon(IHasIcon ihi) { - String imageKey = ihi.getIconImageKey(); - final Texture icon; - if (missingIconKeys.contains(imageKey) || (icon = getImage(ihi.getIconImageKey(), false, true)) == null) { - missingIconKeys.add(imageKey); - return FSkinImage.UNKNOWN; - } - return new FTextureImage(icon); - } - - /** - * checks the card image exists from the disk. - */ - public static boolean imageKeyFileExists(String imageKey) { - if (StringUtils.isEmpty(imageKey)) - return false; - - if (imageKey.length() < 2) - return false; - - final String prefix = imageKey.substring(0, 2); - - if (prefix.equals(ImageKeys.CARD_PREFIX)) { - PaperCard paperCard = ImageUtil.getPaperCardFromImageKey(imageKey); - if (paperCard == null) - return false; - - final boolean backFace = imageKey.endsWith(ImageKeys.BACKFACE_POSTFIX); - final String cardfilename = ImageUtil.getImageKey(paperCard, backFace, true); - if (!new File(ForgeConstants.CACHE_CARD_PICS_DIR + "/" + cardfilename + ".jpg").exists()) - if (!new File(ForgeConstants.CACHE_CARD_PICS_DIR + "/" + cardfilename + ".png").exists()) - return new File(ForgeConstants.CACHE_CARD_PICS_DIR + "/" + TextUtil.fastReplace(cardfilename, ".full", ".fullborder") + ".jpg").exists(); - } else if (prefix.equals(ImageKeys.TOKEN_PREFIX)) { - final String tokenfilename = imageKey.substring(2) + ".jpg"; - - return new File(ForgeConstants.CACHE_TOKEN_PICS_DIR, tokenfilename).exists(); - } - - return true; - } - - /** - * This requests the original unscaled image from the cache for the given key. - * If the image does not exist then it can return a default image if desired. - *

- * If the requested image is not present in the cache then it attempts to load - * the image from file (slower) and then add it to the cache for fast future access. - *

- */ - public static Texture getImage(String imageKey, boolean useDefaultIfNotFound) { - return getImage(imageKey, useDefaultIfNotFound, false); - } - public static Texture getImage(String imageKey, boolean useDefaultIfNotFound, boolean useOtherCache) { - if (StringUtils.isEmpty(imageKey)) { - return null; - } - - boolean altState = imageKey.endsWith(ImageKeys.BACKFACE_POSTFIX); - if (altState) { - imageKey = imageKey.substring(0, imageKey.length() - ImageKeys.BACKFACE_POSTFIX.length()); - } - if (imageKey.startsWith(ImageKeys.CARD_PREFIX)) { - imageKey = ImageUtil.getImageKey(ImageUtil.getPaperCardFromImageKey(imageKey), altState, true); - if (StringUtils.isBlank(imageKey)) { - return defaultImage; - } - } - - Texture image; - if (useDefaultIfNotFound) { - // Load from file and add to cache if not found in cache initially. - image = useOtherCache ? otherCache.getIfPresent(imageKey) : cache.getIfPresent(imageKey); - - if (image != null) { return image; } - - if (imageLoaded) { //prevent loading more than one image each render for performance - if (!delayLoadRequested) { - //ensure images continue to load even if no input is being received - delayLoadRequested = true; - Gdx.graphics.requestRendering(); - } - return null; - } - imageLoaded = true; - } - - try { image = useOtherCache ? otherCache.get(imageKey) : cache.get(imageKey); } - catch (final Exception ex) { - image = null; - } - - // No image file exists for the given key so optionally associate with - // a default "not available" image and add to cache for given key. - if (image == null) { - if (useDefaultIfNotFound) { - image = defaultImage; - if (useOtherCache) - otherCache.put(imageKey, defaultImage); - else - cache.put(imageKey, defaultImage); - if (imageBorder.get(image.toString()) == null) - imageBorder.put(image.toString(), Pair.of(Color.valueOf("#171717").toString(), false)); //black border - } - } - return image; - } - public static void preloadCache(Iterable keys) { - if (FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_DISABLE_CARD_IMAGES)) - return; - for (String imageKey : keys){ - if(getImage(imageKey, false) == null) - System.err.println("could not load card image:"+imageKey); - } - } - public static void preloadCache(Deck deck) { - if (FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_DISABLE_CARD_IMAGES)) - return; - if(deck == null||!Forge.enablePreloadExtendedArt) - return; - if (deck.getAllCardsInASinglePool().toFlatList().size() <= 100) { - for (PaperCard p : deck.getAllCardsInASinglePool().toFlatList()) { - if (getImage(p.getImageKey(false),false) == null) - System.err.println("could not load card image:"+ p); - } - } - } - public static TextureRegion croppedBorderImage(Texture image) { - if (!image.toString().contains(".fullborder.")) - return new TextureRegion(image); - float rscale = 0.96f; - int rw = Math.round(image.getWidth()*rscale); - int rh = Math.round(image.getHeight()*rscale); - int rx = Math.round((image.getWidth() - rw)/2f); - int ry = Math.round((image.getHeight() - rh)/2f)-2; - return new TextureRegion(image, rx, ry, rw, rh); - } - public static Color borderColor(Texture t) { - if (t == null) - return Color.valueOf("#171717"); - return Color.valueOf(imageBorder.get(t.toString()).getLeft()); - } - public static int getFSkinBorders(CardView c) { - if (c == null) - return 0; - - CardView.CardStateView state = c.getCurrentState(); - CardEdition ed = FModel.getMagicDb().getEditions().get(state.getSetCode()); - // TODO: Treatment for silver here - if (ed != null && ed.getBorderColor() == CardEdition.BorderColor.WHITE && state.getFoilIndex() == 0) - return 1; - return 0; - } - public static boolean isBorderlessCardArt(Texture t) { - return ImageLoader.isBorderless(t); - } - public static void updateBorders(String textureString, Pair colorPair){ - imageBorder.put(textureString, colorPair); - } - public static FImage getBorder(String textureString) { - if (imageBorder.get(textureString) == null) - return BlackBorder; - return imageBorder.get(textureString).getRight() ? WhiteBorder : BlackBorder; - } - public static FImage getBorderImage(String textureString, boolean canshow) { - if (!canshow) - return BlackBorder; - return getBorder(textureString); - } - public static FImage getBorderImage(String textureString) { - return getBorder(textureString); - } - public static Color getTint(CardView c, Texture t) { - if (c == null) - return borderColor(t); - if (c.isFaceDown()) - return Color.valueOf("#171717"); - - CardView.CardStateView state = c.getCurrentState(); - if (state.getColors().isColorless()) { //Moonlace -> target spell or permanent becomes colorless. - if (state.hasDevoid()) //devoid is colorless at all zones so return its corresponding border color... - return borderColor(t); - return Color.valueOf("#A0A6A4"); - } - else if (state.getColors().isMonoColor()) { - if (state.getColors().hasBlack()) - return Color.valueOf("#48494a"); - else if (state.getColors().hasBlue()) - return Color.valueOf("#62b5f8"); - else if (state.getColors().hasRed()) - return Color.valueOf("#f6532d"); - else if (state.getColors().hasGreen()) - return Color.valueOf("#66cb35"); - else if (state.getColors().hasWhite()) - return Color.valueOf("#EEEBE1"); - } - else if (state.getColors().isMulticolor()) - return Color.valueOf("#F9E084"); - - return borderColor(t); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/ImageLoader.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/ImageLoader.java deleted file mode 100644 index c1bc1b6b10e..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/ImageLoader.java +++ /dev/null @@ -1,163 +0,0 @@ -package forge.adventure.libgdxgui.assets; - -import com.badlogic.gdx.files.FileHandle; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.TextureData; -import com.badlogic.gdx.graphics.glutils.PixmapTextureData; -import com.google.common.cache.CacheLoader; -import forge.adventure.libgdxgui.Forge; -import forge.ImageKeys; -import forge.gui.FThreads; -import forge.localinstance.properties.ForgeConstants; -import forge.localinstance.properties.ForgePreferences; -import forge.model.FModel; -import forge.util.FileUtil; -import forge.util.TextUtil; -import org.apache.commons.lang3.tuple.Pair; - -import java.io.File; -import java.util.List; - -import static forge.adventure.libgdxgui.assets.ImageCache.croppedBorderImage; - -final class ImageLoader extends CacheLoader { - private static final List borderlessCardlistKey = FileUtil.readFile(ForgeConstants.BORDERLESS_CARD_LIST_FILE); - - Texture n; - @Override - public Texture load(String key) { - if (FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_DISABLE_CARD_IMAGES)) - return null; - - boolean extendedArt = isBorderless(key) && Forge.enableUIMask.equals("Full"); - boolean textureFilter = Forge.isTextureFilteringEnabled(); - File file = ImageKeys.getImageFile(key); - if (file != null) { - FileHandle fh = new FileHandle(file); - try { - Texture t = new Texture(fh, textureFilter); - //update - ImageCache.updateBorders(t.toString(), extendedArt ? Pair.of(Color.valueOf("#171717").toString(), false): isCloserToWhite(getpixelColor(t))); - if (textureFilter) - t.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear); - if (extendedArt) - return generateTexture(fh, t, textureFilter); - return t; - } - catch (Exception ex) { - Forge.log("Could not read image file " + fh.path() + "\nException:\n" + ex); - return null; - } - } - return null; - } - - public Texture generateTexture(FileHandle fh, Texture t, boolean textureFilter) { - if (t == null || fh == null) - return t; - FThreads.invokeInEdtNowOrLater(new Runnable() { - @Override - public void run() { - Pixmap pImage = new Pixmap(fh); - int w = pImage.getWidth(); - int h = pImage.getHeight(); - int radius = (h - w) / 8; - Pixmap pMask = createRoundedRectangle(w, h, radius, Color.RED); - drawPixelstoMask(pImage, pMask); - TextureData textureData = new PixmapTextureData( - pMask, //pixmap to use - Pixmap.Format.RGBA8888, - textureFilter, //use mipmaps - false, true); - n = new Texture(textureData); - if (textureFilter) - n.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear); - pImage.dispose(); - pMask.dispose(); - } - }); - return n; - } - public Pixmap createRoundedRectangle(int width, int height, int cornerRadius, Color color) { - Pixmap pixmap = new Pixmap(width, height, Pixmap.Format.RGBA8888); - Pixmap ret = new Pixmap(width, height, Pixmap.Format.RGBA8888); - pixmap.setColor(color); - //round corners - pixmap.fillCircle(cornerRadius, cornerRadius, cornerRadius); - pixmap.fillCircle(width - cornerRadius - 1, cornerRadius, cornerRadius); - pixmap.fillCircle(cornerRadius, height - cornerRadius - 1, cornerRadius); - pixmap.fillCircle(width - cornerRadius - 1, height - cornerRadius - 1, cornerRadius); - //two rectangle parts - pixmap.fillRectangle(cornerRadius, 0, width - cornerRadius * 2, height); - pixmap.fillRectangle(0, cornerRadius, width, height - cornerRadius * 2); - //draw rounded rectangle - ret.setColor(color); - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - if (pixmap.getPixel(x, y) != 0) ret.drawPixel(x, y); - } - } - pixmap.dispose(); - return ret; - } - public void drawPixelstoMask(Pixmap pixmap, Pixmap mask){ - int pixmapWidth = mask.getWidth(); - int pixmapHeight = mask.getHeight(); - Color pixelColor = new Color(); - for (int x=0; x 7) { - if ((!imagekey.substring(0, 7).contains("MPS_KLD"))&&(imagekey.substring(0, 4).contains("MPS_"))) //MPS_ sets except MPD_KLD - return true; - } - return borderlessCardlistKey.contains(TextUtil.fastReplace(imagekey,".full",".fullborder")); - } - - public static boolean isBorderless(Texture t) { - if(borderlessCardlistKey.isEmpty()) - return false; - //generated texture/pixmap? - if (t.toString().contains("com.badlogic.gdx.graphics.Texture@")) - return true; - for (String key : borderlessCardlistKey) { - if (t.toString().contains(key)) - return true; - } - return false; - } - - public static String getpixelColor(Texture i) { - if (!i.getTextureData().isPrepared()) { - i.getTextureData().prepare(); //prepare texture - } - //get pixmap from texture data - Pixmap pixmap = i.getTextureData().consumePixmap(); - //get pixel color from x,y texture coordinate based on the image fullborder or not - Color color = new Color(pixmap.getPixel(croppedBorderImage(i).getRegionX()+1, croppedBorderImage(i).getRegionY()+1)); - pixmap.dispose(); - return color.toString(); - } - public static Pair isCloserToWhite(String c){ - if (c == null || c == "") - return Pair.of(Color.valueOf("#171717").toString(), false); - int c_r = Integer.parseInt(c.substring(0,2),16); - int c_g = Integer.parseInt(c.substring(2,4),16); - int c_b = Integer.parseInt(c.substring(4,6),16); - int brightness = ((c_r * 299) + (c_g * 587) + (c_b * 114)) / 1000; - return Pair.of(c,brightness > 155); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/OtherImageLoader.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/OtherImageLoader.java deleted file mode 100644 index b9beec287c1..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/OtherImageLoader.java +++ /dev/null @@ -1,34 +0,0 @@ -package forge.adventure.libgdxgui.assets; - -import com.badlogic.gdx.files.FileHandle; -import com.badlogic.gdx.graphics.Texture; -import com.google.common.cache.CacheLoader; -import forge.adventure.libgdxgui.Forge; -import forge.ImageKeys; - -import java.io.File; - -final class OtherImageLoader extends CacheLoader { - @Override - public Texture load(String key) { - File file = ImageKeys.getImageFile(key); - if (file != null) { - FileHandle fh = new FileHandle(file); - try { - if (Forge.isTextureFilteringEnabled()) { - Texture t = new Texture(fh, true); - t.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear); - return t; - } else { - return new Texture(fh); - } - } - catch (Exception ex) { - Forge.log("Could not read image file " + fh.path() + "\n\nException:\n" + ex); - return null; - } - } - return null; - } -} - diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/TextRenderer.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/TextRenderer.java deleted file mode 100644 index 8e1799005fb..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/assets/TextRenderer.java +++ /dev/null @@ -1,649 +0,0 @@ -package forge.adventure.libgdxgui.assets; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.card.CardFaceSymbols; -import forge.localinstance.properties.ForgePreferences; -import forge.localinstance.properties.ForgePreferences.FPref; -import forge.model.FModel; -import forge.adventure.libgdxgui.util.TextBounds; - -import java.text.BreakIterator; -import java.util.*; - -//Encodes text for drawing with symbols and reminder text -public class TextRenderer { - private static final Map symbolLookup = new HashMap<>(64); - static { - symbolLookup.put("C", FSkinImage.MANA_COLORLESS); - symbolLookup.put("W", FSkinImage.MANA_W); - symbolLookup.put("U", FSkinImage.MANA_U); - symbolLookup.put("B", FSkinImage.MANA_B); - symbolLookup.put("R", FSkinImage.MANA_R); - symbolLookup.put("G", FSkinImage.MANA_G); - symbolLookup.put("W/U", FSkinImage.MANA_HYBRID_WU); - symbolLookup.put("U/B", FSkinImage.MANA_HYBRID_UB); - symbolLookup.put("B/R", FSkinImage.MANA_HYBRID_BR); - symbolLookup.put("R/G", FSkinImage.MANA_HYBRID_RG); - symbolLookup.put("G/W", FSkinImage.MANA_HYBRID_GW); - symbolLookup.put("W/B", FSkinImage.MANA_HYBRID_WB); - symbolLookup.put("U/R", FSkinImage.MANA_HYBRID_UR); - symbolLookup.put("B/G", FSkinImage.MANA_HYBRID_BG); - symbolLookup.put("R/W", FSkinImage.MANA_HYBRID_RW); - symbolLookup.put("G/U", FSkinImage.MANA_HYBRID_GU); - symbolLookup.put("2/W", FSkinImage.MANA_2W); - symbolLookup.put("2/U", FSkinImage.MANA_2U); - symbolLookup.put("2/B", FSkinImage.MANA_2B); - symbolLookup.put("2/R", FSkinImage.MANA_2R); - symbolLookup.put("2/G", FSkinImage.MANA_2G); - symbolLookup.put("P/W", FSkinImage.MANA_PHRYX_W); - symbolLookup.put("P/U", FSkinImage.MANA_PHRYX_U); - symbolLookup.put("P/B", FSkinImage.MANA_PHRYX_B); - symbolLookup.put("P/R", FSkinImage.MANA_PHRYX_R); - symbolLookup.put("P/G", FSkinImage.MANA_PHRYX_G); - symbolLookup.put("W/P", FSkinImage.MANA_PHRYX_W); - symbolLookup.put("U/P", FSkinImage.MANA_PHRYX_U); - symbolLookup.put("B/P", FSkinImage.MANA_PHRYX_B); - symbolLookup.put("R/P", FSkinImage.MANA_PHRYX_R); - symbolLookup.put("G/P", FSkinImage.MANA_PHRYX_G); - for (int i = 0; i <= 20; i++) { - symbolLookup.put(String.valueOf(i), FSkinImage.valueOf("MANA_" + i)); - } - symbolLookup.put("X", FSkinImage.MANA_X); - symbolLookup.put("Y", FSkinImage.MANA_Y); - symbolLookup.put("Z", FSkinImage.MANA_Z); - symbolLookup.put("CHAOS", FSkinImage.CHAOS); - symbolLookup.put("Q", FSkinImage.UNTAP); - symbolLookup.put("S", FSkinImage.MANA_SNOW); - symbolLookup.put("T", FSkinImage.TAP); - symbolLookup.put("E", FSkinImage.ENERGY); - symbolLookup.put("AE", FSkinImage.AETHER_SHARD); - symbolLookup.put("PW", FSkinImage.PW_BADGE_COMMON); - symbolLookup.put("CR", FSkinImage.QUEST_COINSTACK); - } - - public static String startColor(Color color) { - return ""; - } - public static String endColor() { - return ""; - } - - private final boolean parseReminderText; - private String fullText = ""; - private float width, height, totalHeight; - private FSkinFont baseFont, font; - private boolean wrap, needClip; - private final List pieces = new ArrayList<>(); - private final List lineWidths = new ArrayList<>(); - private final BreakIterator boundary = BreakIterator.getLineInstance(new Locale(Forge.locale)); - - public TextRenderer() { - this(false); - } - public TextRenderer(boolean parseReminderText0) { - parseReminderText = parseReminderText0; - } - - //break text in pieces - private void updatePieces(FSkinFont font0) { - pieces.clear(); - lineWidths.clear(); - font = font0; - needClip = false; - if (fullText == null || fullText.isEmpty()) { return; } - - totalHeight = font.getCapHeight(); - if (totalHeight > height) { - //immediately try one font size smaller if no room for anything - if (font.canShrink()) { - updatePieces(font.shrink()); - return; - } - needClip = true; - } - - boundary.setText(fullText); - ForgePreferences prefs = FModel.getPreferences(); - boolean hideReminderText = prefs != null && prefs.getPrefBoolean(FPref.UI_HIDE_REMINDER_TEXT); - - char ch; - float x = 0; - float y = 0; - float pieceWidth = 0; - float lineHeight = font.getLineHeight(); - int nextSpaceIdx = boundary.first(); - int lastSpaceIdx = -1; - int lineNum = 0; - StringBuilder text = new StringBuilder(); - int inSymbolCount = 0; - int consecutiveSymbols = 0; - int inKeywordCount = 0; - boolean atReminderTextEnd = false; - int inReminderTextCount = 0; - Color colorOverride = null; - - for (int i = 0; i < fullText.length(); i++) { - atReminderTextEnd = false; - if (i == nextSpaceIdx) { - lastSpaceIdx = text.length(); - nextSpaceIdx = boundary.next(); - } - ch = fullText.charAt(i); - switch (ch) { - case '\r': - continue; //skip '\r' character - case '\n': - if (inSymbolCount > 0) { - inSymbolCount = 0; - text.insert(0, '{'); //if not a symbol, render as text - } - lineWidths.add(x + pieceWidth); - if (text.length() > 0) { - addPiece(new TextPiece(text.toString(), colorOverride, inReminderTextCount > 0), lineNum, x, y, pieceWidth, lineHeight); - pieceWidth = 0; - text.setLength(0); - consecutiveSymbols = 0; - } - lastSpaceIdx = -1; - x = 0; - y += lineHeight; - totalHeight += lineHeight; - lineNum++; - if (totalHeight > height) { - //try next font size down if out of space - if (font.canShrink()) { - updatePieces(font.shrink()); - return; - } - needClip = true; - } - continue; //skip new line character - case '{': - if (inSymbolCount == 0 && text.length() > 0) { //add current text if just entering symbol - addPiece(new TextPiece(text.toString(), colorOverride,inReminderTextCount > 0), lineNum, x, y, pieceWidth, lineHeight); - x += pieceWidth; - pieceWidth = 0; - text.setLength(0); - lastSpaceIdx = -1; - consecutiveSymbols = 0; - } - inSymbolCount++; - continue; //skip '{' character - case '}': - if (inSymbolCount > 0) { - inSymbolCount--; - if (text.length() > 0) { - FSkinImage symbol = symbolLookup.get(text.toString()); - if (symbol != null) { - pieceWidth = lineHeight * CardFaceSymbols.FONT_SIZE_FACTOR; - if (x + pieceWidth > width) { - if (wrap) { - y += lineHeight; - totalHeight += lineHeight; - lineNum++; - if (totalHeight > height) { - //try next font size down if out of space - if (font.canShrink()) { - updatePieces(font.shrink()); - return; - } - needClip = true; - } - if (consecutiveSymbols == 0) { - lineWidths.add(x); - x = 0; - } - else { //make previous consecutive symbols wrap too if needed - x = 0; - int startSymbolIdx = pieces.size() - consecutiveSymbols; - lineWidths.add(pieces.get(startSymbolIdx).x); - for (int j = startSymbolIdx; j < pieces.size(); j++) { - Piece piece = pieces.get(j); - piece.x = x; - piece.y += lineHeight; - piece.lineNum++; - x += piece.w; - } - } - } - else if (font.canShrink()) { - //try next font size down if out of space - updatePieces(font.shrink()); - return; - } - else { - needClip = true; - } - } - addPiece(new SymbolPiece(symbol, inReminderTextCount > 0), lineNum, x, y - font.getAscent() + (lineHeight - pieceWidth) / 2, pieceWidth, pieceWidth); - x += pieceWidth; - pieceWidth = 0; - text.setLength(0); - lastSpaceIdx = -1; - consecutiveSymbols++; - continue; //skip '}' character - } - } - if (!hideReminderText || inReminderTextCount == 0) { - text.insert(0, '{'); //if not a symbol, render as text - if (lastSpaceIdx >= 0) { - lastSpaceIdx++; - } - } - } - break; - case '<': - if (inSymbolCount > 0) { - inSymbolCount = 0; - text.insert(0, '{'); //if not a symbol, render as text - if (lastSpaceIdx >= 0) { - lastSpaceIdx++; - } - } - if (inKeywordCount == 0 && text.length() > 0) { //add current text if starting a keyword - addPiece(new TextPiece(text.toString(), colorOverride,false), lineNum, x, y, pieceWidth, lineHeight); - x += pieceWidth; - pieceWidth = 0; - text.setLength(0); - lastSpaceIdx = -1; - consecutiveSymbols = 0; - } - inKeywordCount++; - break; - case '>': - if (inSymbolCount > 0) { - inSymbolCount = 0; - text.insert(0, '{'); //if not a symbol, render as text - if (lastSpaceIdx >= 0) { - lastSpaceIdx++; - } - } - if (inKeywordCount > 0) { - inKeywordCount--; - if (inKeywordCount == 0 && text.length() > 0) { - String keyword, value; - text.deleteCharAt(0); //trim leading '<' - if (text.charAt(0) == '/') { - keyword = text.substring(1); - value = null; - } - else { - int idx = text.indexOf(" "); - if (idx != -1) { - keyword = text.substring(0, idx); - value = text.substring(idx + 1); - } - else { - keyword = text.toString(); - value = null; - } - } - boolean validKeyword = true; - switch (keyword) { - case "clr": - colorOverride = value != null ? new Color(Integer.parseInt(value)) : null; - break; - default: - validKeyword = false; - break; - } - if (validKeyword) { - text.setLength(0); - lastSpaceIdx = -1; - continue; //skip '>' character - } - } - } - break; - case '(': - if (inSymbolCount > 0) { - inSymbolCount = 0; - text.insert(0, '{'); //if not a symbol, render as text - if (lastSpaceIdx >= 0) { - lastSpaceIdx++; - } - } - if (parseReminderText) { - if (inReminderTextCount == 0 && text.length() > 0) { //add current text if just entering reminder text - addPiece(new TextPiece(text.toString(), colorOverride,false), lineNum, x, y, pieceWidth, lineHeight); - x += pieceWidth; - pieceWidth = 0; - text.setLength(0); - lastSpaceIdx = -1; - consecutiveSymbols = 0; - } - inReminderTextCount++; - } - break; - case ')': - if (inSymbolCount > 0) { - inSymbolCount = 0; - text.insert(0, '{'); //if not a symbol, render as text - if (lastSpaceIdx >= 0) { - lastSpaceIdx++; - } - } - if (inReminderTextCount > 0) { - inReminderTextCount--; - if (inReminderTextCount == 0) { - atReminderTextEnd = true; - } - } - break; - case ' ': - if (inKeywordCount == 0 && inSymbolCount > 0) { - inSymbolCount = 0; - text.insert(0, '{'); //if not a symbol, render as text - if (lastSpaceIdx >= 0) { - lastSpaceIdx++; - } - } - break; - } - if (hideReminderText && (inReminderTextCount > 0 || atReminderTextEnd)) { - continue; - } - text.append(ch); - if (inSymbolCount == 0 && inKeywordCount == 0) { - pieceWidth = font.getBounds(text).width; - if (x + pieceWidth > width) { //wrap or shrink if needed - if (wrap && (lastSpaceIdx >= 0 || consecutiveSymbols > 0)) { - if (lastSpaceIdx < 0) { - //no space between symbols and end of line, wrap those symbols along with text - x = 0; - int startSymbolIdx = pieces.size() - consecutiveSymbols; - lineWidths.add(pieces.get(startSymbolIdx).x); - for (int j = startSymbolIdx; j < pieces.size(); j++) { - Piece piece = pieces.get(j); - piece.x = x; - piece.y += lineHeight; - piece.lineNum++; - x += piece.w; - } - } - else { - int endIdx = lastSpaceIdx; - if (lastSpaceIdx > 0 && text.charAt(lastSpaceIdx - 1) == ' ') { - endIdx = lastSpaceIdx - 1; - } - String currentLineText = text.substring(0, endIdx); - if (!currentLineText.isEmpty()) { - pieceWidth = font.getBounds(currentLineText).width; - addPiece(new TextPiece(currentLineText, colorOverride,inReminderTextCount > 0 || atReminderTextEnd), lineNum, x, y, pieceWidth, lineHeight); - consecutiveSymbols = 0; - } - else { - pieceWidth = 0; - } - lineWidths.add(x + pieceWidth); - text.delete(0, lastSpaceIdx); - x = 0; - } - lastSpaceIdx = -1; - pieceWidth = text.length() == 0 ? 0 : font.getBounds(text).width; - y += lineHeight; - totalHeight += lineHeight; - lineNum++; - if (totalHeight > height) { - //try next font size down if out of space - if (font.canShrink()) { - updatePieces(font.shrink()); - return; - } - needClip = true; - } - } - else if (x > 0 && pieceWidth <= width) { - //if current piece starting past beginning of line and no spaces found, - //wrap current piece being built up along with part of previous pieces as needed - int lastPieceIdx; - for (lastPieceIdx = pieces.size() - 1; lastPieceIdx >= 0; lastPieceIdx--) { - Piece lastPiece = pieces.get(lastPieceIdx); - if (lastPiece.lineNum < lineNum) { - lastPieceIdx = pieces.size() - 1; //don't re-wrap anything if reached previous line - break; - } - if (lastPiece instanceof TextPiece) { - TextPiece textPiece = (TextPiece)lastPiece; - int index = textPiece.text.lastIndexOf(' '); - if (index != -1) { - if (index == 0) { - textPiece.text = textPiece.text.substring(1); - textPiece.w = font.getBounds(textPiece.text).width; - lastPieceIdx--; - } - else if (index == textPiece.text.length() - 1) { - textPiece.text = textPiece.text.substring(0, textPiece.text.length() - 1); - textPiece.w = font.getBounds(textPiece.text).width; - } - else { - TextPiece splitPiece = new TextPiece(textPiece.text.substring(index + 1), textPiece.colorOverride, textPiece.inReminderText); - textPiece.text = textPiece.text.substring(0, index); - textPiece.w = font.getBounds(textPiece.text).width; - splitPiece.x = textPiece.x + textPiece.w; - splitPiece.y = textPiece.y; - splitPiece.w = font.getBounds(splitPiece.text).width; - splitPiece.h = textPiece.h; - } - break; - } - } - } - if (lastPieceIdx >= 0) { - Piece lastPiece = pieces.get(lastPieceIdx); - lineWidths.add(lastPiece.x + lastPiece.w); - x = 0; - for (int j = lastPieceIdx + 1; j < pieces.size(); j++) { - Piece piece = pieces.get(j); - piece.x = x; - piece.y += lineHeight; - piece.lineNum++; - x += piece.w; - } - y += lineHeight; - totalHeight += lineHeight; - lineNum++; - if (totalHeight > height) { - //try next font size down if out of space - if (font.canShrink()) { - updatePieces(font.shrink()); - return; - } - needClip = true; - } - } else { - if (font.canShrink()) { - //try next font size down if out of space - updatePieces(font.shrink()); - return; - } - needClip = true; - } - } - else { - if (font.canShrink()) { - //try next font size down if out of space - updatePieces(font.shrink()); - return; - } - needClip = true; - } - } - if (atReminderTextEnd && text.length() > 0) { //ensure final piece of reminder text added right away - addPiece(new TextPiece(text.toString(), colorOverride, true), lineNum, x, y, pieceWidth, lineHeight); - x += pieceWidth; - pieceWidth = 0; - text.setLength(0); - lastSpaceIdx = -1; - consecutiveSymbols = 0; - } - } - } - - lineWidths.add(x + pieceWidth); - if (text.length() > 0) { - addPiece(new TextPiece(text.toString(), colorOverride, inReminderTextCount > 0), lineNum, x, y, pieceWidth, lineHeight); - consecutiveSymbols = 0; - } - } - - private void addPiece(Piece piece, int lineNum, float x, float y, float w, float h) { - piece.lineNum = lineNum; - piece.x = x; - piece.y = y; - piece.w = w; - piece.h = h; - pieces.add(piece); - } - - private void setProps(String text, FSkinFont skinFont, float w, float h, boolean wrap0) { - boolean needUpdate = false; - if (!fullText.equals(text)) { - fullText = text; - needUpdate = true; - } - if (skinFont != baseFont) { - baseFont = skinFont; - needUpdate = true; - } - if (width != w) { - width = w; - needUpdate = true; - } - if (height != h) { - height = h; - needUpdate = true; - } - if (wrap != wrap0) { - wrap = wrap0; - needUpdate = true; - } - if (needUpdate) { - updatePieces(baseFont); - } - } - - private TextBounds getCurrentBounds() { - float maxWidth = 0; - for (Float lineWidth : lineWidths) { - if (lineWidth > maxWidth) { - maxWidth = lineWidth; - } - } - TextBounds bounds = new TextBounds(); - bounds.width = maxWidth; - bounds.height = totalHeight; - return bounds; - } - - public TextBounds getBounds(String text, FSkinFont skinFont) { - setProps(text, skinFont, Float.MAX_VALUE, Float.MAX_VALUE, false); - return getCurrentBounds(); - } - public TextBounds getWrappedBounds(String text, FSkinFont skinFont, float maxWidth) { - setProps(text, skinFont, maxWidth, Float.MAX_VALUE, true); - return getCurrentBounds(); - } - - public void drawText(Graphics g, String text, FSkinFont skinFont, FSkinColor skinColor, float x, float y, float w, float h, float visibleStartY, float visibleHeight, boolean wrap0, int horzAlignment, boolean centerVertically) { - drawText(g, text, skinFont, skinColor.getColor(), x, y, w, h, visibleStartY, visibleHeight, wrap0, horzAlignment, centerVertically); - } - public void drawText(Graphics g, String text, FSkinFont skinFont, Color color, float x, float y, float w, float h, float visibleStartY, float visibleHeight, boolean wrap0, int horzAlignment, boolean centerVertically) { - setProps(text, skinFont, w, h, wrap0); - if (needClip) { //prevent text flowing outside region if couldn't shrink it to fit - g.startClip(x, y, w, h); - } - if (height > totalHeight && centerVertically) { - y += (height - totalHeight) / 2; - } - float[] alignmentOffsets = new float[lineWidths.size()]; - for (int i = 0; i < lineWidths.size(); i++) { - switch (horzAlignment) { - case Align.left: - alignmentOffsets[i] = 0; - break; - case Align.center: - alignmentOffsets[i] = Math.max((width - lineWidths.get(i)) / 2, 0); - break; - case Align.right: - alignmentOffsets[i] = Math.max(width - lineWidths.get(i), 0); - break; - } - } - - visibleStartY -= y; //subtract y to make calculation quicker - float visibleEndY = visibleStartY + visibleHeight; - - for (Piece piece : pieces) { - if (piece.y + piece.h < visibleStartY) { - continue; - } - if (piece.y >= visibleEndY) { - break; - } - piece.draw(g, color, x + alignmentOffsets[piece.lineNum], y); - } - if (needClip) { - g.endClip(); - } - } - - private abstract class Piece { - protected static final float ALPHA_COMPOSITE = 0.5f; - - protected final boolean inReminderText; - protected float x, y, w, h; - protected int lineNum; - - protected Piece(boolean inReminderText0) { - inReminderText = inReminderText0; - } - - public abstract void draw(Graphics g, Color color, float offsetX, float offsetY); - } - - private class TextPiece extends Piece { - private String text; - private final Color colorOverride; - - private TextPiece(String text0, Color colorOverride0, boolean inReminderText0) { - super(inReminderText0); - text = text0; - colorOverride = colorOverride0; - } - - @Override - public void draw(Graphics g, Color color, float offsetX, float offsetY) { - if (colorOverride != null) { - color = colorOverride; - } - else if (inReminderText) { - color = FSkinColor.alphaColor(color, ALPHA_COMPOSITE); - } - g.drawText(text, font, color, x + offsetX, y + offsetY, w, h, false, Align.left, false); - } - } - - private class SymbolPiece extends Piece { - private final FSkinImage image; - - private SymbolPiece(FSkinImage image0, boolean inReminderText0) { - super(inReminderText0); - image = image0; - } - - @Override - public void draw(Graphics g, Color color, float offsetX, float offsetY) { - if (inReminderText) { - g.setAlphaComposite(ALPHA_COMPOSITE); - } - g.drawImage(image, x + offsetX, y + offsetY, w, h); - if (inReminderText) { - g.resetAlphaComposite(); - } - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardAvatarImage.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardAvatarImage.java deleted file mode 100644 index 34d9eef580c..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardAvatarImage.java +++ /dev/null @@ -1,60 +0,0 @@ -package forge.adventure.libgdxgui.card; - -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FImage; -import forge.adventure.libgdxgui.assets.ImageCache; -import forge.item.PaperCard; - -public class CardAvatarImage implements FImage { - private final String imageKey; - private FImage image; - - public CardAvatarImage(PaperCard card0) { - this(card0.getImageKey(false)); - } - public CardAvatarImage(String imageKey0) { - imageKey = imageKey0; - } - - @Override - public float getWidth() { - return getHeight(); //image will be drawn at its height - } - - @Override - public float getHeight() { - if (image != null) { - return image.getHeight(); - } - return ImageCache.defaultImage.getHeight() * CardRenderer.CARD_ART_HEIGHT_PERCENTAGE; - } - - @Override - public void draw(Graphics g, float x, float y, float w, float h) { - //force to get the avatar since the the cardartcache & loadingcache is always cleared on screen change or the battle bar will display black - image = CardRenderer.getCardArt(imageKey, false, false, false); - if (image == null) { - return; //can't draw anything if can't be loaded yet - } - - //draw scaled image into clipped region so it fills box while maintain aspect ratio - g.startClip(x, y, w, h); - - float aspectRatio = w / h; - float imageAspectRatio = image.getWidth() / image.getHeight(); - if (imageAspectRatio > aspectRatio) { - float w0 = w * imageAspectRatio / aspectRatio; - x -= (w0 - w) / 2; - w = w0; - } - else { - float h0 = h * aspectRatio / imageAspectRatio; - y -= (h0 - h) / 2; - h = h0; - } - - image.draw(g, x, y, w, h); - - g.endClip(); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardFaceSymbols.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardFaceSymbols.java deleted file mode 100644 index 9adf5d6d05d..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardFaceSymbols.java +++ /dev/null @@ -1,248 +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.adventure.libgdxgui.card; - -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinImage; -import forge.card.ColorSet; -import forge.card.mana.ManaCost; -import forge.card.mana.ManaCostShard; -import forge.gui.error.BugReporter; - -import java.util.HashMap; -import java.util.Map; -import java.util.StringTokenizer; - - -public class CardFaceSymbols { - public static final float FONT_SIZE_FACTOR = 0.85f; - private static final Map MANA_IMAGES = new HashMap<>(128); - - public static void loadImages() { - for (int i = 0; i <= 20; i++) { - MANA_IMAGES.put(String.valueOf(i), FSkinImage.valueOf("MANA_" + i)); - } - MANA_IMAGES.put("X", FSkinImage.MANA_X); - MANA_IMAGES.put("Y", FSkinImage.MANA_Y); - MANA_IMAGES.put("Z", FSkinImage.MANA_Z); - - MANA_IMAGES.put("C", FSkinImage.MANA_COLORLESS); - MANA_IMAGES.put("B", FSkinImage.MANA_B); - MANA_IMAGES.put("BG", FSkinImage.MANA_HYBRID_BG); - MANA_IMAGES.put("BR", FSkinImage.MANA_HYBRID_BR); - MANA_IMAGES.put("G", FSkinImage.MANA_G); - MANA_IMAGES.put("GU", FSkinImage.MANA_HYBRID_GU); - MANA_IMAGES.put("GW", FSkinImage.MANA_HYBRID_GW); - MANA_IMAGES.put("R", FSkinImage.MANA_R); - MANA_IMAGES.put("RG", FSkinImage.MANA_HYBRID_RG); - MANA_IMAGES.put("RW", FSkinImage.MANA_HYBRID_RW); - MANA_IMAGES.put("U", FSkinImage.MANA_U); - MANA_IMAGES.put("UB", FSkinImage.MANA_HYBRID_UB); - MANA_IMAGES.put("UR", FSkinImage.MANA_HYBRID_UR); - MANA_IMAGES.put("W", FSkinImage.MANA_W); - MANA_IMAGES.put("WB", FSkinImage.MANA_HYBRID_WB); - MANA_IMAGES.put("WU", FSkinImage.MANA_HYBRID_WU); - MANA_IMAGES.put("PW", FSkinImage.MANA_PHRYX_W); - MANA_IMAGES.put("PR", FSkinImage.MANA_PHRYX_R); - MANA_IMAGES.put("PU", FSkinImage.MANA_PHRYX_U); - MANA_IMAGES.put("PB", FSkinImage.MANA_PHRYX_B); - MANA_IMAGES.put("PG", FSkinImage.MANA_PHRYX_G); - MANA_IMAGES.put("2W", FSkinImage.MANA_2W); - MANA_IMAGES.put("2U", FSkinImage.MANA_2U); - MANA_IMAGES.put("2R", FSkinImage.MANA_2R); - MANA_IMAGES.put("2G", FSkinImage.MANA_2G); - MANA_IMAGES.put("2B", FSkinImage.MANA_2B); - - MANA_IMAGES.put("S", FSkinImage.MANA_SNOW); - MANA_IMAGES.put("T", FSkinImage.TAP); - MANA_IMAGES.put("E", FSkinImage.ENERGY); - MANA_IMAGES.put("slash", FSkinImage.SLASH); - MANA_IMAGES.put("attack", FSkinImage.ATTACK); - MANA_IMAGES.put("defend", FSkinImage.DEFEND); - MANA_IMAGES.put("summonsick", FSkinImage.SUMMONSICK); - MANA_IMAGES.put("phasing", FSkinImage.PHASING); - MANA_IMAGES.put("sacrifice", FSkinImage.COSTRESERVED); - MANA_IMAGES.put("counters1", FSkinImage.COUNTERS1); - MANA_IMAGES.put("counters2", FSkinImage.COUNTERS2); - MANA_IMAGES.put("counters3", FSkinImage.COUNTERS3); - MANA_IMAGES.put("countersMulti", FSkinImage.COUNTERS_MULTI); - - MANA_IMAGES.put("foil01", FSkinImage.FOIL_01); - MANA_IMAGES.put("foil02", FSkinImage.FOIL_02); - MANA_IMAGES.put("foil03", FSkinImage.FOIL_03); - MANA_IMAGES.put("foil04", FSkinImage.FOIL_04); - MANA_IMAGES.put("foil05", FSkinImage.FOIL_05); - MANA_IMAGES.put("foil06", FSkinImage.FOIL_06); - MANA_IMAGES.put("foil07", FSkinImage.FOIL_07); - MANA_IMAGES.put("foil08", FSkinImage.FOIL_08); - MANA_IMAGES.put("foil09", FSkinImage.FOIL_09); - MANA_IMAGES.put("foil10", FSkinImage.FOIL_10); - - MANA_IMAGES.put("foil11", FSkinImage.FOIL_11); - MANA_IMAGES.put("foil12", FSkinImage.FOIL_12); - MANA_IMAGES.put("foil13", FSkinImage.FOIL_13); - MANA_IMAGES.put("foil14", FSkinImage.FOIL_14); - MANA_IMAGES.put("foil15", FSkinImage.FOIL_15); - MANA_IMAGES.put("foil16", FSkinImage.FOIL_16); - MANA_IMAGES.put("foil17", FSkinImage.FOIL_17); - MANA_IMAGES.put("foil18", FSkinImage.FOIL_18); - MANA_IMAGES.put("foil19", FSkinImage.FOIL_19); - MANA_IMAGES.put("foil20", FSkinImage.FOIL_20); - - MANA_IMAGES.put("commander", FSkinImage.IMG_ABILITY_COMMANDER); - - MANA_IMAGES.put("deathtouch", FSkinImage.IMG_ABILITY_DEATHTOUCH); - MANA_IMAGES.put("defender", FSkinImage.IMG_ABILITY_DEFENDER); - MANA_IMAGES.put("doublestrike", FSkinImage.IMG_ABILITY_DOUBLE_STRIKE); - MANA_IMAGES.put("firststrike", FSkinImage.IMG_ABILITY_FIRST_STRIKE); - MANA_IMAGES.put("fear", FSkinImage.IMG_ABILITY_FEAR); - MANA_IMAGES.put("flash", FSkinImage.IMG_ABILITY_FLASH); - MANA_IMAGES.put("flying", FSkinImage.IMG_ABILITY_FLYING); - MANA_IMAGES.put("haste", FSkinImage.IMG_ABILITY_HASTE); - MANA_IMAGES.put("hexproof", FSkinImage.IMG_ABILITY_HEXPROOF); - MANA_IMAGES.put("horsemanship", FSkinImage.IMG_ABILITY_HORSEMANSHIP); - MANA_IMAGES.put("indestructible", FSkinImage.IMG_ABILITY_INDESTRUCTIBLE); - MANA_IMAGES.put("intimidate", FSkinImage.IMG_ABILITY_INTIMIDATE); - MANA_IMAGES.put("landwalk", FSkinImage.IMG_ABILITY_LANDWALK); - MANA_IMAGES.put("lifelink", FSkinImage.IMG_ABILITY_LIFELINK); - MANA_IMAGES.put("menace", FSkinImage.IMG_ABILITY_MENACE); - MANA_IMAGES.put("reach", FSkinImage.IMG_ABILITY_REACH); - MANA_IMAGES.put("shadow", FSkinImage.IMG_ABILITY_SHADOW); - MANA_IMAGES.put("shroud", FSkinImage.IMG_ABILITY_SHROUD); - MANA_IMAGES.put("trample", FSkinImage.IMG_ABILITY_TRAMPLE); - MANA_IMAGES.put("vigilance", FSkinImage.IMG_ABILITY_VIGILANCE); - //hexproof from - MANA_IMAGES.put("hexproofR", FSkinImage.IMG_ABILITY_HEXPROOF_R); - MANA_IMAGES.put("hexproofG", FSkinImage.IMG_ABILITY_HEXPROOF_G); - MANA_IMAGES.put("hexproofB", FSkinImage.IMG_ABILITY_HEXPROOF_B); - MANA_IMAGES.put("hexproofU", FSkinImage.IMG_ABILITY_HEXPROOF_U); - MANA_IMAGES.put("hexproofW", FSkinImage.IMG_ABILITY_HEXPROOF_W); - MANA_IMAGES.put("hexproofC", FSkinImage.IMG_ABILITY_HEXPROOF_C); - MANA_IMAGES.put("hexproofUB", FSkinImage.IMG_ABILITY_HEXPROOF_UB); - //token icon - MANA_IMAGES.put("token", FSkinImage.IMG_ABILITY_TOKEN); - //protection from - MANA_IMAGES.put("protectAll", FSkinImage.IMG_ABILITY_PROTECT_ALL); - MANA_IMAGES.put("protectB", FSkinImage.IMG_ABILITY_PROTECT_B); - MANA_IMAGES.put("protectBU", FSkinImage.IMG_ABILITY_PROTECT_BU); - MANA_IMAGES.put("protectBW", FSkinImage.IMG_ABILITY_PROTECT_BW); - MANA_IMAGES.put("protectColoredSpells", FSkinImage.IMG_ABILITY_PROTECT_COLOREDSPELLS); - MANA_IMAGES.put("protectG", FSkinImage.IMG_ABILITY_PROTECT_G); - MANA_IMAGES.put("protectGB", FSkinImage.IMG_ABILITY_PROTECT_GB); - MANA_IMAGES.put("protectGU", FSkinImage.IMG_ABILITY_PROTECT_GU); - MANA_IMAGES.put("protectGW", FSkinImage.IMG_ABILITY_PROTECT_GW); - MANA_IMAGES.put("protectGeneric", FSkinImage.IMG_ABILITY_PROTECT_GENERIC); - MANA_IMAGES.put("protectR", FSkinImage.IMG_ABILITY_PROTECT_R); - MANA_IMAGES.put("protectRB", FSkinImage.IMG_ABILITY_PROTECT_RB); - MANA_IMAGES.put("protectRG", FSkinImage.IMG_ABILITY_PROTECT_RG); - MANA_IMAGES.put("protectRU", FSkinImage.IMG_ABILITY_PROTECT_RU); - MANA_IMAGES.put("protectRW", FSkinImage.IMG_ABILITY_PROTECT_RW); - MANA_IMAGES.put("protectU", FSkinImage.IMG_ABILITY_PROTECT_U); - MANA_IMAGES.put("protectUW", FSkinImage.IMG_ABILITY_PROTECT_UW); - MANA_IMAGES.put("protectW", FSkinImage.IMG_ABILITY_PROTECT_W); - } - - public static void drawManaCost(Graphics g, ManaCost manaCost, float x, float y, final float imageSize) { - if (manaCost.isNoCost()) { - return; - } - - final int genericManaCost = manaCost.getGenericCost(); - final boolean hasGeneric = (genericManaCost > 0) || manaCost.isPureGeneric(); - final float dx = imageSize; - - if (hasGeneric) { - for (final ManaCostShard s : manaCost) { //render X shards before generic - if (s == ManaCostShard.X) { - drawSymbol(s.getImageKey(), g, x, y, imageSize, imageSize); - x += dx; - } - } - - final String sGeneric = Integer.toString(genericManaCost); - drawSymbol(sGeneric, g, x, y, imageSize, imageSize); - x += dx; - - for (final ManaCostShard s : manaCost) { //render non-X shards after generic - if (s != ManaCostShard.X) { - drawSymbol(s.getImageKey(), g, x, y, imageSize, imageSize); - x += dx; - } - } - } - else { //if no generic, just render shards in order - for (final ManaCostShard s : manaCost) { - drawSymbol(s.getImageKey(), g, x, y, imageSize, imageSize); - x += dx; - } - } - } - - public static void drawColorSet(Graphics g, ColorSet colorSet, float x, float y, final float imageSize) { - drawColorSet(g, colorSet, x, y, imageSize, false); - } - public static void drawColorSet(Graphics g, ColorSet colorSet, float x, float y, final float imageSize, boolean vertical) { - final float dx = imageSize; - - for (final ManaCostShard s : colorSet.getOrderedShards()) { - drawSymbol(s.getImageKey(), g, x, y, imageSize, imageSize); - if (!vertical) - x += dx; - else - y += dx; - } - } - - public static void drawOther(final Graphics g, String s, float x, final float y, final float w, final float h, boolean rotate) { - if (s.length() == 0) { - return; - } - - final float dx = w; - - StringTokenizer tok = new StringTokenizer(s, " "); - while (tok.hasMoreTokens()) { - String symbol = tok.nextToken(); - FSkinImage image = MANA_IMAGES.get(symbol); - if (image == null) { - BugReporter.reportBug("Symbol not recognized \"" + symbol + "\" in string: " + s); - continue; - } - - if(rotate) { - g.drawRotatedImage(image.getTextureRegion(), x, y, w, h, x+w /2, y+h /2,90); - } - else - g.drawImage(image, x, y, w, h); - - x += dx; - } - } - - public static void drawSymbol(final String imageName, final Graphics g, final float x, final float y, final float w, final float h) { - g.drawImage(MANA_IMAGES.get(imageName), x, y, w, h); - } - - public static float getWidth(final ManaCost manaCost, float imageSize) { - return manaCost.getGlyphCount() * imageSize; - } - - public static float getWidth(final ColorSet colorSet, float imageSize) { - return Math.max(colorSet.countColors(), 1) * imageSize; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardImage.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardImage.java deleted file mode 100644 index 982dc0b3588..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardImage.java +++ /dev/null @@ -1,64 +0,0 @@ -package forge.adventure.libgdxgui.card; - -import com.badlogic.gdx.graphics.Texture; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FImage; -import forge.adventure.libgdxgui.assets.ImageCache; -import forge.adventure.libgdxgui.card.CardRenderer.CardStackPosition; -import forge.game.card.CardView; -import forge.item.PaperCard; -import forge.adventure.libgdxgui.toolbox.FCardPanel; - -public class CardImage implements FImage { - private final PaperCard card; - private Texture image; - - public CardImage(PaperCard card0) { - card = card0; - } - - @Override - public float getWidth() { - if (image != null) { - return image.getWidth(); - } - return ImageCache.defaultImage.getWidth(); - } - - @Override - public float getHeight() { - return getWidth() * FCardPanel.ASPECT_RATIO; - } - - @Override - public void draw(Graphics g, float x, float y, float w, float h) { - if (image == null) { //attempt to retrieve card image if needed - image = ImageCache.getImage(card); - if (image == null) { - if (!Forge.enableUIMask.equals("Off")) //render this if mask is still loading - CardImageRenderer.drawCardImage(g, CardView.getCardForUi(card), false, x, y, w, h, CardStackPosition.Top); - - return; //can't draw anything if can't be loaded yet - } - } - - if (image == ImageCache.defaultImage) { - CardImageRenderer.drawCardImage(g, CardView.getCardForUi(card), false, x, y, w, h, CardStackPosition.Top); - } - else { - if (Forge.enableUIMask.equals("Full")) { - if (ImageCache.isBorderlessCardArt(image)) - g.drawImage(image, x, y, w, h); - else { - float radius = (h - w)/8; - g.drawborderImage(ImageCache.borderColor(image), x, y, w, h); - g.drawImage(ImageCache.croppedBorderImage(image), x+radius/2.2f, y+radius/2, w*0.96f, h*0.96f); - } - } else if (Forge.enableUIMask.equals("Crop")) { - g.drawImage(ImageCache.croppedBorderImage(image), x, y, w, h); - } else - g.drawImage(image, x, y, w, h); - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardImageRenderer.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardImageRenderer.java deleted file mode 100644 index ba4aa78e4dc..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardImageRenderer.java +++ /dev/null @@ -1,587 +0,0 @@ -package forge.adventure.libgdxgui.card; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.utils.Align; -import com.google.common.collect.ImmutableList; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.*; -import forge.card.CardEdition; -import forge.card.CardRarity; -import forge.adventure.libgdxgui.card.CardRenderer.CardStackPosition; -import forge.card.mana.ManaCost; -import forge.game.GameView; -import forge.game.card.CardView; -import forge.game.card.CardView.CardStateView; -import forge.game.zone.ZoneType; -import forge.gui.card.CardDetailUtil; -import forge.gui.card.CardDetailUtil.DetailColors; -import forge.localinstance.properties.ForgeConstants; -import forge.localinstance.properties.ForgePreferences; -import forge.model.FModel; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.util.CardTranslation; -import forge.adventure.libgdxgui.util.Utils; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; - -import static forge.adventure.libgdxgui.card.CardRenderer.CROP_MULTIPLIER; -import static forge.adventure.libgdxgui.card.CardRenderer.isModernFrame; - -public class CardImageRenderer { - private static final float BASE_IMAGE_WIDTH = 360; - private static final float BASE_IMAGE_HEIGHT = 504; - private static float MANA_SYMBOL_SIZE, PT_BOX_WIDTH, HEADER_PADDING, BORDER_THICKNESS; - private static FSkinFont NAME_FONT, TYPE_FONT, TEXT_FONT, PT_FONT; - private static float prevImageWidth, prevImageHeight; - private static final float BLACK_BORDER_THICKNESS_RATIO = 0.021f; - - public static void forceStaticFieldUpdate() { - //force static fields to be updated the next time a card image is rendered - prevImageWidth = 0; - prevImageHeight = 0; - forgeArt.clear(); - } - - private static void updateStaticFields(float w, float h) { - if (w == prevImageWidth && h == prevImageHeight) { - //for performance sake, only update static fields if card image size is different than previous rendered card - return; - } - - float ratio = Math.min(w / BASE_IMAGE_WIDTH, h / BASE_IMAGE_HEIGHT); - - MANA_SYMBOL_SIZE = 20 * ratio; - PT_BOX_WIDTH = 56 * ratio; - HEADER_PADDING = 5 * ratio; - NAME_FONT = FSkinFont.forHeight(MANA_SYMBOL_SIZE); - TYPE_FONT = FSkinFont.forHeight(MANA_SYMBOL_SIZE * 0.9f); - TEXT_FONT = FSkinFont.forHeight(MANA_SYMBOL_SIZE * 0.95f); - PT_FONT = NAME_FONT; - BORDER_THICKNESS = Math.max(1.5f * ratio, 1f); //don't let border go below 1 - - prevImageWidth = w; - prevImageHeight = h; - } - - public static void drawFaceDownCard(CardView card, Graphics g, float x, float y, float w, float h) { - //try to draw the card sleeves first - if (FSkin.getSleeves().get(card.getOwner()) != null) - g.drawImage(FSkin.getSleeves().get(card.getOwner()), x, y, w, h); - else - drawArt(g, x, y, w, h); - } - - public static void drawCardImage(Graphics g, CardView card, boolean altState, float x, float y, float w, float h, CardStackPosition pos) { - updateStaticFields(w, h); - - float blackBorderThickness = w * BLACK_BORDER_THICKNESS_RATIO; - g.fillRect(Color.BLACK, x, y, w, h); - x += blackBorderThickness; - y += blackBorderThickness; - w -= 2 * blackBorderThickness; - h -= 2 * blackBorderThickness; - - final CardStateView state = card.getState(altState); - final boolean canShow = MatchController.instance.mayView(card); - - if (!canShow) { - drawFaceDownCard(card, g, x, y, w, h); - return; - } - - //determine colors for borders - final List borderColors; - final boolean isFaceDown = card.isFaceDown(); - if (isFaceDown) { - borderColors = ImmutableList.of(DetailColors.FACE_DOWN); - } - else { - borderColors = CardDetailUtil.getBorderColors(state, canShow); - } - Color[] colors = fillColorBackground(g, borderColors, x, y, w, h); - - float artInset = blackBorderThickness * 0.5f; - float outerBorderThickness = 2 * blackBorderThickness - artInset; - x += outerBorderThickness; - y += outerBorderThickness; - w -= 2 * outerBorderThickness; - float headerHeight = Math.max(MANA_SYMBOL_SIZE + 2 * HEADER_PADDING, 2 * NAME_FONT.getCapHeight()) + 2; - - //draw header containing name and mana cost - Color[] headerColors = FSkinColor.tintColors(Color.WHITE, colors, CardRenderer.NAME_BOX_TINT); - drawHeader(g, card, state, headerColors, x, y, w, headerHeight); - - if (pos == CardStackPosition.BehindVert) { return; } //remaining rendering not needed if card is behind another card in a vertical stack - boolean onTop = (pos == CardStackPosition.Top); - - y += headerHeight; - - float artWidth = w - 2 * artInset; - float artHeight = artWidth / CardRenderer.CARD_ART_RATIO; - float typeBoxHeight = 2 * TYPE_FONT.getCapHeight(); - float ptBoxHeight = 0; - float textBoxHeight = h - headerHeight - artHeight - typeBoxHeight - outerBorderThickness - artInset; - if (state.isCreature() || state.isPlaneswalker() || state.getType().hasSubtype("Vehicle")) { - //if P/T box needed, make room for it - ptBoxHeight = 2 * PT_FONT.getCapHeight(); - textBoxHeight -= ptBoxHeight; - } - else { - textBoxHeight -= 2 * artInset; - } - float minTextBoxHeight = 2 * headerHeight; - if (textBoxHeight < minTextBoxHeight) { - if (textBoxHeight < minTextBoxHeight) { - artHeight -= (minTextBoxHeight - textBoxHeight); //subtract from art height if text box not big enough otherwise - textBoxHeight = minTextBoxHeight; - if (artHeight < 0) { - textBoxHeight += artHeight; - artHeight = 0; - } - } - } - - //draw art box with Forge icon - if (artHeight > 0) { - drawArt(g, x + artInset, y, artWidth, artHeight); - y += artHeight; - } - - //draw type line - drawTypeLine(g, card, state, canShow, headerColors, x, y, w, typeBoxHeight); - y += typeBoxHeight; - - //draw text box - Color[] textBoxColors = FSkinColor.tintColors(Color.WHITE, colors, CardRenderer.TEXT_BOX_TINT); - drawTextBox(g, card, state, textBoxColors, x + artInset, y, w - 2 * artInset, textBoxHeight, onTop); - y += textBoxHeight; - - //draw P/T box - if (onTop && ptBoxHeight > 0) { - //only needed if on top since otherwise P/T will be hidden - Color[] ptColors = FSkinColor.tintColors(Color.WHITE, colors, CardRenderer.PT_BOX_TINT); - drawPtBox(g, card, state, ptColors, x, y - 2 * artInset, w, ptBoxHeight); - } - } - - private static void drawHeader(Graphics g, CardView card, CardStateView state, Color[] colors, float x, float y, float w, float h) { - fillColorBackground(g, colors, x, y, w, h); - g.drawRect(BORDER_THICKNESS, Color.BLACK, x, y, w, h); - - float padding = h / 8; - - //draw mana cost for card - float manaCostWidth = 0; - ManaCost mainManaCost = state.getManaCost(); - if (card.isSplitCard() && card.getAlternateState() != null) { - //handle rendering both parts of split card - mainManaCost = card.getLeftSplitState().getManaCost(); - ManaCost otherManaCost = card.getAlternateState().getManaCost(); - manaCostWidth = CardFaceSymbols.getWidth(otherManaCost, MANA_SYMBOL_SIZE) + HEADER_PADDING; - CardFaceSymbols.drawManaCost(g, otherManaCost, x + w - manaCostWidth, y + (h - MANA_SYMBOL_SIZE) / 2, MANA_SYMBOL_SIZE); - //draw "//" between two parts of mana cost - manaCostWidth += NAME_FONT.getBounds("//").width + HEADER_PADDING; - g.drawText("//", NAME_FONT, Color.BLACK, x + w - manaCostWidth, y, w, h, false, Align.left, true); - } - manaCostWidth += CardFaceSymbols.getWidth(mainManaCost, MANA_SYMBOL_SIZE) + HEADER_PADDING; - CardFaceSymbols.drawManaCost(g, mainManaCost, x + w - manaCostWidth, y + (h - MANA_SYMBOL_SIZE) / 2, MANA_SYMBOL_SIZE); - - //draw name for card - x += padding; - w -= 2 * padding; - g.drawText(CardTranslation.getTranslatedName(state.getName()), NAME_FONT, Color.BLACK, x, y, w - manaCostWidth - padding, h, false, Align.left, true); - } - - public static final FBufferedImage forgeArt; - static { - final float logoWidth = FSkinImage.LOGO.getWidth(); - final float logoHeight = FSkinImage.LOGO.getHeight(); - float h = logoHeight * 1.1f; - float w = h * CardRenderer.CARD_ART_RATIO; - forgeArt = new FBufferedImage(w, h) { - @Override - protected void draw(Graphics g, float w, float h) { - g.drawImage(FSkinTexture.BG_TEXTURE, 0, 0, w, h); - g.fillRect(FScreen.TEXTURE_OVERLAY_COLOR, 0, 0, w, h); - g.drawImage(FSkinImage.LOGO, (w - logoWidth) / 2, (h - logoHeight) / 2, logoWidth, logoHeight); - } - }; - } - - private static void drawArt(Graphics g, float x, float y, float w, float h) { - g.drawImage(forgeArt, x, y, w, h); - g.drawRect(BORDER_THICKNESS, Color.BLACK, x, y, w, h); - } - - private static void drawTypeLine(Graphics g, CardView card, CardStateView state, boolean canShow, Color[] colors, float x, float y, float w, float h) { - fillColorBackground(g, colors, x, y, w, h); - g.drawRect(BORDER_THICKNESS, Color.BLACK, x, y, w, h); - - float padding = h / 8; - - //draw square icon for rarity - float iconSize = h * 0.55f; - float iconPadding = (h - iconSize) / 2; - w -= iconSize + iconPadding * 2; - g.fillRect(CardRenderer.getRarityColor(state.getRarity()), x + w + iconPadding, y + (h - iconSize) / 2, iconSize, iconSize); - - //draw type - x += padding; - g.drawText(CardDetailUtil.formatCardType(state, canShow), TYPE_FONT, Color.BLACK, x, y, w, h, false, Align.left, true); - } - - //use text renderer to handle mana symbols and reminder text - private static final TextRenderer cardTextRenderer = new TextRenderer(true); - - private static void drawTextBox(Graphics g, CardView card, CardStateView state, Color[] colors, float x, float y, float w, float h, boolean onTop) { - fillColorBackground(g, colors, x, y, w, h); - g.drawRect(BORDER_THICKNESS, Color.BLACK, x, y, w, h); - - if (!onTop) { return; } //remaining rendering only needed if card on top - - if (state.isBasicLand()) { - //draw icons for basic lands - FSkinImage image; - switch (state.getName().replaceFirst("^Snow-Covered ", "")) { - case "Plains": - image = FSkinImage.MANA_W; - break; - case "Island": - image = FSkinImage.MANA_U; - break; - case "Swamp": - image = FSkinImage.MANA_B; - break; - case "Mountain": - image = FSkinImage.MANA_R; - break; - case "Forest": - image = FSkinImage.MANA_G; - break; - default: - image = FSkinImage.MANA_COLORLESS; - break; - } - float iconSize = h * 0.75f; - g.drawImage(image, x + (w - iconSize) / 2, y + (h - iconSize) / 2, iconSize, iconSize); - } - else { - boolean needTranslation = true; - if (card.isToken()) { - if (card.getCloneOrigin() == null) - needTranslation = false; - } - final String text = !card.isSplitCard() ? - card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(state.getName(), "") : null) : - card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(card.getLeftSplitState().getName(), card.getRightSplitState().getName()) : null ); - if (StringUtils.isEmpty(text)) { return; } - - float padding = TEXT_FONT.getCapHeight() * 0.75f; - x += padding; - y += padding; - w -= 2 * padding; - h -= 2 * padding; - cardTextRenderer.drawText(g, text, TEXT_FONT, Color.BLACK, x, y, w, h, y, h, true, Align.left, true); - } - } - - private static void drawPtBox(Graphics g, CardView card, CardStateView state, Color[] colors, float x, float y, float w, float h) { - List pieces = new ArrayList<>(); - if (state.isCreature()) { - pieces.add(String.valueOf(state.getPower())); - pieces.add("/"); - pieces.add(String.valueOf(state.getToughness())); - } - else if (state.isPlaneswalker()) { - pieces.add(String.valueOf(state.getLoyalty())); - } - else if (state.getType().hasSubtype("Vehicle")) { - // TODO Invert color box for Vehicles? - pieces.add("["); - pieces.add(String.valueOf(state.getPower())); - pieces.add("/"); - pieces.add(String.valueOf(state.getToughness())); - pieces.add("]"); - } - else { return; } - - float padding = Math.round(PT_FONT.getCapHeight() / 4); - float totalPieceWidth = -padding; - float[] pieceWidths = new float[pieces.size()]; - for (int i = 0; i < pieces.size(); i++) { - float pieceWidth = PT_FONT.getBounds(pieces.get(i)).width + padding; - pieceWidths[i] = pieceWidth; - totalPieceWidth += pieceWidth; - } - float boxHeight = PT_FONT.getCapHeight() + PT_FONT.getAscent() + 3 * padding; - - float boxWidth = Math.max(PT_BOX_WIDTH, totalPieceWidth + 2 * padding); - x += w - boxWidth; - y += h - boxHeight; - w = boxWidth; - h = boxHeight; - - fillColorBackground(g, colors, x, y, w, h); - g.drawRect(BORDER_THICKNESS, Color.BLACK, x, y, w, h); - - x += (boxWidth - totalPieceWidth) / 2; - for (int i = 0; i < pieces.size(); i++) { - g.drawText(pieces.get(i), PT_FONT, Color.BLACK, x, y, w, h, false, Align.left, true); - x += pieceWidths[i]; - } - } - - public static void drawZoom(Graphics g, CardView card, GameView gameView, boolean altState, float x, float y, float w, float h, float dispW, float dispH, boolean isCurrentCard) { - boolean canshow = MatchController.instance.mayView(card); - Texture image = null; - try { - image = ImageCache.getImage(card.getState(altState).getImageKey(), true); - } catch (Exception ex) { - //System.err.println(card.toString()+" : " +ex.getMessage()); - //TODO: don't know why this is needed, needs further investigation... - if (!card.hasAlternateState()) { - altState = false; - image = ImageCache.getImage(card.getState(altState).getImageKey(), true); - } - } - FImage sleeves = MatchController.getPlayerSleeve(card.getOwner()); - if (image == null) { //draw details if can't draw zoom - drawDetails(g, card, gameView, altState, x, y, w, h); - return; - } - if(card.isToken() && card.getCurrentState().getType().hasSubtype("Effect") - && FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_DISABLE_IMAGES_EFFECT_CARDS)){ - drawDetails(g, card, gameView, altState, x, y, w, h); - return; - } - - if (image == ImageCache.defaultImage) { //support drawing card image manually if card image not found - drawCardImage(g, card, altState, x, y, w, h, CardStackPosition.Top); - } else { - float radius = (h - w)/8; - float wh_Adj = ForgeConstants.isGdxPortLandscape && isCurrentCard ? 1.38f:1.0f; - float new_w = w*wh_Adj; - float new_h = h*wh_Adj; - float new_x = ForgeConstants.isGdxPortLandscape && isCurrentCard ? (dispW - new_w) / 2:x; - float new_y = ForgeConstants.isGdxPortLandscape && isCurrentCard ? (dispH - new_h) / 2:y; - float new_xRotate = (dispW - new_h) /2; - float new_yRotate = (dispH - new_w) /2; - boolean rotateSplit = FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_ROTATE_SPLIT_CARDS); - boolean rotatePlane = FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_ROTATE_PLANE_OR_PHENOMENON); - float croppedArea = isModernFrame(card) ? CROP_MULTIPLIER : 0.97f; - float minusxy = isModernFrame(card) ? 0.0f : 0.13f*radius; - if (card.getCurrentState().getSetCode().equals("LEA")||card.getCurrentState().getSetCode().equals("LEB")) { - croppedArea = 0.975f; - minusxy = 0.135f*radius; - } - if (rotatePlane && (card.getCurrentState().isPhenomenon() || card.getCurrentState().isPlane())) { - if (Forge.enableUIMask.equals("Full")){ - if (ImageCache.isBorderlessCardArt(image)) - g.drawRotatedImage(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, -90); - else { - g.drawRotatedImage(FSkin.getBorders().get(0), new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, -90); - g.drawRotatedImage(ImageCache.croppedBorderImage(image), new_x+radius/2-minusxy, new_y+radius/2-minusxy, new_w*croppedArea, new_h*croppedArea, (new_x+radius/2-minusxy) + (new_w*croppedArea) / 2, (new_y+radius/2-minusxy) + (new_h*croppedArea) / 2, -90); - } - } else if (Forge.enableUIMask.equals("Crop")) { - g.drawRotatedImage(ImageCache.croppedBorderImage(image), new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, -90); - } else - g.drawRotatedImage(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, -90); - } else if (rotateSplit && isCurrentCard && card.isSplitCard() && canshow) { - boolean isAftermath = card.getText().contains("Aftermath") || card.getAlternateState().getOracleText().contains("Aftermath"); - if (Forge.enableUIMask.equals("Full")) { - if (ImageCache.isBorderlessCardArt(image)) - g.drawRotatedImage(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, isAftermath ? 90 : -90); - else { - g.drawRotatedImage(FSkin.getBorders().get(ImageCache.getFSkinBorders(card)), new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, isAftermath ? 90 : -90); - g.drawRotatedImage(ImageCache.croppedBorderImage(image), new_x + radius / 2-minusxy, new_y + radius / 2-minusxy, new_w * croppedArea, new_h * croppedArea, (new_x + radius / 2-minusxy) + (new_w * croppedArea) / 2, (new_y + radius / 2-minusxy) + (new_h * croppedArea) / 2, isAftermath ? 90 : -90); - } - } else if (Forge.enableUIMask.equals("Crop")) { - g.drawRotatedImage(ImageCache.croppedBorderImage(image), new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, isAftermath ? 90 : -90); - } else - g.drawRotatedImage(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, isAftermath ? 90 : -90); - } else { - if (Forge.enableUIMask.equals("Full") && canshow) { - if (ImageCache.isBorderlessCardArt(image)) - g.drawImage(image, x, y, w, h); - else { - g.drawImage(ImageCache.getBorderImage(image.toString()), ImageCache.borderColor(image), x, y, w, h); - g.drawImage(ImageCache.croppedBorderImage(image), x + radius / 2.4f-minusxy, y + radius / 2-minusxy, w * croppedArea, h * croppedArea); - } - } else if (Forge.enableUIMask.equals("Crop") && canshow) { - g.drawImage(ImageCache.croppedBorderImage(image), x, y, w, h); - } else { - if (canshow) - g.drawImage(image, x, y, w, h); - else // sleeve - g.drawImage(sleeves, x, y, w, h); - } - } - } - CardRenderer.drawFoilEffect(g, card, x, y, w, h, isCurrentCard && canshow && image != ImageCache.defaultImage); - } - - public static void drawDetails(Graphics g, CardView card, GameView gameView, boolean altState, float x, float y, float w, float h) { - updateStaticFields(w, h); - - float blackBorderThickness = w * BLACK_BORDER_THICKNESS_RATIO; - g.fillRect(Color.BLACK, x, y, w, h); - x += blackBorderThickness; - y += blackBorderThickness; - w -= 2 * blackBorderThickness; - h -= 2 * blackBorderThickness; - - final CardStateView state = card.getState(altState); - final boolean canShow = MatchController.instance.mayView(card); - - //determine colors for borders - final List borderColors; - final boolean isFaceDown = card.isFaceDown(); - if (isFaceDown) { - borderColors = ImmutableList.of(DetailColors.FACE_DOWN); - } - else { - borderColors = CardDetailUtil.getBorderColors(state, canShow); - } - Color[] colors = fillColorBackground(g, borderColors, x, y, w, h); - - Color idForeColor = FSkinColor.getHighContrastColor(colors[0]); - - float outerBorderThickness = 2 * blackBorderThickness; - x += outerBorderThickness; - y += outerBorderThickness; - w -= 2 * outerBorderThickness; - float cardNameBoxHeight = Math.max(MANA_SYMBOL_SIZE + 2 * HEADER_PADDING, 2 * NAME_FONT.getCapHeight()) + 2 * TYPE_FONT.getCapHeight() + 2; - - //draw name/type box - Color[] nameBoxColors = FSkinColor.tintColors(Color.WHITE, colors, CardRenderer.NAME_BOX_TINT); - drawDetailsNameBox(g, card, state, canShow, nameBoxColors, x, y, w, cardNameBoxHeight); - - float innerBorderThickness = outerBorderThickness / 2; - float ptBoxHeight = 2 * PT_FONT.getCapHeight(); - float textBoxHeight = h - cardNameBoxHeight - ptBoxHeight - outerBorderThickness - 3 * innerBorderThickness; - - y += cardNameBoxHeight + innerBorderThickness; - Color[] textBoxColors = FSkinColor.tintColors(Color.WHITE, colors, CardRenderer.TEXT_BOX_TINT); - drawDetailsTextBox(g, state, gameView, canShow, textBoxColors, x, y, w, textBoxHeight); - - y += textBoxHeight + innerBorderThickness; - Color[] ptColors = FSkinColor.tintColors(Color.WHITE, colors, CardRenderer.PT_BOX_TINT); - drawDetailsIdAndPtBox(g, card, state, canShow, idForeColor, ptColors, x, y, w, ptBoxHeight); - } - - public static Color[] fillColorBackground(Graphics g, List backColors, float x, float y, float w, float h) { - Color[] colors = new Color[backColors.size()]; - for (int i = 0; i < colors.length; i++) { - DetailColors dc = backColors.get(i); - colors[i] = FSkinColor.fromRGB(dc.r, dc.g, dc.b); - } - fillColorBackground(g, colors, x, y, w, h); - return colors; - } - public static void fillColorBackground(Graphics g, Color[] colors, float x, float y, float w, float h) { - switch (colors.length) { - case 1: - g.fillRect(colors[0], x, y, w, h); - break; - case 2: - g.fillGradientRect(colors[0], colors[1], false, x, y, w, h); - break; - case 3: - float halfWidth = w / 2; - g.fillGradientRect(colors[0], colors[1], false, x, y, halfWidth, h); - g.fillGradientRect(colors[1], colors[2], false, x + halfWidth, y, halfWidth, h); - break; - } - } - - private static void drawDetailsNameBox(Graphics g, CardView card, CardStateView state, boolean canShow, Color[] colors, float x, float y, float w, float h) { - fillColorBackground(g, colors, x, y, w, h); - g.drawRect(BORDER_THICKNESS, Color.BLACK, x, y, w, h); - - float padding = h / 8; - - //make sure name/mana cost row height is tall enough for both - h = Math.max(MANA_SYMBOL_SIZE + 2 * HEADER_PADDING, 2 * NAME_FONT.getCapHeight()); - - //draw mana cost for card - float manaCostWidth = 0; - if (canShow) { - ManaCost mainManaCost = state.getManaCost(); - if (card.isSplitCard() && card.hasAlternateState() && !card.isFaceDown() && card.getZone() != ZoneType.Stack) { //only display current state's mana cost when on stack - //handle rendering both parts of split card - mainManaCost = card.getLeftSplitState().getManaCost(); - ManaCost otherManaCost = card.getAlternateState().getManaCost(); - manaCostWidth = CardFaceSymbols.getWidth(otherManaCost, MANA_SYMBOL_SIZE) + HEADER_PADDING; - CardFaceSymbols.drawManaCost(g, otherManaCost, x + w - manaCostWidth, y + (h - MANA_SYMBOL_SIZE) / 2, MANA_SYMBOL_SIZE); - //draw "//" between two parts of mana cost - manaCostWidth += NAME_FONT.getBounds("//").width + HEADER_PADDING; - g.drawText("//", NAME_FONT, Color.BLACK, x + w - manaCostWidth, y, w, h, false, Align.left, true); - } - manaCostWidth += CardFaceSymbols.getWidth(mainManaCost, MANA_SYMBOL_SIZE) + HEADER_PADDING; - CardFaceSymbols.drawManaCost(g, mainManaCost, x + w - manaCostWidth, y + (h - MANA_SYMBOL_SIZE) / 2, MANA_SYMBOL_SIZE); - } - - //draw name for card - x += padding; - w -= 2 * padding; - g.drawText(CardDetailUtil.formatCardName(card, canShow, state == card.getAlternateState()), NAME_FONT, Color.BLACK, x, y, w - manaCostWidth - padding, h, false, Align.left, true); - - //draw type and set label for card - y += h; - h = 2 * TYPE_FONT.getCapHeight(); - - String set = state.getSetCode(); - CardRarity rarity = state.getRarity(); - if (!canShow) { - set = CardEdition.UNKNOWN.getCode(); - rarity = CardRarity.Unknown; - } - if (!StringUtils.isEmpty(set)) { - float setWidth = CardRenderer.getSetWidth(TYPE_FONT, set); - CardRenderer.drawSetLabel(g, TYPE_FONT, set, rarity, x + w + padding - setWidth - HEADER_PADDING + CardRenderer.SET_BOX_MARGIN, y + CardRenderer.SET_BOX_MARGIN, setWidth, h - CardRenderer.SET_BOX_MARGIN); - w -= setWidth; //reduce available width for type - } - - g.drawText(CardDetailUtil.formatCardType(state, canShow), TYPE_FONT, Color.BLACK, x, y, w, h, false, Align.left, true); - } - - private static void drawDetailsTextBox(Graphics g, CardStateView state, GameView gameView, boolean canShow, Color[] colors, float x, float y, float w, float h) { - fillColorBackground(g, colors, x, y, w, h); - g.drawRect(BORDER_THICKNESS, Color.BLACK, x, y, w, h); - - float padX = TEXT_FONT.getCapHeight() / 2; - float padY = padX + Utils.scale(2); //add a little more vertical padding - x += padX; - y += padY; - w -= 2 * padX; - h -= 2 * padY; - cardTextRenderer.drawText(g, CardDetailUtil.composeCardText(state, gameView, canShow), TEXT_FONT, Color.BLACK, x, y, w, h, y, h, true, Align.left, false); - } - - private static void drawDetailsIdAndPtBox(Graphics g, CardView card, CardStateView state, boolean canShow, Color idForeColor, Color[] colors, float x, float y, float w, float h) { - float idWidth = 0; - if (canShow) { - String idText = CardDetailUtil.formatCardId(state); - g.drawText(idText, TYPE_FONT, idForeColor, x, y + TYPE_FONT.getCapHeight() / 2, w, h, false, Align.left, false); - idWidth = TYPE_FONT.getBounds(idText).width; - } - - String ptText = CardDetailUtil.formatPowerToughness(state, canShow); - if (StringUtils.isEmpty(ptText)) { return; } - - float padding = PT_FONT.getCapHeight() / 2; - float boxWidth = Math.min(PT_FONT.getBounds(ptText).width + 2 * padding, - w - idWidth - padding); //prevent box overlapping ID - x += w - boxWidth; - w = boxWidth; - - fillColorBackground(g, colors, x, y, w, h); - g.drawRect(BORDER_THICKNESS, Color.BLACK, x, y, w, h); - g.drawText(ptText, PT_FONT, Color.BLACK, x, y, w, h, false, Align.center, true); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardListPreview.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardListPreview.java deleted file mode 100644 index 4fe23f87b42..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardListPreview.java +++ /dev/null @@ -1,51 +0,0 @@ -package forge.adventure.libgdxgui.card; - -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.utils.Align; -import forge.item.PaperCard; -import forge.adventure.libgdxgui.toolbox.FChoiceList; -import forge.adventure.libgdxgui.toolbox.FLabel; - -public class CardListPreview extends FLabel { - public static final float CARD_PREVIEW_RATIO = 0.5f; - - private final FChoiceList list; - - public CardListPreview(FChoiceList list0) { - super(new FLabel.Builder().iconScaleFactor(1).insets(new Vector2(0, 0)) - .iconInBackground(true).align(Align.center)); - list = list0; - } - - @Override - public boolean tap(float x, float y, int count) { - return zoom(); - } - @Override - public boolean longPress(float x, float y) { - return zoom(); - } - private boolean zoom() { - int index = list.getSelectedIndex(); - if (index == -1) { return false; } - CardZoom.show(list.extractListData(), index, list); - return true; - } - - @Override - public boolean fling(float velocityX, float velocityY) { - if (Math.abs(velocityX) > Math.abs(velocityY)) { - int selectedIndex = list.getSelectedIndex(); - if (velocityX > 0) { - if (selectedIndex > 0) { - list.setSelectedIndex(selectedIndex - 1); - } - } - else if (selectedIndex < list.getCount() - 1) { - list.setSelectedIndex(selectedIndex + 1); - } - return true; - } - return false; - } -} \ No newline at end of file diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardRenderer.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardRenderer.java deleted file mode 100644 index a2d4adfc470..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardRenderer.java +++ /dev/null @@ -1,1271 +0,0 @@ -package forge.adventure.libgdxgui.card; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.files.FileHandle; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.PixmapPacker; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; -import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter; -import com.badlogic.gdx.graphics.glutils.PixmapTextureData; -import com.badlogic.gdx.utils.Align; -import com.badlogic.gdx.utils.Array; -import forge.adventure.libgdxgui.CachedCardImage; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.*; -import forge.adventure.libgdxgui.card.CardZoom.ActivateHandler; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.toolbox.FList; -import forge.adventure.libgdxgui.util.TextBounds; -import forge.adventure.libgdxgui.util.Utils; -import forge.card.*; -import forge.card.mana.ManaCost; -import forge.game.card.CardView; -import forge.game.card.CardView.CardStateView; -import forge.game.card.CounterType; -import forge.game.zone.ZoneType; -import forge.gui.FThreads; -import forge.gui.card.CardDetailUtil; -import forge.gui.card.CardDetailUtil.DetailColors; -import forge.item.IPaperCard; -import forge.item.InventoryItem; -import forge.localinstance.properties.ForgeConstants; -import forge.localinstance.properties.ForgeConstants.CounterDisplayType; -import forge.localinstance.properties.ForgePreferences.FPref; -import forge.model.FModel; -import forge.util.CardTranslation; -import org.apache.commons.lang3.StringUtils; - -import java.util.*; - -public class CardRenderer { - public enum CardStackPosition { - Top, - BehindHorz, - BehindVert - } - - // class that simplifies the callback logic of CachedCardImage - static class RendererCachedCardImage extends CachedCardImage { - boolean clearCardArtCache = false; - - public RendererCachedCardImage(CardView card, boolean clearArtCache) { - super(card); - this.clearCardArtCache = clearArtCache; - } - - public RendererCachedCardImage(InventoryItem ii, boolean clearArtCache) { - super(ii); - this.clearCardArtCache = clearArtCache; - } - - public RendererCachedCardImage(String key, boolean clearArtCache) { - super(key); - this.clearCardArtCache = clearArtCache; - } - - @Override - public void onImageFetched() { - ImageCache.clear(); - if (clearCardArtCache) { - cardArtCache.remove(key); - } - } - } - - private static final FSkinFont NAME_FONT = FSkinFont.get(16); - public static final float NAME_BOX_TINT = 0.2f; - public static final float TEXT_BOX_TINT = 0.1f; - public static final float PT_BOX_TINT = 0.2f; - private static final float MANA_COST_PADDING = Utils.scale(3); - public static final float SET_BOX_MARGIN = Utils.scale(1); - public static final float MANA_SYMBOL_SIZE = FSkinImage.MANA_1.getNearestHQWidth(2 * (NAME_FONT.getCapHeight() - MANA_COST_PADDING)); - private static final float NAME_COST_THRESHOLD = Utils.scale(200); - private static final float BORDER_THICKNESS = Utils.scale(1); - public static final float PADDING_MULTIPLIER = 0.021f; - public static final float CROP_MULTIPLIER = 0.96f; - - private static final Map counterFonts = new HashMap<>(); - private static final Color counterBackgroundColor = new Color(0f, 0f, 0f, 0.9f); - private static final Map counterColorCache = new HashMap<>(); - private static final GlyphLayout layout = new GlyphLayout(); - - static { - try { - for (int fontSize = 8; fontSize <= 22; fontSize++) { - generateFontForCounters(fontSize); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - private static Color fromDetailColor(DetailColors detailColor) { - return FSkinColor.fromRGB(detailColor.r, detailColor.g, detailColor.b); - } - - public static Color getRarityColor(CardRarity rarity) { - if (rarity == null)// NPE from Rarity weird... - return Color.CLEAR; - switch(rarity) { - case Uncommon: - return fromDetailColor(DetailColors.UNCOMMON); - case Rare: - return fromDetailColor(DetailColors.RARE); - case MythicRare: - return fromDetailColor(DetailColors.MYTHIC); - case Special: //"Timeshifted" or other Special Rarity Cards - return fromDetailColor(DetailColors.SPECIAL); - default: //case BasicLand: + case Common: - return fromDetailColor(DetailColors.COMMON); - } - } - - public static boolean isModernFrame(IPaperCard c) { - if (c == null) - return false; - - CardEdition ed = FModel.getMagicDb().getEditions().get(c.getEdition()); - if (ed != null) { - switch (ed.getCode()) { - case "MED": - case "ME2": - case "ME3": - case "ME4": - case "TSB": - return false; - default: - return ed.isModern(); - } - } - - return false; - } - - public static boolean isModernFrame(CardView c) { - if (c == null) - return false; - - CardStateView state = c.getCurrentState(); - CardEdition ed = FModel.getMagicDb().getEditions().get(state.getSetCode()); - if (ed != null) { - switch (ed.getCode()) { - case "MED": - case "ME2": - case "ME3": - case "ME4": - case "TSB": - return false; - default: - return ed.isModern(); - } - } - - return false; - } - - public static float getCardListItemHeight(boolean compactMode) { - if (compactMode) { - return MANA_SYMBOL_SIZE + 2 * FList.PADDING; - } - return Math.round(MANA_SYMBOL_SIZE + FSkinFont.get(12).getLineHeight() + 3 * FList.PADDING + 1); - } - - private static final Map cardArtCache = new HashMap<>(1024); - public static final float CARD_ART_RATIO = 1.302f; - public static final float CARD_ART_HEIGHT_PERCENTAGE = 0.43f; - - public static void clearcardArtCache(){ - cardArtCache.clear(); - } - - //extract card art from the given card - public static FImageComplex getCardArt(IPaperCard pc) { - return getCardArt(pc, false); - } - - public static FImageComplex getCardArt(IPaperCard pc, boolean backFace) { - CardType type = pc.getRules().getType(); - return getCardArt(pc.getImageKey(backFace), pc.getRules().getSplitType() == CardSplitType.Split, type.isPlane() || type.isPhenomenon(),pc.getRules().getOracleText().contains("Aftermath")); - } - - public static FImageComplex getCardArt(CardView card) { - CardTypeView type = card.getCurrentState().getType(); - return getCardArt(card.getCurrentState().getImageKey(), card.isSplitCard(), type.isPlane() || type.isPhenomenon(),card.getText().contains("Aftermath")); - } - - public static FImageComplex getCardArt(String imageKey, boolean isSplitCard, boolean isHorizontalCard, boolean isAftermathCard) { - FImageComplex cardArt = cardArtCache.get(imageKey); - if (cardArt == null) { - Texture image = new RendererCachedCardImage(imageKey, true).getImage(); - if (image != null) { - if (image == ImageCache.defaultImage) { - cardArt = CardImageRenderer.forgeArt; - } - else { - float x, y; - float w = image.getWidth(); - float h = image.getHeight(); - if (isSplitCard && !isAftermathCard) { //allow rotated image for split cards - x = w * 33f / 250f; - y = 0; //delay adjusting y and h until drawn - w *= 106f / 250f; - } - else if (isHorizontalCard) { //allow rotated image for horizontal cards - float artX = 40f, artY = 40f; - float artW = 350f, artH = 156f; - float srcW = 430f, srcH = 300f; - if (w > h) { - x = w * 40f / 430f; - y = h * 40f / srcH; - w *= artW / srcW; - h *= artH / srcH; - } - else { //rotate art clockwise if its not the correct orientation - x = w * artY / srcH; - y = h * (srcW - artW - artX) / srcW; - w *= artH / srcH; - h *= artW / srcW; - cardArt = new FRotatedImage(image, Math.round(x), Math.round(y), Math.round(w), Math.round(h), true); - cardArtCache.put(imageKey, cardArt); - return cardArt; - } - } - else { - x = w * 0.1f; - y = h * 0.11f; - w -= 2 * x; - h *= CARD_ART_HEIGHT_PERCENTAGE; - float ratioRatio = w / h / CARD_ART_RATIO; - if (ratioRatio > 1) { //if too wide, shrink width - float dw = w * (ratioRatio - 1); - w -= dw; - x += dw / 2; - } - else { //if too tall, shrink height - float dh = h * (1 - ratioRatio); - h -= dh; - y += dh / 2; - } - } - cardArt = new FTextureRegionImage(new TextureRegion(image, Math.round(x), Math.round(y), Math.round(w), Math.round(h))); - } - cardArtCache.put(imageKey, cardArt); - } - } - return cardArt; - } - - public static FImageComplex getAftermathSecondCardArt(final String imageKey) { - FImageComplex cardArt = cardArtCache.get("Aftermath_second_"+imageKey); - if (cardArt == null) { - Texture image = new CachedCardImage(imageKey) { - @Override - public void onImageFetched() { - ImageCache.clear(); - cardArtCache.remove("Aftermath_second_" + imageKey); - } - }.getImage(); - if (image != null) { - if (image == ImageCache.defaultImage) { - cardArt = CardImageRenderer.forgeArt; - } - else { - float x, y; - float w = image.getWidth(); - float h = image.getHeight(); - //allow rotated image for split cards - x = w * 138f / 250f; - y = h * 210f / 370f; //delay adjusting y and h until drawn - w *= 68f / 250f; - h *= 128f / 370f; - - cardArt = new FTextureRegionImage(new TextureRegion(image, Math.round(x), Math.round(y), Math.round(w), Math.round(h))); - - } - cardArtCache.put("Aftermath_second_"+imageKey, cardArt); - } - } - return cardArt; - } - - public static void drawCardListItem(Graphics g, FSkinFont font, FSkinColor foreColor, CardView card, int count, String suffix, float x, float y, float w, float h, boolean compactMode) { - final CardStateView state = card.getCurrentState(); - if (card.getId() > 0) { - drawCardListItem(g, font, foreColor, getCardArt(card), card, state.getSetCode(), - state.getRarity(), state.getPower(), state.getToughness(), - state.getLoyalty(), count, suffix, x, y, w, h, compactMode); - } - else { //if fake card, just draw card name centered - String name = CardTranslation.getTranslatedName(state.getName()); - if (count > 0) { //preface name with count if applicable - name = count + " " + name; - } - if (suffix != null) { - name += suffix; - } - g.drawText(name, font, foreColor, x, y, w, h, false, Align.center, true); - } - } - - public static void drawCardListItem(Graphics g, FSkinFont font, FSkinColor foreColor, IPaperCard pc, int count, String suffix, float x, float y, float w, float h, boolean compactMode) { - final CardView card = CardView.getCardForUi(pc); - final CardStateView state = card.getCurrentState(); - drawCardListItem(g, font, foreColor, getCardArt(pc), card, pc.getEdition(), - pc.getRarity(), state.getPower(), state.getToughness(), - state.getLoyalty(), count, suffix, x, y, w, h, compactMode); - } - - public static void drawCardListItem(Graphics g, FSkinFont font, FSkinColor foreColor, FImageComplex cardArt, CardView card, String set, CardRarity rarity, int power, int toughness, String loyalty, int count, String suffix, float x, float y, float w, float h, boolean compactMode) { - float cardArtHeight = h + 2 * FList.PADDING; - float cardArtWidth = cardArtHeight * CARD_ART_RATIO; - if (cardArt != null) { - float artX = x - FList.PADDING; - float artY = y - FList.PADDING; - - if (card.isSplitCard() && !card.getText().contains("Aftermath")) { - //draw split art with proper orientation - float srcY = cardArt.getHeight() * 13f / 354f; - float srcHeight = cardArt.getHeight() * 150f / 354f; - float dh = srcHeight * (1 - cardArt.getWidth() / srcHeight / CARD_ART_RATIO); - srcHeight -= dh; - srcY += dh / 2; - g.drawRotatedImage(cardArt.getTexture(), artX, artY, cardArtHeight, cardArtWidth / 2, artX + cardArtWidth / 2, artY + cardArtWidth / 2, cardArt.getRegionX(), (int)srcY, (int)cardArt.getWidth(), (int)srcHeight, -90); - g.drawRotatedImage(cardArt.getTexture(), artX, artY + cardArtWidth / 2, cardArtHeight, cardArtWidth / 2, artX + cardArtWidth / 2, artY + cardArtWidth / 2, cardArt.getRegionX(), (int)cardArt.getHeight() - (int)(srcY + srcHeight), (int)cardArt.getWidth(), (int)srcHeight, -90); - } - else if (card.getText().contains("Aftermath")) { - FImageComplex secondArt = CardRenderer.getAftermathSecondCardArt(card.getCurrentState().getImageKey()); - g.drawRotatedImage(cardArt.getTexture(), artX, artY, cardArtWidth, cardArtHeight / 2, artX + cardArtWidth, artY + cardArtHeight / 2, cardArt.getRegionX(), cardArt.getRegionY(), (int)cardArt.getWidth(), (int)cardArt.getHeight() /2, 0); - g.drawRotatedImage(secondArt.getTexture(), artX - cardArtHeight / 2 , artY + cardArtHeight / 2, cardArtHeight /2, cardArtWidth, artX, artY + cardArtHeight / 2, secondArt.getRegionX(), secondArt.getRegionY(), (int)secondArt.getWidth(), (int)secondArt.getHeight(), 90); - } - else { - g.drawImage(cardArt, artX, artY, cardArtWidth, cardArtHeight); - } - } - - //render card name and mana cost on first line - float manaCostWidth = 0; - ManaCost mainManaCost = card.getCurrentState().getManaCost(); - if (card.isSplitCard()) { - //handle rendering both parts of split card - mainManaCost = card.getLeftSplitState().getManaCost(); - ManaCost otherManaCost = card.getAlternateState().getManaCost(); - manaCostWidth = CardFaceSymbols.getWidth(otherManaCost, MANA_SYMBOL_SIZE) + MANA_COST_PADDING; - CardFaceSymbols.drawManaCost(g, otherManaCost, x + w - manaCostWidth + MANA_COST_PADDING, y, MANA_SYMBOL_SIZE); - //draw "//" between two parts of mana cost - manaCostWidth += font.getBounds("//").width + MANA_COST_PADDING; - g.drawText("//", font, foreColor, x + w - manaCostWidth + MANA_COST_PADDING, y, w, MANA_SYMBOL_SIZE, false, Align.left, true); - } - manaCostWidth += CardFaceSymbols.getWidth(mainManaCost, MANA_SYMBOL_SIZE); - CardFaceSymbols.drawManaCost(g, mainManaCost, x + w - manaCostWidth, y, MANA_SYMBOL_SIZE); - - x += cardArtWidth; - String name = CardTranslation.getTranslatedName(card.getCurrentState().getName()); - if (count > 0) { //preface name with count if applicable - name = count + " " + name; - } - if (suffix != null) { - name += suffix; - } - g.drawText(name, font, foreColor, x, y, w - manaCostWidth - cardArtWidth - FList.PADDING, MANA_SYMBOL_SIZE, false, Align.left, true); - - if (compactMode) { - return; //skip second line if rendering in compact mode - } - - y += MANA_SYMBOL_SIZE + FList.PADDING + SET_BOX_MARGIN; - - //render card type, p/t, and set box on second line - FSkinFont typeFont = FSkinFont.get(12); - float availableTypeWidth = w - cardArtWidth; - float lineHeight = typeFont.getLineHeight(); - if (!StringUtils.isEmpty(set)) { - float setWidth = getSetWidth(typeFont, set); - availableTypeWidth -= setWidth; - drawSetLabel(g, typeFont, set, rarity, x + availableTypeWidth + SET_BOX_MARGIN, y - SET_BOX_MARGIN, setWidth, lineHeight + 2 * SET_BOX_MARGIN); - } - String type = CardDetailUtil.formatCardType(card.getCurrentState(), true); - if (card.getCurrentState().isCreature()) { //include P/T or Loyalty at end of type - type += " (" + power + " / " + toughness + ")"; - } - else if (card.getCurrentState().isPlaneswalker()) { - type += " (" + loyalty + ")"; - } - else if (card.getCurrentState().getType().hasSubtype("Vehicle")) { - type += String.format(" [%s / %s]", power, toughness); - } - g.drawText(type, typeFont, foreColor, x, y, availableTypeWidth, lineHeight, false, Align.left, true); - } - - public static boolean cardListItemTap(List cards, int selectedIndex, ActivateHandler activateHandler, float x, float y, int count, boolean compactMode) { - if (x <= getCardListItemHeight(compactMode) * CARD_ART_RATIO) { - CardZoom.show(cards, selectedIndex, activateHandler); - return true; - } - return false; - } - - public static boolean paperCardListItemTap(List cards, int selectedIndex, ActivateHandler activateHandler, float x, float y, int count, boolean compactMode) { - float cardArtHeight = getCardListItemHeight(compactMode); - float cardArtWidth = cardArtHeight * CARD_ART_RATIO; - if (x <= cardArtWidth && y <= cardArtHeight) { - CardZoom.show(cards, selectedIndex, activateHandler); - return true; - } - return false; - } - - public static float getSetWidth(FSkinFont font, String set) { - return font.getBounds(set).width + font.getCapHeight(); - } - - public static void drawSetLabel(Graphics g, FSkinFont font, String set, CardRarity rarity, float x, float y, float w, float h) { - Color backColor = getRarityColor(rarity); - Color foreColor = FSkinColor.getHighContrastColor(backColor); - g.fillRect(backColor, x, y, w, h); - g.drawText(set, font, foreColor, x, y, w, h, false, Align.center, true); - } - - public static void drawCard(Graphics g, IPaperCard pc, float x, float y, float w, float h, CardStackPosition pos) { - Texture image = new RendererCachedCardImage(pc, false).getImage(); - float radius = (h - w)/8; - float croppedArea = isModernFrame(pc) ? CROP_MULTIPLIER : 0.97f; - float minusxy = isModernFrame(pc) ? 0.0f : 0.13f*radius; - if (pc.getEdition().equals("LEA")||pc.getEdition().equals("LEB")) { - croppedArea = 0.975f; - minusxy = 0.135f*radius; - } - if (image != null) { - if (image == ImageCache.defaultImage) { - CardImageRenderer.drawCardImage(g, CardView.getCardForUi(pc), false, x, y, w, h, pos); - } else { - if (Forge.enableUIMask.equals("Full")) { - if (ImageCache.isBorderlessCardArt(image)) - g.drawImage(image, x, y, w, h); - else { - //tint the border - g.drawImage(ImageCache.getBorderImage(image.toString()), ImageCache.borderColor(image), x, y, w, h); - g.drawImage(ImageCache.croppedBorderImage(image), x + radius / 2.4f-minusxy, y + radius / 2-minusxy, w * croppedArea, h * croppedArea); - } - } else if (Forge.enableUIMask.equals("Crop")) { - g.drawImage(ImageCache.croppedBorderImage(image), x, y, w, h); - } else - g.drawImage(image, x, y, w, h); - } - if (pc.isFoil()) { //draw foil effect if needed - final CardView card = CardView.getCardForUi(pc); - if (card.getCurrentState().getFoilIndex() == 0) { //if foil finish not yet established, assign a random one - card.getCurrentState().setFoilIndexOverride(-1); - } - drawFoilEffect(g, card, x, y, w, h, false); - } - } else { - //if card has invalid or no texture due to sudden changes in ImageCache, draw CardImageRenderer instead and wait for it to refresh automatically - CardImageRenderer.drawCardImage(g, CardView.getCardForUi(pc), false, x, y, w, h, pos); - } - } - public static void drawCard(Graphics g, CardView card, float x, float y, float w, float h, CardStackPosition pos, boolean rotate) { - drawCard(g, card, x, y, w, h, pos, rotate, false); - } - public static void drawCard(Graphics g, CardView card, float x, float y, float w, float h, CardStackPosition pos, boolean rotate, boolean showAltState) { - boolean canshow = MatchController.instance.mayView(card); - boolean showsleeves = card.isFaceDown() && card.isInZone(EnumSet.of(ZoneType.Exile)); //fix facedown card image ie gonti lord of luxury - Texture image = new RendererCachedCardImage(card, false).getImage( showAltState ? card.getAlternateState().getImageKey() : card.getCurrentState().getImageKey()); - FImage sleeves = MatchController.getPlayerSleeve(card.getOwner()); - float radius = (h - w)/8; - float croppedArea = isModernFrame(card) ? CROP_MULTIPLIER : 0.97f; - float minusxy = isModernFrame(card) ? 0.0f : 0.13f*radius; - if (card.getCurrentState().getSetCode().equals("LEA")||card.getCurrentState().getSetCode().equals("LEB")) { - croppedArea = 0.975f; - minusxy = 0.135f*radius; - } - if (image != null) { - if (image == ImageCache.defaultImage) { - CardImageRenderer.drawCardImage(g, card, false, x, y, w, h, pos); - } else if (showsleeves) { - if (!card.isForeTold()) - g.drawImage(sleeves, x, y, w, h); - else - g.drawImage(image, x, y, w, h); - } else { - if(FModel.getPreferences().getPrefBoolean(FPref.UI_ROTATE_PLANE_OR_PHENOMENON) - && (card.getCurrentState().isPhenomenon() || card.getCurrentState().isPlane()) && rotate){ - if (Forge.enableUIMask.equals("Full")) { - if (ImageCache.isBorderlessCardArt(image)) - g.drawRotatedImage(image, x, y, w, h, x + w / 2, y + h / 2, -90); - else { - g.drawRotatedImage(FSkin.getBorders().get(0), x, y, w, h, x + w / 2, y + h / 2, -90); - g.drawRotatedImage(ImageCache.croppedBorderImage(image), x+radius/2.3f-minusxy, y+radius/2-minusxy, w*croppedArea, h*croppedArea, (x+radius/2.3f-minusxy) + (w*croppedArea) / 2, (y+radius/2-minusxy) + (h*croppedArea) / 2, -90); - } - } else if (Forge.enableUIMask.equals("Crop")) { - g.drawRotatedImage(ImageCache.croppedBorderImage(image),x, y, w, h, x + w / 2, y + h / 2, -90); - } else - g.drawRotatedImage(image, x, y, w, h, x + w / 2, y + h / 2, -90); - } else { - if (Forge.enableUIMask.equals("Full") && canshow) { - if (ImageCache.isBorderlessCardArt(image)) - g.drawImage(image, x, y, w, h); - else { - boolean t = (card.getCurrentState().getOriginalColors() != card.getCurrentState().getColors()) || card.getCurrentState().hasChangeColors(); - g.drawBorderImage(ImageCache.getBorderImage(image.toString(), canshow), ImageCache.borderColor(image), ImageCache.getTint(card, image), x, y, w, h, t); //tint check for changed colors - g.drawImage(ImageCache.croppedBorderImage(image), x + radius / 2.4f-minusxy, y + radius / 2-minusxy, w * croppedArea, h * croppedArea); - } - } else if (Forge.enableUIMask.equals("Crop") && canshow) { - g.drawImage(ImageCache.croppedBorderImage(image), x, y, w, h); - } else { - if (canshow) - g.drawImage(image, x, y, w, h); - else // draw card back sleeves - g.drawImage(sleeves, x, y, w, h); - } - } - } - drawFoilEffect(g, card, x, y, w, h, false); - } else { - //if card has invalid or no texture due to sudden changes in ImageCache, draw CardImageRenderer instead and wait for it to refresh automatically - CardImageRenderer.drawCardImage(g, card, false, x, y, w, h, pos); - } - } - - public static void drawCardWithOverlays(Graphics g, CardView card, float x, float y, float w, float h, CardStackPosition pos) { - drawCardWithOverlays(g, card, x, y, w, h, pos, false, false, false); - } - public static void drawCardWithOverlays(Graphics g, CardView card, float x, float y, float w, float h, CardStackPosition pos, boolean stackview, boolean showAltState, boolean isChoiceList) { - boolean canShow = MatchController.instance.mayView(card); - float oldAlpha = g.getfloatAlphaComposite(); - boolean unselectable = !MatchController.instance.isSelectable(card) && MatchController.instance.isSelecting(); - float cx, cy, cw, ch; - cx = x; cy = y; cw = w; ch = h; - drawCard(g, card, x, y, w, h, pos, false, showAltState); - - float padding = w * PADDING_MULTIPLIER; //adjust for card border - x += padding; - y += padding; - w -= 2 * padding; - h -= 2 * padding; - - // TODO: A hacky workaround is currently used to make the game not leak the color information for Morph cards. - final CardStateView details = showAltState ? card.getAlternateState() : isChoiceList && card.isSplitCard() ? card.getLeftSplitState() : card.getCurrentState(); - final boolean isFaceDown = card.isFaceDown(); - final DetailColors borderColor = isFaceDown ? DetailColors.FACE_DOWN : CardDetailUtil.getBorderColor(details, canShow); // canShow doesn't work here for face down Morphs - Color color = FSkinColor.fromRGB(borderColor.r, borderColor.g, borderColor.b); - color = FSkinColor.tintColor(Color.WHITE, color, CardRenderer.PT_BOX_TINT); - - //card name && manacost original position is here moved at the bottom... - - if (stackview) - return; //override - if (pos == CardStackPosition.BehindVert) { return; } //remaining rendering not needed if card is behind another card in a vertical stack - boolean onTop = (pos == CardStackPosition.Top); - - if (canShow && showCardIdOverlay(card)) { - FSkinFont idFont = FSkinFont.forHeight(h * 0.11f); - float idHeight = idFont.getCapHeight(); - g.drawOutlinedText(String.valueOf(card.getId()), idFont, Color.WHITE, Color.BLACK, x + padding, y + h - idHeight - padding, w, h, false, Align.left, false); - } - - if (card.getCounters() != null && !card.getCounters().isEmpty()) { - - switch (CounterDisplayType.from(FModel.getPreferences().getPref(FPref.UI_CARD_COUNTER_DISPLAY_TYPE))) { - case OLD_WHEN_SMALL: - case TEXT: - drawCounterTabs(card, g, x, y, w, h); - break; - case IMAGE: - drawCounterImage(card, g, x, y, w, h); - break; - case HYBRID: - drawCounterImage(card, g, x, y, w, h); - drawCounterTabs(card, g, x, y, w, h); - break; - } - - } - - if (card.getCurrentRoom() != null && !card.getCurrentRoom().isEmpty()) { - List markers = new ArrayList<>(); - markers.add("In Room:"); - markers.add(card.getCurrentRoom()); - drawMarkersTabs(markers, g, x, y, w, h); - } - - float otherSymbolsSize = w / 4f; - final float combatXSymbols = (x + (w / 4)) - otherSymbolsSize / 2 - 10; - final float stateXSymbols = (x + (w / 2)) - otherSymbolsSize / 2 - 10; - final float ySymbols = (y + h) - (h / 12) - otherSymbolsSize / 2; - - if (card.isAttacking()) { - CardFaceSymbols.drawSymbol("attack", g, combatXSymbols, ySymbols, otherSymbolsSize, otherSymbolsSize); - } - else if (card.isBlocking()) { - CardFaceSymbols.drawSymbol("defend", g, combatXSymbols, ySymbols, otherSymbolsSize, otherSymbolsSize); - } - - if (onTop && card.isSick()) { - //only needed if on top since otherwise symbol will be hidden - CardFaceSymbols.drawSymbol("summonsick", g, stateXSymbols, ySymbols, otherSymbolsSize, otherSymbolsSize); - } - - if (card.isPhasedOut()) { - CardFaceSymbols.drawSymbol("phasing", g, stateXSymbols, ySymbols, otherSymbolsSize, otherSymbolsSize); - } - - if (MatchController.instance.isUsedToPay(card)) { - float sacSymbolSize = otherSymbolsSize * 1.2f; - CardFaceSymbols.drawSymbol("sacrifice", g, (x + (w / 2)) - sacSymbolSize / 2, (y + (h / 2)) - sacSymbolSize / 2, otherSymbolsSize, otherSymbolsSize); - } - - if (onTop && showCardPowerOverlay(card) && (canShow || card.isFaceDown())) { //make sure card p/t box appears on top - //only needed if on top since otherwise P/T will be hidden - drawPtBox(g, card, details, color, x, y, w, h); - } - //Darken unselectable cards - if (unselectable){ - g.setAlphaComposite(0.6f); - g.fillRect(Color.BLACK, cx, cy, cw, ch); - g.setAlphaComposite(oldAlpha); - } - //Magenta outline when card is chosen - if (MatchController.instance.isUsedToPay(card)){ - g.drawRect(BORDER_THICKNESS, Color.MAGENTA, cx, cy, cw, ch); - } - //Ability Icons - boolean onbattlefield = ZoneType.Battlefield.equals(card.getZone()); - if (unselectable){ g.setAlphaComposite(0.6f); } - if (onbattlefield && onTop && showAbilityIcons(card)) { - drawAbilityIcons(g,card, cx, cy, cw, cx + ((cw*2)/2.3f), cy, cw / 5.5f, cw / 5.7f); - } else if (canShow && !onbattlefield && showAbilityIcons(card)) { - //draw indicator for flash or can be cast at instant speed, enabled if show ability icons is enabled - String keywordKey = card.getCurrentState().getKeywordKey(); - String abilityText = card.getCurrentState().getAbilityText(); - if ((keywordKey.indexOf("Flash") != -1) - || ((abilityText.indexOf("May be played by") != -1) - && (abilityText.indexOf("and as though it has flash") != -1))){ - if (keywordKey.indexOf("Flashback") == -1) - CardFaceSymbols.drawSymbol("flash", g, cx + ((cw*2)/2.3f), cy, cw / 5.5f, cw / 5.5f); - } - } - //draw name and mana cost overlays if card is small or default card image being used - if (h <= NAME_COST_THRESHOLD && canShow) { - if (showCardNameOverlay(card)) { - float multiplier; - switch (Forge.extrawide) { - case "default": - multiplier = 0.145f; //good for tablets with 16:10 or similar - break; - case "wide": - multiplier = 0.150f; - break; - case "extrawide": - multiplier = 0.155f; //good for tall phones with 21:9 or similar - break; - default: - multiplier = 0.150f; - break; - } - g.drawOutlinedText(CardTranslation.getTranslatedName(details.getName()), FSkinFont.forHeight(h * multiplier), Color.WHITE, Color.BLACK, x + padding -1f, y + padding, w - 2 * padding, h * 0.4f, true, Align.left, false); - } - if (showCardManaCostOverlay(card)) { - float manaSymbolSize = w / 4.5f; - if (card.isSplitCard() && card.hasAlternateState()) { - if (!card.isFaceDown()) { // no need to draw mana symbols on face down split cards (e.g. manifested) - if (isChoiceList) { - if (card.getRightSplitState().getName().equals(details.getName())) - drawManaCost(g, card.getRightSplitState().getManaCost(), x - padding, y, w + 2 * padding, h, manaSymbolSize); - else - drawManaCost(g, card.getLeftSplitState().getManaCost(), x - padding, y, w + 2 * padding, h, manaSymbolSize); - } else { - drawManaCost(g, card.getCurrentState().getManaCost(), x - padding, y, w + 2 * padding, h, manaSymbolSize); - } - } - } - else { - drawManaCost(g, showAltState ? card.getAlternateState().getManaCost() : card.getCurrentState().getManaCost(), x - padding, y, w + 2 * padding, h, manaSymbolSize); - } - } - } - //reset alpha - g.setAlphaComposite(oldAlpha); - } - - public static void drawAbilityIcons(Graphics g, CardView card, float cx, float cy, float cw, float abiX, float abiY, float abiScale, float abiSpace) { - float abiCount = 0; - if (card.isToken()){ - CardFaceSymbols.drawSymbol("token", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (card.isCommander()) { - CardFaceSymbols.drawSymbol("commander", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (card.getCurrentState().hasFlying()) { - CardFaceSymbols.drawSymbol("flying", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (card.getCurrentState().hasHaste()) { - CardFaceSymbols.drawSymbol("haste", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (card.getCurrentState().hasDoubleStrike()) { - CardFaceSymbols.drawSymbol("doublestrike", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - else if (card.getCurrentState().hasFirstStrike()) { - CardFaceSymbols.drawSymbol("firststrike", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (card.getCurrentState().hasDeathtouch()) { - if (abiCount > 5 ) { abiY = cy + (abiSpace * (abiCount - 6)); abiX = cx + ((cw*2)/1.92f); } - CardFaceSymbols.drawSymbol("deathtouch", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (card.getCurrentState().hasIndestructible()) { - if (abiCount > 5 ) { abiY = cy + (abiSpace * (abiCount - 6)); abiX = cx + ((cw*2)/1.92f); } - CardFaceSymbols.drawSymbol("indestructible", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (card.getCurrentState().hasMenace()) { - if (abiCount > 5 ) { abiY = cy + (abiSpace * (abiCount - 6)); abiX = cx + ((cw*2)/1.92f); } - CardFaceSymbols.drawSymbol("menace", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (card.getCurrentState().hasFear()) { - if (abiCount > 5 ) { abiY = cy + (abiSpace * (abiCount - 6)); abiX = cx + ((cw*2)/1.92f); } - CardFaceSymbols.drawSymbol("fear", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (card.getCurrentState().hasIntimidate()) { - if (abiCount > 5 ) { abiY = cy + (abiSpace * (abiCount - 6)); abiX = cx + ((cw*2)/1.92f); } - CardFaceSymbols.drawSymbol("intimidate", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (card.getCurrentState().hasShadow()) { - if (abiCount > 5 ) { abiY = cy + (abiSpace * (abiCount - 6)); abiX = cx + ((cw*2)/1.92f); } - CardFaceSymbols.drawSymbol("shadow", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (card.getCurrentState().hasHorsemanship()) { - if (abiCount > 5 ) { abiY = cy + (abiSpace * (abiCount - 6)); abiX = cx + ((cw*2)/1.92f); } - CardFaceSymbols.drawSymbol("horsemanship", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (card.getCurrentState().hasLandwalk()) { - CardFaceSymbols.drawSymbol("landwalk", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (card.getCurrentState().hasHexproof()) { - if (abiCount > 5 ) { abiY = cy + (abiSpace * (abiCount - 6)); abiX = cx + ((cw*2)/1.92f); } - if (!card.getCurrentState().getHexproofKey().isEmpty()){ - String[] splitK = card.getCurrentState().getHexproofKey().split(":"); - List listHK = Arrays.asList(splitK); - if (listHK.contains("generic")) { - CardFaceSymbols.drawSymbol("hexproof", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (listHK.contains("R")) { - CardFaceSymbols.drawSymbol("hexproofR", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (listHK.contains("B")) { - CardFaceSymbols.drawSymbol("hexproofB", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (listHK.contains("U")) { - CardFaceSymbols.drawSymbol("hexproofU", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (listHK.contains("G")) { - CardFaceSymbols.drawSymbol("hexproofG", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (listHK.contains("W")) { - CardFaceSymbols.drawSymbol("hexproofW", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (listHK.contains("monocolored")) { - CardFaceSymbols.drawSymbol("hexproofC", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - } else { - CardFaceSymbols.drawSymbol("hexproof", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - } - else if (card.getCurrentState().hasShroud()) { - if (abiCount > 5 ) { abiY = cy + (abiSpace * (abiCount - 6)); abiX = cx + ((cw*2)/1.92f); } - CardFaceSymbols.drawSymbol("shroud", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (card.getCurrentState().hasVigilance()) { - if (abiCount > 5 ) { abiY = cy + (abiSpace * (abiCount - 6)); abiX = cx + ((cw*2)/1.92f); } - CardFaceSymbols.drawSymbol("vigilance", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (card.getCurrentState().hasTrample()) { - if (abiCount > 5 ) { abiY = cy + (abiSpace * (abiCount - 6)); abiX = cx + ((cw*2)/1.92f); } - CardFaceSymbols.drawSymbol("trample", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (card.getCurrentState().hasReach()) { - if (abiCount > 5 ) { abiY = cy + (abiSpace * (abiCount - 6)); abiX = cx + ((cw*2)/1.92f); } - CardFaceSymbols.drawSymbol("reach", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (card.getCurrentState().hasLifelink()) { - if (abiCount > 5 ) { abiY = cy + (abiSpace * (abiCount - 6)); abiX = cx + ((cw*2)/1.92f); } - CardFaceSymbols.drawSymbol("lifelink", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - if (card.getCurrentState().hasDefender()) { - if (abiCount > 5 ) { abiY = cy + (abiSpace * (abiCount - 6)); abiX = cx + ((cw*2)/1.92f); } - CardFaceSymbols.drawSymbol("defender", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - //Protection Icons - if (!card.getCurrentState().getProtectionKey().isEmpty()){ - if (abiCount > 5 ) { abiY = cy + (abiSpace * (abiCount - 6)); abiX = cx + ((cw*2)/1.92f); } - if (card.getCurrentState().getProtectionKey().contains("everything") || card.getCurrentState().getProtectionKey().contains("allcolors")) { - CardFaceSymbols.drawSymbol("protectAll", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - else if (card.getCurrentState().getProtectionKey().contains("coloredspells")) { - CardFaceSymbols.drawSymbol("protectColoredSpells", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - else if (card.getCurrentState().getProtectionKey().equals("R")) { - CardFaceSymbols.drawSymbol("protectR", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - else if (card.getCurrentState().getProtectionKey().equals("G")) { - CardFaceSymbols.drawSymbol("protectG", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - else if (card.getCurrentState().getProtectionKey().equals("B")) { - CardFaceSymbols.drawSymbol("protectB", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - else if (card.getCurrentState().getProtectionKey().equals("U")) { - CardFaceSymbols.drawSymbol("protectU", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - else if (card.getCurrentState().getProtectionKey().equals("W")) { - CardFaceSymbols.drawSymbol("protectW", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - else if (card.getCurrentState().getProtectionKey().equals("RG")||card.getCurrentState().getProtectionKey().equals("GR")) { - CardFaceSymbols.drawSymbol("protectRG", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - else if (card.getCurrentState().getProtectionKey().equals("RB")||card.getCurrentState().getProtectionKey().equals("BR")) { - CardFaceSymbols.drawSymbol("protectRB", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - else if (card.getCurrentState().getProtectionKey().equals("RU")||card.getCurrentState().getProtectionKey().equals("UR")) { - CardFaceSymbols.drawSymbol("protectRU", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - else if (card.getCurrentState().getProtectionKey().equals("RW")||card.getCurrentState().getProtectionKey().equals("WR")) { - CardFaceSymbols.drawSymbol("protectRW", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - else if (card.getCurrentState().getProtectionKey().equals("GB")||card.getCurrentState().getProtectionKey().equals("BG")) { - CardFaceSymbols.drawSymbol("protectGB", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - else if (card.getCurrentState().getProtectionKey().equals("GU")||card.getCurrentState().getProtectionKey().equals("UG")) { - CardFaceSymbols.drawSymbol("protectGU", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - else if (card.getCurrentState().getProtectionKey().equals("GW")||card.getCurrentState().getProtectionKey().equals("WG")) { - CardFaceSymbols.drawSymbol("protectGW", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - else if (card.getCurrentState().getProtectionKey().equals("BU")||card.getCurrentState().getProtectionKey().equals("UB")) { - CardFaceSymbols.drawSymbol("protectBU", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - else if (card.getCurrentState().getProtectionKey().equals("BW")||card.getCurrentState().getProtectionKey().equals("WB")) { - CardFaceSymbols.drawSymbol("protectBW", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - else if (card.getCurrentState().getProtectionKey().equals("UW")||card.getCurrentState().getProtectionKey().equals("WU")) { - CardFaceSymbols.drawSymbol("protectUW", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - else if (card.getCurrentState().getProtectionKey().contains("generic") || card.getCurrentState().getProtectionKey().length() > 2) { - CardFaceSymbols.drawSymbol("protectGeneric", g, abiX, abiY, abiScale, abiScale); - abiY += abiSpace; - abiCount += 1; - } - } - } - private static void drawCounterTabs(final CardView card, final Graphics g, final float x, final float y, final float w, final float h) { - - int fontSize = Math.max(11, Math.min(22, (int) (h * 0.08))); - BitmapFont font = counterFonts.get(fontSize); - - final float additionalXOffset = 3f * ((fontSize - 11) / 11f); - final float variableWidth = ((fontSize - 11) / 11f) * 44f; - - float otherSymbolsSize = w / 3.5f; - final float ySymbols = (h / 12) - otherSymbolsSize / 2; - - final float counterBoxHeight = 9 + fontSize; - final float counterBoxBaseWidth = 50 + variableWidth + additionalXOffset * 2; - final float counterBoxSpacing = -4; - - final float spaceFromTopOfCard = y + h - counterBoxHeight - counterBoxSpacing - otherSymbolsSize + ySymbols; - - int currentCounter = 0; - - if (CounterDisplayType.from(FModel.getPreferences().getPref(FPref.UI_CARD_COUNTER_DISPLAY_TYPE)) == CounterDisplayType.OLD_WHEN_SMALL) { - - int maxCounters = 0; - for (Integer numberOfCounters : card.getCounters().values()) { - maxCounters = Math.max(maxCounters, numberOfCounters); - } - - //if (counterBoxBaseWidth + font.getBounds(String.valueOf(maxCounters)).width > w) { - if(font != null && !String.valueOf(maxCounters).isEmpty()){ - layout.setText(font, String.valueOf(maxCounters)); - if (counterBoxBaseWidth + layout.width > w) { - drawCounterImage(card, g, x, y, w, h); - return; - } - } - } - - for (Map.Entry counterEntry : card.getCounters().entrySet()) { - final CounterType counter = counterEntry.getKey(); - final int numberOfCounters = counterEntry.getValue(); - //final float counterBoxRealWidth = counterBoxBaseWidth + font.getBounds(String.valueOf(numberOfCounters)).width + 4; - if(font != null && !String.valueOf(numberOfCounters).isEmpty()){ - layout.setText(font, String.valueOf(numberOfCounters)); - final float counterBoxRealWidth = counterBoxBaseWidth + layout.width + 4; - - final float counterYOffset = spaceFromTopOfCard - (currentCounter++ * (counterBoxHeight + counterBoxSpacing)); - - g.fillRect(counterBackgroundColor, x - 3, counterYOffset, counterBoxRealWidth, counterBoxHeight); - - if (!counterColorCache.containsKey(counter)) { - counterColorCache.put(counter, new Color(counter.getRed() / 255.0f, counter.getGreen() / 255.0f, counter.getBlue() / 255.0f, 1.0f)); - } - - Color counterColor = counterColorCache.get(counter); - - drawText(g, counter.getCounterOnCardDisplayName(), font, counterColor, x + 2 + additionalXOffset, counterYOffset, counterBoxRealWidth, counterBoxHeight, Align.left); - drawText(g, String.valueOf(numberOfCounters), font, counterColor, x + counterBoxBaseWidth - 4f - additionalXOffset, counterYOffset, counterBoxRealWidth, counterBoxHeight, Align.left); - } - } - } - - private static final int GL_BLEND = GL20.GL_BLEND; - - private static void drawText(Graphics g, String text, BitmapFont font, Color color, float x, float y, float w, float h, int horizontalAlignment) { - - if (color.a < 1) { //enable blending so alpha colored shapes work properly - Gdx.gl.glEnable(GL_BLEND); - } - if(font != null && !text.isEmpty()) { - layout.setText(font, text); - TextBounds textBounds = new TextBounds(layout.width, layout.height); - - float textHeight = textBounds.height; - if (h > textHeight) { - y += (h - textHeight) / 2; - } - - font.setColor(color); - font.draw(g.getBatch(), text, g.adjustX(x), g.adjustY(y, 0), w, horizontalAlignment, true); - - if (color.a < 1) { - Gdx.gl.glDisable(GL_BLEND); - } - } - } - - private static void drawCounterImage(final CardView card, final Graphics g, final float x, final float y, final float w, final float h) { - - int number = 0; - if (card.getCounters() != null) { - for (final Integer i : card.getCounters().values()) { - number += i; - } - } - - final int counters = number; - - float countersSize = w / 2; - final float xCounters = x - countersSize / 2; - final float yCounters = y + h * 2 / 3 - countersSize; - - if (counters == 1) { - CardFaceSymbols.drawSymbol("counters1", g, xCounters, yCounters, countersSize, countersSize); - } - else if (counters == 2) { - CardFaceSymbols.drawSymbol("counters2", g, xCounters, yCounters, countersSize, countersSize); - } - else if (counters == 3) { - CardFaceSymbols.drawSymbol("counters3", g, xCounters, yCounters, countersSize, countersSize); - } - else if (counters > 3) { - CardFaceSymbols.drawSymbol("countersMulti", g, xCounters, yCounters, countersSize, countersSize); - } - - } - - private static void drawMarkersTabs(final List markers, final Graphics g, final float x, final float y, final float w, final float h) { - - int fontSize = Math.max(8, Math.min(22, (int) (h * 0.05))); - BitmapFont font = counterFonts.get(fontSize); - - final float additionalXOffset = 3f * ((fontSize - 8) / 8f); - - float otherSymbolsSize = w / 3.5f; - final float ySymbols = (h / 12) - otherSymbolsSize / 2; - - final float markerBoxHeight = 9 + fontSize; - final float markerBoxBaseWidth = 8 + additionalXOffset * 2; - final float markerBoxSpacing = -4; - - final float spaceFromTopOfCard = y + h - markerBoxHeight - markerBoxSpacing - otherSymbolsSize + ySymbols; - - int markerCounter = markers.size() - 1; - - for (String marker : markers) { - layout.setText(font, marker); - final float markerBoxRealWidth = markerBoxBaseWidth + layout.width + 4; - - final float markerYOffset = spaceFromTopOfCard - (markerCounter-- * (markerBoxHeight + markerBoxSpacing)); - - g.fillRect(counterBackgroundColor, x - 3, markerYOffset, markerBoxRealWidth, markerBoxHeight); - - Color markerColor = new Color(200.0f / 255.0f, 200.0f / 255.0f, 200.0f / 255.0f, 1.0f); - - drawText(g, marker, font, markerColor, x + 2 + additionalXOffset, markerYOffset, markerBoxRealWidth, markerBoxHeight, Align.left); - } - } - - private static void drawPtBox(Graphics g, CardView card, CardStateView details, Color color, float x, float y, float w, float h) { - //use array of strings to render separately with a tiny amount of space in between - //instead of using actual spaces which are too wide - List pieces = new ArrayList<>(); - if (details.isCreature()) { - pieces.add(String.valueOf(details.getPower())); - pieces.add("/"); - pieces.add(String.valueOf(details.getToughness())); - } - else if (details.getType().hasSubtype("Vehicle")) { - pieces.add("["); - pieces.add(String.valueOf(details.getPower())); - pieces.add("/"); - pieces.add(String.valueOf(details.getToughness())); - pieces.add("]"); - } - if (details.isPlaneswalker()) { - if (pieces.isEmpty()) { - pieces.add(String.valueOf(details.getLoyalty())); - } - else { - pieces.add("(" + details.getLoyalty() + ")"); - } - } - - if (pieces.isEmpty()) { return; } - - FSkinFont font = FSkinFont.forHeight(h * 0.15f); - float padding = Math.round(font.getCapHeight() / 4); - float boxWidth = padding; - List pieceWidths = new ArrayList<>(); - for (String piece : pieces) { - float pieceWidth = font.getBounds(piece).width + padding; - pieceWidths.add(pieceWidth); - boxWidth += pieceWidth; - } - float boxHeight = font.getCapHeight() + font.getAscent() + 2 * padding; - - x += w - boxWidth; - y += h - boxHeight; - w = boxWidth; - h = boxHeight; - - //draw card damage above P/T box if needed - if (card.getDamage() > 0) { - g.drawOutlinedText(">" + card.getDamage() + "<", font, Color.RED, Color.WHITE, x, y - h + padding, w, h, false, Align.center, true); - } - - g.fillRect(color, x, y, w, h); - g.drawRect(BORDER_THICKNESS, Color.BLACK, x, y, w, h); - - x += padding; - for (int i = 0; i < pieces.size(); i++) { - g.drawText(pieces.get(i), font, Color.BLACK, x, y, w, h, false, Align.left, true); - x += pieceWidths.get(i); - } - } - - private static void drawManaCost(Graphics g, ManaCost cost, float x, float y, float w, float h, float manaSymbolSize) { - float manaCostWidth = CardFaceSymbols.getWidth(cost, manaSymbolSize); - if (manaCostWidth > w) { - manaCostWidth = w; - manaSymbolSize = w / cost.getGlyphCount(); - } - CardFaceSymbols.drawManaCost(g, cost, x + (w - manaCostWidth) / 2, y + (h - manaSymbolSize) / 2, manaSymbolSize); - } - - public static void drawFoilEffect(Graphics g, CardView card, float x, float y, float w, float h, boolean inZoomer) { - float new_x = x; float new_y = y; float new_w = w; float new_h = h; float radius = (h - w)/8; - float croppedArea = isModernFrame(card) ? CROP_MULTIPLIER : 0.97f; - float minusxy = isModernFrame(card) ? 0.0f : 0.13f*radius; - if (card.getCurrentState().getSetCode().equals("LEA")||card.getCurrentState().getSetCode().equals("LEB")) { - croppedArea = 0.975f; - minusxy = 0.135f*radius; - } - if (Forge.enableUIMask.equals("Full")) { - new_x += radius/2.4f-minusxy; new_y += radius/2-minusxy; new_w = w * croppedArea; new_h = h * croppedArea; - } - if (isPreferenceEnabled(FPref.UI_OVERLAY_FOIL_EFFECT) && MatchController.instance.mayView(card)) { - boolean rotateSplit = isPreferenceEnabled(FPref.UI_ROTATE_SPLIT_CARDS) && card.isSplitCard() && inZoomer; - int foil = card.getCurrentState().getFoilIndex(); - if (foil > 0) { - CardFaceSymbols.drawOther(g, String.format("foil%02d", foil), new_x, new_y, new_w, new_h, rotateSplit); - } - } - } - - private static boolean isPreferenceEnabled(FPref preferenceName) { - return FModel.getPreferences().getPrefBoolean(preferenceName); - } - - private static boolean isShowingOverlays(CardView card) { - return isPreferenceEnabled(FPref.UI_SHOW_CARD_OVERLAYS) && card != null; - } - - private static boolean showCardNameOverlay(CardView card) { - return isShowingOverlays(card) && isPreferenceEnabled(FPref.UI_OVERLAY_CARD_NAME); - } - - private static boolean showCardPowerOverlay(CardView card) { - return isShowingOverlays(card) && isPreferenceEnabled(FPref.UI_OVERLAY_CARD_POWER); - } - - private static boolean showCardManaCostOverlay(CardView card) { - return isShowingOverlays(card) && - isPreferenceEnabled(FPref.UI_OVERLAY_CARD_MANA_COST); - } - - public static boolean showAbilityIcons(CardView card) { - return isShowingOverlays(card) && isPreferenceEnabled(FPref.UI_OVERLAY_ABILITY_ICONS); - } - - private static boolean showCardIdOverlay(CardView card) { - return card.getId() > 0 && isShowingOverlays(card) && isPreferenceEnabled(FPref.UI_OVERLAY_CARD_ID); - } - - //TODO Make FSkinFont accept more than one kind of font and merge this with it - private static void generateFontForCounters(final int fontSize) { - - FileHandle ttfFile = Gdx.files.absolute(ForgeConstants.COMMON_FONTS_DIR).child("Roboto-Bold.ttf"); - - if (!ttfFile.exists()) { return; } - - final FreeTypeFontGenerator generator = new FreeTypeFontGenerator(ttfFile); - - //approximate optimal page size - int pageSize = 128; - - //only generate images for characters that could be used by Forge - String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890/-+:'"; - - final PixmapPacker packer = new PixmapPacker(pageSize, pageSize, Pixmap.Format.RGBA8888, 2, false); - final FreeTypeFontParameter parameter = new FreeTypeFontParameter(); - parameter.characters = chars; - parameter.size = fontSize; - parameter.packer = packer; - final FreeTypeFontGenerator.FreeTypeBitmapFontData fontData = generator.generateData(parameter); - final Array pages = packer.getPages(); - - //TODO Cache this - //finish generating font on UI thread - FThreads.invokeInEdtNowOrLater(new Runnable() { - @Override - public void run() { - - //TextureRegion[] textureRegions = new TextureRegion[pages.size]; - Array textureRegions = new Array<>(); - for (int i = 0; i < pages.size; i++) { - PixmapPacker.Page p = pages.get(i); - Texture texture = new Texture(new PixmapTextureData(p.getPixmap(), p.getPixmap().getFormat(), false, false)) { - @Override - public void dispose() { - super.dispose(); - getTextureData().consumePixmap().dispose(); - } - }; - texture.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest); - //textureRegions[i] = new TextureRegion(texture); - textureRegions.add(new TextureRegion(texture)); - } - - counterFonts.put(fontSize, new BitmapFont(fontData, textureRegions, true)); - - generator.dispose(); - packer.dispose(); - - } - }); - - } - -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardZoom.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardZoom.java deleted file mode 100644 index 0a8e0007359..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/CardZoom.java +++ /dev/null @@ -1,384 +0,0 @@ -package forge.adventure.libgdxgui.card; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinImage; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.toolbox.FCardPanel; -import forge.adventure.libgdxgui.toolbox.FDialog; -import forge.adventure.libgdxgui.toolbox.FOverlay; -import forge.adventure.libgdxgui.util.Utils; -import forge.deck.ArchetypeDeckGenerator; -import forge.deck.CardThemedDeckGenerator; -import forge.deck.CommanderDeckGenerator; -import forge.deck.DeckProxy; -import forge.game.GameView; -import forge.game.card.CardView; -import forge.gamemodes.planarconquest.ConquestCommander; -import forge.item.IPaperCard; -import forge.item.InventoryItem; -import forge.localinstance.properties.ForgePreferences; -import forge.localinstance.properties.ForgePreferences.FPref; -import forge.model.FModel; -import forge.util.Localizer; -import forge.util.collect.FCollectionView; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map.Entry; - -public class CardZoom extends FOverlay { - private static final float REQ_AMOUNT = Utils.AVG_FINGER_WIDTH; - - private static final CardZoom cardZoom = new CardZoom(); - private static final ForgePreferences prefs = FModel.getPreferences(); - private static List items; - private static int currentIndex, initialIndex; - private static CardView currentCard, prevCard, nextCard; - private static boolean zoomMode = true; - private static boolean oneCardView = prefs.getPrefBoolean(FPref.UI_SINGLE_CARD_ZOOM); - private float totalZoomAmount; - private static ActivateHandler activateHandler; - private static String currentActivateAction; - private static Rectangle flipIconBounds; - private static Rectangle mutateIconBounds; - private static boolean showAltState; - private static boolean showBackSide = false; - private static boolean showMerged = false; - - public static void show(Object item) { - show(item, false); - } - public static void show(Object item, boolean showbackside) { - List items0 = new ArrayList<>(); - items0.add(item); - showBackSide = showbackside; //reverse the displayed zoomed card for the choice list - show(items0, 0, null); - } - public static void show(FCollectionView items0, int currentIndex0, ActivateHandler activateHandler0) { - show((List)items0, currentIndex0, activateHandler0); - } - public static void show(final List items0, int currentIndex0, ActivateHandler activateHandler0) { - items = items0; - activateHandler = activateHandler0; - currentIndex = currentIndex0; - initialIndex = currentIndex0; - currentCard = getCardView(items.get(currentIndex)); - prevCard = currentIndex > 0 ? getCardView(items.get(currentIndex - 1)) : null; - nextCard = currentIndex < items.size() - 1 ? getCardView(items.get(currentIndex + 1)) : null; - onCardChanged(); - cardZoom.show(); - } - - public static boolean isOpen() { - return cardZoom.isVisible(); - } - - public static void hideZoom() { - cardZoom.hide(); - } - - private CardZoom() { - } - - @Override - public void setVisible(boolean visible0) { - if (this.isVisible() == visible0) { return; } - - super.setVisible(visible0); - - //update selected index when hidden if current index is different than initial index - if (!visible0 && activateHandler != null && currentIndex != initialIndex) { - activateHandler.setSelectedIndex(currentIndex); - } - } - - private static void incrementCard(int dir) { - if (dir > 0) { - if (currentIndex == items.size() - 1) { return; } - currentIndex++; - - prevCard = currentCard; - currentCard = nextCard; - nextCard = currentIndex < items.size() - 1 ? getCardView(items.get(currentIndex + 1)) : null; - } - else { - if (currentIndex == 0) { return; } - currentIndex--; - - nextCard = currentCard; - currentCard = prevCard; - prevCard = currentIndex > 0 ? getCardView(items.get(currentIndex - 1)) : null; - } - onCardChanged(); - } - - private static void onCardChanged() { - mutateIconBounds = null; - if (activateHandler != null) { - currentActivateAction = activateHandler.getActivateAction(currentIndex); - } - if (MatchController.instance.mayFlip(currentCard)) { - flipIconBounds = new Rectangle(); - } else { - flipIconBounds = null; - } - if (currentCard != null) { - if (currentCard.getMergedCardsCollection() != null ) - if (currentCard.getMergedCardsCollection().size() > 0) - mutateIconBounds = new Rectangle(); - } - showAltState = false; - } - - private static CardView getCardView(Object item) { - if (item instanceof Entry) { - item = ((Entry)item).getKey(); - } - if (item instanceof CardView) { - return (CardView)item; - } - if (item instanceof DeckProxy) { - if (item instanceof CardThemedDeckGenerator){ - return CardView.getCardForUi(((CardThemedDeckGenerator)item).getPaperCard()); - }else if (item instanceof CommanderDeckGenerator){ - return CardView.getCardForUi(((CommanderDeckGenerator)item).getPaperCard()); - }else if (item instanceof ArchetypeDeckGenerator){ - return CardView.getCardForUi(((ArchetypeDeckGenerator)item).getPaperCard()); - }else{ - DeckProxy deck = ((DeckProxy)item); - return new CardView(-1, null, deck.getName(), null, deck.getImageKey(false)); - } - - } - if (item instanceof IPaperCard) { - return CardView.getCardForUi((IPaperCard)item); - } - if (item instanceof ConquestCommander) { - return CardView.getCardForUi(((ConquestCommander)item).getCard()); - } - if (item instanceof InventoryItem) { - InventoryItem ii = (InventoryItem)item; - return new CardView(-1, null, ii.getName(), null, ii.getImageKey(false)); - } - return new CardView(-1, null, item.toString()); - } - - @Override - public boolean tap(float x, float y, int count) { - if (mutateIconBounds != null && mutateIconBounds.contains(x, y)) { - if(showMerged) { - showMerged = false; - } else { - showMerged = true; - show(currentCard.getMergedCardsCollection(), 0, null); - } - return true; - } - if (flipIconBounds != null && flipIconBounds.contains(x, y)) { - if (currentCard.isFaceDown() && currentCard.getBackup() != null) { - if (currentCard.getBackup().hasBackSide()) { - show(currentCard.getBackup()); - return true; - } - } - if (!showBackSide) - showAltState = !showAltState; - else - showBackSide = !showBackSide; - return true; - } - hide(); - showBackSide = false; - showAltState = false; - showMerged = false; - return true; - } - - @Override - public boolean fling(float velocityX, float velocityY) { - if (Math.abs(velocityX) > Math.abs(velocityY)) { - incrementCard(velocityX > 0 ? -1 : 1); - showBackSide = false; - showAltState = false; - return true; - } - if (velocityY > 0) { - zoomMode = !zoomMode; - showBackSide = false; - showAltState = false; - return true; - } - if (currentActivateAction != null && activateHandler != null) { - hide(); - showBackSide = false; - showAltState = false; - activateHandler.activate(currentIndex); - return true; - } - return false; - } - - private void setOneCardView(boolean oneCardView0) { - if (oneCardView == oneCardView0 || Forge.isLandscapeMode()) { return; } //don't allow changing this when in landscape mode - - oneCardView = oneCardView0; - prefs.setPref(FPref.UI_SINGLE_CARD_ZOOM, oneCardView0); - prefs.save(); - } - - @Override - public boolean zoom(float x, float y, float amount) { - totalZoomAmount += amount; - - if (totalZoomAmount >= REQ_AMOUNT) { - setOneCardView(true); - totalZoomAmount = 0; - } - else if (totalZoomAmount <= -REQ_AMOUNT) { - setOneCardView(false); - totalZoomAmount = 0; - } - return true; - } - - @Override - public boolean longPress(float x, float y) { - setOneCardView(!oneCardView); - return true; - } - - @Override - public void drawOverlay(Graphics g) { - final GameView gameView = MatchController.instance.getGameView(); - - float w = getWidth(); - float h = getHeight(); - float messageHeight = FDialog.MSG_HEIGHT; - float AspectRatioMultiplier; - switch (Forge.extrawide) { - case "default": - AspectRatioMultiplier = 3; //good for tablets with 16:10 or similar - break; - case "wide": - AspectRatioMultiplier = 2.5f; - break; - case "extrawide": - AspectRatioMultiplier = 2; //good for tall phones with 21:9 or similar - break; - default: - AspectRatioMultiplier = 3; - break; - } - float maxCardHeight = h - AspectRatioMultiplier * messageHeight; //maxheight of currently zoomed card - - float cardWidth, cardHeight, y; - - if (oneCardView && !Forge.isLandscapeMode()) { - - cardWidth = w; - cardHeight = FCardPanel.ASPECT_RATIO * cardWidth; - - boolean rotateSplit = FModel.getPreferences().getPrefBoolean(FPref.UI_ROTATE_SPLIT_CARDS); - if (currentCard.isSplitCard() && rotateSplit) { - // card will be rotated. Make sure that the height does not exceed the width of the view - if (cardHeight > Gdx.graphics.getWidth()) - { - cardHeight = Gdx.graphics.getWidth(); - cardWidth = cardHeight / FCardPanel.ASPECT_RATIO; - } - } - } - else { - - cardWidth = w * 0.5f; - cardHeight = FCardPanel.ASPECT_RATIO * cardWidth; - - float maxSideCardHeight = maxCardHeight * 5 / 7; - if (cardHeight > maxSideCardHeight) { //prevent card overlapping message bars - cardHeight = maxSideCardHeight; - cardWidth = cardHeight / FCardPanel.ASPECT_RATIO; - } - y = (h - cardHeight) / 2; - if (prevCard != null) { - CardImageRenderer.drawZoom(g, prevCard, gameView, false, 0, y, cardWidth, cardHeight, getWidth(), getHeight(), false); - } - if (nextCard != null) { - CardImageRenderer.drawZoom(g, nextCard, gameView, false, w - cardWidth, y, cardWidth, cardHeight, getWidth(), getHeight(), false); - } - - cardWidth = w * 0.7f; - cardHeight = FCardPanel.ASPECT_RATIO * cardWidth; - } - - if (cardHeight > maxCardHeight) { //prevent card overlapping message bars - cardHeight = maxCardHeight; - cardWidth = cardHeight / FCardPanel.ASPECT_RATIO; - } - float x = (w - cardWidth) / 2; - y = (h - cardHeight) / 2; - if (zoomMode) { - CardImageRenderer.drawZoom(g, currentCard, gameView, showBackSide? showBackSide : showAltState, x, y, cardWidth, cardHeight, getWidth(), getHeight(), true); - } else { - CardImageRenderer.drawDetails(g, currentCard, gameView, showBackSide? showBackSide : showAltState, x, y, cardWidth, cardHeight); - } - - if (!showMerged) { - if (mutateIconBounds != null) { - float oldAlpha = g.getfloatAlphaComposite(); - try { - g.setAlphaComposite(0.6f); - drawIconBounds(g, mutateIconBounds, Forge.hdbuttons ? FSkinImage.HDLIBRARY : FSkinImage.LIBRARY, x, y, cardWidth, cardHeight); - g.setAlphaComposite(oldAlpha); - } catch (Exception e) { - mutateIconBounds = null; - g.setAlphaComposite(oldAlpha); - } - } else if (flipIconBounds != null) { - drawIconBounds(g, flipIconBounds, Forge.hdbuttons ? FSkinImage.HDFLIPCARD : FSkinImage.FLIPCARD, x, y, cardWidth, cardHeight); - } - } else if (flipIconBounds != null) { - drawIconBounds(g, flipIconBounds, Forge.hdbuttons ? FSkinImage.HDFLIPCARD : FSkinImage.FLIPCARD, x, y, cardWidth, cardHeight); - } - - if (currentActivateAction != null) { - g.fillRect(FDialog.MSG_BACK_COLOR, 0, 0, w, messageHeight); - g.drawText(Localizer.getInstance().getMessage("lblSwipeUpTo").replace("%s", currentActivateAction), FDialog.MSG_FONT, FDialog.MSG_FORE_COLOR, 0, 0, w, messageHeight, false, Align.center, true); - } - g.fillRect(FDialog.MSG_BACK_COLOR, 0, h - messageHeight, w, messageHeight); - g.drawText(zoomMode ? Localizer.getInstance().getMessage("lblSwipeDownDetailView") : Localizer.getInstance().getMessage("lblSwipeDownPictureView"), FDialog.MSG_FONT, FDialog.MSG_FORE_COLOR, 0, h - messageHeight, w, messageHeight, false, Align.center, true); - - interrupt(false); - } - - private void drawIconBounds(Graphics g, Rectangle iconBounds, FSkinImage skinImage, float x, float y, float cardWidth, float cardHeight) { - float imageWidth = cardWidth / 2; - float imageHeight = imageWidth * skinImage.getHeight() / skinImage.getWidth(); - iconBounds.set(x + (cardWidth - imageWidth) / 2, y + (cardHeight - imageHeight) / 2, imageWidth, imageHeight); - g.drawImage(skinImage, iconBounds.x, iconBounds.y, iconBounds.width, iconBounds.height); - } - - @Override - protected void doLayout(float width, float height) { - } - - public interface ActivateHandler { - String getActivateAction(int index); - void setSelectedIndex(int index); - void activate(int index); - } - - public void interrupt(boolean resume) { - if (MatchController.instance.hasLocalPlayers()) - return; - if(resume && MatchController.instance.isGamePaused()) { - MatchController.instance.resumeMatch(); - return; - } - if(!MatchController.instance.isGamePaused()) - MatchController.instance.pauseMatch(); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/ColorSetImage.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/ColorSetImage.java deleted file mode 100644 index 2cf0bfe90a5..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/ColorSetImage.java +++ /dev/null @@ -1,38 +0,0 @@ -package forge.adventure.libgdxgui.card; - -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FImage; -import forge.adventure.libgdxgui.assets.FSkinImage; -import forge.card.ColorSet; - -public class ColorSetImage implements FImage { - private final ColorSet colorSet; - private final int shardCount; - - public ColorSetImage(ColorSet colorSet0) { - colorSet = colorSet0; - shardCount = colorSet.getOrderedShards().length; - } - - @Override - public float getWidth() { - return FSkinImage.MANA_W.getWidth() * shardCount; - } - - @Override - public float getHeight() { - return FSkinImage.MANA_W.getHeight(); - } - - @Override - public void draw(Graphics g, float x, float y, float w, float h) { - float imageSize = w / shardCount; - if (imageSize > h) { - imageSize = h; - float w0 = imageSize * shardCount; - x += (w - w0) / 2; - w = w0; - } - CardFaceSymbols.drawColorSet(g, colorSet, x, y, imageSize); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/GameEntityPicker.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/GameEntityPicker.java deleted file mode 100644 index 3496ef7d579..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/card/GameEntityPicker.java +++ /dev/null @@ -1,135 +0,0 @@ -package forge.adventure.libgdxgui.card; - -import com.google.common.collect.ImmutableList; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FImage; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.FSkinImage; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.screens.TabPageScreen; -import forge.adventure.libgdxgui.toolbox.FChoiceList; -import forge.adventure.libgdxgui.toolbox.FEvent; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.toolbox.FOptionPane; -import forge.adventure.libgdxgui.toolbox.FTextField; -import forge.game.GameEntityView; -import forge.game.card.CardView; -import forge.util.Callback; -import forge.util.Localizer; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -public class GameEntityPicker extends TabPageScreen { - private final FOptionPane optionPane; - - public GameEntityPicker(String title, Collection choiceList, Collection revealList, String revealListCaption, FImage revealListImage, boolean isOptional, final Callback callback) { - super(new PickerTab[] { - new PickerTab(choiceList, Localizer.getInstance().getMessage("lblChoices"), Forge.hdbuttons ? FSkinImage.HDCHOICE : FSkinImage.DECKLIST, 1), - new PickerTab(revealList, revealListCaption, revealListImage, 0) - }, false); - - setHeight(FOptionPane.getMaxDisplayObjHeight()); - - optionPane = new FOptionPane(null, null, title, null, this, - isOptional ? ImmutableList.of(Localizer.getInstance().getMessage("lblOK"), Localizer.getInstance().getMessage("lblCancel")) : ImmutableList.of(Localizer.getInstance().getMessage("lblOK")), 0, new Callback() { - @Override - public void run(Integer result) { - if (result == 0) { - callback.run(((PickerTab)tabPages[0]).list.getSelectedItem()); - } - else { - callback.run(null); - } - } - }) { - @Override - protected boolean padAboveAndBelow() { - return false; //allow list to go straight up against buttons - } - }; - } - - public void show() { - optionPane.show(); - } - - @Override - protected boolean canActivateTabPage() { - return true; //always allow activating tab pages while this is open - } - - @Override - public FScreen getLandscapeBackdropScreen() { - return null; - } - - private static class PickerTab extends TabPage { - private final FTextField txtSearch; - private final FChoiceList list; - - private PickerTab(final Collection items, String caption0, FImage icon0, final int maxChoices) { - super(caption0 + " (" + items.size() + ")", icon0); - txtSearch = add(new FTextField()); - txtSearch.setFont(FSkinFont.get(12)); - txtSearch.setGhostText(Localizer.getInstance().getMessage("lblSearch")); - txtSearch.setChangedHandler(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - String pattern = txtSearch.getText().toLowerCase(); - list.clearSelection(); - if (pattern.isEmpty()) { - list.setListData(items); - } - else { - List filteredList = new ArrayList<>(); - for (GameEntityView option : items) { - if (option.toString().toLowerCase().contains(pattern)) { - filteredList.add(option); - } - } - list.setListData(filteredList); - } - if (!list.isEmpty() && maxChoices > 0) { - list.addSelectedIndex(0); - } - list.setScrollTop(0); - } - }); - list = add(new FChoiceList(items, maxChoices, maxChoices) { - @Override - protected void onItemActivate(Integer index, GameEntityView value) { - if (maxChoices > 0) { - parentScreen.optionPane.setResult(0); - } - } - - @Override - public void drawOverlay(Graphics g) { - //don't draw border - } - }); - if (maxChoices > 0) { - list.addSelectedIndex(0); - } - } - - @Override - protected void onActivate() { - if (parentScreen.optionPane != null) { - parentScreen.optionPane.setButtonEnabled(0, list.getMaxChoices() > 0); - } - } - - @Override - protected void doLayout(float width, float height) { - float padding = txtSearch.getHeight() * 0.25f; - float y = padding; - txtSearch.setBounds(0, y, width, txtSearch.getHeight()); - y += txtSearch.getHeight() + padding; - list.setBounds(0, y, width, height - y); - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/AddBasicLandsDialog.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/AddBasicLandsDialog.java deleted file mode 100644 index 6a3dca849e7..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/AddBasicLandsDialog.java +++ /dev/null @@ -1,424 +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.adventure.libgdxgui.deck; - -import com.badlogic.gdx.utils.Align; -import com.google.common.collect.Iterables; -import forge.StaticData; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.FSkinImage; -import forge.adventure.libgdxgui.card.CardRenderer; -import forge.adventure.libgdxgui.card.CardRenderer.CardStackPosition; -import forge.adventure.libgdxgui.card.CardZoom; -import forge.adventure.libgdxgui.toolbox.*; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.util.Utils; -import forge.card.CardEdition; -import forge.card.CardRules; -import forge.card.mana.ManaCostShard; -import forge.deck.CardPool; -import forge.deck.Deck; -import forge.deck.DeckgenUtil; -import forge.item.PaperCard; -import forge.model.FModel; -import forge.util.Callback; -import forge.util.Localizer; - -import java.text.NumberFormat; -import java.util.Map; -import java.util.Map.Entry; - - -public class AddBasicLandsDialog extends FDialog { - private static final float ADD_BTN_SIZE = Utils.AVG_FINGER_HEIGHT * 0.75f; - private static final float LAND_PANEL_PADDING = Utils.scale(3); - - private final Deck currentDeck; - - private final Callback callback; - - private final FLabel lblLandSet = add(new FLabel.Builder().text(Localizer.getInstance().getMessage("lblLandSet") + ":").font(FSkinFont.get(12)).textColor(FLabel.INLINE_LABEL_COLOR).build()); - private final FComboBox cbLandSet = add(new FComboBox<>(Iterables.filter(StaticData.instance().getEditions(), CardEdition.Predicates.hasBasicLands))); - - private final FScrollPane scroller = add(new FScrollPane() { - @Override - protected ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) { - float padding = FOptionPane.PADDING; - float x = padding; - float totalWidth = Forge.isLandscapeMode() ? visibleWidth : 2 * visibleWidth - ADD_BTN_SIZE; - float panelWidth = (totalWidth - 6 * padding) / 5; - - pnlPlains.setBounds(x, 0, panelWidth, visibleHeight); - x += panelWidth + padding; - pnlIsland.setBounds(x, 0, panelWidth, visibleHeight); - x += panelWidth + padding; - pnlSwamp.setBounds(x, 0, panelWidth, visibleHeight); - x += panelWidth + padding; - pnlMountain.setBounds(x, 0, panelWidth, visibleHeight); - x += panelWidth + padding; - pnlForest.setBounds(x, 0, panelWidth, visibleHeight); - - return new ScrollBounds(totalWidth, visibleHeight); - } - }); - private final LandPanel pnlPlains = scroller.add(new LandPanel("Plains")); - private final LandPanel pnlIsland = scroller.add(new LandPanel("Island")); - private final LandPanel pnlSwamp = scroller.add(new LandPanel("Swamp")); - private final LandPanel pnlMountain = scroller.add(new LandPanel("Mountain")); - private final LandPanel pnlForest = scroller.add(new LandPanel("Forest")); - - private final FTextArea lblDeckInfo = add(new FTextArea(true) { - @Override - public boolean tap(float x, float y, int count) { - if (count == 2) { - Map suggestionMap = DeckgenUtil.suggestBasicLandCount(currentDeck); - pnlPlains.count = suggestionMap.get(ManaCostShard.WHITE); - pnlIsland.count = suggestionMap.get(ManaCostShard.BLUE); - pnlSwamp.count = suggestionMap.get(ManaCostShard.BLACK); - pnlMountain.count = suggestionMap.get(ManaCostShard.RED); - pnlForest.count = suggestionMap.get(ManaCostShard.GREEN); - - pnlPlains.lblCount.setText(String.valueOf(pnlPlains.count)); - pnlIsland.lblCount.setText(String.valueOf(pnlIsland.count)); - pnlSwamp.lblCount.setText(String.valueOf(pnlSwamp.count)); - pnlMountain.lblCount.setText(String.valueOf(pnlMountain.count)); - pnlForest.lblCount.setText(String.valueOf(pnlForest.count)); - - updateDeckInfoLabel(); - } - return true; - } - }); - - private int nonLandCount, oldLandCount; - private CardEdition landSet; - - public AddBasicLandsDialog(Deck deck, CardEdition defaultLandSet, final Callback callback0) { - super(Localizer.getInstance().getMessage("lblAddBasicLandsAutoSuggest").replace("%s", deck.getName()), 2); - - callback = callback0; - currentDeck = deck; - - lblDeckInfo.setAlignment(Align.center); - lblDeckInfo.setFont(FSkinFont.get(12)); - - cbLandSet.setFont(lblLandSet.getFont()); - cbLandSet.setChangedHandler(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - landSet = cbLandSet.getSelectedItem(); - pnlPlains.refreshArtChoices(); - pnlIsland.refreshArtChoices(); - pnlSwamp.refreshArtChoices(); - pnlMountain.refreshArtChoices(); - pnlForest.refreshArtChoices(); - } - }); - cbLandSet.setSelectedItem(defaultLandSet); - - initButton(0, Localizer.getInstance().getMessage("lblOK"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - CardPool landsToAdd = new CardPool(); - pnlPlains.addToCardPool(landsToAdd); - pnlIsland.addToCardPool(landsToAdd); - pnlSwamp.addToCardPool(landsToAdd); - pnlMountain.addToCardPool(landsToAdd); - pnlForest.addToCardPool(landsToAdd); - - hide(); - - if (landsToAdd.countAll() > 0) { - callback.run(landsToAdd); - } - } - }); - initButton(1, Localizer.getInstance().getMessage("lblCancel"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - hide(); - } - }); - - //initialize land counts based on current deck contents - int halfCountW = 0; //track half shard count for each color to add to symbol count only if a full symbol is also found - int halfCountU = 0; - int halfCountB = 0; - int halfCountR = 0; - int halfCountG = 0; - for (Entry entry : deck.getMain()) { - CardRules cardRules = entry.getKey().getRules(); - int count = entry.getValue(); - if (cardRules.getType().isLand()) { - oldLandCount += count; - } - else { - nonLandCount += count; - - for (ManaCostShard shard : cardRules.getManaCost()) { - boolean isMonoColor = shard.isMonoColor(); - if (shard.isWhite()) { - if (isMonoColor) { - pnlPlains.symbolCount += count; - continue; - } - halfCountW += count; - } - if (shard.isBlue()) { - if (isMonoColor) { - pnlIsland.symbolCount += count; - continue; - } - halfCountU += count; - } - if (shard.isBlack()) { - if (isMonoColor) { - pnlSwamp.symbolCount += count; - continue; - } - halfCountB += count; - } - if (shard.isRed()) { - if (isMonoColor) { - pnlMountain.symbolCount += count; - continue; - } - halfCountR += count; - } - if (shard.isGreen()) { - if (isMonoColor) { - pnlForest.symbolCount += count; - continue; - } - halfCountG += count; - } - } - } - - //only account for half shards if full shards exist for a given color - if (pnlPlains.symbolCount > 0 && halfCountW > 0) { - pnlPlains.symbolCount += halfCountW * 0.5; - } - if (pnlIsland.symbolCount > 0 && halfCountU > 0) { - pnlIsland.symbolCount += halfCountU * 0.5; - } - if (pnlSwamp.symbolCount > 0 && halfCountB > 0) { - pnlSwamp.symbolCount += halfCountB * 0.5; - } - if (pnlMountain.symbolCount > 0 && halfCountR > 0) { - pnlMountain.symbolCount += halfCountR * 0.5; - } - if (pnlForest.symbolCount > 0 && halfCountG > 0) { - pnlForest.symbolCount += halfCountG * 0.5; - } - } - - updateDeckInfoLabel(); - } - - @Override - protected float layoutAndGetHeight(float width, float maxHeight) { - float padding = FOptionPane.PADDING; - float x = padding; - float y = padding; - float w = width - 2 * padding; - - //layout land set combo box - float comboBoxHeight = cbLandSet.getHeight(); - lblLandSet.setBounds(x, y, lblLandSet.getAutoSizeBounds().width, comboBoxHeight); - cbLandSet.setBounds(x + lblLandSet.getWidth(), y, w - lblLandSet.getWidth(), comboBoxHeight); - - //layout card panel scroller - y += comboBoxHeight + padding; - float panelExtraHeight = pnlPlains.cbLandArt.getHeight() + ADD_BTN_SIZE + 2 * LAND_PANEL_PADDING; - float panelWidth; - if (Forge.isLandscapeMode()) { - panelWidth = (width - 6 * padding) / 5; - } - else { - panelWidth = (2 * width - ADD_BTN_SIZE - 6 * padding) / 5; - } - float panelHeight = panelWidth * FCardPanel.ASPECT_RATIO + panelExtraHeight; - scroller.setBounds(0, y, width, panelHeight); - - //adjust scroll based on prevalent colors in deck - if (pnlMountain.symbolCount + pnlForest.symbolCount > pnlPlains.symbolCount + pnlIsland.symbolCount) { - scroller.scrollToRight(); - } - else { - scroller.scrollToLeft(); - } - - //layout info label - y += panelHeight + padding; - lblDeckInfo.setBounds(x, y, w, lblDeckInfo.getPreferredHeight(w)); - - return y + lblDeckInfo.getHeight() + padding; - } - - private void updateDeckInfoLabel() { - NumberFormat integer = NumberFormat.getIntegerInstance(); - NumberFormat percent = NumberFormat.getPercentInstance(); - int newLandCount = pnlPlains.count + pnlIsland.count + pnlSwamp.count + pnlMountain.count + pnlForest.count; - double totalSymbolCount = pnlPlains.symbolCount + pnlIsland.symbolCount + pnlSwamp.symbolCount + pnlMountain.symbolCount + pnlForest.symbolCount; - if (totalSymbolCount == 0) { - totalSymbolCount = 1; //prevent divide by 0 error - } - int newTotalCount = nonLandCount + oldLandCount + newLandCount; - lblDeckInfo.setText( - String.format(Localizer.getInstance().getMessage("lblNonLandCount"), nonLandCount) + " + " + - String.format(Localizer.getInstance().getMessage("lblOldLandCount"), oldLandCount) + " + " + - String.format(Localizer.getInstance().getMessage("lblNewLandCount"), newLandCount) + " = " + - String.format(Localizer.getInstance().getMessage("lblNewTotalCount"), newTotalCount) + "\n" + - "{W} " + integer.format(pnlPlains.symbolCount) + " (" + percent.format(pnlPlains.symbolCount / totalSymbolCount) + ") | " + - "{U} " + integer.format(pnlIsland.symbolCount) + " (" + percent.format(pnlIsland.symbolCount / totalSymbolCount) + ") | " + - "{B} " + integer.format(pnlSwamp.symbolCount) + " (" + percent.format(pnlSwamp.symbolCount / totalSymbolCount) + ") | " + - "{R} " + integer.format(pnlMountain.symbolCount) + " (" + percent.format(pnlMountain.symbolCount / totalSymbolCount) + ") | " + - "{G} " + integer.format(pnlForest.symbolCount) + " (" + percent.format(pnlForest.symbolCount / totalSymbolCount) + ")"); - } - - private class LandPanel extends FContainer { - private final LandCardPanel cardPanel; - private final FLabel lblCount, btnSubtract, btnAdd; - private final FComboBox cbLandArt; - private final String cardName; - private PaperCard card; - private int count, maxCount; - private double symbolCount; - - private LandPanel(String cardName0) { - cardName = cardName0; - cardPanel = add(new LandCardPanel()); - cbLandArt = add(new FComboBox<>()); - cbLandArt.setFont(cbLandSet.getFont()); - cbLandArt.setChangedHandler(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - int artIndex = cbLandArt.getSelectedIndex(); - if (artIndex < 0) { return; } - card = generateCard(artIndex); //generate card for display - } - }); - lblCount = add(new FLabel.Builder().text("0").font(FSkinFont.get(18)).align(Align.center).build()); - btnSubtract = add(new FLabel.ButtonBuilder().icon(Forge.hdbuttons ? FSkinImage.HDMINUS : FSkinImage.MINUS).command(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - if (count > 0) { - count--; - lblCount.setText(String.valueOf(count)); - updateDeckInfoLabel(); - } - } - }).build()); - btnAdd = add(new FLabel.ButtonBuilder().icon(Forge.hdbuttons ? FSkinImage.HDPLUS : FSkinImage.PLUS).command(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - if (maxCount == 0 || count < maxCount) { - count++; - lblCount.setText(String.valueOf(count)); - updateDeckInfoLabel(); - } - } - }).build()); - } - - private void addToCardPool(CardPool pool) { - if (count == 0) { return; } - int artIndex = cbLandArt.getSelectedIndex(); - if (artIndex < 0) { return; } - - if (artIndex > 0 && card != null) { - pool.add(card, count); //simplify things if art index specified - } - else { - for (int i = 0; i < count; i++) { - pool.add(generateCard(artIndex)); - } - } - } - - private PaperCard generateCard(int artIndex) { - PaperCard c = FModel.getMagicDb().getCommonCards().getCard(cardName, landSet.getCode(), artIndex); - if (c == null) { - //if can't find land for this set, fall back to Zendikar lands - c = FModel.getMagicDb().getCommonCards().getCard(cardName, "ZEN"); - } - return c; - } - - private void refreshArtChoices() { - cbLandArt.removeAllItems(); - if (landSet == null) { return; } - - int artChoiceCount = FModel.getMagicDb().getCommonCards().getArtCount(cardName, landSet.getCode()); - cbLandArt.addItem(Localizer.getInstance().getMessage("lblAssortedArt")); - for (int i = 1; i <= artChoiceCount; i++) { - cbLandArt.addItem(Localizer.getInstance().getMessage("lblCardArtN", String.valueOf(i))); - } - } - - @Override - protected void doLayout(float width, float height) { - float y = height - ADD_BTN_SIZE; - float buttonWidth = ADD_BTN_SIZE; - float labelWidth = width - 2 * ADD_BTN_SIZE; - float minLabelWidth = lblCount.getFont().getBounds("0").width + 2 * lblCount.getInsets().x; - if (labelWidth < minLabelWidth) { //ensure count label has enough room for display a single digit count at normal font size - labelWidth = minLabelWidth; - buttonWidth = (width - labelWidth) / 2; - } - btnSubtract.setBounds(0, y, buttonWidth, ADD_BTN_SIZE); - lblCount.setBounds(buttonWidth, y, labelWidth, ADD_BTN_SIZE); - btnAdd.setBounds(width - buttonWidth, y, buttonWidth, ADD_BTN_SIZE); - - y -= cbLandArt.getHeight() + LAND_PANEL_PADDING; - cbLandArt.setBounds(0, y, width, cbLandArt.getHeight()); - - float cardPanelHeight = y - LAND_PANEL_PADDING; - float cardPanelWidth = cardPanelHeight / FCardPanel.ASPECT_RATIO; - cardPanel.setBounds((width - cardPanelWidth) / 2, 0, cardPanelWidth, cardPanelHeight); - } - - private class LandCardPanel extends FDisplayObject { - private LandCardPanel() { - } - - @Override - public boolean tap(float x, float y, int count) { - if (card == null) { return false; } - CardZoom.show(card); - return true; - } - - @Override - public boolean longPress(float x, float y) { - if (card == null) { return false; } - CardZoom.show(card); - return true; - } - - @Override - public void draw(Graphics g) { - if (card == null) { return; } - CardRenderer.drawCard(g, card, 0, 0, getWidth(), getHeight(), CardStackPosition.Top); - } - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FDeckChooser.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FDeckChooser.java deleted file mode 100644 index aa105c9c2a1..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FDeckChooser.java +++ /dev/null @@ -1,1475 +0,0 @@ -package forge.adventure.libgdxgui.deck; - -import com.badlogic.gdx.utils.Align; -import com.google.common.collect.ImmutableList; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.assets.ImageCache; -import forge.adventure.libgdxgui.deck.FDeckEditor.EditorType; -import forge.adventure.libgdxgui.itemmanager.DeckManager; -import forge.adventure.libgdxgui.itemmanager.filters.ItemFilter; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.screens.LoadingOverlay; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.toolbox.*; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.util.Utils; -import forge.deck.*; -import forge.deck.io.DeckPreferences; -import forge.game.GameType; -import forge.game.player.RegisteredPlayer; -import forge.gamemodes.gauntlet.GauntletData; -import forge.gamemodes.gauntlet.GauntletUtil; -import forge.gamemodes.match.HostedMatch; -import forge.gamemodes.quest.QuestController; -import forge.gamemodes.quest.QuestEvent; -import forge.gamemodes.quest.QuestEventChallenge; -import forge.gamemodes.quest.QuestUtil; -import forge.gui.FThreads; -import forge.gui.GuiBase; -import forge.gui.error.BugReporter; -import forge.gui.interfaces.IGuiGame; -import forge.itemmanager.ItemManagerConfig; -import forge.localinstance.properties.ForgePreferences; -import forge.localinstance.properties.ForgePreferences.FPref; -import forge.model.FModel; -import forge.player.GamePlayerUtil; -import forge.util.Callback; -import forge.util.Localizer; -import forge.util.storage.IStorage; -import org.apache.commons.lang3.StringUtils; - -import java.util.*; - -public class FDeckChooser extends FScreen { - public static final float PADDING = Utils.scale(5); - - private FComboBox cmbDeckTypes; - private DeckType selectedDeckType; - private boolean needRefreshOnActivate; - private Callback callback; - private NetDeckCategory netDeckCategory; - private NetDeckArchiveStandard NetDeckArchiveStandard; - private NetDeckArchivePioneer NetDeckArchivePioneer; - private NetDeckArchiveModern NetDeckArchiveModern; - private NetDeckArchiveLegacy NetDeckArchiveLegacy; - private NetDeckArchiveVintage NetDeckArchiveVintage; - private NetDeckArchiveBlock NetDeckArchiveBlock; - private boolean refreshingDeckType; - private boolean firstActivation = true; - - private final DeckManager lstDecks; - private final FButton btnNewDeck = new FButton(Localizer.getInstance().getMessage("lblNewDeck")); - private final FButton btnEditDeck = new FButton(Localizer.getInstance().getMessage("btnEditDeck")); - private final FButton btnViewDeck = new FButton(Localizer.getInstance().getMessage("lblViewDeck")); - private final FButton btnRandom = new FButton(Localizer.getInstance().getMessage("lblRandomDeck")); - - private RegisteredPlayer player; - private boolean isAi; - private final ForgePreferences prefs = FModel.getPreferences(); - private final Localizer localizer = Localizer.getInstance(); - private FPref stateSetting = null; - private FOptionPane optionPane; - - //Show dialog to select a deck - public static void promptForDeck(String title, GameType gameType, boolean forAi, final Callback callback) { - FThreads.assertExecutedByEdt(true); - - final FDeckChooser deckChooser = new FDeckChooser(gameType, forAi, null); - - //use container to contain both combo box and deck list - final FContainer container = new FContainer() { - @Override - protected void doLayout(final float width, final float height) { - float x = 0; - float y = ItemFilter.PADDING; - float fieldHeight = deckChooser.cmbDeckTypes.getHeight(); - deckChooser.cmbDeckTypes.setBounds(x, y, width, fieldHeight); - y += fieldHeight + 1; - deckChooser.lstDecks.setBounds(x, y, width, height - y); - } - }; - container.add(deckChooser.cmbDeckTypes); - container.add(deckChooser.lstDecks); - container.setHeight(FOptionPane.getMaxDisplayObjHeight()); - - deckChooser.optionPane = new FOptionPane(null, null, title, null, container, ImmutableList.of(Localizer.getInstance().getMessage("lblOK"), Localizer.getInstance().getMessage("lblCancel")), 0, new Callback() { - @Override - public void run(Integer result) { - if (result == 0) { - if (callback != null) { - callback.run(deckChooser.getDeck()); - } - } - } - }) { - @Override - protected boolean padAboveAndBelow() { - return false; //allow list to go straight up against buttons - } - }; - deckChooser.optionPane.show(); - } - - public FDeckChooser(GameType gameType0, boolean isAi0, FEventHandler selectionChangedHandler) { - super(""); - lstDecks = new DeckManager(gameType0); - isAi = isAi0; - - lstDecks.setItemActivateHandler(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - if (lstDecks.getGameType() == GameType.DeckManager) { - //for Deck Editor, edit deck instead of accepting - editSelectedDeck(); - return; - } - accept(); - } - }); - btnNewDeck.setCommand(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - createNewDeck(); - } - }); - btnEditDeck.setCommand(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - editSelectedDeck(); - } - }); - btnViewDeck.setCommand(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - if (selectedDeckType != DeckType.STANDARD_COLOR_DECK && selectedDeckType != DeckType.STANDARD_CARDGEN_DECK - && selectedDeckType != DeckType.PIONEER_CARDGEN_DECK && selectedDeckType != DeckType.HISTORIC_CARDGEN_DECK - && selectedDeckType != DeckType.MODERN_CARDGEN_DECK && selectedDeckType != DeckType.LEGACY_CARDGEN_DECK - && selectedDeckType != DeckType.VINTAGE_CARDGEN_DECK && selectedDeckType != DeckType.MODERN_COLOR_DECK && - selectedDeckType != DeckType.COLOR_DECK && selectedDeckType != DeckType.THEME_DECK - && selectedDeckType != DeckType.RANDOM_COMMANDER_DECK && selectedDeckType != DeckType.RANDOM_CARDGEN_COMMANDER_DECK) { - FDeckViewer.show(getDeck()); - } - } - }); - btnRandom.setCommand(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - if (lstDecks.getGameType() == GameType.DeckManager) { - //for Deck Editor, test deck instead of randomly selecting deck - testSelectedDeck(); - return; - } - if (selectedDeckType == DeckType.COLOR_DECK || selectedDeckType == DeckType.STANDARD_COLOR_DECK - || selectedDeckType == DeckType.MODERN_COLOR_DECK) { - DeckgenUtil.randomSelectColors(lstDecks); - } - else if (selectedDeckType == DeckType.STANDARD_CARDGEN_DECK){ - DeckgenUtil.randomSelect(lstDecks); - } - else if (selectedDeckType == DeckType.PIONEER_CARDGEN_DECK){ - DeckgenUtil.randomSelect(lstDecks); - } - else if (selectedDeckType == DeckType.HISTORIC_CARDGEN_DECK){ - DeckgenUtil.randomSelect(lstDecks); - } - else if (selectedDeckType == DeckType.MODERN_CARDGEN_DECK){ - DeckgenUtil.randomSelect(lstDecks); - } - else if (selectedDeckType == DeckType.LEGACY_CARDGEN_DECK){ - DeckgenUtil.randomSelect(lstDecks); - } - else if (selectedDeckType == DeckType.VINTAGE_CARDGEN_DECK){ - DeckgenUtil.randomSelect(lstDecks); - } - else { - DeckgenUtil.randomSelect(lstDecks); - } - accept(); - } - }); - switch (lstDecks.getGameType()) { - case Constructed: - break; //delay initialize for constructed until saved decks can be reloaded - case Commander: - case Oathbreaker: - case TinyLeaders: - case Brawl: - case Gauntlet: - initialize(null, DeckType.CUSTOM_DECK); - break; - case DeckManager: - initialize(null, DeckPreferences.getSelectedDeckType()); - break; - default: - initialize(null, DeckType.RANDOM_DECK); - break; - } - lstDecks.setSelectionChangedHandler(selectionChangedHandler); - } - - private void accept() { - if (optionPane == null) { - Forge.back(); - if (callback != null) { - callback.run(getDeck()); - } - } - else { - optionPane.setResult(0); - } - } - - @Override - public void onActivate() { - String selectedDeck = ""; - int index = 0; - if (lstDecks.getSelectedItem() != null) { - selectedDeck = lstDecks.getSelectedItem().getDeck().toString(); - index = lstDecks.getSelectedIndex(); - } - if (lstDecks.getConfig().getViewIndex() == 1 && firstActivation) { - firstActivation = false; - lstDecks.refresh(); - if (selectedDeckType.name().startsWith("NET_")) { - //we can't use the index here since net decks are updated and may add decks and can be inserted anywhere - lstDecks.setSelectedString(selectedDeck); - } else { - //we use index here as a workaround, if the provided decks are updated somehow at least it will refresh the display - if (lstDecks.getSelectedIndex() < 0) { - lstDecks.setSelectedIndex(index); - } - } - } else if (needRefreshOnActivate) { - needRefreshOnActivate = false; - refreshDecksList(selectedDeckType, true, null); - switch (lstDecks.getGameType()) { - case Commander: - lstDecks.setSelectedString(DeckPreferences.getCommanderDeck()); - break; - case Oathbreaker: - lstDecks.setSelectedString(DeckPreferences.getOathbreakerDeck()); - break; - case TinyLeaders: - lstDecks.setSelectedString(DeckPreferences.getTinyLeadersDeck()); - break; - case Brawl: - lstDecks.setSelectedString(DeckPreferences.getBrawlDeck()); - break; - case Archenemy: - lstDecks.setSelectedString(DeckPreferences.getSchemeDeck()); - break; - case Planechase: - lstDecks.setSelectedString(DeckPreferences.getPlanarDeck()); - break; - case DeckManager: - switch (selectedDeckType) { - case COMMANDER_DECK: - lstDecks.setSelectedString(DeckPreferences.getCommanderDeck()); - break; - case OATHBREAKER_DECK: - lstDecks.setSelectedString(DeckPreferences.getOathbreakerDeck()); - break; - case TINY_LEADERS_DECK: - lstDecks.setSelectedString(DeckPreferences.getTinyLeadersDeck()); - break; - case BRAWL_DECK: - lstDecks.setSelectedString(DeckPreferences.getBrawlDeck()); - break; - case SCHEME_DECK: - lstDecks.setSelectedString(DeckPreferences.getSchemeDeck()); - break; - case PLANAR_DECK: - lstDecks.setSelectedString(DeckPreferences.getPlanarDeck()); - break; - case DRAFT_DECK: - lstDecks.setSelectedString(DeckPreferences.getDraftDeck()); - break; - case SEALED_DECK: - lstDecks.setSelectedString(DeckPreferences.getSealedDeck()); - break; - default: - lstDecks.setSelectedString(DeckPreferences.getCurrentDeck()); - break; - } - break; - default: - if (!lstDecks.setSelectedString(DeckPreferences.getCurrentDeck())) - lstDecks.setSelectedString(selectedDeck); - break; - } - } - } - - private boolean isGeneratedDeck(DeckType deckType) { - switch (deckType) { - case COLOR_DECK: - case STANDARD_COLOR_DECK: - case STANDARD_CARDGEN_DECK: - case RANDOM_CARDGEN_COMMANDER_DECK: - case RANDOM_COMMANDER_DECK: - case MODERN_CARDGEN_DECK: - case PIONEER_CARDGEN_DECK: - case HISTORIC_CARDGEN_DECK: - case LEGACY_CARDGEN_DECK: - case VINTAGE_CARDGEN_DECK: - case MODERN_COLOR_DECK: - case THEME_DECK: - case RANDOM_DECK: - return true; - default: - return false; - } - } - private void createNewDeck() { - final FDeckEditor editor; - final DeckProxy deck = lstDecks.getSelectedItem(); - - if (isGeneratedDeck(selectedDeckType)) { - if (deck == null) { - FOptionPane.showErrorDialog(localizer.getMessage("lblMustSelectGenerateNewDeck")); - return; - } - } - if (isGeneratedDeck(selectedDeckType)) { - Deck generatedDeck = deck.getDeck(); - if (generatedDeck == null) { return; } - generatedDeck = (Deck)generatedDeck.copyTo(""); //prevent deck having a name by default - editor = new FDeckEditor(getEditorType(), generatedDeck, true); - } else { - editor = new FDeckEditor(getEditorType(), "", false); - } - editor.setSaveHandler(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - //ensure user returns to proper deck type and that list is refreshed if new deck is saved - if (!needRefreshOnActivate) { - needRefreshOnActivate = true; - if (lstDecks.getGameType() == GameType.DeckManager) { - switch (selectedDeckType) { - case COMMANDER_DECK: - case OATHBREAKER_DECK: - case TINY_LEADERS_DECK: - case BRAWL_DECK: - case SCHEME_DECK: - case PLANAR_DECK: - case DRAFT_DECK: - case SEALED_DECK: - break; - default: - setSelectedDeckType(DeckType.CONSTRUCTED_DECK); - break; - } - } - else { - setSelectedDeckType(DeckType.CUSTOM_DECK); - } - } - } - }); - Forge.openScreen(editor); - } - - private void editSelectedDeck() { - final DeckProxy deck = lstDecks.getSelectedItem(); - if (deck == null) { return; } - - switch (selectedDeckType) { - case CUSTOM_DECK: - case CONSTRUCTED_DECK: - case COMMANDER_DECK: - case OATHBREAKER_DECK: - case TINY_LEADERS_DECK: - case BRAWL_DECK: - case SCHEME_DECK: - case PLANAR_DECK: - case DRAFT_DECK: - case SEALED_DECK: - editDeck(deck); - break; - default: - final DeckType fallbackType = lstDecks.getGameType() == GameType.DeckManager ? DeckType.CONSTRUCTED_DECK : DeckType.CUSTOM_DECK; - - //see if deck with selected name exists already - final IStorage decks = FModel.getDecks().getConstructed(); - Deck existingDeck = decks.get(deck.getName()); - if (existingDeck != null) { - setSelectedDeckType(fallbackType); - editDeck(new DeckProxy(existingDeck, "Constructed", lstDecks.getGameType(), decks)); - return; - } - - - //prompt to duplicate deck if deck doesn't exist already - FOptionPane.showConfirmDialog(selectedDeckType + " " + localizer.getMessage("lblCannotEditDuplicateCustomDeck").replace("%s", deck.getName()), - localizer.getMessage("lblDuplicateDeck"), localizer.getMessage("lblDuplicate"), localizer.getMessage("lblCancel"), new Callback() { - @Override - public void run(Boolean result) { - if (result) { - Deck copiedDeck = (Deck)deck.getDeck().copyTo(deck.getName()); - decks.add(copiedDeck); - setSelectedDeckType(fallbackType); - editDeck(new DeckProxy(copiedDeck, "Constructed", lstDecks.getGameType(), decks)); - } - } - }); - break; - } - } - - private EditorType getEditorType() { - switch (lstDecks.getGameType()) { - case DeckManager: - switch (selectedDeckType) { - case COMMANDER_DECK: - return EditorType.Commander; - case OATHBREAKER_DECK: - return EditorType.Oathbreaker; - case TINY_LEADERS_DECK: - return EditorType.TinyLeaders; - case BRAWL_DECK: - return EditorType.Brawl; - case SCHEME_DECK: - return EditorType.Archenemy; - case PLANAR_DECK: - return EditorType.Planechase; - case DRAFT_DECK: - return EditorType.Draft; - case SEALED_DECK: - return EditorType.Sealed; - default: - return EditorType.Constructed; - } - case Commander: - return EditorType.Commander; - case Oathbreaker: - return EditorType.Oathbreaker; - case TinyLeaders: - return EditorType.TinyLeaders; - case Brawl: - return EditorType.Brawl; - case Archenemy: - return EditorType.Archenemy; - case Planechase: - return EditorType.Planechase; - default: - return EditorType.Constructed; - } - } - - private void editDeck(DeckProxy deck) { - EditorType editorType = getEditorType(); - switch (editorType) { - case Commander: - DeckPreferences.setCommanderDeck(deck.getName()); - break; - case Oathbreaker: - DeckPreferences.setOathbreakerDeck(deck.getName()); - break; - case TinyLeaders: - DeckPreferences.setTinyLeadersDeck(deck.getName()); - break; - case Archenemy: - DeckPreferences.setSchemeDeck(deck.getName()); - break; - case Planechase: - DeckPreferences.setPlanarDeck(deck.getName()); - break; - case Draft: - DeckPreferences.setDraftDeck(deck.getName()); - break; - case Sealed: - DeckPreferences.setSealedDeck(deck.getName()); - break; - case Constructed: - DeckPreferences.setCurrentDeck(deck.getName()); - break; - default: - break; - } - needRefreshOnActivate = true; - /*preload deck to cache*/ - ImageCache.preloadCache(deck.getDeck()); - Forge.openScreen(new FDeckEditor(editorType, deck, true)); - } - - public void initialize(FPref savedStateSetting, DeckType defaultDeckType) { - stateSetting = savedStateSetting; - selectedDeckType = defaultDeckType; - - if (cmbDeckTypes == null) { //initialize components with delayed initialization the first time this is populated - cmbDeckTypes = new FComboBox<>(); - switch (lstDecks.getGameType()) { - case Constructed: - case Gauntlet: - cmbDeckTypes.addItem(DeckType.CUSTOM_DECK); - cmbDeckTypes.addItem(DeckType.PRECONSTRUCTED_DECK); - cmbDeckTypes.addItem(DeckType.QUEST_OPPONENT_DECK); - cmbDeckTypes.addItem(DeckType.COLOR_DECK); - cmbDeckTypes.addItem(DeckType.STANDARD_COLOR_DECK); - if(FModel.isdeckGenMatrixLoaded()) { - cmbDeckTypes.addItem(DeckType.STANDARD_CARDGEN_DECK); - cmbDeckTypes.addItem(DeckType.PIONEER_CARDGEN_DECK); - cmbDeckTypes.addItem(DeckType.HISTORIC_CARDGEN_DECK); - cmbDeckTypes.addItem(DeckType.MODERN_CARDGEN_DECK); - cmbDeckTypes.addItem(DeckType.LEGACY_CARDGEN_DECK); - cmbDeckTypes.addItem(DeckType.VINTAGE_CARDGEN_DECK); - } - cmbDeckTypes.addItem(DeckType.MODERN_COLOR_DECK); - cmbDeckTypes.addItem(DeckType.THEME_DECK); - cmbDeckTypes.addItem(DeckType.RANDOM_DECK); - cmbDeckTypes.addItem(DeckType.NET_DECK); - cmbDeckTypes.addItem(DeckType.NET_ARCHIVE_STANDARD_DECK); - cmbDeckTypes.addItem(DeckType.NET_ARCHIVE_PIONEER_DECK); - cmbDeckTypes.addItem(DeckType.NET_ARCHIVE_MODERN_DECK); - cmbDeckTypes.addItem(DeckType.NET_ARCHIVE_LEGACY_DECK); - cmbDeckTypes.addItem(DeckType.NET_ARCHIVE_VINTAGE_DECK); - cmbDeckTypes.addItem(DeckType.NET_ARCHIVE_BLOCK_DECK); - - break; - case Commander: - case Oathbreaker: - case TinyLeaders: - case Brawl: - cmbDeckTypes.addItem(DeckType.CUSTOM_DECK); - cmbDeckTypes.addItem(DeckType.PRECON_COMMANDER_DECK); - cmbDeckTypes.addItem(DeckType.RANDOM_DECK); - if(FModel.isdeckGenMatrixLoaded()) { - cmbDeckTypes.addItem(DeckType.RANDOM_CARDGEN_COMMANDER_DECK); - } - cmbDeckTypes.addItem(DeckType.RANDOM_COMMANDER_DECK); - cmbDeckTypes.addItem(DeckType.NET_DECK); - break; - case DeckManager: - cmbDeckTypes.addItem(DeckType.CONSTRUCTED_DECK); - cmbDeckTypes.addItem(DeckType.COMMANDER_DECK); - cmbDeckTypes.addItem(DeckType.OATHBREAKER_DECK); - cmbDeckTypes.addItem(DeckType.TINY_LEADERS_DECK); - cmbDeckTypes.addItem(DeckType.BRAWL_DECK); - cmbDeckTypes.addItem(DeckType.SCHEME_DECK); - cmbDeckTypes.addItem(DeckType.PLANAR_DECK); - cmbDeckTypes.addItem(DeckType.DRAFT_DECK); - cmbDeckTypes.addItem(DeckType.SEALED_DECK); - cmbDeckTypes.addItem(DeckType.PRECONSTRUCTED_DECK); - cmbDeckTypes.addItem(DeckType.PRECON_COMMANDER_DECK); - cmbDeckTypes.addItem(DeckType.QUEST_OPPONENT_DECK); - cmbDeckTypes.addItem(DeckType.NET_DECK); - cmbDeckTypes.addItem(DeckType.NET_COMMANDER_DECK); - cmbDeckTypes.addItem(DeckType.NET_ARCHIVE_STANDARD_DECK); - cmbDeckTypes.addItem(DeckType.NET_ARCHIVE_PIONEER_DECK); - cmbDeckTypes.addItem(DeckType.NET_ARCHIVE_MODERN_DECK); - cmbDeckTypes.addItem(DeckType.NET_ARCHIVE_LEGACY_DECK); - cmbDeckTypes.addItem(DeckType.NET_ARCHIVE_VINTAGE_DECK); - cmbDeckTypes.addItem(DeckType.NET_ARCHIVE_BLOCK_DECK); - break; - default: - cmbDeckTypes.addItem(DeckType.CUSTOM_DECK); - cmbDeckTypes.addItem(DeckType.RANDOM_DECK); - break; - } - cmbDeckTypes.setAlignment(Align.center); - restoreSavedState(); - - cmbDeckTypes.setChangedHandler(new FEventHandler() { - @Override - - public void handleEvent(final FEvent e) { - final DeckType deckType = cmbDeckTypes.getSelectedItem(); - - if (!refreshingDeckType&&(deckType == DeckType.NET_DECK || deckType == DeckType.NET_COMMANDER_DECK)) { - FThreads.invokeInBackgroundThread(new Runnable() { //needed for loading net decks - @Override - public void run() { - GameType gameType = lstDecks.getGameType(); - if (gameType == GameType.DeckManager) { - gameType = deckType == DeckType.NET_COMMANDER_DECK ? GameType.Commander : GameType.Constructed; - } - final NetDeckCategory category = NetDeckCategory.selectAndLoad(gameType); - - FThreads.invokeInEdtLater(new Runnable() { - @Override - public void run() { - if (category == null) { - cmbDeckTypes.setSelectedItem(selectedDeckType); //restore old selection if user cancels - if (selectedDeckType == deckType && netDeckCategory != null) { - cmbDeckTypes.setText(netDeckCategory.getDeckType()); - } - return; - } - - netDeckCategory = category; - refreshDecksList(deckType, true, e); - } - }); - } - }); - return; - } - if (!refreshingDeckType&&(deckType == DeckType.NET_ARCHIVE_STANDARD_DECK)) { - FThreads.invokeInBackgroundThread(new Runnable() { //needed for loading net decks - @Override - public void run() { - GameType gameType = lstDecks.getGameType(); - final NetDeckArchiveStandard category = forge.deck.NetDeckArchiveStandard.selectAndLoad(gameType); - - FThreads.invokeInEdtLater(new Runnable() { - @Override - public void run() { - if (category == null) { - cmbDeckTypes.setSelectedItem(selectedDeckType); //restore old selection if user cancels - if (selectedDeckType == deckType && NetDeckArchiveStandard != null) { - cmbDeckTypes.setText(NetDeckArchiveStandard.getDeckType()); - } - return; - } - - NetDeckArchiveStandard = category; - refreshDecksList(deckType, true, e); - } - }); - } - }); - return; - } - if (!refreshingDeckType&&(deckType == DeckType.NET_ARCHIVE_PIONEER_DECK)) { - FThreads.invokeInBackgroundThread(new Runnable() { //needed for loading net decks - @Override - public void run() { - GameType gameType = lstDecks.getGameType(); - final NetDeckArchivePioneer category = forge.deck.NetDeckArchivePioneer.selectAndLoad(gameType); - - FThreads.invokeInEdtLater(new Runnable() { - @Override - public void run() { - if (category == null) { - cmbDeckTypes.setSelectedItem(selectedDeckType); //restore old selection if user cancels - if (selectedDeckType == deckType && NetDeckArchivePioneer != null) { - cmbDeckTypes.setText(NetDeckArchivePioneer.getDeckType()); - } - return; - } - - NetDeckArchivePioneer = category; - refreshDecksList(deckType, true, e); - } - }); - } - }); - return; - } - if (!refreshingDeckType&&(deckType == DeckType.NET_ARCHIVE_MODERN_DECK)) { - FThreads.invokeInBackgroundThread(new Runnable() { //needed for loading net decks - @Override - public void run() { - GameType gameType = lstDecks.getGameType(); - final NetDeckArchiveModern category = forge.deck.NetDeckArchiveModern.selectAndLoad(gameType); - - FThreads.invokeInEdtLater(new Runnable() { - @Override - public void run() { - if (category == null) { - cmbDeckTypes.setSelectedItem(selectedDeckType); //restore old selection if user cancels - if (selectedDeckType == deckType && NetDeckArchiveModern != null) { - cmbDeckTypes.setText(NetDeckArchiveModern.getDeckType()); - } - return; - } - - NetDeckArchiveModern = category; - refreshDecksList(deckType, true, e); - } - }); - } - }); - return; - } - if (!refreshingDeckType&&(deckType == DeckType.NET_ARCHIVE_LEGACY_DECK)) { - FThreads.invokeInBackgroundThread(new Runnable() { //needed for loading net decks - @Override - public void run() { - GameType gameType = lstDecks.getGameType(); - final NetDeckArchiveLegacy category = forge.deck.NetDeckArchiveLegacy.selectAndLoad(gameType); - - FThreads.invokeInEdtLater(new Runnable() { - @Override - public void run() { - if (category == null) { - cmbDeckTypes.setSelectedItem(selectedDeckType); //restore old selection if user cancels - if (selectedDeckType == deckType && NetDeckArchiveLegacy != null) { - cmbDeckTypes.setText(NetDeckArchiveLegacy.getDeckType()); - } - return; - } - - NetDeckArchiveLegacy = category; - refreshDecksList(deckType, true, e); - } - }); - } - }); - return; - } - if (!refreshingDeckType&&(deckType == DeckType.NET_ARCHIVE_VINTAGE_DECK)) { - FThreads.invokeInBackgroundThread(new Runnable() { //needed for loading net decks - @Override - public void run() { - GameType gameType = lstDecks.getGameType(); - final NetDeckArchiveVintage category = forge.deck.NetDeckArchiveVintage.selectAndLoad(gameType); - - FThreads.invokeInEdtLater(new Runnable() { - @Override - public void run() { - if (category == null) { - cmbDeckTypes.setSelectedItem(selectedDeckType); //restore old selection if user cancels - if (selectedDeckType == deckType && NetDeckArchiveVintage != null) { - cmbDeckTypes.setText(NetDeckArchiveVintage.getDeckType()); - } - return; - } - - NetDeckArchiveVintage = category; - refreshDecksList(deckType, true, e); - } - }); - } - }); - return; - } - - - - if (!refreshingDeckType&&(deckType == DeckType.NET_ARCHIVE_BLOCK_DECK)) { - FThreads.invokeInBackgroundThread(new Runnable() { //needed for loading net decks - @Override - public void run() { - GameType gameType = lstDecks.getGameType(); - final NetDeckArchiveBlock category = forge.deck.NetDeckArchiveBlock.selectAndLoad(gameType); - - FThreads.invokeInEdtLater(new Runnable() { - @Override - public void run() { - if (category == null) { - cmbDeckTypes.setSelectedItem(selectedDeckType); //restore old selection if user cancels - if (selectedDeckType == deckType && NetDeckArchiveBlock != null) { - cmbDeckTypes.setText(NetDeckArchiveBlock.getDeckType()); - } - return; - } - - NetDeckArchiveBlock = category; - refreshDecksList(deckType, true, e); - } - }); - } - }); - return; - } - - - - - refreshDecksList(deckType, false, e); - } - }); - add(cmbDeckTypes); - add(lstDecks); - add(btnNewDeck); - add(btnEditDeck); - add(btnViewDeck); - add(btnRandom); - } - else { - restoreSavedState(); //ensure decks refreshed and state restored in case any deleted or added since last loaded - } - } - - public void refreshDeckListForAI(){ - //remember current deck by name, refresh decklist for AI/Human then reselect if possible - String currentName= lstDecks.getSelectedItem().getName(); - refreshDecksList(selectedDeckType,true,null); - lstDecks.setSelectedString(currentName); - saveState(); - } - - private void refreshDecksList(DeckType deckType, boolean forceRefresh, FEvent e) { - if (selectedDeckType == deckType && !forceRefresh) { return; } - selectedDeckType = deckType; - - if (e == null) { - refreshingDeckType = true; - cmbDeckTypes.setSelectedItem(deckType); - refreshingDeckType = false; - } - if (deckType == null) { return; } - - int maxSelections = 1; - Iterable pool; - ItemManagerConfig config; - - switch (deckType) { - case CUSTOM_DECK: - switch (lstDecks.getGameType()) { - case Commander: - pool = DeckProxy.getAllCommanderDecks(); - config = ItemManagerConfig.COMMANDER_DECKS; - break; - case Oathbreaker: - pool = DeckProxy.getAllOathbreakerDecks(); - config = ItemManagerConfig.COMMANDER_DECKS; - break; - case TinyLeaders: - pool = DeckProxy.getAllTinyLeadersDecks(); - config = ItemManagerConfig.COMMANDER_DECKS; - break; - case Brawl: - pool = DeckProxy.getAllBrawlDecks(); - config = ItemManagerConfig.COMMANDER_DECKS; - break; - case Archenemy: - pool = DeckProxy.getAllSchemeDecks(); - config = ItemManagerConfig.SCHEME_DECKS; - break; - case Planechase: - pool = DeckProxy.getAllPlanarDecks(); - config = ItemManagerConfig.PLANAR_DECKS; - break; - default: - pool = DeckProxy.getAllConstructedDecks(); - config = ItemManagerConfig.CONSTRUCTED_DECKS; - break; - } - break; - case CONSTRUCTED_DECK: - pool = DeckProxy.getAllConstructedDecks(); - config = ItemManagerConfig.CONSTRUCTED_DECKS; - break; - case COMMANDER_DECK: - pool = DeckProxy.getAllCommanderDecks(); - config = ItemManagerConfig.COMMANDER_DECKS; - break; - case PRECON_COMMANDER_DECK: - pool = DeckProxy.getAllCommanderPreconDecks(); - config = ItemManagerConfig.COMMANDER_DECKS; - break; - case OATHBREAKER_DECK: - pool = DeckProxy.getAllOathbreakerDecks(); - config = ItemManagerConfig.COMMANDER_DECKS; - break; - case TINY_LEADERS_DECK: - pool = DeckProxy.getAllTinyLeadersDecks(); - config = ItemManagerConfig.COMMANDER_DECKS; - break; - case BRAWL_DECK: - pool = DeckProxy.getAllBrawlDecks(); - config = ItemManagerConfig.COMMANDER_DECKS; - break; - case RANDOM_COMMANDER_DECK: - pool = CommanderDeckGenerator.getCommanderDecks(lstDecks.getGameType().getDeckFormat(),isAi, false); - config = ItemManagerConfig.STRING_ONLY; - break; - case RANDOM_CARDGEN_COMMANDER_DECK: - pool= new ArrayList<>(); - if(FModel.isdeckGenMatrixLoaded()) { - pool = CommanderDeckGenerator.getCommanderDecks(lstDecks.getGameType().getDeckFormat(), isAi, true); - } - config = ItemManagerConfig.STRING_ONLY; - break; - case SCHEME_DECK: - pool = DeckProxy.getAllSchemeDecks(); - config = ItemManagerConfig.SCHEME_DECKS; - break; - case PLANAR_DECK: - pool = DeckProxy.getAllPlanarDecks(); - config = ItemManagerConfig.PLANAR_DECKS; - break; - case DRAFT_DECK: - pool = DeckProxy.getAllDraftDecks(); - config = ItemManagerConfig.DRAFT_DECKS; - break; - case SEALED_DECK: - pool = DeckProxy.getAllSealedDecks(); - config = ItemManagerConfig.SEALED_DECKS; - break; - case COLOR_DECK: - maxSelections = 3; - pool = ColorDeckGenerator.getColorDecks(lstDecks, null, isAi); - config = ItemManagerConfig.STRING_ONLY; - break; - case STANDARD_COLOR_DECK: - maxSelections = 3; - pool = ColorDeckGenerator.getColorDecks(lstDecks, FModel.getFormats().getStandard().getFilterPrinted(), isAi); - config = ItemManagerConfig.STRING_ONLY; - break; - case STANDARD_CARDGEN_DECK: - maxSelections = 1; - pool= new ArrayList<>(); - if(FModel.isdeckGenMatrixLoaded()) { - pool = ArchetypeDeckGenerator.getMatrixDecks(FModel.getFormats().getStandard(), isAi); - } - config = ItemManagerConfig.STRING_ONLY; - break; - case PIONEER_CARDGEN_DECK: - maxSelections = 1; - pool= new ArrayList<>(); - if(FModel.isdeckGenMatrixLoaded()) { - pool = ArchetypeDeckGenerator.getMatrixDecks(FModel.getFormats().getPioneer(), isAi); - } - config = ItemManagerConfig.STRING_ONLY; - break; - case HISTORIC_CARDGEN_DECK: - maxSelections = 1; - pool= new ArrayList<>(); - if(FModel.isdeckGenMatrixLoaded()) { - pool = ArchetypeDeckGenerator.getMatrixDecks(FModel.getFormats().getHistoric(), isAi); - } - config = ItemManagerConfig.STRING_ONLY; - break; - case MODERN_CARDGEN_DECK: - maxSelections = 1; - pool= new ArrayList<>(); - if(FModel.isdeckGenMatrixLoaded()) { - pool = ArchetypeDeckGenerator.getMatrixDecks(FModel.getFormats().getModern(), isAi); - } - config = ItemManagerConfig.STRING_ONLY; - break; - case LEGACY_CARDGEN_DECK: - maxSelections = 1; - pool= new ArrayList<>(); - if(FModel.isdeckGenMatrixLoaded()) { - pool = ArchetypeDeckGenerator.getMatrixDecks(FModel.getFormats().get("Legacy"), isAi); - } - config = ItemManagerConfig.STRING_ONLY; - break; - case VINTAGE_CARDGEN_DECK: - maxSelections = 1; - pool= new ArrayList<>(); - if(FModel.isdeckGenMatrixLoaded()) { - pool = ArchetypeDeckGenerator.getMatrixDecks(FModel.getFormats().get("Vintage"), isAi); - } - config = ItemManagerConfig.STRING_ONLY; - break; - case MODERN_COLOR_DECK: - maxSelections = 3; - pool = ColorDeckGenerator.getColorDecks(lstDecks, FModel.getFormats().getModern().getFilterPrinted(), isAi); - config = ItemManagerConfig.STRING_ONLY; - break; - case THEME_DECK: - pool = DeckProxy.getAllThemeDecks(); - config = ItemManagerConfig.STRING_ONLY; - break; - case QUEST_OPPONENT_DECK: - pool = DeckProxy.getAllQuestEventAndChallenges(); - config = ItemManagerConfig.QUEST_EVENT_DECKS; - break; - case PRECONSTRUCTED_DECK: - pool = DeckProxy.getAllPreconstructedDecks(QuestController.getPrecons()); - config = ItemManagerConfig.PRECON_DECKS; - break; - case RANDOM_DECK: - pool = RandomDeckGenerator.getRandomDecks(lstDecks, isAi); - config = ItemManagerConfig.STRING_ONLY; - break; - case NET_ARCHIVE_STANDARD_DECK: - if (NetDeckArchiveStandard != null) { - cmbDeckTypes.setText(NetDeckArchiveStandard.getDeckType()); - } - pool = DeckProxy.getNetArchiveStandardDecks(NetDeckArchiveStandard); - config = ItemManagerConfig.NET_ARCHIVE_STANDARD_DECKS; - break; - case NET_ARCHIVE_PIONEER_DECK: - if (NetDeckArchivePioneer != null) { - cmbDeckTypes.setText(NetDeckArchivePioneer.getDeckType()); - } - pool = DeckProxy.getNetArchivePioneerDecks(NetDeckArchivePioneer); - config = ItemManagerConfig.NET_ARCHIVE_PIONEER_DECKS; - break; - case NET_ARCHIVE_MODERN_DECK: - if (NetDeckArchiveModern != null) { - cmbDeckTypes.setText(NetDeckArchiveModern.getDeckType()); - } - pool = DeckProxy.getNetArchiveModernDecks(NetDeckArchiveModern); - config = ItemManagerConfig.NET_ARCHIVE_MODERN_DECKS; - break; - case NET_ARCHIVE_LEGACY_DECK: - if (NetDeckArchiveLegacy != null) { - cmbDeckTypes.setText(NetDeckArchiveLegacy.getDeckType()); - } - pool = DeckProxy.getNetArchiveLegacyDecks(NetDeckArchiveLegacy); - config = ItemManagerConfig.NET_ARCHIVE_LEGACY_DECKS; - break; - case NET_ARCHIVE_VINTAGE_DECK: - if (NetDeckArchiveVintage!= null) { - cmbDeckTypes.setText(NetDeckArchiveVintage.getDeckType()); - } - pool = DeckProxy.getNetArchiveVintageDecks(NetDeckArchiveVintage); - config = ItemManagerConfig.NET_ARCHIVE_VINTAGE_DECKS; - break; - case NET_ARCHIVE_BLOCK_DECK: - if (NetDeckArchiveBlock!= null) { - cmbDeckTypes.setText(NetDeckArchiveBlock.getDeckType()); - } - pool = DeckProxy.getNetArchiveBlockDecks(NetDeckArchiveBlock); - config = ItemManagerConfig.NET_ARCHIVE_BLOCK_DECKS; - break; - case NET_DECK: - case NET_COMMANDER_DECK: - if (netDeckCategory != null) { - cmbDeckTypes.setText(netDeckCategory.getDeckType()); - } - pool = DeckProxy.getNetDecks(netDeckCategory); - config = ItemManagerConfig.NET_DECKS; - break; - default: - BugReporter.reportBug("Unsupported deck type: " + deckType); - return; - } - - lstDecks.setSelectionSupport(1, maxSelections); - lstDecks.setPool(pool); - lstDecks.setup(config); - - if (config == ItemManagerConfig.STRING_ONLY) { - //hide edit/view buttons for string-only lists - if (Forge.isLandscapeMode()) { - btnNewDeck.setWidth((getWidth() - 3 * PADDING) / 2); - } - else { - btnNewDeck.setWidth(getWidth() - 2 * PADDING); - } - btnEditDeck.setVisible(false); - btnViewDeck.setVisible(false); - btnRandom.setWidth(btnNewDeck.getWidth()); - - btnNewDeck.setText(localizer.getMessage("lblGenerateNewDeck")); - switch (deckType) { - case COLOR_DECK: - btnRandom.setText(localizer.getMessage("lblRandomColors")); - break; - case THEME_DECK: - btnRandom.setText(localizer.getMessage("lblRandomTheme")); - break; - default: - btnRandom.setText(localizer.getMessage("lblRandomDeck")); - break; - } - } - else { - btnNewDeck.setWidth(btnEditDeck.getWidth()); - btnEditDeck.setVisible(true); - btnViewDeck.setVisible(true); - btnRandom.setWidth(btnNewDeck.getWidth()); - - btnNewDeck.setText(localizer.getMessage("lblNewDeck")); - - if (lstDecks.getGameType() == GameType.DeckManager) { - //handle special case of Deck Editor screen where this button will start a game with the deck - btnRandom.setText(localizer.getMessage("lblTestDeck")); - - switch (selectedDeckType) { - case SCHEME_DECK: - case PLANAR_DECK: //don't allow testing secondary decks this way - btnRandom.setEnabled(false); - break; - default: - btnRandom.setEnabled(true); - break; - } - } - else { - btnRandom.setText(localizer.getMessage("lblRandomDeck")); - } - } - - btnRandom.setLeft(getWidth() - PADDING - btnRandom.getWidth()); - - if (e != null) { //set default list selection if from combo box change event - if (deckType == DeckType.COLOR_DECK) { - // default selection = basic two color deck - lstDecks.setSelectedIndices(new Integer[]{0, 1}); - } - else { - lstDecks.setSelectedIndex(0); - } - if (lstDecks.getGameType() == GameType.DeckManager) { - DeckPreferences.setSelectedDeckType(deckType); //update saved Deck Manager type - } - } - } - - @Override - protected void doLayout(float startY, float width, float height) { - float x = PADDING; - float y = startY + PADDING; - width -= 2 * x; - - float fieldHeight = cmbDeckTypes.getHeight(); - float totalButtonHeight; - boolean landscapeMode = Forge.isLandscapeMode(); - if (landscapeMode) { - totalButtonHeight = fieldHeight; - } - else { - totalButtonHeight = 2 * fieldHeight + PADDING; - } - - cmbDeckTypes.setBounds(x, y, width, fieldHeight); - y += cmbDeckTypes.getHeight() + 1; - lstDecks.setBounds(x, y, width, height - y - totalButtonHeight - 2 * PADDING); //leave room for buttons at bottom - - y += lstDecks.getHeight() + PADDING; - float buttonWidth; - if (landscapeMode) { - buttonWidth = (width - 3 * PADDING) / 4; - } - else { - buttonWidth = (width - PADDING) / 2; - } - - if (btnEditDeck.isVisible()) { - btnNewDeck.setBounds(x, y, buttonWidth, fieldHeight); - } - else if (landscapeMode) { - btnNewDeck.setBounds(x, y, 2 * buttonWidth + PADDING, fieldHeight); - } - else { - btnNewDeck.setBounds(x, y, width, fieldHeight); - } - btnEditDeck.setBounds(x + buttonWidth + PADDING, y, buttonWidth, fieldHeight); - if (landscapeMode) { - x += 2 * (buttonWidth + PADDING); - } - else { - y += fieldHeight + PADDING; - } - - btnViewDeck.setBounds(x, y, buttonWidth, fieldHeight); - if (btnViewDeck.isVisible()) { - btnRandom.setBounds(x + buttonWidth + PADDING, y, buttonWidth, fieldHeight); - } - else if (landscapeMode) { - btnRandom.setBounds(x, y, 2 * buttonWidth + PADDING, fieldHeight); - } - else { - btnRandom.setBounds(x, y, width, fieldHeight); - } - } - - public DeckType getSelectedDeckType() { return selectedDeckType; } - public void setSelectedDeckType(DeckType selectedDeckType0) { - refreshDecksList(selectedDeckType0, false, null); - } - - public DeckManager getLstDecks() { return lstDecks; } - - public Deck getDeck() { - /*if(selectedDeckType.equals(DeckType.STANDARD_CARDGEN_DECK)){ - return DeckgenUtil.buildCardGenDeck(lstDecks.getSelectedItem().getName()); - }*/ - //ensure a deck is selected first - if(lstDecks.getSelectedIndex() == -1){ - lstDecks.setSelectedIndex(0); - } - DeckProxy proxy = lstDecks.getSelectedItem(); - if (proxy == null) { return null; } - return proxy.getDeck(); - } - - /** Generates deck from current list selection(s). */ - public RegisteredPlayer getPlayer(boolean forceRefresh) { - if (player != null && !forceRefresh) { - return player; - } - - if (lstDecks.getSelectedIndex() < 0) { - player = null; - } - else if (selectedDeckType == DeckType.QUEST_OPPONENT_DECK) { - //Special branch for quest events - QuestEvent event = DeckgenUtil.getQuestEvent(lstDecks.getSelectedItem().getName()); - player = new RegisteredPlayer(event.getEventDeck()); - if (event instanceof QuestEventChallenge) { - player.setStartingLife(((QuestEventChallenge) event).getAiLife()); - } - player.setCardsOnBattlefield(QuestUtil.getComputerStartingCards(event)); - } - else { - player = new RegisteredPlayer(getDeck()); - } - return player; - } - - public final boolean isAi() { - return isAi; - } - - public void setIsAi(boolean isAiDeck) { - isAi = isAiDeck; - } - - private final String SELECTED_DECK_DELIMITER = "::"; - - public void saveState() { - if (stateSetting == null) { - throw new NullPointerException("State setting missing. Specify first using the initialize() method."); - } - prefs.setPref(stateSetting, getState()); - prefs.save(); - } - - private String getState() { - StringBuilder state = new StringBuilder(); - if (cmbDeckTypes.getSelectedItem() == null || cmbDeckTypes.getSelectedItem() == DeckType.NET_DECK) { - //handle special case of net decks - if (netDeckCategory == null) { return ""; } - state.append(NetDeckCategory.PREFIX).append(netDeckCategory.getName()); - } - else { - state.append(cmbDeckTypes.getSelectedItem().name()); - } - state.append(";"); - joinSelectedDecks(state, SELECTED_DECK_DELIMITER); - return state.toString(); - } - - private void joinSelectedDecks(StringBuilder state, String delimiter) { - Iterable selectedDecks = lstDecks.getSelectedItems(); - boolean isFirst = true; - if (selectedDecks != null) { - for (DeckProxy deck : selectedDecks) { - if (isFirst) { - isFirst = false; - } - else { - state.append(delimiter); - } - state.append(deck.toString()); - } - } - } - - private void restoreSavedState() { - DeckType oldDeckType = selectedDeckType; - if (stateSetting == null) { - //if can't restore saved state, just refresh deck list - refreshDecksList(oldDeckType, true, null); - return; - } - - String savedState = prefs.getPref(stateSetting); - refreshDecksList(getDeckTypeFromSavedState(savedState), true, null); - if (!lstDecks.setSelectedStrings(getSelectedDecksFromSavedState(savedState))) { - //if can't select old decks, just refresh deck list - refreshDecksList(oldDeckType, true, null); - } - } - - private DeckType getDeckTypeFromSavedState(String savedState) { - try { - if (StringUtils.isBlank(savedState)) { - return selectedDeckType; - } - else { - String deckType = savedState.split(";")[0]; - if (deckType.startsWith(NetDeckCategory.PREFIX)) { - netDeckCategory = NetDeckCategory.selectAndLoad(lstDecks.getGameType(), deckType.substring(NetDeckCategory.PREFIX.length())); - return DeckType.NET_DECK; - } - if (deckType.startsWith(forge.deck.NetDeckArchiveStandard.PREFIX)) { - NetDeckArchiveStandard = forge.deck.NetDeckArchiveStandard.selectAndLoad(lstDecks.getGameType(), deckType.substring(forge.deck.NetDeckArchiveStandard.PREFIX.length())); - return DeckType.NET_ARCHIVE_STANDARD_DECK; - } - if (deckType.startsWith(forge.deck.NetDeckArchivePioneer.PREFIX)) { - NetDeckArchivePioneer = forge.deck.NetDeckArchivePioneer.selectAndLoad(lstDecks.getGameType(), deckType.substring(forge.deck.NetDeckArchivePioneer.PREFIX.length())); - return DeckType.NET_ARCHIVE_PIONEER_DECK; - } - if (deckType.startsWith(forge.deck.NetDeckArchiveModern.PREFIX)) { - NetDeckArchiveModern = forge.deck.NetDeckArchiveModern.selectAndLoad(lstDecks.getGameType(), deckType.substring(forge.deck.NetDeckArchiveModern.PREFIX.length())); - return DeckType.NET_ARCHIVE_MODERN_DECK; - } - if (deckType.startsWith(forge.deck.NetDeckArchiveLegacy.PREFIX)) { - NetDeckArchiveLegacy = forge.deck.NetDeckArchiveLegacy.selectAndLoad(lstDecks.getGameType(), deckType.substring(forge.deck.NetDeckArchiveLegacy.PREFIX.length())); - return DeckType.NET_ARCHIVE_LEGACY_DECK; - } - if (deckType.startsWith(forge.deck.NetDeckArchiveVintage.PREFIX)) { - NetDeckArchiveVintage = forge.deck.NetDeckArchiveVintage.selectAndLoad(lstDecks.getGameType(), deckType.substring(forge.deck.NetDeckArchiveVintage.PREFIX.length())); - return DeckType.NET_ARCHIVE_VINTAGE_DECK; - } - if (deckType.startsWith(forge.deck.NetDeckArchiveBlock.PREFIX)) { - NetDeckArchiveBlock = forge.deck.NetDeckArchiveBlock.selectAndLoad(lstDecks.getGameType(), deckType.substring(forge.deck.NetDeckArchiveBlock.PREFIX.length())); - return DeckType.NET_ARCHIVE_BLOCK_DECK; - } - return DeckType.valueOf(deckType); - } - } - catch (IllegalArgumentException ex) { - System.err.println(ex.getMessage() + ". Using default : " + selectedDeckType); - return selectedDeckType; - } - } - - private List getSelectedDecksFromSavedState(String savedState) { - try { - if (StringUtils.isBlank(savedState)) { - return new ArrayList<>(); - } - else { - return Arrays.asList(savedState.split(";")[1].split(SELECTED_DECK_DELIMITER)); - } - } - catch (Exception ex) { - System.err.println(ex + " [savedState=" + savedState + "]"); - return new ArrayList<>(); - } - } - - public FComboBox getDecksComboBox() { - return cmbDeckTypes; - } - - //create quick gauntlet for testing deck - private void testSelectedDeck() { - final DeckProxy deckProxy = lstDecks.getSelectedItem(); - if (deckProxy == null) { return; } - final Deck userDeck = deckProxy.getDeck(); - if (userDeck == null) { return; } - - if (selectedDeckType == DeckType.COMMANDER_DECK || selectedDeckType == DeckType.NET_COMMANDER_DECK) { - //cannot create gauntlet for commander decks, so just start single match - testVariantDeck(userDeck, GameType.Commander); - return; - } - - if (selectedDeckType == DeckType.OATHBREAKER_DECK) { - //cannot create gauntlet for oathbreaker decks, so just start single match - testVariantDeck(userDeck, GameType.Oathbreaker); - return; - } - - if (selectedDeckType == DeckType.TINY_LEADERS_DECK) { - //cannot create gauntlet for tiny leaders decks, so just start single match - testVariantDeck(userDeck, GameType.TinyLeaders); - return; - } - - if (selectedDeckType == DeckType.BRAWL_DECK) { - //cannot create gauntlet for tiny leaders decks, so just start single match - testVariantDeck(userDeck, GameType.Brawl); - return; - } - - GuiChoose.getInteger(localizer.getMessage("lblHowManyOpponents"), 1, 50, new Callback() { - @Override - public void run(final Integer numOpponents) { - if (numOpponents == null) { return; } - List deckTypes = Arrays.asList( - DeckType.CUSTOM_DECK, - DeckType.PRECONSTRUCTED_DECK, - DeckType.QUEST_OPPONENT_DECK, - DeckType.COLOR_DECK, - DeckType.STANDARD_COLOR_DECK, - DeckType.STANDARD_CARDGEN_DECK, - DeckType.MODERN_COLOR_DECK, - DeckType.PIONEER_CARDGEN_DECK, - DeckType.HISTORIC_CARDGEN_DECK, - DeckType.MODERN_CARDGEN_DECK, - DeckType.LEGACY_CARDGEN_DECK, - DeckType.VINTAGE_CARDGEN_DECK, - DeckType.THEME_DECK, - DeckType.NET_DECK, - DeckType.NET_ARCHIVE_STANDARD_DECK, - DeckType.NET_ARCHIVE_PIONEER_DECK, - DeckType.NET_ARCHIVE_MODERN_DECK, - DeckType.NET_ARCHIVE_VINTAGE_DECK, - DeckType.NET_ARCHIVE_LEGACY_DECK - - ); - if (!FModel.isdeckGenMatrixLoaded()) { - deckTypes.remove(DeckType.STANDARD_CARDGEN_DECK); - deckTypes.remove(DeckType.PIONEER_CARDGEN_DECK); - deckTypes.remove(DeckType.HISTORIC_CARDGEN_DECK); - deckTypes.remove(DeckType.MODERN_CARDGEN_DECK); - deckTypes.remove(DeckType.LEGACY_CARDGEN_DECK); - deckTypes.remove(DeckType.VINTAGE_CARDGEN_DECK); - } - - ListChooser chooser = new ListChooser<>( - localizer.getMessage("lblChooseAllowedDeckTypeOpponents"), 0, deckTypes.size(), deckTypes, null, new Callback>() { - @Override - public void run(final List allowedDeckTypes) { - if (allowedDeckTypes == null || allowedDeckTypes.isEmpty()) { - return; - } - - FThreads.invokeInBackgroundThread(new Runnable() { //needed for loading net decks - @Override - public void run() { - final NetDeckCategory netCat; - if (allowedDeckTypes.contains(DeckType.NET_DECK)) { - netCat = NetDeckCategory.selectAndLoad(GameType.Constructed); - } else { - netCat = null; - } - - FThreads.invokeInEdtLater(new Runnable() { - @Override - public void run() { - LoadingOverlay.show(localizer.getMessage("lblLoadingNewGame"), new Runnable() { - @Override - public void run() { - GauntletData gauntlet = GauntletUtil.createQuickGauntlet(userDeck, numOpponents, allowedDeckTypes, netCat); - FModel.setGauntletData(gauntlet); - - List players = new ArrayList<>(); - RegisteredPlayer humanPlayer = new RegisteredPlayer(userDeck).setPlayer(GamePlayerUtil.getGuiPlayer()); - players.add(humanPlayer); - players.add(new RegisteredPlayer(gauntlet.getDecks().get(gauntlet.getCompleted())).setPlayer(GamePlayerUtil.createAiPlayer())); - - gauntlet.startRound(players, humanPlayer); - } - }); - } - }); - } - }); - } - }); - chooser.show(null, false); /*setting selectMax to true will select all available option*/ - } - }); - } - - private void testVariantDeck(final Deck userDeck, final GameType variant) { - promptForDeck(localizer.getMessage("lblSelectOpponentDeck"), variant, true, new Callback() { - @Override - public void run(final Deck aiDeck) { - if (aiDeck == null) { return; } - - LoadingOverlay.show(localizer.getMessage("lblLoadingNewGame"), new Runnable() { - @Override - public void run() { - Set appliedVariants = new HashSet<>(); - appliedVariants.add(variant); - - List players = new ArrayList<>(); - RegisteredPlayer humanPlayer = RegisteredPlayer.forVariants(2, appliedVariants, userDeck, null, false, null, null); - humanPlayer.setPlayer(GamePlayerUtil.getGuiPlayer()); - RegisteredPlayer aiPlayer = RegisteredPlayer.forVariants(2, appliedVariants, aiDeck, null, false, null, null); - aiPlayer.setPlayer(GamePlayerUtil.createAiPlayer()); - players.add(humanPlayer); - players.add(aiPlayer); - - final Map guiMap = new HashMap<>(); - guiMap.put(humanPlayer, MatchController.instance); - - final HostedMatch hostedMatch = GuiBase.getInterface().hostMatch(); - hostedMatch.startMatch(GameType.Constructed, appliedVariants, players, guiMap); - } - }); - } - }); - } - - @Override - protected boolean allowBackInLandscapeMode() { - return true; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FDeckEditor.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FDeckEditor.java deleted file mode 100644 index 7ca0fb84b2a..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FDeckEditor.java +++ /dev/null @@ -1,1887 +0,0 @@ -package forge.adventure.libgdxgui.deck; - -import com.badlogic.gdx.Input.Keys; -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.utils.Align; -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import com.google.common.base.Supplier; -import com.google.common.collect.ImmutableList; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Forge.KeyInputAdapter; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.*; -import forge.adventure.libgdxgui.itemmanager.CardManager; -import forge.adventure.libgdxgui.itemmanager.ItemManager.ContextMenuBuilder; -import forge.adventure.libgdxgui.itemmanager.filters.ItemFilter; -import forge.adventure.libgdxgui.menu.FCheckBoxMenuItem; -import forge.adventure.libgdxgui.menu.FDropDownMenu; -import forge.adventure.libgdxgui.menu.FMenuItem; -import forge.adventure.libgdxgui.menu.FPopupMenu; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.screens.LoadingOverlay; -import forge.adventure.libgdxgui.screens.TabPageScreen; -import forge.adventure.libgdxgui.toolbox.*; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventType; -import forge.adventure.libgdxgui.util.Utils; -import forge.card.CardDb; -import forge.card.CardEdition; -import forge.deck.*; -import forge.deck.io.DeckPreferences; -import forge.gamemodes.limited.BoosterDraft; -import forge.gamemodes.planarconquest.ConquestUtil; -import forge.gui.FThreads; -import forge.gui.card.CardPreferences; -import forge.item.PaperCard; -import forge.itemmanager.ColumnDef; -import forge.itemmanager.ItemColumn; -import forge.itemmanager.ItemManagerConfig; -import forge.localinstance.properties.ForgePreferences.FPref; -import forge.model.FModel; -import forge.util.Callback; -import forge.util.ItemPool; -import forge.util.Lang; -import forge.util.Localizer; -import forge.util.storage.IStorage; -import org.apache.commons.lang3.StringUtils; - -import java.util.*; -import java.util.Map.Entry; - -public class FDeckEditor extends TabPageScreen { - public static FSkinImage MAIN_DECK_ICON = Forge.hdbuttons ? FSkinImage.HDLIBRARY :FSkinImage.DECKLIST; - public static FSkinImage SIDEBOARD_ICON = Forge.hdbuttons ? FSkinImage.HDSIDEBOARD : FSkinImage.FLASHBACK; - private static final float HEADER_HEIGHT = Math.round(Utils.AVG_FINGER_HEIGHT * 0.8f); - - public enum EditorType { - Constructed(new DeckController<>(FModel.getDecks().getConstructed(), new Supplier() { - @Override - public Deck get() { - return new Deck(); - } - }), null), - Draft(new DeckController<>(FModel.getDecks().getDraft(), new Supplier() { - @Override - public DeckGroup get() { - return new DeckGroup(""); - } - }), null), - Sealed(new DeckController<>(FModel.getDecks().getSealed(), new Supplier() { - @Override - public DeckGroup get() { - return new DeckGroup(""); - } - }), null), - Winston(new DeckController<>(FModel.getDecks().getWinston(), new Supplier() { - @Override - public DeckGroup get() { - return new DeckGroup(""); - } - }), null), - Commander(new DeckController<>(FModel.getDecks().getCommander(), new Supplier() { - @Override - public Deck get() { - return new Deck(); - } - }), null), - Oathbreaker(new DeckController<>(FModel.getDecks().getOathbreaker(), new Supplier() { - @Override - public Deck get() { - return new Deck(); - } - }), null), - TinyLeaders(new DeckController<>(FModel.getDecks().getTinyLeaders(), new Supplier() { - @Override - public Deck get() { - return new Deck(); - } - }), DeckFormat.TinyLeaders.isLegalCardPredicate()), - Brawl(new DeckController<>(FModel.getDecks().getBrawl(), new Supplier() { - @Override - public Deck get() { - return new Deck(); - } - }), DeckFormat.Brawl.isLegalCardPredicate()), - Archenemy(new DeckController<>(FModel.getDecks().getScheme(), new Supplier() { - @Override - public Deck get() { - return new Deck(); - } - }), null), - Planechase(new DeckController<>(FModel.getDecks().getPlane(), new Supplier() { - @Override - public Deck get() { - return new Deck(); - } - }), null), - Quest(new DeckController<>(null, new Supplier() { //delay setting root folder until quest loaded - @Override - public Deck get() { - return new Deck(); - } - }), null), - QuestCommander(new DeckController<>(null, new Supplier() { //delay setting root folder until quest loaded - @Override - public Deck get() { - return new Deck(); - } - }), null), - QuestDraft(new DeckController<>(null, new Supplier() { //delay setting root folder until quest loaded - @Override - public DeckGroup get() { - return new DeckGroup(""); - } - }), null), - PlanarConquest(new DeckController<>(null, new Supplier() { //delay setting root folder until conquest loaded - @Override - public Deck get() { - return new Deck(); - } - }), null); - - private final DeckController controller; - private final Predicate cardFilter; - - public DeckController getController() { - return controller; - } - - EditorType(DeckController controller0, Predicate cardFilter0) { - controller = controller0; - cardFilter = cardFilter0; - } - - private ItemPool applyCardFilter(ItemPool cardPool, Predicate additionalFilter) { - Predicate filter = cardFilter; - if (filter == null) { - filter = additionalFilter; - if (filter == null) { - return cardPool; - } - } - else if (additionalFilter != null) { - filter = Predicates.and(filter, additionalFilter); - } - - ItemPool filteredPool = new ItemPool<>(PaperCard.class); - for (Entry entry : cardPool) { - if (filter.apply(entry.getKey())) { - filteredPool.add(entry.getKey(), entry.getValue()); - } - } - return filteredPool; - } - } - - private static DeckEditorPage[] getPages(EditorType editorType) { - final Localizer localizer = Localizer.getInstance(); - boolean isLandscape = Forge.isLandscapeMode(); - switch (editorType) { - default: - case Constructed: - return new DeckEditorPage[] { - new CatalogPage(ItemManagerConfig.CARD_CATALOG), - new DeckSectionPage(DeckSection.Main), - new DeckSectionPage(DeckSection.Sideboard) - }; - case Draft: - case QuestDraft: - return new DeckEditorPage[] { - new DraftPackPage(), - new DeckSectionPage(DeckSection.Main), - new DeckSectionPage(DeckSection.Sideboard, ItemManagerConfig.DRAFT_POOL) - }; - case Sealed: - return new DeckEditorPage[] { - new DeckSectionPage(DeckSection.Main), - new DeckSectionPage(DeckSection.Sideboard, ItemManagerConfig.SEALED_POOL) - }; - case Commander: - case TinyLeaders: - case Brawl: - return isLandscape ? new DeckEditorPage[] { - new CatalogPage(ItemManagerConfig.CARD_CATALOG), - new DeckSectionPage(DeckSection.Commander, ItemManagerConfig.COMMANDER_SECTION), - new DeckSectionPage(DeckSection.Main), - new DeckSectionPage(DeckSection.Sideboard) - } : new DeckEditorPage[] { - new CatalogPage(ItemManagerConfig.CARD_CATALOG), - new DeckSectionPage(DeckSection.Main), - new DeckSectionPage(DeckSection.Commander, ItemManagerConfig.COMMANDER_SECTION), - new DeckSectionPage(DeckSection.Sideboard) - }; - case Oathbreaker: - return isLandscape ? new DeckEditorPage[] { - new CatalogPage(ItemManagerConfig.CARD_CATALOG), - new DeckSectionPage(DeckSection.Commander, ItemManagerConfig.OATHBREAKER_SECTION, localizer.getMessage("lblOathbreaker"), FSkinImage.COMMANDER), - new DeckSectionPage(DeckSection.Main), - new DeckSectionPage(DeckSection.Sideboard) - } : new DeckEditorPage[] { - new CatalogPage(ItemManagerConfig.CARD_CATALOG), - new DeckSectionPage(DeckSection.Main), - new DeckSectionPage(DeckSection.Commander, ItemManagerConfig.OATHBREAKER_SECTION, localizer.getMessage("lblOathbreaker"), FSkinImage.COMMANDER), - new DeckSectionPage(DeckSection.Sideboard) - }; - case Archenemy: - return new DeckEditorPage[] { - new CatalogPage(ItemManagerConfig.SCHEME_POOL), - new DeckSectionPage(DeckSection.Schemes, ItemManagerConfig.SCHEME_DECK_EDITOR) - }; - case Planechase: - return new DeckEditorPage[] { - new CatalogPage(ItemManagerConfig.PLANAR_POOL), - new DeckSectionPage(DeckSection.Planes, ItemManagerConfig.PLANAR_DECK_EDITOR) - }; - case Quest: - return new DeckEditorPage[] { - new CatalogPage(ItemManagerConfig.QUEST_EDITOR_POOL, localizer.getMessage("lblInventory"), FSkinImage.QUEST_BOX), - new DeckSectionPage(DeckSection.Main, ItemManagerConfig.QUEST_DECK_EDITOR), - new DeckSectionPage(DeckSection.Sideboard, ItemManagerConfig.QUEST_DECK_EDITOR) - }; - case QuestCommander: - return isLandscape ? new DeckEditorPage[] { - new CatalogPage(ItemManagerConfig.QUEST_EDITOR_POOL, localizer.getMessage("lblInventory"), FSkinImage.QUEST_BOX), - new DeckSectionPage(DeckSection.Commander, ItemManagerConfig.COMMANDER_SECTION), - new DeckSectionPage(DeckSection.Main, ItemManagerConfig.QUEST_DECK_EDITOR) - } : new DeckEditorPage[] { - new CatalogPage(ItemManagerConfig.QUEST_EDITOR_POOL, localizer.getMessage("lblInventory"), FSkinImage.QUEST_BOX), - new DeckSectionPage(DeckSection.Main, ItemManagerConfig.QUEST_DECK_EDITOR), - new DeckSectionPage(DeckSection.Commander, ItemManagerConfig.COMMANDER_SECTION) - }; - case PlanarConquest: - return isLandscape ? new DeckEditorPage[] { - new CatalogPage(ItemManagerConfig.CONQUEST_COLLECTION, localizer.getMessage("lblCollection"), FSkinImage.SPELLBOOK), - new DeckSectionPage(DeckSection.Commander, ItemManagerConfig.COMMANDER_SECTION), - new DeckSectionPage(DeckSection.Main, ItemManagerConfig.CONQUEST_DECK_EDITOR, localizer.getMessage("lblDeck"), Forge.hdbuttons ? FSkinImage.HDLIBRARY : FSkinImage.DECKLIST) - } : new DeckEditorPage[] { - new CatalogPage(ItemManagerConfig.CONQUEST_COLLECTION, localizer.getMessage("lblCollection"), FSkinImage.SPELLBOOK), - new DeckSectionPage(DeckSection.Main, ItemManagerConfig.CONQUEST_DECK_EDITOR, localizer.getMessage("lblDeck"), Forge.hdbuttons ? FSkinImage.HDLIBRARY : FSkinImage.DECKLIST), - new DeckSectionPage(DeckSection.Commander, ItemManagerConfig.COMMANDER_SECTION) - }; - } - } - - private final EditorType editorType; - private Deck deck; - private CatalogPage catalogPage; - private DeckSectionPage mainDeckPage; - private DeckSectionPage sideboardPage; - private DeckSectionPage commanderPage; - private FEventHandler saveHandler; - - protected final DeckHeader deckHeader = add(new DeckHeader()); - protected final FLabel lblName = deckHeader.add(new FLabel.Builder().font(FSkinFont.get(16)).insets(new Vector2(Utils.scale(5), 0)).build()); - private final FLabel btnSave = deckHeader.add(new FLabel.Builder().icon(Forge.hdbuttons ? FSkinImage.HDSAVE : FSkinImage.SAVE).align(Align.center).pressedColor(Header.BTN_PRESSED_COLOR).build()); - private final FLabel btnMoreOptions = deckHeader.add(new FLabel.Builder().text("...").font(FSkinFont.get(20)).align(Align.center).pressedColor(Header.BTN_PRESSED_COLOR).build()); - - public FDeckEditor(EditorType editorType0, DeckProxy editDeck, boolean showMainDeck) { - this(editorType0, editDeck.getName(), editDeck.getPath(), null, showMainDeck); - } - public FDeckEditor(EditorType editorType0, String editDeckName, boolean showMainDeck) { - this(editorType0, editDeckName, "", null, showMainDeck); - } - public FDeckEditor(EditorType editorType0, Deck newDeck, boolean showMainDeck) { - this(editorType0, "", "", newDeck, showMainDeck); - } - private FDeckEditor(EditorType editorType0, String editDeckName, String editDeckPath, Deck newDeck, boolean showMainDeck) { - super(getPages(editorType0)); - - if (editorType0 == EditorType.QuestCommander) //fix saving quest commander - editorType = EditorType.Quest; - else - editorType = editorType0; - - editorType.getController().editor = this; - - //cache specific pages - for (TabPage tabPage : tabPages) { - if (tabPage instanceof CatalogPage) { - catalogPage = (CatalogPage) tabPage; - } - else if (tabPage instanceof DeckSectionPage) { - DeckSectionPage deckSectionPage = (DeckSectionPage) tabPage; - switch (deckSectionPage.deckSection) { - case Main: - case Schemes: - case Planes: - mainDeckPage = deckSectionPage; - break; - case Sideboard: - sideboardPage = deckSectionPage; - break; - case Commander: - commanderPage = deckSectionPage; - break; - default: - break; - } - } - } - - switch (editorType) { - case Sealed: - //if opening brand new sealed deck, show sideboard (card pool) by default - if (!showMainDeck) { - setSelectedPage(sideboardPage); - } - break; - case Draft: - case QuestDraft: - break; - default: - //if editing existing non-limited deck, show main deck by default - if (showMainDeck) { - setSelectedPage(mainDeckPage); - } - break; - } - - if (StringUtils.isEmpty(editDeckName)) { - if (editorType == EditorType.Draft || editorType == EditorType.QuestDraft) { - //hide deck header on while drafting - setDeck(new Deck()); - deckHeader.setVisible(false); - } - else { - if (newDeck == null) { - editorType.getController().newModel(); - } - else { - editorType.getController().setDeck(newDeck); - } - } - } - else { - if (editorType == EditorType.Draft || editorType == EditorType.QuestDraft) { - tabPages[0].hideTab(); //hide Draft Pack page if editing existing draft deck - } - editorType.getController().load(editDeckPath, editDeckName); - } - - btnSave.setCommand(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - save(null); - } - }); - btnMoreOptions.setCommand(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - FPopupMenu menu = new FPopupMenu() { - @Override - protected void buildMenu() { - final Localizer localizer = Localizer.getInstance(); - - addItem(new FMenuItem(localizer.getMessage("lblAddBasicLands"), FSkinImage.LANDLOGO, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - CardEdition defaultLandSet; - switch (editorType) { - case Draft: - case Sealed: - case QuestDraft: - //suggest a random set from the ones used in the limited card pool that have all basic lands - Set availableEditionCodes = new HashSet<>(); - for (PaperCard p : deck.getAllCardsInASinglePool().toFlatList()) { - availableEditionCodes.add(FModel.getMagicDb().getEditions().get(p.getEdition())); - } - defaultLandSet = CardEdition.Predicates.getRandomSetWithAllBasicLands(availableEditionCodes); - break; - case Quest: - defaultLandSet = FModel.getQuest().getDefaultLandSet(); - break; - default: - defaultLandSet = DeckProxy.getDefaultLandSet(deck); - break; - } - AddBasicLandsDialog dialog = new AddBasicLandsDialog(deck, defaultLandSet, new Callback() { - @Override - public void run(CardPool landsToAdd) { - getMainDeckPage().addCards(landsToAdd); - } - }); - dialog.show(); - setSelectedPage(getMainDeckPage()); //select main deck page if needed so main deck is visible below dialog - } - })); - if (!isLimitedEditor()) { - addItem(new FMenuItem(localizer.getMessage("lblImportFromClipboard"), Forge.hdbuttons ? FSkinImage.HDIMPORT : FSkinImage.OPEN, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - FDeckImportDialog dialog = new FDeckImportDialog(!deck.isEmpty(), new Callback() { - @Override - public void run(Deck importedDeck) { - getMainDeckPage().setCards(importedDeck.getMain()); - if (getSideboardPage() != null) { - getSideboardPage().setCards(importedDeck.getOrCreate(DeckSection.Sideboard)); - } - if (getCommanderPage() != null) { - getCommanderPage().setCards(importedDeck.getOrCreate(DeckSection.Commander)); - } - } - }); - dialog.show(); - setSelectedPage(getMainDeckPage()); //select main deck page if needed so main deck if visible below dialog - } - })); - addItem(new FMenuItem(localizer.getMessage("lblSaveAs"), Forge.hdbuttons ? FSkinImage.HDSAVEAS : FSkinImage.SAVEAS, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - String defaultName = editorType.getController().getNextAvailableName(); - FOptionPane.showInputDialog(localizer.getMessage("lblNameNewCopyDeck"), defaultName, new Callback() { - @Override - public void run(String result) { - if (!StringUtils.isEmpty(result)) { - editorType.getController().saveAs(result); - } - } - }); - } - })); - } - if (allowRename()) { - addItem(new FMenuItem(localizer.getMessage("lblRenameDeck"), Forge.hdbuttons ? FSkinImage.HDEDIT : FSkinImage.EDIT, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - FOptionPane.showInputDialog(localizer.getMessage("lblNewNameDeck"), deck.getName(), new Callback() { - @Override - public void run(String result) { - editorType.getController().rename(result); - } - }); - } - })); - } - if (allowDelete()) { - addItem(new FMenuItem(localizer.getMessage("lblDeleteDeck"), Forge.hdbuttons ? FSkinImage.HDDELETE : FSkinImage.DELETE, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - FOptionPane.showConfirmDialog( - localizer.getMessage("lblConfirmDelete") + " '" + deck.getName() + "'?", - localizer.getMessage("lblDeleteDeck"), localizer.getMessage("lblDelete"), localizer.getMessage("lblCancel"), false, new Callback() { - @Override - public void run(Boolean result) { - if (result) { - editorType.getController().delete(); - Forge.back(); - } - } - }); - } - })); - } - addItem(new FMenuItem(localizer.getMessage("btnCopyToClipboard"), Forge.hdbuttons ? FSkinImage.HDEXPORT : FSkinImage.BLANK, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - FDeckViewer.copyDeckToClipboard(deck); - } - })); - ((DeckEditorPage)getSelectedPage()).buildDeckMenu(this); - } - }; - menu.show(btnMoreOptions, 0, btnMoreOptions.getHeight()); - } - }); - } - - protected boolean allowRename() { - return true; - } - protected boolean allowDelete() { - return true; - } - - @Override - protected void doLayout(float startY, float width, float height) { - if (deckHeader.isVisible()) { - deckHeader.setBounds(0, startY, width, HEADER_HEIGHT); - startY += HEADER_HEIGHT; - } - super.doLayout(startY, width, height); - } - - public EditorType getEditorType() { - return editorType; - } - - public Deck getDeck() { - return deck; - } - public void setDeck(Deck deck0) { - if (deck == deck0) { return; } - deck = deck0; - if (deck == null) { return; } - - //reinitialize tab pages when deck changes - for (TabPage tabPage : tabPages) { - ((DeckEditorPage)tabPage).initialize(); - } - } - - protected CatalogPage getCatalogPage() { - return catalogPage; - } - - protected DeckSectionPage getMainDeckPage() { - return mainDeckPage; - } - - protected DeckSectionPage getSideboardPage() { - return sideboardPage; - } - - protected DeckSectionPage getCommanderPage() { - return commanderPage; - } - - protected BoosterDraft getDraft() { - return null; - } - - private enum CardLimit { - Singleton, - Default, - None - } - private CardLimit getCardLimit() { - switch (editorType) { - case Constructed: - case Planechase: - case Archenemy: - case Quest: - default: - if (FModel.getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY)) { - return CardLimit.Default; - } - return CardLimit.None; //if not enforcing deck legality, don't enforce default limit - case Draft: - case Sealed: - case Winston: - case QuestDraft: - return CardLimit.None; - case Commander: - case QuestCommander: - case Oathbreaker: - case TinyLeaders: - case Brawl: - case PlanarConquest: - return CardLimit.Singleton; - } - } - - public void setSaveHandler(FEventHandler saveHandler0) { - saveHandler = saveHandler0; - } - - protected void save(final Callback callback) { - if (StringUtils.isEmpty(deck.getName())) { - List commanders = deck.getCommanders(); //use commander name as default deck name - String initialInput = Lang.joinHomogenous(commanders); - final Localizer localizer = Localizer.getInstance(); - FOptionPane.showInputDialog(localizer.getMessage("lblNameNewDeck"), initialInput, new Callback() { - @Override - public void run(String result) { - if (StringUtils.isEmpty(result)) { return; } - - editorType.getController().saveAs(result); - if (callback != null) { - callback.run(true); - } - } - }); - return; - } - - editorType.getController().save(); - if (callback != null) { - callback.run(true); - } - } - - private final static ImmutableList onCloseOptions = ImmutableList.of( - Localizer.getInstance().getMessage("lblSave"), - Localizer.getInstance().getMessage("lblDontSave"), - Localizer.getInstance().getMessage("lblCancel") - ); - - @Override - public void onClose(final Callback canCloseCallback) { - if (editorType.getController().isSaved() || canCloseCallback == null) { - super.onClose(canCloseCallback); //can skip prompt if draft saved - return; - } - final Localizer localizer = Localizer.getInstance(); - FOptionPane.showOptionDialog(localizer.getMessage("lblSaveChangesCurrentDeck"), "", - FOptionPane.QUESTION_ICON, onCloseOptions, new Callback() { - @Override - public void run(Integer result) { - if (result == 0) { - save(canCloseCallback); - } - else if (result == 1) { - editorType.getController().reload(); //reload if not saving changes - canCloseCallback.run(true); - } - else { - canCloseCallback.run(false); - } - } - }); - } - - @Override - public boolean keyDown(int keyCode) { - switch (keyCode) { - case Keys.BACK: - return true; //suppress Back button so it's not bumped while editing deck - case Keys.S: //save deck on Ctrl+S - if (KeyInputAdapter.isCtrlKeyDown()) { - save(null); - return true; - } - break; - } - return super.keyDown(keyCode); - } - - @Override - public FScreen getLandscapeBackdropScreen() { - return null; //never use backdrop for editor - } - - private boolean isLimitedEditor() { - switch (editorType) { - case Draft: - case Sealed: - case Winston: - case QuestDraft: - return true; - default: - return false; - } - } - - protected Map getColOverrides(ItemManagerConfig config) { - return null; - } - - protected class DeckHeader extends FContainer { - private DeckHeader() { - setHeight(HEADER_HEIGHT); - } - - @Override - public void drawBackground(Graphics g) { - g.fillRect(Header.BACK_COLOR, 0, 0, getWidth(), HEADER_HEIGHT); - } - - @Override - public void drawOverlay(Graphics g) { - float y = HEADER_HEIGHT - Header.LINE_THICKNESS / 2; - g.drawLine(Header.LINE_THICKNESS, Header.LINE_COLOR, 0, y, getWidth(), y); - } - - @Override - protected void doLayout(float width, float height) { - float x = 0; - lblName.setBounds(0, 0, width - 2 * height, height); - x += lblName.getWidth(); - btnSave.setBounds(x, 0, height, height); - x += height; - btnMoreOptions.setBounds(x, 0, height, height); - } - } - - protected static abstract class DeckEditorPage extends TabPage { - protected DeckEditorPage(String caption0, FImage icon0) { - super(caption0, icon0); - } - - protected void buildDeckMenu(FPopupMenu menu) { - } - - protected abstract void initialize(); - - @Override - public boolean fling(float velocityX, float velocityY) { - return false; //prevent left/right swipe to change tabs since it doesn't play nice with item managers - } - } - - protected static abstract class CardManagerPage extends DeckEditorPage { - private final ItemManagerConfig config; - protected final CardManager cardManager = add(new CardManager(false)); - - protected CardManagerPage(ItemManagerConfig config0, String caption0, FImage icon0) { - super(caption0, icon0); - config = config0; - cardManager.setItemActivateHandler(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - onCardActivated(cardManager.getSelectedItem()); - } - }); - cardManager.setContextMenuBuilder(new ContextMenuBuilder() { - @Override - public void buildMenu(final FDropDownMenu menu, final PaperCard card) { - CardManagerPage.this.buildMenu(menu, card); - } - }); - } - - protected void initialize() { - cardManager.setup(config, parentScreen.getColOverrides(config)); - } - - protected boolean canAddCards() { - return true; - } - - public void addCard(PaperCard card) { - addCard(card, 1); - } - public void addCard(PaperCard card, int qty) { - if (canAddCards()) { - cardManager.addItem(card, qty); - parentScreen.getEditorType().getController().notifyModelChanged(); - updateCaption(); - } - } - - public void addCards(Iterable> cards) { - if (canAddCards()) { - cardManager.addItems(cards); - parentScreen.getEditorType().getController().notifyModelChanged(); - updateCaption(); - } - } - - public void removeCard(PaperCard card) { - removeCard(card, 1); - } - public void removeCard(PaperCard card, int qty) { - cardManager.removeItem(card, qty); - parentScreen.getEditorType().getController().notifyModelChanged(); - updateCaption(); - } - - public void setCards(CardPool cards) { - cardManager.setItems(cards); - parentScreen.getEditorType().getController().notifyModelChanged(); - updateCaption(); - } - - protected void updateCaption() { - } - - protected abstract void onCardActivated(PaperCard card); - protected abstract void buildMenu(final FDropDownMenu menu, final PaperCard card); - - private ItemPool getAllowedAdditions(Iterable> itemsToAdd, boolean isAddSource) { - ItemPool additions = new ItemPool<>(cardManager.getGenericType()); - CardLimit limit = parentScreen.getCardLimit(); - Deck deck = parentScreen.getDeck(); - - for (Entry itemEntry : itemsToAdd) { - PaperCard card = itemEntry.getKey(); - - int max; - if (deck == null || card == null) { - max = Integer.MAX_VALUE; - } - else if (limit == CardLimit.None || DeckFormat.canHaveAnyNumberOf(card)) { - max = Integer.MAX_VALUE; - if (parentScreen.isLimitedEditor() && !isAddSource) { - //prevent adding more than is in other pool when editing limited decks - if (parentScreen.getMainDeckPage() == this) { - max = deck.get(DeckSection.Sideboard).count(card); - } - else if (parentScreen.getSideboardPage() == this) { - max = deck.get(DeckSection.Main).count(card); - } - } - } - else { - max = (limit == CardLimit.Singleton ? 1 : FModel.getPreferences().getPrefInt(FPref.DECK_DEFAULT_CARD_LIMIT)); - - Integer cardCopies = DeckFormat.canHaveSpecificNumberInDeck(card); - if (cardCopies != null) { - max = cardCopies; - } - - max -= deck.getMain().count(card); - if (deck.has(DeckSection.Sideboard)) { - max -= deck.get(DeckSection.Sideboard).count(card); - } - if (deck.has(DeckSection.Commander)) { - max -= deck.get(DeckSection.Commander).count(card); - } - if (deck.has(DeckSection.Planes)) { - max -= deck.get(DeckSection.Planes).count(card); - } - if (deck.has(DeckSection.Schemes)) { - max -= deck.get(DeckSection.Schemes).count(card); - } - } - - int qty; - if (isAddSource) { - qty = itemEntry.getValue(); - } - else if (parentScreen.getEditorType() == EditorType.Quest||parentScreen.getEditorType() == EditorType.QuestCommander) { - //prevent adding more than is in quest inventory - try { - qty = parentScreen.getCatalogPage().cardManager.getItemCount(card); - } catch (Exception e) { - //prevent NPE - qty = 0; - } - } - else { - //if not source of items being added, use max directly if unlimited pool - qty = max; - } - if (qty > max) { - qty = max; - } - if (qty > 0) { - additions.add(card, qty); - } - } - - return additions; - } - - protected int getMaxMoveQuantity(boolean isAddMenu, boolean isAddSource) { - ItemPool selectedItemPool = cardManager.getSelectedItemPool(); - if (isAddMenu) { - selectedItemPool = getAllowedAdditions(selectedItemPool, isAddSource); - } - if (selectedItemPool.isEmpty()) { - return 0; - } - int max = Integer.MAX_VALUE; - for (Entry itemEntry : selectedItemPool) { - if (itemEntry.getValue() < max) { - max = itemEntry.getValue(); - } - } - return max; - } - - protected void addItem(FDropDownMenu menu, final String verb, String dest, FImage icon, boolean isAddMenu, boolean isAddSource, final Callback callback) { - final int max = getMaxMoveQuantity(isAddMenu, isAddSource); - if (max == 0) { return; } - - String label = verb; - if (!StringUtils.isEmpty(dest)) { - label += " " + dest; - } - menu.addItem(new FMenuItem(label, icon, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - if (max == 1) { - callback.run(max); - } - else { - final Localizer localizer = Localizer.getInstance(); - GuiChoose.getInteger(cardManager.getSelectedItem() + " - " + verb + " " + localizer.getMessage("lblHowMany"), 1, max, 20, callback); - } - } - })); - } - - protected void addCommanderItems(final FDropDownMenu menu, final PaperCard card, boolean isAddMenu, boolean isAddSource) { - final Localizer localizer = Localizer.getInstance(); - if (parentScreen.getCommanderPage() == null) { - return; - } - boolean isLegalCommander; - String captionSuffix = localizer.getMessage("lblCommander"); - switch (parentScreen.editorType) { - case Brawl: - isLegalCommander = card.getRules().canBeBrawlCommander(); - break; - case TinyLeaders: - isLegalCommander = card.getRules().canBeTinyLeadersCommander(); - break; - case Oathbreaker: - isLegalCommander = card.getRules().canBeOathbreaker(); - captionSuffix = localizer.getMessage("lblOathbreaker"); - break; - case PlanarConquest: - isLegalCommander = false; //don't set commander this way in Planar Conquest - break; - default: - isLegalCommander = DeckFormat.Commander.isLegalCommander(card.getRules()); - break; - } - if (isLegalCommander && !parentScreen.getCommanderPage().cardManager.getPool().contains(card)) { - addItem(menu, "Set", "as " + captionSuffix, parentScreen.getCommanderPage().getIcon(), isAddMenu, isAddSource, new Callback() { - @Override - public void run(Integer result) { - if (result == null || result <= 0) { return; } - setCommander(card); - } - }); - } - if (canHavePartnerCommander() && card.getRules().canBePartnerCommander()) { - addItem(menu, "Set", "as Partner " + captionSuffix, parentScreen.getCommanderPage().getIcon(), isAddMenu, isAddSource, new Callback() { - @Override - public void run(Integer result) { - if (result == null || result <= 0) { return; } - setPartnerCommander(card); - } - }); - } - if (canHaveSignatureSpell() && card.getRules().canBeSignatureSpell()) { - addItem(menu, "Set", "as Signature Spell", FSkinImage.SORCERY, isAddMenu, isAddSource, new Callback() { - @Override - public void run(Integer result) { - if (result == null || result <= 0) { return; } - setSignatureSpell(card); - } - }); - } - } - - protected boolean needsCommander() { - return parentScreen.getCommanderPage() != null && parentScreen.getDeck().getCommanders().isEmpty(); - } - - protected boolean canHavePartnerCommander() { - if (parentScreen.editorType == EditorType.Oathbreaker) { - return false; //at least for now, simplify Oathbreaker by not supporting partners, since there's only one set of partner planeswalkers anyway - } - return parentScreen.getCommanderPage() != null && parentScreen.getDeck().getCommanders().size() == 1 - && parentScreen.getDeck().getCommanders().get(0).getRules().canBePartnerCommander(); - } - - protected boolean canOnlyBePartnerCommander(final PaperCard card) { - if (parentScreen.getCommanderPage() == null) { - return false; - } - - byte cmdCI = 0; - for (final PaperCard p : parentScreen.getDeck().getCommanders()) { - cmdCI |= p.getRules().getColorIdentity().getColor(); - } - - return !card.getRules().getColorIdentity().hasNoColorsExcept(cmdCI); - } - - protected boolean canHaveSignatureSpell() { - return parentScreen.editorType == EditorType.Oathbreaker && parentScreen.getDeck().getOathbreaker() != null; - } - - protected void setCommander(PaperCard card) { - if (!cardManager.isInfinite()) { - removeCard(card); - } - CardPool newPool = new CardPool(); - newPool.add(card); - parentScreen.getCommanderPage().setCards(newPool); - refresh(); //refresh so cards shown that match commander's color identity - } - - protected void setPartnerCommander(PaperCard card) { - if (!cardManager.isInfinite()) { - removeCard(card); - } - parentScreen.getCommanderPage().addCard(card); - refresh(); //refresh so cards shown that match commander's color identity - } - - protected void setSignatureSpell(PaperCard card) { - if (!cardManager.isInfinite()) { - removeCard(card); - } - PaperCard signatureSpell = parentScreen.getDeck().getSignatureSpell(); - if (signatureSpell != null) { - parentScreen.getCommanderPage().removeCard(signatureSpell); //remove existing signature spell if any - } - parentScreen.getCommanderPage().addCard(card); - //refreshing isn't needed since color identity won't change from signature spell - } - - public void refresh() { - //not needed by default - } - - @Override - protected void doLayout(float width, float height) { - float x = 0; - if (Forge.isLandscapeMode()) { //add some horizontal padding in landscape mode - x = ItemFilter.PADDING; - width -= 2 * x; - } - cardManager.setBounds(x, 0, width, height); - } - } - - protected static class CatalogPage extends CardManagerPage { - private boolean initialized, needRefreshWhenShown; - - protected CatalogPage(ItemManagerConfig config) { - this(config, Localizer.getInstance().getMessage("lblCatalog"), Forge.hdbuttons ? FSkinImage.HDFOLDER : FSkinImage.FOLDER); - } - protected CatalogPage(ItemManagerConfig config, String caption0, FImage icon0) { - super(config, caption0, icon0); - } - - @Override - protected void initialize() { - if (initialized) { return; } //prevent initializing more than once if deck changes - initialized = true; - - super.initialize(); - cardManager.setCaption(getItemManagerCaption()); - - if (!isVisible() && (parentScreen.getEditorType() != EditorType.Quest||parentScreen.getEditorType() != EditorType.QuestCommander)) { - needRefreshWhenShown = true; - return; //delay refreshing while hidden unless for quest inventory - } - refresh(); - } - - @Override - protected boolean canAddCards() { - if (needRefreshWhenShown) { //ensure refreshed before cards added if hasn't been refreshed yet - needRefreshWhenShown = false; - refresh(); - } - return !cardManager.isInfinite(); - } - - protected String getItemManagerCaption() { - final Localizer localizer = Localizer.getInstance(); - switch (parentScreen.getEditorType()) { - case Archenemy: - return localizer.getMessage("lblSchemes"); - case Planechase: - return localizer.getMessage("lblPlanes"); - default: - return localizer.getMessage("lblCards"); - } - } - - @Override - public void setVisible(boolean visible0) { - if (isVisible() == visible0) { return; } - - super.setVisible(visible0); - if (visible0 && needRefreshWhenShown) { - needRefreshWhenShown = false; - refresh(); - } - } - - @Override - public void refresh() { - FThreads.invokeInEdtLater(new Runnable() { - @Override - public void run() { - LoadingOverlay.show(Localizer.getInstance().getMessage("lblLoading"), new Runnable() { - @Override - public void run() { - Predicate additionalFilter = null; - final EditorType editorType = parentScreen.getEditorType(); - final Localizer localizer = Localizer.getInstance(); - switch (editorType) { - case Archenemy: - cardManager.setPool(FModel.getArchenemyCards(), true); - break; - case Planechase: - cardManager.setPool(FModel.getPlanechaseCards(), true); - break; - case Quest: - final ItemPool questPool = new ItemPool<>(PaperCard.class); - questPool.addAll(FModel.getQuest().getCards().getCardpool()); - // remove bottom cards that are in the deck from the card pool - questPool.removeAll(parentScreen.getDeck().getMain()); - // remove sideboard cards from the catalog - questPool.removeAll(parentScreen.getDeck().getOrCreate(DeckSection.Sideboard)); - cardManager.setPool(questPool); - break; - case PlanarConquest: - cardManager.setPool(ConquestUtil.getAvailablePool(parentScreen.getDeck())); - break; - case QuestCommander: - case Commander: - case Oathbreaker: - case TinyLeaders: - case Brawl: - final List commanders = parentScreen.getDeck().getCommanders(); - if (commanders.isEmpty()) { - //if no commander set for deck, only show valid commanders - switch (editorType) { - case Commander: - case QuestCommander: - additionalFilter = DeckFormat.Commander.isLegalCommanderPredicate(); - cardManager.setCaption(localizer.getMessage("lblCommanders")); - break; - case Oathbreaker: - additionalFilter = DeckFormat.Oathbreaker.isLegalCommanderPredicate(); - cardManager.setCaption(localizer.getMessage("lblOathbreakers")); - break; - case TinyLeaders: - additionalFilter = DeckFormat.TinyLeaders.isLegalCommanderPredicate(); - cardManager.setCaption(localizer.getMessage("lblCommanders")); - break; - case Brawl: - additionalFilter = DeckFormat.Brawl.isLegalCommanderPredicate(); - cardManager.setCaption(localizer.getMessage("lblCommanders")); - break; - default: - // Do nothing - } - } - else { - //if a commander has been set, only show cards that match its color identity - switch (editorType) { - case Commander: - case QuestCommander: - additionalFilter = DeckFormat.Commander.isLegalCardForCommanderPredicate(commanders); - break; - case Oathbreaker: - additionalFilter = DeckFormat.Oathbreaker.isLegalCardForCommanderPredicate(commanders); - break; - case TinyLeaders: - additionalFilter = DeckFormat.TinyLeaders.isLegalCardForCommanderPredicate(commanders); - break; - case Brawl: - additionalFilter = DeckFormat.Brawl.isLegalCardForCommanderPredicate(commanders); - break; - default: - // Do nothing - } - cardManager.setCaption(localizer.getMessage("lblCards")); - } - // fall through to below - default: - if (cardManager.getWantUnique()) { - cardManager.setPool(editorType.applyCardFilter(FModel.getUniqueCardsNoAlt(), additionalFilter), true); - } - else { - cardManager.setPool(editorType.applyCardFilter(FModel.getAllCardsNoAlt(), additionalFilter), true); - } - break; - } - } - }); - } - }); - } - - @Override - protected void onCardActivated(PaperCard card) { - if (getMaxMoveQuantity(true, true) == 0) { - return; //don't add card if maximum copies of card already in deck - } - if (needsCommander()) { - setCommander(card); //handle special case of setting commander - return; - } - if (canOnlyBePartnerCommander(card)) { - return; //don't auto-change commander unexpectedly - } - if (!cardManager.isInfinite()) { - removeCard(card); - } - parentScreen.getMainDeckPage().addCard(card); - } - - @Override - protected void buildMenu(final FDropDownMenu menu, final PaperCard card) { - final Localizer localizer = Localizer.getInstance(); - - if (!needsCommander() && !canOnlyBePartnerCommander(card)) { - addItem(menu, localizer.getMessage("lblAdd"), localizer.getMessage("lblTo") + " " + parentScreen.getMainDeckPage().cardManager.getCaption(), parentScreen.getMainDeckPage().getIcon(), true, true, new Callback() { - @Override - public void run(Integer result) { - if (result == null || result <= 0) { return; } - - if (!cardManager.isInfinite()) { - removeCard(card, result); - } - parentScreen.getMainDeckPage().addCard(card, result); - } - }); - if (parentScreen.getSideboardPage() != null) { - addItem(menu, localizer.getMessage("lblAdd"), localizer.getMessage("lbltosideboard"), parentScreen.getSideboardPage().getIcon(), true, true, new Callback() { - @Override - public void run(Integer result) { - if (result == null || result <= 0) { return; } - - if (!cardManager.isInfinite()) { - removeCard(card, result); - } - parentScreen.getSideboardPage().addCard(card, result); - } - }); - } - } - - addCommanderItems(menu, card, true, true); - - if (parentScreen.getEditorType() == EditorType.Constructed) { - //add option to add or remove card from favorites - final CardPreferences prefs = CardPreferences.getPrefs(card); - if (prefs.getStarCount() == 0) { - menu.addItem(new FMenuItem(localizer.getMessage("lblAddFavorites"), Forge.hdbuttons ? FSkinImage.HDSTAR_FILLED : FSkinImage.STAR_FILLED, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - prefs.setStarCount(1); - CardPreferences.save(); - } - })); - } - else { - menu.addItem(new FMenuItem(localizer.getMessage("lblRemoveFavorites"), Forge.hdbuttons ? FSkinImage.HDSTAR_OUTLINE : FSkinImage.STAR_OUTLINE, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - prefs.setStarCount(0); - CardPreferences.save(); - } - })); - } - - //if card has more than one art option, add item to change user's preferred art - final List artOptions = FModel.getMagicDb().getCommonCards().getAllCardsNoAlt(card.getName()); - if (artOptions != null && artOptions.size() > 1) { - menu.addItem(new FMenuItem(localizer.getMessage("lblChangePreferredArt"), Forge.hdbuttons ? FSkinImage.HDPREFERENCE : FSkinImage.SETTINGS, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - //sort options so current option is on top and selected by default - List sortedOptions = new ArrayList<>(); - sortedOptions.add(card); - for (PaperCard option : artOptions) { - if (option != card) { - sortedOptions.add(option); - } - } - GuiChoose.oneOrNone(localizer.getMessage("lblSelectPreferredArt") + " " + card.getName(), sortedOptions, new Callback() { - @Override - public void run(PaperCard result) { - if (result != null) { - if (result != card) { - cardManager.replaceAll(card, result); - } - prefs.setPreferredArt(result.getEdition() + CardDb.NameSetSeparator + result.getArtIndex()); - CardPreferences.save(); - } - } - }); - } - })); - } - } - } - - @Override - protected void buildDeckMenu(FPopupMenu menu) { - if (cardManager.getConfig().getShowUniqueCardsOption()) { - final Localizer localizer = Localizer.getInstance(); - menu.addItem(new FCheckBoxMenuItem(localizer.getMessage("lblUniqueCardsOnly"), cardManager.getWantUnique(), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - boolean wantUnique = !cardManager.getWantUnique(); - cardManager.setWantUnique(wantUnique); - refresh(); - cardManager.getConfig().setUniqueCardsOnly(wantUnique); - } - })); - } - } - } - - protected static class DeckSectionPage extends CardManagerPage { - private final String captionPrefix; - private final DeckSection deckSection; - - protected DeckSectionPage(DeckSection deckSection0) { - this(deckSection0, ItemManagerConfig.DECK_EDITOR); - } - protected DeckSectionPage(DeckSection deckSection0, ItemManagerConfig config) { - super(config, null, null); - - final Localizer localizer = Localizer.getInstance(); - - deckSection = deckSection0; - switch (deckSection) { - default: - case Main: - captionPrefix = localizer.getMessage("lblMain"); - cardManager.setCaption(localizer.getMessage("ttMain")); - icon = MAIN_DECK_ICON; - break; - case Sideboard: - captionPrefix = localizer.getMessage("lblSide"); - cardManager.setCaption(localizer.getMessage("lblSideboard")); - icon = SIDEBOARD_ICON; - break; - case Commander: - captionPrefix = localizer.getMessage("lblCommander"); - cardManager.setCaption(localizer.getMessage("lblCommander")); - icon = FSkinImage.COMMANDER; - break; - case Avatar: - captionPrefix = localizer.getMessage("lblAvatar"); - cardManager.setCaption(localizer.getMessage("lblAvatar")); - icon = new FTextureRegionImage(FSkin.getAvatars().get(0)); - break; - case Planes: - captionPrefix = localizer.getMessage("lblPlanes"); - cardManager.setCaption(localizer.getMessage("lblPlanes")); - icon = FSkinImage.CHAOS; - break; - case Schemes: - captionPrefix = localizer.getMessage("lblSchemes"); - cardManager.setCaption(localizer.getMessage("lblSchemes")); - icon = FSkinImage.POISON; - break; - } - } - protected DeckSectionPage(DeckSection deckSection0, ItemManagerConfig config, String caption0, FImage icon0) { - super(config, null, icon0); - - deckSection = deckSection0; - captionPrefix = caption0; - cardManager.setCaption(caption0); - } - - @Override - protected void initialize() { - super.initialize(); - cardManager.setPool(parentScreen.getDeck().getOrCreate(deckSection)); - updateCaption(); - } - - @Override - protected void updateCaption() { - if (deckSection == DeckSection.Commander) { - caption = captionPrefix; //don't display count for commander section since it won't be more than 1 - } - else { - caption = captionPrefix + " (" + parentScreen.getDeck().get(deckSection).countAll() + ")"; - } - } - - @Override - protected void onCardActivated(PaperCard card) { - switch (deckSection) { - case Main: - case Planes: - case Schemes: - removeCard(card); - switch (parentScreen.getEditorType()) { - case Draft: - case Sealed: - case QuestDraft: - parentScreen.getSideboardPage().addCard(card); - break; - default: - if (parentScreen.getCatalogPage() != null) { - parentScreen.getCatalogPage().addCard(card); - } - break; - } - break; - case Sideboard: - removeCard(card); - parentScreen.getMainDeckPage().addCard(card); - break; - default: - break; - } - } - - @Override - protected void buildMenu(final FDropDownMenu menu, final PaperCard card) { - final Localizer localizer = Localizer.getInstance(); - switch (deckSection) { - default: - case Main: - addItem(menu, localizer.getMessage("lblAdd"), null, Forge.hdbuttons ? FSkinImage.HDPLUS : FSkinImage.PLUS, true, false, new Callback() { - @Override - public void run(Integer result) { - if (result == null || result <= 0) { return; } - - if (parentScreen.isLimitedEditor()) { //ensure card removed from sideboard before adding to main - parentScreen.getSideboardPage().removeCard(card, result); - } - else if (parentScreen.getEditorType() == EditorType.Quest || parentScreen.getEditorType() == EditorType.QuestCommander) { - parentScreen.getCatalogPage().removeCard(card, result); - } - addCard(card, result); - } - }); - if (!parentScreen.isLimitedEditor()) { - addItem(menu, localizer.getMessage("lblRemove"), null, Forge.hdbuttons ? FSkinImage.HDMINUS : FSkinImage.MINUS, false, false, new Callback() { - @Override - public void run(Integer result) { - if (result == null || result <= 0) { return; } - - removeCard(card, result); - if (parentScreen.getCatalogPage() != null) { - parentScreen.getCatalogPage().addCard(card, result); - } - } - }); - } - if (parentScreen.getSideboardPage() != null) { - addItem(menu, localizer.getMessage("lblMove"), localizer.getMessage("lbltosideboard"), parentScreen.getSideboardPage().getIcon(), false, false, new Callback() { - @Override - public void run(Integer result) { - if (result == null || result <= 0) { return; } - - removeCard(card, result); - parentScreen.getSideboardPage().addCard(card, result); - } - }); - } - addCommanderItems(menu, card, false, false); - break; - case Sideboard: - addItem(menu, localizer.getMessage("lblAdd"), null, Forge.hdbuttons ? FSkinImage.HDPLUS : FSkinImage.PLUS, true, false, new Callback() { - @Override - public void run(Integer result) { - if (result == null || result <= 0) { return; } - - if (parentScreen.isLimitedEditor()) { //ensure card removed from main deck before adding to sideboard - parentScreen.getMainDeckPage().removeCard(card, result); - } - else if (parentScreen.getEditorType() == EditorType.Quest || parentScreen.getEditorType() == EditorType.QuestCommander) { - parentScreen.getCatalogPage().removeCard(card, result); - } - addCard(card, result); - } - }); - if (!parentScreen.isLimitedEditor()) { - addItem(menu, localizer.getMessage("lblRemove"), null, Forge.hdbuttons ? FSkinImage.HDMINUS : FSkinImage.MINUS, false, false, new Callback() { - @Override - public void run(Integer result) { - if (result == null || result <= 0) { return; } - - removeCard(card, result); - if (parentScreen.getCatalogPage() != null) { - parentScreen.getCatalogPage().addCard(card, result); - } - } - }); - } - addItem(menu, localizer.getMessage("lblMove"), localizer.getMessage("lblToMainDeck"), parentScreen.getMainDeckPage().getIcon(), false, false, new Callback() { - @Override - public void run(Integer result) { - if (result == null || result <= 0) { return; } - - removeCard(card, result); - parentScreen.getMainDeckPage().addCard(card, result); - } - }); - addCommanderItems(menu, card, false, false); - break; - case Commander: - if (parentScreen.editorType != EditorType.PlanarConquest || isPartnerCommander(card)) { - addItem(menu, localizer.getMessage("lblRemove"), null, Forge.hdbuttons ? FSkinImage.HDMINUS : FSkinImage.MINUS, false, false, new Callback() { - @Override - public void run(Integer result) { - if (result == null || result <= 0) { - return; - } - - removeCard(card, result); - parentScreen.getCatalogPage().refresh(); //refresh so commander options shown again - parentScreen.setSelectedPage(parentScreen.getCatalogPage()); - } - }); - } - break; - case Avatar: - addItem(menu, localizer.getMessage("lblRemove"), null, Forge.hdbuttons ? FSkinImage.HDMINUS : FSkinImage.MINUS, false, false, new Callback() { - @Override - public void run(Integer result) { - if (result == null || result <= 0) { return; } - - removeCard(card, result); - } - }); - break; - case Schemes: - addItem(menu, localizer.getMessage("lblAdd"), null, Forge.hdbuttons ? FSkinImage.HDPLUS : FSkinImage.PLUS, true, false, new Callback() { - @Override - public void run(Integer result) { - if (result == null || result <= 0) { return; } - - addCard(card, result); - } - }); - addItem(menu, localizer.getMessage("lblRemove"), null, Forge.hdbuttons ? FSkinImage.HDMINUS : FSkinImage.MINUS, false, false, new Callback() { - @Override - public void run(Integer result) { - if (result == null || result <= 0) { return; } - - removeCard(card, result); - } - }); - break; - case Planes: - addItem(menu, localizer.getMessage("lblAdd"), null, Forge.hdbuttons ? FSkinImage.HDPLUS : FSkinImage.PLUS, true, false, new Callback() { - @Override - public void run(Integer result) { - if (result == null || result <= 0) { return; } - - addCard(card, result); - } - }); - addItem(menu, localizer.getMessage("lblRemove"), null, Forge.hdbuttons ? FSkinImage.HDMINUS : FSkinImage.MINUS, false, false, new Callback() { - @Override - public void run(Integer result) { - if (result == null || result <= 0) { return; } - - removeCard(card, result); - } - }); - break; - } - } - - private boolean isPartnerCommander(final PaperCard card) { - if (parentScreen.getCommanderPage() == null || parentScreen.getDeck().getCommanders().isEmpty()) { - return false; - } - - PaperCard firstCmdr = parentScreen.getDeck().getCommanders().get(0); - return !card.getName().equals(firstCmdr.getName()); - } - } - - private static class DraftPackPage extends CatalogPage { - protected DraftPackPage() { - super(ItemManagerConfig.DRAFT_PACK, Localizer.getInstance().getMessage("lblPackN", String.valueOf(1)), FSkinImage.PACK); - } - - @Override - public void refresh() { - BoosterDraft draft = parentScreen.getDraft(); - if (draft == null) { return; } - - CardPool pool = draft.nextChoice(); - int packNumber = draft.getCurrentBoosterIndex() + 1; - caption = Localizer.getInstance().getMessage("lblPackN", String.valueOf(packNumber)); - cardManager.setPool(pool); - } - - @Override - protected void onCardActivated(PaperCard card) { - super.onCardActivated(card); - afterCardPicked(card); - } - - private void afterCardPicked(PaperCard card) { - BoosterDraft draft = parentScreen.getDraft(); - draft.setChoice(card); - - // TODO Implement handling of extra boosters - - if (draft.hasNextChoice()) { - refresh(); - } - else { - hideTab(); //hide this tab page when finished drafting - parentScreen.save(null); - } - } - - @Override - protected void buildMenu(final FDropDownMenu menu, final PaperCard card) { - final Localizer localizer = Localizer.getInstance(); - addItem(menu, localizer.getMessage("lblAdd"), localizer.getMessage("lblToMainDeck"), parentScreen.getMainDeckPage().getIcon(), true, true, new Callback() { - @Override - public void run(Integer result) { //ignore quantity - parentScreen.getMainDeckPage().addCard(card); - afterCardPicked(card); - } - }); - addItem(menu, localizer.getMessage("lblAdd"), localizer.getMessage("lbltosideboard"), parentScreen.getSideboardPage().getIcon(), true, true, new Callback() { - @Override - public void run(Integer result) { //ignore quantity - parentScreen.getSideboardPage().addCard(card); - afterCardPicked(card); - } - }); - } - } - - public static class DeckController { - private T model; - private boolean saved; - private boolean modelInStorage; - private IStorage rootFolder; - private IStorage currentFolder; - private String modelPath; - private FDeckEditor editor; - private final Supplier newModelCreator; - - protected DeckController(final IStorage folder0, final Supplier newModelCreator0) { - setRootFolder(folder0); - newModelCreator = newModelCreator0; - } - - public void setRootFolder(IStorage folder0) { - rootFolder = folder0; - currentFolder = folder0; - model = null; - saved = true; - modelInStorage = false; - modelPath = ""; - } - - public T getModel() { - return model; - } - - public String getModelPath() { - return modelPath; - } - - @SuppressWarnings("unchecked") - public void setDeck(final Deck deck) { - modelInStorage = false; - model = (T)deck; - currentFolder = rootFolder; - modelPath = ""; - setSaved(false); - editor.setDeck(deck); - } - - public void setModel(final T document) { - setModel(document, false); - } - public void setModel(final T document, final boolean isStored) { - modelInStorage = isStored; - model = document; - - if (isStored) { - if (isModelInSyncWithFolder()) { - setSaved(true); - } - else { - notifyModelChanged(); - } - } - else { //TODO: Make this smarter - currentFolder = rootFolder; - modelPath = ""; - setSaved(true); - } - if (model != null) { - editor.setDeck(model.getHumanDeck()); - } - else { - editor.setDeck(null); - } - - } - - private boolean isModelInSyncWithFolder() { - if (model.getName().isEmpty()) { - return true; - } - - final T modelStored = currentFolder.get(model.getName()); - // checks presence in dictionary only. - if (modelStored == model) { - return true; - } - if (modelStored == null) { - return false; - } - - return modelStored.equals(model); - } - - public void notifyModelChanged() { - if (saved) { - setSaved(false); - } - } - - private void setSaved(boolean val) { - saved = val; - - if (editor != null) { - String name = this.getModelName(); - if (name.isEmpty()) { - final Localizer localizer = Localizer.getInstance(); - name = "[" + localizer.getMessage("lblNewDeck") + "]"; - } - if (!saved) { - name = "*" + name; - } - editor.lblName.setText(name); - editor.btnSave.setEnabled(!saved); - } - } - - public void reload() { - String name = getModelName(); - if (name.isEmpty()) { - newModel(); - } - else { - load(name); - } - } - - public void load(final String path, final String name) { - if (StringUtils.isBlank(path)) { - currentFolder = rootFolder; - } - else { - currentFolder = rootFolder.tryGetFolder(path); - } - modelPath = path; - load(name); - } - - @SuppressWarnings("unchecked") - private void load(final String name) { - T newModel = currentFolder.get(name); - if (newModel != null) { - setModel((T) newModel.copyTo(name), true); - } - else { - setSaved(true); - } - } - - @SuppressWarnings("unchecked") - public void save() { - if (model == null) { - return; - } - - // copy to new instance before adding to current folder so further changes are auto-saved - currentFolder.add((T) model.copyTo(model.getName())); - model.setDirectory(DeckProxy.getDeckDirectory(currentFolder)); - modelInStorage = true; - setSaved(true); - - //update saved deck names - String deckStr = DeckProxy.getDeckString(getModelPath(), getModelName()); - switch (editor.getEditorType()) { - case Constructed: - DeckPreferences.setCurrentDeck(deckStr); - break; - case Commander: - DeckPreferences.setCommanderDeck(deckStr); - break; - case Oathbreaker: - DeckPreferences.setOathbreakerDeck(deckStr); - break; - case TinyLeaders: - DeckPreferences.setTinyLeadersDeck(deckStr); - break; - case Brawl: - DeckPreferences.setBrawlDeck(deckStr); - break; - case Archenemy: - DeckPreferences.setSchemeDeck(deckStr); - break; - case Planechase: - DeckPreferences.setPlanarDeck(deckStr); - break; - case Draft: - case QuestDraft: - DeckPreferences.setDraftDeck(deckStr); - break; - case Sealed: - DeckPreferences.setSealedDeck(deckStr); - break; - case Quest: - case QuestCommander: - FModel.getQuest().setCurrentDeck(model.toString()); - FModel.getQuest().save(); - break; - default: - break; - } - editor.setDeck(model.getHumanDeck()); - if (editor.saveHandler != null) { - editor.saveHandler.handleEvent(new FEvent(editor, FEventType.SAVE)); - } - } - - @SuppressWarnings("unchecked") - public void saveAs(final String name0) { - model = (T)model.copyTo(name0); - modelInStorage = false; - save(); - } - - public void rename(final String name0) { - if (StringUtils.isEmpty(name0)) { return; } - - String oldName = model.getName(); - if (name0.equals(oldName)) { return; } - - saveAs(name0); - currentFolder.delete(oldName); //delete deck with old name - } - - public String getNextAvailableName() { - String name = model.getName(); - int idx = name.lastIndexOf('('); - if (idx != -1) { - name = name.substring(0, idx).trim(); //strip old number - } - - String baseName = name; - int number = 2; - do { - name = baseName + " (" + number + ")"; - number++; - } while (fileExists(name)); - - return name; - } - - public boolean isSaved() { - return saved; - } - - public boolean fileExists(final String deckName) { - return currentFolder.contains(deckName); - } - - public void importDeck(final T newDeck) { - setModel(newDeck); - } - - public void refreshModel() { - if (model == null) { - newModel(); - } - else { - setModel(model, modelInStorage); - } - } - - public void newModel() { - setModel(newModelCreator.get()); - } - - public String getModelName() { - return model != null ? model.getName() : ""; - } - - public boolean delete() { - if (model == null) { return false; } - currentFolder.delete(model.getName()); - setModel(null); - return true; - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FDeckImportDialog.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FDeckImportDialog.java deleted file mode 100644 index cedcccc0eb3..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FDeckImportDialog.java +++ /dev/null @@ -1,184 +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.adventure.libgdxgui.deck; - -import com.google.common.collect.ImmutableList; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.deck.Deck; -import forge.deck.DeckImportController; -import forge.deck.DeckRecognizer; -import forge.deck.DeckRecognizer.TokenType; -import forge.gui.FThreads; -import forge.gui.util.SOptionPane; -import forge.adventure.libgdxgui.toolbox.*; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.util.Callback; -import forge.util.Localizer; - -import java.util.List; - - -public class FDeckImportDialog extends FDialog { - private final Callback callback; - - private final FTextArea txtInput = add(new FTextArea(true)); - private final FCheckBox newEditionCheck = add(new FCheckBox(Localizer.getInstance().getMessage("lblImportLatestVersionCard"), true)); - private final FCheckBox dateTimeCheck = add(new FCheckBox(Localizer.getInstance().getMessage("lblUseOnlySetsReleasedBefore"), false)); - /*setting onlyCoreExpCheck to false allow the copied cards to pass the check of deck contents - forge-core\src\main\java\forge\deck\Deck.javaDeck.java starting @ Line 320 which is called by - forge-gui-mobile\src\forge\deck\FDeckEditor.java starting @ Line 373 - (as of latest commit: 8e6655e3ee67688cff66b422d4722c58392eaa7e) - */ - private final FCheckBox onlyCoreExpCheck = add(new FCheckBox(Localizer.getInstance().getMessage("lblUseOnlyCoreAndExpansionSets"), false)); - - private final FComboBox monthDropdown = add(new FComboBox<>()); //don't need wrappers since skin can't change while this dialog is open - private final FComboBox yearDropdown = add(new FComboBox<>()); - - private final boolean showOptions; - private final DeckImportController controller; - - private final static ImmutableList importOrCancel = ImmutableList.of(Localizer.getInstance().getMessage("lblImport"), Localizer.getInstance().getMessage("lblCancel")); - - public FDeckImportDialog(final boolean replacingDeck, final Callback callback0) { - super(Localizer.getInstance().getMessage("lblImportFromClipboard"), 2); - - callback = callback0; - controller = new DeckImportController(replacingDeck, newEditionCheck, dateTimeCheck, onlyCoreExpCheck, monthDropdown, yearDropdown); - txtInput.setText(Forge.getClipboard().getContents()); //just pull import directly off the clipboard - - initButton(0, Localizer.getInstance().getMessage("lblImport"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - FThreads.invokeInBackgroundThread(new Runnable() { - @Override - public void run() { - List tokens = controller.parseInput(txtInput.getText()); //ensure deck updated based on any changes to options - - //if there are any unknown cards, let user know this and give them the option to cancel - StringBuilder sb = new StringBuilder(); - for (DeckRecognizer.Token token : tokens) { - if (token.getType() == TokenType.UnknownCard) { - if (sb.length() > 0) { - sb.append("\n"); - } - sb.append(token.getNumber()).append(" ").append(token.getText()); - } - } - if (sb.length() > 0) { - if (SOptionPane.showOptionDialog(Localizer.getInstance().getMessage("lblFollowingCardsCannotBeImported") + "\n\n" + sb, Localizer.getInstance().getMessage("lblImportRemainingCards"), SOptionPane.INFORMATION_ICON, importOrCancel) == 1) { - return; - } - } - - final Deck deck = controller.accept(); //must accept in background thread in case a dialog is shown - if (deck == null) { return; } - - FThreads.invokeInEdtLater(new Runnable() { - @Override - public void run() { - hide(); - callback.run(deck); - } - }); - } - }); - } - }); - initButton(1, Localizer.getInstance().getMessage("lblCancel"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - hide(); - } - }); - - List tokens = controller.parseInput(txtInput.getText()); - - //ensure at least one known card found on clipboard - for (DeckRecognizer.Token token : tokens) { - if (token.getType() == TokenType.KnownCard) { - showOptions = true; - - dateTimeCheck.setCommand(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - updateDropDownEnabled(); - } - }); - updateDropDownEnabled(); - return; - } - } - - showOptions = false; - setButtonEnabled(0, false); - txtInput.setText(Localizer.getInstance().getMessage("lblNoKnownCardsOnClipboard")); - } - - private void updateDropDownEnabled() { - boolean enabled = dateTimeCheck.isSelected(); - monthDropdown.setEnabled(enabled); - yearDropdown.setEnabled(enabled); - } - - @Override - public void drawOverlay(Graphics g) { - super.drawOverlay(g); - if (showOptions) { - float y = txtInput.getTop() - FOptionPane.PADDING; - g.drawLine(BORDER_THICKNESS, BORDER_COLOR, 0, y, getWidth(), y); - } - } - - @Override - protected float layoutAndGetHeight(float width, float maxHeight) { - float padding = FOptionPane.PADDING; - float x = padding; - float y = padding; - float w = width - 2 * padding; - float h; - if (showOptions) { - h = monthDropdown.getHeight(); - float fieldPadding = padding / 2; - - newEditionCheck.setBounds(x, y, w, h); - y += h + fieldPadding; - dateTimeCheck.setBounds(x, y, w, h); - y += h + fieldPadding; - - float dropDownWidth = (w - fieldPadding) / 2; - monthDropdown.setBounds(x, y, dropDownWidth, h); - yearDropdown.setBounds(x + dropDownWidth + fieldPadding, y, dropDownWidth, h); - y += h + fieldPadding; - - onlyCoreExpCheck.setBounds(x, y, w, h); - y += h + 2 * padding; - } - h = txtInput.getPreferredHeight(w); - float maxTextBoxHeight = maxHeight - y - padding; - if (h > maxTextBoxHeight) { - h = maxTextBoxHeight; - } - txtInput.setBounds(x, y, w, h); - y += h + padding; - if (showOptions) { - h = newEditionCheck.getHeight(); - } - return y; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FDeckViewer.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FDeckViewer.java deleted file mode 100644 index d9bd58528b5..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FDeckViewer.java +++ /dev/null @@ -1,175 +0,0 @@ -package forge.adventure.libgdxgui.deck; - -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.assets.*; -import forge.deck.CardPool; -import forge.deck.Deck; -import forge.deck.DeckSection; -import forge.item.PaperCard; -import forge.adventure.libgdxgui.itemmanager.CardManager; -import forge.itemmanager.ItemManagerConfig; -import forge.adventure.libgdxgui.itemmanager.filters.ItemFilter; -import forge.adventure.libgdxgui.menu.FMenuItem; -import forge.adventure.libgdxgui.menu.FPopupMenu; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.toolbox.FEvent; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.toolbox.FOptionPane; -import forge.util.Localizer; - -import java.util.Map.Entry; - -public class FDeckViewer extends FScreen { - private static FDeckViewer deckViewer; - private static final FPopupMenu menu = new FPopupMenu() { - @Override - protected void buildMenu() { - Deck deck = deckViewer.deck; - for (Entry entry : deck) { - final DeckSection section = entry.getKey(); - final CardPool pool = entry.getValue(); - int count = pool.countAll(); - if (count == 0) { continue; } - - final String captionPrefix; - final FImage icon; - switch (section) { - default: - case Main: - captionPrefix = Localizer.getInstance().getMessage("ttMain"); - icon = FDeckEditor.MAIN_DECK_ICON; - break; - case Sideboard: - captionPrefix = Localizer.getInstance().getMessage("lblSideboard"); - icon = FDeckEditor.SIDEBOARD_ICON; - break; - case Commander: - captionPrefix = Localizer.getInstance().getMessage("lblCommander"); - icon = FSkinImage.COMMANDER; - break; - case Avatar: - captionPrefix = Localizer.getInstance().getMessage("lblAvatar"); - icon = new FTextureRegionImage(FSkin.getAvatars().get(0)); - break; - case Planes: - captionPrefix = Localizer.getInstance().getMessage("lblPlanes"); - icon = FSkinImage.CHAOS; - break; - case Schemes: - captionPrefix = Localizer.getInstance().getMessage("lblSchemes"); - icon = FSkinImage.POISON; - break; - } - - FMenuItem item = new FMenuItem(captionPrefix + " (" + count + ")", icon, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - deckViewer.setCurrentSection(section); - } - }); - if (section == deckViewer.currentSection) { - item.setSelected(true); - } - addItem(item); - } - addItem(new FMenuItem(Localizer.getInstance().getMessage("btnCopyToClipboard"), Forge.hdbuttons ? FSkinImage.HDEXPORT : FSkinImage.BLANK, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - copyDeckToClipboard(deckViewer.deck); - } - })); - } - }; - - public static void copyDeckToClipboard(Deck deck) { - final String nl = System.getProperty("line.separator"); - final StringBuilder deckList = new StringBuilder(); - String dName = deck.getName(); - //fix copying a commander netdeck then importing it again... - if (dName.startsWith("[Commander")||dName.contains("Commander")) - dName = ""; - deckList.append(dName == null ? "" : dName + nl + nl); - - for (DeckSection s : DeckSection.values()){ - CardPool cp = deck.get(s); - if (cp == null || cp.isEmpty()) { - continue; - } - deckList.append(s.toString()).append(": "); - deckList.append(nl); - for (final Entry ev : cp) { - deckList.append(ev.getValue()).append(" ").append(ev.getKey()).append(nl); - } - deckList.append(nl); - } - - Forge.getClipboard().setContents(deckList.toString()); - FOptionPane.showMessageDialog(Localizer.getInstance().getMessage("lblDeckListCopiedClipboard", deck.getName())); - } - - private final Deck deck; - private final CardManager cardManager; - private DeckSection currentSection; - - public static void show(final Deck deck0) { - show(deck0, false); - } - public static void show(final Deck deck0, boolean noPreload) { - if (deck0 == null) { return; } - - if (!noPreload){ - /*preload deck to cache*/ - ImageCache.preloadCache(deck0); - } - - deckViewer = new FDeckViewer(deck0); - deckViewer.setRotate180(MatchController.getView() != null && MatchController.getView().isTopHumanPlayerActive()); - Forge.openScreen(deckViewer); - } - - private FDeckViewer(Deck deck0) { - super(new MenuHeader(deck0.getName(), menu) { - @Override - protected boolean displaySidebarForLandscapeMode() { - return false; - } - }); - deck = deck0; - cardManager = new CardManager(false); - cardManager.setPool(deck.getMain()); - - currentSection = DeckSection.Main; - updateCaption(); - - add(cardManager); - - cardManager.setup(ItemManagerConfig.DECK_VIEWER); - } - - private void setCurrentSection(DeckSection currentSection0) { - if (currentSection == currentSection0) { return; } - currentSection = currentSection0; - cardManager.setPool(deck.get(currentSection)); - updateCaption(); - } - - private void updateCaption() { - cardManager.setCaption(currentSection.name()); - } - - @Override - protected void doLayout(float startY, float width, float height) { - float x = 0; - if (Forge.isLandscapeMode()) { //add some horizontal padding in landscape mode - x = ItemFilter.PADDING; - width -= 2 * x; - } - cardManager.setBounds(x, startY, width, height - startY); - } - - @Override - public FScreen getLandscapeBackdropScreen() { - return null; //never use backdrop for editor - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FSideboardDialog.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FSideboardDialog.java deleted file mode 100644 index 5472ac8e85d..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FSideboardDialog.java +++ /dev/null @@ -1,211 +0,0 @@ -package forge.adventure.libgdxgui.deck; - -import forge.adventure.libgdxgui.assets.FImage; -import forge.deck.CardPool; -import forge.item.PaperCard; -import forge.adventure.libgdxgui.itemmanager.CardManager; -import forge.adventure.libgdxgui.itemmanager.ItemManager.ContextMenuBuilder; -import forge.itemmanager.ItemManagerConfig; -import forge.adventure.libgdxgui.menu.FDropDownMenu; -import forge.adventure.libgdxgui.menu.FMenuItem; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.screens.TabPageScreen; -import forge.adventure.libgdxgui.toolbox.FDialog; -import forge.adventure.libgdxgui.toolbox.FEvent; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.toolbox.GuiChoose; -import forge.util.Callback; -import forge.util.Localizer; -import org.apache.commons.lang3.StringUtils; - -import java.util.List; - -public class FSideboardDialog extends FDialog { - private final SideboardTabs tabs; - private final Callback> callback; - - public FSideboardDialog(CardPool sideboard, CardPool main, final Callback> callback0, String message) { - super(String.format(Localizer.getInstance().getMessage("lblUpdateMainFromSideboard"), message), 1); - - callback = callback0; - tabs = add(new SideboardTabs(sideboard, main)); - initButton(0, Localizer.getInstance().getMessage("lblOK"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - hide(); - } - }); - if (sideboard.isEmpty()) { //show main deck by default if sideboard is empty - tabs.setSelectedPage(tabs.getMainDeckPage()); - } - } - - @Override - public void setVisible(boolean visible0) { - super.setVisible(visible0); - if (!visible0) { //do callback when hidden to ensure you don't get stuck if Back pressed - callback.run(tabs.getMainDeckPage().cardManager.getPool().toFlatList()); - } - } - - @Override - protected float layoutAndGetHeight(float width, float maxHeight) { - tabs.setBounds(0, 0, width, maxHeight); - return maxHeight; - } - - private static class SideboardTabs extends TabPageScreen { - private SideboardTabs(CardPool sideboard, CardPool main) { - super(new TabPageBase[] { - new SideboardPage(sideboard), - new MainDeckPage(main) - }, false); - ((SideboardPage)tabPages[0]).parent = this; - ((MainDeckPage)tabPages[1]).parent = this; - } - - private SideboardPage getSideboardPage() { - return ((SideboardPage)tabPages[0]); - } - - private MainDeckPage getMainDeckPage() { - return ((MainDeckPage)tabPages[1]); - } - - @Override - protected boolean canActivateTabPage() { - return true; //always allow activating tab pages while this is open - } - - @Override - public FScreen getLandscapeBackdropScreen() { - return null; - } - - private static abstract class TabPageBase extends TabPage { - protected SideboardTabs parent; - protected final CardManager cardManager = add(new CardManager(false)); - - protected TabPageBase(CardPool cardPool, FImage icon0) { - super("", icon0); - - cardManager.setItemActivateHandler(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - onCardActivated(cardManager.getSelectedItem()); - } - }); - cardManager.setContextMenuBuilder(new ContextMenuBuilder() { - @Override - public void buildMenu(final FDropDownMenu menu, final PaperCard card) { - TabPageBase.this.buildMenu(menu, card); - } - }); - cardManager.setup(ItemManagerConfig.SIDEBOARD); - cardManager.setPool(new CardPool(cardPool)); //create copy of card pool to avoid modifying the original card pool - updateCaption(); - } - - protected void addCard(PaperCard card, int qty) { - cardManager.addItem(card, qty); - updateCaption(); - } - - protected void removeCard(PaperCard card, int qty) { - cardManager.removeItem(card, qty); - updateCaption(); - } - - protected void addItem(FDropDownMenu menu, final String verb, String dest, FImage icon, final Callback callback) { - String label = verb; - if (!StringUtils.isEmpty(dest)) { - label += " " + dest; - } - menu.addItem(new FMenuItem(label, icon, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - PaperCard card = cardManager.getSelectedItem(); - int max = cardManager.getItemCount(card); - if (max == 1) { - callback.run(max); - } - else { - GuiChoose.getInteger(card + " - " + verb + " " + Localizer.getInstance().getMessage("lblHowMany"), 1, max, 20, callback); - } - } - })); - } - - protected abstract void updateCaption(); - protected abstract void onCardActivated(PaperCard card); - protected abstract void buildMenu(final FDropDownMenu menu, final PaperCard card); - - @Override - protected void doLayout(float width, float height) { - cardManager.setBounds(0, 0, width, height); - } - } - - private static class SideboardPage extends TabPageBase { - protected SideboardPage(CardPool cardPool) { - super(cardPool, FDeckEditor.SIDEBOARD_ICON); - cardManager.setCaption(Localizer.getInstance().getMessage("lblSideboard")); - } - - @Override - protected void updateCaption() { - caption = Localizer.getInstance().getMessage("lblSideboard") + " (" + cardManager.getPool().countAll() + ")"; - } - - @Override - protected void onCardActivated(PaperCard card) { - removeCard(card, 1); - parent.getMainDeckPage().addCard(card, 1); - } - - @Override - protected void buildMenu(FDropDownMenu menu, final PaperCard card) { - addItem(menu, Localizer.getInstance().getMessage("lblMove"), Localizer.getInstance().getMessage("lblToMainDeck"), FDeckEditor.MAIN_DECK_ICON, new Callback() { - @Override - public void run(Integer result) { - if (result == null || result <= 0) { return; } - - removeCard(card, result); - parent.getMainDeckPage().addCard(card, result); - } - }); - } - } - - private static class MainDeckPage extends TabPageBase { - protected MainDeckPage(CardPool cardPool) { - super(cardPool, FDeckEditor.MAIN_DECK_ICON); - cardManager.setCaption(Localizer.getInstance().getMessage("ttMain")); - } - - @Override - protected void updateCaption() { - caption = Localizer.getInstance().getMessage("ttMain") + " (" + cardManager.getPool().countAll() + ")"; - } - - @Override - protected void onCardActivated(PaperCard card) { - removeCard(card, 1); - parent.getSideboardPage().addCard(card, 1); - } - - @Override - protected void buildMenu(FDropDownMenu menu, final PaperCard card) { - addItem(menu, Localizer.getInstance().getMessage("lblMove"), Localizer.getInstance().getMessage("lbltosideboard"), FDeckEditor.SIDEBOARD_ICON, new Callback() { - @Override - public void run(Integer result) { - if (result == null || result <= 0) { return; } - - removeCard(card, result); - parent.getSideboardPage().addCard(card, result); - } - }); - } - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FVanguardChooser.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FVanguardChooser.java deleted file mode 100644 index 15191c54818..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/deck/FVanguardChooser.java +++ /dev/null @@ -1,111 +0,0 @@ -package forge.adventure.libgdxgui.deck; - -import forge.adventure.libgdxgui.Forge; -import forge.deck.CardPool; -import forge.item.PaperCard; -import forge.adventure.libgdxgui.itemmanager.CardManager; -import forge.itemmanager.ItemManagerConfig; -import forge.model.FModel; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.toolbox.FButton; -import forge.adventure.libgdxgui.toolbox.FEvent; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.util.Aggregates; -import forge.util.Localizer; -import forge.adventure.libgdxgui.util.Utils; - -public class FVanguardChooser extends FScreen { - public static final float PADDING = Utils.scale(5); - - private static final CardPool allHumanAvatars = new CardPool(); - private static final CardPool allAiAvatars = new CardPool(); - private static final CardPool nonRandomHumanAvatars = new CardPool(); - private static final CardPool nonRandomAiAvatars = new CardPool(); - - static { - for (PaperCard c : FModel.getMagicDb().getVariantCards().getAllCards()) { - if (c.getRules().getType().isVanguard()) { - allHumanAvatars.add(c); - if (!c.getRules().getAiHints().getRemRandomDecks()) { - nonRandomHumanAvatars.add(c); - } - if (!c.getRules().getAiHints().getRemAIDecks()) { - allAiAvatars.add(c); - if (!c.getRules().getAiHints().getRemRandomDecks()) { - nonRandomAiAvatars.add(c); - } - } - } - } - } - - private final CardManager lstVanguards = add(new CardManager(true)); - private final FButton btnRandom = add(new FButton(Localizer.getInstance().getMessage("lblRandomVanguard"))); - private boolean isAi; - - public FVanguardChooser(boolean isAi0, FEventHandler selectionChangedHandler) { - super(""); - isAi = isAi0; - lstVanguards.setItemActivateHandler(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - Forge.back(); - } - }); - btnRandom.setCommand(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - selectRandom(); - Forge.back(); - } - }); - lstVanguards.setup(ItemManagerConfig.VANGUARDS); - lstVanguards.setPool(isAi ? allAiAvatars : allHumanAvatars, true); - lstVanguards.setSelectionChangedHandler(selectionChangedHandler); - selectRandom(); - } - - private void selectRandom() { - if (lstVanguards.getItemCount() == 0) { return; } - - if (isAi) { - lstVanguards.setSelectedItem(Aggregates.random(nonRandomAiAvatars).getKey()); - } - else { - lstVanguards.setSelectedItem(Aggregates.random(nonRandomHumanAvatars).getKey()); - } - } - - public void setIsAi(boolean isAi0) { - if (isAi == isAi0) { return; } - isAi = isAi0; - - PaperCard lastSelection = lstVanguards.getSelectedItem(); - - lstVanguards.setPool(isAi ? allAiAvatars : allHumanAvatars, true); - - if (lastSelection != null) { - lstVanguards.setSelectedItem(lastSelection); - } - if (lstVanguards.getSelectedIndex() == -1) { - selectRandom(); - } - } - - public CardManager getLstVanguards() { - return lstVanguards; - } - - @Override - protected void doLayout(float startY, float width, float height) { - float x = PADDING; - float y = startY; - width -= 2 * x; - - float buttonHeight = Utils.AVG_FINGER_HEIGHT; - lstVanguards.setBounds(x, y, width, height - y - buttonHeight - 2 * PADDING); //leave room for buttons at bottom - - y += lstVanguards.getHeight() + PADDING; - btnRandom.setBounds(x, y, width, buttonHeight); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/error/BugReportDialog.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/error/BugReportDialog.java deleted file mode 100644 index 59de3391674..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/error/BugReportDialog.java +++ /dev/null @@ -1,158 +0,0 @@ -package forge.adventure.libgdxgui.error; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.toolbox.FButton; -import forge.adventure.libgdxgui.toolbox.FEvent; -import forge.adventure.libgdxgui.toolbox.FScrollPane; -import forge.adventure.libgdxgui.toolbox.FTextArea; -import forge.adventure.libgdxgui.util.TextBounds; -import forge.adventure.libgdxgui.util.Utils; -import forge.gui.error.BugReporter; -import forge.util.Callback; - -public class BugReportDialog extends FScreen { //use screen rather than dialog so screen with bug isn't rendered - private static final float PADDING = Utils.scale(5); - private static final float BUTTON_HEIGHT = Utils.AVG_FINGER_HEIGHT * 0.75f; - private static boolean isOpen; - - public static void show(String title, String text, boolean showExitAppBtn) { - if (isOpen || Forge.getCurrentScreen() == null) { return; } //don't allow showing if Forge not finished initializing yet - - isOpen = true; - Forge.openScreen(new BugReportDialog(title, text, showExitAppBtn)); - } - - private final FTextArea lblHeader = add(new FTextArea(false, "Report Bug")); - private final TemplateView tvDetails; - private final FButton btnReport = add(new FButton(BugReporter.REPORT)); - private final FButton btnSave = add(new FButton(BugReporter.SAVE)); - private final FButton btnDiscard = add(new FButton(BugReporter.DISCARD)); - private final FButton btnExit = add(new FButton(BugReporter.EXIT)); - - private BugReportDialog(String title, String text0, boolean showExitAppBtn) { - super(title); - lblHeader.setFont(FSkinFont.get(12)); - tvDetails = add(new TemplateView(text0)); - btnReport.setCommand(new FEvent.FEventHandler() { - @Override - public void handleEvent(FEvent e) { - BugReporter.sendSentry(); - Forge.back(); - } - }); - btnSave.setCommand(new FEvent.FEventHandler() { - @Override - public void handleEvent(FEvent e) { - BugReporter.saveToFile(tvDetails.text); - } - }); - btnDiscard.setCommand(new FEvent.FEventHandler() { - @Override - public void handleEvent(FEvent e) { - Forge.back(); - } - }); - if (showExitAppBtn) { - btnExit.setCommand(new FEvent.FEventHandler() { - @Override - public void handleEvent(FEvent e) { - Forge.exit(true); - } - }); - } - else { - btnExit.setVisible(false); - } - } - - @Override - public FScreen getLandscapeBackdropScreen() { - return null; - } - - @Override - public void onClose(Callback canCloseCallback) { - super.onClose(canCloseCallback); - isOpen = false; - } - - @Override - protected void doLayout(float startY, float width, float height) { - float x = PADDING; - float y = startY + PADDING; - float w = width - 2 * PADDING; - - lblHeader.setBounds(x, y, w, lblHeader.getPreferredHeight(w)); - y += lblHeader.getHeight() + PADDING; - - float buttonWidth, totalButtonHeight; - float buttonHeight = BUTTON_HEIGHT; - boolean landscapeMode = Forge.isLandscapeMode(); - if (landscapeMode) { - buttonWidth = (w - 3 * PADDING) / 4; - totalButtonHeight = buttonHeight; - } - else { - buttonWidth = (w - PADDING) / 2; - totalButtonHeight = 2 * buttonHeight + PADDING; - } - - tvDetails.setBounds(x, y, w, height - totalButtonHeight - 2 * PADDING - y); - y += tvDetails.getHeight() + PADDING; - - btnReport.setBounds(x, y, buttonWidth, buttonHeight); - btnSave.setBounds(x + buttonWidth + PADDING, y, buttonWidth, buttonHeight); - if (landscapeMode) { - x += 2 * (buttonWidth + PADDING); - } - else { - y += buttonHeight + PADDING; - } - if (btnExit.isVisible()) { - btnDiscard.setBounds(x, y, buttonWidth, buttonHeight); - btnExit.setBounds(x + buttonWidth + PADDING, y, buttonWidth, buttonHeight); - } - else { - btnDiscard.setBounds(x, y, 2 * buttonWidth + PADDING, buttonHeight); - } - } - - private static class TemplateView extends FScrollPane { - private static final FSkinFont FONT = FSkinFont.get(11); - private static final FSkinColor BACK_COLOR = FSkinColor.get(FSkinColor.Colors.CLR_ZEBRA); - private static final FSkinColor FORE_COLOR = FSkinColor.get(FSkinColor.Colors.CLR_TEXT); - private static final FSkinColor BORDER_COLOR = FSkinColor.get(FSkinColor.Colors.CLR_BORDERS); - private static final float PADDING = Utils.scale(3); - - private final String text; - - private TemplateView(String text0) { - text = text0; - setHeight(Forge.getScreenHeight() / 3); - } - - @Override - protected ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) { - TextBounds bounds = FONT.getMultiLineBounds(text); - return new ScrollBounds(bounds.width + 2 * PADDING, bounds.height + 2 * PADDING + - FONT.getLineHeight() - FONT.getCapHeight()); //account for height below baseline of final line); - } - - @Override - public void drawBackground(Graphics g) { - g.fillRect(BACK_COLOR, 0, 0, getWidth(), getHeight()); - g.drawText(text, FONT, FORE_COLOR, PADDING - getScrollLeft(), PADDING - getScrollTop(), getScrollWidth() - 2 * PADDING, getScrollHeight() - 2 * PADDING, false, Align.left, false); - } - - @Override - public void drawOverlay(Graphics g) { - super.drawOverlay(g); - g.drawRect(1, BORDER_COLOR, 0, 0, getWidth(), getHeight()); - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/CardManager.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/CardManager.java deleted file mode 100644 index 0b09fdb92a6..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/CardManager.java +++ /dev/null @@ -1,92 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager; - -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.card.CardRenderer; -import forge.adventure.libgdxgui.card.CardZoom; -import forge.item.PaperCard; -import forge.adventure.libgdxgui.itemmanager.filters.*; -import forge.adventure.libgdxgui.toolbox.FList; -import forge.adventure.libgdxgui.toolbox.FList.CompactModeHandler; - -import java.util.Map.Entry; - -/** - * ItemManager for cards - */ -public class CardManager extends ItemManager { - public CardManager(boolean wantUnique0) { - super(PaperCard.class, wantUnique0); - } - - @Override - protected void addDefaultFilters() { - addDefaultFilters(this); - } - - @Override - protected TextSearchFilter createSearchFilter() { - return createSearchFilter(this); - } - - @Override - protected AdvancedSearchFilter createAdvancedSearchFilter() { - return createAdvancedSearchFilter(this); - } - - protected void onCardLongPress(int index, Entry value, float x, float y) { - CardZoom.show(model.getOrderedList(), index, CardManager.this); - } - - /* Static overrides shared with SpellShopManager*/ - - public static void addDefaultFilters(final ItemManager itemManager) { - itemManager.addFilter(new CardColorFilter(itemManager)); - itemManager.addFilter(new CardFormatFilter(itemManager)); - itemManager.addFilter(new CardTypeFilter(itemManager)); - } - - public static TextSearchFilter createSearchFilter(final ItemManager itemManager) { - return new CardSearchFilter(itemManager); - } - - public static AdvancedSearchFilter createAdvancedSearchFilter(final ItemManager itemManager) { - return new AdvancedSearchFilter<>(itemManager); - } - - @Override - public ItemRenderer getListItemRenderer(final CompactModeHandler compactModeHandler) { - return new ItemRenderer() { - @Override - public float getItemHeight() { - return CardRenderer.getCardListItemHeight(compactModeHandler.isCompactMode()); - } - - @Override - public void drawValue(Graphics g, Entry value, FSkinFont font, FSkinColor foreColor, FSkinColor backColor, boolean pressed, float x, float y, float w, float h) { - CardRenderer.drawCardListItem(g, font, foreColor, value.getKey(), isInfinite() ? 0 : value.getValue(), getItemSuffix(value), x, y, w, h, compactModeHandler.isCompactMode()); - } - - @Override - public boolean tap(Integer index, Entry value, float x, float y, int count) { - return CardRenderer.cardListItemTap(model.getOrderedList(), index, CardManager.this, x, y, count, compactModeHandler.isCompactMode()); - } - - @Override - public boolean longPress(Integer index, Entry value, float x, float y) { - if (CardRenderer.cardListItemTap(model.getOrderedList(), index, CardManager.this, x, y, 1, compactModeHandler.isCompactMode())) { - return true; //avoid calling onCardLongPress if user long presses on card art - } - onCardLongPress(index, value, x, y); - return true; - } - - @Override - public boolean allowPressEffect(FList> list, float x, float y) { - //only allow press effect if right of card art - return x > CardRenderer.getCardListItemHeight(compactModeHandler.isCompactMode()) * CardRenderer.CARD_ART_RATIO; - } - }; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/DeckManager.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/DeckManager.java deleted file mode 100644 index eaf6440e8b6..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/DeckManager.java +++ /dev/null @@ -1,181 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.FSkinImage; -import forge.adventure.libgdxgui.card.CardFaceSymbols; -import forge.adventure.libgdxgui.card.CardRenderer; -import forge.adventure.libgdxgui.deck.FDeckViewer; -import forge.adventure.libgdxgui.itemmanager.filters.AdvancedSearchFilter; -import forge.adventure.libgdxgui.itemmanager.filters.DeckColorFilter; -import forge.adventure.libgdxgui.itemmanager.filters.DeckFormatFilter; -import forge.adventure.libgdxgui.itemmanager.filters.TextSearchFilter; -import forge.adventure.libgdxgui.toolbox.FList; -import forge.adventure.libgdxgui.toolbox.FList.CompactModeHandler; -import forge.adventure.libgdxgui.util.Utils; -import forge.card.ColorSet; -import forge.deck.DeckProxy; -import forge.deck.io.DeckPreferences; -import forge.game.GameType; -import forge.game.IHasGameType; -import forge.itemmanager.ItemManagerConfig; -import forge.util.Localizer; - -import java.util.Map.Entry; - -/** - * ItemManager for decks - */ -public final class DeckManager extends ItemManager implements IHasGameType { - private final GameType gameType; - - /** - * Creates deck list for selected decks for quick deleting, editing, and - * basic info. "selectable" and "editable" assumed true. - * - * @param gt - */ - public DeckManager(final GameType gt) { - super(DeckProxy.class, true); - gameType = gt; - setCaption(Localizer.getInstance().getMessage("lblDecks")); - } - - public GameType getGameType() { - return gameType; - } - - @Override - public void setup(ItemManagerConfig config0) { - boolean wasStringOnly = (getConfig() == ItemManagerConfig.STRING_ONLY); - boolean isStringOnly = (config0 == ItemManagerConfig.STRING_ONLY); - - super.setup(config0, null); - - if (isStringOnly != wasStringOnly) { - restoreDefaultFilters(); - } - } - - @Override - protected void addDefaultFilters() { - if (getConfig() == ItemManagerConfig.STRING_ONLY) { return; } - - addFilter(new DeckColorFilter(this)); - addFilter(new DeckFormatFilter(this)); - } - - @Override - protected TextSearchFilter createSearchFilter() { - return new TextSearchFilter<>(this); - } - - @Override - protected AdvancedSearchFilter createAdvancedSearchFilter() { - return new AdvancedSearchFilter<>(this); - } - - @Override - protected boolean allowSortChange() { - return false; - } - - private static final float IMAGE_SIZE = CardRenderer.MANA_SYMBOL_SIZE; - - @Override - public ItemRenderer getListItemRenderer(final CompactModeHandler compactModeHandler) { - return new ItemRenderer() { - @Override - public float getItemHeight() { - if (DeckManager.this.getConfig().getCols().size() == 1) { - //if just string column, use normal list item height - return Utils.AVG_FINGER_HEIGHT; - } - return CardRenderer.getCardListItemHeight(compactModeHandler.isCompactMode()); //use same height for decks as for cards - } - - @Override - public boolean tap(Integer index, Entry value, float x, float y, int count) { - float bottomRight = IMAGE_SIZE + 2 * FList.PADDING; - if (x <= bottomRight && y <= bottomRight) { - DeckPreferences prefs = DeckPreferences.getPrefs(value.getKey()); - prefs.setStarCount((prefs.getStarCount() + 1) % 2); //TODO: consider supporting more than 1 star - return true; - } - return false; - } - - @Override - public boolean longPress(Integer index, Entry value, float x, float y) { - FDeckViewer.show(value.getKey().getDeck()); - return true; - } - - @Override - public void drawValue(Graphics g, Entry value, FSkinFont font, FSkinColor foreColor, FSkinColor backColor, boolean pressed, float x, float y, float w, float h) { - DeckProxy deck = value.getKey(); - - if (DeckManager.this.getConfig().getCols().size() == 1) { - //if just string column, just draw deck string value - g.drawText(deck.toString(), font, foreColor, x, y, w, h, false, Align.left, true); - return; - } - - //draw favorite, name, path and color on first line - if (Forge.hdbuttons) - g.drawImage(DeckPreferences.getPrefs(deck).getStarCount() > 0 ? - FSkinImage.HDSTAR_FILLED : FSkinImage.HDSTAR_OUTLINE, x, y, IMAGE_SIZE, IMAGE_SIZE); - else - g.drawImage(DeckPreferences.getPrefs(deck).getStarCount() > 0 ? FSkinImage.STAR_FILLED : FSkinImage.STAR_OUTLINE, x, y, IMAGE_SIZE, IMAGE_SIZE); - - x += IMAGE_SIZE + FList.PADDING; - ColorSet deckColor = deck.getColor(); - float availableNameWidth = w - CardFaceSymbols.getWidth(deckColor, IMAGE_SIZE) - IMAGE_SIZE - 2 * FList.PADDING; - String name = deck.getName(); - if (!deck.getPath().isEmpty()) { //render path after name if needed - name += " (" + deck.getPath().substring(1) + ")"; - } - g.drawText(name, font, foreColor, x, y, availableNameWidth, IMAGE_SIZE, false, Align.left, true); - x += availableNameWidth + FList.PADDING; - CardFaceSymbols.drawColorSet(g, deckColor, x, y, IMAGE_SIZE); - - if (compactModeHandler.isCompactMode()) { - return; //skip second line if compact mode - } - - //draw formats, main/side, and set/highest rarity on second line - font = FSkinFont.get(12); - float lineHeight = font.getLineHeight(); - - x = FList.PADDING; - y += IMAGE_SIZE + FList.PADDING + CardRenderer.SET_BOX_MARGIN; - String set = deck.getEdition().getCode(); - float setWidth = CardRenderer.getSetWidth(font, set); - float availableFormatWidth = w - setWidth + CardRenderer.SET_BOX_MARGIN; - - int mainSize = deck.getMainSize(); - if (mainSize < 0) { - mainSize = 0; //show main as 0 if empty - } - int sideSize = deck.getSideSize(); - if (sideSize < 0) { - sideSize = 0; //show sideboard as 0 if empty - } - - g.drawText(deck.getFormatsString() + " (" + mainSize + " / " + sideSize + ")", font, foreColor, x, y, availableFormatWidth, lineHeight, false, Align.left, true); - - x += availableFormatWidth + CardRenderer.SET_BOX_MARGIN; - y -= CardRenderer.SET_BOX_MARGIN; - CardRenderer.drawSetLabel(g, font, set, deck.getHighestRarity(), x, y, setWidth, lineHeight + 2 * CardRenderer.SET_BOX_MARGIN); - } - - @Override - public boolean allowPressEffect(FList> list, float x, float y) { - return true; - } - }; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/ItemManager.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/ItemManager.java deleted file mode 100644 index 98cc8634542..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/ItemManager.java +++ /dev/null @@ -1,984 +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.adventure.libgdxgui.itemmanager; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.utils.Align; -import com.google.common.base.Function; -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import com.google.common.collect.Iterables; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.FSkinImage; -import forge.adventure.libgdxgui.card.CardZoom.ActivateHandler; -import forge.adventure.libgdxgui.itemmanager.filters.AdvancedSearchFilter; -import forge.adventure.libgdxgui.itemmanager.filters.ItemFilter; -import forge.adventure.libgdxgui.itemmanager.filters.TextSearchFilter; -import forge.adventure.libgdxgui.itemmanager.views.ImageView; -import forge.adventure.libgdxgui.itemmanager.views.ItemListView; -import forge.adventure.libgdxgui.itemmanager.views.ItemView; -import forge.adventure.libgdxgui.menu.FDropDownMenu; -import forge.adventure.libgdxgui.menu.FMenuItem; -import forge.adventure.libgdxgui.menu.FPopupMenu; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.toolbox.*; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventType; -import forge.adventure.libgdxgui.toolbox.FList.CompactModeHandler; -import forge.adventure.libgdxgui.util.LayoutHelper; -import forge.gui.FThreads; -import forge.item.InventoryItem; -import forge.itemmanager.*; -import forge.util.ItemPool; -import forge.util.Localizer; - -import java.util.*; -import java.util.Map.Entry; - - -public abstract class ItemManager extends FContainer implements IItemManager, ActivateHandler { - private ItemPool pool; - protected final ItemManagerModel model; - private Predicate filterPredicate = null; - private AdvancedSearchFilter advancedSearchFilter; - private final List> filters = new ArrayList<>(); - private boolean hideFilters = false; - private boolean wantUnique = false; - private boolean multiSelectMode = false; - private FEventHandler selectionChangedHandler, itemActivateHandler; - private ContextMenuBuilder contextMenuBuilder; - private ContextMenu contextMenu; - private final Class genericType; - private ItemManagerConfig config; - private Function, Object> fnNewGet; - private boolean viewUpdating, needSecondUpdate; - private final List sortCols = new ArrayList<>(); - - private final TextSearchFilter searchFilter; - - private final FLabel btnSearch = new FLabel.ButtonBuilder() - .icon(Forge.hdbuttons ? FSkinImage.HDSEARCH : FSkinImage.SEARCH).iconScaleFactor(0.9f).build(); - private final FLabel btnView = new FLabel.ButtonBuilder() - .iconScaleFactor(0.9f).build(); //icon set later - private final FLabel btnAdvancedSearchOptions = new FLabel.Builder() - .selectable(true).align(Align.center) - .icon(Forge.hdbuttons ? FSkinImage.HDPREFERENCE : FSkinImage.SETTINGS).iconScaleFactor(0.9f) - .build(); - - private final FComboBox cbxSortOptions; - - private final List> views = new ArrayList<>(); - private final ItemListView listView; - private final ImageView imageView; - private ItemView currentView; - private final boolean initialized; - protected boolean lockFiltering; - - /** - * ItemManager Constructor. - * - * @param genericType0 the class of item that this table will contain - * @param wantUnique0 whether this table should display only one item with the same name - */ - protected ItemManager(final Class genericType0, final boolean wantUnique0) { - genericType = genericType0; - wantUnique = wantUnique0; - model = new ItemManagerModel<>(genericType0); - - searchFilter = createSearchFilter(); - - listView = new ItemListView(this, model); - imageView = createImageView(model); - - views.add(listView); - views.add(imageView); - currentView = listView; - btnView.setIcon(currentView.getIcon()); - - //build display - add(searchFilter.getWidget()); - add(btnSearch); - add(btnView); - add(btnAdvancedSearchOptions); - btnAdvancedSearchOptions.setSelected(!hideFilters); - if (allowSortChange()) { - cbxSortOptions = add(new FComboBox<>(Localizer.getInstance().getMessage("lblSort") + ": ")); - cbxSortOptions.setFont(FSkinFont.get(12)); - } - else { - cbxSortOptions = null; - } - add(currentView.getPnlOptions()); - add(currentView.getScroller()); - - btnSearch.setCommand(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - FPopupMenu menu = new FPopupMenu() { - @Override - protected void buildMenu() { - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblAdvancedSearch"), Forge.hdbuttons ? FSkinImage.HDSEARCH : FSkinImage.SEARCH, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - if (advancedSearchFilter == null) { - advancedSearchFilter = createAdvancedSearchFilter(); - ItemManager.this.add(advancedSearchFilter.getWidget()); - } - advancedSearchFilter.edit(); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblResetFilters"), Forge.hdbuttons ? FSkinImage.HDDELETE : FSkinImage.DELETE, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - resetFilters(); - } - })); - } - }; - menu.show(btnSearch, 0, btnSearch.getHeight()); - } - }); - btnView.setCommand(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - FPopupMenu menu = new FPopupMenu() { - @Override - protected void buildMenu() { - for (int i = 0; i < views.size(); i++) { - final int index = i; - ItemView view = views.get(i); - FMenuItem item = new FMenuItem(view.getCaption(), view.getIcon(), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - setViewIndex(index); - } - }); - if (currentView == view) { - item.setSelected(true); - } - addItem(item); - } - } - }; - menu.show(btnView, 0, btnView.getHeight()); - } - }); - btnAdvancedSearchOptions.setCommand(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - setHideFilters(!hideFilters); - } - }); - - //setup initial filters - addDefaultFilters(); - - initialized = true; //must set flag just before applying filters - if (!applyFilters()) { - if (pool != null) { //ensure view updated even if filter predicate didn't change - updateView(true, null); - } - } - } - - protected ImageView createImageView(final ItemManagerModel model0) { - return new ImageView(this, model0); - } - - public ItemManagerConfig getConfig() { - return config; - } - - public void setup(ItemManagerConfig config0) { - setup(config0, null); - } - public void setup(ItemManagerConfig config0, Map colOverrides) { - config = config0; - setWantUnique(config0.getUniqueCardsOnly()); - - //ensure sort cols ordered properly - final List cols = new LinkedList<>(); - for (ItemColumnConfig colConfig : config.getCols().values()) { - if (colOverrides == null || !colOverrides.containsKey(colConfig.getDef())) { - cols.add(new ItemColumn(colConfig)); - } - else { - cols.add(colOverrides.get(colConfig.getDef())); - } - } - Collections.sort(cols, new Comparator() { - @Override - public int compare(ItemColumn arg0, ItemColumn arg1) { - return Integer.compare(arg0.getConfig().getIndex(), arg1.getConfig().getIndex()); - } - }); - - sortCols.clear(); - if (cbxSortOptions != null) { - cbxSortOptions.setDropDownItemTap(null); - cbxSortOptions.removeAllItems(); - } - - int modelIndex = 0; - for (final ItemColumn col : cols) { - col.setIndex(modelIndex++); - if (col.isVisible()) { sortCols.add(col); } - } - - final ItemColumn[] sortcols = new ItemColumn[sortCols.size()]; - - // Assemble priority sort. - for (ItemColumn col : sortCols) { - if (cbxSortOptions != null) { - cbxSortOptions.addItem(col); - } - if (col.getSortPriority() > 0 && col.getSortPriority() <= sortcols.length) { - sortcols[col.getSortPriority() - 1] = col; - } - } - - if (cbxSortOptions != null) { - cbxSortOptions.setText("(" + Localizer.getInstance().getMessage("lblNone") + ")"); - } - - model.getCascadeManager().reset(); - - for (int i = sortcols.length - 1; i >= 0; i--) { - ItemColumn col = sortcols[i]; - if (col != null) { - model.getCascadeManager().add(col, true); - if (cbxSortOptions != null) { - cbxSortOptions.setSelectedItem(col); - } - } - } - - if (cbxSortOptions != null) { - cbxSortOptions.setDropDownItemTap(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - model.getCascadeManager().add((ItemColumn)e.getArgs(), false); - model.refreshSort(); - ItemManagerConfig.save(); - updateView(true, null); - } - }); - } - - for (ItemView view : views) { - view.setup(config0, colOverrides); - } - setViewIndex(config0.getViewIndex()); - setHideFilters(config0.getHideFilters()); - - if (colOverrides == null || !colOverrides.containsKey(ColumnDef.NEW)) { - fnNewGet = null; - } - else { - fnNewGet = colOverrides.get(ColumnDef.NEW).getFnDisplay(); - } - } - - protected boolean allowSortChange() { - return true; - } - - protected String getItemSuffix(Entry item) { - if (fnNewGet != null) { - String suffix = fnNewGet.apply(item).toString(); - if (!suffix.isEmpty()) { - return " *" + suffix + "*"; - } - } - return null; - } - - public abstract class ItemRenderer { - public abstract float getItemHeight(); - public abstract boolean allowPressEffect(FList> list, float x, float y); - public abstract boolean tap(Integer index, Entry value, float x, float y, int count); - public abstract boolean longPress(Integer index, Entry value, float x, float y); - public abstract void drawValue(Graphics g, Entry value, FSkinFont font, FSkinColor foreColor, FSkinColor backColor, boolean pressed, float x, float y, float w, float h); - } - public abstract ItemRenderer getListItemRenderer(final CompactModeHandler compactModeHandler); - - public void setViewIndex(int viewIndex) { - if (viewIndex < 0 || viewIndex >= views.size()) { return; } - ItemView view = views.get(viewIndex); - if (currentView == view) { return; } - - if (config != null) { - config.setViewIndex(viewIndex); - } - - final int backupIndexToSelect = currentView.getSelectedIndex(); - final Iterable itemsToSelect; //only retain selected items if not single selection of first item - if (backupIndexToSelect > 0 || currentView.getSelectionCount() > 1) { - itemsToSelect = currentView.getSelectedItems(); - } - else { - itemsToSelect = null; - } - - remove(currentView.getPnlOptions()); - remove(currentView.getScroller()); - - currentView = view; - btnView.setIcon(view.getIcon()); - - view.refresh(itemsToSelect, backupIndexToSelect, 0); - - add(view.getPnlOptions()); - add(view.getScroller()); - revalidate(); - } - - @Override - public void doLayout(float width, float height) { - LayoutHelper helper = new LayoutHelper(this, ItemFilter.PADDING, ItemFilter.PADDING); - float fieldHeight = searchFilter.getMainComponent().getHeight(); - float viewButtonWidth = fieldHeight; - helper.offset(0, ItemFilter.PADDING); - helper.fillLine(searchFilter.getWidget(), fieldHeight, (viewButtonWidth + helper.getGapX()) * 3); //leave room for search, view, and options buttons - helper.include(btnSearch, viewButtonWidth, fieldHeight); - helper.include(btnView, viewButtonWidth, fieldHeight); - helper.include(btnAdvancedSearchOptions, viewButtonWidth, fieldHeight); - helper.newLine(); - if (advancedSearchFilter != null && advancedSearchFilter.getWidget().isVisible()) { - helper.fillLine(advancedSearchFilter.getWidget(), fieldHeight); - } - if (!hideFilters) { - for (ItemFilter filter : filters) { - helper.include(filter.getWidget(), filter.getPreferredWidth(helper.getRemainingLineWidth(), fieldHeight), fieldHeight); - } - if (allowSortChange()) { - helper.fillLine(cbxSortOptions, fieldHeight); - } - helper.newLine(-ItemFilter.PADDING); - if (currentView.getPnlOptions().getChildCount() > 0) { - helper.fillLine(currentView.getPnlOptions(), fieldHeight + ItemFilter.PADDING); - } - else { - helper.offset(0, -fieldHeight); //prevent showing whitespace for empty view options panel - } - } - helper.fill(currentView.getScroller()); - } - - public Class getGenericType() { - return genericType; - } - - public String getCaption() { - return searchFilter.getCaption(); - } - public void setCaption(String caption0) { - searchFilter.setCaption(caption0); - } - - public ItemPool getPool() { - return pool; - } - public void setPool(final Iterable items) { - setPool(ItemPool.createFrom(items, genericType), false); - } - public void setPool(final ItemPool pool0) { - setPool(pool0, false); - } - public void setPool(final ItemPool pool0, boolean infinite) { - pool = pool0; - model.clear(); - model.addItems(pool); - model.setInfinite(infinite); - updateView(true, null); - } - - public ItemView getCurrentView() { - return currentView; - } - - public int getItemCount() { - return currentView.getCount(); - } - - public int getSelectionCount() { - return currentView.getSelectionCount(); - } - - public T getSelectedItem() { - return currentView.getSelectedItem(); - } - - public Collection getSelectedItems() { - return currentView.getSelectedItems(); - } - - public ItemPool getSelectedItemPool() { - ItemPool selectedItemPool = new ItemPool<>(genericType); - if (currentView == listView) { - for (T item : getSelectedItems()) { - selectedItemPool.add(item, getItemCount(item)); - } - } - else { //just add all flat for image view - selectedItemPool.addAllFlat(getSelectedItems()); - } - return selectedItemPool; - } - - public boolean setSelectedItem(T item) { - return currentView.setSelectedItem(item); - } - - public boolean setSelectedItems(Iterable items) { - return currentView.setSelectedItems(items); - } - - public T stringToItem(String str) { - for (Entry itemEntry : pool) { - if (itemEntry.getKey().toString().equals(str)) { - return itemEntry.getKey(); - } - } - return null; - } - - public boolean setSelectedString(String str) { - T item = stringToItem(str); - if (item != null) { - return setSelectedItem(item); - } - return false; - } - - public boolean setSelectedStrings(Iterable strings) { - List items = new ArrayList<>(); - for (String str : strings) { - T item = stringToItem(str); - if (item != null) { - items.add(item); - } - } - return setSelectedItems(items); - } - - public boolean selectItemEntrys(Iterable> itemEntrys) { - List items = new ArrayList<>(); - for (Entry itemEntry : itemEntrys) { - items.add(itemEntry.getKey()); - } - return setSelectedItems(items); - } - - public void selectAll() { - currentView.selectAll(); - } - - public int getSelectedIndex() { - return currentView.getSelectedIndex(); - } - - public Iterable getSelectedIndices() { - return currentView.getSelectedIndices(); - } - - public void setSelectedIndex(int index) { - currentView.setSelectedIndex(index); - } - - public void setSelectedIndices(Integer[] indices) { - currentView.setSelectedIndices(Arrays.asList(indices)); - } - public void setSelectedIndices(Iterable indices) { - currentView.setSelectedIndices(indices); - } - - public void addItem(final T item, int qty) { - pool.add(item, qty); - if (isUnfiltered()) { - model.addItem(item, qty); - } - List items = new ArrayList<>(); - items.add(item); - updateView(false, items); - } - - public void addItems(Iterable> itemsToAdd) { - pool.addAll(itemsToAdd); - if (isUnfiltered()) { - model.addItems(itemsToAdd); - } - - List items = new ArrayList<>(); - for (Entry item : itemsToAdd) { - items.add(item.getKey()); - } - updateView(false, items); - } - - public void addItemsFlat(Iterable itemsToAdd) { - pool.addAllFlat(itemsToAdd); - if (isUnfiltered()) { - for (T item : itemsToAdd) { - model.addItem(item, 1); - } - } - updateView(false, itemsToAdd); - } - - public void setItems(Iterable> items) { - pool.clear(); - model.clear(); - addItems(items); - } - - public void removeItem(final T item, int qty) { - final Iterable itemsToSelect = currentView == listView ? getSelectedItems() : null; - - pool.remove(item, qty); - if (isUnfiltered()) { - model.removeItem(item, qty); - } - updateView(false, itemsToSelect); - } - - public void removeItems(Iterable> itemsToRemove) { - final Iterable itemsToSelect = currentView == listView ? getSelectedItems() : null; - - for (Entry item : itemsToRemove) { - pool.remove(item.getKey(), item.getValue()); - if (isUnfiltered()) { - model.removeItem(item.getKey(), item.getValue()); - } - } - updateView(false, itemsToSelect); - } - - public void removeItemsFlat(Iterable itemsToRemove) { - final Iterable itemsToSelect = currentView == listView ? getSelectedItems() : null; - - pool.removeAllFlat(itemsToRemove); - if (isUnfiltered()) { - for (T item : itemsToRemove) { - model.removeItem(item, 1); - } - } - updateView(false, itemsToSelect); - } - - public void removeAllItems() { - pool.clear(); - model.clear(); - updateView(false, null); - } - - public void replaceAll(final T item, final T replacement) { - int count = pool.count(item); - if (count == 0) { return; } - - final Iterable itemsToSelect = currentView == listView ? getSelectedItems() : null; - - pool.removeAll(item); - pool.add(replacement, count); - if (isUnfiltered()) { - model.replaceAll(item, replacement); - } - updateView(false, itemsToSelect); - } - - public void scrollSelectionIntoView() { - currentView.scrollSelectionIntoView(); - } - - public int getItemCount(final T item) { - return model.isInfinite() ? Integer.MAX_VALUE : pool.count(item); - } - - public ItemPool getFilteredItems() { - return model.getItems(); - } - - protected abstract void addDefaultFilters(); - protected abstract TextSearchFilter createSearchFilter(); - protected abstract AdvancedSearchFilter createAdvancedSearchFilter(); - - public void addFilter(final ItemFilter filter) { - filters.add(filter); - add(filter.getWidget()); - - boolean visible = !hideFilters; - filter.getWidget().setVisible(visible); - if (visible && initialized) { - revalidate(); - applyNewOrModifiedFilter(filter); - } - } - - //apply filters and focus existing filter's main component if filtering not locked - public void applyNewOrModifiedFilter(final ItemFilter filter) { - if (lockFiltering) { return; } - - if (filter == advancedSearchFilter) { - //handle update the visibility of the advanced search filter - boolean empty = filter.isEmpty(); - ItemFilter.Widget widget = filter.getWidget(); - if (widget.isVisible() == empty) { - widget.setVisible(!empty); - revalidate(); - } - } - - applyFilters(); - } - - public void restoreDefaultFilters() { - lockFiltering = true; - for (ItemFilter filter : filters) { - remove(filter.getWidget()); - } - filters.clear(); - addDefaultFilters(); - lockFiltering = false; - revalidate(); - applyFilters(); - } - - public void resetFilters() { - lockFiltering = true; //prevent updating filtering from this change until all filters reset - for (final ItemFilter filter : filters) { - filter.reset(); - } - searchFilter.reset(); - if (advancedSearchFilter != null) { - advancedSearchFilter.reset(); - ItemFilter.Widget widget = advancedSearchFilter.getWidget(); - if (widget.isVisible()) { - widget.setVisible(false); - revalidate(); - } - } - lockFiltering = false; - - applyFilters(); - } - - public void removeFilter(ItemFilter filter) { - filters.remove(filter); - remove(filter.getWidget()); - revalidate(); - applyFilters(); - } - - public boolean applyFilters() { - if (lockFiltering || !initialized) { return false; } - - List> predicates = new ArrayList<>(); - for (ItemFilter filter : filters) { - if (!filter.isEmpty()) { - predicates.add(filter.buildPredicate(genericType)); - } - } - if (!searchFilter.isEmpty()) { - predicates.add(searchFilter.buildPredicate(genericType)); - } - if (advancedSearchFilter != null && !advancedSearchFilter.isEmpty()) { - predicates.add(advancedSearchFilter.buildPredicate(genericType)); - } - - Predicate newFilterPredicate = predicates.size() == 0 ? null : Predicates.and(predicates); - if (filterPredicate == newFilterPredicate) { return false; } - - filterPredicate = newFilterPredicate; - if (pool != null) { - if (viewUpdating) { - needSecondUpdate = true; - } - else { - viewUpdating = true; - FThreads.invokeInBackgroundThread(new Runnable() { - @Override - public void run() { - do { - needSecondUpdate = false; - updateView(true, null); - Gdx.graphics.requestRendering(); - } while (needSecondUpdate); - viewUpdating = false; - } - }); - } - } - return true; - } - - private boolean isUnfiltered() { - return filterPredicate == null; - } - - public boolean getHideFilters() { - return hideFilters; - } - - public void setHideFilters(boolean hideFilters0) { - if (hideFilters == hideFilters0) { return; } - hideFilters = hideFilters0; - - boolean visible = !hideFilters0; - for (ItemFilter filter : filters) { - filter.getWidget().setVisible(visible); - } - if (allowSortChange()) { - cbxSortOptions.setVisible(visible); - } - for (ItemView view : views) { - view.getPnlOptions().setVisible(visible); - } - - if (initialized) { - btnAdvancedSearchOptions.setSelected(visible); - - revalidate(); - - if (config != null) { - config.setHideFilters(hideFilters0); - } - } - } - - //Refresh displayed items - public void refresh() { - updateView(true, getSelectedItems()); - } - - public void updateView(final boolean forceFilter, final Iterable itemsToSelect) { - final boolean useFilter = (forceFilter && (filterPredicate != null)) || !isUnfiltered(); - - if (useFilter || forceFilter) { - model.clear(); - - Iterable> items = pool; - if (useFilter) { - Predicate> pred = Predicates.compose(filterPredicate, pool.FN_GET_KEY); - items = Iterables.filter(pool, pred); - } - model.addItems(items); - } - - currentView.refresh(itemsToSelect, getSelectedIndex(), forceFilter ? 0 : currentView.getScrollValue()); - - //update ratio of # in filtered pool / # in total pool - ItemPool filteredItems = getFilteredItems(); - int filteredCount = filteredItems.countAll(); - int totalCount = useFilter ? pool.countAll() : filteredCount; - - searchFilter.setRatio("(" + filteredCount + " / " + totalCount + ")"); - } - - public boolean isIncrementalSearchActive() { - return currentView.isIncrementalSearchActive(); - } - - public boolean getWantUnique() { - return wantUnique; - } - - public void setWantUnique(boolean unique) { - wantUnique = unique; - } - - public void setSelectionSupport(int minSelections0, int maxSelections0) { - for (ItemView view : views) { - view.setSelectionSupport(minSelections0, maxSelections0); - } - } - - public boolean getMultiSelectMode() { - return multiSelectMode; - } - public void toggleMultiSelectMode(int indexToSelect) { - multiSelectMode = !multiSelectMode; - if (multiSelectMode) { - setSelectionSupport(0, Integer.MAX_VALUE); - } - else { - setSelectionSupport(0, 1); - } - if (isContextMenuOpen()) { - contextMenu.hide(); //ensure context menu hidden - } - if (indexToSelect != -1) { - setSelectedIndex(indexToSelect); - } - } - - //whether item manager's pool of items is in infinite supply - public boolean isInfinite() { - return model.isInfinite(); - } - - public void focusSearch() { - setHideFilters(false); //ensure filters shown - } - - public FEventHandler getSelectionChangedHandler() { - return selectionChangedHandler; - } - public void setSelectionChangedHandler(FEventHandler selectionChangedHandler0) { - selectionChangedHandler = selectionChangedHandler0; - } - - public void setItemActivateHandler(FEventHandler itemActivateHandler0) { - itemActivateHandler = itemActivateHandler0; - } - - public void activateSelectedItems() { - if (itemActivateHandler != null) { - itemActivateHandler.handleEvent(new FEvent(this, FEventType.ACTIVATE)); - } - } - - public void setContextMenuBuilder(ContextMenuBuilder contextMenuBuilder0) { - contextMenuBuilder = contextMenuBuilder0; - } - - public void showMenu(boolean delay) { - if (contextMenuBuilder != null && getSelectionCount() > 0) { - if (contextMenu == null) { - contextMenu = new ContextMenu(); - } - if (delay) { //delay showing menu to prevent it hiding right away - FThreads.delayInEDT(50, new Runnable() { - @Override - public void run() { - contextMenu.show(); - Gdx.graphics.requestRendering(); - } - }); - } - else { - contextMenu.show(); - } - } - } - - public boolean isContextMenuOpen() { - return contextMenu != null && contextMenu.isVisible(); - } - - public static abstract class ContextMenuBuilder { - public abstract void buildMenu(final FDropDownMenu menu, final T item); - } - - private class ContextMenu extends FDropDownMenu { - @Override - protected void buildMenu() { - contextMenuBuilder.buildMenu(this, getSelectedItem()); - } - - @Override - protected boolean hideBackdropOnPress(float x, float y) { - Rectangle bounds = currentView.getSelectionBounds(); - return bounds != null && !bounds.contains(x, y); //don't hide on press if within selection bounds - } - - @Override - protected boolean preventOwnerHandlingBackupTap(float x, float y, int count) { - //prevent view handling single tap, but allow it to handle double tap - return count == 1; - } - - @Override - protected void updateSizeAndPosition() { - FScreen screen = Forge.getCurrentScreen(); - float screenWidth = screen.getWidth(); - float screenHeight = screen.getHeight(); - - paneSize = updateAndGetPaneSize(screenWidth, screenHeight); - float w = paneSize.getWidth(); - float h = paneSize.getHeight(); - - Rectangle bounds = currentView.getSelectionBounds(); - - //try displaying right of selection if possible - float x = bounds.x + bounds.width; - float y = bounds.y; - if (x + w > screenWidth) { - //try displaying left of selection if possible - x = bounds.x - w; - if (x < 0) { - //display below selection if no room left or right of selection - x = bounds.x; - if (w < bounds.width) { - //center below item if needed - x += (bounds.width - w) / 2; - } - if (x + w > screenWidth) { - x = screenWidth - w; - } - y += bounds.height; - } - } - if (y + h > screenHeight) { - if (y == bounds.y) { - //if displaying to left or right, move up if not enough room - y = screenHeight - h; - } - else { - //if displaying below selection and not enough room, display above selection - y -= bounds.height + h; - } - if (y < 0) { - y = 0; - if (h > bounds.y) { - h = bounds.y; //cut off menu if not enough room above or below selection - } - } - } - - setBounds(Math.round(x), Math.round(y), Math.round(w), Math.round(h)); - } - } - - @Override - public String getActivateAction(int index) { - if (contextMenuBuilder != null) { - return Localizer.getInstance().getMessage("lblSelectCard"); - } - return null; - } - - @Override - public void activate(int index) { - setSelectedIndex(index); - showMenu(true); - } - - public float getPileByWidth() { - if (cbxSortOptions != null) { - return cbxSortOptions.getWidth(); - } - if(filters.isEmpty()){ - return 0f; - } - return filters.get(filters.size() - 1).getWidget().getWidth(); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/SpellShopManager.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/SpellShopManager.java deleted file mode 100644 index 576aab3ce08..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/SpellShopManager.java +++ /dev/null @@ -1,121 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager; - -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.utils.Align; -import com.google.common.base.Function; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.FSkinImage; -import forge.adventure.libgdxgui.assets.ImageCache; -import forge.adventure.libgdxgui.card.CardRenderer; -import forge.gamemodes.quest.QuestSpellShop; -import forge.item.InventoryItem; -import forge.item.PaperCard; -import forge.adventure.libgdxgui.itemmanager.filters.AdvancedSearchFilter; -import forge.adventure.libgdxgui.itemmanager.filters.TextSearchFilter; -import forge.adventure.libgdxgui.toolbox.FList; -import forge.adventure.libgdxgui.toolbox.FList.CompactModeHandler; -import forge.util.Localizer; - -import java.util.Map.Entry; - - -public class SpellShopManager extends ItemManager { - private final Function, Object> fnGetPrice; - - public SpellShopManager(boolean isShop0) { - super(InventoryItem.class, false); - - fnGetPrice = isShop0 ? QuestSpellShop.fnPriceGet : QuestSpellShop.fnPriceSellGet; - if (!isShop0) { - setCaption(Localizer.getInstance().getMessage("lblCards")); - } - } - - @Override - protected void addDefaultFilters() { - CardManager.addDefaultFilters(this); - } - - @Override - protected TextSearchFilter createSearchFilter() { - return CardManager.createSearchFilter(this); - } - - @Override - protected AdvancedSearchFilter createAdvancedSearchFilter() { - return CardManager.createAdvancedSearchFilter(this); - } - - @Override - public ItemRenderer getListItemRenderer(final CompactModeHandler compactModeHandler) { - return new ItemRenderer() { - @Override - public float getItemHeight() { - return CardRenderer.getCardListItemHeight(compactModeHandler.isCompactMode()); - } - - @Override - public void drawValue(Graphics g, Entry value, FSkinFont font, FSkinColor foreColor, FSkinColor backColor, boolean pressed, float x, float y, float w, float h) { - if (value.getValue() == null) { return; } //prevent crash after item removed on different thread - - float totalHeight = h + 2 * FList.PADDING; - float cardArtWidth = totalHeight * CardRenderer.CARD_ART_RATIO; - - if (value.getKey() instanceof PaperCard) { - CardRenderer.drawCardListItem(g, font, foreColor, (PaperCard)value.getKey(), value.getValue(), getItemSuffix(value), x, y, w, h, compactModeHandler.isCompactMode()); - } - else { - g.drawText(value.getValue() + " " + value.getKey().toString(), font, foreColor, x + cardArtWidth, y, w - cardArtWidth, h, false, Align.left, true); - Texture image = ImageCache.getImage(value.getKey()); - if (image != null) { - float imageRatio = (float)image.getWidth() / (float)image.getHeight(); - float imageHeight = totalHeight; - float imageWidth = imageHeight * imageRatio; - if (imageWidth > cardArtWidth) { - imageWidth = cardArtWidth; - imageHeight = imageWidth / imageRatio; - } - g.drawImage(image, x - FList.PADDING + (cardArtWidth - imageWidth) / 2, y - FList.PADDING + (totalHeight - imageHeight) / 2, imageWidth, imageHeight); - } - } - - //render price on top of card art - float priceHeight = font.getLineHeight(); - y += totalHeight - priceHeight - FList.PADDING; - g.fillRect(backColor, x - FList.PADDING, y, cardArtWidth, priceHeight); - g.drawImage(FSkinImage.QUEST_COINSTACK, x, y, priceHeight, priceHeight); - float offset = priceHeight * 1.1f; - g.drawText(fnGetPrice.apply(value).toString(), font, foreColor, x + offset, y, cardArtWidth - offset - 2 * FList.PADDING, priceHeight, false, Align.left, true); - } - - @Override - public boolean tap(Integer index, Entry value, float x, float y, int count) { - if (value.getKey() instanceof PaperCard) { - return CardRenderer.cardListItemTap(model.getOrderedList(), index, SpellShopManager.this, x, y, count, compactModeHandler.isCompactMode()); - } - return false; - } - - @Override - public boolean longPress(Integer index, Entry value, float x, float y) { - if (value.getKey() instanceof PaperCard && CardRenderer.cardListItemTap(model.getOrderedList(), index, SpellShopManager.this, x, y, 1, compactModeHandler.isCompactMode())) { - return true; //avoid calling toggleMultiSelectMode if user long presses on card art - } - toggleMultiSelectMode(index); - return true; - } - - @Override - public boolean allowPressEffect(FList> list, float x, float y) { - Entry value = list.getItemAtPoint(x, y); - if (value != null && value.getKey() instanceof PaperCard) { - //only allow press effect for cards if right of card art - return x > CardRenderer.getCardListItemHeight(compactModeHandler.isCompactMode()) * CardRenderer.CARD_ART_RATIO; - } - return true; - } - }; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/AdvancedSearchFilter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/AdvancedSearchFilter.java deleted file mode 100644 index 66bbf369e82..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/AdvancedSearchFilter.java +++ /dev/null @@ -1,328 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.filters; - -import com.badlogic.gdx.utils.Align; -import com.google.common.base.Predicate; -import com.google.common.collect.Iterables; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.assets.FSkinImage; -import forge.adventure.libgdxgui.assets.TextRenderer; -import forge.adventure.libgdxgui.itemmanager.ItemManager; -import forge.adventure.libgdxgui.menu.FMenuItem; -import forge.adventure.libgdxgui.menu.FPopupMenu; -import forge.adventure.libgdxgui.menu.FTooltip; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.toolbox.*; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.gui.interfaces.IButton; -import forge.item.InventoryItem; -import forge.itemmanager.AdvancedSearch; -import forge.itemmanager.AdvancedSearch.IFilterControl; -import forge.util.Callback; -import forge.util.Localizer; - - -public class AdvancedSearchFilter extends ItemFilter { - private final AdvancedSearch.Model model; - - private FiltersLabel label; - private EditScreen editScreen; - - public AdvancedSearchFilter(ItemManager itemManager0) { - super(itemManager0); - model = new AdvancedSearch.Model<>(); - } - - @Override - public ItemFilter createCopy() { - AdvancedSearchFilter copy = new AdvancedSearchFilter<>(itemManager); - return copy; - } - - @Override - protected final Predicate buildPredicate() { - return model.getPredicate(); - } - - public Predicate getPredicate() { - return model.getPredicate(); - } - - public void edit() { - if (editScreen == null) { - editScreen = new EditScreen(); - } - Forge.openScreen(editScreen); - } - - @Override - public boolean isEmpty() { - return model.isEmpty(); - } - - @Override - public void reset() { - model.reset(); - editScreen = null; - } - - @Override - protected void buildWidget(Widget widget) { - label = new FiltersLabel(); - model.setLabel(label); - widget.add(label); - widget.setVisible(!isEmpty()); - } - - @Override - protected void doWidgetLayout(float width, float height) { - label.setSize(width, height); - } - - private final Runnable onFilterChange = new Runnable() { - @Override - public void run() { - //update expression when edit screen closed or a single filter is changed - model.updateExpression(); - itemManager.applyNewOrModifiedFilter(AdvancedSearchFilter.this); - } - }; - - private class FiltersLabel extends FLabel { - private String toolTipText; - - private FiltersLabel() { - super(new FLabel.Builder().align(Align.left).parseSymbols(true).font(ListLabelFilter.LABEL_FONT)); - } - - @Override - public String getToolTipText() { - return toolTipText; - } - @Override - public void setToolTipText(String s0) { - toolTipText = s0; - } - - @Override - public boolean tap(float x, float y, int count) { - if (count == 1) { - FPopupMenu menu = new FPopupMenu() { - @Override - protected void buildMenu() { - //add a menu item for each filter to allow easily editing just that filter - for (final IFilterControl control : model.getControls()) { - FMenuItem item = new FMenuItem(control.getFilter().toString(), Forge.hdbuttons ? FSkinImage.HDEDIT : FSkinImage.EDIT, new FEvent.FEventHandler() { - @Override - public void handleEvent(FEvent e) { - model.editFilterControl(control, onFilterChange); - } - }); - item.setTextRenderer(new TextRenderer()); //ensure symbols are displayed - addItem(item); - } - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblEditExpression"), Forge.hdbuttons ? FSkinImage.HDEDIT : FSkinImage.EDIT, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - edit(); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblRemoveFilter"), Forge.hdbuttons ? FSkinImage.HDDELETE : FSkinImage.DELETE, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - reset(); - itemManager.applyNewOrModifiedFilter(AdvancedSearchFilter.this); - } - })); - } - }; - menu.show(this, x, y); - } - else if (count == 2) { - edit(); - } - return true; - } - - @Override - public boolean longPress(float x, float y) { - FTooltip tooltip = new FTooltip(toolTipText); - tooltip.show(this, x, getHeight()); - return true; - } - } - - private class EditScreen extends FScreen { - private final FScrollPane scroller = add(new FScrollPane() { - @Override - protected ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) { - float x = 0; - float y = 0; - float w = visibleWidth; - float h = (FTextField.getDefaultHeight() + FList.PADDING) * 3; - - for (FDisplayObject child : getChildren()) { - child.setBounds(x, y, w, h); - y += h; - } - - return new ScrollBounds(visibleWidth, y); - } - }); - - private EditScreen() { - super(Localizer.getInstance().getMessage("lblAdvancedSearch")); - Filter filter = new Filter(); - model.addFilterControl(filter); - scroller.add(filter); - } - - @Override - public void onActivate() { - super.onActivate(); - - //automatically edit first filter if search is empty - if (model.isEmpty()) { - model.editFilterControl(Iterables.getFirst(model.getControls(), null), onFilterChange); - } - } - - @Override - public void onClose(Callback canCloseCallback) { - onFilterChange.run(); - super.onClose(canCloseCallback); - } - - @Override - protected void doLayout(float startY, float width, float height) { - scroller.setBounds(0, startY, width, height - startY); - } - - private void addNewFilter(Filter fromFilter) { - if (scroller.getChildAt(scroller.getChildCount() - 1) == fromFilter) { - Filter filter = new Filter(); - model.addFilterControl(filter); - scroller.add(filter); - scroller.revalidate(); - scroller.scrollToBottom(); - } - } - - @SuppressWarnings("unchecked") - private void removeNextFilter(Filter fromFilter) { - int index = scroller.indexOf(fromFilter); - if (index < scroller.getChildCount() - 1) { - Filter nextFilter = (Filter)scroller.getChildAt(index + 1); - model.removeFilterControl(nextFilter); - scroller.remove(nextFilter); - scroller.revalidate(); - } - } - - private class Filter extends FContainer implements IFilterControl { - private final FLabel btnNotBeforeParen, btnOpenParen, btnNotAfterParen; - private final FLabel btnFilter; - private final FLabel btnCloseParen, btnAnd, btnOr; - private AdvancedSearch.Filter filter; - - private Filter() { - btnNotBeforeParen = add(new FLabel.Builder().align(Align.center).text("NOT").selectable().build()); - btnOpenParen = add(new FLabel.Builder().align(Align.center).text("(").selectable().build()); - btnNotAfterParen = add(new FLabel.Builder().align(Align.center).text("NOT").selectable().build()); - btnFilter = add(new FLabel.ButtonBuilder().parseSymbols(true).build()); - btnCloseParen = add(new FLabel.Builder().align(Align.center).selectable().text(")").build()); - btnAnd = add(new FLabel.Builder().align(Align.center).text("AND").selectable().command(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - if (btnAnd.isSelected()) { - btnOr.setSelected(false); - addNewFilter(Filter.this); - } - else { - removeNextFilter(Filter.this); - } - } - }).build()); - btnOr = add(new FLabel.Builder().align(Align.center).text("OR").selectable().command(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - if (btnOr.isSelected()) { - btnAnd.setSelected(false); - addNewFilter(Filter.this); - } - else { - removeNextFilter(Filter.this); - } - } - }).build()); - } - - @Override - protected void doLayout(float width, float height) { - float padding = FList.PADDING; - float buttonWidth = (width - padding * 4) / 3; - float buttonHeight = (height - padding * 3) / 3; - - float x = padding; - float y = padding; - float dx = buttonWidth + padding; - float dy = buttonHeight + padding; - - btnNotBeforeParen.setBounds(x, y, buttonWidth, buttonHeight); - x += dx; - btnOpenParen.setBounds(x, y, buttonWidth, buttonHeight); - x += dx; - btnNotAfterParen.setBounds(x, y, buttonWidth, buttonHeight); - x = padding; - y += dy; - btnFilter.setBounds(x, y, width - 2 * padding, buttonHeight); - y += dy; - btnCloseParen.setBounds(x, y, buttonWidth, buttonHeight); - x += dx; - btnAnd.setBounds(x, y, buttonWidth, buttonHeight); - x += dx; - btnOr.setBounds(x, y, buttonWidth, buttonHeight); - } - - @Override - public IButton getBtnNotBeforeParen() { - return btnNotBeforeParen; - } - @Override - public IButton getBtnOpenParen() { - return btnOpenParen; - } - @Override - public IButton getBtnNotAfterParen() { - return btnNotAfterParen; - } - @Override - public IButton getBtnFilter() { - return btnFilter; - } - @Override - public IButton getBtnCloseParen() { - return btnCloseParen; - } - @Override - public IButton getBtnAnd() { - return btnAnd; - } - @Override - public IButton getBtnOr() { - return btnOr; - } - @Override - public AdvancedSearch.Filter getFilter() { - return filter; - } - @Override - public void setFilter(AdvancedSearch.Filter filter0) { - filter = filter0; - } - @Override - public Class getGenericType() { - return itemManager.getGenericType(); - } - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardCMCFilter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardCMCFilter.java deleted file mode 100644 index a631de4aa53..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardCMCFilter.java +++ /dev/null @@ -1,34 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.filters; - -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import forge.card.CardRules; -import forge.card.CardRulesPredicates; -import forge.item.PaperCard; -import forge.adventure.libgdxgui.itemmanager.ItemManager; - - -public class CardCMCFilter extends ValueRangeFilter { - public CardCMCFilter(ItemManager itemManager0) { - super(itemManager0); - } - - @Override - public ItemFilter createCopy() { - return new CardCMCFilter(itemManager); - } - - @Override - protected String getCaption() { - return "Mana Value"; - } - - @Override - protected Predicate buildPredicate() { - Predicate predicate = getCardRulesFieldPredicate(CardRulesPredicates.LeafNumber.CardField.CMC); - if (predicate == null) { - return Predicates.alwaysTrue(); - } - return Predicates.compose(predicate, PaperCard.FN_GET_RULES); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardColorFilter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardColorFilter.java deleted file mode 100644 index 6574e81de4d..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardColorFilter.java +++ /dev/null @@ -1,35 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.filters; - -import com.google.common.base.Predicate; -import forge.item.PaperCard; -import forge.adventure.libgdxgui.itemmanager.ItemManager; -import forge.itemmanager.SFilterUtil; -import forge.itemmanager.SItemManagerUtil.StatTypes; - - -public class CardColorFilter extends StatTypeFilter { - public CardColorFilter(ItemManager itemManager0) { - super(itemManager0); - } - - @Override - public ItemFilter createCopy() { - return new CardColorFilter(itemManager); - } - - @Override - protected void buildWidget(Widget widget) { - addToggleButton(widget, StatTypes.WHITE); - addToggleButton(widget, StatTypes.BLUE); - addToggleButton(widget, StatTypes.BLACK); - addToggleButton(widget, StatTypes.RED); - addToggleButton(widget, StatTypes.GREEN); - addToggleButton(widget, StatTypes.COLORLESS); - addToggleButton(widget, StatTypes.MULTICOLOR); - } - - @Override - protected final Predicate buildPredicate() { - return SFilterUtil.buildColorFilter(buttonMap); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardColorlessCostFilter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardColorlessCostFilter.java deleted file mode 100644 index 66f210ec711..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardColorlessCostFilter.java +++ /dev/null @@ -1,34 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.filters; - -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import forge.card.CardRules; -import forge.card.CardRulesPredicates; -import forge.item.PaperCard; -import forge.adventure.libgdxgui.itemmanager.ItemManager; - - -public class CardColorlessCostFilter extends ValueRangeFilter { - public CardColorlessCostFilter(ItemManager itemManager0) { - super(itemManager0); - } - - @Override - public ItemFilter createCopy() { - return new CardColorlessCostFilter(itemManager); - } - - @Override - protected String getCaption() { - return "Generic Cost"; - } - - @Override - protected Predicate buildPredicate() { - Predicate predicate = getCardRulesFieldPredicate(CardRulesPredicates.LeafNumber.CardField.GENERIC_COST); - if (predicate == null) { - return Predicates.alwaysTrue(); - } - return Predicates.compose(predicate, PaperCard.FN_GET_RULES); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardFormatFilter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardFormatFilter.java deleted file mode 100644 index a3d793a63d0..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardFormatFilter.java +++ /dev/null @@ -1,31 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.filters; - -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import forge.item.PaperCard; -import forge.adventure.libgdxgui.itemmanager.ItemManager; - - -public class CardFormatFilter extends FormatFilter { - public CardFormatFilter(ItemManager itemManager0) { - super(itemManager0); - } - - @Override - public ItemFilter createCopy() { - CardFormatFilter copy = new CardFormatFilter(itemManager); - copy.format = this.format; - return copy; - } - - @Override - protected final Predicate buildPredicate() { - if (format == null) { - return Predicates.alwaysTrue(); - } - if (format.getName() == null) { - return format.getFilterPrinted(); //if format is collection of sets, don't show reprints in other sets - } - return format.getFilterRules(); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardPowerFilter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardPowerFilter.java deleted file mode 100644 index 0d65654f214..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardPowerFilter.java +++ /dev/null @@ -1,35 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.filters; - -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import forge.card.CardRules; -import forge.card.CardRulesPredicates; -import forge.item.PaperCard; -import forge.adventure.libgdxgui.itemmanager.ItemManager; - - -public class CardPowerFilter extends ValueRangeFilter { - public CardPowerFilter(ItemManager itemManager0) { - super(itemManager0); - } - - @Override - public ItemFilter createCopy() { - return new CardPowerFilter(itemManager); - } - - @Override - protected String getCaption() { - return "Power"; - } - - @Override - protected Predicate buildPredicate() { - Predicate predicate = getCardRulesFieldPredicate(CardRulesPredicates.LeafNumber.CardField.POWER); - if (predicate == null) { - return Predicates.alwaysTrue(); - } - predicate = Predicates.and(predicate, CardRulesPredicates.Presets.IS_CREATURE); - return Predicates.compose(predicate, PaperCard.FN_GET_RULES); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardRarityFilter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardRarityFilter.java deleted file mode 100644 index c6fcb2e02e7..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardRarityFilter.java +++ /dev/null @@ -1,37 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.filters; - -import com.google.common.base.Predicate; -import forge.card.CardRarity; -import forge.item.PaperCard; -import forge.adventure.libgdxgui.itemmanager.ItemManager; - -public class CardRarityFilter extends ComboBoxFilter { - public CardRarityFilter(ItemManager itemManager0) { - super("Any Rarity", CardRarity.FILTER_OPTIONS, itemManager0); - } - - @Override - public ItemFilter createCopy() { - CardRarityFilter copy = new CardRarityFilter(itemManager); - copy.filterValue = filterValue; - return copy; - } - - @Override - protected String getDisplayText(CardRarity value) { - return CardRarity.FN_GET_LONG_NAME.apply(value); - } - - @Override - protected Predicate buildPredicate() { - return new Predicate() { - @Override - public boolean apply(PaperCard input) { - if (filterValue == null) { - return true; - } - return input.getRarity() == filterValue; - } - }; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardSearchFilter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardSearchFilter.java deleted file mode 100644 index e75c0d6a40c..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardSearchFilter.java +++ /dev/null @@ -1,49 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.filters; - -import com.google.common.base.Predicate; -import forge.item.InventoryItem; -import forge.item.PaperCard; -import forge.adventure.libgdxgui.itemmanager.ItemManager; -import forge.itemmanager.SFilterUtil; - - -public class CardSearchFilter extends TextSearchFilter { - private final boolean inName, inType, inText, inCost; - - public CardSearchFilter(ItemManager itemManager0) { - this(itemManager0, true, true, true, false); - } - - public CardSearchFilter(ItemManager itemManager0, boolean inName0, boolean inType0, boolean inText0, boolean inCost0) { - super(itemManager0); - inName = inName0; - inType = inType0; - inText = inText0; - inCost = inCost0; - } - - @Override - public ItemFilter createCopy() { - CardSearchFilter copy = new CardSearchFilter(itemManager, inName, inType, inText, inCost); - copy.getWidget(); //initialize widget - copy.txtSearch.setText(txtSearch.getText()); - return copy; - } - - @Override - protected Predicate buildPredicate() { - return SFilterUtil.buildTextFilter( - txtSearch.getText(), - false, - inName, - inType, - inText, - inCost); - } - - @Override - protected boolean showUnsupportedItem(U item) { - //fallback to regular item text filter if item not PaperCard - return SFilterUtil.buildItemTextFilter(txtSearch.getText()).apply(item); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardToughnessFilter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardToughnessFilter.java deleted file mode 100644 index 977ce4072f7..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardToughnessFilter.java +++ /dev/null @@ -1,35 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.filters; - -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import forge.card.CardRules; -import forge.card.CardRulesPredicates; -import forge.item.PaperCard; -import forge.adventure.libgdxgui.itemmanager.ItemManager; - - -public class CardToughnessFilter extends ValueRangeFilter { - public CardToughnessFilter(ItemManager itemManager0) { - super(itemManager0); - } - - @Override - public ItemFilter createCopy() { - return new CardToughnessFilter(itemManager); - } - - @Override - protected String getCaption() { - return "Toughness"; - } - - @Override - protected Predicate buildPredicate() { - Predicate predicate = getCardRulesFieldPredicate(CardRulesPredicates.LeafNumber.CardField.TOUGHNESS); - if (predicate == null) { - return Predicates.alwaysTrue(); - } - predicate = Predicates.and(predicate, CardRulesPredicates.Presets.IS_CREATURE); - return Predicates.compose(predicate, PaperCard.FN_GET_RULES); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardTypeFilter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardTypeFilter.java deleted file mode 100644 index 136d4a6697f..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/CardTypeFilter.java +++ /dev/null @@ -1,58 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.filters; - -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import forge.card.CardRules; -import forge.item.PaperCard; -import forge.adventure.libgdxgui.itemmanager.ItemManager; -import forge.itemmanager.SItemManagerUtil.StatTypes; - -import java.util.ArrayList; -import java.util.List; - - -public class CardTypeFilter extends StatTypeFilter { - public CardTypeFilter(ItemManager itemManager0) { - super(itemManager0); - } - - @Override - public ItemFilter createCopy() { - return new CardTypeFilter(itemManager); - } - - @Override - protected void buildWidget(Widget widget) { - /*if (itemManager instanceof SpellShopManager) { - addToggleButton(widget, StatTypes.PACK_OR_DECK); - }*/ - addToggleButton(widget, StatTypes.LAND); - addToggleButton(widget, StatTypes.ARTIFACT); - addToggleButton(widget, StatTypes.CREATURE); - addToggleButton(widget, StatTypes.ENCHANTMENT); - addToggleButton(widget, StatTypes.PLANESWALKER); - addToggleButton(widget, StatTypes.INSTANT); - addToggleButton(widget, StatTypes.SORCERY); - } - - @Override - protected final Predicate buildPredicate() { - final List> types = new ArrayList<>(); - - for (StatTypes s : buttonMap.keySet()) { - if (s.predicate != null && buttonMap.get(s).isSelected()) { - types.add(s.predicate); - } - } - - if (types.size() == buttonMap.size()) { - return new Predicate() { //use custom return true delegate to validate the item is a card - @Override - public boolean apply(PaperCard card) { - return true; - } - }; - } - return Predicates.compose(Predicates.or(types), PaperCard.FN_GET_RULES); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/ComboBoxFilter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/ComboBoxFilter.java deleted file mode 100644 index 24cb3a7edf6..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/ComboBoxFilter.java +++ /dev/null @@ -1,95 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.filters; - -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.item.InventoryItem; -import forge.adventure.libgdxgui.itemmanager.ItemManager; -import forge.adventure.libgdxgui.toolbox.FComboBox; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.toolbox.FEvent; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; - -public abstract class ComboBoxFilter extends ItemFilter { - protected V filterValue; - private boolean preventHandling = false; - private final FComboBox comboBox = new FComboBox() { - @SuppressWarnings("unchecked") - @Override - protected String getDisplayText(Object item) { - if (item instanceof String) { - return (String)item; - } - return ComboBoxFilter.this.getDisplayText((V)item); - } - }; - - protected ComboBoxFilter(String allText, Iterable values, ItemManager itemManager0) { - this(allText, itemManager0); - for (V value : values) { - comboBox.addItem(value); - } - } - protected ComboBoxFilter(String allText, V[] values, ItemManager itemManager0) { - this(allText, itemManager0); - for (V value : values) { - comboBox.addItem(value); - } - } - private ComboBoxFilter(String allText, ItemManager itemManager0) { - super(itemManager0); - - comboBox.setFont(FSkinFont.get(12)); - comboBox.addItem(allText); - comboBox.setChangedHandler(new FEventHandler() { - @SuppressWarnings("unchecked") - @Override - public void handleEvent(FEvent e) { - if (preventHandling) { return; } - - int index = comboBox.getSelectedIndex(); - if (index == -1) { - //Do nothing when index set to -1 - } - else if (index == 0) { - filterValue = null; - applyChange(); - } - else { - filterValue = (V)comboBox.getSelectedItem(); - applyChange(); - } - } - }); - } - - protected String getDisplayText(V value) { - return value.toString(); - } - - @Override - public void reset() { - preventHandling = true; - comboBox.setSelectedIndex(0); - preventHandling = false; - filterValue = null; - } - - @Override - public FDisplayObject getMainComponent() { - return comboBox; - } - - @Override - public boolean isEmpty() { - return filterValue == null; - } - - @Override - protected void buildWidget(Widget widget) { - widget.add(comboBox); - } - - @Override - protected void doWidgetLayout(float width, float height) { - comboBox.setSize(width, height); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/DeckColorFilter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/DeckColorFilter.java deleted file mode 100644 index c65d7060d0c..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/DeckColorFilter.java +++ /dev/null @@ -1,35 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.filters; - -import com.google.common.base.Predicate; -import forge.deck.DeckProxy; -import forge.adventure.libgdxgui.itemmanager.ItemManager; -import forge.itemmanager.SFilterUtil; -import forge.itemmanager.SItemManagerUtil.StatTypes; - - -public class DeckColorFilter extends StatTypeFilter { - public DeckColorFilter(ItemManager itemManager0) { - super(itemManager0); - } - - @Override - public ItemFilter createCopy() { - return new DeckColorFilter(itemManager); - } - - @Override - protected void buildWidget(Widget widget) { - addToggleButton(widget, StatTypes.DECK_WHITE); - addToggleButton(widget, StatTypes.DECK_BLUE); - addToggleButton(widget, StatTypes.DECK_BLACK); - addToggleButton(widget, StatTypes.DECK_RED); - addToggleButton(widget, StatTypes.DECK_GREEN); - addToggleButton(widget, StatTypes.DECK_COLORLESS); - addToggleButton(widget, StatTypes.DECK_MULTICOLOR); - } - - @Override - protected final Predicate buildPredicate() { - return SFilterUtil.buildDeckColorFilter(buttonMap); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/DeckFolderFilter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/DeckFolderFilter.java deleted file mode 100644 index f2b1b88904e..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/DeckFolderFilter.java +++ /dev/null @@ -1,71 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.filters; - -import com.google.common.base.Predicate; -import forge.deck.DeckProxy; -import forge.adventure.libgdxgui.itemmanager.ItemManager; - -import java.util.HashSet; -import java.util.Set; - - -public class DeckFolderFilter extends ListLabelFilter { - protected final Set folders = new HashSet<>(); - - public DeckFolderFilter(ItemManager itemManager0) { - super(itemManager0); - } - - public DeckFolderFilter(ItemManager itemManager0, String folder0) { - super(itemManager0); - this.folders.add(folder0); - } - - @Override - public ItemFilter createCopy() { - DeckFolderFilter copy = new DeckFolderFilter(itemManager); - copy.folders.addAll(this.folders); - return copy; - } - - @Override - protected final Predicate buildPredicate() { - return new Predicate() { - @Override - public boolean apply(DeckProxy input) { - String path = input.getPath(); - for (String folder : folders) { - if (path.startsWith(folder)) { - return true; - } - } - return false; - } - }; - } - - @Override - protected String getCaption() { - return "Folder"; - } - - @Override - protected Iterable getList() { - return this.folders; - } - - @Override - protected String getTooltip() { - return null; - } - - @Override - protected int getCount() { - return this.folders.size(); - } - - @Override - public void reset() { - this.folders.clear(); - this.updateLabel(); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/DeckFormatFilter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/DeckFormatFilter.java deleted file mode 100644 index 30aa835dff4..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/DeckFormatFilter.java +++ /dev/null @@ -1,33 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.filters; - -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import forge.deck.DeckProxy; -import forge.adventure.libgdxgui.itemmanager.ItemManager; - - -public class DeckFormatFilter extends FormatFilter { - public DeckFormatFilter(ItemManager itemManager0) { - super(itemManager0); - } - - @Override - public ItemFilter createCopy() { - DeckFormatFilter copy = new DeckFormatFilter(itemManager); - copy.format = format; - return copy; - } - - @Override - protected final Predicate buildPredicate() { - if (format == null) { - return Predicates.alwaysTrue(); - } - return new Predicate() { - @Override - public boolean apply(DeckProxy input) { - return format.isDeckLegal(input.getDeck()); - } - }; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/DeckStatTypeFilter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/DeckStatTypeFilter.java deleted file mode 100644 index 907bc97503c..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/DeckStatTypeFilter.java +++ /dev/null @@ -1,16 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.filters; - -import forge.deck.DeckProxy; -import forge.item.InventoryItem; -import forge.adventure.libgdxgui.itemmanager.ItemManager; - -public abstract class DeckStatTypeFilter extends StatTypeFilter { - public DeckStatTypeFilter(ItemManager itemManager0) { - super(itemManager0); - } - - @Override - protected boolean showUnsupportedItem(U item) { - return false; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/FormatFilter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/FormatFilter.java deleted file mode 100644 index f826bf841e6..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/FormatFilter.java +++ /dev/null @@ -1,269 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.filters; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.card.CardEdition; -import forge.game.GameFormat; -import forge.item.InventoryItem; -import forge.adventure.libgdxgui.itemmanager.ItemManager; -import forge.model.FModel; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.screens.settings.SettingsScreen; -import forge.adventure.libgdxgui.toolbox.*; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.util.Callback; -import forge.util.Localizer; -import forge.util.TextUtil; -import forge.adventure.libgdxgui.util.Utils; - -import java.util.*; - - - -public abstract class FormatFilter extends ItemFilter { - protected GameFormat format; - private String selectedFormat; - private boolean preventHandling = false; - private final FComboBox cbxFormats = new FComboBox<>(); - - public FormatFilter(ItemManager itemManager0) { - super(itemManager0); - - final Localizer localizer = Localizer.getInstance(); - cbxFormats.setFont(FSkinFont.get(12)); - cbxFormats.addItem(localizer.getMessage("lblAllSetsFormats")); - for (GameFormat format : FModel.getFormats().getFilterList()) { - cbxFormats.addItem(format); - } - cbxFormats.addItem(localizer.getMessage("lblOtherFormats")); - cbxFormats.addItem(localizer.getMessage("lblChooseSets")); - selectedFormat = cbxFormats.getText(); - - cbxFormats.setChangedHandler(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - if (preventHandling) { return; } - - int index = cbxFormats.getSelectedIndex(); - if (index == -1) { - //Do nothing when index set to -1 - } - else if (index == 0) { - format = null; - applyChange(); - } - else if (index == cbxFormats.getItemCount() - 2) { - preventHandling = true; - cbxFormats.setText(selectedFormat); //restore previous selection by default - preventHandling = false; - HistoricFormatSelect historicFormatSelect = new HistoricFormatSelect(); - historicFormatSelect.setOnCloseCallBack(new Runnable(){ - @Override - public void run() { - format = historicFormatSelect.getSelectedFormat(); - cbxFormats.setText(format.getName()); - applyChange(); - } - }); - Forge.openScreen(historicFormatSelect); - } - else if (index == cbxFormats.getItemCount() - 1) { - preventHandling = true; - cbxFormats.setText(selectedFormat); //restore previous selection by default - preventHandling = false; - Forge.openScreen(new MultiSetSelect()); - } - else { - format = (GameFormat)cbxFormats.getSelectedItem(); - applyChange(); - } - } - }); - } - - @Override - protected void applyChange() { - selectedFormat = cbxFormats.getText(); //backup current text - super.applyChange(); - } - - @Override - public void reset() { - preventHandling = true; - cbxFormats.setSelectedIndex(0); - preventHandling = false; - format = null; - } - - @Override - public FDisplayObject getMainComponent() { - return cbxFormats; - } - - @Override - public boolean isEmpty() { - return format == null; - } - - @Override - protected void buildWidget(Widget widget) { - widget.add(cbxFormats); - } - - @Override - protected void doWidgetLayout(float width, float height) { - cbxFormats.setSize(width, height); - } - - private class MultiSetSelect extends FScreen { - private final Set selectedSets = new HashSet<>(); - private final FGroupList lstSets = add(new FGroupList<>()); - - private MultiSetSelect() { - super("Choose Sets"); - - lstSets.addGroup("Core Sets"); - lstSets.addGroup("Expansions"); - lstSets.addGroup("Starter Sets"); - lstSets.addGroup("Reprint Sets"); - lstSets.addGroup("Boxed Sets"); - - lstSets.addGroup("Collector's Edition"); - lstSets.addGroup("Duel Decks"); - lstSets.addGroup("Promo Sets"); - lstSets.addGroup("Digital Sets"); - - lstSets.addGroup("Draft Innovation Sets"); - - - - lstSets.addGroup("Commander Sets"); - lstSets.addGroup("Multiplayer Sets"); - lstSets.addGroup("Other Supplemental Sets"); - lstSets.addGroup("Funny Sets"); - - lstSets.addGroup("Custom Sets"); - - List sets = FModel.getMagicDb().getSortedEditions(); - for (CardEdition set : sets) { - switch (set.getType()) { - case CORE: - lstSets.addItem(set, 0); - break; - case EXPANSION: - lstSets.addItem(set, 1); - break; - case STARTER: - lstSets.addItem(set, 2); - break; - case REPRINT: - lstSets.addItem(set, 3); - break; - case BOXED_SET: - lstSets.addItem(set,4); - break; - case COLLECTOR_EDITION: - lstSets.addItem(set, 5); - break; - case DUEL_DECK: - lstSets.addItem(set, 6); - break; - case PROMO: - lstSets.addItem(set, 7); - break; - case ONLINE: - lstSets.addItem(set, 8); - break; - case DRAFT: - lstSets.addItem(set, 9); - break; - case COMMANDER: - lstSets.addItem(set, 10); - break; - case MULTIPLAYER: - lstSets.addItem(set, 11); - break; - case OTHER: - lstSets.addItem(set, 12); - break; - case FUNNY: - lstSets.addItem(set, 13); - break; - default: // THIRDPARTY - Custom Sets - lstSets.addItem(set, 14); - break; - } - } - - lstSets.setListItemRenderer(new SetRenderer()); - } - - @Override - public void onClose(Callback canCloseCallback) { - if (selectedSets.size() > 0) { - List setCodes = new ArrayList<>(); - List sortedSets = new ArrayList<>(selectedSets); - Collections.sort(sortedSets); - for (CardEdition set : sortedSets) { - setCodes.add(set.getCode()); - } - format = new GameFormat(null, setCodes, null); - cbxFormats.setText(sortedSets.size() > 1 ? TextUtil.join(setCodes, ", ") : sortedSets.get(0).toString()); - applyChange(); - } - super.onClose(canCloseCallback); - } - - @Override - protected void doLayout(float startY, float width, float height) { - lstSets.setBounds(0, startY, width, height - startY); - } - - private class SetRenderer extends FList.ListItemRenderer { - @Override - public float getItemHeight() { - return Utils.AVG_FINGER_HEIGHT; - } - - @Override - public boolean tap(Integer index, CardEdition value, float x, float y, int count) { - if (selectedSets.contains(value)) { - if (count == 2) { - Forge.back(); //support double tap to confirm selection without unselecting double tapped item - } - else { - selectedSets.remove(value); - } - } - else { - selectedSets.add(value); - if (count == 2) { - Forge.back(); //support double tap to confirm selection after selecting double tapped item - } - } - return true; - } - - @Override - public void drawValue(Graphics g, Integer index, CardEdition value, FSkinFont font, FSkinColor foreColor, FSkinColor backColor, boolean pressed, float x, float y, float w, float h) { - float offset = SettingsScreen.getInsets(w) - FList.PADDING; //increase padding for settings items - x += offset; - y += offset; - w -= 2 * offset; - h -= 2 * offset; - - float textHeight = h; - h *= 0.66f; - - g.drawText(value.toString(), font, foreColor, x, y, w - h - FList.PADDING, textHeight, false, Align.left, true); - - x += w - h; - y += (textHeight - h) / 2; - FCheckBox.drawCheckBox(g, SettingsScreen.DESC_COLOR, foreColor, selectedSets.contains(value), x, y, h, h); - } - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/HistoricFormatSelect.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/HistoricFormatSelect.java deleted file mode 100644 index bcd9427da9c..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/HistoricFormatSelect.java +++ /dev/null @@ -1,142 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.filters; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.game.GameFormat; -import forge.model.FModel; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.screens.settings.SettingsScreen; -import forge.adventure.libgdxgui.toolbox.FGroupList; -import forge.adventure.libgdxgui.toolbox.FList; -import forge.util.Callback; -import forge.util.Localizer; -import forge.adventure.libgdxgui.util.Utils; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -/** - * Created by maustin on 16/04/2018. - */ -public class HistoricFormatSelect extends FScreen { - - private GameFormat selectedFormat; - private final FGroupList lstFormats = add(new FGroupList<>()); - private final Set historicSubTypes = new HashSet<>(Arrays.asList(GameFormat.FormatSubType.BLOCK, - GameFormat.FormatSubType.STANDARD,GameFormat.FormatSubType.EXTENDED,GameFormat.FormatSubType.MODERN, - GameFormat.FormatSubType.LEGACY, GameFormat.FormatSubType.VINTAGE)); - - private Runnable onCloseCallBack; - - public HistoricFormatSelect() { - super(Localizer.getInstance().getMessage("lblChooseFormat")); - for (GameFormat.FormatType group:GameFormat.FormatType.values()){ - if (group == GameFormat.FormatType.HISTORIC){ - for (GameFormat.FormatSubType subgroup:GameFormat.FormatSubType.values()){ - if (historicSubTypes.contains(subgroup)){ - lstFormats.addGroup(group.name() + "-" + subgroup.name()); - } - } - }else { - lstFormats.addGroup(group.name()); - } - } - for (GameFormat format: FModel.getFormats().getOrderedList()){ - switch(format.getFormatType()){ - case SANCTIONED: - lstFormats.addItem(format, 0); - break; - case CASUAL: - lstFormats.addItem(format, 1); - break; - case HISTORIC: - switch (format.getFormatSubType()){ - case BLOCK: - lstFormats.addItem(format, 2); - break; - case STANDARD: - lstFormats.addItem(format, 3); - break; - case EXTENDED: - lstFormats.addItem(format, 4); - break; - case MODERN: - lstFormats.addItem(format, 5); - break; - case LEGACY: - lstFormats.addItem(format, 6); - break; - case VINTAGE: - lstFormats.addItem(format, 7); - break; - - } - break; - case DIGITAL: - lstFormats.addItem(format, 8); - break; - case CUSTOM: - lstFormats.addItem(format, 9); - } - } - lstFormats.setListItemRenderer(new FormatRenderer()); - } - - public GameFormat getSelectedFormat() { - return selectedFormat; - } - - public void setOnCloseCallBack(Runnable onCloseCallBack) { - this.onCloseCallBack = onCloseCallBack; - } - - @Override - public void onClose(Callback canCloseCallback) { - if (selectedFormat != null) { - if (onCloseCallBack != null) { - onCloseCallBack.run(); - } - } - super.onClose(canCloseCallback); - } - - @Override - protected void doLayout(float startY, float width, float height) { - lstFormats.setBounds(0, startY, width, height - startY); - } - - private class FormatRenderer extends FList.ListItemRenderer{ - @Override - public float getItemHeight() { - return Utils.AVG_FINGER_HEIGHT; - } - - @Override - public boolean tap(Integer index, GameFormat value, float x, float y, int count) { - selectedFormat=value; - Forge.back(); - return true; - } - - @Override - public void drawValue(Graphics g, Integer index, GameFormat value, FSkinFont font, FSkinColor foreColor, FSkinColor backColor, boolean pressed, float x, float y, float w, float h) { - float offset = SettingsScreen.getInsets(w) - FList.PADDING; //increase padding for settings items - x += offset; - y += offset; - w -= 2 * offset; - h -= 2 * offset; - - float textHeight = h; - h *= 0.66f; - - g.drawText(value.toString(), font, foreColor, x, y, w - h - FList.PADDING, textHeight, false, Align.left, true); - - x += w - h; - y += (textHeight - h) / 2; - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/ItemFilter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/ItemFilter.java deleted file mode 100644 index 04d7675514b..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/ItemFilter.java +++ /dev/null @@ -1,86 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.filters; - -import com.google.common.base.Predicate; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.item.InventoryItem; -import forge.adventure.libgdxgui.itemmanager.ItemManager; -import forge.adventure.libgdxgui.toolbox.FContainer; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.util.Utils; - - -public abstract class ItemFilter { - public static final float PADDING = Utils.scale(3); - public static final FSkinFont DEFAULT_FONT = FSkinFont.get(11); - - protected final ItemManager itemManager; - private Widget widget; - - protected ItemFilter(ItemManager itemManager0) { - itemManager = itemManager0; - } - - public Widget getWidget() { - if (widget == null) { - widget = new Widget(); - buildWidget(widget); - } - return widget; - } - - public void refreshWidget() { - if (widget == null) { return; } - widget.clear(); - buildWidget(widget); - } - - public FDisplayObject getMainComponent() { - return getWidget(); - } - - protected void applyChange() { - itemManager.applyFilters(); - } - - public final Predicate buildPredicate(Class genericType) { - final Predicate predicate = buildPredicate(); - return new Predicate() { - @SuppressWarnings("unchecked") - @Override - public boolean apply(U item) { - try { - return predicate.apply((T)item); - } - catch (Exception ex) { - return showUnsupportedItem(item); //if can't cast U to T, filter item out unless derived class can handle it - } - } - }; - } - - protected boolean showUnsupportedItem(U item) { - return false; //don't show unsupported items by default - } - - public abstract ItemFilter createCopy(); - public abstract boolean isEmpty(); - public abstract void reset(); - - public float getPreferredWidth(float maxWidth, float height) { - return maxWidth; //use maximum width by default - } - - protected abstract void buildWidget(Widget widget); - protected abstract void doWidgetLayout(float width, float height); - protected abstract Predicate buildPredicate(); - - public class Widget extends FContainer { - private Widget() { - } - - @Override - protected void doLayout(float width, float height) { - doWidgetLayout(width, height); - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/ListLabelFilter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/ListLabelFilter.java deleted file mode 100644 index 3df1b5cbeee..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/ListLabelFilter.java +++ /dev/null @@ -1,72 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.filters; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.item.InventoryItem; -import forge.adventure.libgdxgui.itemmanager.ItemManager; -import forge.adventure.libgdxgui.menu.FTooltip; -import forge.adventure.libgdxgui.toolbox.FLabel; -import forge.util.TextUtil; - - -public abstract class ListLabelFilter extends ItemFilter { - public static final FSkinFont LABEL_FONT = FSkinFont.get(12); - - private ListLabel label; - - protected ListLabelFilter(ItemManager itemManager0) { - super(itemManager0); - } - - protected abstract String getCaption(); - protected abstract Iterable getList(); - protected abstract String getTooltip(); - protected abstract int getCount(); - - @Override - public final boolean isEmpty() { - return getCount() == 0; - } - - @Override - protected final void buildWidget(Widget widget) { - label = new ListLabel(); - updateLabel(); - widget.add(label); - } - - protected void updateLabel() { - StringBuilder labelBuilder = new StringBuilder(); - labelBuilder.append(getCaption()); - switch (getCount()) { - case 0: - labelBuilder.append("s: All"); - break; - case 1: - labelBuilder.append(": ").append(getList().iterator().next()); - break; - default: - labelBuilder.append("s: ").append(TextUtil.join(getList(), ", ")); - break; - } - label.setText(labelBuilder.toString()); - } - - @Override - protected void doWidgetLayout(float width, float height) { - label.setSize(width, height); - } - - private class ListLabel extends FLabel { - private ListLabel() { - super(new FLabel.Builder().align(Align.left).font(LABEL_FONT)); - } - - @Override - public boolean tap(float x, float y, int count) { - FTooltip tooltip = new FTooltip(getTooltip()); - tooltip.show(this, x, getHeight()); - return true; - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/StatTypeFilter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/StatTypeFilter.java deleted file mode 100644 index cc63215c127..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/StatTypeFilter.java +++ /dev/null @@ -1,48 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.filters; - -import forge.adventure.libgdxgui.assets.FSkin; -import forge.item.InventoryItem; -import forge.item.ItemPredicate; -import forge.adventure.libgdxgui.itemmanager.ItemManager; -import forge.itemmanager.SFilterUtil; -import forge.itemmanager.SItemManagerUtil.StatTypes; -import forge.adventure.libgdxgui.toolbox.FEvent; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.toolbox.FLabel; - -import java.util.HashMap; -import java.util.Map; - -public abstract class StatTypeFilter extends ToggleButtonsFilter { - protected final Map buttonMap; - - public StatTypeFilter(ItemManager itemManager0) { - super(itemManager0); - buttonMap = new HashMap<>(); - } - - protected void addToggleButton(Widget widget, final StatTypes st) { - final ToggleButton button = addToggleButton(widget, FSkin.getImages().get(st.skinProp)); - buttonMap.put(st, button); - - //hook so long-pressing a button toggles itself on and toggles off all other buttons - button.setLongPressHandler(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - lockFiltering = true; - SFilterUtil.showOnlyStat(st, button, buttonMap); - lockFiltering = false; - applyChange(); - } - }); - } - - @Override - protected boolean showUnsupportedItem(U item) { - FLabel btnPackOrDeck = buttonMap.get(StatTypes.PACK_OR_DECK); //support special pack/deck case - if (btnPackOrDeck != null && btnPackOrDeck.isSelected()) { - return ItemPredicate.Presets.IS_PACK_OR_DECK.apply(item); - } - return false; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/TextSearchFilter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/TextSearchFilter.java deleted file mode 100644 index b949d87b44f..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/TextSearchFilter.java +++ /dev/null @@ -1,107 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.filters; - -import com.badlogic.gdx.utils.Align; -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.item.InventoryItem; -import forge.adventure.libgdxgui.itemmanager.ItemManager; -import forge.itemmanager.SFilterUtil; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.toolbox.FEvent; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.toolbox.FTextField; -import forge.util.Localizer; - - -public class TextSearchFilter extends ItemFilter { - private static final FSkinFont FONT = FSkinFont.get(12); - protected SearchField txtSearch; - - public TextSearchFilter(ItemManager itemManager0) { - super(itemManager0); - } - - @Override - public ItemFilter createCopy() { - TextSearchFilter copy = new TextSearchFilter<>(itemManager); - copy.getWidget(); //initialize widget - copy.txtSearch.setText(this.txtSearch.getText()); - return copy; - } - - @Override - public boolean isEmpty() { - return txtSearch.isEmpty(); - } - - @Override - public void reset() { - txtSearch.setText(""); - } - - @Override - public FDisplayObject getMainComponent() { - return txtSearch; - } - - @Override - protected void buildWidget(Widget widget) { - txtSearch = new SearchField(); - widget.add(txtSearch); - - txtSearch.setChangedHandler(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - applyChange(); - } - }); - } - - @Override - protected void doWidgetLayout(float width, float height) { - txtSearch.setSize(width, height); - } - - @Override - protected Predicate buildPredicate() { - String text = txtSearch.getText(); - if (text.trim().isEmpty()) { - return Predicates.alwaysTrue(); - } - return SFilterUtil.buildItemTextFilter(text); - } - - public void setRatio(String ratio0) { - txtSearch.ratio = ratio0; - } - - public String getCaption() { - return txtSearch.getGhostText().substring((Localizer.getInstance().getMessage("lblSearch") + " ").length()); - } - public void setCaption(String caption0) { - txtSearch.setGhostText(Localizer.getInstance().getMessage("lblSearch") + " " + caption0); - } - - protected class SearchField extends FTextField { - private String ratio = "(0 / 0)"; - - private SearchField() { - setFont(FONT); - setGhostText(Localizer.getInstance().getMessage("lblSearch")); - setHeight(getDefaultHeight(DEFAULT_FONT)); //set height based on default filter font - } - - @Override - protected float getRightPadding() { - return renderedFont.getBounds(ratio).width + 2 * PADDING; - } - - @Override - public void draw(Graphics g) { - super.draw(g); - g.drawText(ratio, renderedFont, GHOST_TEXT_COLOR, 0, 0, getWidth() - PADDING, getHeight(), false, Align.right, true); - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/ToggleButtonsFilter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/ToggleButtonsFilter.java deleted file mode 100644 index 483d568d35d..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/ToggleButtonsFilter.java +++ /dev/null @@ -1,96 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.filters; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.assets.FImage; -import forge.item.InventoryItem; -import forge.adventure.libgdxgui.itemmanager.ItemManager; -import forge.adventure.libgdxgui.toolbox.FEvent; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventType; -import forge.adventure.libgdxgui.toolbox.FLabel; - -import java.util.ArrayList; -import java.util.List; - - -public abstract class ToggleButtonsFilter extends ItemFilter { - protected boolean lockFiltering; - private final List buttons = new ArrayList<>(); - - protected ToggleButtonsFilter(ItemManager itemManager0) { - super(itemManager0); - } - - protected ToggleButton addToggleButton(Widget widget, FImage icon) { - final ToggleButton button = new ToggleButton(icon); - - this.buttons.add(button); - widget.add(button); - return button; - } - - @Override - public float getPreferredWidth(float maxWidth, float height) { - return Math.min((height - FLabel.BORDER_THICKNESS) * buttons.size() + FLabel.BORDER_THICKNESS, maxWidth); - } - - @Override - protected void doWidgetLayout(float width, float height) { - float buttonWidth = (width + FLabel.BORDER_THICKNESS * (buttons.size() - 1)) / buttons.size(); - float buttonHeight = height; - - float x = 0; - for (FLabel btn : buttons) { - btn.setBounds(x, 0, buttonWidth, buttonHeight); - x += buttonWidth - FLabel.BORDER_THICKNESS; - } - } - - @Override - public final boolean isEmpty() { - for (FLabel button : buttons) { //consider filter empty if any button isn't selected - if (!button.isSelected()) { - return false; - } - } - return true; - } - - @Override - public void reset() { - for (FLabel button : buttons) { - button.setSelected(true); - } - } - - public class ToggleButton extends FLabel { - private FEventHandler longPressHandler; - - private ToggleButton(FImage icon) { - super(new FLabel.Builder() - .icon(icon).iconScaleFactor(1f) - .align(Align.center) - .selectable(true).selected(true) - .command(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - if (lockFiltering) { return; } - applyChange(); - } - })); - } - - public void setLongPressHandler(FEventHandler longPressHandler0) { - longPressHandler = longPressHandler0; - } - - @Override - public boolean longPress(float x, float y) { - if (longPressHandler != null) { - longPressHandler.handleEvent(new FEvent(this, FEventType.LONG_PRESS)); - return true; - } - return false; - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/ValueRangeFilter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/ValueRangeFilter.java deleted file mode 100644 index 0a076b2eac2..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/filters/ValueRangeFilter.java +++ /dev/null @@ -1,111 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.filters; - -import com.badlogic.gdx.utils.Align; -import com.google.common.base.Predicate; -import forge.card.CardRules; -import forge.card.CardRulesPredicates; -import forge.item.InventoryItem; -import forge.adventure.libgdxgui.itemmanager.ItemManager; -import forge.itemmanager.SFilterUtil; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.toolbox.FEvent; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.toolbox.FLabel; -import forge.adventure.libgdxgui.toolbox.FSpinner; -import forge.util.ComparableOp; - - -public abstract class ValueRangeFilter extends ItemFilter { - private FLabel label; - private FSpinner lowerBound, upperBound; - - protected ValueRangeFilter(ItemManager itemManager0) { - super(itemManager0); - } - - protected abstract String getCaption(); - - protected int minValue() { - return 0; - } - - protected int maxValue() { - return 20; - } - - @Override - public final boolean isEmpty() { - return lowerBound.getValue() == minValue() && upperBound.getValue() == maxValue(); - } - - @Override - public void reset() { - lowerBound.setValue(minValue()); - upperBound.setValue(maxValue()); - } - - @Override - public FDisplayObject getMainComponent() { - return lowerBound; - } - - @Override - protected final void buildWidget(Widget widget) { - lowerBound = addSpinner(widget, true); - - String text = "<= " + this.getCaption() + " <="; - label = new FLabel.Builder().text(text).align(Align.center).font(ListLabelFilter.LABEL_FONT).build(); - widget.add(label); - - upperBound = addSpinner(widget, false); - - lowerBound.setChangedHandler(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - if (upperBound.getValue() < lowerBound.getValue()) { - upperBound.setValue(lowerBound.getValue()); - } - applyChange(); - } - }); - - upperBound.setChangedHandler(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - if (lowerBound.getValue() > upperBound.getValue()) { - lowerBound.setValue(upperBound.getValue()); - } - applyChange(); - } - }); - } - - @Override - protected void doWidgetLayout(float width, float height) { - float x = 0; - float spinnerWidth = height * 1.5f; - lowerBound.setBounds(x, 0, spinnerWidth, height); - x += lowerBound.getWidth(); - label.setBounds(x, 0, width - 2 * spinnerWidth, height); - x += label.getWidth(); - upperBound.setBounds(x, 0, spinnerWidth, height); - } - - private FSpinner addSpinner(Widget widget, boolean lowerBound) { - FSpinner spinner = new FSpinner(minValue(), maxValue(), lowerBound ? this.minValue() : this.maxValue()); - widget.add(spinner); - return spinner; - } - - protected Predicate getCardRulesFieldPredicate(CardRulesPredicates.LeafNumber.CardField field) { - int lowerValue = lowerBound.getValue(); - int upperValue = upperBound.getValue(); - boolean hasMin = lowerValue != minValue(); - boolean hasMax = upperValue != maxValue(); - - Predicate pLower = hasMin ? new CardRulesPredicates.LeafNumber(field, ComparableOp.GT_OR_EQUAL, lowerValue) : null; - Predicate pUpper = hasMax ? new CardRulesPredicates.LeafNumber(field, ComparableOp.LT_OR_EQUAL, upperValue) : null; - - return SFilterUtil.optimizedAnd(pLower, pUpper); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/views/ImageView.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/views/ImageView.java deleted file mode 100644 index c6203ccd66b..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/views/ImageView.java +++ /dev/null @@ -1,1066 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.views; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Forge.KeyInputAdapter; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.*; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.card.CardFaceSymbols; -import forge.adventure.libgdxgui.card.CardRenderer; -import forge.adventure.libgdxgui.card.CardRenderer.CardStackPosition; -import forge.adventure.libgdxgui.card.CardZoom; -import forge.adventure.libgdxgui.deck.FDeckViewer; -import forge.adventure.libgdxgui.itemmanager.ItemManager; -import forge.adventure.libgdxgui.itemmanager.filters.ItemFilter; -import forge.adventure.libgdxgui.toolbox.*; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.util.Utils; -import forge.card.ColorSet; -import forge.deck.ArchetypeDeckGenerator; -import forge.deck.CardThemedDeckGenerator; -import forge.deck.CommanderDeckGenerator; -import forge.deck.DeckProxy; -import forge.deck.io.DeckPreferences; -import forge.gamemodes.planarconquest.ConquestCommander; -import forge.item.InventoryItem; -import forge.item.PaperCard; -import forge.itemmanager.*; -import forge.util.Localizer; -import forge.util.TextUtil; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.TreeMap; - -public class ImageView extends ItemView { - private static final float PADDING = Utils.scale(5); - private static final float PILE_SPACING_Y = 0.1f; - private static final FSkinFont LABEL_FONT = FSkinFont.get(12); - private static final FSkinColor GROUP_HEADER_FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT); - private static final FSkinColor GROUP_HEADER_LINE_COLOR = GROUP_HEADER_FORE_COLOR.alphaColor(0.5f); - private static final FSkinFont GROUP_HEADER_FONT = LABEL_FONT; - private static final float GROUP_HEADER_HEIGHT = Utils.scale(19); - private static final float GROUP_HEADER_GLYPH_WIDTH = Utils.scale(6); - private static final float GROUP_HEADER_LINE_THICKNESS = Utils.scale(1); - private static final float SEL_BORDER_SIZE = Utils.scale(1); - private static final int MIN_COLUMN_COUNT = Forge.isLandscapeMode() ? 2 : 1; - private static final int MAX_COLUMN_COUNT = 10; - - private final List selectedIndices = new ArrayList<>(); - private int columnCount = 4; - private float scrollHeight = 0; - private ColumnDef pileBy = null; - private GroupDef groupBy = null; - private ItemInfo focalItem; - private boolean updatingLayout; - private float totalZoomAmount; - private final List orderedItems = new ArrayList<>(); - private final List groups = new ArrayList<>(); - - private class ExpandCollapseButton extends FLabel { - private boolean isAllCollapsed; - - private ExpandCollapseButton() { - super(new FLabel.ButtonBuilder()); - setCommand(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - if (groupBy == null || model.getItems().isEmpty()) { return; } - - boolean collapsed = !isAllCollapsed; - for (Group group : groups) { - group.isCollapsed = collapsed; - } - - updateIsAllCollapsed(); - clearSelection(); //must clear selection since indices and visible items will be changing - updateLayout(false); - } - }); - } - - private void updateIsAllCollapsed() { - boolean isAllCollapsed0 = true; - for (Group group : groups) { - if (!group.isCollapsed) { - isAllCollapsed0 = false; - break; - } - } - isAllCollapsed = isAllCollapsed0; - } - - @Override - protected void drawContent(Graphics g, float w, float h, final boolean pressed) { - float lineThickness = Utils.scale(1); - float offset = 2 * lineThickness; - float squareSize = Math.round(w / 2 - offset); - if (squareSize % 2 == 1) { - squareSize++; //needs to be even number for this to look right - } - float x = Math.round((w - squareSize) / 2 - offset); - float y = Math.round((h - squareSize) / 2 - offset); - if (pressed) { - y += lineThickness; - } - else { - x -= lineThickness; - } - - for (int i = 0; i < 2; i++) { - g.drawLine(lineThickness, GROUP_HEADER_FORE_COLOR, x, y, x + squareSize, y); - g.drawLine(lineThickness, GROUP_HEADER_FORE_COLOR, x + squareSize, y, x + squareSize, y + offset); - g.drawLine(lineThickness, GROUP_HEADER_FORE_COLOR, x, y, x, y + squareSize); - g.drawLine(lineThickness, GROUP_HEADER_FORE_COLOR, x, y + squareSize, x + offset, y + squareSize); - x += offset; - y += offset; - } - g.drawLine(lineThickness, GROUP_HEADER_FORE_COLOR, x, y, x + squareSize, y); - g.drawLine(lineThickness, GROUP_HEADER_FORE_COLOR, x + squareSize, y, x + squareSize, y + squareSize); - g.drawLine(lineThickness, GROUP_HEADER_FORE_COLOR, x, y, x, y + squareSize); - g.drawLine(lineThickness, GROUP_HEADER_FORE_COLOR, x, y + squareSize, x + squareSize, y + squareSize); - g.drawLine(lineThickness, GROUP_HEADER_FORE_COLOR, x + offset + 1, y + squareSize / 2, x + squareSize - offset, y + squareSize / 2); - if (isAllCollapsed) { - g.drawLine(lineThickness, GROUP_HEADER_FORE_COLOR, x + squareSize / 2, y + offset, x + squareSize / 2, y + squareSize - offset - 1); - } - } - } - private final ExpandCollapseButton btnExpandCollapseAll = new ExpandCollapseButton(); - private final FComboBox cbGroupByOptions = new FComboBox<>(Localizer.getInstance().getMessage("lblGroups") + " "); - private final FComboBox cbPileByOptions = new FComboBox<>(Localizer.getInstance().getMessage("lblPiles") + " "); - - public ImageView(ItemManager itemManager0, ItemManagerModel model0) { - super(itemManager0, model0); - - SItemManagerUtil.populateImageViewOptions(itemManager0, cbGroupByOptions, cbPileByOptions); - - cbGroupByOptions.setChangedHandler(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - if (cbGroupByOptions.getSelectedIndex() > 0) { - setGroupBy((GroupDef) cbGroupByOptions.getSelectedItem()); - } - else { - setGroupBy(null); - } - } - }); - cbPileByOptions.setChangedHandler(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - if (cbPileByOptions.getSelectedIndex() > 0) { - setPileBy((ColumnDef) cbPileByOptions.getSelectedItem()); - } - else { - setPileBy(null); - } - } - }); - - cbGroupByOptions.setFont(LABEL_FONT); - cbPileByOptions.setFont(LABEL_FONT); - getPnlOptions().add(btnExpandCollapseAll); - getPnlOptions().add(cbGroupByOptions); - getPnlOptions().add(cbPileByOptions); - - Group group = new Group(""); //add default group - groups.add(group); - getScroller().add(group); - } - - @Override - public void setup(ItemManagerConfig config, Map colOverrides) { - setGroupBy(config.getGroupBy(), true); - setPileBy(config.getPileBy(), true); - setColumnCount(config.getImageColumnCount(), true); - } - - public GroupDef getGroupBy() { - return groupBy; - } - public void setGroupBy(GroupDef groupBy0) { - setGroupBy(groupBy0, false); - } - private void setGroupBy(GroupDef groupBy0, boolean forSetup) { - if (groupBy == groupBy0) { return; } - groupBy = groupBy0; - - if (groupBy == null) { - cbGroupByOptions.setSelectedIndex(0); - } - else { - cbGroupByOptions.setSelectedItem(groupBy); - } - - groups.clear(); - - if (groupBy == null) { - groups.add(new Group("")); - btnExpandCollapseAll.updateIsAllCollapsed(); - } - else { - for (String groupName : groupBy.getGroups()) { - groups.add(new Group(groupName)); - } - - //collapse all groups by default if all previous groups were collapsed - if (btnExpandCollapseAll.isAllCollapsed) { - for (Group group : groups) { - group.isCollapsed = true; - } - } - } - - getScroller().clear(); - for (Group group : groups) { - getScroller().add(group); - } - - if (!forSetup) { - if (itemManager.getConfig() != null) { - itemManager.getConfig().setGroupBy(groupBy); - } - refresh(null, -1, 0); - } - } - - public ColumnDef getPileBy() { - return pileBy; - } - public void setPileBy(ColumnDef pileBy0) { - setPileBy(pileBy0, false); - } - private void setPileBy(ColumnDef pileBy0, boolean forSetup) { - if (pileBy == pileBy0) { return; } - pileBy = pileBy0; - - if (pileBy == null) { - cbPileByOptions.setSelectedIndex(0); - } - else { - cbPileByOptions.setSelectedItem(pileBy); - } - - if (!forSetup) { - if (itemManager.getConfig() != null) { - itemManager.getConfig().setPileBy(pileBy); - } - refresh(null, -1, 0); - } - } - - @Override - protected void fixSelection(final Iterable itemsToSelect, final int backupIndexToSelect, final float scrollValueToRestore) { - clearSelection(); //just clear selection instead of fixing selection this way - setScrollValue(scrollValueToRestore); //ensure scroll value restored - } - - public int getColumnCount() { - return columnCount; - } - - public void setColumnCount(int columnCount0) { - setColumnCount(columnCount0, false); - } - private void setColumnCount(int columnCount0, boolean forSetup) { - if (columnCount0 < MIN_COLUMN_COUNT) { - columnCount0 = MIN_COLUMN_COUNT; - } - else if (columnCount0 > MAX_COLUMN_COUNT) { - columnCount0 = MAX_COLUMN_COUNT; - } - if (columnCount == columnCount0) { return; } - columnCount = columnCount0; - - if (!forSetup) { - if (itemManager.getConfig() != null) { - itemManager.getConfig().setImageColumnCount(columnCount); - } - - //determine item to retain scroll position of following column count change - ItemInfo focalItem0 = getFocalItem(); - if (focalItem0 == null) { - updateLayout(false); - return; - } - - float offsetTop = focalItem0.getTop() - getScrollValue(); - updateLayout(false); - setScrollValue(focalItem0.getTop() - offsetTop); - focalItem = focalItem0; //cache focal item so consecutive column count changes use the same item - } - } - - private ItemInfo getFocalItem() { - if (focalItem != null) { //use cached focalItem if one - return focalItem; - } - - //if not item hovered, use first fully visible item as focal point - final float visibleTop = getScrollValue(); - for (Group group : groups) { - if (group.getBottom() < visibleTop) { - continue; - } - for (Pile pile : group.piles) { - if (group.getBottom() < visibleTop) { - continue; - } - for (ItemInfo item : pile.items) { - if (item.getTop() >= visibleTop) { - return item; - } - } - } - } - if (orderedItems.isEmpty()) { - return null; - } - return orderedItems.get(0); - } - - @Override - protected void onResize(float visibleWidth, float visibleHeight) { - updateLayout(false); //need to update layout to adjust wrapping of items - } - - @Override - protected void onRefresh() { - Group otherItems = groupBy == null ? groups.get(0) : null; - - for (Group group : groups) { - group.items.clear(); - } - clearSelection(); - - for (Entry itemEntry : model.getOrderedList()) { - T item = itemEntry.getKey(); - int qty = itemEntry.getValue(); - int groupIndex = groupBy == null ? -1 : groupBy.getItemGroupIndex(item); - - Group group; - if (groupIndex >= 0) { - group = groups.get(groupIndex); - } - else { - if (otherItems == null) { - //reuse existing Other group if possible - if (groups.size() > groupBy.getGroups().length) { - otherItems = groups.get(groups.size() - 1); - } - else { - otherItems = new Group(Localizer.getInstance().getMessage("lblOther")); - otherItems.isCollapsed = btnExpandCollapseAll.isAllCollapsed; - groups.add(otherItems); - } - } - group = otherItems; - } - - for (int i = 0; i < qty; i++) { - group.add(new ItemInfo(item, group)); - } - } - - if (otherItems == null && groups.size() > groupBy.getGroups().length) { - groups.remove(groups.size() - 1); //remove Other group if empty - btnExpandCollapseAll.updateIsAllCollapsed(); - } - - updateLayout(true); - } - - @Override - protected void layoutOptionsPanel(float width, float height) { - float padding = ItemFilter.PADDING; - float x = 0; - float h = FTextField.getDefaultHeight(ItemFilter.DEFAULT_FONT); - float y = padding; - btnExpandCollapseAll.setBounds(x, y, h, h); - x += h + padding; - - float pileByWidth = itemManager.getPileByWidth(); - float groupByWidth = width - x - padding - pileByWidth; - - cbGroupByOptions.setBounds(x, y, groupByWidth, h); - x += groupByWidth + padding; - cbPileByOptions.setBounds(x, y, pileByWidth, h); - } - - private void updateLayout(boolean forRefresh) { - if (updatingLayout) { return; } //prevent infinite loop - updatingLayout = true; - - focalItem = null; //clear cached focalItem when layout changes - - float x, groupY, pileY, pileHeight, maxPileHeight; - float y = PADDING; - float groupX = PADDING; - float itemAreaWidth = getScroller().getWidth(); - float groupWidth = itemAreaWidth - 2 * groupX; - - float gap = (MAX_COLUMN_COUNT - columnCount) / 2 + Utils.scale(2); //more items per row == less gap between them - float itemWidth = (groupWidth + gap) / columnCount - gap; - if (pileBy != null) { - //if showing piles, make smaller so part of the next card is visible so it's obvious if scrolling is needed - itemWidth *= (1 - 0.2f / columnCount); - } - float itemHeight = itemWidth * FCardPanel.ASPECT_RATIO; - float dx = itemWidth + gap; - float dy = pileBy == null ? itemHeight + gap : itemHeight * PILE_SPACING_Y; - - for (int i = 0; i < groups.size(); i++) { - Group group = groups.get(i); - - if (forRefresh && pileBy != null) { //refresh piles if needed - //use TreeMap to build pile set so iterating below sorts on key - ColumnDef groupPileBy = groupBy == null ? pileBy : groupBy.getGroupPileBy(i, pileBy); - Map, Pile> piles = new TreeMap<>(); - for (ItemInfo itemInfo : group.items) { - Comparable key = groupPileBy.fnSort.apply(itemInfo); - if (!piles.containsKey(key)) { - piles.put(key, new Pile()); - } - piles.get(key).items.add(itemInfo); - } - group.piles.clear(); - group.piles.addAll(piles.values()); - } - - groupY = y; - - if (group.items.isEmpty()) { - group.setBounds(groupX, groupY, groupWidth, 0); - group.scrollWidth = groupWidth; - continue; - } - - if (groupBy != null) { - y += GROUP_HEADER_HEIGHT + PADDING; //leave room for group header - if (group.isCollapsed) { - group.setBounds(groupX, groupY, groupWidth, GROUP_HEADER_HEIGHT); - group.scrollWidth = groupWidth; - continue; - } - } - - if (pileBy == null) { - //if not piling by anything, wrap items using a pile for each row - group.piles.clear(); - Pile pile = new Pile(); - x = 0; - - for (ItemInfo itemInfo : group.items) { - itemInfo.pos = CardStackPosition.Top; - - if (pile.items.size() == columnCount) { - pile = new Pile(); - x = 0; - y += dy; - } - - itemInfo.setBounds(x, y, itemWidth, itemHeight); - - if (pile.items.size() == 0) { - pile.setBounds(0, y, groupWidth, itemHeight); - group.piles.add(pile); - } - pile.items.add(itemInfo); - x += dx; - } - y += itemHeight; - group.scrollWidth = groupWidth; - } - else { - x = 0; - pileY = y; - maxPileHeight = 0; - for (int j = 0; j < group.piles.size(); j++) { - Pile pile = group.piles.get(j); - y = pileY; - for (ItemInfo itemInfo : pile.items) { - itemInfo.pos = CardStackPosition.BehindVert; - itemInfo.setBounds(x, y, itemWidth, itemHeight); - y += dy; - } - pile.items.get(pile.items.size() - 1).pos = CardStackPosition.Top; - pileHeight = y + itemHeight - dy - pileY; - if (pileHeight > maxPileHeight) { - maxPileHeight = pileHeight; - } - pile.setBounds(x, pileY, itemWidth, pileHeight); - x += dx; - } - y = pileY + maxPileHeight; //update y for setting group height below - group.scrollWidth = Math.max(x - gap, groupWidth); - } - - group.setBounds(groupX, groupY, groupWidth, y - groupY); - y += PADDING; - } - scrollHeight = y; - - if (forRefresh) { //refresh ordered items if needed - int index = 0; - orderedItems.clear(); - for (Group group : groups) { - if (group.isCollapsed || group.items.isEmpty()) { continue; } - - for (Pile pile : group.piles) { - for (ItemInfo itemInfo : pile.items) { - itemInfo.index = index++; - orderedItems.add(itemInfo); - } - } - } - } - getScroller().revalidate(); - updatingLayout = false; - } - - @Override - protected float getScrollHeight() { - return scrollHeight; - } - - @Override - protected boolean tap(float x, float y, int count) { - ItemInfo item = getItemAtPoint(x, y); - if (count == 1) { - selectItem(item); - itemManager.showMenu(false); - } - else if (count == 2) { - if (item != null && item.selected) { - if (!(item.getKey() instanceof DeckProxy)) - itemManager.activateSelectedItems(); - } - } - return true; - } - - @Override - protected boolean zoom(float x, float y, float amount) { - totalZoomAmount += amount; - - float columnZoomAmount = 2 * Utils.AVG_FINGER_WIDTH; - while (totalZoomAmount >= columnZoomAmount) { - setColumnCount(getColumnCount() - 1); - totalZoomAmount -= columnZoomAmount; - } - while (totalZoomAmount <= -columnZoomAmount) { - setColumnCount(getColumnCount() + 1); - totalZoomAmount += columnZoomAmount; - } - return true; - } - - private ItemInfo getItemAtPoint(float x, float y) { - //check selected items first since they appear on top - for (int i = selectedIndices.size() - 1; i >= 0; i--) { - ItemInfo item = orderedItems.get(selectedIndices.get(i)); - float relX = x + item.group.getScrollLeft() - item.group.getLeft(); - float relY = y + getScrollValue(); - if (item.contains(relX, relY)) { - return item; - } - } - - for (int i = groups.size() - 1; i >= 0; i--) { - Group group = groups.get(i); - if (!group.isCollapsed) { - for (int j = group.piles.size() - 1; j >= 0; j--) { - float relX = x + group.getScrollLeft() - group.getLeft(); - float relY = y + getScrollValue(); - Pile pile = group.piles.get(j); - if (pile.contains(relX, relY)) { - for (int k = pile.items.size() - 1; k >= 0; k--) { - ItemInfo item = pile.items.get(k); - if (item.contains(relX, relY)) { - return item; - } - } - } - } - } - } - return null; - } - - @Override - public T getItemAtIndex(int index) { - if (index >= 0 && index < getCount()) { - return orderedItems.get(index).item; - } - return null; - } - - @Override - public int getIndexOfItem(T item) { - for (Group group : groups) { - for (ItemInfo itemInfo : group.items) { - if (itemInfo.item == item) { - //if group containing item is collapsed, expand it so the item can be selected and has a valid index - if (group.isCollapsed) { - group.isCollapsed = false; - btnExpandCollapseAll.updateIsAllCollapsed(); - clearSelection(); //must clear selection since indices and visible items will be changing - updateLayout(false); - } - return itemInfo.index; - } - } - } - return -1; - } - - @Override - public int getSelectedIndex() { - return selectedIndices.isEmpty() ? -1 : selectedIndices.get(0); - } - - @Override - public Iterable getSelectedIndices() { - return selectedIndices; - } - - @Override - public int getCount() { - return orderedItems.size(); - } - - @Override - public int getSelectionCount() { - return selectedIndices.size(); - } - - @Override - public int getIndexAtPoint(float x, float y) { - ItemInfo item = getItemAtPoint(x, y); - if (item != null) { - return item.index; - } - return -1; - } - - @Override - public FImage getIcon() { - if (itemManager.getGenericType().equals(DeckProxy.class)) { - return FSkinImage.PACK; - } - return FSkinImage.CARD_IMAGE; - } - - @Override - public String getCaption() { - return Localizer.getInstance().getMessage("lblImageView"); - } - - @Override - public void selectAll() { - clearSelection(); - for (Integer i = 0; i < getCount(); i++) { - selectedIndices.add(i); - } - updateSelection(); - onSelectionChange(); - } - - @Override - protected void onSetSelectedIndex(int index) { - clearSelection(); - selectedIndices.add(index); - updateSelection(); - } - - @Override - protected void onSetSelectedIndices(Iterable indices) { - clearSelection(); - for (Integer index : indices) { - selectedIndices.add(index); - } - updateSelection(); - } - - private void clearSelection() { - int count = getCount(); - for (Integer i : selectedIndices) { - if (i < count) { - orderedItems.get(i).selected = false; - } - } - selectedIndices.clear(); - } - - private void updateSelection() { - for (Integer i : selectedIndices) { - orderedItems.get(i).selected = true; - } - } - - private boolean selectItem(ItemInfo item) { - if (item == null) { - if (!KeyInputAdapter.isCtrlKeyDown() && !KeyInputAdapter.isShiftKeyDown()) { - if (minSelections == 0) { - clearSelection(); - onSelectionChange(); - } - } - return false; - } - - if (item.selected) { //unselect item if already selected - if (selectedIndices.size() > minSelections) { - item.selected = false; - selectedIndices.remove((Object)item.index); - onSelectionChange(); - item.group.scrollIntoView(item); - } - return true; - } - if (maxSelections <= 1 || (!KeyInputAdapter.isCtrlKeyDown() && !KeyInputAdapter.isShiftKeyDown())) { - clearSelection(); - } - if (selectedIndices.size() < maxSelections) { - selectedIndices.add(0, item.index); - item.selected = true; - onSelectionChange(); - item.group.scrollIntoView(item); - getScroller().scrollIntoView(item); - } - return true; - } - - @Override - public void scrollSelectionIntoView() { - if (selectedIndices.isEmpty()) { return; } - - ItemInfo itemInfo = orderedItems.get(selectedIndices.get(0)); - getScroller().scrollIntoView(itemInfo); - } - - @Override - public Rectangle getSelectionBounds() { - if (selectedIndices.isEmpty()) { return null; } - - ItemInfo itemInfo = orderedItems.get(selectedIndices.get(0)); - Vector2 relPos = itemInfo.group.getChildRelativePosition(itemInfo); - return new Rectangle(itemInfo.group.screenPos.x + relPos.x - SEL_BORDER_SIZE + itemInfo.group.getLeft(), - itemInfo.group.screenPos.y + relPos.y - SEL_BORDER_SIZE, - itemInfo.getWidth() + 2 * SEL_BORDER_SIZE, itemInfo.getHeight() + 2 * SEL_BORDER_SIZE); - } - - private class Group extends FScrollPane { - private final List items = new ArrayList<>(); - private final List piles = new ArrayList<>(); - private final String name; - private boolean isCollapsed; - private float scrollWidth; - - public Group(String name0) { - name = name0; - } - - public void add(ItemInfo item) { - items.add(item); - } - - @Override - public String toString() { - return name; - } - - @Override - public void draw(Graphics g) { - if (items.isEmpty()) { return; } - - if (groupBy != null) { - //draw group name and horizontal line - float x = GROUP_HEADER_GLYPH_WIDTH + PADDING + 1; - float y = 0; - String caption = name + " (" + items.size() + ")"; - g.drawText(caption, GROUP_HEADER_FONT, GROUP_HEADER_FORE_COLOR, x, y, getWidth(), GROUP_HEADER_HEIGHT, false, Align.left, true); - x += GROUP_HEADER_FONT.getBounds(caption).width + PADDING; - y += GROUP_HEADER_HEIGHT / 2; - g.drawLine(GROUP_HEADER_LINE_THICKNESS, GROUP_HEADER_LINE_COLOR, x, y, getWidth(), y); - - //draw expand/collapse glyph - float offset = GROUP_HEADER_GLYPH_WIDTH / 2 + 1; - x = offset; - if (isCollapsed) { - y += GROUP_HEADER_LINE_THICKNESS; - g.fillTriangle(GROUP_HEADER_LINE_COLOR, - x, y - offset, - x + offset, y, - x, y + offset); - } - else { - g.fillTriangle(GROUP_HEADER_LINE_COLOR, - x - offset + 2, y + offset - 1, - x + offset, y + offset - 1, - x + offset, y - offset + 1); - } - - if (isCollapsed) { return; } - - float visibleLeft = getScrollLeft(); - float visibleRight = visibleLeft + getWidth(); - for (Pile pile : piles) { - if (pile.getRight() < visibleLeft) { - continue; - } - if (pile.getLeft() >= visibleRight) { - break; - } - pile.draw(g); - } - return; - } - - final float visibleTop = getScrollValue(); - final float visibleBottom = visibleTop + getScroller().getHeight(); - for (ItemInfo itemInfo : items) { - if (itemInfo.getBottom() < visibleTop) { - continue; - } - if (itemInfo.getTop() >= visibleBottom) { - break; - } - itemInfo.draw(g); - } - } - - @Override - protected ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) { - return new ScrollBounds(scrollWidth, visibleHeight); - } - - @Override - public boolean tap(float x, float y, int count) { - ItemInfo item = getItemAtPoint(x + getLeft(), y + getTop()); - if (item != null) { - if(item.getKey() instanceof DeckProxy) { - DeckProxy dp = (DeckProxy)item.getKey(); - if (count >= 2 && !dp.isGeneratedDeck()) { - //double tap to add to favorites or remove.... - if (DeckPreferences.getPrefs(dp).getStarCount() > 0) - DeckPreferences.getPrefs(dp).setStarCount(0); - else - DeckPreferences.getPrefs(dp).setStarCount(1); - - updateLayout(false); - } - } - } - if (groupBy != null && !items.isEmpty() && y < GROUP_HEADER_HEIGHT) { - isCollapsed = !isCollapsed; - btnExpandCollapseAll.updateIsAllCollapsed(); - clearSelection(); //must clear selection since indices and visible items will be changing - updateLayout(false); - return true; - } - return false; - } - - @Override - public boolean longPress(float x, float y) { - ItemInfo item = getItemAtPoint(x + getLeft(), y + getTop()); - if (item != null) { - if(item.getKey() instanceof CardThemedDeckGenerator || item.getKey() instanceof CommanderDeckGenerator - || item.getKey() instanceof ArchetypeDeckGenerator || item.getKey() instanceof DeckProxy){ - FDeckViewer.show(((DeckProxy)item.getKey()).getDeck()); - return true; - } - CardZoom.show(orderedItems, orderedItems.indexOf(item), itemManager); - return true; - } - return false; - } - - //provide special override for this function to account for special ItemInfo positioning logic - @Override - protected Vector2 getChildRelativePosition(FDisplayObject child, float offsetX, float offsetY) { - return new Vector2(child.getLeft() - getScrollLeft() + offsetX - getLeft(), child.getTop() - getScrollValue() + offsetY - getTop()); - } - } - private class Pile extends FDisplayObject { - private final List items = new ArrayList<>(); - - @Override - public void draw(Graphics g) { - final float visibleTop = getScrollValue(); - final float visibleBottom = visibleTop + getScroller().getHeight(); - - ItemInfo skippedItem = null; - for (ItemInfo itemInfo : items) { - if (itemInfo.getBottom() < visibleTop) { - continue; - } - if (itemInfo.getTop() >= visibleBottom) { - break; - } - if (itemInfo.selected) { - skippedItem = itemInfo; - } - else { - itemInfo.draw(g); - } - } - if (skippedItem != null) { - CardStackPosition backupPos = skippedItem.pos; - skippedItem.pos = CardStackPosition.Top; //ensure skipped item rendered as if it was on top - skippedItem.draw(g); - skippedItem.pos = backupPos; - } - } - } - private class ItemInfo extends FDisplayObject implements Entry { - private final T item; - private final Group group; - private int index; - private CardStackPosition pos; - private boolean selected; - private final float IMAGE_SIZE = CardRenderer.MANA_SYMBOL_SIZE; - - private ItemInfo(T item0, Group group0) { - item = item0; - group = group0; - } - - @Override - public String toString() { - return item.toString(); - } - - @Override - public InventoryItem getKey() { - return item; - } - - @Override - public Integer getValue() { - return 1; - } - - @Override - public Integer setValue(Integer value) { - return 1; - } - - @Override - public void draw(Graphics g) { - final float x = getLeft() - group.getScrollLeft(); - final float y = getTop() - group.getTop() - getScrollValue(); - final float w = getWidth(); - final float h = getHeight(); - Texture dpImg = null; - boolean deckSelectMode = false; - if (item instanceof DeckProxy) { - dpImg = ImageCache.getImage(item); - deckSelectMode = true; - } - if (selected) { - if (!deckSelectMode) { - //if round border is enabled, the select highlight is also rounded.. - if (Forge.enableUIMask.equals("Full")) { - //fillroundrect has rough/aliased corner - g.fillRoundRect(Color.GREEN, x - SEL_BORDER_SIZE, y - SEL_BORDER_SIZE, w + 2 * SEL_BORDER_SIZE, h + 2 * SEL_BORDER_SIZE, (h - w) / 10); - //drawroundrect has GL_SMOOTH to `smoothen/faux` the aliased corner - g.drawRoundRect(1f, Color.GREEN, x - SEL_BORDER_SIZE, y - SEL_BORDER_SIZE, w + 1.5f * SEL_BORDER_SIZE, h + 1.5f * SEL_BORDER_SIZE, (h - w) / 10); - } - else //default rectangle highlight - g.fillRect(Color.GREEN, x - SEL_BORDER_SIZE, y - SEL_BORDER_SIZE, w + 2 * SEL_BORDER_SIZE, h + 2 * SEL_BORDER_SIZE); - } - } - - if (item instanceof PaperCard) { - CardRenderer.drawCard(g, (PaperCard) item, x, y, w, h, pos); - } else if (item instanceof ConquestCommander) { - CardRenderer.drawCard(g, ((ConquestCommander) item).getCard(), x, y, w, h, pos); - } else if (deckSelectMode) { - DeckProxy dp = ((DeckProxy) item); - ColorSet deckColor = dp.getColor(); - float scale = 0.75f; - - if (dpImg != null) {//generated decks have missing info... - if (Forge.enableUIMask.equals("Off")){ - if (selected) - g.fillRect(Color.GREEN, x - SEL_BORDER_SIZE, y - SEL_BORDER_SIZE, w + 2 * SEL_BORDER_SIZE, h + 2 * SEL_BORDER_SIZE); - g.drawImage(dpImg, x, y, w, h); - } else { - //commander bg - g.drawImage(FSkin.getDeckbox().get(0), FSkin.getDeckbox().get(0), x, y, w, h, Color.GREEN, selected); - TextureRegion tr = ImageCache.croppedBorderImage(dpImg); - g.drawImage(tr, x+(w-w*scale)/2, y+(h-h*scale)/1.5f, w*scale, h*scale); - } - //fake labelname shadow - g.drawText(item.getName(), GROUP_HEADER_FONT, Color.BLACK, (x + PADDING)-1f, (y + PADDING*2)+1f, w - 2 * PADDING, h - 2 * PADDING, true, Align.center, false); - //labelname - g.drawText(item.getName(), GROUP_HEADER_FONT, Color.WHITE, x + PADDING, y + PADDING*2, w - 2 * PADDING, h - 2 * PADDING, true, Align.center, false); - } else { - if (!dp.isGeneratedDeck()){ - //If deck has Commander, use it as cardArt reference - String deckImageKey = dp.getDeck().getCommanders().isEmpty() ? dp.getHighestCMCCard().getImageKey(false) : dp.getDeck().getCommanders().get(0).getImageKey(false); - FImageComplex cardArt = CardRenderer.getCardArt(deckImageKey, false, false, false); - //draw the deckbox - if (cardArt == null){ - //draw generic box if null or still loading - g.drawImage(FSkin.getDeckbox().get(2), FSkin.getDeckbox().get(2), x, y-(h*0.25f), w, h, Color.GREEN, selected); - } else { - g.drawDeckBox(cardArt, scale, FSkin.getDeckbox().get(1), FSkin.getDeckbox().get(2), x, y, w, h, Color.GREEN, selected); - } - } else { - //generic box - g.drawImage(FSkin.getDeckbox().get(2), FSkin.getDeckbox().get(2), x, y-(h*0.25f), w, h, Color.GREEN, selected); - } - if (deckColor != null) { - //deck color identity - float symbolSize = IMAGE_SIZE; - if (Forge.isLandscapeMode()) { - if (columnCount == 4) - symbolSize = IMAGE_SIZE * 1.5f; - else if (columnCount == 3) - symbolSize = IMAGE_SIZE * 2f; - else if (columnCount == 2) - symbolSize = IMAGE_SIZE * 3f; - else if (columnCount == 1) - symbolSize = IMAGE_SIZE * 4f; - } else { - if (columnCount > 2) - symbolSize = IMAGE_SIZE * (0.5f); - } - //vertical mana icons - CardFaceSymbols.drawColorSet(g, deckColor, x +(w-symbolSize), y+(h/8), symbolSize, true); - if(!dp.isGeneratedDeck()) { - if (Forge.hdbuttons) - g.drawImage(DeckPreferences.getPrefs(dp).getStarCount() > 0 ? FSkinImage.HDSTAR_FILLED : FSkinImage.HDSTAR_OUTLINE, x, y, symbolSize, symbolSize); - else - g.drawImage(DeckPreferences.getPrefs(dp).getStarCount() > 0 ? FSkinImage.STAR_FILLED : FSkinImage.STAR_OUTLINE, x, y, symbolSize, symbolSize); - } - } - String deckname = TextUtil.fastReplace(item.getName(),"] #", "]\n#"); - //deckname fakeshadow - g.drawText(deckname, GROUP_HEADER_FONT, Color.BLACK, (x + PADDING)-1f, (y + (h/10) + PADDING)+1f, w - 2 * PADDING, h - 2 * PADDING, true, Align.center, true); - //deck name - g.drawText(deckname, GROUP_HEADER_FONT, Color.WHITE, x + PADDING, y + (h/10) + PADDING, w - 2 * PADDING, h - 2 * PADDING, true, Align.center, true); - } - } else { - Texture img = ImageCache.getImage(item); - if (img != null) { - g.drawImage(img, x, y, w, h); - } else { - g.fillRect(Color.BLACK, x, y, w, h); - g.drawText(item.getName(), GROUP_HEADER_FONT, Color.WHITE, x + PADDING, y + PADDING, w - 2 * PADDING, h - 2 * PADDING, true, Align.center, false); - } - } - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/views/ItemListView.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/views/ItemListView.java deleted file mode 100644 index 7feef4731f3..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/views/ItemListView.java +++ /dev/null @@ -1,331 +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.adventure.libgdxgui.itemmanager.views; - -import com.badlogic.gdx.math.Rectangle; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FImage; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.FSkinImage; -import forge.adventure.libgdxgui.itemmanager.ItemManager; -import forge.adventure.libgdxgui.toolbox.FCheckBox; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.toolbox.FList; -import forge.item.InventoryItem; -import forge.itemmanager.ColumnDef; -import forge.itemmanager.ItemColumn; -import forge.itemmanager.ItemManagerConfig; -import forge.itemmanager.ItemManagerModel; -import forge.util.Localizer; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - - -public final class ItemListView extends ItemView { - private static final FSkinColor ROW_COLOR = FSkinColor.get(Colors.CLR_ZEBRA); - private static final FSkinColor ALT_ROW_COLOR = ROW_COLOR.getContrastColor(-20); - private static final FSkinColor SEL_COLOR = FSkinColor.get(Colors.CLR_ACTIVE); - - private final ItemList list = new ItemList(); - private final ItemListModel listModel; - private final List selectedIndices = new ArrayList<>(); - - public ItemListModel getListModel() { - return listModel; - } - - /** - * ItemListView Constructor. - * - * @param itemManager0 - * @param model0 - */ - public ItemListView(ItemManager itemManager0, ItemManagerModel model0) { - super(itemManager0, model0); - listModel = new ItemListModel(model0); - getPnlOptions().setVisible(false); //hide options panel by default - getScroller().add(list); - } - - @Override - public void setup(ItemManagerConfig config, Map colOverrides) { - list.compactModeHandler.setCompactMode(config.getCompactListView()); - refresh(null, 0, 0); - } - - @Override - public FImage getIcon() { - return FSkinImage.LIST; - } - - @Override - public String getCaption() { - return Localizer.getInstance().getMessage("lblListView"); - } - - @Override - public int getSelectedIndex() { - if (selectedIndices.isEmpty()) { - return -1; - } - return selectedIndices.get(0); - } - - @Override - public Iterable getSelectedIndices() { - return selectedIndices; - } - - @Override - protected void onSetSelectedIndex(int index) { - selectedIndices.clear(); - selectedIndices.add(index); - } - - @Override - protected void onSetSelectedIndices(Iterable indices) { - selectedIndices.clear(); - for (Integer index : indices) { - selectedIndices.add(index); - } - } - - @Override - public float getScrollValue() { - return list.getScrollTop(); - } - - @Override - public void setScrollValue(float value) { - list.setScrollTop(value); - } - - @Override - public void scrollSelectionIntoView() { - list.scrollIntoView(getSelectedIndex()); - } - - @Override - public Rectangle getSelectionBounds() { - if (selectedIndices.isEmpty()) { return null; } - - return new Rectangle(list.screenPos.x, list.screenPos.y + list.getItemStartPosition(getSelectedIndex()), list.getWidth(), list.getListItemRenderer().getItemHeight()); - } - - @Override - public void selectAll() { - selectedIndices.clear(); - for (Integer i = 0; i < getCount(); i++) { - selectedIndices.add(i); - } - onSelectionChange(); - } - - @Override - public int getIndexOfItem(T item) { - return listModel.itemToRow(item); - } - - @Override - public T getItemAtIndex(int index) { - Entry itemEntry = listModel.rowToItem(index); - return itemEntry != null ? itemEntry.getKey() : null; - } - - @Override - public int getCount() { - return list.getCount(); - } - - @Override - public int getSelectionCount() { - return selectedIndices.size(); - } - - @Override - public int getIndexAtPoint(float x, float y) { - return 0; //TODO - } - - @Override - protected void onResize(float visibleWidth, float visibleHeight) { - list.setSize(visibleWidth, visibleHeight); - } - - @Override - protected void onRefresh() { - list.setListData(model.getOrderedList()); - } - - @Override - protected float getScrollHeight() { - return getScroller().getHeight(); - } - - @Override - protected void layoutOptionsPanel(float width, float height) { - } - - public final class ItemList extends FList> { - private final ItemManager.ItemRenderer renderer; - private final CompactModeHandler compactModeHandler; - - private ItemList() { - compactModeHandler = new CompactModeHandler(); - renderer = itemManager.getListItemRenderer(compactModeHandler); - setListItemRenderer(new ListItemRenderer>() { - private int prevTapIndex = -1; - - @Override - public float getItemHeight() { - return renderer.getItemHeight(); - } - - @Override - public boolean tap(Integer index, Entry value, float x, float y, int count) { - if (maxSelections > 1) { //if multi-select - //don't toggle checkbox if renderer handles tap - if (!renderer.tap(index, value, x, y, count)) { - if (selectedIndices.contains(index)) { - //allow removing selection if it won't fall below min - //or if max selected (since you need to be able to deselect an item before selecting a new item) - if (selectedIndices.size() > minSelections || selectedIndices.size() == maxSelections) { - selectedIndices.remove(index); - onSelectionChange(); - } - } - else if (selectedIndices.size() < maxSelections) { - selectedIndices.add(index); - Collections.sort(selectedIndices); //ensure selected indices are sorted - onSelectionChange(); - } - } - } - else { //if single-select - setSelectedIndex(index); - - //don't activate if renderer handles tap - if (!renderer.tap(index, value, x, y, count)) { - if (count == 1) { - itemManager.showMenu(false); - } - else if (count == 2 && index == prevTapIndex) { - itemManager.activateSelectedItems(); - } - } - } - - prevTapIndex = index; - return true; - } - - @Override - public boolean showMenu(Integer index, Entry value, FDisplayObject owner, float x, float y) { - return renderer.longPress(index, value, x, y); - } - - @Override - public void drawValue(Graphics g, Integer index, Entry value, FSkinFont font, FSkinColor foreColor, FSkinColor backColor, boolean pressed, float x, float y, float w, float h) { - if (maxSelections > 1) { - if (pressed) { //if multi-select mode, draw SEL_COLOR when pressed - g.fillRect(SEL_COLOR, x - FList.PADDING, y - FList.PADDING, w + 2 * FList.PADDING, h + 2 * FList.PADDING); - } - //draw checkbox, with it checked based on whether item is selected - float checkBoxSize = h * 0.4f; - float padding = checkBoxSize / 2; - w -= checkBoxSize + padding; - FCheckBox.drawCheckBox(g, selectedIndices.contains(index), x + w, y + (h - checkBoxSize) / 2, checkBoxSize, checkBoxSize); - w -= padding; - } - renderer.drawValue(g, value, font, foreColor, backColor, pressed, x + 1, y, w - 2, h); //x + 1 and w - 2 to account for left and right borders - } - }); - setFont(FSkinFont.get(14)); - } - - @Override - protected void drawBackground(Graphics g) { - //draw no background by default - } - - @Override - public boolean press(float x, float y) { - if (renderer.allowPressEffect(this, x, y)) { - return super.press(x, y); - } - return true; - } - - @Override - protected FSkinColor getItemFillColor(int index) { - if (maxSelections == 1 && selectedIndices.contains(index)) { - return SEL_COLOR; //don't show SEL_COLOR if in multi-select mode - } - if (index % 2 == 1) { - return ALT_ROW_COLOR; - } - return ROW_COLOR; - } - - @Override - protected boolean drawLineSeparators() { - return false; - } - - @Override - public boolean zoom(float x, float y, float amount) { - if (compactModeHandler.update(amount)) { - revalidate(); //update scroll bounds - scrollSelectionIntoView(); //ensure selection remains in view - - //update compact mode configuration - itemManager.getConfig().setCompactListView(compactModeHandler.isCompactMode()); - } - return true; - } - } - - public final class ItemListModel { - private final ItemManagerModel model; - - public ItemListModel(final ItemManagerModel model0) { - model = model0; - } - - public Entry rowToItem(final int row) { - final List> orderedList = model.getOrderedList(); - return (row >= 0) && (row < orderedList.size()) ? orderedList.get(row) : null; - } - - public int itemToRow(final T item) { //TODO: Consider optimizing this if used frequently - final List> orderedList = model.getOrderedList(); - for (int i = 0; i < orderedList.size(); i++) { - if (orderedList.get(i).getKey() == item) { - return i; - } - } - return -1; - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/views/ItemView.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/views/ItemView.java deleted file mode 100644 index dc5b8901e76..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/itemmanager/views/ItemView.java +++ /dev/null @@ -1,283 +0,0 @@ -package forge.adventure.libgdxgui.itemmanager.views; - -import com.badlogic.gdx.math.Rectangle; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FImage; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.itemmanager.ItemManager; -import forge.adventure.libgdxgui.toolbox.FContainer; -import forge.adventure.libgdxgui.toolbox.FEvent; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventType; -import forge.adventure.libgdxgui.toolbox.FScrollPane; -import forge.item.InventoryItem; -import forge.itemmanager.ColumnDef; -import forge.itemmanager.ItemColumn; -import forge.itemmanager.ItemManagerConfig; -import forge.itemmanager.ItemManagerModel; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -public abstract class ItemView { - protected static final float UNOWNED_ALPHA_COMPOSITE = 0.35f; - private static final FSkinColor BORDER_COLOR = FSkinColor.get(Colors.CLR_TEXT); - - protected final ItemManager itemManager; - protected final ItemManagerModel model; - protected int minSelections = 0; - protected int maxSelections = 1; - private final Scroller scroller = new Scroller(); - private final OptionsPanel pnlOptions = new OptionsPanel(); - - private float heightBackup; - private final boolean isIncrementalSearchActive = false; - - protected ItemView(ItemManager itemManager0, ItemManagerModel model0) { - itemManager = itemManager0; - model = model0; - } - - private class Scroller extends FScrollPane { - @Override - protected ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) { - onResize(visibleWidth, visibleHeight); - return new ScrollBounds(visibleWidth, ItemView.this.getScrollHeight()); - } - - protected void setScrollPositionsAfterLayout(float scrollLeft0, float scrollTop0) { - if (getHeight() != heightBackup) { - heightBackup = getHeight(); - scrollSelectionIntoView(); //scroll selection into view whenever view height changes - } - else { - super.setScrollPositionsAfterLayout(scrollLeft0, scrollTop0); - } - } - - @Override - public boolean tap(float x, float y, int count) { - return ItemView.this.tap(x, y, count); - } - - @Override - public boolean zoom(float x, float y, float amount) { - return ItemView.this.zoom(x, y, amount); - } - - @Override - public void drawOverlay(Graphics g) { - super.drawOverlay(g); - g.drawRect(1.5f, BORDER_COLOR, 0, 0, getWidth(), getHeight()); - } - } - - protected boolean tap(float x, float y, int count) { - return false; - } - protected boolean zoom(float x, float y, float amount) { - return false; - } - protected abstract float getScrollHeight(); - protected abstract void layoutOptionsPanel(float width, float height); - - private class OptionsPanel extends FContainer { - @Override - protected void doLayout(float width, float height) { - layoutOptionsPanel(width, height); - } - } - - public FScrollPane getScroller() { - return scroller; - } - - public FContainer getPnlOptions() { - return pnlOptions; - } - - public float getScrollValue() { - return scroller.getScrollTop(); - } - - public void setScrollValue(float value) { - scroller.setScrollTop(value); - } - - public boolean isIncrementalSearchActive() { - return isIncrementalSearchActive; - } - - public void refresh(final Iterable itemsToSelect, final int backupIndexToSelect, final float scrollValueToRestore) { - model.refreshSort(); - onRefresh(); - fixSelection(itemsToSelect, backupIndexToSelect, scrollValueToRestore); - } - protected abstract void onResize(float visibleWidth, float visibleHeight); - protected abstract void onRefresh(); - protected void fixSelection(final Iterable itemsToSelect, final int backupIndexToSelect, final float scrollValueToRestore) { - if (itemsToSelect == null) { - if (itemManager.getMultiSelectMode()) { //if in multi-select mode, clear selection - setSelectedIndex(-1, false); - } - else { //otherwise select first item if no items to select - setSelectedIndex(0, false); - } - setScrollValue(0); //ensure scrolled to top - } - else { - if (!setSelectedItems(itemsToSelect)) { - setSelectedIndex(backupIndexToSelect); - - if (itemManager.getMultiSelectMode()) { //in multi-select mode, clear selection after scrolling into view - setSelectedIndex(-1, false); - } - } - } - } - - public final T getSelectedItem() { - return getItemAtIndex(getSelectedIndex()); - } - - public final Collection getSelectedItems() { - List items = new ArrayList<>(); - for (Integer i : getSelectedIndices()) { - T item = getItemAtIndex(i); - if (item != null) { - items.add(item); - } - } - return items; - } - - public final boolean setSelectedItem(T item) { - return setSelectedItem(item, true); - } - public final boolean setSelectedItem(T item, boolean scrollIntoView) { - int index = getIndexOfItem(item); - if (index != -1) { - setSelectedIndex(index, scrollIntoView); - return true; - } - return false; - } - - public final boolean setSelectedItems(Iterable items) { - return setSelectedItems(items, true); - } - public final boolean setSelectedItems(Iterable items, boolean scrollIntoView) { - List indices = new ArrayList<>(); - for (T item : items) { - int index = getIndexOfItem(item); - if (index != -1) { - indices.add(index); - } - } - if (indices.size() > 0) { - onSetSelectedIndices(indices); - if (scrollIntoView) { - scrollSelectionIntoView(); - } - onSelectionChange(); - return true; - } - return false; - } - - public void setSelectedIndex(int index) { - setSelectedIndex(index, true); - } - public void setSelectedIndex(int index, boolean scrollIntoView) { - int count = getCount(); - if (count == 0) { return; } - if (maxSelections == 0) { return; } - - if (index < 0) { - if (index == -1 && minSelections == 0) { //allow passing -1 to clear selection if no selection allowed - if (getSelectionCount() > 0) { - onSetSelectedIndices(new ArrayList<>()); - onSelectionChange(); - } - return; - } - index = 0; - } - else if (index >= count) { - index = count - 1; - } - - onSetSelectedIndex(index); - if (scrollIntoView) { - scrollSelectionIntoView(); - } - - onSelectionChange(); - } - - public void setSelectedIndices(Iterable indices) { - setSelectedIndices(indices, true); - } - public void setSelectedIndices(Iterable indices, boolean scrollIntoView) { - int count = getCount(); - if (count == 0) { return; } - - List indexList = new ArrayList<>(); - for (Integer index : indices) { - if (index >= 0 && index < count) { - indexList.add(index); - } - } - - if (indexList.isEmpty()) { //if no index in range, set selected index based on first index - for (Integer index : indices) { - setSelectedIndex(index); - return; - } - return; - } - - onSetSelectedIndices(indexList); - if (scrollIntoView) { - scrollSelectionIntoView(); - } - - onSelectionChange(); - } - - protected void onSelectionChange() { - if (getSelectedIndex() != -1 || itemManager.getMultiSelectMode()) { - if (itemManager.getSelectionChangedHandler() != null) { - itemManager.getSelectionChangedHandler().handleEvent(new FEvent(itemManager, FEventType.CHANGE)); - } - } - } - - public void setSelectionSupport(int minSelections0, int maxSelections0) { - minSelections = minSelections0; - maxSelections = maxSelections0; - } - - @Override - public String toString() { - return getCaption(); //return caption as string for display in combo box - } - - public abstract void setup(ItemManagerConfig config, Map colOverrides); - public abstract T getItemAtIndex(int index); - public abstract int getIndexOfItem(T item); - public abstract int getSelectedIndex(); - public abstract Iterable getSelectedIndices(); - public abstract void selectAll(); - public abstract int getCount(); - public abstract int getSelectionCount(); - public abstract int getIndexAtPoint(float x, float y); - public abstract void scrollSelectionIntoView(); - public abstract Rectangle getSelectionBounds(); - public abstract FImage getIcon(); - public abstract String getCaption(); - protected abstract void onSetSelectedIndex(int index); - protected abstract void onSetSelectedIndices(Iterable indices); -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FCheckBoxMenuItem.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FCheckBoxMenuItem.java deleted file mode 100644 index 326e072ad89..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FCheckBoxMenuItem.java +++ /dev/null @@ -1,47 +0,0 @@ -package forge.adventure.libgdxgui.menu; - -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FImage; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.toolbox.FCheckBox; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; - -public class FCheckBoxMenuItem extends FMenuItem { - public static final float CHECKBOX_SIZE = HEIGHT * 0.45f; - public static final float PADDING = (HEIGHT - CHECKBOX_SIZE) / 3; - public static final FSkinColor FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT); - public static final FSkinColor CHECKBOX_COLOR = FORE_COLOR.alphaColor(0.5f); - - private final boolean checked; - - public FCheckBoxMenuItem(String text0, boolean checked0, FEventHandler handler0) { - this(text0, checked0, null, handler0, true); - } - public FCheckBoxMenuItem(String text0, boolean checked0, FEventHandler handler0, boolean enabled0) { - this(text0, checked0, null, handler0, enabled0); - } - public FCheckBoxMenuItem(String text0, boolean checked0, FImage icon0, FEventHandler handler0) { - this(text0, checked0, icon0, handler0, true); - } - public FCheckBoxMenuItem(String text0, boolean checked0, FImage icon0, FEventHandler handler0, boolean enabled0) { - super(text0, icon0, handler0, enabled0); - checked = checked0; - } - - @Override - public float getMinWidth() { - return super.getMinWidth() + CHECKBOX_SIZE + 2 * PADDING - GAP_X; - } - - @Override - public void draw(Graphics g) { - super.draw(g); - - float w = CHECKBOX_SIZE; - float h = CHECKBOX_SIZE; - float x = getWidth() - PADDING - w; - float y = (getHeight() - h) / 2; - FCheckBox.drawCheckBox(g, CHECKBOX_COLOR, FORE_COLOR, checked, x, y, w, h); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FDropDown.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FDropDown.java deleted file mode 100644 index 3f25ec6f35c..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FDropDown.java +++ /dev/null @@ -1,244 +0,0 @@ -package forge.adventure.libgdxgui.menu; - -import com.badlogic.gdx.math.Rectangle; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinTexture; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.toolbox.FContainer; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.toolbox.FOverlay; -import forge.adventure.libgdxgui.toolbox.FScrollPane; - -public abstract class FDropDown extends FScrollPane { - public static final FSkinColor BORDER_COLOR = FSkinColor.get(Colors.CLR_BORDERS); - - private Backdrop backdrop; - private FMenuTab menuTab; - private FContainer dropDownContainer; - protected ScrollBounds paneSize; - - public FDropDown() { - super.setVisible(false); //hide by default - } - - public FMenuTab getMenuTab() { - return menuTab; - } - public void setMenuTab(FMenuTab menuTab0) { - menuTab = menuTab0; - } - - public FContainer getDropDownContainer() { - return dropDownContainer; - } - public void setDropDownContainer(FContainer dropDownContainer0) { - dropDownContainer = dropDownContainer0; - } - - protected FContainer getContainer() { - FContainer container = dropDownContainer; - if (container == null) { - container = FOverlay.getTopOverlay(); - if (container == null) { - container = Forge.getCurrentScreen(); - } - } - return container; - } - - public void update() { - if (isVisible()) { - updateSizeAndPosition(); - } - } - - public void show() { - setVisible(true); - } - - public void hide() { - setVisible(false); - } - - @Override - public boolean press(float x, float y) { - return true; //prevent auto-hiding when drop down pressed - } - - @Override - public boolean tap(float x, float y, int count) { - if (autoHide()) { - hide(); //hide when tapped by default if configured for auto-hide - } - return true; - } - - @Override - public boolean longPress(float x, float y) { - return true; //prevent objects behind drop down handling long press - } - - @Override - public boolean flick(float x, float y) { - return true; //prevent objects behind drop down handling flick - } - - @Override - public void setVisible(boolean visible0) { - if (isVisible() == visible0) { return; } - - //add/remove drop down from its container, current screen, or top overlay when its visibility changes - FContainer container = getContainer(); - if (visible0) { - updateSizeAndPosition(); - - if (autoHide()) { //add invisible backdrop if needed to allow auto-hiding when pressing outside drop down - backdrop = new Backdrop(); - backdrop.setSize(container.getWidth(), container.getHeight()); - container.add(backdrop); - } - container.add(this); - } - else { - container.remove(this); - if (backdrop != null) { - backdrop.setVisible(false); - container.remove(backdrop); - backdrop = null; - } - onHidden(); - } - super.setVisible(visible0); - } - - protected void onHidden() { - } - - protected abstract boolean autoHide(); - protected abstract ScrollBounds updateAndGetPaneSize(float maxWidth, float maxVisibleHeight); - - protected void updateSizeAndPosition() { - if (menuTab == null) { return; } - - Rectangle boundary = Forge.getCurrentScreen().getDropDownBoundary(); - - float x = menuTab.screenPos.x; - float y = menuTab.screenPos.y + menuTab.getHeight(); - boolean showAbove; - float maxVisibleHeight; - if (y < boundary.y + boundary.height / 2) { - showAbove = false; - maxVisibleHeight = boundary.y + boundary.height - y; //prevent covering prompt - } - else { //handle drop downs at near bottom of screen - showAbove = true; - y = menuTab.screenPos.y; - maxVisibleHeight = y - boundary.y; - } - - paneSize = updateAndGetPaneSize(boundary.width, maxVisibleHeight); - - //round width and height so borders appear properly - paneSize = new ScrollBounds(Math.round(paneSize.getWidth()), Math.round(paneSize.getHeight())); - if (x + paneSize.getWidth() > boundary.x + boundary.width) { - x = boundary.x + boundary.width - paneSize.getWidth(); - } - float height = Math.min(paneSize.getHeight(), maxVisibleHeight); - if (showAbove) { - //make drop down appear above - y -= height; - } - - setBounds(Math.round(x), Math.round(y), paneSize.getWidth(), height); - } - - @Override - protected final ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) { - return paneSize; - } - - @Override - protected void drawBackground(Graphics g) { - float w = getWidth(); - float h = getHeight(); - g.drawImage(FSkinTexture.BG_TEXTURE, 0, 0, w, h); - g.fillRect(FScreen.TEXTURE_OVERLAY_COLOR, 0, 0, w, h); - } - - protected boolean drawAboveOverlay() { - return true; //draw drop downs above screen overlay by default - } - - @Override - protected void drawOverlay(Graphics g) { - super.drawOverlay(g); - float w = getWidth(); - float h = getHeight(); - g.drawRect(2, BORDER_COLOR, 0, 0, w, h); //ensure border shows up on all sides - } - - protected FDisplayObject getDropDownOwner() { - return menuTab; - } - - protected boolean hideBackdropOnPress(float x, float y) { - FDisplayObject owner = getDropDownOwner(); - return owner == null || !owner.screenPos.contains(x, y); //auto-hide when backdrop pressed unless over owner - } - - protected boolean preventOwnerHandlingBackupTap(float x, float y, int count) { - //prevent owner handling this tap unless it's a sub menu and not over it - FDisplayObject owner = getDropDownOwner(); - if (owner instanceof FSubMenu) { - return owner.contains(owner.getLeft() + owner.screenToLocalX(x), owner.getTop() + owner.screenToLocalY(y)); - } - return true; - } - - private class Backdrop extends FDisplayObject { - private Backdrop() { - } - - @Override - public boolean press(float x, float y) { - if (hideBackdropOnPress(localToScreenX(x), y)) { - hide(); - } - return false; //allow press to pass through to object behind backdrop - } - - @Override - public boolean tap(float x, float y, int count) { - if (!isVisible()) { return false; } - hide(); //always hide if tapped - - return preventOwnerHandlingBackupTap(x, y, count); - } - - @Override - public boolean pan(float x, float y, float deltaX, float deltaY, boolean moreVertical) { - hide(); //always hide if backdrop panned - return false; //allow pan to pass through to object behind backdrop - } - - @Override - public boolean fling(float velocityX, float velocityY) { - hide(); //always hide if backdrop flung - return false; //allow fling to pass through to object behind backdrop - } - - @Override - public boolean zoom(float x, float y, float amount) { - hide(); //always hide if backdrop zoomed - return false; //allow zoom to pass through to object behind backdrop - } - - @Override - public void draw(Graphics g) { - //draw nothing for backdrop - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FDropDownMenu.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FDropDownMenu.java deleted file mode 100644 index e26da580829..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FDropDownMenu.java +++ /dev/null @@ -1,76 +0,0 @@ -package forge.adventure.libgdxgui.menu; - -import java.util.ArrayList; -import java.util.List; - -public abstract class FDropDownMenu extends FDropDown { - protected final List items = new ArrayList<>(); - - public FDropDownMenu() { - } - - @Override - protected boolean autoHide() { - return true; - } - - protected abstract void buildMenu(); - - @Override - protected ScrollBounds updateAndGetPaneSize(float maxWidth, float maxVisibleHeight) { - clear(); - items.clear(); - - buildMenu(); - - //ensure text is all aligned if some items have icons and others don't - boolean allowForIcon = false; - for (FMenuItem item : items) { - if (item.hasIcon()) { - allowForIcon = true; - break; - } - } - for (FMenuItem item : items) { - item.setAllowForIcon(allowForIcon); - } - - //determine needed width of menu - float width = determineMenuWidth(); - if (width > maxWidth) { - width = maxWidth; - } - - //set bounds for each item - float y = 0; - for (FMenuItem item : items) { - item.setBounds(0, y, width, FMenuItem.HEIGHT); - y += FMenuItem.HEIGHT; - } - - return new ScrollBounds(width, y); - } - - protected float determineMenuWidth() { - float width = 0; - for (FMenuItem item : items) { - float minWidth = item.getMinWidth(); - if (width < minWidth) { - width = minWidth; - } - } - return width; - } - - public void addItem(FMenuItem item) { - if (item.isVisible()) { - items.add(add(item)); - } - } - - @Override - public boolean tap(float x, float y, int count) { - super.tap(x, y, count); - return !(getDropDownOwner() instanceof FSubMenu); //return false so owning sub menu can be hidden - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FMagnifyView.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FMagnifyView.java deleted file mode 100644 index a4f72695e09..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FMagnifyView.java +++ /dev/null @@ -1,70 +0,0 @@ -package forge.adventure.libgdxgui.menu; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.TextRenderer; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.util.TextBounds; -import forge.adventure.libgdxgui.util.Utils; - -public class FMagnifyView extends FDropDown { - private static final float PADDING = Utils.scale(5); - - private FDisplayObject owner; - private String text; - private FSkinColor foreColor, backColor; - private FSkinFont font; - private TextRenderer renderer; - - public static void show(FDisplayObject owner0, String text0, FSkinColor foreColor0, FSkinColor backColor0, FSkinFont font0, boolean parseReminderText0) { - FMagnifyView view = new FMagnifyView(); - view.owner = owner0; - view.text = text0; - view.foreColor = foreColor0; - view.backColor = backColor0; - view.font = font0; - view.renderer = new TextRenderer(parseReminderText0); - view.show(); - } - private FMagnifyView() { - } - - @Override - protected void updateSizeAndPosition() { - float x = owner.screenPos.x; - float y = owner.screenPos.y + owner.getHeight(); - paneSize = updateAndGetPaneSize(owner.getWidth(), y); - float height = paneSize.getHeight(); - if (height > y) { - height = y; - } - y -= height; - - setBounds(Math.round(x), Math.round(y), Math.round(owner.getWidth()), Math.round(height)); - } - - @Override - protected boolean autoHide() { - return true; - } - - @Override - protected FDisplayObject getDropDownOwner() { - return owner; - } - - @Override - protected ScrollBounds updateAndGetPaneSize(float maxWidth, float maxVisibleHeight) { - TextBounds bounds = renderer.getWrappedBounds(text, font, maxWidth - 2 * PADDING); - return new ScrollBounds(maxWidth, bounds.height + 2 * PADDING); - } - - @Override - public void drawBackground(Graphics g) { - super.drawBackground(g); - g.fillRect(backColor, 0, 0, getWidth(), getHeight()); - renderer.drawText(g, text, font, foreColor, PADDING - getScrollLeft(), PADDING - getScrollTop(), getScrollWidth() - 2 * PADDING, getScrollHeight() - 2 * PADDING, 0, getHeight(), true, Align.left, false); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FMenuBar.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FMenuBar.java deleted file mode 100644 index 9274996a447..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FMenuBar.java +++ /dev/null @@ -1,62 +0,0 @@ -package forge.adventure.libgdxgui.menu; - -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.screens.FScreen.Header; - -import java.util.ArrayList; -import java.util.List; - -public class FMenuBar extends Header { - private final List tabs = new ArrayList<>(); - - public void addTab(String text0, FDropDown dropDown0) { - FMenuTab tab = new FMenuTab(text0, this, dropDown0, tabs.size()); - dropDown0.setMenuTab(tab); - tabs.add(add(tab)); - } - - public float getPreferredHeight() { - return Math.round(FMenuTab.FONT.getLineHeight() * 2f/*fixes touch for tall devices - old value 1.5f*/ + 2 * FMenuTab.PADDING); - } - - public int getTabCount() { - return tabs.size(); - } - - @Override - protected void doLayout(float width, float height) { - int visibleTabCount = 0; - float minWidth = 0; - for (FMenuTab tab : tabs) { - if (tab.isVisible()) { - minWidth += tab.getMinWidth(); - visibleTabCount++; - } - } - int tabWidth; - int x = 0; - float dx = (width - minWidth) / visibleTabCount; - for (FMenuTab tab : tabs) { - if (tab.isVisible()) { - tabWidth = Math.round(tab.getMinWidth() + dx); - if (x + tabWidth > width) { - tabWidth = Math.round(width - x); //prevent final tab extending off screen - } - tab.setBounds(x, 0, tabWidth, height); - x += tabWidth; - } - } - } - - @Override - protected void drawBackground(Graphics g) { - float w = getWidth(); - float h = getHeight(); - g.fillRect(BACK_COLOR, 0, 0, w, h); - } - - @Override - public float doLandscapeLayout(float screenWidth, float screenHeight) { - return 0; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FMenuItem.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FMenuItem.java deleted file mode 100644 index 1e54207eb9e..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FMenuItem.java +++ /dev/null @@ -1,176 +0,0 @@ -package forge.adventure.libgdxgui.menu; - -import com.badlogic.gdx.utils.Align; -import com.badlogic.gdx.utils.Timer; -import com.badlogic.gdx.utils.Timer.Task; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FImage; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.TextRenderer; -import forge.gui.UiCommand; -import forge.gui.interfaces.IButton; -import forge.localinstance.skin.FSkinProp; -import forge.adventure.libgdxgui.screens.FScreen.Header; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.toolbox.FEvent; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventType; -import forge.adventure.libgdxgui.util.Utils; - -public class FMenuItem extends FDisplayObject implements IButton { - public static final float HEIGHT = Utils.AVG_FINGER_HEIGHT * 0.8f; - protected static final float DIVOT_WIDTH = HEIGHT / 6; - protected static final float GAP_X = HEIGHT * 0.1f; - private static final float ICON_SIZE = ((int)((HEIGHT - 2 * GAP_X) / 20f)) * 20; //round down to nearest multiple of 20 - - private static final FSkinFont FONT = FSkinFont.get(12); - protected static final FSkinColor FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT); - private static final FSkinColor PRESSED_COLOR = FSkinColor.get(Colors.CLR_ACTIVE).alphaColor(0.9f); - private static final FSkinColor SEPARATOR_COLOR = FORE_COLOR.alphaColor(0.5f); - private static final FSkinColor TAB_SEPARATOR_COLOR = Header.BACK_COLOR.stepColor(-40); - - private final String text; - private final FImage icon; - private final FEventHandler handler; - private boolean pressed, allowForIcon, selected, tabMode; - private final float textWidth; - private TextRenderer textRenderer; - - public FMenuItem(String text0, FEventHandler handler0) { - this(text0, null, handler0, true); - } - public FMenuItem(String text0, FEventHandler handler0, boolean enabled0) { - this(text0, null, handler0, enabled0); - } - public FMenuItem(String text0, FImage icon0, FEventHandler handler0) { - this(text0, icon0, handler0, true); - } - public FMenuItem(String text0, FImage icon0, FEventHandler handler0, boolean enabled0) { - text = text0; - icon = icon0; - handler = handler0; - setEnabled(enabled0); - - textWidth = FONT.getBounds(text).width; - } - - public String getText() { - return text; - } - - public boolean hasIcon() { - return icon != null; - } - - public void setAllowForIcon(boolean allowForIcon0) { - allowForIcon = allowForIcon0; - } - - public void setTabMode(boolean tabMode0) { - tabMode = tabMode0; - } - - public void setTextRenderer(TextRenderer textRenderer0) { - textRenderer = textRenderer0; - } - - public float getMinWidth() { - //pretend there's a divot even if there isn't to provide extra right padding and allow menu items to line up nicer - float width = textWidth + DIVOT_WIDTH + 4 * GAP_X; - if (allowForIcon) { - width += ICON_SIZE + GAP_X; - } - return width; - } - - @Override - public boolean press(float x, float y) { - pressed = true; - return true; - } - - @Override - public boolean release(float x, float y) { - pressed = false; - return true; - } - - private final Task handleTapTask = new Task() { - @Override - public void run () { - handler.handleEvent(new FEvent(FMenuItem.this, FEventType.TAP)); - } - }; - - @Override - public boolean tap(float x, float y, int count) { - Timer.schedule(handleTapTask, 0.1f); //delay handling tap just long enough for menu to be hidden - return false; //return false so parent can use event to hide menu - } - - protected boolean showPressedColor() { - return (pressed && !tabMode) || selected; - } - - @Override - public void draw(Graphics g) { - float w = getWidth(); - float h = HEIGHT; - - if (showPressedColor()) { - g.fillRect(PRESSED_COLOR, 0, 0, w, h); - } - - float x = GAP_X; - - if (allowForIcon) { - if (icon != null) { - g.drawImage(icon, x, (h - ICON_SIZE) / 2, ICON_SIZE, ICON_SIZE); - } - //account for not having icon but having been given icon size for alignment with other items - x += ICON_SIZE + GAP_X; - } - - if (textRenderer == null) { - g.drawText(text, FONT, FORE_COLOR, x, 0, w - x - GAP_X, h, false, Align.left, true); - } - else { - textRenderer.drawText(g, text, FONT, FORE_COLOR, x, 0, w - x - GAP_X, h, 0, h, false, Align.left, true); - } - - //draw separator line - if (tabMode) { - g.drawLine(1, TAB_SEPARATOR_COLOR, 0, h, w, h); - } - else { - g.drawLine(1, SEPARATOR_COLOR, 0, h, w, h); - } - } - - @Override - public void setText(String text0) { - } - @Override - public boolean isSelected() { - return selected; - } - @Override - public void setSelected(boolean b0) { - selected = b0; - } - @Override - public boolean requestFocusInWindow() { - return false; - } - @Override - public void setCommand(UiCommand command0) { - } - @Override - public void setImage(FSkinProp color) { - } - @Override - public void setTextColor(int r, int g, int b) { - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FMenuTab.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FMenuTab.java deleted file mode 100644 index bc25f876d12..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FMenuTab.java +++ /dev/null @@ -1,103 +0,0 @@ -package forge.adventure.libgdxgui.menu; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.util.Utils; - -public class FMenuTab extends FDisplayObject { - public static final FSkinFont FONT = FSkinFont.get(12); - private static final FSkinColor SEL_BACK_COLOR = FSkinColor.get(Colors.CLR_ACTIVE); - private static final FSkinColor SEL_BORDER_COLOR = FDropDown.BORDER_COLOR; - private static final FSkinColor SEL_FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT); - private static final FSkinColor FORE_COLOR = SEL_FORE_COLOR.alphaColor(0.5f); - private static final FSkinColor SEPARATOR_COLOR = SEL_FORE_COLOR.alphaColor(0.3f); - public static final float PADDING = Utils.scale(2); - private static final float SEPARATOR_WIDTH = Utils.scale(1); - - private final FMenuBar menuBar; - private final FDropDown dropDown; - - private String text; - private float minWidth; - private final int index; - - public FMenuTab(String text0, FMenuBar menuBar0, FDropDown dropDown0, int index0) { - menuBar = menuBar0; - dropDown = dropDown0; - index = index0; - setText(text0); - } - - @Override - public boolean tap(float x, float y, int count) { - if (dropDown.isVisible()) { - dropDown.hide(); - } - else { - dropDown.show(); - } - return true; - } - - public void setText(String text0) { - text = text0; - minWidth = FONT.getBounds(text).width; - menuBar.revalidate(); - } - - @Override - public void setVisible(boolean visible0) { - if (isVisible() == visible0) { return; } - super.setVisible(visible0); - if (!visible0) { - dropDown.hide(); - } - if (menuBar != null) { - menuBar.revalidate(); - } - } - - public float getMinWidth() { - return minWidth; - } - - @Override - public void draw(Graphics g) { - float x, y, w, h; - - FSkinColor foreColor; - if (dropDown.isVisible()) { - x = PADDING; //round so lines show up reliably - y = PADDING; - w = getWidth() - 2 * x + 1; - h = getHeight() - y + 1; - - g.startClip(x, y, w, h); - g.fillRect(SEL_BACK_COLOR, x, y, w, h); - g.drawRect(2, SEL_BORDER_COLOR, x, y, w, h); - g.endClip(); - - foreColor = SEL_FORE_COLOR; - } - else { - foreColor = FORE_COLOR; - } - - //draw right separator - if (index < menuBar.getTabCount() - 1) { - x = getWidth(); - y = getHeight() / 4; - g.drawLine(SEPARATOR_WIDTH, SEPARATOR_COLOR, x, y, x, getHeight() - y); - } - - x = PADDING; - y = PADDING; - w = getWidth() - 2 * PADDING; - h = getHeight() - 2 * PADDING; - g.drawText(text, FONT, foreColor, x, y, w, h, false, Align.center, true); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FPopupMenu.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FPopupMenu.java deleted file mode 100644 index 719bf6d034c..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FPopupMenu.java +++ /dev/null @@ -1,111 +0,0 @@ -package forge.adventure.libgdxgui.menu; - -import com.badlogic.gdx.math.Vector2; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.toolbox.FButton; -import forge.adventure.libgdxgui.toolbox.FLabel; - -public abstract class FPopupMenu extends FDropDownMenu { - private FDisplayObject owner; - private float x, y; - private Vector2 pressPoint, fixedSize; - - public void show(FDisplayObject owner0, float x0, float y0) { - owner = owner0; - x = owner.localToScreenX(x0); - y = owner.localToScreenY(y0); - - if (owner instanceof FLabel || owner instanceof FButton) { - //if owner is FLabel or FButton, keep them pressed while menu open - owner.press(x0, y0); - pressPoint = new Vector2(x0, y0); - } - - show(); - } - - public void show(float screenX, float screenY, float fixedWidth, float fixedHeight) { - x = screenX; - y = screenY; - fixedSize = new Vector2(fixedWidth, fixedHeight); - setDropDownContainer(Forge.getCurrentScreen()); - - show(); - } - - @Override - protected FDisplayObject getDropDownOwner() { - return owner; - } - - @Override - protected void onHidden() { - if (pressPoint != null) { - //if owner kept pressed while open, release when menu hidden - owner.release(pressPoint.x, pressPoint.y); - pressPoint = null; - } - owner = null; - fixedSize = null; - } - - @Override - protected void updateSizeAndPosition() { - if (fixedSize != null) { - paneSize = updateAndGetPaneSize(fixedSize.x, fixedSize.y); - setBounds(x, y, fixedSize.x, fixedSize.y); - for (FMenuItem item : items) { - item.setTabMode(true); //ensure items in fixed size menu are treated as tabs - } - return; - } - - FScreen screen = Forge.getCurrentScreen(); - float screenWidth = screen.getWidth(); - float screenHeight = screen.getHeight(); - - paneSize = updateAndGetPaneSize(screenWidth, screenHeight); - - //round width and height so borders appear properly - paneSize = new ScrollBounds(Math.round(paneSize.getWidth()), Math.round(paneSize.getHeight())); - - if (x + paneSize.getWidth() > screenWidth) { - x = screenWidth - paneSize.getWidth(); - } - if (y + paneSize.getHeight() > screenHeight) { - y = screenHeight - paneSize.getHeight(); - } - - setBounds(Math.round(x), Math.round(y), paneSize.getWidth(), paneSize.getHeight()); - } - - @Override - protected float determineMenuWidth() { - if (fixedSize != null) { - return fixedSize.x; - } - return super.determineMenuWidth(); - } - - @Override - protected boolean autoHide() { - return fixedSize == null; //don't auto-hide if menu has fixed size - } - - @Override - protected void drawBackground(Graphics g) { - if (fixedSize == null) { //avoid showing background if menu has fixed size - super.drawBackground(g); - } - } - - @Override - protected void drawOverlay(Graphics g) { - if (fixedSize == null) { //avoid showing overlay if menu has fixed size - super.drawOverlay(g); - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FSubMenu.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FSubMenu.java deleted file mode 100644 index cd205d9e94a..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FSubMenu.java +++ /dev/null @@ -1,53 +0,0 @@ -package forge.adventure.libgdxgui.menu; - -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FImage; - -public class FSubMenu extends FMenuItem { - FPopupMenu popupMenu; - - public FSubMenu(String text0, FPopupMenu popupMenu0) { - this(text0, null, popupMenu0, true); - } - public FSubMenu(String text0, FPopupMenu popupMenu0, boolean enabled0) { - this(text0, null, popupMenu0, enabled0); - } - public FSubMenu(String text0, FImage icon0, final FPopupMenu popupMenu0) { - this(text0, icon0, popupMenu0, true); - } - public FSubMenu(String text0, FImage icon0, final FPopupMenu popupMenu0, boolean enabled0) { - super(text0, icon0, null, enabled0); - popupMenu = popupMenu0; - } - - @Override - protected boolean showPressedColor() { - return super.showPressedColor() || popupMenu.isVisible(); - } - - @Override - public boolean tap(float x, float y, int count) { - if (popupMenu.isVisible()) { - popupMenu.hide(); - } - else { - popupMenu.show(this, getWidth(), 0); - } - return true; - } - - @Override - public void draw(Graphics g) { - super.draw(g); - - float divotWidth = DIVOT_WIDTH; - float divotHeight = divotWidth * 2f; - float x2 = getWidth() - GAP_X - 1; - float x1 = x2 - divotWidth; - float x3 = x1; - float y2 = getHeight() / 2; - float y1 = y2 - divotHeight / 2; - float y3 = y2 + divotHeight / 2; - g.fillTriangle(FORE_COLOR, x1, y1, x2, y2, x3, y3); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FTooltip.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FTooltip.java deleted file mode 100644 index 5bfa1ea0036..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/menu/FTooltip.java +++ /dev/null @@ -1,72 +0,0 @@ -package forge.adventure.libgdxgui.menu; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.util.TextBounds; -import forge.adventure.libgdxgui.util.Utils; - -public class FTooltip extends FDropDown { - private static final FSkinFont FONT = FSkinFont.get(12); - private static final FSkinColor FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT); - private static final float PADDING = Utils.scale(5); - - private FDisplayObject owner; - private float x, y; - private final String text; - - public void show(FDisplayObject owner0, float x0, float y0) { - owner = owner0; - x = owner.localToScreenX(x0); - y = owner.localToScreenY(y0); - show(); - } - - @Override - protected void updateSizeAndPosition() { - FScreen screen = Forge.getCurrentScreen(); - float screenWidth = screen.getWidth(); - float screenHeight = screen.getHeight(); - - paneSize = updateAndGetPaneSize(screenWidth, screenHeight); - if (x + paneSize.getWidth() > screenWidth) { - x = screenWidth - paneSize.getWidth(); - } - if (y + paneSize.getHeight() > screenHeight) { - y = screenHeight - paneSize.getHeight(); - } - - setBounds(Math.round(x), Math.round(y), Math.round(paneSize.getWidth()), Math.round(paneSize.getHeight())); - } - - public FTooltip(String text0) { - text = text0; - } - - @Override - protected boolean autoHide() { - return true; - } - - @Override - protected FDisplayObject getDropDownOwner() { - return owner; - } - - @Override - protected ScrollBounds updateAndGetPaneSize(float maxWidth, float maxVisibleHeight) { - TextBounds bounds = FONT.getWrappedBounds(text, maxWidth - 2 * PADDING); - return new ScrollBounds(Math.min(maxWidth, bounds.width + 2 * PADDING), bounds.height + 2 * PADDING); - } - - @Override - public void drawBackground(Graphics g) { - super.drawBackground(g); - g.drawText(text, FONT, FORE_COLOR, PADDING - getScrollLeft(), PADDING - getScrollTop(), getScrollWidth() - 2 * PADDING, getScrollHeight() - 2 * PADDING, true, Align.left, false); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/FScreen.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/FScreen.java deleted file mode 100644 index ac6e0704cbe..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/FScreen.java +++ /dev/null @@ -1,397 +0,0 @@ -package forge.adventure.libgdxgui.screens; - -import com.badlogic.gdx.Input.Keys; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FImage; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.FSkinTexture; -import forge.adventure.libgdxgui.menu.FPopupMenu; -import forge.adventure.libgdxgui.screens.settings.SettingsScreen; -import forge.adventure.libgdxgui.toolbox.FContainer; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.toolbox.FEvent; -import forge.adventure.libgdxgui.toolbox.FLabel; -import forge.adventure.libgdxgui.util.Utils; -import forge.gui.GuiBase; -import forge.util.Callback; - -import java.util.List; - -public abstract class FScreen extends forge.adventure.libgdxgui.toolbox.FContainer { - public static final FSkinColor TEXTURE_OVERLAY_COLOR = FSkinColor.get(FSkinColor.Colors.CLR_THEME); - - private final Header header; - - protected FScreen(String headerCaption) { - this(headerCaption == null ? null : new DefaultHeader(headerCaption)); - } - protected FScreen(String headerCaption, FPopupMenu menu) { - this(new MenuHeader(headerCaption, menu)); - } - protected FScreen(Header header0) { - header = header0; - if (header != null) { - add(header); - } - } - - public Header getHeader() { - return header; - } - - public void setHeaderCaption(String headerCaption) { - if (header instanceof DefaultHeader) { - ((DefaultHeader)header).lblCaption.setText(headerCaption); - } - } - - public Rectangle getDropDownBoundary() { - return new Rectangle(0, 0, getWidth(), getHeight()); - } - - public void onActivate() { - } - - public void onSwitchAway(Callback canSwitchCallback) { - canSwitchCallback.run(true); - } - - public void onClose(Callback canCloseCallback) { - if (canCloseCallback != null) { //will be null if app exited - canCloseCallback.run(true); - } - } - - public void showMenu() { - if (header instanceof MenuHeader) { - ((MenuHeader)header).btnMenu.trigger(); - } - else { //just so settings screen if no menu header - SettingsScreen.show(false); - } - } - - @Override - protected final void doLayout(float width, float height) { - if ((GuiBase.isAndroid() && Forge.isLandscapeMode())||(width > height)) { - doLandscapeLayout(width, height); //handle landscape layout special - } else if (header != null) { - header.setBounds(0, 0, width, header.getPreferredHeight()); - doLayout(header.getHeight(), width, height); - } else { - doLayout(0, width, height); - } - } - - protected abstract void doLayout(float startY, float width, float height); - - //do layout for landscape mode and return width for any screen hosted on top of this screen - protected float doLandscapeLayout(float width, float height) { - //just use normal doLayout function by default after making room for header menu - float startY = 0; - if (header != null) { - float headerWidth = header.doLandscapeLayout(width, height); - if (headerWidth == 0) { //if header doesn't support landscape layout, make room for it at top - header.setBounds(0, 0, width, header.getPreferredHeight()); - startY += header.getHeight(); - } - else { //otherwise make room for it on right - width -= headerWidth; - } - } - doLayout(startY, width, height); - return width; - } - - //get screen to serve as the backdrop for this screen when in landscape mode - public FScreen getLandscapeBackdropScreen() { - return null; //use home screen as backdrop when in landscape mode by default - } - - @Override - public void setSize(float width, float height) { - if (Forge.isLandscapeMode()) { - //adjust size if in landscape mode and has a backdrop - FScreen backdrop = getLandscapeBackdropScreen(); - if (backdrop != null) { - width = backdrop.doLandscapeLayout(width, height); - } - } - if (getWidth() == width && getHeight() == height) { - if (header != null) { - header.onScreenActivate(); //let header handle when screen activated - } - return; - } - super.setSize(width, height); - } - - @Override - public void buildTouchListeners(float screenX, float screenY, List listeners) { - if (Forge.isLandscapeMode()) { - //allow touch events on backdrop screen if any - FScreen backdrop = getLandscapeBackdropScreen(); - if (backdrop != null) { - backdrop.buildTouchListeners(screenX, screenY, listeners); - } - } - super.buildTouchListeners(screenX, screenY, listeners); - } - - @Override - public void draw(Graphics g) { - if (Forge.isLandscapeMode() && getLeft() == 0) { //check that left is 0 to avoid infinite loop - //draw landscape backdrop first if needed - FScreen backdrop = getLandscapeBackdropScreen(); - if (backdrop != null) { - g.draw(backdrop); - //temporarily shift into position for drawing in front of backdrop - setLeft(Forge.getScreenWidth() - getWidth()); - g.draw(this); - setLeft(0); - return; - } - } - super.draw(g); - } - - @Override - protected void drawBackground(Graphics g) { - if (Forge.isLandscapeMode() && getLandscapeBackdropScreen() != null) { - return; //don't draw background if this screen has a backdrop - } - float w = getWidth(); - float h = getHeight(); - g.drawImage(FSkinTexture.BG_TEXTURE, 0, 0, w, h); - g.fillRect(TEXTURE_OVERLAY_COLOR, 0, 0, w, h); - } - - public static abstract class Header extends FContainer { - public static final FSkinColor BTN_PRESSED_COLOR = TEXTURE_OVERLAY_COLOR.alphaColor(1f); - public static final FSkinColor LINE_COLOR = BTN_PRESSED_COLOR.stepColor(-40); - public static final FSkinColor BACK_COLOR = BTN_PRESSED_COLOR.stepColor(-80); - public static final float LINE_THICKNESS = Utils.scale(1); - - public abstract float getPreferredHeight(); - - //handle when screen activated - protected void onScreenActivate() { - } - - //do layout for landscape mode and return needed width - public abstract float doLandscapeLayout(float screenWidth, float screenHeight); - } - private static class DefaultHeader extends Header { - protected static final float HEIGHT = Math.round(Utils.AVG_FINGER_HEIGHT * 0.8f); - protected static final FSkinFont FONT = FSkinFont.get(16); - - protected final FLabel btnBack, lblCaption; - - public DefaultHeader(String headerCaption) { - btnBack = add(new FLabel.Builder().icon(new BackIcon(HEIGHT, HEIGHT)).pressedColor(BTN_PRESSED_COLOR).align(Align.center).command(new FEvent.FEventHandler() { - @Override - public void handleEvent(FEvent e) { - Forge.back(); - } - }).build()); - lblCaption = add(new FLabel.Builder().text(headerCaption).font(FONT).align(Align.center).build()); - } - - @Override - public float getPreferredHeight() { - return HEIGHT; - } - - @Override - public float doLandscapeLayout(float screenWidth, float screenHeight) { - return 0; //default header doesn't need to display for landscape mode - } - - @Override - public void drawBackground(Graphics g) { - g.fillRect(BACK_COLOR, 0, 0, getWidth(), getHeight()); - } - - @Override - public void drawOverlay(Graphics g) { - if (Forge.isLandscapeMode() && getWidth() < Forge.getCurrentScreen().getWidth()) { - //in landscape mode, draw left border for sidebar if needed - g.drawLine(LINE_THICKNESS, LINE_COLOR, 0, 0, 0, getHeight()); - return; - } - float y = HEIGHT - LINE_THICKNESS / 2; - g.drawLine(LINE_THICKNESS, LINE_COLOR, 0, y, getWidth(), y); - } - - @Override - protected void doLayout(float width, float height) { - btnBack.setBounds(0, 0, height, height); - lblCaption.setBounds(height, 0, width - 2 * height, height); - } - } - protected static class MenuHeader extends DefaultHeader { - private final FLabel btnMenu; - private final FPopupMenu menu; - - public MenuHeader(String headerCaption, FPopupMenu menu0) { - super(headerCaption); - menu = menu0; - btnMenu = add(new FLabel.Builder().icon(new MenuIcon(HEIGHT, HEIGHT)).pressedColor(BTN_PRESSED_COLOR).align(Align.center).command(new FEvent.FEventHandler() { - @Override - public void handleEvent(FEvent e) { - menu.show(btnMenu, 0, HEIGHT); - } - }).build()); - } - - @Override - public void drawOverlay(Graphics g) { - if (Forge.isLandscapeMode() && displaySidebarForLandscapeMode()) { - //in landscape mode, draw left border for header - g.drawLine(LINE_THICKNESS, LINE_COLOR, 0, 0, 0, getHeight()); - return; - } - super.drawOverlay(g); - } - - @Override - protected void doLayout(float width, float height) { - super.doLayout(width, height); - - menu.hide(); //ensure menu hidden when screen resized - - if (Forge.isLandscapeMode() && displaySidebarForLandscapeMode()) { - //for landscape mode, hide menu button and display menu as sidebar - btnBack.setBounds(0, 0, 0, 0); - lblCaption.setBounds(0, 0, 0, 0); - btnMenu.setBounds(0, 0, 0, 0); - menu.show(getLeft(), 0, width, height); - return; - } - - btnMenu.setBounds(width - height, 0, height, height); - } - - @Override - protected void onScreenActivate() { - //ensure menu layout refreshed for sidebar when screen activated - if (Forge.isLandscapeMode() && displaySidebarForLandscapeMode()) { - menu.hide(); - menu.show(getLeft(), 0, getWidth(), getHeight()); - } - } - - protected boolean displaySidebarForLandscapeMode() { - return true; - } - - @Override - public float doLandscapeLayout(float screenWidth, float screenHeight) { - if (displaySidebarForLandscapeMode()) { - float width = screenHeight * 0.8f; - setBounds(screenWidth - width, 0, width, screenHeight); - return width; - } - return 0; - } - } - - protected static class BackIcon implements FImage { - private static final float THICKNESS = Utils.scale(3); - private static final FSkinColor COLOR = FSkinColor.get(FSkinColor.Colors.CLR_TEXT); - - private final float width, height; - public BackIcon(float width0, float height0) { - width = width0; - height = height0; - } - - @Override - public float getWidth() { - return width; - } - - @Override - public float getHeight() { - return height; - } - - @Override - public void draw(Graphics g, float x, float y, float w, float h) { - float xMid = x + w * 0.4f; - float yMid = y + h / 2; - float offsetX = h / 8; - float offsetY = w / 4; - - g.drawLine(THICKNESS, COLOR, xMid + offsetX, yMid - offsetY, xMid - offsetX, yMid + 1); - g.drawLine(THICKNESS, COLOR, xMid - offsetX, yMid - 1, xMid + offsetX, yMid + offsetY); - } - } - - protected static class MenuIcon implements FImage { - private static final FSkinColor COLOR = FSkinColor.get(FSkinColor.Colors.CLR_TEXT); - - private final float width, height; - public MenuIcon(float width0, float height0) { - width = width0; - height = height0; - } - - @Override - public float getWidth() { - return width; - } - - @Override - public float getHeight() { - return height; - } - - @Override - public void draw(Graphics g, float x, float y, float w, float h) { - float thickness = Math.round(h / 5); - float delta = Math.round(thickness * 1.75f); - y += (h - 2 * delta - thickness) / 2; - - g.fillRect(COLOR, x, y, thickness, thickness); - y += delta; - g.fillRect(COLOR, x, y, thickness, thickness); - y += delta; - g.fillRect(COLOR, x, y, thickness, thickness); - x += delta; - y -= 2 * delta; - w -= delta; - g.fillRect(COLOR, x, y, w, thickness); - y += delta; - g.fillRect(COLOR, x, y, w, thickness); - y += delta; - g.fillRect(COLOR, x, y, w, thickness); - } - } - - protected boolean allowBackInLandscapeMode() { - return false; //don't allow going back if home screen is backdrop by default - } - - @Override - public boolean keyDown(int keyCode) { - if (keyCode == Keys.ESCAPE || keyCode == Keys.BACK) { - if (Forge.endKeyInput()) { return true; } - - if (Forge.isLandscapeMode() && !allowBackInLandscapeMode()) { - Forge.exit(false); //prompt to exit if attempting to go back from screen that doesn't allow back in landscape mode - return true; - } - Forge.back(); //go back on escape by default - return true; - } - if (keyCode == Keys.F5) { //allow revalidating current screen when running desktop app - revalidate(); - } - return super.keyDown(keyCode); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/LaunchScreen.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/LaunchScreen.java deleted file mode 100644 index 50fab8b85f9..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/LaunchScreen.java +++ /dev/null @@ -1,103 +0,0 @@ -package forge.adventure.libgdxgui.screens; - -import com.badlogic.gdx.Input.Keys; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinImage; -import forge.adventure.libgdxgui.menu.FPopupMenu; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.toolbox.FOptionPane; -import forge.adventure.libgdxgui.util.Utils; - -public abstract class LaunchScreen extends FScreen { - private static final float MAX_START_BUTTON_HEIGHT = 1.75f * Utils.AVG_FINGER_HEIGHT; - private float START_BUTTON_RATIO = 0.f; - private static final float PADDING = FOptionPane.PADDING; - - protected final StartButton btnStart = add(new StartButton()); - - public LaunchScreen(String headerCaption) { - super(headerCaption); - } - public LaunchScreen(String headerCaption, FPopupMenu menu) { - super(headerCaption, menu); - } - - @Override - protected final void doLayout(float startY, float width, float height) { - if (Forge.hdstart) - START_BUTTON_RATIO = FSkinImage.HDBTN_START_UP.getWidth() / FSkinImage.HDBTN_START_UP.getHeight(); - else - START_BUTTON_RATIO = FSkinImage.BTN_START_UP.getWidth() / FSkinImage.BTN_START_UP.getHeight(); - - float buttonWidth = width - 2 * PADDING; - float buttonHeight = buttonWidth / START_BUTTON_RATIO; - if (buttonHeight > MAX_START_BUTTON_HEIGHT) { - buttonHeight = MAX_START_BUTTON_HEIGHT; - buttonWidth = buttonHeight * START_BUTTON_RATIO; - } - btnStart.setBounds((width - buttonWidth) / 2, height - buttonHeight - PADDING, buttonWidth, buttonHeight); - - doLayoutAboveBtnStart(startY, width, height - buttonHeight - 2 * PADDING); - } - - protected abstract void doLayoutAboveBtnStart(float startY, float width, float height); - protected abstract void startMatch(); - - protected class StartButton extends FDisplayObject { - private boolean pressed; - - /** - * Instantiates a new FButton. - */ - public StartButton() { - } - - @Override - public final boolean press(float x, float y) { - pressed = true; - return true; - } - - @Override - public final boolean release(float x, float y) { - pressed = false; - return true; - } - - @Override - public final boolean tap(float x, float y, int count) { - if (count == 1) { - btnStart.setEnabled(false); - startMatch(); - } - return true; - } - - @Override - public void draw(Graphics g) { - if (Forge.hdstart) - g.drawImage(pressed ? FSkinImage.HDBTN_START_DOWN : FSkinImage.HDBTN_START_UP, - 0, 0, getWidth(), getHeight()); - else - g.drawImage(pressed ? FSkinImage.BTN_START_DOWN : FSkinImage.BTN_START_UP, - 0, 0, getWidth(), getHeight()); - //its must be enabled or you can't start any game modes - if (!Forge.isLoadingaMatch()) { - if(!btnStart.isEnabled()) - btnStart.setEnabled(true); - } - } - } - - @Override - public boolean keyDown(int keyCode) { - switch (keyCode) { - case Keys.ENTER: - case Keys.SPACE: - startMatch(); //start match on Enter or Space - return true; - } - return super.keyDown(keyCode); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/LoadingOverlay.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/LoadingOverlay.java deleted file mode 100644 index 0a5af67000c..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/LoadingOverlay.java +++ /dev/null @@ -1,110 +0,0 @@ -package forge.adventure.libgdxgui.screens; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkin; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.FSkinImage; -import forge.adventure.libgdxgui.toolbox.FOverlay; -import forge.adventure.libgdxgui.util.Utils; -import forge.gui.FThreads; -import forge.util.ThreadUtil; - -public class LoadingOverlay extends FOverlay { - private static final float INSETS = Utils.scale(10); - private static final float LOGO_SIZE_FACTOR = 0.7f; - private static final float INSETS_FACTOR = 0.025f; - private static final FSkinFont FONT = FSkinFont.get(22); - private static final FSkinColor BACK_COLOR = FSkinColor.get(FSkinColor.Colors.CLR_ACTIVE).alphaColor(0.75f); - private static final FSkinColor FORE_COLOR = FSkinColor.get(FSkinColor.Colors.CLR_TEXT); - - public static void show(String caption0, final Runnable runnable) { - final LoadingOverlay loader = new LoadingOverlay(caption0); - loader.show(); //show loading overlay then delay running remaining logic so UI can respond - ThreadUtil.invokeInGameThread(new Runnable() { - @Override - public void run() { - FThreads.invokeInEdtLater(new Runnable() { - @Override - public void run() { - runnable.run(); - loader.hide(); - loader.finishedloading(); //setLoadingaMatch to false - } - }); - } - }); - } - - public static void runBackgroundTask(String caption0, final Runnable task) { - final LoadingOverlay loader = new LoadingOverlay(caption0); - loader.show(); - FThreads.invokeInBackgroundThread(new Runnable() { - @Override - public void run() { - task.run(); - FThreads.invokeInEdtLater(new Runnable() { - @Override - public void run() { - loader.hide(); - } - }); - } - }); - } - - private String caption; - - public LoadingOverlay(String caption0) { - caption = caption0; - } - - public void setCaption(String caption0) { - caption = caption0; - } - - @Override - public boolean isVisibleOnScreen(FScreen screen) { - return true; //allow LoadingOverlay to remain visible while transitioning between screens - } - - @Override - protected void doLayout(float width, float height) { - } - - @Override - public void drawOverlay(Graphics g) { - float x = INSETS; - float panelWidth = getWidth() - 2 * INSETS; - - if (Forge.isLandscapeMode()) { - panelWidth = getHeight() - 2 * INSETS; - x = (getWidth() - panelWidth) / 2; - } - - float padding = panelWidth * INSETS_FACTOR; - float logoSize = panelWidth * LOGO_SIZE_FACTOR; - float fontHeight = FONT.getCapHeight(); - float panelHeight = logoSize + fontHeight + 4 * padding; - - float y = (getHeight() - panelHeight) / 2; - float oldAlpha = g.getfloatAlphaComposite(); - //dark translucent back.. - g.setAlphaComposite(0.6f); - g.fillRect(Color.BLACK, 0, 0, getWidth(), getHeight()); - g.setAlphaComposite(oldAlpha); - //overlay - g.fillRect(BACK_COLOR, x, y, panelWidth, panelHeight); - g.drawRect(Utils.scale(2), FORE_COLOR, x, y, panelWidth, panelHeight); - y += padding; - if (FSkin.hdLogo == null) - g.drawImage(FSkinImage.LOGO, (getWidth() - logoSize) / 2f, y, logoSize, logoSize); - else - g.drawImage(FSkin.hdLogo, (getWidth() - logoSize) / 2f, y, logoSize, logoSize); - y += logoSize + padding; - g.drawText(caption, FONT, FORE_COLOR, x, y, panelWidth, getHeight(), false, Align.center, false); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/SplashScreen.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/SplashScreen.java deleted file mode 100644 index e104f264fcf..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/SplashScreen.java +++ /dev/null @@ -1,107 +0,0 @@ -package forge.adventure.libgdxgui.screens; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.FSkinTexture; -import forge.adventure.libgdxgui.toolbox.FContainer; -import forge.adventure.libgdxgui.toolbox.FProgressBar; - -public class SplashScreen extends FContainer { - private TextureRegion background; - private final FProgressBar progressBar; - private FSkinFont disclaimerFont; - private boolean preparedForDialogs; - - public SplashScreen() { - progressBar = new FProgressBar(); - progressBar.setDescription("Welcome to Forge"); - } - - public FProgressBar getProgressBar() { - return progressBar; - } - - public void setBackground(TextureRegion background0) { - background = background0; - } - - @Override - protected void doLayout(float width, float height) { - } - - //prepare for showing dialogs on top of splash screen if needed - public void prepareForDialogs() { - if (preparedForDialogs) { return; } - - //establish fallback colors for before actual colors are loaded - Color defaultColor = new Color(0, 0, 0, 0); - for (final FSkinColor.Colors c : FSkinColor.Colors.values()) { - switch (c) { - case CLR_BORDERS: - case CLR_TEXT: - c.setColor(FProgressBar.SEL_FORE_COLOR); - break; - case CLR_ACTIVE: - case CLR_THEME2: - c.setColor(FProgressBar.SEL_BACK_COLOR); - break; - case CLR_INACTIVE: - c.setColor(FSkinColor.stepColor(FProgressBar.SEL_BACK_COLOR, -80)); - break; - default: - c.setColor(defaultColor); - break; - } - } - FSkinColor.updateAll(); - preparedForDialogs = true; - } - - @Override - protected void drawBackground(Graphics g) { - if (background == null) { return; } - - g.drawImage(FSkinTexture.BG_TEXTURE, 0, 0, getWidth(), getHeight()); - - float x, y, w, h; - float backgroundRatio = background.getRegionWidth() / background.getRegionHeight(); - float screenRatio = getWidth() / getHeight(); - if (backgroundRatio > screenRatio) { - x = 0; - w = getWidth(); - h = getWidth() * backgroundRatio; - y = (getHeight() - h) / 2; - } - else { - y = 0; - h = getHeight(); - w = getHeight() / backgroundRatio; - x = (getWidth() - w) / 2; - } - g.drawImage(background, x, y, w, h); - - y += h * 295f / 450f; - if (disclaimerFont == null) { - disclaimerFont = FSkinFont.get(9); - } - float disclaimerHeight = 30f / 450f * h; - String disclaimer = "Forge is not affiliated in any way with Wizards of the Coast.\n" - + "Forge is open source software, released under the GNU General Public License."; - g.drawText(disclaimer, disclaimerFont, FProgressBar.SEL_FORE_COLOR, - x, y, w, disclaimerHeight, true, Align.center, true); - - float padding = 20f / 450f * w; - float pbHeight = 57f / 450f * h; - y += 78f / 450f * h; - progressBar.setBounds(x + padding, y, w - 2 * padding, pbHeight); - g.draw(progressBar); - - String version = "v. " + Forge.CURRENT_VERSION + " (Alpha)"; - g.drawText(version, disclaimerFont, FProgressBar.SEL_FORE_COLOR, x, getHeight() - disclaimerHeight, w, disclaimerHeight, false, Align.center, true); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/TabPageScreen.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/TabPageScreen.java deleted file mode 100644 index 417198b5459..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/TabPageScreen.java +++ /dev/null @@ -1,425 +0,0 @@ -package forge.adventure.libgdxgui.screens; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.AdventureApplicationAdapter; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FImage; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.menu.FPopupMenu; -import forge.adventure.libgdxgui.toolbox.*; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.util.Utils; -import forge.localinstance.properties.ForgePreferences.FPref; -import forge.model.FModel; - -public class TabPageScreen> extends FScreen { - public static boolean COMPACT_TABS = FModel.getPreferences().getPrefBoolean(FPref.UI_COMPACT_TABS); - - protected final TabHeader tabHeader; - protected final TabPage[] tabPages; - private TabPage selectedPage; - - @SuppressWarnings("unchecked") - public TabPageScreen(TabPage... tabPages0) { - this(tabPages0, true); - } - - public TabPageScreen(TabPage[] tabPages0, boolean showBackButton) { - this(new TabHeader<>(tabPages0, showBackButton)); - } - - public TabPageScreen(TabHeader tabHeader0) { - super(tabHeader0); - tabHeader = tabHeader0; - tabPages = tabHeader.tabPages; - initialize(); - } - - public TabPageScreen(String headerCaption, FPopupMenu menu, TabPage[] tabPages0) { - super(headerCaption, menu); - tabHeader = add(new TabHeader<>(tabPages0, false)); - tabHeader.showBottomBorder = false; - tabPages = tabHeader.tabPages; - initialize(); - } - - public TabPageScreen(String headerCaption, FPopupMenu menu, TabPage[] tabPages0, boolean alwaysRenderHorizontal) { - super(headerCaption, menu); - tabHeader = add(new TabHeader<>(tabPages0, false)); - tabHeader.showBottomBorder = false; - tabHeader.alwaysRenderHorizontal = alwaysRenderHorizontal; - tabPages = tabHeader.tabPages; - initialize(); - } - - @SuppressWarnings("unchecked") - private void initialize() { - int index = 0; - for (TabPage tabPage : tabPages) { - tabPage.index = index++; - tabPage.parentScreen = (T)this; - add(tabPage); - tabPage.setVisible(false); - } - setSelectedPage(tabPages[0]); - } - - public TabPage getSelectedPage() { - return selectedPage; - } - public void setSelectedPage(TabPage tabPage0) { - if (selectedPage == tabPage0) { return; } - - if (selectedPage != null) { - selectedPage.setVisible(false); - } - selectedPage = tabPage0; - if (selectedPage != null) { - selectedPage.setVisible(true); - if (canActivateTabPage()) { - scrollSelectedTabIntoView(); - selectedPage.onActivate(); - } - } - } - - protected boolean canActivateTabPage() { - return Forge.getCurrentScreen() == this; - } - - protected boolean showCompactTabs() { - return COMPACT_TABS || getHeader() != tabHeader; //always show compact tabs if not in primary header - } - - @Override - public void onActivate() { - if (selectedPage != null) { - scrollSelectedTabIntoView(); //ensure selected tab in view when screen activated - selectedPage.onActivate(); - } - } - - private void scrollSelectedTabIntoView() { - if (tabHeader.isScrollable) { //scroll tab into view if needed, leaving half of the previous/next tab visible if possible - tabHeader.scroller.scrollIntoView(selectedPage.tab, selectedPage.tab.getWidth() / 2); - } - } - - @Override - protected void doLayout(float startY, float width, float height) { - if (getHeader() != tabHeader) { //show tabs at bottom if not in main header - float tabHeight = tabHeader.getPreferredHeight(); - tabHeader.setBounds(0, height - tabHeight, width, tabHeight); - height -= tabHeight; - } - height -= startY; - for (TabPage tabPage : tabPages) { - tabPage.setBounds(0, startY, width, height); - } - } - - protected static class TabHeader> extends Header { - private static final float HEIGHT = Math.round(Utils.AVG_FINGER_HEIGHT * 1.4f); - private static final float COMPACT_HEIGHT = Math.round(Utils.AVG_FINGER_HEIGHT * 0.8f); - private static final float BACK_BUTTON_WIDTH = Math.round(HEIGHT / 2); - private static final FSkinColor SEPARATOR_COLOR = BACK_COLOR.stepColor(-40); - - private final TabPage[] tabPages; - private final FLabel btnBack; - private boolean isScrollable; - private FDisplayObject finalVisibleTab; - private boolean showBottomBorder = true; - private boolean alwaysRenderHorizontal = false; - - private final FScrollPane scroller = add(new FScrollPane() { - @Override - protected ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) { - int tabCount = 0; - for (FDisplayObject child : getChildren()) { - if (child.isVisible()) { - tabCount++; - finalVisibleTab = child; - } - } - - if (Forge.isLandscapeMode() && !alwaysRenderHorizontal) { - //render vertically in Landscape mode - float y = 0; - for (FDisplayObject child : getChildren()) { - if (child.isVisible()) { - child.setBounds(0, y, visibleWidth, HEIGHT); - y += HEIGHT; - } - } - return new ScrollBounds(visibleWidth, y); - } - - float x = 0; - float tabWidth; - isScrollable = (tabCount > 3); //support up to 3 tabs without scrolling - if (isScrollable) { - tabWidth = visibleWidth / 2.5f; //support half of the third tab to make scrolling more obvious - } - else { - tabWidth = visibleWidth / tabCount; - } - for (FDisplayObject child : getChildren()) { - if (child.isVisible()) { - child.setBounds(x, 0, tabWidth, visibleHeight); - x += tabWidth; - } - } - return new ScrollBounds(isScrollable ? x : visibleWidth, visibleHeight); - } - }); - - public TabHeader(TabPage[] tabPages0, boolean showBackButton) { - tabPages = tabPages0; - if (showBackButton) { - btnBack = add(new FLabel.Builder().icon(new BackIcon(BACK_BUTTON_WIDTH, BACK_BUTTON_WIDTH)).pressedColor(BTN_PRESSED_COLOR).align(Align.center).command(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - AdventureApplicationAdapter.instance.switchToLast(); - } - }).build()); - } - else { - btnBack = null; - } - - for (TabPage tabPage : tabPages) { - scroller.add(tabPage.tab); - } - } - - protected boolean showBackButtonInLandscapeMode() { - return btnBack != null; - } - - @Override - public float getPreferredHeight() { - return tabPages[0].parentScreen.showCompactTabs() ? COMPACT_HEIGHT : HEIGHT; - } - - @Override - public void drawBackground(Graphics g) { - g.fillRect(BACK_COLOR, 0, 0, getWidth(), getHeight()); - } - - @Override - public void drawOverlay(Graphics g) { - if (Forge.isLandscapeMode()) { - //in landscape mode, draw left border for header - g.drawLine(LINE_THICKNESS, LINE_COLOR, 0, 0, 0, getHeight()); - if (showBackButtonInLandscapeMode()) { //draw top border for back button - float y = btnBack.getTop() - LINE_THICKNESS / 2; - g.drawLine(LINE_THICKNESS, SEPARATOR_COLOR, 0, y, getWidth(), y); - } - return; - } - - //draw right border for back button - if (btnBack != null) { - float x = btnBack.getWidth() - LINE_THICKNESS / 2; - g.drawLine(LINE_THICKNESS, SEPARATOR_COLOR, x, 0, x, getHeight()); - } - - //draw bottom border for header - if (showBottomBorder) { - float y = getHeight() - LINE_THICKNESS / 2; - g.drawLine(LINE_THICKNESS, LINE_COLOR, 0, y, getWidth(), y); - } - } - - @Override - protected void doLayout(float width, float height) { - float x = 0; - if (btnBack != null) { - if (Forge.isLandscapeMode()) { //show back button at bottom for landscape mode - if (showBackButtonInLandscapeMode()) { - float backButtonHeight = HEIGHT * 0.7f; - btnBack.setBounds(0, height - backButtonHeight, width, backButtonHeight); - height -= backButtonHeight; - } - } - else { - btnBack.setIconScaleAuto(tabPages[0].parentScreen.showCompactTabs()); - btnBack.setSize(BACK_BUTTON_WIDTH, height); - x += BACK_BUTTON_WIDTH; - } - } - scroller.setBounds(x, 0, width - x, height); - } - - @Override - public float doLandscapeLayout(float screenWidth, float screenHeight) { - float width = HEIGHT * 1.25f; - setBounds(screenWidth - width, 0, width, screenHeight); - return width; - } - } - - public static abstract class TabPage> extends FContainer { - private static final FSkinColor SEL_TAB_COLOR = FSkinColor.get(Colors.CLR_ACTIVE); - private static final FSkinColor TAB_FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT); - private static final FSkinFont TAB_FONT = FSkinFont.get(12); - - protected T parentScreen; - protected String caption; - protected FImage icon; - private int index; - private final Tab tab; - - protected TabPage(String caption0, FImage icon0) { - caption = caption0; - icon = icon0; - tab = new Tab(); - } - - public void showTab() { - tab.setVisible(true); - } - public void hideTab() { - tab.setVisible(false); - } - - public String getCaption() { - return caption; - } - - public FImage getIcon() { - return icon; - } - - protected void onActivate() { - } - - @Override - public boolean fling(float velocityX, float velocityY) { - //switch to next/previous tab page when flung left or right - if (Math.abs(velocityX) > Math.abs(velocityY)) { - if (velocityX < 0) { - if (index < parentScreen.tabPages.length - 1) { - parentScreen.setSelectedPage(parentScreen.tabPages[index + 1]); - } - } - else if (index > 0) { - parentScreen.setSelectedPage(parentScreen.tabPages[index - 1]); - } - return true; - } - return false; - } - - protected class Tab extends FDisplayObject { - @Override - public boolean tap(float x, float y, int count) { - parentScreen.setSelectedPage(TabPage.this); - return true; - } - - public void setVisible(boolean b0) { - if (isVisible() == b0) { return; } - super.setVisible(b0); - parentScreen.getHeader().revalidate(); //revalidate header to account for tab visiblility change - - if (!b0 && parentScreen.getSelectedPage() == TabPage.this) { - //select next page if this page is hidden - for (int i = index + 1; i < parentScreen.tabPages.length; i++) { - if (parentScreen.tabPages[i].tab.isVisible()) { - parentScreen.setSelectedPage(parentScreen.tabPages[i]); - return; - } - } - //select previous page if selecting next page is not possible - for (int i = index - 1; i >= 0; i--) { - if (parentScreen.tabPages[i].tab.isVisible()) { - parentScreen.setSelectedPage(parentScreen.tabPages[i]); - return; - } - } - parentScreen.setSelectedPage(null); - } - } - - @Override - public void draw(Graphics g) { - boolean isLandscapeMode = Forge.isLandscapeMode(); - - float w = getWidth(); - float h = getHeight(); - float padding = h * 0.1f; - if (parentScreen.getSelectedPage() == TabPage.this) { - g.fillRect(SEL_TAB_COLOR, Header.LINE_THICKNESS / 2, 0, w - Header.LINE_THICKNESS, h); - } - w -= 2 * padding; - - //draw caption and icon - if (parentScreen.showCompactTabs() && !isLandscapeMode) { - h -= 2 * padding; - if (icon == null) { - g.drawText(caption, TAB_FONT, TAB_FORE_COLOR, padding, padding, w, h, false, Align.center, true); - } - else { - //center combination of icon and text - float iconWidth = h * icon.getWidth() / icon.getHeight(); - float iconOffset = iconWidth + padding; - - float x = padding; - float y = padding; - float dx; - FSkinFont font = TAB_FONT; - while (true) { - dx = (w - iconOffset - font.getMultiLineBounds(caption).width) / 2; - if (dx > 0) { - x += dx; - break; - } - if (!font.canShrink()) { - break; - } - font = font.shrink(); - } - - g.drawImage(icon, x, y, iconWidth, h); - - x += iconOffset; - w -= iconOffset; - g.startClip(x, y, w, h); - g.drawText(caption, font, TAB_FORE_COLOR, x, y, w, h, false, Align.left, true); - g.endClip(); - } - } - else { - float y = h - padding - TAB_FONT.getCapHeight(); - g.drawText(caption, TAB_FONT, TAB_FORE_COLOR, padding, y - padding, w, h - y + padding, false, Align.center, true); - - if (icon != null) { - float iconHeight = y - 2 * padding; - float iconWidth = iconHeight * icon.getWidth() / icon.getHeight(); - if (iconWidth > w) { - iconHeight *= w / iconWidth; - iconWidth = w; - } - g.drawImage(icon, padding + (w - iconWidth) / 2, (y - iconHeight) / 2, iconWidth, iconHeight); - } - } - - //draw right/bottom border if needed - if (parentScreen.tabHeader.finalVisibleTab != this || isLandscapeMode) { - if (isLandscapeMode) { - float y = getHeight() - Header.LINE_THICKNESS / 2; - g.drawLine(Header.LINE_THICKNESS, TabHeader.SEPARATOR_COLOR, 0, y, getWidth(), y); - } - else { - float x = getWidth() - Header.LINE_THICKNESS / 2; - g.drawLine(Header.LINE_THICKNESS, TabHeader.SEPARATOR_COLOR, x, 0, x, getHeight()); - } - } - } - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/MatchController.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/MatchController.java deleted file mode 100644 index 91875f94460..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/MatchController.java +++ /dev/null @@ -1,666 +0,0 @@ -package forge.adventure.libgdxgui.screens.match; - -import com.google.common.base.Function; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import com.google.common.collect.Maps; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.LobbyPlayer; -import forge.ai.GameState; -import forge.adventure.libgdxgui.assets.*; -import forge.adventure.libgdxgui.card.CardAvatarImage; -import forge.adventure.libgdxgui.card.GameEntityPicker; -import forge.deck.CardPool; -import forge.adventure.libgdxgui.deck.FSideboardDialog; -import forge.game.GameEntityView; -import forge.game.card.CardView; -import forge.game.phase.PhaseType; -import forge.game.player.DelayedReveal; -import forge.game.player.IHasIcon; -import forge.game.player.PlayerView; -import forge.game.spellability.SpellAbilityView; -import forge.game.zone.ZoneType; -import forge.gamemodes.match.AbstractGuiGame; -import forge.gamemodes.match.HostedMatch; -import forge.gui.FThreads; -import forge.gui.GuiBase; -import forge.gui.util.SGuiChoose; -import forge.gui.util.SOptionPane; -import forge.item.IPaperCard; -import forge.item.PaperCard; -import forge.localinstance.properties.ForgePreferences; -import forge.localinstance.properties.ForgePreferences.FPref; -import forge.localinstance.skin.FSkinProp; -import forge.model.FModel; -import forge.player.PlayerZoneUpdate; -import forge.player.PlayerZoneUpdates; -import forge.adventure.libgdxgui.screens.match.views.*; -import forge.adventure.libgdxgui.screens.match.views.VPhaseIndicator.PhaseLabel; -import forge.adventure.libgdxgui.screens.match.views.VPlayerPanel.InfoTab; -import forge.adventure.libgdxgui.screens.match.winlose.ViewWinLose; -import forge.adventure.libgdxgui.toolbox.FButton; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.toolbox.FOptionPane; -import forge.trackable.TrackableCollection; -import forge.util.ITriggerEvent; -import forge.util.Localizer; -import forge.util.MessageUtil; -import forge.util.WaitCallback; -import forge.util.collect.FCollectionView; -import org.apache.commons.lang3.StringUtils; - -import java.util.*; - -public class MatchController extends AbstractGuiGame { - private MatchController() { } - public static final MatchController instance = new MatchController(); - - private static final Map avatarImages = new HashMap<>(); - - private static HostedMatch hostedMatch; - private static MatchScreen view; - private static GameState phaseGameState; - - private GameState getPhaseGameState() { - return phaseGameState; - } - - private final Map zonesToRestore = Maps.newHashMap(); - - public static MatchScreen getView() { - return view; - } - - @Override - protected void updateCurrentPlayer(final PlayerView player) { - for (final PlayerView other : getLocalPlayers()) { - if (!other.equals(player)) { - updatePromptForAwait(other); - } - } - } - - public static FImage getPlayerAvatar(final PlayerView p) { - final String lp = p.getLobbyPlayerName(); - FImage avatar = avatarImages.get(lp); - if (avatar == null) { - if (StringUtils.isEmpty(p.getAvatarCardImageKey())) { - avatar = new FTextureRegionImage(FSkin.getAvatars().get(p.getAvatarIndex())); - } - else { //handle lobby players with art from cards - avatar = new CardAvatarImage(p.getAvatarCardImageKey()); - } - } - return avatar; - } - - public static FImage getPlayerSleeve(final PlayerView p) { - if (p == null) - return FSkinImage.UNKNOWN; - return new FTextureRegionImage(FSkin.getSleeves().get(p.getSleeveIndex())); - } - - @Override - public void refreshCardDetails(final Iterable cards) { - //ensure cards appear in the correct row of the field - for (final VPlayerPanel pnl : view.getPlayerPanels().values()) { - pnl.getField().update(true); - } - } - - @Override - public void refreshField() { - if(!GuiBase.isNetworkplay()) - return; - refreshCardDetails(null); - } - - @Override - public GameState getGamestate() { - return getPhaseGameState(); - } - - public boolean hotSeatMode() { - return FModel.getPreferences().getPrefBoolean(FPref.MATCH_HOT_SEAT_MODE); - } - - @Override - public void openView(final TrackableCollection myPlayers) { - final boolean noHumans = !hasLocalPlayers(); - - final FCollectionView allPlayers = getGameView().getPlayers(); - final List playerPanels = new ArrayList<>(); - for (final PlayerView p : allPlayers) { - final boolean isLocal = isLocalPlayer(p); - final VPlayerPanel playerPanel = new VPlayerPanel(p, isLocal || noHumans, allPlayers.size()); - if (isLocal && !playerPanels.isEmpty()) { - playerPanels.add(0, playerPanel); //ensure local player always first among player panels - } - else { - playerPanels.add(playerPanel); - } - } - view = new MatchScreen(playerPanels); - if(GuiBase.isNetworkplay()) - view.resetFields(); - clearSelectables(); //fix uncleared selection - - if (noHumans) { - //add special object that pauses game if screen touched - view.add(new FDisplayObject() { - @Override - public void draw(final Graphics g) { - //don't draw anything - } - - @Override - public void buildTouchListeners(final float screenX, final float screenY, final List listeners) { - if (screenY < view.getHeight() - VPrompt.HEIGHT) { - hostedMatch.pause(); - } - } - }); - } - - actuateMatchPreferences(); - - Forge.openScreen(view); - } - - @Override - public void showPromptMessage(final PlayerView player, final String message) { - view.getPrompt(player).setMessage(message); - } - - @Override - public void showPromptMessage(final PlayerView player, final String message, final CardView card) { - view.getPrompt(player).setMessage(message, card); - } - - @Override - public void updateButtons(final PlayerView owner, final String label1, final String label2, final boolean enable1, final boolean enable2, final boolean focus1) { - final VPrompt prompt = view.getPrompt(owner); - final FButton btn1 = prompt.getBtnOk(), btn2 = prompt.getBtnCancel(); - btn1.setText(label1); - btn2.setText(label2); - btn1.setEnabled(enable1); - btn2.setEnabled(enable2); - } - - @Override - public void flashIncorrectAction() { - //SDisplayUtil.remind(VPrompt.SINGLETON_INSTANCE); //TODO - } - @Override - public void alertUser() { - //TODO - } - - @Override - public void updatePhase(boolean saveState) { - final PlayerView p = getGameView().getPlayerTurn(); - final PhaseType ph = getGameView().getPhase(); - - PhaseLabel lbl = null; - - if(ph!=null) { - lbl = p == null ? null : view.getPlayerPanel(p).getPhaseIndicator().getLabel(ph); - } else { - System.err.println("getGameView().getPhase() returned 'null'"); - } - - view.resetAllPhaseButtons(); - if (lbl != null) { - lbl.setActive(true); - } - if(GuiBase.isNetworkplay()) - checkStack(); - - if (saveState && ph.isMain()) { - phaseGameState = new GameState() { - @Override //todo get specific card edition for this function? - public IPaperCard getPaperCard(final String cardName) { - return FModel.getMagicDb().getCommonCards().getCard(cardName); - } - }; - try { - phaseGameState.initFromGame(getGameView().getGame()); - } catch (Exception e) {} - } - } - - - public void checkStack() { - view.getStack().checkEmptyStack(); - } - - public void showWinlose() { - if (view.getViewWinLose() != null) - view.getViewWinLose().setVisible(true); - } - - @Override - public void updateTurn(final PlayerView player) { - } - - @Override - public void updatePlayerControl() { - //show/hide hand for top player based on whether the opponent is controlled - if (getLocalPlayerCount() == 1) { - final PlayerView player = view.getTopPlayerPanel().getPlayer(); - if (player.getMindSlaveMaster() != null) { - view.getTopPlayerPanel().setSelectedZone(ZoneType.Hand); - } else { - view.getTopPlayerPanel().setSelectedTab(null); - } - } - } - - @Override - public void disableOverlay() { - } - - @Override - public void enableOverlay() { - } - - @Override - public void finishGame() { - if (hasLocalPlayers() || getGameView().isMatchOver()) { - view.setViewWinLose(new ViewWinLose(getGameView())); - view.getViewWinLose().setVisible(true); - } - } - - @Override - public void updateStack() { - view.getStack().update(); - } - - @Override - public void setPanelSelection(final CardView c) { - //GuiUtils.setPanelSelection(c); //TODO - } - - @Override - public SpellAbilityView getAbilityToPlay(final CardView hostCard, final List abilities, final ITriggerEvent triggerEvent) { - if (abilities.isEmpty()) { - return null; - } - if (abilities.size() == 1) { - return abilities.get(0); - } - return SGuiChoose.oneOrNone(Localizer.getInstance().getMessage("lblChooseAbilityToPlay"), abilities); - } - - @Override - public void showCombat() { - } - - @Override - public void showManaPool(final PlayerView player) { - final VPlayerPanel playerPanel = view.getPlayerPanel(player); - final InfoTab selectedTab = playerPanel.getSelectedTab(), manaPoolTab = playerPanel.getManaPoolTab(); - if (!manaPoolTab.equals(selectedTab)) { - //if mana pool was selected previously, we don't need to switch back to anything - zonesToRestore.put(player, selectedTab); - } - playerPanel.setSelectedTab(manaPoolTab); - } - - @Override - public void hideManaPool(final PlayerView player) { - final VPlayerPanel playerPanel = view.getPlayerPanel(player); - // value may be null so explicit containsKey call is necessary - final boolean doRestore = zonesToRestore.containsKey(player); - final InfoTab zoneToRestore = zonesToRestore.remove(player); - if (!playerPanel.getManaPoolTab().equals(playerPanel.getSelectedTab()) || !doRestore) { - return; //if player switched away from mana pool already, don't change anything - } - - playerPanel.setSelectedTab(zoneToRestore); - } - - @Override - public PlayerZoneUpdates openZones(PlayerView controller, final Collection zones, final Map playersWithTargetables) { - PlayerZoneUpdates updates = new PlayerZoneUpdates(); - if (zones.size() == 1) { - final ZoneType zoneType = zones.iterator().next(); - switch (zoneType) { - case Battlefield: - case Command: - playersWithTargetables.clear(); //clear since no zones need to be restored - default: - //open zone tab for given zone if needed - boolean result = true; - for (final PlayerView player : playersWithTargetables.keySet()) { - final VPlayerPanel playerPanel = view.getPlayerPanel(player); - playersWithTargetables.put(player, playerPanel.getSelectedTab()); //backup selected tab before changing it - final InfoTab zoneTab = playerPanel.getZoneTab(zoneType); - ZoneType previousZone = playerPanel.getZoneByInfoTab(playerPanel.getSelectedTab()); - updates.add(new PlayerZoneUpdate(player, previousZone)); - if (zoneTab != null) { - playerPanel.setSelectedTab(zoneTab); - } - } - } - } - return updates; - } - - @Override - public void restoreOldZones(PlayerView playerView, PlayerZoneUpdates playerZoneUpdates) { - for(PlayerZoneUpdate update : playerZoneUpdates) { - PlayerView player = update.getPlayer(); - - ZoneType zone = null; - for(ZoneType type : update.getZones()) { - zone = type; - break; - } - - final VPlayerPanel playerPanel = view.getPlayerPanel(player); - if (zone == null) { - playerPanel.hideSelectedTab(); - continue; - } - - final InfoTab zoneTab = playerPanel.getZoneTab(zone); - playerPanel.setSelectedTab(zoneTab); - } - } - - @Override - public Map assignCombatDamage(final CardView attacker, final List blockers, final int damage, final GameEntityView defender, final boolean overrideOrder) { - return new WaitCallback>() { - @Override - public void run() { - final VAssignCombatDamage v = new VAssignCombatDamage(attacker, blockers, damage, defender, overrideOrder, this); - v.show(); - } - }.invokeAndWait(); - } - - @Override - public Map assignGenericAmount(final CardView effectSource, final Map targets, - final int amount, final boolean atLeastOne, final String amountLabel) { - return new WaitCallback>() { - @Override - public void run() { - final VAssignGenericAmount v = new VAssignGenericAmount(effectSource, targets, amount, atLeastOne, amountLabel, this); - v.show(); - } - }.invokeAndWait(); - } - - @Override - public void updateManaPool(final Iterable manaPoolUpdate) { - for (final PlayerView p : manaPoolUpdate) { - view.getPlayerPanel(p).updateManaPool(); - } - } - - @Override - public void updateLives(final Iterable livesUpdate) { - for (final PlayerView p : livesUpdate) { - view.getPlayerPanel(p).updateLife(); - } - } - - @Override - public void updateZones(final Iterable zonesToUpdate) { - view.updateZones(zonesToUpdate); - } - - @Override - public Iterable tempShowZones(final PlayerView controller, final Iterable zonesToUpdate) { - return view.tempShowZones(controller, zonesToUpdate); - } - - @Override - public void hideZones(final PlayerView controller, final Iterable zonesToUpdate) { - view.hideZones(controller, zonesToUpdate); - } - - @Override - public void updateCards(final Iterable cards) { - for (final CardView card : cards) { - view.updateSingleCard(card); - } - } - - @Override - public void setSelectables(final Iterable cards) { - super.setSelectables(cards); - // update zones on tabletop and floating zones - non-selectable cards may be rendered differently - FThreads.invokeInEdtNowOrLater(new Runnable() { - @Override public final void run() { - for (final PlayerView p : getGameView().getPlayers()) { - if ( p.getCards(ZoneType.Battlefield) != null ) { - updateCards(p.getCards(ZoneType.Battlefield)); - } - if ( p.getCards(ZoneType.Hand) != null ) { - updateCards(p.getCards(ZoneType.Hand)); - } - } - } - }); - } - - @Override - public void clearSelectables() { - super.clearSelectables(); - // update zones on tabletop and floating zones - non-selectable cards may be rendered differently - FThreads.invokeInEdtNowOrLater(new Runnable() { - @Override public final void run() { - for (final PlayerView p : getGameView().getPlayers()) { - if ( p.getCards(ZoneType.Battlefield) != null ) { - updateCards(p.getCards(ZoneType.Battlefield)); - } - if ( p.getCards(ZoneType.Hand) != null ) { - updateCards(p.getCards(ZoneType.Hand)); - } - } - } - }); - } - - @Override - public void afterGameEnd() { - super.afterGameEnd(); - Forge.back(); - //view = null; - } - - public void resetPlayerPanels() { - if (view != null) - view.forceRevalidate(); - } - - private static void actuateMatchPreferences() { - final ForgePreferences prefs = FModel.getPreferences(); - - for (int i=0; i options, final int defaultOption) { - return SOptionPane.showOptionDialog(message, title, icon, options, defaultOption); - } - - @Override - public String showInputDialog(final String message, final String title, final FSkinProp icon, final String initialInput, final List inputOptions) { - return SOptionPane.showInputDialog(message, title, icon, initialInput, inputOptions); - } - - @Override - public boolean confirm(final CardView c, final String question, final boolean defaultIsYes, final List options) { - final List optionsToUse; - if (options == null) { - optionsToUse = ImmutableList.of(Localizer.getInstance().getMessage("lblYes"), Localizer.getInstance().getMessage("lblNo")); - } else { - optionsToUse = options; - } - return FOptionPane.showCardOptionDialog(c, question, "", SOptionPane.INFORMATION_ICON, optionsToUse, defaultIsYes ? 0 : 1) == 0; - } - - @Override - public List getChoices(final String message, final int min, final int max, final List choices, final T selected, final Function display) { - return GuiBase.getInterface().getChoices(message, min, max, choices, selected, display); - } - - @Override - public List order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax, final List sourceChoices, final List destChoices, final CardView referenceCard, final boolean sideboardingMode) { - return GuiBase.getInterface().order(title, top, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices); - } - - @Override - public List sideboard(final CardPool sideboard, final CardPool main, final String message) { - return new WaitCallback>() { - @Override - public void run() { - final FSideboardDialog sideboardDialog = new FSideboardDialog(sideboard, main, this, message); - sideboardDialog.show(); - } - }.invokeAndWait(); - } - - @Override - public GameEntityView chooseSingleEntityForEffect(final String title, final List optionList, final DelayedReveal delayedReveal, final boolean isOptional) { - if (delayedReveal == null || Iterables.isEmpty(delayedReveal.getCards())) { - if (isOptional) { - return SGuiChoose.oneOrNone(title, optionList); - } - return SGuiChoose.one(title, optionList); - } - - final Collection revealList = delayedReveal.getCards(); - final String revealListCaption = StringUtils.capitalize(MessageUtil.formatMessage("{player's} " + delayedReveal.getZone().getTranslatedName(), delayedReveal.getOwner(), delayedReveal.getOwner())); - final InfoTab revealListTab = MatchController.getView().getPlayerPanels().values().iterator().next().getZoneTab(delayedReveal.getZone()); - final FImage revealListImage = revealListTab != null ? revealListTab.getIcon() : null; - - //use special dialog for choosing card and offering ability to see all revealed cards at the same time - return new WaitCallback() { - @Override - public void run() { - final GameEntityPicker picker = new GameEntityPicker(title, optionList, revealList, revealListCaption, revealListImage, isOptional, this); - picker.show(); - } - }.invokeAndWait(); - } - - @Override - public List chooseEntitiesForEffect(String title, List optionList, int min, int max, DelayedReveal delayedReveal) { - final int m1 = max >= 0 ? optionList.size() - max : -1; - final int m2 = min >= 0 ? optionList.size() - min : -1; - return SGuiChoose.order(title, Localizer.getInstance().getMessage("lblSelected"), m1, m2, (List) optionList, null); - } - - @Override - public List manipulateCardList(final String title, final Iterable cards, final Iterable manipulable, final boolean toTop, final boolean toBottom, final boolean toAnywhere) { - System.err.println("Not implemented yet - should never be called"); - return null; - } - - @Override - public void setCard(final CardView card) { - // doesn't need to do anything - } - - @Override - public void setPlayerAvatar(final LobbyPlayer player, final IHasIcon ihi) { - avatarImages.put(player.getName(), ImageCache.getIcon(ihi)); - } - - @Override - public boolean isUiSetToSkipPhase(final PlayerView playerTurn, final PhaseType phase) { - return !view.stopAtPhase(playerTurn, phase); - } - - public static HostedMatch hostMatch() { - hostedMatch = new HostedMatch(); - return hostedMatch; - } - - public static HostedMatch getHostedMatch() { - return hostedMatch; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/MatchScreen.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/MatchScreen.java deleted file mode 100644 index 4fba22e2ca6..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/MatchScreen.java +++ /dev/null @@ -1,785 +0,0 @@ -package forge.adventure.libgdxgui.screens.match; - -import com.badlogic.gdx.Input.Keys; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.math.Rectangle; -import com.google.common.collect.Maps; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Forge.KeyInputAdapter; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.animation.AbilityEffect; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinTexture; -import forge.adventure.libgdxgui.menu.*; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.screens.match.views.*; -import forge.adventure.libgdxgui.screens.match.views.VCardDisplayArea.CardAreaPanel; -import forge.adventure.libgdxgui.screens.match.views.VPhaseIndicator.PhaseLabel; -import forge.adventure.libgdxgui.screens.match.views.VPlayerPanel.InfoTab; -import forge.adventure.libgdxgui.screens.match.winlose.ViewWinLose; -import forge.adventure.libgdxgui.toolbox.FCardPanel; -import forge.adventure.libgdxgui.toolbox.FEvent; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.toolbox.FScrollPane; -import forge.game.GameEntityView; -import forge.game.GameView; -import forge.game.card.CardView; -import forge.game.combat.CombatView; -import forge.game.phase.PhaseType; -import forge.game.player.PlayerView; -import forge.game.zone.ZoneType; -import forge.gui.GuiBase; -import forge.interfaces.IGameController; -import forge.localinstance.properties.ForgePreferences; -import forge.localinstance.properties.ForgePreferences.FPref; -import forge.model.FModel; -import forge.player.PlayerZoneUpdate; -import forge.sound.MusicPlaylist; -import forge.sound.SoundSystem; -import forge.util.Callback; -import forge.util.Localizer; -import org.apache.commons.lang3.tuple.Pair; - -import java.util.*; -import java.util.Map.Entry; - -public class MatchScreen extends FScreen { - public static FSkinColor BORDER_COLOR = FSkinColor.get(Colors.CLR_BORDERS); - - private final Map playerPanels = Maps.newHashMap(); - private final List playerPanelsList; - private final VGameMenu gameMenu; - private final VPlayers players; - private final VLog log; - private final VStack stack; - private final VDevMenu devMenu; - private final FieldScroller scroller; - private final VPrompt bottomPlayerPrompt, topPlayerPrompt; - private final VPlayerPanel bottomPlayerPanel; - private final VPlayerPanel topPlayerPanel; - private AbilityEffect activeEffect; - - private ViewWinLose viewWinLose = null; - - public MatchScreen(List playerPanels0) { - super(new FMenuBar()); - - scroller = add(new FieldScroller()); - - int humanCount = 0; - - for (VPlayerPanel playerPanel : playerPanels0) { - playerPanels.put(playerPanel.getPlayer(), scroller.add(playerPanel)); - playerPanel.setFlipped(true); - if(!playerPanel.getPlayer().isAI()) - humanCount++; - } - bottomPlayerPanel = playerPanels0.get(0); - bottomPlayerPanel.setFlipped(false); - topPlayerPanel = playerPanels0.get(1); - playerPanelsList = playerPanels0; - //reorder list so bottom player is at the end of the list ensuring top to bottom turn order - playerPanelsList.remove(bottomPlayerPanel); - playerPanelsList.add(bottomPlayerPanel); - - - bottomPlayerPrompt = add(new VPrompt("", "", - new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - getGameController().selectButtonOk(); - } - }, - new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - getGameController().selectButtonCancel(); - } - })); - - if (humanCount < 2 || MatchController.instance.hotSeatMode() || GuiBase.isNetworkplay()) - topPlayerPrompt = null; - else { - //show top prompt if multiple human players and not playing in Hot Seat mode and not in network play - topPlayerPrompt = add(new VPrompt("", "", - new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - getGameController().selectButtonOk(); - } - }, - new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - getGameController().selectButtonCancel(); - } - })); - topPlayerPrompt.setRotate180(true); - topPlayerPanel.setRotate180(true); - getHeader().setRotate90(true); - } - - gameMenu = new VGameMenu(); - gameMenu.setDropDownContainer(this); - players = new VPlayers(); - players.setDropDownContainer(this); - log = new VLog(); - log.setDropDownContainer(this); - devMenu = new VDevMenu(); - devMenu.setDropDownContainer(this); - stack = new VStack(); - stack.setDropDownContainer(this); - - FMenuBar menuBar = (FMenuBar)getHeader(); - final Localizer localizer = Localizer.getInstance(); - if (topPlayerPrompt == null) { - menuBar.addTab(localizer.getMessage("lblGame"), gameMenu); - menuBar.addTab(localizer.getMessage("lblPlayers") + " (" + playerPanels.size() + ")", players); - menuBar.addTab(localizer.getMessage("lblLog"), log); - menuBar.addTab(localizer.getMessage("lblDev"), devMenu); - menuBar.addTab( localizer.getMessage("lblStack") + " (0)", stack); - } - else { - menuBar.addTab("\u2022 \u2022 \u2022", new PlayerSpecificMenu(true)); - stack.setRotate90(true); - menuBar.addTab(localizer.getMessage("lblStack") + " (0)", stack); - menuBar.addTab("\u2022 \u2022 \u2022", new PlayerSpecificMenu(false)); - - //create fake menu tabs for other drop downs so they can be positioned as needed - gameMenu.setMenuTab(new HiddenMenuTab(gameMenu)); - players.setMenuTab(new HiddenMenuTab(players)); - log.setMenuTab(new HiddenMenuTab(log)); - devMenu.setMenuTab(new HiddenMenuTab(devMenu)); - } - } - - private boolean is4Player(){ - return playerPanels.keySet().size() == 4; - } - - private boolean is3Player(){ - return playerPanels.keySet().size() == 3; - } - - private IGameController getGameController() { - return MatchController.instance.getGameController(); - } - - private class HiddenMenuTab extends FMenuTab { - private HiddenMenuTab(FDropDown dropDown0) { - super(null, null, dropDown0, -1); - setVisible(false); - } - @Override - public void setText(String text0) { - //avoid trying to set text for this tab - } - } - - private class PlayerSpecificMenu extends FDropDownMenu { - private PlayerSpecificMenu(boolean forTopPlayer) { - setRotate180(forTopPlayer); - } - - @Override - protected void updateSizeAndPosition() { - Rectangle menuTabPos = getMenuTab().screenPos; - FScreen screen = Forge.getCurrentScreen(); - float maxWidth = screen.getWidth() - menuTabPos.width; - float maxHeight = screen.getHeight() / 2; - - paneSize = updateAndGetPaneSize(maxWidth, maxHeight); - - //round width and height so borders appear properly - paneSize = new ScrollBounds(Math.round(paneSize.getWidth()), Math.round(paneSize.getHeight())); - - float x = maxWidth - paneSize.getWidth(); - float y = getRotate180() ? menuTabPos.y + FMenuTab.PADDING : menuTabPos.y + menuTabPos.height - paneSize.getHeight() - FMenuTab.PADDING + 1; - setBounds(Math.round(x), Math.round(y), paneSize.getWidth(), paneSize.getHeight()); - } - - private class MenuItem extends FMenuItem { - private MenuItem(String text0, final FDropDown dropDown) { - super(text0, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - dropDown.setRotate180(PlayerSpecificMenu.this.getRotate180()); - Rectangle menuScreenPos = PlayerSpecificMenu.this.screenPos; - if (dropDown.getRotate180()) { - dropDown.getMenuTab().screenPos.setPosition(menuScreenPos.x + menuScreenPos.width, menuScreenPos.y); - } - else { - dropDown.getMenuTab().screenPos.setPosition(menuScreenPos.x + menuScreenPos.width, menuScreenPos.y + menuScreenPos.height); - } - dropDown.show(); - } - }); - } - } - - @Override - protected void buildMenu() { - final Localizer localizer = Localizer.getInstance(); - - if (isTopHumanPlayerActive() == getRotate180()) { - addItem(new MenuItem(localizer.getMessage("lblGame"), gameMenu)); - addItem(new MenuItem(localizer.getMessage("lblPlayers") + " (" + playerPanels.size() + ")", players)); - addItem(new MenuItem(localizer.getMessage("lblLog"), log)); - if (ForgePreferences.DEV_MODE) { - addItem(new MenuItem(localizer.getMessage("lblDev"), devMenu)); - } - } - else { //TODO: Support using menu when player doesn't have priority - FMenuItem item = new FMenuItem(localizer.getMessage("lblMustWaitPriority"), null); - item.setEnabled(false); - addItem(item); - } - } - } - - @Override - public void onActivate() { - //update dev menu visibility here so returning from Settings screen allows update - if (topPlayerPrompt == null) { - devMenu.getMenuTab().setVisible(ForgePreferences.DEV_MODE); - } - } - - public boolean isTopHumanPlayerActive() { - return topPlayerPrompt != null && topPlayerPanel.getPlayer() == MatchController.instance.getCurrentPlayer(); - } - - public VPrompt getActivePrompt() { - if (isTopHumanPlayerActive()) { - return topPlayerPrompt; - } - return bottomPlayerPrompt; - } - - public VPrompt getPrompt(PlayerView playerView) { - if (topPlayerPrompt == null || bottomPlayerPanel.getPlayer() == playerView) { - return bottomPlayerPrompt; - } - return topPlayerPrompt; - } - - public VLog getLog() { - return log; - } - - public VStack getStack() { - return stack; - } - - public VPlayerPanel getTopPlayerPanel() { - return topPlayerPanel; - } - - public void setViewWinLose( ViewWinLose viewWinLose ){ - this.viewWinLose = viewWinLose; - } - - public ViewWinLose getViewWinLose() { - return viewWinLose; - } - - public VPlayerPanel getBottomPlayerPanel() { - return bottomPlayerPanel; - } - - public Map getPlayerPanels() { - return playerPanels; - } - - public List getPlayerPanelsList() { - return playerPanelsList; - } - - @Override - public void onClose(Callback canCloseCallback) { - MatchController.writeMatchPreferences(); - SoundSystem.instance.setBackgroundMusic(MusicPlaylist.MENUS); - super.onClose(canCloseCallback); - } - - @Override - protected void doLayout(float startY, float width, float height) { - float scrollerWidth = width; - if (topPlayerPrompt != null) { - topPlayerPrompt.setBounds(0, 0, width, VPrompt.HEIGHT); - float menuBarWidth = getHeader().getHeight(); - float menuBarHeight = height - 2 * VPrompt.HEIGHT; - getHeader().setBounds(width - menuBarHeight, height - VPrompt.HEIGHT, menuBarHeight, menuBarWidth); //adjust position prior to rotate transform - startY = VPrompt.HEIGHT; - scrollerWidth -= menuBarWidth; - } - scroller.setBounds(0, startY, scrollerWidth, height - VPrompt.HEIGHT - startY); - bottomPlayerPrompt.setBounds(0, height - VPrompt.HEIGHT, width, VPrompt.HEIGHT); - } - - @Override - public FScreen getLandscapeBackdropScreen() { - return null; - } - - @Override - public Rectangle getDropDownBoundary() { - if (topPlayerPrompt == null) { - return new Rectangle(0, 0, getWidth(), getHeight() - VPrompt.HEIGHT); //prevent covering prompt - } - return new Rectangle(0, VPrompt.HEIGHT, scroller.getWidth(), getHeight() - 2 * VPrompt.HEIGHT); - } - - @Override - protected void drawOverlay(Graphics g) { - final GameView game = MatchController.instance.getGameView(); - if (game == null) { return; } - - if(gameMenu!=null) { - if(gameMenu.getChildCount()>3){ - if(viewWinLose == null) { - gameMenu.getChildAt(0).setEnabled(!game.isMulligan()); - gameMenu.getChildAt(1).setEnabled(!game.isMulligan()); - gameMenu.getChildAt(2).setEnabled(!game.isMulligan()); - gameMenu.getChildAt(3).setEnabled(!game.isMulligan()); - gameMenu.getChildAt(4).setEnabled(false); - } else { - gameMenu.getChildAt(0).setEnabled(false); - gameMenu.getChildAt(1).setEnabled(false); - gameMenu.getChildAt(2).setEnabled(false); - gameMenu.getChildAt(3).setEnabled(false); - gameMenu.getChildAt(4).setEnabled(true); - } - } - } - if(devMenu!=null) { - if(devMenu.isVisible()){ - devMenu.setEnabled(viewWinLose == null); - - try { - //rollbackphase enable -- todo limit by gametype? - devMenu.getChildAt(2).setEnabled(game.getPlayers().size() == 2 && game.getStack().size() == 0 && !GuiBase.isNetworkplay() && game.getPhase().isMain() && !game.getPlayerTurn().isAI()); - } catch (Exception e) {/*NPE when the game hasn't started yet and you click dev mode*/} - } - } - - //draw arrows for paired cards - Set pairedCards = new HashSet<>(); - for (VPlayerPanel playerPanel : playerPanels.values()) { - for (CardView card : playerPanel.getField().getRow1().getOrderedCards()) { - if (pairedCards.contains(card)) { continue; } //prevent arrows going both ways - - CardView paired = card.getPairedWith(); - if (paired != null) { - TargetingOverlay.drawArrow(g, card, paired); - } - } - } - - //draw arrows for combat - final CombatView combat = game.getCombat(); - if (combat != null) { - for (final CardView attacker : combat.getAttackers()) { - //connect each attacker with planeswalker it's attacking if applicable - final GameEntityView defender = combat.getDefender(attacker); - if (defender instanceof CardView) { - TargetingOverlay.drawArrow(g, attacker, (CardView) defender); - } - final Iterable blockers = combat.getBlockers(attacker); - if (blockers != null) { - //connect each blocker with the attacker it's blocking - for (final CardView blocker : blockers) { - TargetingOverlay.drawArrow(g, blocker, attacker); - } - } - final Iterable plannedBlockers = combat.getPlannedBlockers(attacker); - if (plannedBlockers != null) { - //connect each planned blocker with the attacker it's blocking - for (final CardView blocker : plannedBlockers) { - TargetingOverlay.drawArrow(g, blocker, attacker); - } - } - //player - if (is4Player() || is3Player()) { - int numplayers = is3Player() ? 3 : 4; - for (final PlayerView p : game.getPlayers()) { - if (combat.getAttackersOf(p).contains(attacker)) - TargetingOverlay.drawArrow(g, attacker, p, numplayers); - } - } - } - } - - if (activeEffect != null) { - activeEffect.draw(g, 10, 10, 100, 100); - } - } - - @Override - public boolean keyDown(int keyCode) { - switch (keyCode) { - case Keys.ENTER: - case Keys.SPACE: - if (getActivePrompt().getBtnOk().trigger()) { //trigger OK on Enter or Space - return true; - } - return getActivePrompt().getBtnCancel().trigger(); //trigger Cancel if can't trigger OK - case Keys.ESCAPE: - if (!FModel.getPreferences().getPrefBoolean(FPref.UI_ALLOW_ESC_TO_END_TURN)) { - if (getActivePrompt().getBtnCancel().getText().equals(Localizer.getInstance().getMessage("lblEndTurn"))) { - return false; - } - } - return getActivePrompt().getBtnCancel().trigger(); //otherwise trigger Cancel - case Keys.BACK: - return true; //suppress Back button so it's not bumped when trying to press OK or Cancel buttons - case Keys.A: //alpha strike on Ctrl+A on Android, A when running on desktop - if (KeyInputAdapter.isCtrlKeyDown() || GuiBase.getInterface().isRunningOnDesktop()) { - getGameController().alphaStrike(); - return true; - } - break; - case Keys.E: //end turn on Ctrl+E on Android, E when running on desktop - if (KeyInputAdapter.isCtrlKeyDown() || GuiBase.getInterface().isRunningOnDesktop()) { - getGameController().passPriorityUntilEndOfTurn(); - return true; - } - break; - case Keys.Q: //concede game on Ctrl+Q - if (KeyInputAdapter.isCtrlKeyDown()) { - MatchController.instance.concede(); - return true; - } - break; - case Keys.Z: //undo on Ctrl+Z - if (KeyInputAdapter.isCtrlKeyDown()) { - getGameController().undoLastAction(); - return true; - } - break; - } - return super.keyDown(keyCode); - } - - @Override - public void showMenu() { - //don't show menu from this screen since it's too easy to bump the menu button when trying to press OK or Cancel - } - - public boolean stopAtPhase(final PlayerView turn, final PhaseType phase) { - final PhaseLabel label = getPlayerPanel(turn).getPhaseIndicator().getLabel(phase); - return label == null || label.getStopAtPhase(); - } - - public void resetAllPhaseButtons() { - for (final VPlayerPanel panel : getPlayerPanels().values()) { - panel.getPhaseIndicator().resetPhaseButtons(); - } - } - - public VPlayerPanel getPlayerPanel(final PlayerView playerView) { - return getPlayerPanels().get(playerView); - } - - public void highlightCard(final CardView c) { - for (VPlayerPanel playerPanel : getPlayerPanels().values()) { - for (FCardPanel p : playerPanel.getField().getCardPanels()) { - if (p.getCard().equals(c)) { - p.setHighlighted(true); - return; - } - } - } - } - - public void clearCardHighlights() { - for (VPlayerPanel playerPanel : getPlayerPanels().values()) { - for (FCardPanel p : playerPanel.getField().getCardPanels()) { - p.setHighlighted(false); - } - } - } - - public void resetFields() { - CardAreaPanel.resetForNewGame(); - for (VPlayerPanel playerPanel : getPlayerPanels().values()) { - for (CardAreaPanel p : playerPanel.getField().getCardPanels()){ - p.reset(); - } - playerPanel.getZoneTab(ZoneType.Hand).getDisplayArea().clear(); - playerPanel.getZoneTab(ZoneType.Library).getDisplayArea().clear(); - playerPanel.getZoneTab(ZoneType.Graveyard).getDisplayArea().clear(); - playerPanel.getZoneTab(ZoneType.Exile).getDisplayArea().clear(); - - } - } - - public void forceRevalidate() { - for (VPlayerPanel playerPanel : getPlayerPanels().values()) { - playerPanel.revalidate(true); - - } - } - - public void updateZones(final Iterable zonesToUpdate) { - for (final PlayerZoneUpdate update : zonesToUpdate) { - final PlayerView owner = update.getPlayer(); - final VPlayerPanel panel = getPlayerPanel(owner); - for (final ZoneType zone : update.getZones()) { - panel.updateZone(zone); - } - } - } - - public Iterable tempShowZones(final PlayerView controller, final Iterable zonesToUpdate) { - // pfps needs to actually do something - return zonesToUpdate; // pfps should return only those zones newly shown - } - - public void hideZones(final PlayerView controller, final Iterable zonesToUpdate) { - // pfps needs to actually do something - } - - public void updateSingleCard(final CardView card) { - final CardAreaPanel pnl = CardAreaPanel.get(card); - if (pnl == null) { return; } - final ZoneType zone = card.getZone(); - if (zone != null && zone == ZoneType.Battlefield) { - pnl.updateCard(card); - } - else { //ensure card not on battlefield is reset such that it no longer thinks it's on the battlefield - pnl.setTapped(false); - pnl.getAttachedPanels().clear(); - pnl.setAttachedToPanel(null); - pnl.setPrevPanelInStack(null); - pnl.setNextPanelInStack(null); - } - } - - private class FieldScroller extends FScrollPane { - private float extraHeight = 0; - - @Override - public void drawBackground(Graphics g) { - super.drawBackground(g); - - if (FModel.getPreferences().getPrefBoolean(FPref.UI_MATCH_IMAGE_VISIBLE)) { - float midField = topPlayerPanel.getBottom(); - float x = topPlayerPanel.getField().getLeft(); - float y = midField - topPlayerPanel.getField().getHeight(); - float w = getWidth() - x; - float bgFullWidth, scaledbgHeight; - int multiplier = playerPanels.keySet().size() - 1; //fix scaling of background when zoomed in multiplayer - float bgHeight = (midField + bottomPlayerPanel.getField().getHeight() * multiplier) - y; - if(FModel.getPreferences().getPrefBoolean(FPref.UI_DYNAMIC_PLANECHASE_BG) - && hasActivePlane()) { - String imageName = getPlaneName() - .replace(" ", "_") - .replace("'", "") - .replace("-", ""); - if (FSkinTexture.getValues().contains(imageName)) { - bgFullWidth = bgHeight * FSkinTexture.valueOf(imageName).getWidth() / FSkinTexture.valueOf(imageName).getHeight(); - if (bgFullWidth < w) { - scaledbgHeight = w * (bgHeight / bgFullWidth); - bgFullWidth = w; - bgHeight = scaledbgHeight; - } - g.drawImage(FSkinTexture.valueOf(imageName), x + (w - bgFullWidth) / 2, y, bgFullWidth, bgHeight, true); - } - } - else { - bgFullWidth = bgHeight * FSkinTexture.BG_MATCH.getWidth() / FSkinTexture.BG_MATCH.getHeight(); - if (bgFullWidth < w) { - scaledbgHeight = w * (bgHeight / bgFullWidth); - bgFullWidth = w; - bgHeight = scaledbgHeight; - } - g.drawImage(FSkinTexture.BG_MATCH, x + (w - bgFullWidth) / 2, y, bgFullWidth, bgHeight); - } - } - } - - @Override - public void drawOverlay(Graphics g) { - float midField; - float x = 0; - float y; - float w = getWidth(); - Color color = Color.CYAN; - GameView game = MatchController.instance.getGameView(); - CombatView combat = game.getCombat(); - PlayerView currentPlayer = MatchController.instance.getCurrentPlayer(); - - //field separator lines - if (!Forge.isLandscapeMode()) { - for (VPlayerPanel playerPanel: playerPanelsList){ - midField = playerPanel.getTop(); - y = midField - playerPanel.getField().getHeight(); - if (playerPanel.getSelectedTab() == null) { - y++; - } - g.drawLine(1, BORDER_COLOR, x, y, w, y); - } - } - - for (VPlayerPanel playerPanel: playerPanelsList){ - midField = playerPanel.getTop(); - y = midField - 0.5f; - g.drawLine(1, BORDER_COLOR, x, y, w, y); - } - - if (!Forge.isLandscapeMode()) { - y = bottomPlayerPanel.getTop() + bottomPlayerPanel.getField().getHeight(); - g.drawLine(1, BORDER_COLOR, x, y, w, y); - } - - //Draw Priority Human Multiplayer 2 player - float oldAlphaComposite = g.getfloatAlphaComposite(); - //TODO: support up to 4 players - if ((getPlayerPanels().keySet().size() == 2) && (countHuman() == 2)){ - for (VPlayerPanel playerPanel: playerPanelsList){ - midField = playerPanel.getTop(); - y = midField - 0.5f; - float adjustY = Forge.isLandscapeMode() ? y + 1f : midField; - float adjustH = Forge.isLandscapeMode() ? playerPanel.getField().getBottom() - 1f : playerPanel.getBottom() - 1f; - - if(playerPanel.getPlayer().getHasPriority()) - g.setAlphaComposite(0.8f); - else - g.setAlphaComposite(0f); - - if(game!= null) { - if(combat!=null) { - //hide rectangle - if(playerPanel.getPlayer() == currentPlayer) - g.setAlphaComposite(0.8f); - else - g.setAlphaComposite(0f); - //color rectangle - if(playerPanel.getPlayer() == game.getPlayerTurn()) - color = Color.RED; //attacking player - else - color = Color.LIME; //defending player - } else { - color = Color.CYAN; - } - } - g.drawRect(4f, color, playerPanel.getField().getLeft(), adjustY, playerPanel.getField().getWidth(), adjustH); - g.setAlphaComposite(oldAlphaComposite); - } - } - } - - protected ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) { - float totalHeight = visibleHeight + extraHeight; - float avatarHeight = VAvatar.HEIGHT; - if (is4Player() || is3Player()){ - avatarHeight *= 0.5f; - } - float playerCount = getPlayerPanels().keySet().size(); - - if (Forge.isLandscapeMode() && playerCount == 2) { - // Ensure that players have equal player panel heights in two player Forge in Landscape mode - float topPlayerPanelHeight = totalHeight / 2; - float bottomPlayerPanelHeight = topPlayerPanelHeight; - topPlayerPanel.setBounds(0, 0, visibleWidth, topPlayerPanelHeight); - bottomPlayerPanel.setBounds(0, totalHeight - bottomPlayerPanelHeight, visibleWidth, bottomPlayerPanelHeight); - } else { - // Determine player panel heights based on visibility of zone displays - float cardRowsHeight = totalHeight - playerCount * avatarHeight; - float totalCardRows = 0; - for (VPlayerPanel playerPanel : playerPanelsList) { - if (playerPanel.getSelectedTab() != null) { - totalCardRows += 1; - } - totalCardRows += 2; - } - float y = 0; - for (VPlayerPanel playerPanel : playerPanelsList) { - float panelHeight; - if (playerPanel.getSelectedTab() != null) { - panelHeight = cardRowsHeight * 3f / totalCardRows; - } else { - panelHeight = cardRowsHeight * 2f / totalCardRows; - } - panelHeight += avatarHeight; - playerPanel.setBounds(0, y, visibleWidth, panelHeight); - y += panelHeight; - } - } - - return new ScrollBounds(visibleWidth, totalHeight); - } - - @Override - public boolean zoom(float x, float y, float amount) { - //adjust position for current scroll positions - float staticHeight = 2 * VAvatar.HEIGHT; //take out avatar rows that don't scale - float oldScrollHeight = getScrollHeight() - staticHeight; - float oldScrollTop = getScrollTop(); - y += oldScrollTop - VAvatar.HEIGHT; - - //build map of all horizontal scroll panes and their current scrollWidths and adjusted X values - Map> horzScrollPanes = new HashMap<>(); - backupHorzScrollPanes(topPlayerPanel, x, horzScrollPanes); - backupHorzScrollPanes(bottomPlayerPanel, x, horzScrollPanes); - - float zoom = oldScrollHeight / (getHeight() - staticHeight); - extraHeight += amount * zoom; //scale amount by current zoom - if (extraHeight < 0) { - extraHeight = 0; - } - revalidate(); //apply change in height to all scroll panes - - //adjust scroll top to keep y position the same - float newScrollHeight = getScrollHeight() - staticHeight; - float ratio = newScrollHeight / oldScrollHeight; - float yAfter = y * ratio; - setScrollTop(oldScrollTop + yAfter - y); - - //adjust scroll left of all horizontal scroll panes to keep x position the same - float startX = x; - for (Entry> entry : horzScrollPanes.entrySet()) { - FScrollPane horzScrollPane = entry.getKey(); - float oldScrollLeft = entry.getValue().getLeft(); - x = startX + oldScrollLeft; - float xAfter = x * ratio; - horzScrollPane.setScrollLeft(oldScrollLeft + xAfter - x); - } - - return true; - } - - private void backupHorzScrollPanes(VPlayerPanel playerPanel, float x, Map> horzScrollPanes) { - backupHorzScrollPane(playerPanel.getField().getRow1(), x, horzScrollPanes); - backupHorzScrollPane(playerPanel.getField().getRow2(), x, horzScrollPanes); - for (InfoTab tab : playerPanel.getTabs()) { - if (tab.getDisplayArea() instanceof VManaPool) { - continue; //don't include Mana pool in this - } - backupHorzScrollPane(tab.getDisplayArea(), x, horzScrollPanes); - } - backupHorzScrollPane(playerPanel.getCommandZone(), x, horzScrollPanes); - } - private void backupHorzScrollPane(FScrollPane scrollPane, float x, Map> horzScrollPanes) { - horzScrollPanes.put(scrollPane, Pair.of(scrollPane.getScrollLeft(), scrollPane.getScrollWidth())); - } - private String getPlaneName(){ return MatchController.instance.getGameView().getPlanarPlayer().getCurrentPlaneName(); } - private boolean hasActivePlane(){ - if(MatchController.instance.getGameView() != null) - if(MatchController.instance.getGameView().getPlanarPlayer() != null) { - return !MatchController.instance.getGameView().getPlanarPlayer().getCurrentPlaneName().equals(""); - } - return false; - } - private int countHuman(){ - int humanplayers = 0; - for (VPlayerPanel playerPanel: playerPanelsList) { - if(!playerPanel.getPlayer().isAI()) - humanplayers++; - } - return humanplayers; - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/TargetingOverlay.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/TargetingOverlay.java deleted file mode 100644 index 98796fd9ef5..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/TargetingOverlay.java +++ /dev/null @@ -1,121 +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.adventure.libgdxgui.screens.match; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.math.Vector2; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.game.card.CardView; -import forge.game.player.PlayerView; -import forge.adventure.libgdxgui.screens.match.views.VCardDisplayArea.CardAreaPanel; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.util.Utils; - -public class TargetingOverlay { - private static final float BORDER_THICKNESS = Utils.scale(1); - private static final float ARROW_THICKNESS = Utils.scale(5); - private static final float ARROW_SIZE = 3 * ARROW_THICKNESS; - private static FSkinColor friendColor, foeAtkColor, foeDefColor; - - public enum ArcConnection { - Friends, - FoesAttacking, - FoesBlocking, - FriendsStackTargeting, - FoesStackTargeting - } - - public static void updateColors() { - friendColor = FSkinColor.get(Colors.CLR_NORMAL_TARGETING_ARROW); - if (friendColor.getAlpha() == 0) { - friendColor = FSkinColor.get(Colors.CLR_ACTIVE).alphaColor(153f / 255f); - } - - foeDefColor = FSkinColor.get(Colors.CLR_COMBAT_TARGETING_ARROW); - if (foeDefColor.getAlpha() == 0) { - foeDefColor = FSkinColor.getStandardColor(new Color(1, 0, 0, 153 / 255f)); - } - - foeAtkColor = FSkinColor.get(Colors.CLR_PWATTK_TARGETING_ARROW); - if (foeAtkColor.getAlpha() == 0) { - foeAtkColor = FSkinColor.getStandardColor(new Color(255 / 255f, 138 / 255f, 1 / 255f, 153 / 255f)); - } - } - - private TargetingOverlay() { - } - - public static void drawArrow(Graphics g, CardView startCard, CardView endCard) { - ArcConnection connects; - if (startCard.getOwner().isOpponentOf((endCard.getOwner()))) { - if (startCard.isAttacking()) { - connects = ArcConnection.FoesAttacking; - } else { - connects = ArcConnection.FoesBlocking; - } - } else { - connects = ArcConnection.Friends; - } - - drawArrow(g, CardAreaPanel.get(startCard).getTargetingArrowOrigin(), - CardAreaPanel.get(endCard).getTargetingArrowOrigin(), - connects); - } - public static void drawArrow(Graphics g, CardView startCard, PlayerView targetPlayer, int numplayers) { - drawArrow(g, CardAreaPanel.get(startCard).getTargetingArrowOrigin(), - MatchController.getView().getPlayerPanel(targetPlayer).getAvatar().getTargetingArrowOrigin(numplayers), - ArcConnection.FoesAttacking); - } - public static void drawArrow(Graphics g, Vector2 start, CardView targetCard, ArcConnection connects) { - drawArrow(g, start, - CardAreaPanel.get(targetCard).getTargetingArrowOrigin(), - connects); - } - public static void drawArrow(Graphics g, Vector2 start, PlayerView targetPlayer, ArcConnection connects) { - drawArrow(g, start, - MatchController.getView().getPlayerPanel(targetPlayer).getAvatar().getTargetingArrowOrigin(), - connects); - } - public static void drawArrow(Graphics g, FDisplayObject startCardDisplay, FDisplayObject endCardDisplay, ArcConnection connects) { - drawArrow(g, CardAreaPanel.getTargetingArrowOrigin(startCardDisplay, false), - CardAreaPanel.getTargetingArrowOrigin(endCardDisplay, false), - connects); - } - public static void drawArrow(Graphics g, Vector2 start, Vector2 end, ArcConnection connects) { - if (start == null || end == null) { return; } - - FSkinColor color = foeDefColor; - - switch (connects) { - case Friends: - case FriendsStackTargeting: - color = friendColor; - break; - case FoesAttacking: - color = foeAtkColor; - break; - case FoesBlocking: - case FoesStackTargeting: - color = foeDefColor; - } - - g.drawArrow(BORDER_THICKNESS, ARROW_THICKNESS, ARROW_SIZE, color, start.x, start.y, end.x, end.y); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VAssignCombatDamage.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VAssignCombatDamage.java deleted file mode 100644 index 088eb598071..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VAssignCombatDamage.java +++ /dev/null @@ -1,468 +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.adventure.libgdxgui.screens.match.views; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FImage; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.FSkinImage; -import forge.adventure.libgdxgui.card.CardZoom; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.toolbox.*; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.util.Utils; -import forge.game.GameEntityView; -import forge.game.card.CardView; -import forge.game.card.CounterEnumType; -import forge.game.player.PlayerView; -import forge.util.*; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class VAssignCombatDamage extends FDialog { - private static final float CARD_GAP_X = Utils.scale(10); - private static final float ADD_BTN_HEIGHT = Utils.AVG_FINGER_HEIGHT * 0.75f; - - private final Callback> callback; - private final int totalDamageToAssign; - - private boolean attackerHasDeathtouch = false; - private boolean attackerHasDivideDamage = false; - private boolean attackerHasTrample = false; - private boolean attackerHasInfect = false; - private boolean overrideCombatantOrder = false; - - private final GameEntityView defender; - - private final FLabel lblTotalDamage = add(new FLabel.Builder().text(Localizer.getInstance().getMessage("lblTotalDamageText")).align(Align.center).build()); - private final FLabel lblAssignRemaining = add(new FLabel.Builder().text(Localizer.getInstance().getMessage("lblAssignRemainingText")).align(Align.center).build()); - - private final AttDefCardPanel pnlAttacker; - private final DefendersPanel pnlDefenders; - - // Indexes of defenders correspond to their indexes in the damage list and labels. - private final List defenders = new ArrayList<>(); // NULL in this map means defender - private final Map damage = new HashMap<>(); // NULL in this map means defender - - private boolean canAssignTo(CardView card) { - for (DamageTarget dt : defenders) { - if (dt.card == card) { return true; } - if (getDamageToKill(dt.card) > dt.damage) { - return false; - } - } - throw new RuntimeException("Asking to assign damage to object which is not present in defenders list"); - } - - /** Constructor. - * - * @param attacker {@link forge.game.card.Card} - * @param blockers List<{@link forge.game.card.Card}> - * @param damage0 int - * @param defender0 GameEntity that's bein attacked - * @param overrideOrder override combatant order - */ - public VAssignCombatDamage(final CardView attacker, final List blockers, final int damage0, final GameEntityView defender0, boolean overrideOrder, final WaitCallback> waitCallback) { - super(Localizer.getInstance().getMessage("lbLAssignDamageDealtBy").replace("%s",CardTranslation.getTranslatedName(attacker.getName())) , 3); - - callback = waitCallback; - totalDamageToAssign = damage0; - defender = defender0; - attackerHasDeathtouch = attacker.getCurrentState().hasDeathtouch(); - attackerHasDivideDamage = attacker.getCurrentState().hasDivideDamage(); - attackerHasInfect = attacker.getCurrentState().hasInfect(); - attackerHasTrample = defender != null && attacker.getCurrentState().hasTrample(); - overrideCombatantOrder = overrideOrder; - - pnlAttacker = add(new AttDefCardPanel(attacker)); - pnlDefenders = add(new DefendersPanel(blockers)); - - initButton(0, Localizer.getInstance().getMessage("lblAuto"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - resetAssignedDamage(); - initialAssignDamage(true); - finish(); - } - }); - initButton(1, Localizer.getInstance().getMessage("lblOK"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - finish(); - } - }); - initButton(2, Localizer.getInstance().getMessage("lblReset"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - resetAssignedDamage(); - initialAssignDamage(false); - } - }); - - initialAssignDamage(false); - } - - @Override - protected float layoutAndGetHeight(float width, float maxHeight) { - float padding = FOptionPane.PADDING; - float w = width - 2 * padding; - - float x = padding; - float labelHeight = lblAssignRemaining.getAutoSizeBounds().height; - float y = maxHeight - labelHeight + padding; - lblAssignRemaining.setBounds(x, y, w, labelHeight); - - float dtOffset = ADD_BTN_HEIGHT + defenders.get(0).label.getAutoSizeBounds().height; - float cardPanelHeight = (y - dtOffset - labelHeight - 3 * padding) / 2; - float cardPanelWidth = cardPanelHeight / FCardPanel.ASPECT_RATIO; - - y = padding; - pnlAttacker.setBounds(x + (w - cardPanelWidth) / 2, y, cardPanelWidth, cardPanelHeight); - - y += cardPanelHeight + padding; - lblTotalDamage.setBounds(x, y, w, labelHeight); - - y += labelHeight + padding; - pnlDefenders.setBounds(0, y, width, cardPanelHeight + dtOffset); - - return maxHeight; - } - - private class DefendersPanel extends FScrollPane { - private DefendersPanel(final List defenderCards) { - for (final CardView c : defenderCards) { - addDamageTarget(c); - } - - if (attackerHasTrample || (attackerHasDivideDamage && overrideCombatantOrder)) { - //add damage target for target of attack that trample damage will go through to - addDamageTarget(null); - } - } - - private void addDamageTarget(CardView card) { - DamageTarget dt = add(new DamageTarget(card)); - damage.put(card, dt); - defenders.add(dt); - } - - @Override - protected ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) { - float cardPanelHeight = visibleHeight - ADD_BTN_HEIGHT - defenders.get(0).label.getAutoSizeBounds().height; - float width = cardPanelHeight / FCardPanel.ASPECT_RATIO; - float dx = width + CARD_GAP_X; - - float x = (visibleWidth - defenders.size() * dx + CARD_GAP_X) / 2; - if (x < FOptionPane.PADDING) { - x = FOptionPane.PADDING; - } - - for (DamageTarget dt : defenders) { - dt.setBounds(x, 0, width, visibleHeight); - x += dx; - } - return new ScrollBounds(x - CARD_GAP_X + FOptionPane.PADDING, visibleHeight); - } - } - - private class DamageTarget extends FContainer { - private final CardView card; - private final FDisplayObject obj; - private final FLabel label, btnSubtract, btnAdd; - private int damage; - - public DamageTarget(CardView card0) { - card = card0; - if (card != null) { - obj = add(new AttDefCardPanel(card)); - } - else if (defender instanceof CardView) { - obj = add(new AttDefCardPanel((CardView)defender)); - } - else if (defender instanceof PlayerView) { - PlayerView player = (PlayerView)defender; - obj = add(new MiscAttDefPanel(player.getName(), MatchController.getPlayerAvatar(player))); - } - else { - obj = add(new MiscAttDefPanel(defender.toString(), FSkinImage.UNKNOWN)); - } - label = add(new FLabel.Builder().text("0").font(FSkinFont.get(18)).align(Align.center).build()); - btnSubtract = add(new FLabel.ButtonBuilder().icon(FSkinImage.MINUS).command(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - assignDamageTo(card, false); - } - }).build()); - btnAdd = add(new FLabel.ButtonBuilder().icon(Forge.hdbuttons ? FSkinImage.HDPLUS : FSkinImage.PLUS).command(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - assignDamageTo(card, true); - } - }).build()); - } - - @Override - protected void doLayout(float width, float height) { - float y = 0; - obj.setBounds(0, y, width, FCardPanel.ASPECT_RATIO * width); - y += obj.getHeight(); - - label.setBounds(0, y, width, label.getAutoSizeBounds().height); - y += label.getHeight(); - - float buttonSize = (width - FOptionPane.PADDING) / 2; - btnSubtract.setBounds(0, y, buttonSize, ADD_BTN_HEIGHT); - btnAdd.setBounds(width - buttonSize, y, buttonSize, ADD_BTN_HEIGHT); - } - } - - private static class AttDefCardPanel extends FCardPanel { - private AttDefCardPanel(CardView card) { - super(card); - } - - @Override - public boolean tap(float x, float y, int count) { - CardZoom.show(getCard()); - return true; - } - - @Override - public boolean longPress(float x, float y) { - CardZoom.show(getCard()); - return true; - } - - @Override - protected float getPadding() { - return 0; - } - } - - private static class MiscAttDefPanel extends FDisplayObject { - private static final FSkinFont FONT = FSkinFont.get(18); - private static final FSkinColor FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT); - private final String name; - private final FImage image; - - private MiscAttDefPanel(String name0, FImage image0) { - name = name0; - image = image0; - } - - @Override - public void draw(Graphics g) { - float w = getWidth(); - float h = getHeight(); - g.drawImage(image, 0, 0, w, w); - g.drawText(name, FONT, FORE_COLOR, 0, w, w, h - w, false, Align.center, true); - } - } - - private void assignDamageTo(CardView source, boolean isAdding) { - if (!damage.containsKey(source)) { - source = null; - } - - // If trying to assign to the defender, follow the normal assignment rules - // No need to check for "active" creature assignee when overiding combatant order - if (!attackerHasDivideDamage) { // Creatures with this can assign to defender - if ((source == null || source == defender || !overrideCombatantOrder) && isAdding && !canAssignTo(source)) { - return; - } - } - - // If lethal damage has already been assigned just act like it's 0. - int lethalDamage = getDamageToKill(source); - int damageItHad = damage.get(source).damage; - - int damageToAdd = isAdding ? 1 : -1; - - int leftToAssign = getRemainingDamage(); - - if (damageToAdd > leftToAssign) { - damageToAdd = leftToAssign; - } - - // cannot assign first blocker less than lethal damage except when overriding order - boolean isFirstBlocker = defenders.get(0).card == source; - if (!overrideCombatantOrder && isFirstBlocker && damageToAdd + damageItHad < lethalDamage) { - return; - } - - if (damageToAdd == 0 || damageToAdd + damageItHad < 0) { - return; - } - - addDamage(source, damageToAdd); - checkDamageQueue(); - updateLabels(); - } - - private void checkDamageQueue() { - if (overrideCombatantOrder && attackerHasDivideDamage) { - return; - } - // Clear out any Damage that shouldn't be assigned to other combatants - boolean hasAliveEnemy = false; - for (DamageTarget dt : defenders) { - int lethal = getDamageToKill(dt.card); - int damage = dt.damage; - // If overriding combatant order, make sure everything has lethal if defender has damage assigned to it - // Otherwise, follow normal combatant order - if (hasAliveEnemy && (!overrideCombatantOrder || dt.card == null || dt.card == defender)) { - dt.damage = 0; - } - else { - hasAliveEnemy |= damage < lethal; - } - } - } - - // will assign all damage to defenders and rest to player, if present - private void initialAssignDamage(boolean toAllBlockers) { - if (!toAllBlockers && overrideCombatantOrder) { - // Don't auto assign the first damage when overriding combatant order - updateLabels(); - return; - } - - int dmgLeft = totalDamageToAssign; - DamageTarget dtLast = null; - for(DamageTarget dt : defenders) { // MUST NOT RUN WITH EMPTY collection - int lethal = getDamageToKill(dt.card); - int damage = Math.min(lethal, dmgLeft); - addDamage(dt.card, damage); - dmgLeft -= damage; - dtLast = dt; - if (dmgLeft <= 0 || !toAllBlockers) { break; } - } - if (dmgLeft < 0) { - throw new RuntimeException("initialAssignDamage managed to assign more damage than it could"); - } - if (toAllBlockers && dmgLeft > 0) { - // flush the remaining damage into last defender if assigning all damage - addDamage(dtLast.card, dmgLeft); - } - updateLabels(); - } - - /** Reset Assign Damage back to how it was at the beginning. */ - private void resetAssignedDamage() { - for (DamageTarget dt : defenders) { - dt.damage = 0; - } - } - - private void addDamage(final CardView card, int addedDamage) { - // If we don't have enough left or we're trying to unassign too much return - int canAssign = getRemainingDamage(); - if (canAssign < addedDamage) { - addedDamage = canAssign; - } - - DamageTarget dt = damage.get(card); - dt.damage = Math.max(0, addedDamage + dt.damage); - } - - private int getRemainingDamage() { - int spent = 0; - for (DamageTarget dt : defenders) { - spent += dt.damage; - } - return totalDamageToAssign - spent; - } - - /** Updates labels and other UI elements. - **/ - private void updateLabels() { - int damageLeft = totalDamageToAssign; - boolean allHaveLethal = true; - - for (DamageTarget dt : defenders) { - int dmg = dt.damage; - damageLeft -= dmg; - int lethal = getDamageToKill(dt.card); - int overkill = dmg - lethal; - StringBuilder sb = new StringBuilder(); - sb.append(dmg); - if(overkill >= 0) { - sb.append(" (" + Localizer.getInstance().getMessage("lblLethal")); - if(overkill > 0) - sb.append(" +").append(overkill); - sb.append(")"); - } - allHaveLethal &= dmg >= lethal; - dt.label.setText(sb.toString()); - } - - lblTotalDamage.setText(TextUtil.concatNoSpace(Localizer.getInstance().getMessage("lblAvailableDamagePoints") + ": ", - String.valueOf(damageLeft), " (of ", String.valueOf(totalDamageToAssign), ")")); - setButtonEnabled(1, damageLeft == 0); - lblAssignRemaining.setVisible(allHaveLethal && damageLeft > 0); - } - - // Dumps damage onto cards. Damage must be stored first, because if it is - // assigned dynamically, the cards die off and further damage to them can't - // be modified. - private void finish() { - if (getRemainingDamage() > 0) { - return; - } - hide(); - callback.run(getDamageMap()); - } - - private int getDamageToKill(CardView source) { - int lethalDamage = 0; - if (source == null) { - if (defender instanceof PlayerView) { - PlayerView p = (PlayerView)defender; - lethalDamage = attackerHasInfect ? MatchController.instance.getGameView().getPoisonCountersToLose() - p.getCounters(CounterEnumType.POISON) : p.getLife(); - } - else if (defender instanceof CardView) { // planeswalker - CardView pw = (CardView)defender; - lethalDamage = Integer.valueOf(pw.getCurrentState().getLoyalty()); - } - } - else { - lethalDamage = Math.max(0, source.getLethalDamage()); - if (source.getCurrentState().getType().isPlaneswalker()) { - lethalDamage = Integer.valueOf(source.getCurrentState().getLoyalty()); - } else if (attackerHasDeathtouch) { - lethalDamage = Math.min(lethalDamage, 1); - } - } - return lethalDamage; - } - - public Map getDamageMap() { - Map result = new HashMap<>(); - for (DamageTarget dt : defenders) { - result.put(dt.card, dt.damage); - } - return result; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VAssignGenericAmount.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VAssignGenericAmount.java deleted file mode 100644 index b8a46089aea..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VAssignGenericAmount.java +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2021 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.adventure.libgdxgui.screens.match.views; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FImage; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.FSkinImage; -import forge.adventure.libgdxgui.card.CardZoom; -import forge.card.MagicColor; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.toolbox.*; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.util.Utils; -import forge.game.card.CardView; -import forge.game.player.PlayerView; -import forge.util.*; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class VAssignGenericAmount extends FDialog { - private static final float CARD_GAP_X = Utils.scale(10); - private static final float ADD_BTN_HEIGHT = Utils.AVG_FINGER_HEIGHT * 0.75f; - - private final Callback> callback; - private final int totalAmountToAssign; - - private final String lblAmount; - private final FLabel lblTotalAmount; - private final boolean atLeastOne; - - private final EffectSourcePanel pnlSource; - private final TargetsPanel pnlTargets; - - private final List targetsList = new ArrayList<>(); - private final Map targetsMap = new HashMap<>(); - - /** Constructor. - * - * @param effectSource {@link forge.game.card.Card} - * @param targets Map, map of GameEntity and its maximum assignable amount - * @param amount Total amount to be assigned - * @param atLeastOne Must assign at least one amount to each target - */ - public VAssignGenericAmount(final CardView effectSource, final Map targets, final int amount, final boolean atLeastOne, final String amountLabel, final WaitCallback> waitCallback) { - super(Localizer.getInstance().getMessage("lbLAssignAmountForEffect", amountLabel, CardTranslation.getTranslatedName(effectSource.getName())) , 2); - - callback = waitCallback; - totalAmountToAssign = amount; - this.atLeastOne = atLeastOne; - - lblAmount = amountLabel; - lblTotalAmount = add(new FLabel.Builder().text(Localizer.getInstance().getMessage("lblTotalAmountText", lblAmount)).align(Align.center).build()); - - pnlSource = add(new EffectSourcePanel(effectSource)); - pnlTargets = add(new TargetsPanel(targets)); - - initButton(0, Localizer.getInstance().getMessage("lblOK"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - finish(); - } - }); - initButton(1, Localizer.getInstance().getMessage("lblReset"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - resetAssignedDamage(); - initialAssignAmount(); - } - }); - - initialAssignAmount(); - } - - @Override - protected float layoutAndGetHeight(float width, float maxHeight) { - float padding = FOptionPane.PADDING; - float w = width - 2 * padding; - - float x = padding; - float labelHeight = lblTotalAmount.getAutoSizeBounds().height; - float y = maxHeight - labelHeight + padding; - - float dtOffset = ADD_BTN_HEIGHT + targetsList.get(0).label.getAutoSizeBounds().height; - float cardPanelHeight = (y - dtOffset - labelHeight - 3 * padding) / 2; - float cardPanelWidth = cardPanelHeight / FCardPanel.ASPECT_RATIO; - - y = padding; - pnlSource.setBounds(x + (w - cardPanelWidth) / 2, y, cardPanelWidth, cardPanelHeight); - - y += cardPanelHeight + padding; - lblTotalAmount.setBounds(x, y, w, labelHeight); - - y += labelHeight + padding; - pnlTargets.setBounds(0, y, width, cardPanelHeight + dtOffset); - - return maxHeight; - } - - private class TargetsPanel extends FScrollPane { - private TargetsPanel(final Map targets) { - for (final Map.Entry e : targets.entrySet()) { - addDamageTarget(e.getKey(), e.getValue()); - } - } - - private void addDamageTarget(Object entity, int max) { - AssignTarget at = add(new AssignTarget(entity, max)); - targetsMap.put(entity, at); - targetsList.add(at); - } - - @Override - protected ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) { - float cardPanelHeight = visibleHeight - ADD_BTN_HEIGHT - targetsList.get(0).label.getAutoSizeBounds().height; - float width = cardPanelHeight / FCardPanel.ASPECT_RATIO; - float dx = width + CARD_GAP_X; - - float x = (visibleWidth - targetsList.size() * dx + CARD_GAP_X) / 2; - if (x < FOptionPane.PADDING) { - x = FOptionPane.PADDING; - } - - for (AssignTarget at : targetsList) { - at.setBounds(x, 0, width, visibleHeight); - x += dx; - } - return new ScrollBounds(x - CARD_GAP_X + FOptionPane.PADDING, visibleHeight); - } - } - - private class AssignTarget extends FContainer { - private final Object entity; - private final FDisplayObject obj; - private final FLabel label, btnSubtract, btnAdd; - private final int max; - private int amount; - - public AssignTarget(Object entity0, int max0) { - entity = entity0; - max = max0; - if (entity instanceof CardView) { - obj = add(new EffectSourcePanel((CardView)entity)); - } else if (entity instanceof PlayerView) { - PlayerView player = (PlayerView)entity; - obj = add(new MiscTargetPanel(player.getName(), MatchController.getPlayerAvatar(player))); - } else if (entity instanceof Byte) { - FSkinImage manaSymbol; - Byte color = (Byte) entity; - if (color == MagicColor.WHITE) { - manaSymbol = FSkinImage.MANA_W; - } else if (color == MagicColor.BLUE) { - manaSymbol = FSkinImage.MANA_U; - } else if (color == MagicColor.BLACK) { - manaSymbol = FSkinImage.MANA_B; - } else if (color == MagicColor.RED) { - manaSymbol = FSkinImage.MANA_R; - } else if (color == MagicColor.GREEN) { - manaSymbol = FSkinImage.MANA_G; - } else { // Should never come here, but add this to avoid compile error - manaSymbol = FSkinImage.MANA_COLORLESS; - } - obj = add(new MiscTargetPanel("", manaSymbol)); - } else { - obj = add(new MiscTargetPanel(entity.toString(), FSkinImage.UNKNOWN)); - } - label = add(new FLabel.Builder().text("0").font(FSkinFont.get(18)).align(Align.center).build()); - btnSubtract = add(new FLabel.ButtonBuilder().icon(FSkinImage.MINUS).command(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - assignAmountTo(entity, false); - } - }).build()); - btnAdd = add(new FLabel.ButtonBuilder().icon(Forge.hdbuttons ? FSkinImage.HDPLUS : FSkinImage.PLUS).command(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - assignAmountTo(entity, true); - } - }).build()); - } - - @Override - protected void doLayout(float width, float height) { - float y = 0; - obj.setBounds(0, y, width, FCardPanel.ASPECT_RATIO * width); - y += obj.getHeight(); - - label.setBounds(0, y, width, label.getAutoSizeBounds().height); - y += label.getHeight(); - - float buttonSize = (width - FOptionPane.PADDING) / 2; - btnSubtract.setBounds(0, y, buttonSize, ADD_BTN_HEIGHT); - btnAdd.setBounds(width - buttonSize, y, buttonSize, ADD_BTN_HEIGHT); - } - } - - private static class EffectSourcePanel extends FCardPanel { - private EffectSourcePanel(CardView card) { - super(card); - } - - @Override - public boolean tap(float x, float y, int count) { - CardZoom.show(getCard()); - return true; - } - - @Override - public boolean longPress(float x, float y) { - CardZoom.show(getCard()); - return true; - } - - @Override - protected float getPadding() { - return 0; - } - } - - private static class MiscTargetPanel extends FDisplayObject { - private static final FSkinFont FONT = FSkinFont.get(18); - private static final FSkinColor FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT); - private final String name; - private final FImage image; - - private MiscTargetPanel(String name0, FImage image0) { - name = name0; - image = image0; - } - - @Override - public void draw(Graphics g) { - float w = getWidth(); - float h = getHeight(); - g.drawImage(image, 0, 0, w, w); - g.drawText(name, FONT, FORE_COLOR, 0, w, w, h - w, false, Align.center, true); - } - } - - private void assignAmountTo(Object source, boolean isAdding) { - AssignTarget at = targetsMap.get(source); - int assigned = at.amount; - int leftToAssign = Math.max(0, at.max - assigned); - int amountToAdd = isAdding ? 1 : -1; - int remainingAmount = Math.min(getRemainingAmount(), leftToAssign); - - if (amountToAdd > remainingAmount) { - amountToAdd = remainingAmount; - } - if (atLeastOne && assigned + amountToAdd < 1) { - amountToAdd = 1 - assigned; - } - - if (0 == amountToAdd || amountToAdd + assigned < 0) { - return; - } - - addAssignedAmount(at, amountToAdd); - updateLabels(); - } - - private void initialAssignAmount() { - if (!atLeastOne) { - updateLabels(); - return; - } - - for(AssignTarget at : targetsList) { - addAssignedAmount(at, 1); - } - updateLabels(); - } - - private void resetAssignedDamage() { - for (AssignTarget at : targetsList) { - at.amount = 0; - } - } - - private void addAssignedAmount(final AssignTarget at, int addedAmount) { - // If we don't have enough left or we're trying to unassign too much return - int canAssign = getRemainingAmount(); - if (canAssign < addedAmount) { - addedAmount = canAssign; - } - - at.amount = Math.max(0, addedAmount + at.amount); - } - - private int getRemainingAmount() { - int spent = 0; - for (AssignTarget at : targetsList) { - spent += at.amount; - } - return totalAmountToAssign - spent; - } - - /** Updates labels and other UI elements.*/ - private void updateLabels() { - int amountLeft = totalAmountToAssign; - - for (AssignTarget at : targetsList) { - amountLeft -= at.amount; - StringBuilder sb = new StringBuilder(); - sb.append(at.amount); - if (at.max - at.amount == 0) { - sb.append(" (").append(Localizer.getInstance().getMessage("lblMax")).append(")"); - } - at.label.setText(sb.toString()); - } - - lblTotalAmount.setText(TextUtil.concatNoSpace(Localizer.getInstance().getMessage("lblAvailableAmount", lblAmount) + ": ", - String.valueOf(amountLeft), " (of ", String.valueOf(totalAmountToAssign), ")")); - setButtonEnabled(0, amountLeft == 0); - } - - // Dumps damage onto cards. Damage must be stored first, because if it is - // assigned dynamically, the cards die off and further damage to them can't - // be modified. - private void finish() { - if (getRemainingAmount() > 0) { - return; - } - hide(); - callback.run(getAssignedMap()); - } - - public Map getAssignedMap() { - Map result = new HashMap<>(targetsList.size()); - for (AssignTarget at : targetsList) - result.put(at.entity, at.amount); - return result; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VAutoYields.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VAutoYields.java deleted file mode 100644 index ce4a58ff28d..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VAutoYields.java +++ /dev/null @@ -1,93 +0,0 @@ -package forge.adventure.libgdxgui.screens.match.views; - -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.toolbox.*; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.util.Localizer; -import forge.adventure.libgdxgui.util.TextBounds; - -import java.util.ArrayList; -import java.util.List; - -public class VAutoYields extends FDialog { - private final FChoiceList lstAutoYields; - private final FCheckBox chkDisableAll; - - public VAutoYields() { - super(Localizer.getInstance().getMessage("lblAutoYields"), 2); - List autoYields = new ArrayList<>(); - for (String autoYield : MatchController.instance.getAutoYields()) { - autoYields.add(autoYield); - } - lstAutoYields = add(new FChoiceList(autoYields) { - @Override - protected void onCompactModeChange() { - VAutoYields.this.revalidate(); //revalidate entire dialog so height updated - } - - @Override - protected boolean allowDefaultItemWrap() { - return true; - } - }); - chkDisableAll = add(new FCheckBox(Localizer.getInstance().getMessage("lblDisableAllAutoYields"), MatchController.instance.getDisableAutoYields())); - chkDisableAll.setCommand(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - MatchController.instance.setDisableAutoYields(chkDisableAll.isSelected()); - } - }); - initButton(0, Localizer.getInstance().getMessage("lblOK"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - hide(); - } - }); - initButton(1, Localizer.getInstance().getMessage("lblRemoveYield"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - String selected = lstAutoYields.getSelectedItem(); - if (selected != null) { - lstAutoYields.removeItem(selected); - MatchController.instance.setShouldAutoYield(selected, false); - setButtonEnabled(1, lstAutoYields.getCount() > 0); - lstAutoYields.cleanUpSelections(); - VAutoYields.this.revalidate(); - } - } - }); - setButtonEnabled(1, autoYields.size() > 0); - } - - @Override - public void show() { - if (lstAutoYields.getCount() > 0) { - super.show(); - } - else { - FOptionPane.showMessageDialog(Localizer.getInstance().getMessage("lblNoActiveAutoYield"), Localizer.getInstance().getMessage("lblNoAutoYield"), FOptionPane.INFORMATION_ICON); - } - } - - @Override - protected float layoutAndGetHeight(float width, float maxHeight) { - float padding = FOptionPane.PADDING; - float x = padding; - float y = padding; - float w = width - 2 * padding; - TextBounds checkBoxSize = chkDisableAll.getAutoSizeBounds(); - - float listHeight = lstAutoYields.getListItemRenderer().getItemHeight() * lstAutoYields.getCount(); - float maxListHeight = maxHeight - 3 * padding - checkBoxSize.height; - if (listHeight > maxListHeight) { - listHeight = maxListHeight; - } - - lstAutoYields.setBounds(x, y, w, listHeight); - y += listHeight + padding; - chkDisableAll.setBounds(x, y, Math.min(checkBoxSize.width, w), checkBoxSize.height); - y += checkBoxSize.height + padding; - - return y; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VAvatar.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VAvatar.java deleted file mode 100644 index fc9f94bc71e..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VAvatar.java +++ /dev/null @@ -1,84 +0,0 @@ -package forge.adventure.libgdxgui.screens.match.views; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FImage; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.game.card.CounterEnumType; -import forge.game.player.PlayerView; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.util.ThreadUtil; -import forge.adventure.libgdxgui.util.Utils; - -public class VAvatar extends FDisplayObject { - public static final float WIDTH = Utils.AVG_FINGER_WIDTH; - public static final float HEIGHT = Utils.AVG_FINGER_HEIGHT; - - private final PlayerView player; - private final FImage image; - - public VAvatar(PlayerView player0) { - player = player0; - image = MatchController.getPlayerAvatar(player); - setSize(WIDTH, HEIGHT); - } - - public VAvatar(PlayerView player0, float size) { - player = player0; - image = MatchController.getPlayerAvatar(player); - setSize(size, size); - } - - @Override - public boolean tap(float x, float y, int count) { - ThreadUtil.invokeInGameThread(new Runnable() { //must invoke in game thread in case a dialog needs to be shown - @Override - public void run() { - MatchController.instance.getGameController().selectPlayer(player, null); - } - }); - return true; - } - - public Vector2 getTargetingArrowOrigin() { - return getTargetingArrowOrigin(2); - } - public Vector2 getTargetingArrowOrigin(int numplayers) { - Vector2 origin = new Vector2(screenPos.x, screenPos.y); - - float modx = numplayers > 2 ? 0.25f : 0.75f; - - origin.x += WIDTH * modx; - if (origin.y < MatchController.getView().getHeight() / numplayers) { - origin.y += HEIGHT * 0.75f; //target bottom right corner if on top half of screen - } - else { - origin.y += HEIGHT * 0.25f; //target top right corner if on bottom half of screen - } - - return origin; - } - - @Override - public void draw(Graphics g) { - float w = getWidth(); - float h = getHeight(); - g.drawImage(image, 0, 0, w, h); - - if (Forge.altPlayerLayout && !Forge.altZoneTabs && Forge.isLandscapeMode()) - return; - - //display XP in lower right corner of avatar - int xp = player.getCounters(CounterEnumType.EXPERIENCE); - if (xp > 0) { - //use font and padding from phase indicator so text lines up - FSkinFont font = VPhaseIndicator.BASE_FONT; - float xpHeight = font.getCapHeight(); - g.drawOutlinedText(xp + " XP", font, Color.WHITE, Color.BLACK, 0, h - xpHeight - VPhaseIndicator.PADDING_Y, w - VPhaseIndicator.PADDING_X, h, false, Align.right, false); - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VCardDisplayArea.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VCardDisplayArea.java deleted file mode 100644 index 64524273a3e..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VCardDisplayArea.java +++ /dev/null @@ -1,486 +0,0 @@ -package forge.adventure.libgdxgui.screens.match.views; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.math.Vector2; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.card.CardRenderer.CardStackPosition; -import forge.adventure.libgdxgui.card.CardZoom; -import forge.adventure.libgdxgui.card.CardZoom.ActivateHandler; -import forge.game.card.CardView; -import forge.gui.FThreads; -import forge.gui.GuiBase; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.toolbox.FCardPanel; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.util.ThreadUtil; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public abstract class VCardDisplayArea extends VDisplayArea implements ActivateHandler { - private static final float CARD_STACK_OFFSET = 0.2f; - - protected final List orderedCards = new ArrayList<>(); - protected final List cardPanels = new ArrayList<>(); - private boolean rotateCards180; - - public Iterable getOrderedCards() { - return orderedCards; - } - - public Iterable getCardPanels() { - return cardPanels; - } - - @Override - public int getCount() { - return cardPanels.size(); - } - - @Override - public void setRotate180(boolean b0) { - //only rotate cards themselves - rotateCards180 = b0; - } - - protected void refreshCardPanels(Iterable model) { - clear(); - - CardAreaPanel newCardPanel = null; - if (model != null) { - for (CardView card : model) { - CardAreaPanel cardPanel = CardAreaPanel.get(card); - addCardPanelToDisplayArea(cardPanel); - cardPanels.add(cardPanel); - if (newCardPanel == null && !orderedCards.contains(card)) { - newCardPanel = cardPanel; - } - } - } - if (isVisible()) { //only revalidate if currently visible - revalidate(); - - if (newCardPanel != null) { //if new cards added, ensure first new card is scrolled into view - scrollIntoView(newCardPanel); - } - } - } - - @Override - public void setVisible(boolean b0) { - if (isVisible() == b0) { return; } - super.setVisible(b0); - if (b0) { //when zone becomes visible, ensure display area of panels is updated and panels layed out - for (CardAreaPanel pnl : cardPanels) { - pnl.displayArea = this; - } - revalidate(); - } - } - - //support adding card panel and attached panels to display area recursively - private void addCardPanelToDisplayArea(CardAreaPanel cardPanel) { - do { - List attachedPanels = cardPanel.getAttachedPanels(); - if (!attachedPanels.isEmpty()) { - for (int i = attachedPanels.size() - 1; i >= 0; i--) { - addCardPanelToDisplayArea(attachedPanels.get(i)); - } - } - - if (isVisible()) { //only set display area for card if area is visible - cardPanel.displayArea = this; - } - add(cardPanel); - - cardPanel = cardPanel.getNextPanelInStack(); - } while (cardPanel != null); - } - - public final void removeCardPanel(final CardAreaPanel fromPanel) { - FThreads.assertExecutedByEdt(true); - /*if (CardPanelContainer.this.getMouseDragPanel() != null) { - CardPanel.getDragAnimationPanel().setVisible(false); - CardPanel.getDragAnimationPanel().repaint(); - CardPanelContainer.this.getCardPanels().remove(CardPanel.getDragAnimationPanel()); - CardPanelContainer.this.remove(CardPanel.getDragAnimationPanel()); - CardPanelContainer.this.setMouseDragPanel(null); - }*/ - cardPanels.remove(fromPanel); - remove(fromPanel); - } - - protected void clearChildren() { - super.clear(); - } - - @Override - public void clear() { - super.clear(); - if (!cardPanels.isEmpty()) { - for (CardAreaPanel panel : cardPanels) { - if (panel.displayArea == null || panel.displayArea == this || - !panel.displayArea.cardPanels.contains(panel)) { //don't reset if panel's displayed in another area already - panel.reset(); - } - } - cardPanels.clear(); - } - } - - private final int addCards(CardAreaPanel cardPanel, float x, float y, float cardWidth, float cardHeight) { - int totalCount = 0; - List attachedPanels = cardPanel.getAttachedPanels(); - if (!attachedPanels.isEmpty()) { - for (int i = attachedPanels.size() - 1; i >= 0; i--) { - int count = addCards(attachedPanels.get(i), x, y, cardWidth, cardHeight); - x += count * cardWidth * CARD_STACK_OFFSET; - totalCount += count; - } - } - - orderedCards.add(cardPanel.getCard()); - cardPanel.setBounds(x, y, cardWidth, cardHeight); - - if (cardPanel.getNextPanelInStack() != null) { //add next panel in stack if needed - x += cardWidth * CARD_STACK_OFFSET; - totalCount += addCards(cardPanel.getNextPanelInStack(), x, y, cardWidth, cardHeight); - } - return totalCount + 1; - } - - protected float getCardWidth(float cardHeight) { - return (cardHeight - 2 * FCardPanel.PADDING) / FCardPanel.ASPECT_RATIO + 2 * FCardPanel.PADDING; //ensure aspect ratio maintained after padding applied - } - protected float getCardHeight(float cardWidth) { - return (cardWidth - 2 * FCardPanel.PADDING) * FCardPanel.ASPECT_RATIO + 2 * FCardPanel.PADDING; //ensure aspect ratio maintained after padding applied - } - - @Override - protected ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) { - orderedCards.clear(); - - float x = 0; - float y = 0; - float cardHeight = visibleHeight; - float cardWidth = getCardWidth(cardHeight); - - for (CardAreaPanel cardPanel : cardPanels) { - int count = addCards(cardPanel, x, y, cardWidth, cardHeight); - x += cardWidth + (count - 1) * cardWidth * CARD_STACK_OFFSET; - } - - return new ScrollBounds(x, visibleHeight); - } - - @Override - protected void startClip(Graphics g) { - //prevent clipping top and bottom - float h = getHeight(); - g.startClip(0, -h, getWidth(), 3 * h); - } - - @Override - public String getActivateAction(int index) { - if(!GuiBase.isNetworkplay()) //causes lag on netplay client side - return MatchController.instance.getGameController().getActivateDescription(orderedCards.get(index)); - - return "Activate | Cast | Play (if allowed)"; //simple text on card zoom swipe up - } - - @Override - public void setSelectedIndex(int index) { - //just scroll card into view - if (index < orderedCards.size()) { - final CardAreaPanel cardPanel = CardAreaPanel.get(orderedCards.get(index)); - scrollIntoView(cardPanel); - } - } - - @Override - public void activate(int index) { - final CardAreaPanel cardPanel = CardAreaPanel.get(orderedCards.get(index)); - ThreadUtil.invokeInGameThread(new Runnable() { //must invoke in game thread in case a dialog needs to be shown - @Override - public void run() { - cardPanel.selectCard(false); - } - }); - } - - public static class CardAreaPanel extends FCardPanel { - private static final Map allCardPanels = new HashMap<>(); - - public static CardAreaPanel get(CardView card0) { - CardAreaPanel cardPanel = allCardPanels.get(card0.getId()); - if (cardPanel == null || cardPanel.getCard() != card0) { //replace card panel if card copied - cardPanel = new CardAreaPanel(card0); - allCardPanels.put(card0.getId(), cardPanel); - } - return cardPanel; - } - - public static void resetForNewGame() { - for (CardAreaPanel cardPanel : allCardPanels.values()) { - cardPanel.displayArea = null; - cardPanel.attachedToPanel = null; - cardPanel.attachedPanels.clear(); - cardPanel.prevPanelInStack = null; - cardPanel.nextPanelInStack = null; - } - allCardPanels.clear(); - } - - private VCardDisplayArea displayArea; - private CardAreaPanel attachedToPanel; - private final List attachedPanels = new ArrayList<>(); - private CardAreaPanel nextPanelInStack, prevPanelInStack; - - //use static get(card) function instead - private CardAreaPanel(CardView card0) { - super(card0); - } - - public VCardDisplayArea getDisplayArea() { - return displayArea; - } - - public CardAreaPanel getAttachedToPanel() { - return attachedToPanel; - } - public void setAttachedToPanel(final CardAreaPanel attachedToPanel0) { - attachedToPanel = attachedToPanel0; - } - public List getAttachedPanels() { - return attachedPanels; - } - public CardAreaPanel getNextPanelInStack() { - return nextPanelInStack; - } - public void setNextPanelInStack(CardAreaPanel nextPanelInStack0) { - nextPanelInStack = nextPanelInStack0; - } - public CardAreaPanel getPrevPanelInStack() { - return prevPanelInStack; - } - public void setPrevPanelInStack(CardAreaPanel prevPanelInStack0) { - prevPanelInStack = prevPanelInStack0; - } - - @Override - protected CardStackPosition getStackPosition() { - if (nextPanelInStack == null && attachedToPanel == null) { - return CardStackPosition.Top; - } - if (isTapped()) { - return CardStackPosition.Top; //ensure P/T not hidden for tapped cards - } - return CardStackPosition.BehindHorz; - } - - public void updateCard(final CardView card) { - setTapped(card.isTapped()); - - attachedPanels.clear(); - - if (card.hasAnyCardAttachments()) { - final Iterable enchants = card.getAllAttachedCards(); - for (final CardView e : enchants) { - final CardAreaPanel cardE = CardAreaPanel.get(e); - if (cardE != null) { - attachedPanels.add(cardE); - } - } - } - - if (card.getAttachedTo() != null) { - setAttachedToPanel(CardAreaPanel.get(card.getAttachedTo())); - } - else { - setAttachedToPanel(null); - } - } - - //clear and reset all pointers from this panel - public void reset() { - if (!attachedPanels.isEmpty()) { - attachedPanels.clear(); - } - if (nextPanelInStack != null) { - nextPanelInStack.reset(); - nextPanelInStack = null; - } - attachedToPanel = null; - prevPanelInStack = null; - displayArea = null; - } - - @Override - public boolean tap(float x, float y, int count) { - if (renderedCardContains(x, y)) { - ThreadUtil.invokeInGameThread(new Runnable() { //must invoke in game thread in case a dialog needs to be shown - @Override - public void run() { - if (!selectCard(false)) { - //if no cards in stack can be selected, just show zoom/details for card - FThreads.invokeInEdtLater(new Runnable() { - @Override - public void run() { - showZoom(); - } - }); - } - } - }); - return true; - } - return false; - } - - @Override - public boolean flick(float x, float y) { - if (renderedCardContains(x, y)) { - ThreadUtil.invokeInGameThread(new Runnable() { //must invoke in game thread in case a dialog needs to be shown - @Override - public void run() { - selectCard(true); - } - }); - return true; - } - return false; - } - - public boolean selectCard(boolean selectEntireStack) { - if (MatchController.instance.getGameController().selectCard(getCard(), getOtherCardsToSelect(selectEntireStack), null)) { - Gdx.graphics.requestRendering(); - return true; - } - //if panel can't do anything with card selection, try selecting previous panel in stack - if (prevPanelInStack != null && prevPanelInStack.selectCard(selectEntireStack)) { - Gdx.graphics.requestRendering(); - return true; - } - //as a last resort try to select attached panels - for (CardAreaPanel panel : attachedPanels) { - if (panel.selectCard(selectEntireStack)) { - Gdx.graphics.requestRendering(); - return true; - } - } - return false; - } - - @Override - public boolean longPress(float x, float y) { - if (renderedCardContains(x, y)) { - showZoom(); - return true; - } - return false; - } - - private void showZoom() { - if (displayArea == null) { return; } - - final List cards = displayArea.orderedCards; - CardZoom.show(cards, cards.indexOf(getCard()), displayArea); - } - - public void buildCardPanelList(List list) { - if (!attachedPanels.isEmpty()) { - for (int i = attachedPanels.size() - 1; i >= 0; i--) { - attachedPanels.get(i).buildCardPanelList(list); - } - } - - list.add(this); - - if (nextPanelInStack != null) { - nextPanelInStack.buildCardPanelList(list); - } - } - - private List getOtherCardsToSelect(boolean selectOtherCardsInStack) { - if (!selectOtherCardsInStack) { return null; } - - //on double-tap select all other cards in stack if any - if (prevPanelInStack == null && nextPanelInStack == null) { return null; } - - List cards = new ArrayList<>(); - - CardAreaPanel panel = nextPanelInStack; - while (panel != null) { - cards.add(panel.getCard()); - panel = panel.nextPanelInStack; - } - panel = prevPanelInStack; - while (panel != null) { - cards.add(panel.getCard()); - panel = panel.prevPanelInStack; - } - return cards; - } - - public static Vector2 getTargetingArrowOrigin(FDisplayObject cardDisplay, boolean isTapped) { - Vector2 origin = new Vector2(cardDisplay.screenPos.x, cardDisplay.screenPos.y); - - float left = PADDING; - float top = PADDING; - float w = cardDisplay.getWidth() - 2 * PADDING; - float h = cardDisplay.getHeight() - 2 * PADDING; - if (w == h) { //adjust width if needed to make room for tapping - w = h / ASPECT_RATIO; - } - - if (isTapped) { //rotate box if tapped - top += h - w; - float temp = w; - w = h; - h = temp; - } - - origin.x += left + w * TARGET_ORIGIN_FACTOR_X; - origin.y += top + h * TARGET_ORIGIN_FACTOR_Y; - - return origin; - } - - public Vector2 getTargetingArrowOrigin() { - //don't show targeting arrow unless in display area that's visible - if (displayArea == null || !displayArea.isVisible()) { return null; } - - return getTargetingArrowOrigin(this, isTapped()); - } - - @Override - protected float getTappedAngle() { - if (displayArea != null && displayArea.rotateCards180) { - return -super.getTappedAngle(); //reverse tap angle if rotated 180 degrees - } - return super.getTappedAngle(); - } - - @Override - public void draw(Graphics g) { - if (displayArea != null && displayArea.rotateCards180) { - float padding = getPadding(); - float x = padding; - float y = padding; - float w = getWidth() - 2 * padding; - float h = getHeight() - 2 * padding; - if (w == h) { //adjust width if needed to make room for tapping - w = h / ASPECT_RATIO; - } - g.startRotateTransform(x + w / 2, y + h / 2, 180); - super.draw(g); - g.endTransform(); - } - else { - super.draw(g); - } - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VDevMenu.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VDevMenu.java deleted file mode 100644 index 104872e11d1..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VDevMenu.java +++ /dev/null @@ -1,286 +0,0 @@ -package forge.adventure.libgdxgui.screens.match.views; - -import forge.adventure.libgdxgui.menu.FCheckBoxMenuItem; -import forge.adventure.libgdxgui.menu.FDropDownMenu; -import forge.adventure.libgdxgui.menu.FMenuItem; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.toolbox.FEvent; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.util.Localizer; -import forge.util.ThreadUtil; - -public class VDevMenu extends FDropDownMenu { - @Override - protected void buildMenu() { - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblGenerateMana"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { //must invoke all these in game thread since they may require synchronous user input - @Override - public void run() { - MatchController.instance.getGameController().cheat().generateMana(); - } - }); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblTutor"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { - @Override - public void run() { - MatchController.instance.getGameController().cheat().tutorForCard(); - } - }); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblRollbackPhase"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { //must invoke all these in game thread since they may require synchronous user input - @Override - public void run() { - MatchController.instance.getGameController().cheat().rollbackPhase(); - } - }); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblCastSpellOrPlayLand"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { - @Override - public void run() { - MatchController.instance.getGameController().cheat().castASpell(); - } - }); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblCardToHand"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { - @Override - public void run() { - MatchController.instance.getGameController().cheat().addCardToHand(); - } - }); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblCardToBattlefield"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { - @Override - public void run() { - MatchController.instance.getGameController().cheat().addCardToBattlefield(); - } - }); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblCardToLibrary"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { - @Override - public void run() { - MatchController.instance.getGameController().cheat().addCardToLibrary(); - } - }); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblCardToGraveyard"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { - @Override - public void run() { - MatchController.instance.getGameController().cheat().addCardToGraveyard(); - } - }); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblCardToExile"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { - @Override - public void run() { - MatchController.instance.getGameController().cheat().addCardToExile(); - } - }); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblRepeatAddCard"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { - @Override - public void run() { - MatchController.instance.getGameController().cheat().repeatLastAddition(); - } - }); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblExileFromHand"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { - @Override - public void run() { - MatchController.instance.getGameController().cheat().exileCardsFromHand(); - } - }); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblExileFromPlay"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { - @Override - public void run() { - MatchController.instance.getGameController().cheat().exileCardsFromBattlefield(); - } - }); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblRemoveFromGame"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { - @Override - public void run() { - MatchController.instance.getGameController().cheat().removeCardsFromGame(); - } - }); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblSetLife"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { - @Override - public void run() { - MatchController.instance.getGameController().cheat().setPlayerLife(); - } - }); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblWinGame"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { - @Override - public void run() { - MatchController.instance.getGameController().cheat().winGame(); - } - }); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblSetupGame"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { - @Override - public void run() { - MatchController.instance.getGameController().cheat().setupGameState(); - } - }); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblDumpGame"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { - @Override - public void run() { - MatchController.instance.getGameController().cheat().dumpGameState(); - } - }); - } - })); - - final boolean unlimitedLands = MatchController.instance.getGameController().canPlayUnlimitedLands(); - addItem(new FCheckBoxMenuItem(Localizer.getInstance().getMessage("lblUnlimitedLands"), unlimitedLands, - new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - MatchController.instance.getGameController().cheat().setCanPlayUnlimitedLands(!unlimitedLands); - } - })); - final boolean viewAll = MatchController.instance.getGameController().mayLookAtAllCards(); - addItem(new FCheckBoxMenuItem(Localizer.getInstance().getMessage("lblViewAll"), viewAll, - new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - MatchController.instance.getGameController().cheat().setViewAllCards(!viewAll); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblAddCounterPermanent"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { - @Override - public void run() { - MatchController.instance.getGameController().cheat().addCountersToPermanent(); - } - }); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblSubCounterPermanent"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { - @Override - public void run() { - MatchController.instance.getGameController().cheat().removeCountersFromPermanent(); - } - }); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblTapPermanent"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { - @Override - public void run() { - MatchController.instance.getGameController().cheat().tapPermanents(); - } - }); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblUntapPermanent"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { - @Override - public void run() { - MatchController.instance.getGameController().cheat().untapPermanents(); - } - }); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblRiggedRoll"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { - @Override - public void run() { - MatchController.instance.getGameController().cheat().riggedPlanarRoll(); - } - }); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblWalkTo"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { - @Override - public void run() { - MatchController.instance.getGameController().cheat().planeswalkTo(); - } - }); - } - })); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VDisplayArea.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VDisplayArea.java deleted file mode 100644 index 0edbee928af..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VDisplayArea.java +++ /dev/null @@ -1,11 +0,0 @@ -package forge.adventure.libgdxgui.screens.match.views; - -import forge.adventure.libgdxgui.toolbox.FScrollPane; - -public abstract class VDisplayArea extends FScrollPane { - public VDisplayArea() { - setVisible(false); //hide by default - } - public abstract int getCount(); - public abstract void update(); -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VField.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VField.java deleted file mode 100644 index 3ddaf5ff65c..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VField.java +++ /dev/null @@ -1,206 +0,0 @@ -package forge.adventure.libgdxgui.screens.match.views; - -import forge.game.card.CardView; -import forge.game.card.CardView.CardStateView; -import forge.game.player.PlayerView; -import forge.gui.FThreads; -import forge.adventure.libgdxgui.screens.match.views.VCardDisplayArea.CardAreaPanel; -import forge.adventure.libgdxgui.toolbox.FContainer; - -import java.util.ArrayList; -import java.util.List; - -public class VField extends FContainer { - private final PlayerView player; - private final FieldRow row1, row2; - private boolean flipped; - private float commandZoneWidth; - private float fieldModifier; - - public VField(PlayerView player0) { - player = player0; - row1 = add(new FieldRow()); - row2 = add(new FieldRow()); - } - - public boolean isFlipped() { - return flipped; - } - public void setFlipped(boolean flipped0) { - flipped = flipped0; - } - - public Iterable getCardPanels() { - List cardPanels = new ArrayList<>(); - for (CardAreaPanel cardPanel : row1.getCardPanels()) { - cardPanels.add(cardPanel); - } - for (CardAreaPanel cardPanel : row2.getCardPanels()) { - cardPanels.add(cardPanel); - } - return cardPanels; - } - - public void update(boolean invokeInEdtNowOrLater) { - if (invokeInEdtNowOrLater) - FThreads.invokeInEdtNowOrLater(updateRoutine); - else - FThreads.invokeInEdtLater(updateRoutine); - } - - private final Runnable updateRoutine = new Runnable() { - @Override - public void run() { - clear(); - - Iterable model = player.getBattlefield(); - if (model == null) { return; } - - for (CardView card : model) { - CardAreaPanel cardPanel = CardAreaPanel.get(card); - cardPanel.updateCard(card); - // Clear all stacks since they will be rebuilt in the loop below. - cardPanel.setNextPanelInStack(null); - cardPanel.setPrevPanelInStack(null); - } - - List creatures = new ArrayList<>(); - List lands = new ArrayList<>(); - List otherPermanents = new ArrayList<>(); - - for (CardView card : model) { - CardAreaPanel cardPanel = CardAreaPanel.get(card); - CardStateView details = card.getCurrentState(); - if (cardPanel.getAttachedToPanel() == null) { //skip attached panels - if (details.isCreature()) { - if (!tryStackCard(card, creatures)) { - creatures.add(card); - } - } - else if (details.isLand()) { - if (!tryStackCard(card, lands)) { - lands.add(card); - } - } - else { - if (!tryStackCard(card, otherPermanents)) { - otherPermanents.add(card); - } - } - } - } - - if (creatures.isEmpty()) { - row1.refreshCardPanels(otherPermanents); - row2.refreshCardPanels(lands); - } - else { - row1.refreshCardPanels(creatures); - lands.addAll(otherPermanents); - row2.refreshCardPanels(lands); - } - } - }; - - private boolean tryStackCard(CardView card, List cardsOfType) { - if (card.hasCardAttachments()) { - return false; //can stack with enchanted or equipped card - } - if (card.getCurrentState().isCreature() && !card.isToken()) { - return false; //don't stack non-token creatures - } - final String cardName = card.getCurrentState().getName(); - for (CardView c : cardsOfType) { - if (c.getCurrentState().isCreature()) { - if (!c.hasCardAttachments() && - cardName.equals(c.getCurrentState().getName()) && - card.hasSameCounters(c) && - card.hasSamePT(c) && //don't stack token with different PT - card.getCurrentState().getKeywordKey().equals(c.getCurrentState().getKeywordKey()) && - card.isTapped() == c.isTapped() && // don't stack tapped tokens on untapped tokens - card.isSick() == c.isSick() && //don't stack sick tokens on non sick - card.isToken() == c.isToken()) { //don't stack tokens on top of non-tokens - CardAreaPanel cPanel = CardAreaPanel.get(c); - while (cPanel.getNextPanelInStack() != null) { - cPanel = cPanel.getNextPanelInStack(); - } - CardAreaPanel cardPanel = CardAreaPanel.get(card); - cPanel.setNextPanelInStack(cardPanel); - cardPanel.setPrevPanelInStack(cPanel); - return true; - } - } else { - if (!c.hasCardAttachments() && - cardName.equals(c.getCurrentState().getName()) && - card.hasSameCounters(c) && - card.getCurrentState().getKeywordKey().equals(c.getCurrentState().getKeywordKey()) && - card.getCurrentState().getColors() == c.getCurrentState().getColors() && - card.isSick() == c.isSick() && //don't stack sick tokens on non sick - card.isToken() == c.isToken()) { //don't stack tokens on top of non-tokens - CardAreaPanel cPanel = CardAreaPanel.get(c); - while (cPanel.getNextPanelInStack() != null) { - cPanel = cPanel.getNextPanelInStack(); - } - CardAreaPanel cardPanel = CardAreaPanel.get(card); - cPanel.setNextPanelInStack(cardPanel); - cardPanel.setPrevPanelInStack(cPanel); - return true; - } - } - } - return false; - } - - public FieldRow getRow1() { - return row1; - } - - public FieldRow getRow2() { - return row2; - } - - void setCommandZoneWidth(float commandZoneWidth0) { - commandZoneWidth = commandZoneWidth0; - } - - void setFieldModifier(float fieldModifierWidth) { - fieldModifier = fieldModifierWidth; - } - - @Override - public void clear() { - row1.clear(); //clear rows instead of removing the rows - row2.clear(); - } - - @Override - protected void doLayout(float width, float height) { - float cardSize = height / 2; - float y1, y2; - if (flipped) { - y1 = cardSize; - y2 = 0; - } - else { - y1 = 0; - y2 = cardSize; - } - row1.setBounds(0, y1, width-fieldModifier, cardSize); - row2.setBounds(0, y2, (width - commandZoneWidth)-fieldModifier, cardSize); - } - - public class FieldRow extends VCardDisplayArea { - private FieldRow() { - setVisible(true); //make visible by default unlike other display areas - } - - @Override - protected float getCardWidth(float cardHeight) { - return cardHeight; //allow cards room to tap - } - - @Override - public void update() { //no logic needed - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VGameMenu.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VGameMenu.java deleted file mode 100644 index 06c7c4b25bc..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VGameMenu.java +++ /dev/null @@ -1,113 +0,0 @@ -package forge.adventure.libgdxgui.screens.match.views; - -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.assets.FSkinImage; -import forge.deck.Deck; -import forge.adventure.libgdxgui.deck.FDeckViewer; -import forge.game.player.Player; -import forge.adventure.libgdxgui.menu.FDropDownMenu; -import forge.adventure.libgdxgui.menu.FMenuItem; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.screens.settings.SettingsScreen; -import forge.adventure.libgdxgui.toolbox.FEvent; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.toolbox.FOptionPane; -import forge.util.Localizer; -import forge.util.ThreadUtil; - -public class VGameMenu extends FDropDownMenu { - public VGameMenu() { - } - - @Override - protected void buildMenu() { - final Localizer localizer = Localizer.getInstance(); - - addItem(new FMenuItem(MatchController.instance.getConcedeCaption(), FSkinImage.CONCEDE, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - ThreadUtil.invokeInGameThread(new Runnable() { - @Override - public void run() { - MatchController.instance.concede(); - } - }); - } - })); - /*addItem(new FMenuItem("Save Game", FSkinImage.SAVE, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - GameStateSerializer.saveGameState(MatchUtil.getGame(), ForgeConstants.USER_GAMES_DIR + "GameSave.txt"); - FOptionPane.showMessageDialog("Game saved successfully.", "Save Game", FOptionPane.INFORMATION_ICON); - } - })); - addItem(new FMenuItem("Load Game", FSkinImage.OPEN, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - GameStateDeserializer.loadGameState(MatchUtil.getGame(), ForgeConstants.USER_GAMES_DIR + "GameSave.txt"); - } - }));*/ - addItem(new FMenuItem(localizer.getMessage("lblDeckList"), FSkinImage.DECKLIST, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - //pause game when spectating AI Match - if (!MatchController.instance.hasLocalPlayers()) { - if(!MatchController.instance.isGamePaused()) - MatchController.instance.pauseMatch(); - } - - final Player player = MatchController.getHostedMatch().getGame().getPhaseHandler().getPlayerTurn(); - if (player != null) { - final Deck deck = player.getRegisteredPlayer().getDeck(); - if (deck != null) { - FDeckViewer.show(deck); - return; - } - } - FOptionPane.showMessageDialog(localizer.getMessage("lblNoPlayerPriorityNoDeckListViewed")); - } - })); - addItem(new FMenuItem(localizer.getMessage("lblAutoYields"), Forge.hdbuttons ? FSkinImage.HDYIELD : FSkinImage.WARNING, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - final boolean autoYieldsDisabled = MatchController.instance.getDisableAutoYields(); - final VAutoYields autoYields = new VAutoYields() { - @Override - public void setVisible(boolean b0) { - super.setVisible(b0); - if (!b0) { - if (autoYieldsDisabled && !MatchController.instance.getDisableAutoYields()) { - //if re-enabling auto-yields, auto-yield to current ability on stack if applicable - final String key = MatchController.instance.getGameView().peekStack().getKey(); - final boolean autoYield = MatchController.instance.shouldAutoYield(key); - MatchController.instance.setShouldAutoYield(key, !autoYield); - if (!autoYield && MatchController.instance.shouldAutoYield(key)) { - //auto-pass priority if ability is on top of stack - MatchController.instance.getGameController().passPriority(); - } - } - } - } - }; - autoYields.show(); - } - })); - addItem(new FMenuItem(localizer.getMessage("lblSettings"), Forge.hdbuttons ? FSkinImage.HDPREFERENCE : FSkinImage.SETTINGS, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - //pause game when spectating AI Match - if (!MatchController.instance.hasLocalPlayers()) { - if(!MatchController.instance.isGamePaused()) - MatchController.instance.pauseMatch(); - } - SettingsScreen.show(false); - } - })); - addItem(new FMenuItem(localizer.getMessage("lblShowWinLoseOverlay"), FSkinImage.ENDTURN, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - MatchController.instance.showWinlose(); - } - })); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VLog.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VLog.java deleted file mode 100644 index 613f8159253..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VLog.java +++ /dev/null @@ -1,113 +0,0 @@ -package forge.adventure.libgdxgui.screens.match.views; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.TextRenderer; -import forge.game.GameLogEntry; -import forge.game.GameLogEntryType; -import forge.localinstance.properties.ForgePreferences.FPref; -import forge.adventure.libgdxgui.menu.FDropDown; -import forge.model.FModel; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.util.Utils; - -import java.util.List; - -public class VLog extends FDropDown { - private static final float PADDING = Utils.scale(5); - private static final FSkinFont FONT = FSkinFont.get(11); - private static final FSkinColor ALT_ROW_COLOR = FSkinColor.get(Colors.CLR_ZEBRA); - private static final FSkinColor ROW_COLOR = ALT_ROW_COLOR.darker(); - private static final FSkinColor FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT); - - public VLog() { - } - - @Override - protected boolean autoHide() { - return true; - } - - @Override - protected void drawBackground(Graphics g) { - float w = getWidth(); - float h = getHeight(); - g.fillRect(ROW_COLOR, 0, 0, w, h); //can fill background with main row color since drop down will never be taller than number of rows - } - - @Override - protected ScrollBounds updateAndGetPaneSize(float maxWidth, float maxVisibleHeight) { - clear(); - - GameLogEntryType logVerbosityFilter = GameLogEntryType.valueOf(FModel.getPreferences().getPref(FPref.DEV_LOG_ENTRY_TYPE)); - List logEntrys = MatchController.instance.getGameView().getGameLog().getLogEntries(logVerbosityFilter); - - LogEntryDisplay logEntryDisplay; - float width = maxWidth - getMenuTab().screenPos.x; //stretch from tab to edge of screen - float minWidth = 4 * Utils.AVG_FINGER_WIDTH; - if (width < minWidth) { - width = minWidth; - } - - float y = 1; - float height; - if (logEntrys.isEmpty()) { - logEntryDisplay = add(new LogEntryDisplay("[Empty]", false)); - height = logEntryDisplay.getMinHeight(width); - logEntryDisplay.setBounds(0, y, width, height); - y += height; - } - else { - boolean isAltRow = false; - for (int i = logEntrys.size() - 1; i >= 0; i--) { //show latest entry on bottom - logEntryDisplay = add(new LogEntryDisplay(logEntrys.get(i).message, isAltRow)); - height = logEntryDisplay.getMinHeight(width); - logEntryDisplay.setBounds(0, y, width, height); - isAltRow = !isAltRow; - y += height; - } - } - - return new ScrollBounds(width, y + 1); - } - - @Override - protected void setScrollPositionsAfterLayout(float scrollLeft0, float scrollTop0) { - super.setScrollPositionsAfterLayout(0, getMaxScrollTop()); //always scroll to bottom after layout - } - - private class LogEntryDisplay extends FDisplayObject { - private final String text; - private final boolean isAltRow; - private final TextRenderer renderer = new TextRenderer(true); - - private LogEntryDisplay(String text0, boolean isAltRow0) { - text = text0; - isAltRow = isAltRow0; - } - - private float getMinHeight(float width) { - width -= 2 * PADDING; //account for left and right insets - float height = renderer.getWrappedBounds(text, FONT, width).height; - height += 2 * PADDING; - return Math.round(height); - } - - @Override - public void draw(Graphics g) { - float w = getWidth(); - float h = getHeight(); - - if (isAltRow) { - g.fillRect(ALT_ROW_COLOR, 0, 0, w, h); - } - - //use full height without padding so text not scaled down - renderer.drawText(g, text, FONT, FORE_COLOR, PADDING, PADDING, w - 2 * PADDING, h, 0, h, true, Align.left, false); - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VManaPool.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VManaPool.java deleted file mode 100644 index e789b1fb232..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VManaPool.java +++ /dev/null @@ -1,153 +0,0 @@ -package forge.adventure.libgdxgui.screens.match.views; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.FSkinImage; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.card.MagicColor; -import forge.card.mana.ManaAtom; -import forge.game.player.PlayerView; -import forge.player.GamePlayerUtil; - -import java.util.ArrayList; -import java.util.List; - -public class VManaPool extends VDisplayArea { - private static final FSkinColor FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT); - private static final FSkinFont FONT = FSkinFont.get(16); - - private final PlayerView player; - private final List manaLabels = new ArrayList<>(); - private int totalMana; - - public VManaPool(PlayerView player0) { - player = player0; - - addManaLabel(FSkinImage.MANA_COLORLESS, (byte)ManaAtom.COLORLESS); - addManaLabel(FSkinImage.MANA_W, MagicColor.WHITE); - addManaLabel(FSkinImage.MANA_U, MagicColor.BLUE); - addManaLabel(FSkinImage.MANA_B, MagicColor.BLACK); - addManaLabel(FSkinImage.MANA_R, MagicColor.RED); - addManaLabel(FSkinImage.MANA_G, MagicColor.GREEN); - } - - private void addManaLabel(FSkinImage image, byte colorCode) { - manaLabels.add(add(new ManaLabel(image, colorCode))); - } - - @Override - public int getCount() { - return totalMana; - } - - @Override - public void update() { - totalMana = 0; - for (ManaLabel label : manaLabels) { - int colorCount = player.getMana(label.colorCode); - totalMana += colorCount; - label.text = Integer.toString(colorCount); - } - } - - @Override - protected ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) { - float x = 0; - float y = 0; - - if (Forge.isLandscapeMode()) { - float labelWidth = visibleWidth / 2; - float labelHeight = visibleHeight / 3; - - int count = 0; - for (ManaLabel label : manaLabels) { - label.setBounds(x, y, labelWidth, labelHeight); - if (++count % 2 == 0) { - x = 0; - y += labelHeight; - } - else { - x += labelWidth; - } - } - } - else { - float labelWidth = visibleWidth / manaLabels.size(); - float labelHeight = visibleHeight; - - for (ManaLabel label : manaLabels) { - label.setBounds(x, y, labelWidth, labelHeight); - x += labelWidth; - } - } - - return new ScrollBounds(visibleWidth, visibleHeight); - } - - private class ManaLabel extends FDisplayObject { - private final FSkinImage image; - private final byte colorCode; - private String text = "0"; - - private ManaLabel(FSkinImage image0, byte colorCode0) { - image = image0; - colorCode = colorCode0; - } - - @Override - public boolean tap(float x, float y, int count) { - if (player.isLobbyPlayer(GamePlayerUtil.getGuiPlayer())) { - MatchController.instance.getGameController().useMana(colorCode); - } - return true; - } - - @Override - public boolean flick(float x, float y) { - if (player.isLobbyPlayer(GamePlayerUtil.getGuiPlayer())) { - //on two finger tap, keep using mana until it runs out or no longer can be put towards the cost - int oldMana, newMana = player.getMana(colorCode); - do { - oldMana = newMana; - MatchController.instance.getGameController().useMana(colorCode); - newMana = player.getMana(colorCode); - } - while (oldMana != newMana); - } - return true; - } - - @Override - public void draw(Graphics g) { - float textHeight = FONT.getCapHeight(); - float gapY = textHeight / 4f; - - float maxImageHeight = getHeight() - textHeight - 3 * gapY; - float h = image.getNearestHQHeight(maxImageHeight); - if (h > maxImageHeight) { - h /= 2; - } - float w = image.getWidth() * h / image.getHeight(); - while (w > getWidth()) { - h /= 2; - w = image.getWidth() * h / image.getHeight(); - } - float x = (getWidth() - w) / 2; - float y = gapY + (maxImageHeight - h) / 2; - - g.drawImage(image, x, y, w, h); - - x = 0; - y += h + gapY; - w = getWidth(); - h = getHeight() - y; - - g.drawText(text, FONT, FORE_COLOR, x, y, w, h, false, Align.center, false); - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VPhaseIndicator.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VPhaseIndicator.java deleted file mode 100644 index 49ad701e5a2..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VPhaseIndicator.java +++ /dev/null @@ -1,165 +0,0 @@ -package forge.adventure.libgdxgui.screens.match.views; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.game.phase.PhaseType; -import forge.adventure.libgdxgui.toolbox.FContainer; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.util.TextBounds; -import forge.adventure.libgdxgui.util.Utils; - -import java.util.HashMap; -import java.util.Map; - -public class VPhaseIndicator extends FContainer { - public static final FSkinFont BASE_FONT = FSkinFont.get(11); - public static final float PADDING_X = Utils.scale(1); - public static final float PADDING_Y = Utils.scale(2); - - private final Map phaseLabels = new HashMap<>(); - private FSkinFont font; - - public VPhaseIndicator() { - addPhaseLabel("UP", PhaseType.UPKEEP); - addPhaseLabel("DR", PhaseType.DRAW); - addPhaseLabel("M1", PhaseType.MAIN1); - addPhaseLabel("BC", PhaseType.COMBAT_BEGIN); - addPhaseLabel("DA", PhaseType.COMBAT_DECLARE_ATTACKERS); - addPhaseLabel("DB", PhaseType.COMBAT_DECLARE_BLOCKERS); - addPhaseLabel("FS", PhaseType.COMBAT_FIRST_STRIKE_DAMAGE); - addPhaseLabel("CD", PhaseType.COMBAT_DAMAGE); - addPhaseLabel("EC", PhaseType.COMBAT_END); - addPhaseLabel("M2", PhaseType.MAIN2); - addPhaseLabel("ET", PhaseType.END_OF_TURN); - addPhaseLabel("CL", PhaseType.CLEANUP); - } - - private void addPhaseLabel(String caption, PhaseType phaseType) { - phaseLabels.put(phaseType, add(new PhaseLabel(caption, phaseType))); - } - - public PhaseLabel getLabel(PhaseType phaseType) { - return phaseLabels.get(phaseType); - } - - public void resetPhaseButtons() { - for (PhaseLabel lbl : phaseLabels.values()) { - lbl.setActive(false); - } - } - - public void resetFont() { - font = BASE_FONT; - } - - public float getPreferredHeight(float width) { - //build string to use to determine ideal font - float w = width / phaseLabels.size(); - w -= 2 * PADDING_X; - resetFont(); - return _getPreferredHeight(w); - } - private float _getPreferredHeight(float w) { - TextBounds bounds = null; - for (PhaseLabel lbl : phaseLabels.values()) { - bounds = font.getBounds(lbl.caption); - if (bounds.width > w) { - if (font.canShrink()) { - font = font.shrink(); - return _getPreferredHeight(w); - } - break; - } - } - return bounds.height + 2 * PADDING_Y; - } - - @Override - protected void doLayout(float width, float height) { - if (width > height) { - float x = 0; - float w = width / phaseLabels.size(); - float h = height; - - for (FDisplayObject lbl : getChildren()) { - lbl.setBounds(x, 0, w, h); - x += w; - } - } - else { - float padding = Utils.scale(1); - float y = 0; - float w = width - 2 * padding; - float h = height / phaseLabels.size(); - - for (FDisplayObject lbl : getChildren()) { - lbl.setBounds(padding, y + padding, w, h - 2 * padding); - y += h; - } - } - } - - public class PhaseLabel extends FDisplayObject { - private final String caption; - private final PhaseType phaseType; - private boolean stopAtPhase = false; - private boolean active = false; - - public PhaseLabel(String caption0, PhaseType phaseType0) { - caption = caption0; - phaseType = phaseType0; - } - - public boolean getActive() { - return active; - } - public void setActive(boolean active0) { - active = active0; - } - - public PhaseType getPhaseType() { - return phaseType; - } - - public boolean getStopAtPhase() { - return stopAtPhase; - } - public void setStopAtPhase(boolean stopAtPhase0) { - stopAtPhase = stopAtPhase0; - } - - @Override - public boolean tap(float x, float y, int count) { - stopAtPhase = !stopAtPhase; - return true; - } - - @Override - public void draw(final Graphics g) { - float x = PADDING_X; - float w = getWidth() - 2 * PADDING_X; - float h = getHeight(); - - //determine back color according to skip or active state of label - FSkinColor backColor; - if (active && stopAtPhase) { - backColor = FSkinColor.get(Colors.CLR_PHASE_ACTIVE_ENABLED); - } - else if (!active && stopAtPhase) { - backColor = FSkinColor.get(Colors.CLR_PHASE_INACTIVE_ENABLED); - } - else if (active && !stopAtPhase) { - backColor = FSkinColor.get(Colors.CLR_PHASE_ACTIVE_DISABLED); - } - else { - backColor = FSkinColor.get(Colors.CLR_PHASE_INACTIVE_DISABLED); - } - g.fillRect(backColor, x, 0, w, h); - g.drawText(caption, font, Color.BLACK, x, 0, w, h, false, Align.center, true); - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VPlayerPanel.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VPlayerPanel.java deleted file mode 100644 index 0a68327ee6d..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VPlayerPanel.java +++ /dev/null @@ -1,662 +0,0 @@ -package forge.adventure.libgdxgui.screens.match.views; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.FSkinImage; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.screens.match.MatchScreen; -import forge.adventure.libgdxgui.toolbox.FCardPanel; -import forge.adventure.libgdxgui.toolbox.FContainer; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.util.Utils; -import forge.game.card.CardView; -import forge.game.card.CounterEnumType; -import forge.game.player.PlayerView; -import forge.game.zone.ZoneType; -import forge.localinstance.properties.ForgePreferences.FPref; -import forge.model.FModel; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class VPlayerPanel extends FContainer { - private static final FSkinFont LIFE_FONT = FSkinFont.get(18); - private static final FSkinFont LIFE_FONT_ALT = FSkinFont.get(22); - private static final FSkinFont INFO_FONT = FSkinFont.get(12); - private static final FSkinFont INFO2_FONT = FSkinFont.get(14); - private static final FSkinColor INFO_FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT); - private static final FSkinColor DISPLAY_AREA_BACK_COLOR = FSkinColor.get(Colors.CLR_INACTIVE).alphaColor(0.5f); - private static final FSkinColor DELIRIUM_HIGHLIGHT = FSkinColor.get(Colors.CLR_PHASE_ACTIVE_ENABLED).alphaColor(0.5f); - private static final float INFO_TAB_PADDING_X = Utils.scale(2); - private static final float INFO_TAB_PADDING_Y = Utils.scale(2); - - private final PlayerView player; - private final VPhaseIndicator phaseIndicator; - private final VField field; - private final VAvatar avatar; - private final VZoneDisplay commandZone; - private final LifeLabel lblLife; - private final InfoTab tabManaPool; - private final Map zoneTabs = new HashMap<>(); - private final List tabs = new ArrayList<>(); - private InfoTab selectedTab; - private float avatarHeight = VAvatar.HEIGHT; - private final float displayAreaHeightFactor = 1.0f; - private boolean forMultiPlayer = false; - public int adjustHeight = 1; - - public VPlayerPanel(PlayerView player0, boolean showHand, int playerCount) { - player = player0; - phaseIndicator = add(new VPhaseIndicator()); - - if(playerCount > 2){ - forMultiPlayer = true; - avatarHeight *= 0.5f; - //displayAreaHeightFactor *= 0.7f; - } - field = add(new VField(player)); - avatar = add(new VAvatar(player, avatarHeight)); - lblLife = add(new LifeLabel()); - addZoneDisplay(ZoneType.Hand, Forge.hdbuttons ? FSkinImage.HDHAND : FSkinImage.HAND); - addZoneDisplay(ZoneType.Graveyard, Forge.hdbuttons ? FSkinImage.HDGRAVEYARD : FSkinImage.GRAVEYARD); - addZoneDisplay(ZoneType.Library, Forge.hdbuttons ? FSkinImage.HDLIBRARY : FSkinImage.LIBRARY); - addZoneDisplay(ZoneType.Flashback, Forge.hdbuttons ? FSkinImage.HDFLASHBACK :FSkinImage.FLASHBACK); - - VManaPool manaPool = add(new VManaPool(player)); - tabManaPool = add(new InfoTab(Forge.hdbuttons ? FSkinImage.HDMANAPOOL : FSkinImage.MANA_X, manaPool)); - tabs.add(tabManaPool); - - addZoneDisplay(ZoneType.Exile, Forge.hdbuttons ? FSkinImage.HDEXILE : FSkinImage.EXILE); - - commandZone = add(new CommandZoneDisplay(player)); - - if (showHand) { - setSelectedZone(ZoneType.Hand); - } - } - - public PlayerView getPlayer() { - return player; - } - - public void addZoneDisplay(ZoneType zoneType, FSkinImage tabIcon) { - VZoneDisplay zoneDisplay = add(new VZoneDisplay(player, zoneType)); - InfoTab zoneTab = add(new InfoTab(tabIcon, zoneDisplay)); - zoneTabs.put(zoneType, zoneTab); - tabs.add(zoneTab); - } - - public Iterable getTabs() { - return tabs; - } - - public InfoTab getSelectedTab() { - return selectedTab; - } - - public InfoTab getZoneTab(ZoneType zoneType) { - return zoneTabs.get(zoneType); - } - - public ZoneType getZoneByInfoTab(InfoTab tab) { - for(ZoneType zone : zoneTabs.keySet()) { - if (zoneTabs.get(zone).equals(tab)) { - return zone; - } - } - - return null; - } - - private boolean isAltZoneDisplay(InfoTab tab) { - if (tab.getIcon() == FSkinImage.HDHAND || tab.getIcon() == FSkinImage.HAND) - return true; - if (tab.getIcon() == FSkinImage.HDGRAVEYARD || tab.getIcon() == FSkinImage.GRAVEYARD) - return true; - if (tab.getIcon() == FSkinImage.HDLIBRARY || tab.getIcon() == FSkinImage.LIBRARY) - return true; - return tab.getIcon() == FSkinImage.HDEXILE || tab.getIcon() == FSkinImage.EXILE; - } - - public void setSelectedZone(ZoneType zoneType) { - setSelectedTab(zoneTabs.get(zoneType)); - } - - public void hideSelectedTab() { - if (selectedTab != null) { - selectedTab.displayArea.setVisible(false); - } - } - - public void setSelectedTab(InfoTab selectedTab0) { - if (selectedTab == selectedTab0) { - return; - } - - hideSelectedTab(); - - selectedTab = selectedTab0; - - if (selectedTab != null) { - selectedTab.displayArea.setVisible(true); - } - - if (MatchController.getView() != null) { //must revalidate entire screen so panel heights updated - MatchController.getView().revalidate(); - } - } - - public InfoTab getManaPoolTab() { - return tabManaPool; - } - - public boolean isFlipped() { - return field.isFlipped(); - } - public void setFlipped(boolean flipped0) { - field.setFlipped(flipped0); - } - - @Override - public void setRotate180(boolean b0) { - //only rotate certain parts of panel - avatar.setRotate180(b0); - lblLife.setRotate180(b0); - phaseIndicator.setRotate180(b0); - for (InfoTab tab : tabs) { - tab.displayArea.setRotate180(b0); - } - field.getRow1().setRotate180(b0); - field.getRow2().setRotate180(b0); - } - - public VField getField() { - return field; - } - - public VPhaseIndicator getPhaseIndicator() { - return phaseIndicator; - } - - public VAvatar getAvatar() { - return avatar; - } - - public VZoneDisplay getCommandZone() { - return commandZone; - } - - public void updateLife() { - lblLife.update(); - } - - public void updateManaPool() { - tabManaPool.update(); - } - - public void updateZone(ZoneType zoneType) { - if (zoneType == ZoneType.Battlefield ) { - field.update(true); - } - else if (zoneType == ZoneType.Command) { - commandZone.update(); - } - else { - InfoTab zoneTab = zoneTabs.get(zoneType); - if (zoneTab != null) { //TODO: Support Ante somehow - zoneTab.update(); - } - - //update flashback zone when graveyard, library, exile, or stack zones updated - switch (zoneType) { - case Graveyard: - case Library: - case Exile: - case Stack: - zoneTabs.get(ZoneType.Flashback).update(); - break; - default: - break; - } - } - } - - @Override - protected void doLayout(float width, float height) { - if (Forge.isLandscapeMode()) { - doLandscapeLayout(width, height); - return; - } - - //layout for bottom panel by default - float x = avatarHeight; - float w = width - avatarHeight; - float indicatorScale = 1f; - if(avatarHeight 0) { - float commandZoneHeight = y / 2; - float commandZoneWidth = Math.min(commandZoneCount, 2) * commandZone.getCardWidth(commandZoneHeight); - commandZone.setBounds(width - commandZoneWidth, y - commandZoneHeight, commandZoneWidth, commandZoneHeight); - - field.setCommandZoneWidth(commandZoneWidth + 1); //ensure second row of field accounts for width of command zone and its border - } - else { - field.setCommandZoneWidth(0); - } - - field.setBounds(0, 0, width, y); - - if (isFlipped()) { //flip all positions across x-axis if needed - for (FDisplayObject child : getChildren()) { - child.setTop(height - child.getBottom()); - } - } - - //this is used for landscape so set this to 0 - field.setFieldModifier(0); - } - - private void doLandscapeLayout(float width, float height) { - float x = 0; - float y = 0; - float yAlt = 0; - float avatarWidth = Forge.altZoneTabs ? avatar.getWidth() : 0; - avatar.setPosition(x, y); - y += avatar.getHeight(); - - lblLife.setBounds(x, (Forge.altPlayerLayout && !Forge.altZoneTabs) ? 0 : y, avatar.getWidth(), (Forge.altPlayerLayout && !Forge.altZoneTabs) ? INFO_FONT.getLineHeight() : Forge.altZoneTabs ? LIFE_FONT_ALT.getLineHeight() : LIFE_FONT.getLineHeight()); - if (Forge.altPlayerLayout && !Forge.altZoneTabs) { - if (adjustHeight > 2) - y += INFO_FONT.getLineHeight()/2; - } else - y += lblLife.getHeight(); - - float infoTabWidth = avatar.getWidth(); - int tabSize = !Forge.altZoneTabs ? tabs.size() : tabs.size() - 4; - float infoTabHeight = (height - y) / tabSize; - float infoTabHeightAlt = (height - yAlt) / 4; - - for (InfoTab tab : tabs) { - if (!Forge.altZoneTabs) { - tab.setBounds(x, y, infoTabWidth, infoTabHeight); - y += infoTabHeight; - } else { - if (!isAltZoneDisplay(tab)) { - tab.setBounds(x, y, infoTabWidth, infoTabHeight); - y += infoTabHeight; - } else { - tab.setBounds(x+width-avatarWidth, yAlt, avatarWidth, infoTabHeightAlt); - yAlt += infoTabHeightAlt; - } - } - } - x = avatar.getRight(); - phaseIndicator.resetFont(); - phaseIndicator.setBounds(x, 0, avatar.getWidth() * 0.6f, height); - x += phaseIndicator.getWidth(); - - float fieldWidth = width - x - avatarWidth; - float displayAreaWidth = height / FCardPanel.ASPECT_RATIO; - if (selectedTab != null) { - fieldWidth -= displayAreaWidth; - } - - //account for command zone if needed - int commandZoneCount = commandZone.getCount(); - if (commandZoneCount > 0) { - float commandZoneHeight = height / 2; - float commandZoneWidth = Math.min(commandZoneCount, 2) * commandZone.getCardWidth(commandZoneHeight); - commandZone.setBounds(x + fieldWidth - commandZoneWidth, height - commandZoneHeight, commandZoneWidth, commandZoneHeight); - if (isFlipped()) { //flip across x-axis if needed - commandZone.setTop(height - commandZone.getBottom()); - } - - field.setCommandZoneWidth(commandZoneWidth + 1); //ensure second row of field accounts for width of command zone and its border - } - else { - field.setCommandZoneWidth(0); - } - - field.setBounds(x, 0, fieldWidth, height); - - x = width - displayAreaWidth-avatarWidth; - for (InfoTab tab : tabs) { - tab.displayArea.setBounds(x, 0, displayAreaWidth, height); - } - - if (!Forge.altZoneTabs) - field.setFieldModifier(0); - else - field.setFieldModifier(avatarWidth); - } - - @Override - public void drawBackground(Graphics g) { - float y; - if (selectedTab != null) { //draw background and border for selected zone if needed - VDisplayArea selectedDisplayArea = selectedTab.displayArea; - float x = selectedDisplayArea.getLeft(); - float w = selectedDisplayArea.getWidth(); - g.fillRect(DISPLAY_AREA_BACK_COLOR, x, selectedDisplayArea.getTop(), w, selectedDisplayArea.getHeight()); - - if (Forge.isLandscapeMode()) { - g.drawLine(1, MatchScreen.BORDER_COLOR, x, selectedDisplayArea.getTop(), x, selectedDisplayArea.getBottom()); - } - else { - y = isFlipped() ? selectedDisplayArea.getTop() + 1 : selectedDisplayArea.getBottom(); - //leave gap at selected zone tab - g.drawLine(1, MatchScreen.BORDER_COLOR, x, y, selectedTab.getLeft(), y); - g.drawLine(1, MatchScreen.BORDER_COLOR, selectedTab.getRight(), y, w, y); - } - } - if (commandZone.isVisible()) { //draw border for command zone if needed - float x = commandZone.getLeft(); - y = commandZone.getTop(); - g.drawLine(1, MatchScreen.BORDER_COLOR, x, y, x, y + commandZone.getHeight()); - if (isFlipped()) { - y += commandZone.getHeight(); - } - g.drawLine(1, MatchScreen.BORDER_COLOR, x, y, x + commandZone.getWidth(), y); - } - } - - private class LifeLabel extends FDisplayObject { - private int life = player.getLife(); - private int poisonCounters = player.getCounters(CounterEnumType.POISON); - private int energyCounters = player.getCounters(CounterEnumType.ENERGY); - private int experienceCounters = player.getCounters(CounterEnumType.EXPERIENCE); - private String lifeStr = String.valueOf(life); - - private LifeLabel() { - } - - private void update() { - int vibrateDuration = 0; - int delta = player.getLife() - life; - if (delta != 0) { - if (delta < 0) { - //TODO: Show animation on avatar for life loss - vibrateDuration += delta * -100; - } - life = player.getLife(); - lifeStr = String.valueOf(life); - } - - delta = player.getCounters(CounterEnumType.POISON) - poisonCounters; - if (delta != 0) { - if (delta > 0) { - //TODO: Show animation on avatar for gaining poison counters - vibrateDuration += delta * 200; - } - poisonCounters = player.getCounters(CounterEnumType.POISON); - } - - energyCounters = player.getCounters(CounterEnumType.ENERGY); - experienceCounters = player.getCounters(CounterEnumType.EXPERIENCE); - - //when gui player loses life, vibrate device for a length of time based on amount of life lost - if (vibrateDuration > 0 && MatchController.instance.isLocalPlayer(player) && - FModel.getPreferences().getPrefBoolean(FPref.UI_VIBRATE_ON_LIFE_LOSS)) { - //never vibrate more than two seconds regardless of life lost or poison counters gained - Gdx.input.vibrate(Math.min(vibrateDuration, 2000)); - } - } - - @Override - public boolean tap(float x, float y, int count) { - MatchController.instance.getGameController().selectPlayer(player, null); //treat tapping on life the same as tapping on the avatar - return true; - } - - @Override - public void draw(Graphics g) { - adjustHeight = 1; - float divider = Gdx.app.getGraphics().getHeight() > 900 ? 1.2f : 2f; - if(Forge.altPlayerLayout && !Forge.altZoneTabs && Forge.isLandscapeMode()) { - if (poisonCounters == 0 && energyCounters == 0 && experienceCounters == 0) { - g.fillRect(Color.DARK_GRAY, 0, 0, INFO2_FONT.getBounds(lifeStr).width+1, INFO2_FONT.getBounds(lifeStr).height+1); - g.drawText(lifeStr, INFO2_FONT, INFO_FORE_COLOR.getColor(), 0, 0, getWidth(), getHeight(), false, Align.left, false); - } else { - float halfHeight = getHeight() / divider; - float textStart = halfHeight + Utils.scale(1); - float textWidth = getWidth() - textStart; - int mod = 1; - g.fillRect(Color.DARK_GRAY, 0, 0, INFO_FONT.getBounds(lifeStr).width+halfHeight+1, INFO_FONT.getBounds(lifeStr).height+1); - g.drawImage(FSkinImage.QUEST_LIFE, 0, 0, halfHeight, halfHeight); - g.drawText(lifeStr, INFO_FONT, INFO_FORE_COLOR.getColor(), textStart, 0, textWidth, halfHeight, false, Align.left, false); - if (poisonCounters > 0) { - g.fillRect(Color.DARK_GRAY, 0, halfHeight+2, INFO_FONT.getBounds(String.valueOf(poisonCounters)).width+halfHeight+1, INFO_FONT.getBounds(String.valueOf(poisonCounters)).height+1); - g.drawImage(FSkinImage.POISON, 0, halfHeight+2, halfHeight, halfHeight); - g.drawText(String.valueOf(poisonCounters), INFO_FONT, INFO_FORE_COLOR.getColor(), textStart, halfHeight+2, textWidth, halfHeight, false, Align.left, false); - mod+=1; - } - if (energyCounters > 0) { - g.fillRect(Color.DARK_GRAY, 0, (halfHeight*mod)+2, INFO_FONT.getBounds(String.valueOf(energyCounters)).width+halfHeight+1, INFO_FONT.getBounds(String.valueOf(energyCounters)).height+1); - g.drawImage(FSkinImage.ENERGY, 0, (halfHeight*mod)+2, halfHeight, halfHeight); - g.drawText(String.valueOf(energyCounters), INFO_FONT, INFO_FORE_COLOR.getColor(), textStart, (halfHeight*mod)+2, textWidth, halfHeight, false, Align.left, false); - mod+=1; - } - if (experienceCounters > 0) { - g.fillRect(Color.DARK_GRAY, 0, (halfHeight*mod)+2, INFO_FONT.getBounds(String.valueOf(experienceCounters)).width+halfHeight+1, INFO_FONT.getBounds(String.valueOf(experienceCounters)).height+1); - g.drawImage(FSkinImage.COMMANDER, 0, (halfHeight*mod)+2, halfHeight, halfHeight); - g.drawText(String.valueOf(experienceCounters), INFO_FONT, INFO_FORE_COLOR.getColor(), textStart, (halfHeight*mod)+2, textWidth, halfHeight, false, Align.left, false); - mod+=1; - } - adjustHeight = (mod > 2) && (avatar.getHeight() < halfHeight*mod)? mod : 1; - } - } else { - if (poisonCounters == 0 && energyCounters == 0) { - g.drawText(lifeStr, Forge.altZoneTabs ? LIFE_FONT_ALT : LIFE_FONT, INFO_FORE_COLOR, 0, 0, getWidth(), getHeight(), false, Align.center, true); - } else { - float halfHeight = getHeight() / 2; - float textStart = halfHeight + Utils.scale(1); - float textWidth = getWidth() - textStart; - g.drawImage(FSkinImage.QUEST_LIFE, 0, 0, halfHeight, halfHeight); - g.drawText(lifeStr, INFO_FONT, INFO_FORE_COLOR, textStart, 0, textWidth, halfHeight, false, Align.center, true); - if (poisonCounters > 0) { //prioritize showing poison counters over energy counters - g.drawImage(FSkinImage.POISON, 0, halfHeight, halfHeight, halfHeight); - g.drawText(String.valueOf(poisonCounters), INFO_FONT, INFO_FORE_COLOR, textStart, halfHeight, textWidth, halfHeight, false, Align.center, true); - } else { - g.drawImage(FSkinImage.ENERGY, 0, halfHeight, halfHeight, halfHeight); - g.drawText(String.valueOf(energyCounters), INFO_FONT, INFO_FORE_COLOR, textStart, halfHeight, textWidth, halfHeight, false, Align.center, true); - } - } - } - } - } - - public class InfoTab extends FDisplayObject { - private String value = "0"; - private final FSkinImage icon; - private final VDisplayArea displayArea; - - private InfoTab(FSkinImage icon0, VDisplayArea displayArea0) { - icon = icon0; - displayArea = displayArea0; - } - - public FSkinImage getIcon() { - return icon; - } - public VDisplayArea getDisplayArea() { - return displayArea; - } - - @Override - public boolean tap(float x, float y, int count) { - if (selectedTab == this) { - setSelectedTab(null); - } - else { - setSelectedTab(this); - } - return true; - } - - public void update() { - displayArea.update(); - value = String.valueOf(displayArea.getCount()); - } - - @Override - public void draw(Graphics g) { - float x, y, w, h; - - if (selectedTab == this) { - y = 0; - w = getWidth(); - h = getHeight(); - float yAcross; - if (isFlipped()) { - y += INFO_TAB_PADDING_Y; - yAcross = y; - y--; - h++; - } else { - h -= INFO_TAB_PADDING_Y; - yAcross = h; - y--; - h += 2; - } - //change the graveyard tab selection color to active phase color to indicate the player has delirium - if ((icon == FSkinImage.HDGRAVEYARD || icon == FSkinImage.GRAVEYARD) && player.hasDelirium()) { - g.fillRect(DELIRIUM_HIGHLIGHT, 0 ,isFlipped() ? INFO_TAB_PADDING_Y : 0, w, getHeight() - INFO_TAB_PADDING_Y); - } else { - g.fillRect(DISPLAY_AREA_BACK_COLOR, 0, isFlipped() ? INFO_TAB_PADDING_Y : 0, w, getHeight() - INFO_TAB_PADDING_Y); - } - if (!Forge.isLandscapeMode()) { - if (isFlipped()) { //use clip to ensure all corners connect - g.startClip(-1, y, w + 2, h); - } else { - g.startClip(-1, y, w + 2, yAcross - y); - } - if (forMultiPlayer) { - g.drawLine(1, MatchScreen.BORDER_COLOR, 0, yAcross, w, yAcross); - g.drawLine(1, MatchScreen.BORDER_COLOR, 0, y, 0, h); - g.drawLine(1, MatchScreen.BORDER_COLOR, w, y, w, h); - } - g.endClip(); - } - } - - //show image left of text if wider than tall - if (getWidth() > getHeight()) { - float maxImageWidth = getWidth() - INFO_FONT.getBounds("0").width - 3 * INFO_TAB_PADDING_X; - w = icon.getNearestHQWidth(maxImageWidth); - if (w > maxImageWidth) { - w /= 2; - } - h = icon.getHeight() * w / icon.getWidth(); - float maxImageHeight = getHeight() - 2 * INFO_TAB_PADDING_Y; - if (h > maxImageHeight) { - h = icon.getNearestHQHeight(maxImageHeight); - if (h > maxImageWidth) { - h /= 2; - } - w = icon.getWidth() * h / icon.getHeight(); - } - x = INFO_TAB_PADDING_X + (maxImageWidth - w) / 2; - y = (getHeight() - h) / 2; - if (lblLife.getRotate180()) { - g.startRotateTransform(x + w / 2, y + h / 2, 180); - } - g.drawImage(icon, x, y, w, h); - if (lblLife.getRotate180()) { - g.endTransform(); - } - - x += w + INFO_TAB_PADDING_X; - int alignX = Align.left; - if (lblLife.getRotate180()) { - g.startRotateTransform(x + (getWidth() - x + 1) / 2, getHeight() / 2, 180); - alignX = Align.right; - } - g.drawText(value, INFO_FONT, INFO_FORE_COLOR, x, 0, getWidth() - x + 1, getHeight(), false, alignX, true); - if (lblLife.getRotate180()) { - g.endTransform(); - } - } else { //show image above text if taller than wide - if (lblLife.getRotate180()) { - g.startRotateTransform(getWidth() / 2, getHeight() / 2, 180); - } - float maxImageWidth = getWidth() - 2 * INFO_TAB_PADDING_X; - w = icon.getNearestHQWidth(maxImageWidth); - if (w > maxImageWidth) { - w /= 2; - } - h = icon.getHeight() * w / icon.getWidth(); - x = (getWidth() - w) / 2; - y = INFO_TAB_PADDING_Y; - g.drawImage(icon, x, y, w, h); - - y += h + INFO_TAB_PADDING_Y; - g.drawText(value, INFO_FONT, INFO_FORE_COLOR, 0, y, getWidth(), getHeight() - y + 1, false, Align.center, false); - if (lblLife.getRotate180()) { - g.endTransform(); - } - } - } - } - - private class CommandZoneDisplay extends VZoneDisplay { - private CommandZoneDisplay(PlayerView player0) { - super(player0, ZoneType.Command); - } - - @Override - protected void refreshCardPanels(Iterable model) { - int oldCount = getCount(); - super.refreshCardPanels(model); - int newCount = getCount(); - if (newCount != oldCount) { - setVisible(newCount > 0); - VPlayerPanel.this.revalidate(); //need to revalidated entire panel when command zone size changes - } - } - - @Override - protected boolean layoutVerticallyForLandscapeMode() { - return false; - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VPlayers.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VPlayers.java deleted file mode 100644 index a57554b38a6..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VPlayers.java +++ /dev/null @@ -1,74 +0,0 @@ -package forge.adventure.libgdxgui.screens.match.views; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FImage; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.game.player.PlayerView; -import forge.adventure.libgdxgui.menu.FDropDown; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.toolbox.FContainer; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.toolbox.FList; -import forge.adventure.libgdxgui.util.Utils; - -public class VPlayers extends FDropDown { - public VPlayers() { - for (final PlayerView p : MatchController.instance.getGameView().getPlayers()) { - add(new PlayerInfoPanel(p)); - } - } - - @Override - protected boolean autoHide() { - return true; - } - - @Override - protected ScrollBounds updateAndGetPaneSize(float maxWidth, float maxVisibleHeight) { - float totalHeight = getChildCount() * PlayerInfoPanel.HEIGHT; - float y = totalHeight - PlayerInfoPanel.HEIGHT; - //display in reverse order so gui player on bottom - for (FDisplayObject panel : getChildren()) { - panel.setBounds(0, y, maxWidth, PlayerInfoPanel.HEIGHT); - y -= PlayerInfoPanel.HEIGHT; - } - return new ScrollBounds(maxWidth, totalHeight); - } - - private static class PlayerInfoPanel extends FContainer { - private static final FSkinFont FONT = FSkinFont.get(12); - private static final float PADDING = Utils.scale(5); - private static final float HEIGHT = Utils.AVG_FINGER_HEIGHT * 1.8f; - private final PlayerView player; - - private PlayerInfoPanel(PlayerView player0) { - player = player0; - } - - @Override - protected void doLayout(float width, float height) { - //TODO: Add FLabels to click to select player in top or bottom panel of Match screen - } - - @Override - public void drawBackground(Graphics g) { - float x = PADDING; - float y = PADDING; - float h = getHeight() - 2 * y; - - FImage avatarImage = MatchController.getPlayerAvatar(player); - g.drawImage(avatarImage, x, y, h, h); - x += h + PADDING; - - g.drawText(player.getDetails(), FONT, FList.FORE_COLOR, x, y, getWidth() - PADDING - x, h, true, Align.left, true); - } - - @Override - public void drawOverlay(Graphics g) { - //draw bottom border - float y = getHeight(); - g.drawLine(1, FList.LINE_COLOR, 0, y, getWidth(), y); - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VPrompt.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VPrompt.java deleted file mode 100644 index 66a6f2bcf92..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VPrompt.java +++ /dev/null @@ -1,130 +0,0 @@ -package forge.adventure.libgdxgui.screens.match.views; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.TextRenderer; -import forge.adventure.libgdxgui.card.CardZoom; -import forge.game.card.CardView; -import forge.adventure.libgdxgui.menu.FMagnifyView; -import forge.adventure.libgdxgui.toolbox.FButton; -import forge.adventure.libgdxgui.toolbox.FButton.Corner; -import forge.adventure.libgdxgui.toolbox.FContainer; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.util.TextBounds; -import forge.adventure.libgdxgui.util.Utils; -import org.apache.commons.lang3.StringUtils; - -public class VPrompt extends FContainer { - public static final float HEIGHT = Utils.AVG_FINGER_HEIGHT; - public static final float BTN_WIDTH = HEIGHT * 1.5f; - public static final float PADDING = Utils.scale(2); - public static final FSkinFont FONT = FSkinFont.get(14); - public static final FSkinColor BACK_COLOR = FSkinColor.get(Colors.CLR_THEME2); - public static final FSkinColor FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT); - - private final FButton btnOk, btnCancel; - private final MessageLabel lblMessage; - private String message; - private CardView card = null ; - - public void setCardView(final CardView card) { - this.card = card ; - } - - public VPrompt(String okText, String cancelText, FEventHandler okCommand, FEventHandler cancelCommand) { - lblMessage = add(new MessageLabel()); - lblMessage.setLeft(BTN_WIDTH); - lblMessage.setHeight(HEIGHT); - btnOk = add(new FButton(okText, okCommand)); - btnCancel = add(new FButton(cancelText, cancelCommand)); - btnOk.setSize(BTN_WIDTH, HEIGHT); - btnCancel.setSize(BTN_WIDTH, HEIGHT); - btnOk.setCorner(Corner.BottomLeft); - btnCancel.setCorner(Corner.BottomRight); - btnOk.setEnabled(false); //disable buttons until first input queued - btnCancel.setEnabled(false); - } - - public FButton getBtnOk() { - return btnOk; - } - - public FButton getBtnCancel() { - return btnCancel; - } - - public String getMessage() { - return message; - } - public void setMessage(String message0) { - message = message0; - card = null ; - } - public void setMessage(String message0, CardView card0) { - message = message0; - card = card0; - } - - /** Flashes animation on input panel if play is currently waiting on input. */ - public void remind() { - //SDisplayUtil.remind(view); - } - - @Override - protected void doLayout(float width, float height) { - lblMessage.setWidth(width - 2 * BTN_WIDTH); - btnCancel.setLeft(lblMessage.getRight()); - } - - @Override - protected void drawBackground(Graphics g) { - g.fillRect(BACK_COLOR, 0, 0, getWidth(), getHeight()); - } - - private class MessageLabel extends FDisplayObject { - private final TextRenderer renderer = new TextRenderer(); - - @Override - public boolean tap(float x, float y, int count) { - //if not enough room for prompt at given size, show magnify view - float maxWidth = getWidth() - 2 * PADDING; - float maxHeight = getHeight() - 2 * PADDING; - TextBounds textBounds = renderer.getWrappedBounds(message, FONT, maxWidth); - if (textBounds.height > maxHeight) { - FMagnifyView.show(this, message, FORE_COLOR, BACK_COLOR, FONT, false); - } - return true; - } - - @Override - public boolean fling(float x, float y) { - if ( card != null ) { - CardZoom.show(card); - } - return true; - } - - @Override - public boolean longPress(float x, float y) { - if ( card != null ) { - CardZoom.show(card); - } - return true; - } - - @Override - public void draw(Graphics g) { - if (!StringUtils.isEmpty(message)) { - float x = PADDING; - float y = PADDING; - float w = getWidth() - 2 * PADDING; - float h = getHeight() - 2 * PADDING; - renderer.drawText(g, message, FONT, FORE_COLOR, x, y, w, h, y, h, true, Align.center, true); - } - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VStack.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VStack.java deleted file mode 100644 index 1c2ee262b9d..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VStack.java +++ /dev/null @@ -1,428 +0,0 @@ -package forge.adventure.libgdxgui.screens.match.views; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.TextRenderer; -import forge.adventure.libgdxgui.card.CardRenderer; -import forge.adventure.libgdxgui.card.CardRenderer.CardStackPosition; -import forge.adventure.libgdxgui.card.CardZoom; -import forge.game.GameView; -import forge.game.card.CardView; -import forge.game.player.PlayerView; -import forge.game.spellability.StackItemView; -import forge.game.zone.ZoneType; -import forge.gui.card.CardDetailUtil; -import forge.gui.card.CardDetailUtil.DetailColors; -import forge.gui.interfaces.IGuiGame; -import forge.interfaces.IGameController; -import forge.adventure.libgdxgui.menu.*; -import forge.player.PlayerZoneUpdates; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.screens.match.TargetingOverlay; -import forge.adventure.libgdxgui.toolbox.FCardPanel; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.toolbox.FEvent; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.toolbox.FLabel; -import forge.util.Localizer; -import forge.util.TextUtil; -import forge.adventure.libgdxgui.util.Utils; -import forge.util.collect.FCollectionView; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -public class VStack extends FDropDown { - public static final float CARD_WIDTH = Utils.AVG_FINGER_WIDTH; - public static final float CARD_HEIGHT = Math.round(CARD_WIDTH * FCardPanel.ASPECT_RATIO); - public static final float BORDER_THICKNESS = Utils.scale(2); - public static final float PADDING = Utils.scale(3); - public static final float MARGINS = Utils.scale(4); - private static final FSkinFont FONT = FSkinFont.get(11); - private static final float ALPHA_COMPOSITE = 0.5f; - private static final TextRenderer textRenderer = new TextRenderer(true); - - private StackInstanceDisplay activeItem; - private StackItemView activeStackInstance; - private Map playersWithValidTargets; - private PlayerZoneUpdates restorablePlayerZones = null; - - private int stackSize; - - public VStack() { - } - - @Override - protected boolean autoHide() { - return false; - } - - //temporarily reveal zones targeted by active stack instance - private void revealTargetZones() { - if (activeStackInstance == null) { return; } - - PlayerView player = MatchController.instance.getCurrentPlayer(); - - final Set zones = new HashSet<>(); - playersWithValidTargets = new HashMap<>(); - for (final CardView c : activeStackInstance.getTargetCards()) { - if (c.getZone() != null) { - zones.add(c.getZone()); - playersWithValidTargets.put(c.getController(), c); - } - } - if (zones.isEmpty() || playersWithValidTargets.isEmpty()) { return; } - restorablePlayerZones = MatchController.instance.openZones(player, zones, playersWithValidTargets); - } - - //restore old zones when active stack instance changes - private void restoreOldZones() { - if (restorablePlayerZones == null) { return; } - PlayerView player = MatchController.instance.getCurrentPlayer(); - MatchController.instance.restoreOldZones(player, restorablePlayerZones); - restorablePlayerZones = null; - } - - public void checkEmptyStack() { //sort the bug in client when desynch happens - final FCollectionView stack = MatchController.instance.getGameView().getStack(); - if(stack!=null) - if(isVisible() && stack.isEmpty()) { //visible stack but empty already - hide(); - getMenuTab().setText(Localizer.getInstance().getMessage("lblStack") + " (" + 0 + ")"); - } - } - - @Override - public void update() { - activeItem = null; - activeStackInstance = null; //reset before updating stack - restoreOldZones(); - - final FCollectionView stack = MatchController.instance.getGameView().getStack(); - if (stackSize != stack.size()) { - int oldStackSize = stackSize; - stackSize = stack.size(); - getMenuTab().setText(Localizer.getInstance().getMessage("lblStack") + " (" + stackSize + ")"); - - if (stackSize > 0) { - if (!isVisible()) { - if (stackSize > oldStackSize) { //don't re-show stack if user hid it and then resolved an item on the stack - show(); - } - return; //don't call super.update() either way since show handles this - } - } - else { - hide(); - return; //super.update() isn't needed if hidden - } - } - super.update(); - } - - @Override - protected ScrollBounds updateAndGetPaneSize(float maxWidth, float maxVisibleHeight) { - clear(); - - float x = MARGINS; - float y = MARGINS; - float totalWidth; - if (Forge.isLandscapeMode()) { - totalWidth = Forge.getScreenWidth() * 0.35f; - } - else { - totalWidth = maxWidth - MatchController.getView().getTopPlayerPanel().getTabs().iterator().next().getRight(); //keep avatar, life total, and hand tab visible to left of stack - } - float width = totalWidth - 2 * MARGINS; - - final FCollectionView stack = MatchController.instance.getGameView().getStack(); - if (stack.isEmpty()) { //show label if stack empty - FLabel label = add(new FLabel.Builder().text("[" + Localizer.getInstance().getMessage("lblEmpty") + "]").font(FONT).align(Align.center).build()); - - float height = Math.round(label.getAutoSizeBounds().height) + 2 * PADDING; - label.setBounds(x, y, width, height); - return new ScrollBounds(totalWidth, y + height + MARGINS); - } - else { - //iterate stack in reverse so most recent items appear on bottom - StackItemView stackInstance = null; - StackInstanceDisplay display = null; - float overlap = Math.round(CARD_HEIGHT / 2 + PADDING + BORDER_THICKNESS); - for (int i = stack.size() - 1; i >= 0; i--) { - stackInstance = stack.get(i); - display = new StackInstanceDisplay(stackInstance, width); - if (activeStackInstance == stackInstance) { - activeItem = display; - } - else { //only add non-active items here - add(display); - } - //use full preferred height of display for topmost item on stack, overlap amount for other items - display.setBounds(x, y, width, i > 0 ? overlap : display.preferredHeight); - y += display.getHeight(); - } - if (activeStackInstance == null) { - activeStackInstance = stackInstance; //use topmost item on stack as default active item - activeItem = display; - } - else { - activeItem.setHeight(display.preferredHeight); //increase active item height to preferred height if needed - if (activeItem.getBottom() > y) { - y = activeItem.getBottom(); //ensure stack height increases if needed - } - add(activeItem); - } - scrollIntoView(activeItem); //scroll active display into view - revealTargetZones(); - } - return new ScrollBounds(totalWidth, y + MARGINS); - } - - protected void updateSizeAndPosition() { - if (!getRotate90()) { - super.updateSizeAndPosition(); - return; - } - - FMenuTab menuTab = getMenuTab(); - float screenHeight = Forge.getScreenHeight(); - float width = (screenHeight - 2 * VPrompt.HEIGHT - 2 * VAvatar.HEIGHT) * 4f / 6f; - float maxVisibleHeight = menuTab.screenPos.x; - paneSize = updateAndGetPaneSize(width + MatchController.getView().getTopPlayerPanel().getTabs().iterator().next().getRight(), maxVisibleHeight); - - //round width and height so borders appear properly - paneSize = new ScrollBounds(Math.round(paneSize.getWidth()), Math.round(paneSize.getHeight())); - - setBounds(Math.round(menuTab.screenPos.x - width), Math.round((screenHeight + width) / 2), paneSize.getWidth(), Math.min(paneSize.getHeight(), maxVisibleHeight)); - } - - @Override - protected void setScrollPositionsAfterLayout(float scrollLeft0, float scrollTop0) { - super.setScrollPositionsAfterLayout(0, 0); //always scroll to top after layout - } - - @Override - protected void drawOnContainer(Graphics g) { - //draw target arrows immediately above stack for active item only - if (activeItem != null) { - Vector2 arrowOrigin = new Vector2( - activeItem.getLeft() + VStack.CARD_WIDTH * FCardPanel.TARGET_ORIGIN_FACTOR_X + VStack.PADDING + VStack.BORDER_THICKNESS, - activeItem.getTop() + VStack.CARD_HEIGHT * FCardPanel.TARGET_ORIGIN_FACTOR_Y + VStack.PADDING + VStack.BORDER_THICKNESS); - - PlayerView activator = activeStackInstance.getActivatingPlayer(); - arrowOrigin = arrowOrigin.add(screenPos.x, screenPos.y); - - StackItemView instance = activeStackInstance; - while (instance != null) { - for (CardView c : instance.getTargetCards()) { - TargetingOverlay.ArcConnection conn = activator.isOpponentOf(c.getController()) ? TargetingOverlay.ArcConnection.FoesStackTargeting : TargetingOverlay.ArcConnection.FriendsStackTargeting; - TargetingOverlay.drawArrow(g, arrowOrigin, c, conn); - } - for (PlayerView p : instance.getTargetPlayers()) { - TargetingOverlay.ArcConnection conn = activator.isOpponentOf(p) ? TargetingOverlay.ArcConnection.FoesStackTargeting : TargetingOverlay.ArcConnection.FriendsStackTargeting; - TargetingOverlay.drawArrow(g, arrowOrigin, p, conn); - } - instance = instance.getSubInstance(); - } - } - } - - private class StackInstanceDisplay extends FDisplayObject { - private final StackItemView stackInstance; - private final Color foreColor, backColor; - private String text; - private final float preferredHeight; - - private StackInstanceDisplay(StackItemView stackInstance0, float width) { - stackInstance = stackInstance0; - CardView card = stackInstance.getSourceCard(); - - text = stackInstance.getText(); - if (stackInstance.isOptionalTrigger() && - stackInstance0.getActivatingPlayer().equals(MatchController.instance.getCurrentPlayer())) { - text = "(OPTIONAL) " + text; - } - - // TODO: A hacky workaround is currently used to make the game not leak the color information for Morph cards. - final boolean isFaceDown = card.isFaceDown(); - final DetailColors color = isFaceDown ? DetailColors.FACE_DOWN : CardDetailUtil.getBorderColor(card.getCurrentState(), true); // otherwise doesn't work correctly for face down Morphs - backColor = FSkinColor.fromRGB(color.r, color.g, color.b); - foreColor = FSkinColor.getHighContrastColor(backColor); - - width -= CARD_WIDTH; //account for card picture - width -= 3 * PADDING + 2 * BORDER_THICKNESS; //account for left and right insets and gap between picture and text - float height = Math.max(CARD_HEIGHT, textRenderer.getWrappedBounds(text, FONT, width).height); - height += 2 * (PADDING + BORDER_THICKNESS); - preferredHeight = Math.round(height); - } - - @Override - public boolean tap(float x, float y, int count) { - if (activeStackInstance != stackInstance) { //set as active stack instance if not already such - activeStackInstance = stackInstance; - restoreOldZones(); //restore old zones before changing active stack instance - VStack.this.updateSizeAndPosition(); - return true; - } - final GameView gameView = MatchController.instance.getGameView(); - final IGuiGame gui = MatchController.instance; - final IGameController controller = MatchController.instance.getGameController(); - final PlayerView player = MatchController.instance.getCurrentPlayer(); - if (player != null) { //don't show menu if tapping on art - if (stackInstance.isAbility()) { - FPopupMenu menu = new FPopupMenu() { - @Override - protected void buildMenu() { - final String key = stackInstance.getKey(); - final boolean autoYield = gui.shouldAutoYield(key); - addItem(new FCheckBoxMenuItem(Localizer.getInstance().getMessage("cbpAutoYieldMode"), autoYield, - new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - gui.setShouldAutoYield(key, !autoYield); - if (!autoYield && stackInstance.equals(gameView.peekStack())) { - //auto-pass priority if ability is on top of stack - controller.passPriority(); - } - } - })); - if (stackInstance.isOptionalTrigger() && stackInstance.getActivatingPlayer().equals(player)) { - final int triggerID = stackInstance.getSourceTrigger(); - addItem(new FCheckBoxMenuItem(Localizer.getInstance().getMessage("lblAlwaysYes"), - gui.shouldAlwaysAcceptTrigger(triggerID), - new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - if (gui.shouldAlwaysAcceptTrigger(triggerID)) { - gui.setShouldAlwaysAskTrigger(triggerID); - } - else { - gui.setShouldAlwaysAcceptTrigger(triggerID); - if (stackInstance.equals(gameView.peekStack())) { - //auto-yes if ability is on top of stack - controller.selectButtonOk(); - } - } - } - })); - addItem(new FCheckBoxMenuItem(Localizer.getInstance().getMessage("lblAlwaysNo"), - gui.shouldAlwaysDeclineTrigger(triggerID), - new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - if (gui.shouldAlwaysDeclineTrigger(triggerID)) { - gui.setShouldAlwaysAskTrigger(triggerID); - } - else { - gui.setShouldAlwaysDeclineTrigger(triggerID); - if (stackInstance.equals(gameView.peekStack())) { - //auto-no if ability is on top of stack - controller.selectButtonCancel(); - } - } - } - })); - } - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblZoomOrDetails"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - CardZoom.show(stackInstance.getSourceCard()); - } - })); - } - }; - - menu.show(this, x, y); - return true; - } - } - CardZoom.show(stackInstance.getSourceCard()); - return true; - } - - @Override - public boolean longPress(float x, float y) { - CardZoom.show(stackInstance.getSourceCard()); - return true; - } - - @Override - public void draw(Graphics g) { - float x = 0; - float y = 0; - float w = getWidth(); - float h = preferredHeight; - CardView sourceCard = stackInstance.getSourceCard(); - - boolean needAlpha = (activeStackInstance != stackInstance); - if (needAlpha) { //use alpha for non-active items on stack - g.setAlphaComposite(ALPHA_COMPOSITE); - } - - g.startClip(0, 0, w, getHeight()); //clip based on actual height - - g.fillRect(Color.BLACK, x, y, w, h); //draw rectangle for border - - x += BORDER_THICKNESS; - y += BORDER_THICKNESS; - w -= 2 * BORDER_THICKNESS; - h -= 2 * BORDER_THICKNESS; - g.fillRect(backColor, x, y, w, h); - - x += PADDING; - y += PADDING; - CardRenderer.drawCardWithOverlays(g, sourceCard, x, y, CARD_WIDTH, CARD_HEIGHT, CardStackPosition.Top, true, false, false); - - x += CARD_WIDTH + PADDING; - w -= x + PADDING - BORDER_THICKNESS; - h -= y + PADDING - BORDER_THICKNESS; - - String name = sourceCard.getName(); - int index = text.indexOf(name); - String newtext = ""; - String cId = "(" + sourceCard.getId() + ")"; - String optionalCostString = !stackInstance.getOptionalCostString().equals("") ? " ("+ stackInstance.getOptionalCostString() + ")" : ""; - - if (index == -1) { - newtext = TextUtil.fastReplace(text.trim(), " ", " "); - newtext = TextUtil.fastReplace(TextUtil.fastReplace(newtext,"--","-"),"- -","-"); - newtext = TextUtil.fastReplace(TextUtil.fastReplace(newtext, " and .", ".")," .", "."); - newtext = TextUtil.fastReplace(TextUtil.fastReplace(newtext, "- - ", "- "), ". .", "."); - newtext = TextUtil.fastReplace(newtext, "CARDNAME", name); - textRenderer.drawText(g, name + " " + (name.length() > 1 ? cId : "") + optionalCostString + "\n" + (newtext.length() > 1 ? newtext : ""), - FONT, foreColor, x, y, w, h, y, h, true, Align.left, true); - - } else { - String modifier = (text.substring(0, index).length() > 0) ? "CARDNAME" : ""; - String trimFirst = TextUtil.fastReplace("\n" + text.substring(0, index) + modifier + text.substring(index + name.length()), "- -", "-"); - String trimSecond = TextUtil.fastReplace(trimFirst, name+" "+cId, name); - newtext = TextUtil.fastReplace(trimSecond, " "+cId, name); - - if(newtext.equals("\n"+name)) - textRenderer.drawText(g, name + " " + cId + optionalCostString, FONT, foreColor, x, y, w, h, y, h, true, Align.left, true); - else { - newtext = TextUtil.fastReplace(newtext, " ", " "); - newtext = TextUtil.fastReplace(TextUtil.fastReplace(newtext,name+" -","-"), "\n ", "\n"); - newtext = "\n"+ TextUtil.fastReplace(newtext.trim(),"--","-"); - newtext = TextUtil.fastReplace(TextUtil.fastReplace(newtext, " and .", ".")," .", "."); - newtext = TextUtil.fastReplace(TextUtil.fastReplace(newtext, "- - ", "- "), ". .", "."); - newtext = TextUtil.fastReplace(newtext, "CARDNAME", name); - textRenderer.drawText(g, name+" "+cId + optionalCostString +newtext, FONT, foreColor, x, y, w, h, y, h, true, Align.left, true); - } - } - - g.endClip(); - - if (needAlpha) { - g.resetAlphaComposite(); - } - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VZoneDisplay.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VZoneDisplay.java deleted file mode 100644 index 873ceeaa723..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/views/VZoneDisplay.java +++ /dev/null @@ -1,210 +0,0 @@ -package forge.adventure.libgdxgui.screens.match.views; - -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.game.player.PlayerView; -import forge.game.zone.ZoneType; -import forge.adventure.libgdxgui.toolbox.FCardPanel; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; - -import java.util.List; - -public class VZoneDisplay extends VCardDisplayArea { - private final PlayerView player; - private final ZoneType zoneType; - private FCardPanel revealedPanel; - - public VZoneDisplay(PlayerView player0, ZoneType zoneType0) { - player = player0; - zoneType = zoneType0; - } - - public ZoneType getZoneType() { - return zoneType; - } - - @Override - public void update() { - refreshCardPanels(player.getCards(zoneType)); - } - - @Override - public void buildTouchListeners(float screenX, float screenY, List listeners) { - super.buildTouchListeners(screenX, screenY, listeners); - - if (revealedPanel != null) { - float x = screenToLocalX(screenX); - float y = screenToLocalY(screenY); - if (revealedPanel.contains(x, y)) { return; } - - int idx = cardPanels.size() - 1; - for (int i = getChildCount() - 2; i >= 0; i--) { - final FDisplayObject cardPanel = getChildAt(i); - if (cardPanel.contains(x, y)) { - idx = cardPanels.indexOf(cardPanel); - break; - } - } - setRevealedPanel(idx); - } - } - - @Override - public boolean pan(float x, float y, float deltaX, float deltaY, boolean moreVertical) { - if (revealedPanel == null) { //if no overlapping panels, just pan scroll as normal - return super.pan(x, y, deltaX, deltaY, moreVertical); - } - int idx = cardPanels.size() - 1; - for (int i = idx - 1; i >= 0; i--) { - if (cardPanels.get(i).contains(x, y)) { - idx = i; - break; - } - } - setRevealedPanel(idx); - return true; - } - - private void setRevealedPanel(int idx) { - try { - revealedPanel = cardPanels.get(idx); //on network match, when zoomed and cast a card would randomly trigger the bug - } catch (Exception e) { //before it was arrayindexoutofbounds, then indexoutofbounds, so just use a general exception - e.printStackTrace(); - return; - } - clearChildren(); - if (Forge.isLandscapeMode()) { - //for landscape mode, just show revealed card on top - for (CardAreaPanel cardPanel : cardPanels) { - if (cardPanel != revealedPanel) { - add(cardPanel); - } - } - } - else { - //for portrait mode, cascade cards back from revealed panel - int maxIdx = cardPanels.size() - 1; - int offset = Math.max(idx, maxIdx - idx); - for (int i = offset; i > 0; i--) { - int idx1 = idx - i; - int idx2 = idx + i; - if (idx1 >= 0) { - add(cardPanels.get(idx1)); - } - if (idx2 <= maxIdx) { - add(cardPanels.get(idx2)); - } - } - } - add(revealedPanel); - } - - @Override - public void setSelectedIndex(int index) { - if (revealedPanel == null) { - super.setSelectedIndex(index); - } - setRevealedPanel(index); - } - - @Override - public void clear() { - revealedPanel = null; - super.clear(); - } - - protected boolean layoutVerticallyForLandscapeMode() { - return true; - } - - @Override - protected ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) { - if (!isVisible()) { //if zone not visible, don't spend time laying out cards - return new ScrollBounds(visibleWidth, visibleHeight); - } - - orderedCards.clear(); - - if (Forge.isLandscapeMode() && layoutVerticallyForLandscapeMode()) { - return layoutAndGetScrollBoundsLandscape(visibleWidth, visibleHeight); - } - - float x = 0; - float y = 0; - float cardHeight = visibleHeight; - float cardWidth = getCardWidth(cardHeight); - float dx = cardWidth; - - float totalWidth = cardWidth * cardPanels.size(); - if (totalWidth > visibleWidth && totalWidth <= visibleWidth * 2) { - //allow overlapping cards up to one half of the card, - //otherwise don't overlap and allow scrolling horizontally - dx *= (visibleWidth - cardWidth) / (totalWidth - cardWidth); - dx += FCardPanel.PADDING / cardPanels.size(); //make final card go right up to right edge of screen - if (revealedPanel == null) { - revealedPanel = cardPanels.get(cardPanels.size() - 1); - } - } - else { - revealedPanel = null; - } - - for (CardAreaPanel cardPanel : cardPanels) { - orderedCards.add(cardPanel.getCard()); - cardPanel.setBounds(x, y, cardWidth, cardHeight); - x += dx; - } - - return new ScrollBounds(x, visibleHeight); - } - - private ScrollBounds layoutAndGetScrollBoundsLandscape(float visibleWidth, float visibleHeight) { - float x = 0; - float y = 0; - float cardWidth = visibleWidth / 2; - float cardHeight = getCardHeight(cardWidth); - float dy = cardHeight; - float scrollHeight; - - int rowCount = (int)Math.ceil((float)cardPanels.size() / 2f); - float totalHeight = cardHeight * rowCount; - if (totalHeight > visibleHeight && totalHeight <= visibleHeight * 3) { - //allow overlapping cards up to one third of the card, - //otherwise don't overlap and allow scrolling vertically - dy *= (visibleHeight - cardHeight) / (totalHeight - cardHeight); - dy += FCardPanel.PADDING / rowCount; //make final card go right up to right edge of screen - if (revealedPanel == null) { - revealedPanel = cardPanels.get(cardPanels.size() - 1); - } - scrollHeight = visibleHeight; - } - else { - revealedPanel = null; - scrollHeight = rowCount * dy; - } - - for (CardAreaPanel cardPanel : cardPanels) { - orderedCards.add(cardPanel.getCard()); - cardPanel.setBounds(x, y, cardWidth, cardHeight); - if (orderedCards.size() % 2 == 0) { - x = 0; - y += dy; - } - else { - x += cardWidth; - } - } - - return new ScrollBounds(visibleWidth, scrollHeight); - } - - @Override - protected void startClip(Graphics g) { - if (Forge.isLandscapeMode()) { - g.startClip(0, 0, getWidth(), getHeight()); - } - else { - super.startClip(g); - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/ConquestWinLose.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/ConquestWinLose.java deleted file mode 100644 index f8aa656dafa..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/ConquestWinLose.java +++ /dev/null @@ -1,39 +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.adventure.libgdxgui.screens.match.winlose; - -import forge.game.GameView; -import forge.model.FModel; - -public class ConquestWinLose extends ControlWinLose { - public ConquestWinLose(final ViewWinLose view0, GameView lastGame0) { - super(view0, lastGame0); - view0.getBtnContinue().setVisible(false); - view0.getBtnRestart().setVisible(false); - } - - @Override - public final void showRewards() { - FModel.getConquest().showGameOutcome(lastGame, getView()); - } - - @Override - public final void actionOnQuit() { - FModel.getConquest().finishEvent(getView()); - super.actionOnQuit(); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/ControlWinLose.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/ControlWinLose.java deleted file mode 100644 index b883ba33a90..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/ControlWinLose.java +++ /dev/null @@ -1,119 +0,0 @@ -package forge.adventure.libgdxgui.screens.match.winlose; - -import forge.adventure.libgdxgui.Forge; -import forge.game.GameView; -import forge.game.player.PlayerView; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.toolbox.FEvent; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; - -/** - * Default controller for a ViewWinLose object. This class can - * be extended for various game modes to populate the custom - * panel in the win/lose screen. - * - */ -public class ControlWinLose { - private final ViewWinLose view; - protected final GameView lastGame; - private int humancount; - - /** @param v   ViewWinLose - * @param game */ - public ControlWinLose(final ViewWinLose v, GameView game) { - view = v; - lastGame = game; - humancount = 0; - for(PlayerView p: game.getPlayers()){ - if (!p.isAI()) - humancount++; - } - addListeners(); - } - - /** */ - public void addListeners() { - view.getBtnContinue().setCommand(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - actionOnContinue(); - } - }); - - view.getBtnRestart().setCommand(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - actionOnRestart(); - } - }); - - view.getBtnQuit().setCommand(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - actionOnQuit(); - view.getBtnQuit().setEnabled(false); - } - }); - if(humancount == 0) - view.getBtnRestart().setEnabled(false); - } - - /** Action performed when "continue" button is pressed in default win/lose UI. */ - public void actionOnContinue() { - view.hide(); - saveOptions(); - - try { MatchController.getHostedMatch().continueMatch(); - } catch (NullPointerException e) {} - } - - /** Action performed when "restart" button is pressed in default win/lose UI. */ - public void actionOnRestart() { - view.hide(); - saveOptions(); - try { MatchController.getHostedMatch().restartMatch(); - } catch (NullPointerException e) {} - } - - /** Action performed when "quit" button is pressed in default win/lose UI. */ - public void actionOnQuit() { - boolean openHomeScreen = false; - // Reset other stuff - saveOptions(); - try { - if(MatchController.getHostedMatch().subGameCount > 0) { - openHomeScreen = true; - MatchController.getHostedMatch().subGameCount--; - } - MatchController.getHostedMatch().endCurrentGame(); - } catch (NullPointerException e) {} - view.hide(); - if (openHomeScreen || humancount == 0) - Forge.openHomeScreen(Forge.lastButtonIndex); - } - - /** - * Either continues or restarts a current game. May be overridden for use - * with other game modes. - */ - public void saveOptions() { - MatchController.writeMatchPreferences(); - } - - /** - *

- * populateCustomPanel. - *

- * May be overridden as required by controllers for various game modes - * to show custom information in center panel. Default configuration is empty. - * - * @return boolean, panel has contents or not. - */ - public void showRewards() { - } - - /** @return ViewWinLose object this controller is in charge of */ - public ViewWinLose getView() { - return view; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/GauntletWinLose.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/GauntletWinLose.java deleted file mode 100644 index 40a949056a7..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/GauntletWinLose.java +++ /dev/null @@ -1,86 +0,0 @@ -package forge.adventure.libgdxgui.screens.match.winlose; - -import forge.game.GameView; -import forge.gamemodes.gauntlet.GauntletWinLoseController; -import forge.gui.FThreads; -import forge.gui.util.SOptionPane; -import forge.localinstance.skin.FSkinProp; -import forge.util.Localizer; - -import java.util.List; - -/** - * The Win/Lose handler for 'gauntlet' type tournament - * games. - */ -public class GauntletWinLose extends ControlWinLose { - private final GauntletWinLoseController controller; - - /** - * Instantiates a new gauntlet win/lose handler. - * - * @param view0 ViewWinLose object - * @param lastGame - */ - public GauntletWinLose(final ViewWinLose view0, GameView lastGame) { - super(view0, lastGame); - controller = new GauntletWinLoseController(view0, lastGame) { - @Override - protected void showOutcome(final boolean isMatchOver, final String message1, final String message2, final FSkinProp icon, final List lstEventNames, final List lstEventRecords, final int len, final int num) { - if (!isMatchOver) { return; } //don't show progress dialog unless match over - - FThreads.invokeInBackgroundThread(new Runnable() { - @Override - public void run() { - StringBuilder sb = new StringBuilder(); - if (!lstEventNames.isEmpty()) { - for (int i = 0; i < len; i++) { - if (i <= num) { - sb.append(i + 1).append(". ").append(lstEventNames.get(i)).append(" (").append(lstEventRecords.get(i)).append(")\n"); - } else { - sb.append(i + 1).append(". ??????\n"); - } - } - } - - if (message1 != null) { - sb.append("\n"); - sb.append(message1).append("\n\n"); - sb.append(message2); - } - else { - if (sb.length() > 0) { - sb.deleteCharAt(sb.length() - 1); //remove final new line character - } - } - - SOptionPane.showMessageDialog(sb.toString(), Localizer.getInstance().getMessage("lblGauntletProgress"), icon); - } - }); - } - - @Override - protected void saveOptions() { - GauntletWinLose.this.saveOptions(); - } - }; - } - - @Override - public final void showRewards() { - controller.showOutcome(); - } - - @Override - public void actionOnContinue() { - if (!controller.actionOnContinue()) { - super.actionOnContinue(); - } - } - - @Override - public void actionOnQuit() { - super.actionOnQuit(); - controller.actionOnQuit(); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/LimitedWinLose.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/LimitedWinLose.java deleted file mode 100644 index c046672746b..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/LimitedWinLose.java +++ /dev/null @@ -1,81 +0,0 @@ -package forge.adventure.libgdxgui.screens.match.winlose; - -/** 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 . - */ - -import forge.game.GameView; -import forge.gamemodes.limited.LimitedWinLoseController; - -/** - * The Win/Lose handler for 'gauntlet' type tournament - * games. - */ -public class LimitedWinLose extends ControlWinLose { - private final LimitedWinLoseController controller; - - /** - * Instantiates a new limited mode win/lose handler. - * - */ - public LimitedWinLose(final ViewWinLose view0, GameView lastGame) { - super(view0, lastGame); - controller = new LimitedWinLoseController(view0, lastGame) { - @Override - protected void showOutcome(Runnable runnable) { - //invoke reward logic in background thread so dialogs can be shown - //FThreads.invokeInBackgroundThread(runnable); - runnable.run(); //background thread only needed if message shown - } - - @Override - protected void showMessage(String message, String title) { - //avoid showing unnecessary message for mobile game - //TODO: Consider a better way to do this - //SOptionPane.showMessageDialog(message, title); - } - - @Override - protected void saveOptions() { - LimitedWinLose.this.saveOptions(); - } - }; - } - - @Override - public final void showRewards() { - controller.showOutcome(); - } - - @Override - public final void actionOnRestart() { - controller.actionOnRestart(); - super.actionOnRestart(); - } - - @Override - public final void actionOnQuit() { - controller.actionOnQuit(); - super.actionOnQuit(); - } - - @Override - public final void actionOnContinue() { - if (!controller.actionOnContinue()) { - super.actionOnContinue(); - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/QuestDraftWinLose.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/QuestDraftWinLose.java deleted file mode 100644 index d957d0cf3d2..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/QuestDraftWinLose.java +++ /dev/null @@ -1,126 +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.adventure.libgdxgui.screens.match.winlose; - -import forge.game.GameView; -import forge.game.player.PlayerView; -import forge.gamemodes.match.NextGameDecision; -import forge.gamemodes.quest.QuestController; -import forge.gamemodes.quest.QuestDraftUtils; -import forge.model.FModel; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.toolbox.FEvent; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; - -/** - *

- * QuestDraftWinLose. - *

- * Processes win/lose presentation for Quest Draft events. This presentation is - * displayed by WinLoseFrame. Components to be added to pnlCustom in - * WinLoseFrame should use MigLayout. - * - */ -public class QuestDraftWinLose extends ControlWinLose { - private final transient ViewWinLose view; - private final ControlWinLose controller; - - /** - * Instantiates a new quest win lose handler. - */ - public QuestDraftWinLose(final ViewWinLose view0, final GameView game0) { - super(view0, game0); - this.view = view0; - controller = new ControlWinLose(view0, game0); - } - - @Override - public final void actionOnQuit() { - controller.actionOnQuit(); - super.actionOnQuit(); - } - - @Override - public final void showRewards(){ - final QuestController quest = FModel.getQuest(); - final boolean gameHadHumanPlayer = MatchController.instance.hasLocalPlayers(); - - if (lastGame.isMatchOver()) { - final String winner = lastGame.getWinningPlayerName(); - quest.getAchievements().getCurrentDraft().setWinner(winner); - quest.save(); - // TODO: update needed here? - } - - QuestDraftUtils.update(MatchController.instance); - QuestDraftUtils.matchInProgress = false; - if (!gameHadHumanPlayer) { - return; - } - - view.getBtnRestart().setEnabled(false); - view.getBtnRestart().setVisible(false); - - final boolean isMatchOver = lastGame.isMatchOver(); - final String quitString, warningString, warningCaption; - if (isMatchOver) { - quitString = "Continue Tournament"; - warningString = null; - warningCaption = null; - } else { - quitString = "Forfeit Tournament"; - warningString = "Quitting the match now will forfeit the tournament!\n\nReally quit?"; - warningCaption = "Really Quit Tournament?"; - } - view.getBtnQuit().setEnabled(true); - view.getBtnContinue().setEnabled(!isMatchOver); - view.getBtnQuit().setText(quitString); - - view.getBtnQuit().setCommand(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - if (warningString == null /*|| - FOptionPane.showOptionDialog(warningString, warningCaption, FSkin.getImages().get(FSkinProp.ICO_WARNING), ImmutableList.of("Yes", "No"), 1) == 0*/) { - if (warningString != null) { - PlayerView humanPlayer = null; - for (PlayerView playerView : MatchController.instance.getLocalPlayers()) { - humanPlayer = playerView; - } - for (PlayerView playerView : lastGame.getPlayers()) { - if (humanPlayer == null) { - throw new IllegalStateException("Forfeit tournament button was pressed in a match without human players."); - } - if (playerView != humanPlayer) { - quest.getAchievements().getCurrentDraft().setWinner(playerView.getName()); - quest.save(); - // TODO: update needed here? - } - } - //The player is probably not interested in watching more AI matches. - QuestDraftUtils.cancelFurtherMatches(); - } else { - MatchController.instance.getGameController().nextGameDecision(NextGameDecision.QUIT); - controller.actionOnQuit(); - QuestDraftUtils.matchInProgress = false; - QuestDraftUtils.continueMatches(MatchController.instance); - } - } - } - }); - } -} - diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/QuestWinLose.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/QuestWinLose.java deleted file mode 100644 index 6208e80b75f..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/QuestWinLose.java +++ /dev/null @@ -1,69 +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.adventure.libgdxgui.screens.match.winlose; - -import forge.game.GameView; -import forge.gamemodes.quest.QuestWinLoseController; - -/** - *

- * QuestWinLose. - *

- * Processes win/lose presentation for Quest events. This presentation is - * displayed by WinLoseFrame. Components to be added to pnlCustom in - * WinLoseFrame should use MigLayout. - * - */ -public class QuestWinLose extends ControlWinLose { - private final QuestWinLoseController controller; - - /** - * Instantiates a new quest win lose handler. - * - * @param view0 ViewWinLose object - * @param lastGame0 - */ - public QuestWinLose(final ViewWinLose view0, GameView lastGame0) { - super(view0, lastGame0); - controller = new QuestWinLoseController(lastGame0, view0); - } - - @Override - public final void showRewards() { - //set loading overlay again - controller.showRewards(); - } - - /** - *

- * actionOnQuit. - *

- * When "quit" button is pressed, this method adjusts quest data as - * appropriate and saves. - * - */ - @Override - public final void actionOnQuit() { - controller.actionOnQuit(); - super.actionOnQuit(); - } - - @Override - public void actionOnContinue() { - super.actionOnContinue(); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/ViewWinLose.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/ViewWinLose.java deleted file mode 100644 index ab8014789e1..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/match/winlose/ViewWinLose.java +++ /dev/null @@ -1,250 +0,0 @@ -package forge.adventure.libgdxgui.screens.match.winlose; - -import com.badlogic.gdx.Input.Keys; -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.game.GameLogEntry; -import forge.game.GameLogEntryType; -import forge.game.GameView; -import forge.gui.FThreads; -import forge.gui.interfaces.IWinLoseView; -import forge.gui.util.SGuiChoose; -import forge.gui.util.SOptionPane; -import forge.item.PaperCard; -import forge.localinstance.skin.FSkinProp; -import forge.adventure.libgdxgui.menu.FMagnifyView; -import forge.model.FModel; -import forge.adventure.libgdxgui.toolbox.*; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.util.Localizer; -import forge.adventure.libgdxgui.util.Utils; -import org.apache.commons.lang3.StringUtils; - -import java.util.List; - -public class ViewWinLose extends FOverlay implements IWinLoseView { - private static final float INSETS_FACTOR = 0.025f; - private static final float GAP_Y_FACTOR = 0.02f; - - private final FButton btnContinue, btnRestart, btnQuit; - private final FLabel lblTitle, lblLog, lblStats, btnCopyLog, btnMinimize; - private final FTextArea txtLog; - private final OutcomesPanel pnlOutcomes; - private final GameView game; - - public ViewWinLose(final GameView game0) { - super(FSkinColor.get(Colors.CLR_OVERLAY).alphaColor(0.75f)); - - game = game0; - - lblTitle = add(new FLabel.Builder().font(FSkinFont.get(30)).align(Align.center).build()); - lblStats = add(new FLabel.Builder().font(FSkinFont.get(26)).align(Align.center).build()); - pnlOutcomes = add(new OutcomesPanel()); - - btnContinue = add(new FButton()); - btnRestart = add(new FButton()); - btnQuit = add(new FButton()); - - // Control of the win/lose is handled differently for various game - // modes. - ControlWinLose control = null; - switch (game0.getGameType()) { - case Quest: - control = new QuestWinLose(this, game0); - break; - case QuestDraft: - control = new QuestDraftWinLose(this, game0); - break; - case PlanarConquest: - control = new ConquestWinLose(this, game0); - break; - case Draft: - if (!FModel.getGauntletMini().isGauntletDraft()) { - break; - } - //$FALL-THROUGH$ - case Sealed: - control = new LimitedWinLose(this, game0); - break; - case Gauntlet: - case DeckManager: - control = new GauntletWinLose(this, game0); - break; - default: // will catch it after switch - break; - } - if (control == null) { - control = new ControlWinLose(this, game0); - } - - final Localizer localizer = Localizer.getInstance(); - btnContinue.setText(localizer.getMessage("btnNextGame")); - btnContinue.setFont(FSkinFont.get(22)); - btnRestart.setText(localizer.getMessage("btnStartNewMatch")); - btnRestart.setFont(btnContinue.getFont()); - btnQuit.setText(localizer.getMessage("btnQuitMatch")); - btnQuit.setFont(btnContinue.getFont()); - btnContinue.setEnabled(!game0.isMatchOver()); - - lblLog = add(new FLabel.Builder().text(localizer.getMessage("lblGameLog")).align(Align.center).font(FSkinFont.get(18)).build()); - txtLog = add(new FTextArea(true, StringUtils.join(game.getGameLog().getLogEntries(null), "\r\n").replace("[COMPUTER]", "[AI]")) { - @Override - public boolean tap(float x, float y, int count) { - if (txtLog.getMaxScrollTop() > 0) { - FMagnifyView.show(txtLog, txtLog.getText(), txtLog.getTextColor(), ViewWinLose.this.getBackColor(), txtLog.getFont(), true); - } - return true; - } - }); - txtLog.setFont(FSkinFont.get(12)); - - btnCopyLog = add(new FLabel.ButtonBuilder().text(localizer.getMessage("btnCopyToClipboard")).command(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - Forge.getClipboard().setContents(txtLog.getText()); - } - }).build()); - - btnMinimize = add(new FLabel.ButtonBuilder().text(localizer.getMessage("lblMinimize")).font(FSkinFont.get(12)).command(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - hide(); - } - }).build()); - lblTitle.setText(composeTitle(game0)); - - showGameOutcomeSummary(); - showPlayerScores(); - control.showRewards(); - } - - private String composeTitle(final GameView game) { - final String winner = game.getWinningPlayerName(); - final int winningTeam = game.getWinningTeam(); - final Localizer localizer = Localizer.getInstance(); - if (winner == null) { - return localizer.getMessage("lblItsADraw"); - } else if (winningTeam != -1) { - return localizer.getMessage("lblTeamWon").replace("%s", String.valueOf(winningTeam)); - } else { - return localizer.getMessage("lblWinnerWon").replace("%s", winner); - } - } - - public FButton getBtnContinue() { - return this.btnContinue; - } - - public FButton getBtnRestart() { - return this.btnRestart; - } - - public FButton getBtnQuit() { - return this.btnQuit; - } - - private void showGameOutcomeSummary() { - for (GameLogEntry o : game.getGameLog().getLogEntriesExact(GameLogEntryType.GAME_OUTCOME)) { - pnlOutcomes.add(new FLabel.Builder().text(o.message).font(FSkinFont.get(14)).build()); - } - } - - private void showPlayerScores() { - for (GameLogEntry o : game.getGameLog().getLogEntriesExact(GameLogEntryType.MATCH_RESULTS)) { - lblStats.setText(removePlayerTypeFromLogMessage(o.message)); - } - } - - private String removePlayerTypeFromLogMessage(String message) { - return message.replaceAll("\\[[^\\]]*\\]", ""); - } - - @Override - protected void doLayout(float width, float height) { - float x = width * INSETS_FACTOR; - float y = x; - if (Forge.isLandscapeMode()) { //prevent everything being too wide in Landscape mode - x += width * 0.25f; - } - float w = width - 2 * x; - float dy = height * GAP_Y_FACTOR; - - float h = height / 10; - lblTitle.setBounds(x, y, w, h); - y += h + dy; - - h = OutcomesPanel.LBL_HEIGHT * pnlOutcomes.getChildCount(); - pnlOutcomes.setBounds(x, y, w, h); - y += h + dy; - - h = height / 10; - lblStats.setBounds(x, y, w, h); - y += h + dy; - - h = height / 12; - btnContinue.setBounds(x, y, w, h); - y += h + dy; - btnRestart.setBounds(x, y, w, h); - y += h + dy; - btnQuit.setBounds(x, y, w, h); - y += h + dy; - - h = lblLog.getAutoSizeBounds().height + dy; - lblLog.setBounds(x, y, w, h); - y += h; - - h = height / 16; - float y2 = height - dy - h; - btnCopyLog.setBounds(width / 4, y2, width / 2, h); - txtLog.setBounds(x, y, w, y2 - y - dy); - btnMinimize.setBounds(width / 4,0,width / 2, h); - } - - private static class OutcomesPanel extends FContainer { - private static final float LBL_HEIGHT = Utils.scale(20); - - @Override - protected void doLayout(float width, float height) { - float y = 0; - for (FDisplayObject lbl : getChildren()) { - lbl.setBounds(0, y, width, LBL_HEIGHT); - y += LBL_HEIGHT; - } - } - } - - @Override - public boolean keyDown(int keyCode) { - if (keyCode == Keys.ESCAPE || keyCode == Keys.BACK) { - btnQuit.trigger(); //quit on escape or back - return true; - } else if (keyCode == Keys.SPACE || keyCode == Keys.ENTER) { - if (btnContinue.isEnabled()) { - btnContinue.trigger(); - } else { - btnQuit.trigger(); - } - return true; - } - return super.keyDown(keyCode); - } - - @Override - public void showRewards(Runnable runnable) { - //invoke reward logic in background thread so dialogs can be shown - FThreads.invokeInBackgroundThread(runnable); - } - - @Override - public void showCards(String title, List cards) { - SGuiChoose.reveal(title, cards); - } - - @Override - public void showMessage(String message, String title, FSkinProp icon) { - SOptionPane.showMessageDialog(message, title, icon); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/settings/FilesPage.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/settings/FilesPage.java deleted file mode 100644 index f54a1a78ffc..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/settings/FilesPage.java +++ /dev/null @@ -1,272 +0,0 @@ -package forge.adventure.libgdxgui.screens.settings; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.FSkinImage; -import forge.gui.GuiBase; -import forge.gui.download.*; -import forge.localinstance.properties.ForgeConstants; -import forge.localinstance.properties.ForgeProfileProperties; -import forge.adventure.libgdxgui.screens.TabPageScreen.TabPage; -import forge.adventure.libgdxgui.toolbox.*; -import forge.adventure.libgdxgui.toolbox.FFileChooser.ChoiceType; -import forge.util.Callback; -import forge.util.FileUtil; -import forge.util.Localizer; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -public class FilesPage extends TabPage { - private final FGroupList lstItems = add(new FGroupList<>()); - private final Localizer localizer = Localizer.getInstance(); - - protected FilesPage() { - super(Localizer.getInstance().getMessage("lblFiles"), Forge.hdbuttons ? FSkinImage.HDOPEN : FSkinImage.OPEN); - - lstItems.setListItemRenderer(new FilesItemRenderer()); - - lstItems.addGroup(localizer.getMessage("ContentDownloaders")); - lstItems.addGroup(localizer.getMessage("lblStorageLocations")); - //lstItems.addGroup("Data Import"); - - //content downloaders - lstItems.addItem(new ContentDownloader(localizer.getMessage("btnDownloadPics"), - localizer.getMessage("lblDownloadPics")) { - @Override - protected GuiDownloadService createService() { - return new GuiDownloadPicturesLQ(); - } - }, 0); - lstItems.addItem(new ContentDownloader(localizer.getMessage("btnDownloadSetPics"), - localizer.getMessage("lblDownloadSetPics")) { - @Override - protected GuiDownloadService createService() { - return new GuiDownloadSetPicturesLQ(); - } - }, 0); - lstItems.addItem(new ContentDownloader(localizer.getMessage("btnDownloadQuestImages"), - localizer.getMessage("lblDownloadQuestImages")) { - @Override - protected GuiDownloadService createService() { - return new GuiDownloadQuestImages(); - } - }, 0); - lstItems.addItem(new ContentDownloader(localizer.getMessage("btnDownloadAchievementImages"), - localizer.getMessage("lblDownloadAchievementImages")) { - @Override - protected GuiDownloadService createService() { - return new GuiDownloadAchievementImages(); - } - }, 0); - lstItems.addItem(new ContentDownloader(localizer.getMessage("btnDownloadPrices"), - localizer.getMessage("lblDownloadPrices")) { - @Override - protected GuiDownloadService createService() { - return new GuiDownloadPrices(); - } - }, 0); - lstItems.addItem(new ContentDownloader(localizer.getMessage("btnDownloadSkins"), - localizer.getMessage("lblDownloadSkins")) { - @Override - protected GuiDownloadService createService() { - return new GuiDownloadSkins(); - } - @Override - protected void finishCallback() { - SettingsScreen.getSettingsScreen().getSettingsPage().refreshSkinsList(); - } - }, 0); - lstItems.addItem(new OptionContentDownloader(localizer.getMessage("btnDownloadCJKFonts"), - localizer.getMessage("lblDownloadCJKFonts"), - localizer.getMessage("lblDownloadCJKFontPrompt")) { - @Override - protected Map getCategories() { - // read CJK font list - Map categories = new TreeMap<>(); - List lines = FileUtil.readFile(ForgeConstants.CJK_FONTS_LIST_FILE); - List options = new ArrayList<>(); - for (String line : lines) { - int idx = line.indexOf('|'); - if (idx != -1) { - String name = line.substring(0, idx).trim(); - String url = line.substring(idx + 1).trim(); - categories.put(name, url); - options.add(name); - } - } - return categories; - } - @Override - protected void finishCallback() { - SettingsScreen.getSettingsScreen().getSettingsPage().refreshCJKFontsList(); - } - }, 0); - //storage locations - final StorageOption cardPicsOption = new StorageOption(localizer.getMessage("lblCardPicsLocation"), ForgeProfileProperties.getCardPicsDir()) { - @Override - protected void onDirectoryChanged(String newDir) { - ForgeProfileProperties.setCardPicsDir(newDir); - } - }; - final StorageOption decksOption = new StorageOption(localizer.getMessage("lblDecksLocation"), ForgeProfileProperties.getDecksDir()) { - @Override - protected void onDirectoryChanged(String newDir) { - ForgeProfileProperties.setDecksDir(newDir); - } - }; - if (!GuiBase.isUsingAppDirectory()) { - lstItems.addItem(new StorageOption(localizer.getMessage("lblDataLocation"), ForgeProfileProperties.getUserDir()) { - @Override - protected void onDirectoryChanged(String newDir) { - ForgeProfileProperties.setUserDir(newDir); - - //ensure decks option is updated if needed - decksOption.updateDir(ForgeProfileProperties.getDecksDir()); - } - }, 1); - lstItems.addItem(new StorageOption(localizer.getMessage("lblImageCacheLocation"), ForgeProfileProperties.getCacheDir()) { - @Override - protected void onDirectoryChanged(String newDir) { - ForgeProfileProperties.setCacheDir(newDir); - - //ensure card pics option is updated if needed - cardPicsOption.updateDir(ForgeProfileProperties.getCardPicsDir()); - } - }, 1); - lstItems.addItem(cardPicsOption, 1); - lstItems.addItem(decksOption, 1); - } - } - - @Override - protected void doLayout(float width, float height) { - lstItems.setBounds(0, 0, width, height); - } - - private abstract class FilesItem { - protected String label; - protected String description; - - FilesItem(String label0, String description0) { - label = label0; - description = description0; - } - - public abstract void select(); - } - - private static class FilesItemRenderer extends FList.ListItemRenderer { - @Override - public float getItemHeight() { - return SettingsScreen.SETTING_HEIGHT; - } - - @Override - public boolean tap(Integer index, FilesItem value, float x, float y, int count) { - value.select(); - return true; - } - - @Override - public void drawValue(Graphics g, Integer index, FilesItem value, FSkinFont font, FSkinColor foreColor, FSkinColor backColor, boolean pressed, float x, float y, float w, float h) { - float offset = SettingsScreen.getInsets(w) - FList.PADDING; //increase padding for settings items - x += offset; - y += offset; - w -= 2 * offset; - h -= 2 * offset; - - float totalHeight = h; - h = font.getMultiLineBounds(value.label).height + SettingsScreen.SETTING_PADDING; - - g.drawText(value.label, font, foreColor, x, y, w, h, false, Align.left, false); - h += SettingsScreen.SETTING_PADDING; - g.drawText(value.description, SettingsScreen.DESC_FONT, SettingsScreen.DESC_COLOR, x, y + h, w, totalHeight - h + SettingsScreen.getInsets(w), true, Align.left, false); - } - } - - private abstract class ContentDownloader extends FilesItem { - ContentDownloader(String label0, String description0) { - super(label0, description0); - } - - @Override - public void select() { - new GuiDownloader(createService(), new Callback() { - @Override - public void run(Boolean finished) { - if (finished) { - finishCallback(); - } - } - }).show(); - } - protected abstract GuiDownloadService createService(); - - protected void finishCallback() { - } - } - - private abstract class OptionContentDownloader extends FilesItem { - private final String prompt; - - OptionContentDownloader(String label0, String description0, String propmt0) { - super(label0, description0); - prompt = propmt0; - } - - @Override - public void select() { - final Map categories = getCategories(); - GuiChoose.one(prompt, categories.keySet(), new Callback() { - @Override - public void run(String result) { - final String url = categories.get(result); - final String name = url.substring(url.lastIndexOf("/") + 1); - new GuiDownloader(new GuiDownloadZipService(name, name, url, ForgeConstants.FONTS_DIR, null, null), new Callback() { - @Override - public void run(Boolean finished) { - if (finished) { - finishCallback(); - } - } - }).show(); - } - }); - } - protected abstract Map getCategories(); - - protected void finishCallback() { - } - } - - private abstract class StorageOption extends FilesItem { - StorageOption(String name0, String dir0) { - super(name0, dir0); - } - - private void updateDir(String dir0) { - description = dir0; - } - - @Override - public void select() { - FFileChooser.show(localizer.getMessage("lblSelect").replace("%s", label), ChoiceType.GetDirectory, description, new Callback() { - @Override - public void run(String result) { - if (StringUtils.isEmpty(result) || description.equals(result)) { return; } - updateDir(result); - onDirectoryChanged(result); - FOptionPane.showMessageDialog(localizer.getMessage("lblRestartForgeMoveFilesNewLocation"), localizer.getMessage("lblRestartRequired"), FOptionPane.INFORMATION_ICON); - } - }); - } - protected abstract void onDirectoryChanged(String newDir); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/settings/GuiDownloader.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/settings/GuiDownloader.java deleted file mode 100644 index c63dde03944..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/settings/GuiDownloader.java +++ /dev/null @@ -1,153 +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.adventure.libgdxgui.screens.settings; - -import forge.adventure.libgdxgui.Forge; -import forge.gui.UiCommand; -import forge.gui.download.GuiDownloadService; -import forge.gui.download.GuiDownloadZipService; -import forge.adventure.libgdxgui.toolbox.*; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.toolbox.FRadioButton.RadioButtonGroup; -import forge.util.Callback; -import forge.adventure.libgdxgui.util.Utils; - -import java.net.Proxy; - -public class GuiDownloader extends FDialog { - public static final Proxy.Type[] TYPES = Proxy.Type.values(); - private static final float PADDING = Utils.scale(10); - - private final FProgressBar progressBar = add(new FProgressBar()); - private final FTextField txtAddress = add(new FTextField()); - private final FTextField txtPort = add(new FTextField()); - private final FRadioButton radProxyNone = add(new FRadioButton("No Proxy")); - private final FRadioButton radProxySocks = add(new FRadioButton("SOCKS Proxy")); - private final FRadioButton radProxyHTTP = add(new FRadioButton("HTTP Proxy")); - - @SuppressWarnings("serial") - private final UiCommand cmdClose = new UiCommand() { - @Override - public void run() { - Forge.stopContinuousRendering(); - service.setCancel(true); - hide(); - if (callback != null) { - callback.run(getButton(0).getText() == "OK"); //determine result based on whether download finished - } - } - }; - - private final GuiDownloadService service; - private final Callback callback; - - public GuiDownloader(final GuiDownloadService service0) { - this(service0, null); - } - public GuiDownloader(final GuiDownloadService service0, final Callback callback0) { - super(service0.getTitle(), 2); - service = service0; - callback = callback0; - - txtAddress.setGhostText("Proxy Address"); - txtPort.setGhostText("Proxy Port"); - txtAddress.setEnabled(false); - txtPort.setEnabled(false); - - final RadioButtonGroup group = new RadioButtonGroup(); - radProxyNone.setGroup(group); - radProxyHTTP.setGroup(group); - radProxySocks.setGroup(group); - - radProxyNone.setCommand(new ProxyHandler(0)); - radProxyHTTP.setCommand(new ProxyHandler(1)); - radProxySocks.setCommand(new ProxyHandler(2)); - radProxyNone.setSelected(true); - - getButton(0).setText("Start"); - initButton(1, "Cancel", new FEventHandler() { - @Override - public void handleEvent(final FEvent e) { - cmdClose.run(); - } - }); - - progressBar.reset(); - progressBar.setShowProgressTrail(true); - progressBar.setDescription("Scanning for existing items..."); - } - - @Override - public void show() { - Forge.startContinuousRendering(); - - super.show(); - - service.initialize(txtAddress, txtPort, progressBar, getButton(0), cmdClose, new Runnable() { - @Override - public void run() { - if (!(service instanceof GuiDownloadZipService)) { //retain continuous rendering for zip service - Forge.stopContinuousRendering(); - } - progressBar.setShowProgressTrail(false); - } - }, null); - } - - private class ProxyHandler implements FEventHandler { - private final int type; - - public ProxyHandler(final int type) { - this.type = type; - } - - @Override - public void handleEvent(final FEvent e) { - if (((FRadioButton) e.getSource()).isSelected()) { - service.setType(this.type); - txtAddress.setEnabled(this.type != 0); - txtPort.setEnabled(this.type != 0); - } - } - } - - @Override - protected float layoutAndGetHeight(final float width, final float maxHeight) { - float x = PADDING; - float y = PADDING; - final float w = width - 2 * PADDING; - final float radioButtonWidth = w / 3; - final float radioButtonHeight = radProxyNone.getAutoSizeBounds().height; - - radProxyNone.setBounds(x, y, radioButtonWidth, radioButtonHeight); - x += radioButtonWidth; - radProxyHTTP.setBounds(x, y, radioButtonWidth, radioButtonHeight); - x += radioButtonWidth; - radProxySocks.setBounds(x, y, radioButtonWidth, radioButtonHeight); - - x = PADDING; - y += radioButtonHeight + PADDING; - txtAddress.setBounds(x, y, w, txtAddress.getHeight()); - y += txtAddress.getHeight() + PADDING; - txtPort.setBounds(x, y, w, txtPort.getHeight()); - y += txtPort.getHeight() + PADDING * 2; - progressBar.setBounds(x, y, w, txtPort.getHeight() * 1.5f); - y += progressBar.getHeight() + PADDING * 2; - return y; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/settings/SettingsPage.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/settings/SettingsPage.java deleted file mode 100644 index 4fb16d411ab..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/settings/SettingsPage.java +++ /dev/null @@ -1,768 +0,0 @@ -package forge.adventure.libgdxgui.screens.settings; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.MulliganDefs; -import forge.StaticData; -import forge.ai.AiProfileUtil; -import forge.adventure.libgdxgui.assets.*; -import forge.game.GameLogEntryType; -import forge.gui.GuiBase; -import forge.localinstance.properties.ForgeConstants; -import forge.localinstance.properties.ForgePreferences; -import forge.localinstance.properties.ForgePreferences.FPref; -import forge.model.FModel; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.screens.TabPageScreen; -import forge.adventure.libgdxgui.screens.TabPageScreen.TabPage; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.sound.SoundSystem; -import forge.adventure.libgdxgui.toolbox.FCheckBox; -import forge.adventure.libgdxgui.toolbox.FGroupList; -import forge.adventure.libgdxgui.toolbox.FList; -import forge.adventure.libgdxgui.toolbox.FOptionPane; -import forge.util.Callback; -import forge.util.Localizer; -import forge.adventure.libgdxgui.util.Utils; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -public class SettingsPage extends TabPage { - private final FGroupList lstSettings = add(new FGroupList<>()); - private final CustomSelectSetting settingSkins; - private final CustomSelectSetting settingCJKFonts; - - public SettingsPage() { - super(Localizer.getInstance().getMessage("lblSettings"), Forge.hdbuttons ? FSkinImage.HDPREFERENCE : FSkinImage.SETTINGS); - - final Localizer localizer = Localizer.getInstance(); - - lstSettings.setListItemRenderer(new SettingRenderer()); - - lstSettings.addGroup(localizer.getMessage("lblGeneralSettings")); - lstSettings.addGroup(localizer.getMessage("lblGameplayOptions")); - lstSettings.addGroup(localizer.getMessage("RandomDeckGeneration")); - lstSettings.addGroup(localizer.getMessage("AdvancedSettings")); - lstSettings.addGroup(localizer.getMessage("GraphicOptions")); - lstSettings.addGroup(localizer.getMessage("lblCardOverlays")); - lstSettings.addGroup(localizer.getMessage("lblVibrationOptions")); - lstSettings.addGroup(localizer.getMessage("SoundOptions")); - - //General Settings - lstSettings.addItem(new CustomSelectSetting(FPref.UI_LANGUAGE, localizer.getMessage("cbpSelectLanguage"), - localizer.getMessage("nlSelectLanguage"), - FLanguage.getAllLanguages()) { - @Override - public void valueChanged(String newValue) { - // if the new locale needs to use CJK font, disallow change if UI_CJK_FONT is not set yet - ForgePreferences prefs = FModel.getPreferences(); - if (prefs.getPref(FPref.UI_CJK_FONT).equals("") && - (newValue.equals("zh-CN") || newValue.equals("ja-JP"))) { - String message = "Please download CJK font (from \"Files\"), and set it before change language."; - if (newValue.equals("zh-CN")) { - message += "\nChinese please use \"SourceHanSansCN\"."; - } - if (newValue.equals("ja-JP")) { - message += "\nJapanese please use \"SourceHanSansJP\"."; - } - FOptionPane.showMessageDialog(message, "Please set CJK Font"); - return; - } - - FLanguage.changeLanguage(newValue); - - FOptionPane.showConfirmDialog(localizer.getMessage("lblRestartForgeDescription"), localizer.getMessage("lblRestartForge"), localizer.getMessage("lblRestart"), localizer.getMessage("lblLater"), new Callback() { - @Override - public void run(Boolean result) { - if (result) { - Forge.restart(true); - } - } - }); - } - }, 0); - settingSkins = new CustomSelectSetting(FPref.UI_SKIN, localizer.getMessage("lblTheme"), - localizer.getMessage("nlTheme"), - FSkin.getAllSkins()) { - @Override - public void valueChanged(String newValue) { - FSkin.changeSkin(newValue); - } - }; - lstSettings.addItem(settingSkins, 0); - settingCJKFonts = new CustomSelectSetting(FPref.UI_CJK_FONT, localizer.getMessage("lblCJKFont"), - localizer.getMessage("nlCJKFont"), - FSkinFont.getAllCJKFonts()) { - @Override - public void valueChanged(String newValue) { - ForgePreferences prefs = FModel.getPreferences(); - if (newValue.equals("None")) { - // If locale needs to use CJK fonts, disallow change to None - String locale = prefs.getPref(FPref.UI_LANGUAGE); - if (locale.equals("zh-CN") || locale.equals("ja-JP")) { - return; - } - newValue = ""; - } - if (newValue.equals(prefs.getPref(FPref.UI_CJK_FONT))) { - return; - } - super.valueChanged(newValue); - } - }; - lstSettings.addItem(settingCJKFonts, 0); - lstSettings.addItem(new BooleanSetting(FPref.UI_LANDSCAPE_MODE, - localizer.getMessage("lblLandscapeMode"), - localizer.getMessage("nlLandscapeMode")) { - @Override - public void select() { - super.select(); - boolean landscapeMode = FModel.getPreferences().getPrefBoolean(FPref.UI_LANDSCAPE_MODE); - Forge.getDeviceAdapter().setLandscapeMode(landscapeMode); //ensure device able to save off ini file so landscape change takes effect - if (Forge.isLandscapeMode() != landscapeMode) { - FOptionPane.showConfirmDialog(localizer.getMessage("lblRestartForgeDescription"), localizer.getMessage("lblRestartForge"), localizer.getMessage("lblRestart"), localizer.getMessage("lblLater"), new Callback() { - @Override - public void run(Boolean result) { - if (result) { - Forge.restart(true); - } - } - }); - } - } - }, 0); - lstSettings.addItem(new BooleanSetting(FPref.UI_ANDROID_MINIMIZE_ON_SCRLOCK, - localizer.getMessage("lblMinimizeScreenLock"), - localizer.getMessage("nlMinimizeScreenLock")), - 0); - lstSettings.addItem(new BooleanSetting(FPref.USE_SENTRY, - localizer.getMessage("lblAutomaticBugReports"), - localizer.getMessage("nlAutomaticBugReports")), - 0); - - //Gameplay Options - lstSettings.addItem(new CustomSelectSetting(FPref.MULLIGAN_RULE, localizer.getMessage("cbpMulliganRule"), - localizer.getMessage("nlpMulliganRule"), - MulliganDefs.getMulliganRuleNames()) { - @Override - public void valueChanged(String newValue) { - super.valueChanged(newValue); - StaticData.instance().setMulliganRule(MulliganDefs.GetRuleByName(FModel.getPreferences().getPref(FPref.MULLIGAN_RULE))); - } - }, 1); - lstSettings.addItem(new CustomSelectSetting(FPref.UI_CURRENT_AI_PROFILE, - localizer.getMessage("cbpAiProfiles"), - localizer.getMessage("nlpAiProfiles"), - AiProfileUtil.getProfilesArray()), - 1); - lstSettings.addItem(new BooleanSetting(FPref.UI_ANTE, - localizer.getMessage("cbAnte"), - localizer.getMessage("nlAnte")), - 1); - lstSettings.addItem(new BooleanSetting(FPref.UI_ANTE_MATCH_RARITY, - localizer.getMessage("cbAnteMatchRarity"), - localizer.getMessage("nlAnteMatchRarity")), - 1); - lstSettings.addItem(new BooleanSetting(FPref.MATCH_HOT_SEAT_MODE, - localizer.getMessage("lblHotSeatMode"), - localizer.getMessage("nlHotSeatMode")), - 1); - lstSettings.addItem(new BooleanSetting(FPref.UI_ENABLE_AI_CHEATS, - localizer.getMessage("cbEnableAICheats"), - localizer.getMessage("nlEnableAICheats")), - 1); - lstSettings.addItem(new BooleanSetting(FPref.UI_MANABURN, - localizer.getMessage("cbManaBurn"), - localizer.getMessage("nlManaBurn")), - 1); - lstSettings.addItem(new BooleanSetting(FPref.UI_MANA_LOST_PROMPT, - localizer.getMessage("cbManaLostPrompt"), - localizer.getMessage("nlManaLostPrompt")), - 1); - lstSettings.addItem(new BooleanSetting(FPref.ENFORCE_DECK_LEGALITY, - localizer.getMessage("cbEnforceDeckLegality"), - localizer.getMessage("nlEnforceDeckLegality")), - 1); - lstSettings.addItem(new BooleanSetting(FPref.PERFORMANCE_MODE, - localizer.getMessage("cbPerformanceMode"), - localizer.getMessage("nlPerformanceMode")), - 1); - lstSettings.addItem(new BooleanSetting(FPref.MATCH_SIDEBOARD_FOR_AI, - localizer.getMessage("cbSideboardForAI"), - localizer.getMessage("nlSideboardForAI")), - 1); - lstSettings.addItem(new BooleanSetting(FPref.FILTERED_HANDS, - localizer.getMessage("cbFilteredHands"), - localizer.getMessage("nlFilteredHands")), - 1); - lstSettings.addItem(new BooleanSetting(FPref.UI_CLONE_MODE_SOURCE, - localizer.getMessage("cbCloneImgSource"), - localizer.getMessage("nlCloneImgSource")), - 1); - lstSettings.addItem(new BooleanSetting(FPref.MATCHPREF_PROMPT_FREE_BLOCKS, - localizer.getMessage("cbPromptFreeBlocks"), - localizer.getMessage("nlPromptFreeBlocks")), - 1); - lstSettings.addItem(new BooleanSetting(FPref.UI_DETAILED_SPELLDESC_IN_PROMPT, - localizer.getMessage("cbDetailedPaymentDesc"), - localizer.getMessage("nlDetailedPaymentDesc")), - 1); - lstSettings.addItem(new BooleanSetting(FPref.UI_SHOW_STORM_COUNT_IN_PROMPT, - localizer.getMessage("cbShowStormCount"), - localizer.getMessage("nlShowStormCount")), - 1); - lstSettings.addItem(new BooleanSetting(FPref.UI_PRESELECT_PREVIOUS_ABILITY_ORDER, - localizer.getMessage("cbPreselectPrevAbOrder"), - localizer.getMessage("nlPreselectPrevAbOrder")), - 1); - lstSettings.addItem(new CustomSelectSetting(FPref.UI_ALLOW_ORDER_GRAVEYARD_WHEN_NEEDED, - localizer.getMessage("lblOrderGraveyard"), - localizer.getMessage("nlOrderGraveyard"), - new String[]{ - ForgeConstants.GRAVEYARD_ORDERING_NEVER, ForgeConstants.GRAVEYARD_ORDERING_OWN_CARDS, - ForgeConstants.GRAVEYARD_ORDERING_ALWAYS}), - 1); - lstSettings.addItem(new CustomSelectSetting(FPref.UI_AUTO_YIELD_MODE, - localizer.getMessage("lblAutoYields"), - localizer.getMessage("nlpAutoYieldMode"), - new String[]{ForgeConstants.AUTO_YIELD_PER_ABILITY, ForgeConstants.AUTO_YIELD_PER_CARD}), - 1); - lstSettings.addItem(new BooleanSetting(FPref.UI_ALLOW_ESC_TO_END_TURN, - localizer.getMessage("cbEscapeEndsTurn"), - localizer.getMessage("nlEscapeEndsTurn")), - 1); - lstSettings.addItem(new BooleanSetting(FPref.UI_ALT_PLAYERINFOLAYOUT, - localizer.getMessage("lblAltLifeDisplay"), - localizer.getMessage("nlAltLifeDisplay")){ - @Override - public void select() { - super.select(); - //update - Forge.altPlayerLayout = FModel.getPreferences().getPrefBoolean(FPref.UI_ALT_PLAYERINFOLAYOUT); - if (MatchController.instance != null) - MatchController.instance.resetPlayerPanels(); - } - },1); - lstSettings.addItem(new BooleanSetting(FPref.UI_ALT_PLAYERZONETABS, - localizer.getMessage("lblAltZoneTabs"), - localizer.getMessage("nlAltZoneTabs")){ - @Override - public void select() { - super.select(); - //update - Forge.altZoneTabs = FModel.getPreferences().getPrefBoolean(FPref.UI_ALT_PLAYERZONETABS); - if (MatchController.instance != null) - MatchController.instance.resetPlayerPanels(); - } - },1); - - //Random Deck Generation - lstSettings.addItem(new BooleanSetting(FPref.DECKGEN_NOSMALL, - localizer.getMessage("cbRemoveSmall"), - localizer.getMessage("nlRemoveSmall")), - 2); - lstSettings.addItem(new BooleanSetting(FPref.DECKGEN_CARDBASED, - localizer.getMessage("cbCardBased"), - localizer.getMessage("nlCardBased")), - 2); - lstSettings.addItem(new BooleanSetting(FPref.DECKGEN_SINGLETONS, - localizer.getMessage("cbSingletons"), - localizer.getMessage("nlSingletons")), - 2); - lstSettings.addItem(new BooleanSetting(FPref.DECKGEN_ARTIFACTS, - localizer.getMessage("cbRemoveArtifacts"), - localizer.getMessage("nlRemoveArtifacts")), - 2); - - //Advanced Settings - lstSettings.addItem(new BooleanSetting(FPref.DEV_MODE_ENABLED, - localizer.getMessage("cbDevMode"), - localizer.getMessage("nlDevMode")) { - @Override - public void select() { - super.select(); - //update DEV_MODE flag when preference changes - ForgePreferences.DEV_MODE = FModel.getPreferences().getPrefBoolean(FPref.DEV_MODE_ENABLED); - } - }, 3); - lstSettings.addItem(new CustomSelectSetting(FPref.DEV_LOG_ENTRY_TYPE, - localizer.getMessage("cbpGameLogEntryType"), - localizer.getMessage("nlGameLogEntryType"), - GameLogEntryType.class), - 3); - lstSettings.addItem(new BooleanSetting(FPref.LOAD_CARD_SCRIPTS_LAZILY, - localizer.getMessage("cbLoadCardsLazily"), - localizer.getMessage("nlLoadCardsLazily")), - 3); - lstSettings.addItem(new BooleanSetting(FPref.LOAD_HISTORIC_FORMATS, - localizer.getMessage("cbLoadHistoricFormats"), - localizer.getMessage("nlLoadHistoricFormats")), - 3); - lstSettings.addItem(new BooleanSetting(FPref.UI_LOAD_UNKNOWN_CARDS, - localizer.getMessage("lblEnableUnknownCards"), - localizer.getMessage("nlEnableUnknownCards")) { - @Override - public void select() { - super.select(); - FOptionPane.showConfirmDialog( - localizer.getMessage("lblRestartForgeDescription"), - localizer.getMessage("lblRestartForge"), - localizer.getMessage("lblRestart"), - localizer.getMessage("lblLater"), new Callback() { - @Override - public void run(Boolean result) { - if (result) { - Forge.restart(true); - } - } - } - ); - } - }, - 3); - lstSettings.addItem(new BooleanSetting(FPref.UI_LOAD_NONLEGAL_CARDS, - localizer.getMessage("lblEnableNonLegalCards"), - localizer.getMessage("nlEnableNonLegalCards")) { - @Override - public void select() { - super.select(); - FOptionPane.showConfirmDialog( - localizer.getMessage("lblRestartForgeDescription"), - localizer.getMessage("lblRestartForge"), - localizer.getMessage("lblRestart"), - localizer.getMessage("lblLater"), new Callback() { - @Override - public void run(Boolean result) { - if (result) { - Forge.restart(true); - } - } - } - ); - } - }, - 3); - lstSettings.addItem(new BooleanSetting(FPref.UI_NETPLAY_COMPAT, - localizer.getMessage("lblExperimentalNetworkCompatibility"), - localizer.getMessage("nlExperimentalNetworkCompatibility")) { - @Override - public void select() { - super.select(); - GuiBase.enablePropertyConfig(FModel.getPreferences().getPrefBoolean(FPref.UI_NETPLAY_COMPAT)); - } - }, - 3); - lstSettings.addItem(new BooleanSetting(FPref.UI_ENABLE_DISPOSE_TEXTURES, - localizer.getMessage("lblDisposeTextures"), - localizer.getMessage("nlDisposeTextures")) { - @Override - public void select() { - super.select(); - Forge.disposeTextures = FModel.getPreferences().getPrefBoolean(FPref.UI_ENABLE_DISPOSE_TEXTURES); - } - }, - 3); - if (GuiBase.isAndroid()) { //this option does nothing except on Android - lstSettings.addItem(new BooleanSetting(FPref.UI_AUTO_CACHE_SIZE, - localizer.getMessage("lblAutoCacheSize"), - localizer.getMessage("nlAutoCacheSize")) { - @Override - public void select() { - super.select(); - FOptionPane.showConfirmDialog ( - localizer.getMessage("lblRestartForgeDescription"), - localizer.getMessage("lblRestartForge"), - localizer.getMessage("lblRestart"), - localizer.getMessage("lblLater"), new Callback() { - @Override - public void run(Boolean result) { - if (result) { - Forge.restart(true); - } - } - } - ); - } - }, - 3); - } - //Graphic Options - lstSettings.addItem(new BooleanSetting(FPref.UI_DISABLE_CARD_IMAGES, - localizer.getMessage("lblDisableCardImages"), - localizer.getMessage("nlDisableCardImages")) { - @Override - public void select() { - super.select(); - ImageCache.disposeTexture(); - } - }, - 4); - lstSettings.addItem(new BooleanSetting(FPref.UI_ENABLE_ONLINE_IMAGE_FETCHER, - localizer.getMessage("cbImageFetcher"), - localizer.getMessage("nlImageFetcher")), - 4); - lstSettings.addItem(new CustomSelectSetting(FPref.UI_PREFERRED_ART, - localizer.getMessage("lblPreferredArt"), - localizer.getMessage("nlPreferredArt"), - new String[]{"Latest", "Earliest", "Default"}) { - @Override - public void valueChanged(String newValue) { - super.valueChanged(newValue); - FOptionPane.showConfirmDialog ( - localizer.getMessage("lblRestartForgeDescription"), - localizer.getMessage("lblRestartForge"), - localizer.getMessage("lblRestart"), - localizer.getMessage("lblLater"), new Callback() { - @Override - public void run(Boolean result) { - if (result) { - Forge.restart(true); - } - } - } - ); - } - }, - 4); - lstSettings.addItem(new BooleanSetting(FPref.UI_OVERLAY_FOIL_EFFECT, - localizer.getMessage("cbDisplayFoil"), - localizer.getMessage("nlDisplayFoil")), - 4); - lstSettings.addItem(new BooleanSetting(FPref.UI_RANDOM_FOIL, - localizer.getMessage("cbRandomFoil"), - localizer.getMessage("nlRandomFoil")), - 4); - lstSettings.addItem(new BooleanSetting(FPref.UI_RANDOM_ART_IN_POOLS, - localizer.getMessage("cbRandomArtInPools"), - localizer.getMessage("nlRandomArtInPools")), - 4); - lstSettings.addItem(new BooleanSetting(FPref.UI_COMPACT_TABS, - localizer.getMessage("lblCompactTabs"), - localizer.getMessage("nlCompactTabs")) { - @Override - public void select() { - super.select(); - //update layout of screen when this setting changes - TabPageScreen.COMPACT_TABS = FModel.getPreferences().getPrefBoolean(FPref.UI_COMPACT_TABS); - parentScreen.revalidate(); - } - },4); - lstSettings.addItem(new BooleanSetting(FPref.UI_COMPACT_LIST_ITEMS, - localizer.getMessage("lblCompactListItems"), - localizer.getMessage("nlCompactListItems")), - 4); - lstSettings.addItem(new BooleanSetting(FPref.UI_HIDE_REMINDER_TEXT, - localizer.getMessage("cbHideReminderText"), - localizer.getMessage("nlHideReminderText")), - 4); - lstSettings.addItem(new BooleanSetting(FPref.UI_MATCH_IMAGE_VISIBLE, - localizer.getMessage("lblShowMatchBackground"), - localizer.getMessage("nlShowMatchBackground")), - 4); - lstSettings.addItem(new BooleanSetting(FPref.UI_LIBGDX_TEXTURE_FILTERING, - localizer.getMessage("lblBattlefieldTextureFiltering"), - localizer.getMessage("nlBattlefieldTextureFiltering")), - 4); - lstSettings.addItem(new CustomSelectSetting(FPref.UI_DISPLAY_CURRENT_COLORS, - localizer.getMessage("cbpDisplayCurrentCardColors"), - localizer.getMessage("nlDisplayCurrentCardColors"), - new String[]{ - ForgeConstants.DISP_CURRENT_COLORS_NEVER, ForgeConstants.DISP_CURRENT_COLORS_MULTICOLOR, - ForgeConstants.DISP_CURRENT_COLORS_CHANGED, ForgeConstants.DISP_CURRENT_COLORS_MULTI_OR_CHANGED, - ForgeConstants.DISP_CURRENT_COLORS_ALWAYS}), - 4); - lstSettings.addItem(new BooleanSetting(FPref.UI_ROTATE_SPLIT_CARDS, - localizer.getMessage("lblRotateZoomSplit"), - localizer.getMessage("nlRotateZoomSplit")), - 4); - lstSettings.addItem(new BooleanSetting(FPref.UI_ROTATE_PLANE_OR_PHENOMENON, - localizer.getMessage("lblRotateZoomPlanesPhenomena"), - localizer.getMessage("nlRotateZoomPlanesPhenomena")), - 4); - lstSettings.addItem(new BooleanSetting(FPref.UI_DYNAMIC_PLANECHASE_BG, - localizer.getMessage("lblDynamicBackgroundPlanechase"), - localizer.getMessage("nlDynamicBackgroundPlanechase")), - 4); - lstSettings.addItem(new BooleanSetting(FPref.UI_DISABLE_IMAGES_EFFECT_CARDS, - localizer.getMessage("lblDisableCardEffect"), - localizer.getMessage("nlDisableCardEffect")), - 4); - lstSettings.addItem(new CustomSelectSetting(FPref.UI_ENABLE_BORDER_MASKING, - localizer.getMessage("lblBorderMaskOption"), - localizer.getMessage("nlBorderMaskOption"), - new String[]{"Off", "Crop", "Full"}) { - @Override - public void valueChanged(String newValue) { - super.valueChanged(newValue); - Forge.enableUIMask = FModel.getPreferences().getPref(FPref.UI_ENABLE_BORDER_MASKING); - } - }, 4); - lstSettings.addItem(new BooleanSetting(FPref.UI_ENABLE_PRELOAD_EXTENDED_ART, - localizer.getMessage("lblPreloadExtendedArtCards"), - localizer.getMessage("nlPreloadExtendedArtCards")){ - @Override - public void select() { - super.select(); - //update - Forge.enablePreloadExtendedArt = FModel.getPreferences().getPrefBoolean(FPref.UI_ENABLE_PRELOAD_EXTENDED_ART); - } - },4); - lstSettings.addItem(new BooleanSetting(FPref.UI_ENABLE_MATCH_SCROLL_INDICATOR, - localizer.getMessage("lblMatchScrollIndicator"), - localizer.getMessage("nlMatchScrollIndicator")), - 4); - lstSettings.addItem(new BooleanSetting(FPref.UI_SHOW_FPS, - localizer.getMessage("lblShowFPSDisplay"), - localizer.getMessage("nlShowFPSDisplay")){ - @Override - public void select() { - super.select(); - //update - Forge.showFPS = FModel.getPreferences().getPrefBoolean(FPref.UI_SHOW_FPS); - } - },4); - lstSettings.addItem(new CustomSelectSetting(FPref.UI_CARD_COUNTER_DISPLAY_TYPE, - localizer.getMessage("cbpCounterDisplayType"), - localizer.getMessage("nlCounterDisplayType"), - new String[]{ - ForgeConstants.CounterDisplayType.TEXT.getName(), ForgeConstants.CounterDisplayType.IMAGE.getName(), - ForgeConstants.CounterDisplayType.HYBRID.getName(), ForgeConstants.CounterDisplayType.OLD_WHEN_SMALL.getName()}), - 4); - //Card Overlays - lstSettings.addItem(new BooleanSetting(FPref.UI_SHOW_CARD_OVERLAYS, - localizer.getMessage("lblShowCardOverlays"), - localizer.getMessage("nlShowCardOverlays")), - 5); - lstSettings.addItem(new BooleanSetting(FPref.UI_OVERLAY_CARD_NAME, - localizer.getMessage("lblShowCardNameOverlays"), - localizer.getMessage("nlShowCardNameOverlays")), - 5); - lstSettings.addItem(new BooleanSetting(FPref.UI_OVERLAY_CARD_MANA_COST, - localizer.getMessage("lblShowCardManaCostOverlays"), - localizer.getMessage("nlShowCardManaCostOverlays")), - 5); - lstSettings.addItem(new BooleanSetting(FPref.UI_OVERLAY_CARD_POWER, - localizer.getMessage("lblShowCardPTOverlays"), - localizer.getMessage("nlShowCardPTOverlays")), - 5); - lstSettings.addItem(new BooleanSetting(FPref.UI_OVERLAY_CARD_ID, - localizer.getMessage("lblShowCardIDOverlays"), - localizer.getMessage("nlShowCardIDOverlays")), - 5); - lstSettings.addItem(new BooleanSetting(FPref.UI_OVERLAY_ABILITY_ICONS, - localizer.getMessage("lblShowAbilityIconsOverlays"), - localizer.getMessage("nlShowAbilityIconsOverlays")), - 5); - //Vibration Options - lstSettings.addItem(new BooleanSetting(FPref.UI_VIBRATE_ON_LIFE_LOSS, - localizer.getMessage("lblVibrateWhenLosingLife"), - localizer.getMessage("nlVibrateWhenLosingLife")), - 6); - lstSettings.addItem(new BooleanSetting(FPref.UI_VIBRATE_ON_LONG_PRESS, - localizer.getMessage("lblVibrateAfterLongPress"), - localizer.getMessage("nlVibrateAfterLongPress")), - 6); - //Sound Options - lstSettings.addItem(new CustomSelectSetting(FPref.UI_VOL_SOUNDS, - localizer.getMessage("cbAdjustSoundsVolume"), - localizer.getMessage("nlAdjustSoundsVolume"), - new String[]{"0", "10", "20", "30", "40", "50", "60", "70", "80", "90", "100"}), - 7); - lstSettings.addItem(new CustomSelectSetting(FPref.UI_VOL_MUSIC, - localizer.getMessage("cbAdjustMusicVolume"), - localizer.getMessage("nlAdjustMusicVolume"), - new String[]{"0", "10", "20", "30", "40", "50", "60", "70", "80", "90", "100"}) { - @Override - public void valueChanged(String newValue) { - super.valueChanged(newValue); - //update background music when this setting changes - SoundSystem.instance.changeBackgroundTrack(); - } - }, 7); - /*lstSettings.addItem(new BooleanSetting(FPref.UI_ALT_SOUND_SYSTEM, - "Use Alternate Sound System", - "Use the alternate sound system (only use if you have issues with sound not playing or disappearing)."), - 7);*/ - } - - public void refreshSkinsList() { - settingSkins.updateOptions(FSkin.getAllSkins()); - } - - public void refreshCJKFontsList() { - settingCJKFonts.updateOptions(FSkinFont.getAllCJKFonts()); - } - - @Override - protected void doLayout(float width, float height) { - lstSettings.setBounds(0, 0, width, height); - } - - private abstract class Setting { - protected String label; - protected String description; - protected FPref pref; - - public Setting(FPref pref0, String label0, String description0) { - label = label0; - description = description0; - pref = pref0; - } - - public abstract void select(); - public abstract void drawPrefValue(Graphics g, FSkinFont font, FSkinColor color, float x, float y, float width, float height); - } - - private class BooleanSetting extends Setting { - public BooleanSetting(FPref pref0, String label0, String description0) { - super(pref0, label0, description0); - } - - @Override - public void select() { - FModel.getPreferences().setPref(pref, !FModel.getPreferences().getPrefBoolean(pref)); - FModel.getPreferences().save(); - } - - @Override - public void drawPrefValue(Graphics g, FSkinFont font, FSkinColor color, float x, float y, float w, float h) { - x += w - h; - w = h; - FCheckBox.drawCheckBox(g, SettingsScreen.DESC_COLOR, color, FModel.getPreferences().getPrefBoolean(pref), x, y, w, h); - } - } - - private class CustomSelectSetting extends Setting { - private final List options = new ArrayList<>(); - - public CustomSelectSetting(FPref pref0, String label0, String description0, String[] options0) { - super(pref0, label0 + ":", description0); - - options.addAll(Arrays.asList(options0)); - } - public CustomSelectSetting(FPref pref0, String label0, String description0, Iterable options0) { - super(pref0, label0 + ":", description0); - - if (options0 != null) { - for (String option : options0) { - options.add(option); - } - } - } - public > CustomSelectSetting(FPref pref0, String label0, String description0, Class enumData) { - super(pref0, label0 + ":", description0); - - for (E option : enumData.getEnumConstants()) { - options.add(option.toString()); - } - } - - public void valueChanged(String newValue) { - FModel.getPreferences().setPref(pref, newValue); - FModel.getPreferences().save(); - } - - public void updateOptions(Iterable options0) { - options.clear(); - if (options0 != null) { - for (String option : options0) { - options.add(option); - } - } - } - - @Override - public void select() { - Forge.openScreen(new CustomSelectScreen()); - } - - private class CustomSelectScreen extends FScreen { - private final FList lstOptions; - private final String currentValue = FModel.getPreferences().getPref(pref); - - private CustomSelectScreen() { - super("Select " + label.substring(0, label.length() - 1)); - lstOptions = add(new FList<>(options)); - lstOptions.setListItemRenderer(new FList.DefaultListItemRenderer() { - @Override - public boolean tap(Integer index, String value, float x, float y, int count) { - Forge.back(); - if (!value.equals(currentValue)) { - valueChanged(value); - } - return true; - } - - @Override - public void drawValue(Graphics g, Integer index, String value, FSkinFont font, FSkinColor foreColor, FSkinColor backColor, boolean pressed, float x, float y, float w, float h) { - float offset = SettingsScreen.getInsets(w) - FList.PADDING; //increase padding for settings items - x += offset; - y += offset; - w -= 2 * offset; - h -= 2 * offset; - - g.drawText(value, font, foreColor, x, y, w, h, false, Align.left, true); - - float radius = h / 3; - x += w - radius; - y += h / 2; - g.drawCircle(Utils.scale(1), SettingsScreen.DESC_COLOR, x, y, radius); - if (value.equals(currentValue)) { - g.fillCircle(foreColor, x, y, radius / 2); - } - } - }); - } - - @Override - protected void doLayout(float startY, float width, float height) { - lstOptions.setBounds(0, startY, width, height - startY); - } - - @Override - public FScreen getLandscapeBackdropScreen() { - if (SettingsScreen.launchedFromHomeScreen()) { - } - return null; - } - } - - @Override - public void drawPrefValue(Graphics g, FSkinFont font, FSkinColor color, float x, float y, float w, float h) { - g.drawText(FModel.getPreferences().getPref(pref), font, color, x, y, w, h, false, Align.right, false); - } - } - - private class SettingRenderer extends FList.ListItemRenderer { - @Override - public float getItemHeight() { - return SettingsScreen.SETTING_HEIGHT; - } - - @Override - public boolean tap(Integer index, Setting value, float x, float y, int count) { - value.select(); - return true; - } - - @Override - public void drawValue(Graphics g, Integer index, Setting value, FSkinFont font, FSkinColor foreColor, FSkinColor backColor, boolean pressed, float x, float y, float w, float h) { - float offset = SettingsScreen.getInsets(w) - FList.PADDING; //increase padding for settings items - x += offset; - y += offset; - w -= 2 * offset; - h -= 2 * offset; - - float totalHeight = h; - h = font.getMultiLineBounds(value.label).height + SettingsScreen.SETTING_PADDING; - - g.drawText(value.label, font, foreColor, x, y, w, h, false, Align.left, false); - value.drawPrefValue(g, font, foreColor, x, y, w, h); - h += SettingsScreen.SETTING_PADDING; - g.drawText(value.description, SettingsScreen.DESC_FONT, SettingsScreen.DESC_COLOR, x, y + h, w, totalHeight - h + SettingsScreen.getInsets(w), true, Align.left, false); - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/settings/SettingsScreen.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/settings/SettingsScreen.java deleted file mode 100644 index b6914c6d9a7..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/screens/settings/SettingsScreen.java +++ /dev/null @@ -1,73 +0,0 @@ -package forge.adventure.libgdxgui.screens.settings; - -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.screens.TabPageScreen; -import forge.adventure.libgdxgui.util.Utils; - -public class SettingsScreen extends TabPageScreen { - public static final FSkinFont DESC_FONT = FSkinFont.get(11); - public static final FSkinColor DESC_COLOR = FSkinColor.get(Colors.CLR_TEXT).alphaColor(0.5f); - public static final float SETTING_HEIGHT = Utils.AVG_FINGER_HEIGHT + Utils.scale(12); - public static final float SETTING_PADDING = Utils.scale(5); - private static final float INSETS_FACTOR = 0.025f; - private static final float MAX_INSETS = SETTING_HEIGHT * 0.15f; - - private static boolean fromHomeScreen; - private static SettingsScreen settingsScreen; //keep settings screen around so scroll positions maintained - private final SettingsPage settingsPage; - - public static void show(boolean fromHomeScreen0) { - if (settingsScreen == null) { - settingsScreen = new SettingsScreen(); - } - fromHomeScreen = fromHomeScreen0; - Forge.openScreen(settingsScreen); - } - - public static boolean launchedFromHomeScreen() { - return fromHomeScreen; - } - - public static float getInsets(float itemWidth) { - float insets = itemWidth * INSETS_FACTOR; - if (insets > MAX_INSETS) { - insets = MAX_INSETS; - } - return insets; - } - - public SettingsPage getSettingsPage() { - return settingsPage; - } - - public static SettingsScreen getSettingsScreen() { - return settingsScreen; - } - - @SuppressWarnings("unchecked") - private SettingsScreen() { - super(new TabHeader(new TabPage[] { - new SettingsPage(), - new FilesPage() - }, true) { - @Override - protected boolean showBackButtonInLandscapeMode() { - return !fromHomeScreen; //don't show back button if launched from home screen - } - }); - settingsPage = (SettingsPage) tabPages[0]; - } - - public FScreen getLandscapeBackdropScreen() { - return null; - } - - @Override - public void showMenu() { - Forge.back(); //hide settings screen when menu button pressed - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/sound/AudioClip.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/sound/AudioClip.java deleted file mode 100644 index dd8cd93c169..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/sound/AudioClip.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2012 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.adventure.libgdxgui.sound; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.audio.Sound; -import com.badlogic.gdx.files.FileHandle; -import forge.sound.IAudioClip; -import forge.sound.SoundSystem; - -public class AudioClip implements IAudioClip { - private Sound clip; - - public static AudioClip createClip(String filename) { - FileHandle fileHandle = Gdx.files.absolute(filename); - if (!fileHandle.exists()) { return null; } - return new AudioClip(fileHandle); - } - - private AudioClip(final FileHandle fileHandle) { - try { - clip = Gdx.audio.newSound(fileHandle); - } - catch (Exception ex) { - System.err.println("Unable to load sound file: " + fileHandle.toString()); - } - } - - public final void play(float value) { - if (clip == null) { - return; - } - try { - Thread.sleep(SoundSystem.DELAY); - } - catch (InterruptedException ex) { - ex.printStackTrace(); - } - clip.play(value); - } - - public final void loop() { - if (clip == null) { - return; - } - try { - Thread.sleep(SoundSystem.DELAY); - } - catch (InterruptedException ex) { - ex.printStackTrace(); - } - clip.loop(); - } - - public final void stop() { - if (clip == null) { - return; - } - clip.stop(); - } - - public final boolean isDone() { - return clip != null;//TODO: Make this smarter if Sound supports marking as done - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/sound/AudioMusic.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/sound/AudioMusic.java deleted file mode 100644 index 8ca4dd64234..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/sound/AudioMusic.java +++ /dev/null @@ -1,49 +0,0 @@ -package forge.adventure.libgdxgui.sound; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.audio.Music; -import com.badlogic.gdx.audio.Music.OnCompletionListener; -import forge.sound.IAudioMusic; - -public class AudioMusic implements IAudioMusic { - private final Music music; - - public AudioMusic(String filename) { - music = Gdx.audio.newMusic(Gdx.files.absolute(filename)); - } - - public void play(final Runnable onComplete) { - music.setOnCompletionListener(new OnCompletionListener() { - @Override - public void onCompletion(Music music) { - onComplete.run(); - } - }); - music.play(); - } - - public void pause() { - music.pause(); - } - - public void resume() { - if (!music.isPlaying()) { - music.play(); - } - } - - public void stop() { - music.setOnCompletionListener(null); //prevent firing if stopped manually - music.stop(); - } - - public void dispose() { - stop(); - music.dispose(); - } - - @Override - public void setVolume(float value) { - music.setVolume(value); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/DualListBox.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/DualListBox.java deleted file mode 100644 index 35c8a52b21f..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/DualListBox.java +++ /dev/null @@ -1,238 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.badlogic.gdx.Input.Keys; -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventType; -import forge.util.Callback; -import forge.util.Localizer; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -// An input box for handling the order of choices. -// Left box has the original choices -// Right box has the final order -// Top string will be like Top of the Stack or Top of the Library -// Bottom string will be like Bottom of the Stack or Bottom of the Library -// Single Arrows in between left box and right box for ordering -// Multi Arrows for moving everything in order -// Up/down arrows on the right of the right box for swapping -// Single ok button, disabled until left box has specified number of items remaining -public class DualListBox extends FDialog { - private final ChoiceList sourceList; - private final ChoiceList destList; - - private final FButton addButton; - private final FButton addAllButton; - private final FButton removeButton; - private final FButton removeAllButton; - - private final FLabel orderedLabel; - private final FLabel selectOrder; - - private final int targetRemainingSourcesMin; - private final int targetRemainingSourcesMax; - - public DualListBox(String title, int remainingSources, List sourceElements, List destElements, final Callback> callback) { - this(title, remainingSources, remainingSources, sourceElements, destElements, callback); - } - - public DualListBox(String title, int remainingSourcesMin, int remainingSourcesMax, List sourceElements, List destElements, final Callback> callback) { - super(title, 2); - targetRemainingSourcesMin = remainingSourcesMin; - targetRemainingSourcesMax = remainingSourcesMax; - - final FEventHandler onAdd = new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - if (!addButton.isEnabled()) { return; } - - List selected = sourceList.getSelectedItems(); - destList.clearSelection(); - for (T item : selected) { - sourceList.removeItem(item); - destList.addSelectedIndex(destList.getCount()); - destList.addItem(item); - } - sourceList.cleanUpSelections(); - setButtonState(); - } - }; - - final FEventHandler onRemove = new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - if (!removeButton.isEnabled()) { return; } - - List selected = destList.getSelectedItems(); - sourceList.clearSelection(); - for (T item : selected) { - destList.removeItem(item); - sourceList.addSelectedIndex(sourceList.getCount()); - sourceList.addItem(item); - } - destList.cleanUpSelections(); - setButtonState(); - } - }; - - T typeItem = null; //pass typeItem so both lists use same renderer - if (sourceElements != null && sourceElements.size() > 0) { - typeItem = sourceElements.get(0); - } - else if (destElements != null && destElements.size() > 0) { - typeItem = destElements.get(0); - } - sourceList = add(new ChoiceList(sourceElements, typeItem, onAdd)); - destList = add(new ChoiceList(destElements, typeItem, onRemove)); - - // Dual List control buttons - addButton = add(new FButton(">", onAdd)); - addAllButton = add(new FButton(">>", new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - addAll(); - } - })); - removeButton = add(new FButton("<", onRemove)); - removeAllButton = add(new FButton("<<", new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - removeAll(); - } - })); - - final FEventHandler onAccept = new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - hide(); - callback.run(destList.extractListData()); - } - }; - - // Dual List Complete Buttons - initButton(0, Localizer.getInstance().getMessage("lblOK"), onAccept); - initButton(1, Localizer.getInstance().getMessage("lblAuto"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - addAll(); - onAccept.handleEvent(e); - } - }); - - selectOrder = add(new FLabel.Builder().align(Align.center).text(Localizer.getInstance().getMessage("lblSelectOrder")).build()); - orderedLabel = add(new FLabel.Builder().align(Align.center).build()); - - setButtonState(); - } - - @Override - protected float layoutAndGetHeight(float width, float maxHeight) { - float x = FOptionPane.PADDING; - float y = FOptionPane.PADDING / 2; - width -= 2 * x; - - float gapBetweenButtons = FOptionPane.PADDING / 2; - float labelHeight = selectOrder.getAutoSizeBounds().height; - float listHeight = (maxHeight - 2 * labelHeight - 2 * FOptionPane.PADDING) / 2; - float addButtonWidth = addAllButton.getAutoSizeBounds().width * 1.2f; - float addButtonHeight = listHeight / 2 - gapBetweenButtons; - float listWidth = width - addButtonWidth - gapBetweenButtons; - - selectOrder.setBounds(x, y, width, labelHeight); - y += labelHeight; - sourceList.setBounds(x, y, listWidth, listHeight); - x += width - addButtonWidth; - addButton.setBounds(x, y, addButtonWidth, addButtonHeight); - addAllButton.setBounds(x, y + addButtonHeight + gapBetweenButtons, addButtonWidth, addButtonHeight); - y += listHeight + FOptionPane.PADDING / 2; - - x = FOptionPane.PADDING; - orderedLabel.setBounds(x, y, width, labelHeight); - y += labelHeight; - removeButton.setBounds(x, y, addButtonWidth, addButtonHeight); - removeAllButton.setBounds(x, y + addButtonHeight + gapBetweenButtons, addButtonWidth, addButtonHeight); - destList.setBounds(x + width - listWidth, y, listWidth, listHeight); - - return maxHeight; - } - - public void setSecondColumnLabelText(String label) { - orderedLabel.setText(label); - } - - public List getRemainingSourceList() { - return sourceList.extractListData(); - } - - private void addAll() { - destList.clearSelection(); - for (T item : sourceList) { - destList.addSelectedIndex(destList.getCount()); - destList.addItem(item); - } - sourceList.clear(); - setButtonState(); - } - - private void removeAll() { - sourceList.clearSelection(); - for (T item : destList) { - sourceList.addSelectedIndex(sourceList.getCount()); - sourceList.addItem(item); - } - destList.clear(); - setButtonState(); - } - - private void setButtonState() { - boolean anySize = targetRemainingSourcesMax < 0; - boolean canAdd = sourceList.getCount() != 0 && (anySize || targetRemainingSourcesMin <= sourceList.getCount()); - boolean canRemove = destList.getCount() != 0; - boolean targetReached = anySize || targetRemainingSourcesMin <= sourceList.getCount() && targetRemainingSourcesMax >= sourceList.getCount(); - - setButtonEnabled(1, targetRemainingSourcesMax == 0 && !targetReached); - - addButton.setEnabled(canAdd); - addAllButton.setEnabled(canAdd); - removeButton.setEnabled(canRemove); - removeAllButton.setEnabled(canRemove); - setButtonEnabled(0, targetReached); - } - - private class ChoiceList extends FChoiceList { - private final FEventHandler onActivate; - - private ChoiceList(Collection items, final T typeItem, final FEventHandler onActivate0) { - super(items != null ? items : new ArrayList<>(), typeItem); //handle null without crashing - onActivate = onActivate0; - } - - protected void onItemActivate(Integer index, T value) { - onActivate.handleEvent(new FEvent(this, FEventType.ACTIVATE, value)); - } - } - - @Override - public boolean keyDown(int keyCode) { - switch (keyCode) { - case Keys.ENTER: - case Keys.ESCAPE: //Enter and Escape should trigger either OK or Auto based on which is enabled - if (getButton(0).trigger()) { - return true; - } - return getButton(1).trigger(); - case Keys.SPACE: //Space should trigger OK button if enabled, - //otherwise it should trigger first enabled button (default container behavior) - if (getButton(0).trigger()) { - return true; - } - break; - case Keys.BACK: - return true; //suppress Back button - } - return super.keyDown(keyCode); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FButton.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FButton.java deleted file mode 100644 index b0f7e402664..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FButton.java +++ /dev/null @@ -1,350 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.badlogic.gdx.Input.Keys; -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.FSkinImage; -import forge.gui.UiCommand; -import forge.gui.interfaces.IButton; -import forge.localinstance.skin.FSkinProp; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventType; -import forge.adventure.libgdxgui.util.TextBounds; -import forge.adventure.libgdxgui.util.Utils; -import org.apache.commons.lang3.StringUtils; - -public class FButton extends FDisplayObject implements IButton { - private static final FSkinColor DEFAULT_FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT); - private static final float PADDING = Utils.scale(10); - - private FSkinImage imgL, imgM, imgR; - private String text; - private FSkinFont font; - private FSkinColor foreColor = DEFAULT_FORE_COLOR; - private boolean toggled = false; - private FEventHandler command; - - public enum Corner { - None, - BottomLeft, - BottomRight, - BottomMiddle - } - private Corner corner = Corner.None; - - /** - * Instantiates a new FButton. - */ - public FButton() { - this("", null); - } - - public FButton(final String text0) { - this(text0, null); - } - - public FButton(final String text0, FEventHandler command0) { - text = text0; - command = command0; - font = FSkinFont.get(14); - resetImg(); - } - - private boolean hdbuttonskin(){ - return Forge.hdbuttons; - } - - private void resetImg() { - imgL = FSkinImage.BTN_UP_LEFT; - imgM = FSkinImage.BTN_UP_CENTER; - imgR = FSkinImage.BTN_UP_RIGHT; - if (hdbuttonskin()) - { - imgL = FSkinImage.HDBTN_UP_LEFT; - imgM = FSkinImage.HDBTN_UP_CENTER; - imgR = FSkinImage.HDBTN_UP_RIGHT; - } else { - imgL = FSkinImage.BTN_UP_LEFT; - imgM = FSkinImage.BTN_UP_CENTER; - imgR = FSkinImage.BTN_UP_RIGHT; - } - } - - public String getText() { - return text; - } - public void setText(String text0) { - text = text0; - } - - public FSkinFont getFont() { - return font; - } - public void setFont(FSkinFont font0) { - font = font0; - } - - @Override - public void setEnabled(boolean b0) { - if (isEnabled() == b0) { return; } - super.setEnabled(b0); - - if (b0) { - resetImg(); - } - else { - imgL = FSkinImage.BTN_DISABLED_LEFT; - imgM = FSkinImage.BTN_DISABLED_CENTER; - imgR = FSkinImage.BTN_DISABLED_RIGHT; - if (hdbuttonskin()) - { - imgL = FSkinImage.HDBTN_DISABLED_LEFT; - imgM = FSkinImage.HDBTN_DISABLED_CENTER; - imgR = FSkinImage.HDBTN_DISABLED_RIGHT; - } else { - imgL = FSkinImage.BTN_DISABLED_LEFT; - imgM = FSkinImage.BTN_DISABLED_CENTER; - imgR = FSkinImage.BTN_DISABLED_RIGHT; - } - } - } - - /** - * Button toggle state, for a "permanently pressed" functionality, e.g. as a tab. - * - * @return boolean - */ - public boolean isToggled() { - return toggled; - } - public void setToggled(boolean b0) { - if (toggled == b0) { return; } - toggled = b0; - - if (toggled) { - imgL = FSkinImage.BTN_TOGGLE_LEFT; - imgM = FSkinImage.BTN_TOGGLE_CENTER; - imgR = FSkinImage.BTN_TOGGLE_RIGHT; - if (hdbuttonskin()) - { - imgL = FSkinImage.HDBTN_TOGGLE_LEFT; - imgM = FSkinImage.HDBTN_TOGGLE_CENTER; - imgR = FSkinImage.HDBTN_TOGGLE_RIGHT; - } else { - imgL = FSkinImage.BTN_TOGGLE_LEFT; - imgM = FSkinImage.BTN_TOGGLE_CENTER; - imgR = FSkinImage.BTN_TOGGLE_RIGHT; - } - } - else if (isEnabled()) { - resetImg(); - } - else { - imgL = FSkinImage.BTN_DISABLED_LEFT; - imgM = FSkinImage.BTN_DISABLED_CENTER; - imgR = FSkinImage.BTN_DISABLED_RIGHT; - if (hdbuttonskin()) - { - imgL = FSkinImage.HDBTN_DISABLED_LEFT; - imgM = FSkinImage.HDBTN_DISABLED_CENTER; - imgR = FSkinImage.HDBTN_DISABLED_RIGHT; - } else { - imgL = FSkinImage.BTN_DISABLED_LEFT; - imgM = FSkinImage.BTN_DISABLED_CENTER; - imgR = FSkinImage.BTN_DISABLED_RIGHT; - } - } - } - - public Corner getCorner() { - return corner; - } - public void setCorner(Corner corner0) { - corner = corner0; - } - - public void setCommand(FEventHandler command0) { - command = command0; - } - - public TextBounds getAutoSizeBounds() { - TextBounds bounds = new TextBounds(); - bounds.width = font.getBounds(text).width + 2 * PADDING; - bounds.height = 3 * font.getCapHeight(); - return bounds; - } - - @Override - public final boolean press(float x, float y) { - if (isToggled()) { return true; } - imgL = FSkinImage.BTN_DOWN_LEFT; - imgM = FSkinImage.BTN_DOWN_CENTER; - imgR = FSkinImage.BTN_DOWN_RIGHT; - - if (hdbuttonskin()) - { - imgL = FSkinImage.HDBTN_DOWN_LEFT; - imgM = FSkinImage.HDBTN_DOWN_CENTER; - imgR = FSkinImage.HDBTN_DOWN_RIGHT; - } else { - imgL = FSkinImage.BTN_DOWN_LEFT; - imgM = FSkinImage.BTN_DOWN_CENTER; - imgR = FSkinImage.BTN_DOWN_RIGHT; - } - - return true; - } - - @Override - public final boolean release(float x, float y) { - if (isToggled()) { return true; } - resetImg(); - return true; - } - - @Override - public final boolean tap(float x, float y, int count) { - if (command != null) { - command.handleEvent(new FEvent(this, FEventType.TAP)); - } - return true; - } - - public boolean trigger() { - if (isEnabled() && command != null) { - command.handleEvent(new FEvent(this, FEventType.TAP)); - return true; - } - return false; - } - - @Override - public void draw(Graphics g) { - float x = 0; - float y = 0; - float w = getWidth(); - float h = getHeight(); - - float cornerButtonWidth = w / 2; - float cornerButtonHeight = h * 1.5f; - float cornerTextOffsetX = cornerButtonWidth / 2; - float cornerTextOffsetY = (cornerButtonHeight - h) / 2; - - if (imgL.getTextureRegion() == null) { - //handle rendering buttons before textures loaded - FLabel.drawButtonBackground(g, w, h, imgL == FSkinImage.BTN_DOWN_LEFT); - } - else { - //determine images to draw and text alignment based on which corner button is in (if any) - switch (corner) { - case None: - if (w > 2 * h) { - g.drawImage(imgL, 0, 0, h, h); - g.drawImage(imgM, h, 0, w - (2 * h), h); - g.drawImage(imgR, w - h, 0, h, h); - } - else { - g.drawImage(imgL, 0, 0, cornerButtonWidth, h); - g.drawImage(imgR, cornerButtonWidth, 0, w - cornerButtonWidth, h); - } - x += PADDING; - w -= 2 * PADDING; - break; - case BottomLeft: - g.startClip(x, y, w, h); - g.drawImage(imgM, 0, 0, cornerButtonWidth, cornerButtonHeight); - g.drawImage(imgR, cornerButtonWidth, 0, cornerButtonWidth, cornerButtonHeight); - g.endClip(); - w -= cornerTextOffsetX; - y += cornerTextOffsetY; - h -= cornerTextOffsetY; - break; - case BottomRight: - g.startClip(x, y, w, h); - g.drawImage(imgL, 0, 0, cornerButtonWidth, cornerButtonHeight); - g.drawImage(imgM, cornerButtonWidth, 0, cornerButtonWidth, cornerButtonHeight); - g.endClip(); - x += cornerTextOffsetX; - w -= cornerTextOffsetX; - y += cornerTextOffsetY; - h -= cornerTextOffsetY; - break; - case BottomMiddle: - g.startClip(x, y, w, h); - cornerButtonWidth = w / 3; - cornerTextOffsetX = cornerButtonWidth / 2; - g.drawImage(imgL, 0, 0, cornerButtonWidth, cornerButtonHeight); - g.drawImage(imgM, cornerButtonWidth, 0, w - 2 * cornerButtonWidth, cornerButtonHeight); - g.drawImage(imgR, w - cornerButtonWidth, 0, cornerButtonWidth, cornerButtonHeight); - g.endClip(); - x += cornerTextOffsetX / 2; - w -= cornerTextOffsetX; - y += cornerTextOffsetY; - h -= cornerTextOffsetY; - break; - } - } - - String displayText = text; - if (!StringUtils.isEmpty(displayText)) { - if (corner == Corner.BottomLeft || corner == Corner.BottomRight) { - displayText = displayText.replaceFirst(" ", "\n"); //allow second word to wrap if corner button - } - g.drawText(displayText, font, foreColor, x, y, w, h, false, Align.center, true); - } - } - - @Override - public boolean isSelected() { - return isToggled(); - } - - @Override - public void setSelected(boolean b0) { - setToggled(b0); - } - - @Override - public boolean keyDown(int keyCode) { - switch (keyCode) { - case Keys.ENTER: - case Keys.SPACE: - return trigger(); //trigger button on Enter or Space - } - return false; - } - - //use FEventHandler one except when references as IButton - @Override - public void setCommand(final UiCommand command0) { - setCommand(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - command0.run(); - } - }); - } - - @Override - public boolean requestFocusInWindow() { - return false; - } - - @Override - public void setImage(FSkinProp color) { - foreColor = FSkinColor.get(Colors.fromSkinProp(color)); - } - - @Override - public void setTextColor(int r, int g, int b) { - foreColor = FSkinColor.getStandardColor(r, g, b); - } - - public FSkinColor getForeColor() { - return foreColor; - } -} \ No newline at end of file diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FCardPanel.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FCardPanel.java deleted file mode 100644 index c9d89f21191..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FCardPanel.java +++ /dev/null @@ -1,107 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.card.CardRenderer; -import forge.adventure.libgdxgui.card.CardRenderer.CardStackPosition; -import forge.game.card.CardView; -import forge.adventure.libgdxgui.util.Utils; - -public class FCardPanel extends FDisplayObject { - public static final float ASPECT_RATIO = 3.5f / 2.5f; - public static final float PADDING = Utils.scale(2); - public static final float TARGET_ORIGIN_FACTOR_X = 0.15f; - public static final float TARGET_ORIGIN_FACTOR_Y = 0.5f; - - private CardView card; - private boolean tapped; - private boolean highlighted; - - public FCardPanel() { - this(null); - } - public FCardPanel(CardView card0) { - card = card0; - } - - public CardView getCard() { - return card; - } - public void setCard(CardView card0) { - card = card0; - } - - public boolean isHighlighted() { - return highlighted; - } - public void setHighlighted(boolean highlighted0) { - highlighted = highlighted0; - } - - public boolean isTapped() { - return tapped; - } - public void setTapped(final boolean tapped0) { - tapped = tapped0; - } - - protected float getTappedAngle() { - return -90; - } - - protected boolean renderedCardContains(float x, float y) { - float left = PADDING; - float top = PADDING; - float w = getWidth() - 2 * PADDING; - float h = getHeight() - 2 * PADDING; - if (w == h) { //adjust width if needed to make room for tapping - w = h / ASPECT_RATIO; - } - - if (tapped) { //rotate box if tapped - top += h - w; - float temp = w; - w = h; - h = temp; - } - - return x >= left && x <= left + w && y >= top && y <= top + h; - } - - protected float getPadding() { - return PADDING; - } - - //allow overriding stack position - protected CardStackPosition getStackPosition() { - return CardStackPosition.Top; - } - - @Override - public void draw(Graphics g) { - if (card == null) { return; } - - float padding = getPadding(); - float x = padding; - float y = padding; - float w = getWidth() - 2 * padding; - float h = getHeight() - 2 * padding; - if (w == h) { //adjust width if needed to make room for tapping - w = h / ASPECT_RATIO; - } - - if (tapped) { - float edgeOffset = w / 2f; - g.startRotateTransform(x + edgeOffset, y + h - edgeOffset, getTappedAngle()); - } - - CardRenderer.drawCardWithOverlays(g, card, x, y, w, h, getStackPosition()); - - if (tapped) { - g.endTransform(); - } - } - - public String toString() { - return card == null ? "" : card.toString(); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FCheckBox.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FCheckBox.java deleted file mode 100644 index 91c4eef09c2..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FCheckBox.java +++ /dev/null @@ -1,70 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FImage; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.util.Utils; -import forge.gui.interfaces.ICheckBox; - -public class FCheckBox extends FLabel implements ICheckBox { - private static final FSkinColor CHECK_COLOR = FSkinColor.get(FSkinColor.Colors.CLR_TEXT); - private static final FSkinColor BOX_COLOR = CHECK_COLOR.alphaColor(0.5f); - private static final float EXTRA_GAP = Utils.scale(3); - - public FCheckBox() { - this("", false); - } - public FCheckBox(String text0) { - this(text0, false); - } - public FCheckBox(String text0, boolean selected0) { - super(new Builder().text(text0).align(Align.left).selectable().selected(selected0)); - setIcon(new CheckBoxIcon()); - } - - @Override - protected float getExtraGapBetweenIconAndText() { - return EXTRA_GAP; - } - - private class CheckBoxIcon implements FImage { - @Override - public float getWidth() { - return FCheckBox.this.getHeight(); - } - - @Override - public float getHeight() { - return FCheckBox.this.getHeight(); - } - - @Override - public void draw(Graphics g, float x, float y, float w, float h) { - drawCheckBox(g, isSelected(), x, y, w, h); - } - } - - @Override - public void draw(Graphics g) { - drawContent(g, getWidth(), getHeight(), false); - } - - public static void drawCheckBox(Graphics g, boolean isChecked, float x, float y, float w, float h) { - drawCheckBox(g, BOX_COLOR, CHECK_COLOR, isChecked, x, y, w, h); - } - public static void drawCheckBox(Graphics g, FSkinColor boxColor, FSkinColor checkColor, boolean isChecked, float x, float y, float w, float h) { - g.drawRect(Utils.scale(1), boxColor, x, y, w, h); - if (isChecked) { - //draw check mark - float padX = Utils.scale(3); - float thickness = Utils.scale(2); - x += padX; - y += Utils.scale(1); - w -= 2 * padX; - h -= Utils.scale(3); - g.drawLine(thickness, checkColor, x, y + h / 2, x + w / 2, y + h); - g.drawLine(thickness, checkColor, x + w / 2, y + h, x + w, y); - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FChoiceList.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FChoiceList.java deleted file mode 100644 index 04b1bcd0ca8..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FChoiceList.java +++ /dev/null @@ -1,594 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkin; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.TextRenderer; -import forge.adventure.libgdxgui.card.CardFaceSymbols; -import forge.adventure.libgdxgui.card.CardRenderer; -import forge.adventure.libgdxgui.card.CardRenderer.CardStackPosition; -import forge.adventure.libgdxgui.card.CardZoom; -import forge.adventure.libgdxgui.card.CardZoom.ActivateHandler; -import forge.card.mana.ManaCost; -import forge.card.mana.ManaCostParser; -import forge.game.card.CardView; -import forge.game.card.IHasCardView; -import forge.game.player.PlayerView; -import forge.game.zone.ZoneType; -import forge.item.InventoryItem; -import forge.item.PaperCard; -import forge.itemmanager.AdvancedSearch.FilterOperator; -import forge.adventure.libgdxgui.itemmanager.CardManager; -import forge.adventure.libgdxgui.itemmanager.filters.AdvancedSearchFilter; -import forge.adventure.libgdxgui.itemmanager.filters.ItemFilter; -import forge.localinstance.skin.FSkinProp; -import forge.localinstance.skin.IHasSkinProp; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.screens.match.views.VAvatar; -import forge.adventure.libgdxgui.screens.match.views.VStack; -import forge.util.TextUtil; -import forge.adventure.libgdxgui.util.Utils; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.EnumSet; -import java.util.List; - -import static forge.adventure.libgdxgui.card.CardRenderer.MANA_SYMBOL_SIZE; - -public class FChoiceList extends FList implements ActivateHandler { - public static final FSkinColor ITEM_COLOR = FSkinColor.get(Colors.CLR_ZEBRA); - public static final FSkinColor ALT_ITEM_COLOR = ITEM_COLOR.getContrastColor(-20); - public static final FSkinColor SEL_COLOR = FSkinColor.get(Colors.CLR_ACTIVE); - public static final FSkinColor BORDER_COLOR = FList.FORE_COLOR; - public static final float DEFAULT_ITEM_HEIGHT = Utils.AVG_FINGER_HEIGHT * 0.75f; - - protected final int minChoices, maxChoices; - private final CompactModeHandler compactModeHandler = new CompactModeHandler(); - private final List selectedIndices = new ArrayList<>(); - - public FChoiceList(Iterable items) { - this(items, null); - } - protected FChoiceList(Iterable items, T typeItem) { - this(items, 0, 1, typeItem); - if (getCount() > 0) { - addSelectedIndex(0); //select first item by default - } - } - public FChoiceList(Iterable items, int minChoices0, int maxChoices0) { - this(items, minChoices0, maxChoices0, null); - } - protected FChoiceList(Iterable items, int minChoices0, int maxChoices0, T typeItem) { - super(items); - minChoices = minChoices0; - maxChoices = maxChoices0; - - //determine renderer from first item's type if none passed - T item = typeItem == null ? getItemAt(0) : typeItem; - final ItemRenderer renderer; - if (item instanceof PaperCard) { - renderer = new PaperCardItemRenderer(); - } - else if (item instanceof CardView) { - renderer = new CardItemRenderer(); - } - else if (item instanceof IHasCardView) { - renderer = new IHasCardViewItemRenderer(); - } - else if (item instanceof PlayerView) { - renderer = new PlayerItemRenderer(); - } - else if (item instanceof Integer || item == FilterOperator.EQUALS) { //allow numeric operators to be selected horizontally - renderer = new NumberRenderer(); - } - else if (item instanceof IHasSkinProp) { - renderer = new IHasSkinPropRenderer(); - } - else { - renderer = new DefaultItemRenderer(); - } - setListItemRenderer(new ListItemRenderer() { - private int prevTapIndex = -1; - - @Override - public float getItemHeight() { - return renderer.getItemHeight(); - } - - @Override - public boolean layoutHorizontal() { - return renderer.layoutHorizontal(); - } - - @Override - public AdvancedSearchFilter getAdvancedSearchFilter(ListChooser listChooser) { - return renderer.getAdvancedSearchFilter(listChooser); - } - - @Override - public boolean tap(Integer index, T value, float x, float y, int count) { - boolean activate = (count == 2 && index == prevTapIndex); - if (maxChoices > 1) { - if (selectedIndices.contains(index)) { - if (!activate) { //retain selected item if double tapped - selectedIndices.remove(index); - onSelectionChange(); - } - } - else if (selectedIndices.size() < maxChoices) { - selectedIndices.add(index); - Collections.sort(selectedIndices); //ensure selected indices are sorted - onSelectionChange(); - } - } - else if (maxChoices > 0) { - selectedIndices.clear(); - selectedIndices.add(index); - onSelectionChange(); - } - if (renderer.tap(index, value, x, y, count)) { - activate = false; //don't activate if renderer handles tap - } - if (activate) { - onItemActivate(index, value); - } - prevTapIndex = index; - return true; - } - - @Override - public boolean showMenu(Integer index, T value, FDisplayObject owner, float x, float y) { - return renderer.longPress(index, value, x, y); - } - - @Override - public void drawValue(Graphics g, Integer index, T value, FSkinFont font, FSkinColor foreColor, FSkinColor backColor, boolean pressed, float x, float y, float w, float h) { - if (maxChoices > 1) { - if (pressed) { //if multi-select mode, draw SEL_COLOR when pressed - g.fillRect(SEL_COLOR, x - FList.PADDING, y - FList.PADDING, w + 2 * FList.PADDING, h + 2 * FList.PADDING); - } - //draw checkbox, with it checked based on whether item is selected - float checkBoxSize = h / 2; - float padding = checkBoxSize / 2; - w -= checkBoxSize + padding; - FCheckBox.drawCheckBox(g, selectedIndices.contains(index), x + w, y + padding, checkBoxSize, checkBoxSize); - w -= padding; - } - renderer.drawValue(g, value, font, foreColor, pressed, x, y, w, h); - } - }); - setFont(renderer.getDefaultFont()); - } - - public int getMinChoices() { - return minChoices; - } - - public int getMaxChoices() { - return maxChoices; - } - - public T getSelectedItem() { - if (selectedIndices.size() > 0) { - return getItemAt(selectedIndices.get(0)); - } - return null; - } - - public List getSelectedItems() { - List choices = new ArrayList<>(); - for (int i : selectedIndices) { - choices.add(getItemAt(i)); - } - return choices; - } - - public int getSelectedIndex() { - if (selectedIndices.size() > 0) { - return selectedIndices.get(0); - } - return -1; - } - - public Iterable getSelectedIndices() { - return selectedIndices; - } - - public int getSelectionCount() { - return selectedIndices.size(); - } - - @Override - public void clear() { - super.clear(); - clearSelection(); - } - - public void clearSelection() { - selectedIndices.clear(); - onSelectionChange(); - } - - //remove any selected indices outside item range - public void cleanUpSelections() { - int count = getCount(); - for (int i = 0; i < selectedIndices.size(); i++) { - if (selectedIndices.get(i) >= count) { - selectedIndices.remove(i); - i--; - } - } - if (selectedIndices.isEmpty() && count > 0) { - selectedIndices.add(count - 1); //select last item if nothing remains selected - } - onSelectionChange(); - } - - public void addSelectedIndex(int index) { - selectedIndices.add(index); - onSelectionChange(); - } - - public void addSelectedItem(T choice) { - addSelectedIndex(getIndexOf(choice)); - } - - public void setSelectedIndex(int index) { - selectedIndices.clear(); - selectedIndices.add(index); - scrollIntoView(index); - onSelectionChange(); - } - - public void setSelectedItem(T choice) { - setSelectedIndex(getIndexOf(choice)); - } - - protected String getChoiceText(T choice) { - return choice.toString(); - } - - protected void onItemActivate(Integer index, T value) { - } - - protected void onSelectionChange() { - } - - protected void onCompactModeChange() { - revalidate(); //update scroll bounds by default when compact mode changes - } - - protected boolean allowDefaultItemWrap() { - return false; - } - - @Override - public boolean zoom(float x, float y, float amount) { - if (compactModeHandler.update(amount)) { - onCompactModeChange(); - if (selectedIndices.size() > 0) { - scrollIntoView(selectedIndices.get(0)); //ensure selection remains in view - } - } - return true; - } - - @Override - protected void drawBackground(Graphics g) { - //draw no background - } - - @Override - public void drawOverlay(Graphics g) { - super.drawOverlay(g); - g.drawRect(1.5f, BORDER_COLOR, 0, 0, getWidth(), getHeight()); - } - - @Override - protected FSkinColor getItemFillColor(int index) { - if (maxChoices == 1 && selectedIndices.contains(index)) { - return SEL_COLOR; //don't show SEL_COLOR if in multi-select mode - } - if (index % 2 == 1) { - return ALT_ITEM_COLOR; - } - return ITEM_COLOR; - } - - @Override - protected boolean drawLineSeparators() { - return false; - } - - protected abstract class ItemRenderer { - public abstract FSkinFont getDefaultFont(); - public abstract float getItemHeight(); - public abstract boolean tap(Integer index, T value, float x, float y, int count); - public abstract boolean longPress(Integer index, T value, float x, float y); - public abstract void drawValue(Graphics g, T value, FSkinFont font, FSkinColor foreColor, boolean pressed, float x, float y, float w, float h); - - public boolean layoutHorizontal() { - return false; //this doesn't need to be overridden to specify vertical layouts - } - - public AdvancedSearchFilter getAdvancedSearchFilter(ListChooser listChooser) { - return null; //allow overriding to support advanced search - } - } - protected class DefaultItemRenderer extends ItemRenderer { - @Override - public FSkinFont getDefaultFont() { - return FSkinFont.get(12); - } - - @Override - public float getItemHeight() { - if (allowDefaultItemWrap()) { - return DEFAULT_ITEM_HEIGHT * 1.5f; //provide more height for wrapping - } - return DEFAULT_ITEM_HEIGHT; - } - - @Override - public boolean tap(Integer index, T value, float x, float y, int count) { - return false; - } - - @Override - public boolean longPress(Integer index, T value, float x, float y) { - return false; - } - - @Override - public void drawValue(Graphics g, T value, FSkinFont font, FSkinColor foreColor, boolean pressed, float x, float y, float w, float h) { - //update manacost text to draw symbols instead - if (value.toString().contains(" {")){ - String[] values = value.toString().split(" "); - String cost = TextUtil.fastReplace(values[1],"}{", " "); - cost = TextUtil.fastReplace(TextUtil.fastReplace(cost,"{", ""),"}", ""); - ManaCost manaCost = new ManaCost(new ManaCostParser(cost)); - CardFaceSymbols.drawManaCost(g, manaCost, x + font.getBounds(values[0]+" ").width, y + (h - MANA_SYMBOL_SIZE) / 2, MANA_SYMBOL_SIZE); - g.drawText(values[0], font, foreColor, x, y, w, h, allowDefaultItemWrap(), Align.left, true); - } else { - g.drawText(getChoiceText(value), font, foreColor, x, y, w, h, allowDefaultItemWrap(), Align.left, true); - } - } - } - protected class NumberRenderer extends DefaultItemRenderer { - @Override - public FSkinFont getDefaultFont() { - return FSkinFont.get(14); - } - - @Override - public float getItemHeight() { //this is actually item width since laying out horizontally - float width = Utils.AVG_FINGER_WIDTH; - int itemCount = getCount(); - float totalWidth = width * itemCount; - if (totalWidth < getWidth()) { - width = getWidth() / itemCount; //make items wider to take up full width - } - return width; - } - - @Override - public boolean layoutHorizontal() { - return true; - } - - @Override - public void drawValue(Graphics g, T value, FSkinFont font, FSkinColor foreColor, boolean pressed, float x, float y, float w, float h) { - g.drawText(getChoiceText(value), font, foreColor, x, y, w, h, false, Align.center, true); - } - } - //simple check for cardview needed on some special renderer for cards - private boolean showAlternate(CardView cardView, String value){ - if(cardView == null) - return false; - boolean showAlt = false; - if(cardView.hasAlternateState()){ - if(cardView.hasBackSide()) - showAlt = value.contains(cardView.getBackSideName()); - else if (cardView.isAdventureCard()) - showAlt = value.equals(cardView.getAlternateState().getAbilityText()); - else if (cardView.isSplitCard()) { - //special case if aftermath cards can be cast from graveyard like yawgmoths will, you will have choices - if (cardView.getAlternateState().getOracleText().contains("Aftermath")) - showAlt = cardView.getAlternateState().getOracleText().contains(value); - else - showAlt = value.equals(cardView.getAlternateState().getAbilityText()); - } - } - return showAlt; - } - //special renderer for cards - protected class PaperCardItemRenderer extends ItemRenderer { - @Override - public FSkinFont getDefaultFont() { - return FSkinFont.get(14); - } - - @Override - public float getItemHeight() { - return CardRenderer.getCardListItemHeight(compactModeHandler.isCompactMode()); - } - - @Override - public boolean tap(Integer index, T value, float x, float y, int count) { - return CardRenderer.cardListItemTap(items, index, FChoiceList.this, x, y, count, compactModeHandler.isCompactMode()); - } - - @Override - public boolean longPress(Integer index, T value, float x, float y) { - CardZoom.show(items, index, FChoiceList.this); - return true; - } - - @Override - public void drawValue(Graphics g, T value, FSkinFont font, FSkinColor foreColor, boolean pressed, float x, float y, float w, float h) { - CardRenderer.drawCardListItem(g, font, foreColor, (PaperCard)value, 0, null, x, y, w, h, compactModeHandler.isCompactMode()); - } - - @Override - public AdvancedSearchFilter getAdvancedSearchFilter(final ListChooser listChooser) { - //must create a fake CardManager in order to utilize advance search filter - final CardManager manager = new CardManager(true) { - @Override - public void applyNewOrModifiedFilter(final ItemFilter filter) { - //handle update the visibility of the advanced search filter - boolean empty = filter.isEmpty(); - ItemFilter.Widget widget = filter.getWidget(); - if (widget.isVisible() == empty) { - widget.setVisible(!empty); - listChooser.revalidate(); - } - listChooser.applyFilters(); - } - - @Override - protected void addDefaultFilters() { - //avoid creating unneeded filters - } - }; - return CardManager.createAdvancedSearchFilter(manager); - } - } - //special renderer for cards - protected class CardItemRenderer extends ItemRenderer { - @Override - public FSkinFont getDefaultFont() { - return FSkinFont.get(14); - } - - @Override - public float getItemHeight() { - return CardRenderer.getCardListItemHeight(compactModeHandler.isCompactMode()); - } - - @Override - public boolean tap(Integer index, T value, float x, float y, int count) { - return CardRenderer.cardListItemTap(items, index, FChoiceList.this, x, y, count, compactModeHandler.isCompactMode()); - } - - @Override - public boolean longPress(Integer index, T value, float x, float y) { - CardZoom.show(items, index, FChoiceList.this); - return true; - } - - @Override - public void drawValue(Graphics g, T value, FSkinFont font, FSkinColor foreColor, boolean pressed, float x, float y, float w, float h) { - CardRenderer.drawCardListItem(g, font, foreColor, (CardView)value, 0, null, x, y, w, h, compactModeHandler.isCompactMode()); - } - } - //special renderer for SpellAbilities - protected class IHasCardViewItemRenderer extends ItemRenderer { - private final TextRenderer textRenderer = new TextRenderer(true); - - @Override - public FSkinFont getDefaultFont() { - return FSkinFont.get(14); - } - - @Override - public float getItemHeight() { - return VStack.CARD_HEIGHT + 2 * FList.PADDING; - } - - @Override - public boolean tap(Integer index, T value, float x, float y, int count) { - if (x <= VStack.CARD_WIDTH + 2 * FList.PADDING) { - CardView cv = ((IHasCardView)value).getCardView(); - CardZoom.show(cv, showAlternate(cv, value.toString())); - return true; - } - return false; - } - - @Override - public boolean longPress(Integer index, T value, float x, float y) { - CardView cv = ((IHasCardView)value).getCardView(); - CardZoom.show(cv, showAlternate(cv, value.toString())); - return true; - } - - @Override - public void drawValue(Graphics g, T value, FSkinFont font, FSkinColor foreColor, boolean pressed, float x, float y, float w, float h) { - //should fix NPE ie Thief of Sanity, Gonti... etc - CardView cv = ((IHasCardView)value).getCardView().isFaceDown() && ((IHasCardView)value).getCardView().isInZone(EnumSet.of(ZoneType.Exile)) ? ((IHasCardView)value).getCardView().getBackup() : ((IHasCardView)value).getCardView(); - boolean showAlternate = showAlternate(cv, value.toString()); - CardRenderer.drawCardWithOverlays(g, cv, x, y, VStack.CARD_WIDTH, VStack.CARD_HEIGHT, CardStackPosition.Top, false, showAlternate, true); - - float dx = VStack.CARD_WIDTH + FList.PADDING; - x += dx; - w -= dx; - textRenderer.drawText(g, value.toString(), font, foreColor, x, y, w, h, y, h, true, Align.left, true); - } - } - protected class PlayerItemRenderer extends ItemRenderer { - @Override - public FSkinFont getDefaultFont() { - return FSkinFont.get(18); - } - - @Override - public float getItemHeight() { - return VAvatar.HEIGHT; - } - - @Override - public boolean tap(Integer index, T value, float x, float y, int count) { - return false; - } - - @Override - public boolean longPress(Integer index, T value, float x, float y) { - return false; - } - - @Override - public void drawValue(Graphics g, T value, FSkinFont font, FSkinColor foreColor, boolean pressed, float x, float y, float w, float h) { - PlayerView player = (PlayerView)value; - g.drawImage(MatchController.getPlayerAvatar(player), x - FList.PADDING, y - FList.PADDING, VAvatar.WIDTH, VAvatar.HEIGHT); - x += VAvatar.WIDTH; - w -= VAvatar.WIDTH; - g.drawText(player.getName() + " (" + player.getLife() + ")", font, foreColor, x, y, w, h, false, Align.left, true); - } - } - protected class IHasSkinPropRenderer extends DefaultItemRenderer { - private final TextRenderer textRenderer = new TextRenderer(true); - - @Override - public void drawValue(Graphics g, T value, FSkinFont font, FSkinColor foreColor, boolean pressed, float x, float y, float w, float h) { - FSkinProp skinProp = ((IHasSkinProp)value).getSkinProp(); - if (skinProp != null) { - float iconSize = h * 0.8f; - float offset = (h - iconSize) / 2; - - g.drawImage(FSkin.getImages().get(skinProp), x + offset - 1, y + offset, iconSize, iconSize); - - float dx = iconSize + PADDING + 2 * offset - 1; - x += dx; - w -= dx; - } - textRenderer.drawText(g, value.toString(), font, foreColor, x, y, w, h, y, h, true, Align.left, true); - } - } - - @Override - public String getActivateAction(int index) { - if (maxChoices > 0) { - return "select card"; - } - return null; - } - - @Override - public void activate(int index) { - setSelectedIndex(index); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FComboBox.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FComboBox.java deleted file mode 100644 index 8e4ffbda9f1..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FComboBox.java +++ /dev/null @@ -1,298 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Graphics; -import forge.gui.interfaces.IComboBox; -import forge.adventure.libgdxgui.menu.FDropDownMenu; -import forge.adventure.libgdxgui.menu.FMenuItem; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventType; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -public class FComboBox extends FTextField implements IComboBox { - private final List items = new ArrayList<>(); - private T selectedItem; - private String label = ""; - private final DropDown dropDown = new DropDown(); - private FEventHandler dropDownItemTap, dropDownChangeHandler; - - public FComboBox() { - initialize(); - } - public FComboBox(String label0) { - initialize(); - setLabel(label0); - } - public FComboBox(T[] itemArray) { - items.addAll(Arrays.asList(itemArray)); - initialize(); - } - public FComboBox(Iterable items0) { - for (T item : items0) { - items.add(item); - } - initialize(); - } - - private void initialize() { - if (!items.isEmpty()) { - setSelectedItem(items.get(0)); //select first item by default - } - } - - protected String getDisplayText(T item) { - return item.toString(); - } - - public String getLabel() { - return label; - } - public void setLabel(String label0) { - if (label0 == null) { label0 = ""; } - if (label.equals(label0)) { return; } - label = label0; - if (selectedItem != null) { - super.setText(label + getDisplayText(selectedItem)); - } - else { - super.setText(label); - } - } - - public void setItems(T[] itemArray, T selectedItem0) { - items.clear(); - if (itemArray != null) { - items.addAll(Arrays.asList(itemArray)); - } - setSelectedItem(selectedItem0); - } - public void setItems(Iterable items0, T selectedItem0) { - items.clear(); - if (items0 != null) { - for (T item : items0) { - items.add(item); - } - } - setSelectedItem(selectedItem0); - } - - public void addItem(T item) { - items.add(item); - if (items.size() == 1) { - setSelectedItem(item); //select first item by default - } - } - - public boolean removeItem(T item) { - int restoreIndex = -1; - if (selectedItem == item) { - restoreIndex = getSelectedIndex(); - } - if (items.remove(item)) { - if (restoreIndex >= 0) { - setSelectedIndex(restoreIndex); - } - } - return false; - } - - public void removeAllItems() { - items.clear(); - setSelectedItem(null); - } - - public int getItemCount() { - return items.size(); - } - - public int getSelectedIndex() { - if (selectedItem == null) { return -1; } - return items.indexOf(selectedItem); - } - - public void setSelectedIndex(int index) { - if (index < 0) { - setSelectedItem(null); - return; - } - - if (index >= items.size()) { - index = items.size() - 1; - } - setSelectedItem(items.get(index)); - } - - public T getSelectedItem() { - return selectedItem; - } - - public void setSelectedItem(T item) { - if (selectedItem == item) { return; } - - if (item != null) { - if (items.contains(item)) { - selectedItem = item; - super.setText(label + getDisplayText(item)); - } - else { return; } - } - else { - selectedItem = null; - super.setText(label); - } - - if (getChangedHandler() != null) { - getChangedHandler().handleEvent(new FEvent(this, FEventType.CHANGE, item)); - } - } - - @Override - public void setText(String text0) { - for (T item : items) { - if (getDisplayText(item).equals(text0)) { - setSelectedItem(item); - return; - } - } - selectedItem = null; - super.setText(label + text0); - } - - @Override - public boolean tap(float x, float y, int count) { - dropDown.setVisible(!dropDown.isVisible()); - return true; - } - - @Override - public boolean startEdit() { - return false; //don't allow editing text - } - - public FEventHandler getDropDownItemTap() { - return dropDownItemTap; - } - public void setDropDownItemTap(FEventHandler itemTap0) { - dropDownItemTap = itemTap0; - } - - public FEventHandler getDropDownChangeHandler() { - return dropDownChangeHandler; - } - public void setDropDownChangeHandler(FEventHandler changedHandler0) { - dropDownChangeHandler = changedHandler0; - } - - @Override - public float getAutoSizeWidth() { - //use widest item width to determine auto-size width - float maxTextWidth = 0; - for (T item : items) { - float width = font.getBounds(getDisplayText(item)).width; - if (width > maxTextWidth) { - maxTextWidth = width; - } - } - return PADDING + maxTextWidth + getRightPadding(); - } - - @Override - public void draw(Graphics g) { - super.draw(g); - - float divotWidth = getDivotWidth(); - float divotHeight = divotWidth * 0.5f; - float x3 = getWidth() - PADDING - 1; - float x1 = x3 - divotWidth; - float x2 = x1 + divotWidth / 2; - float y1 = getHeight() / 2 - 1; - float y2 = y1 + divotHeight; - float y3 = y1; - g.fillTriangle(FORE_COLOR, x1, y1, x2, y2, x3, y3); - } - - private float getDivotWidth() { - return getHeight() / 3 + 1; - } - - @Override - protected float getLeftPadding() { - if (getAlignment() == Align.center) { - return getRightPadding(); //match right padding if center aligned - } - return super.getLeftPadding(); - } - - @Override - protected float getRightPadding() { - return getDivotWidth() + 2 * PADDING; - } - - private class DropDown extends FDropDownMenu { - @Override - protected void buildMenu() { - for (final T item : FComboBox.this.items) { - FMenuItem menuItem = new FMenuItem(getDisplayText(item), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - if (dropDownItemTap != null) { - dropDownItemTap.handleEvent(new FEvent(FComboBox.this, FEventType.TAP, item)); - } - if (item != selectedItem) { - setSelectedItem(item); - if (dropDownChangeHandler != null) { - dropDownChangeHandler.handleEvent(new FEvent(FComboBox.this, FEventType.CHANGE, item)); - } - } - } - }); - if (selectedItem == item) { - menuItem.setSelected(true); - } - addItem(menuItem); - } - } - - @Override - protected ScrollBounds updateAndGetPaneSize(float maxWidth, float maxVisibleHeight) { - clear(); - items.clear(); - - buildMenu(); - - //determine needed width of menu - float width = FComboBox.this.getWidth(); - - //set bounds for each item - float y = 0; - for (FMenuItem item : items) { - item.setBounds(0, y, width, FMenuItem.HEIGHT); - y += FMenuItem.HEIGHT; - } - - return new ScrollBounds(width, y); - } - - @Override - protected void updateSizeAndPosition() { - FContainer container = getContainer(); - float containerHeight = container.getHeight(); - - float x = container.screenToLocalX(FComboBox.this.localToScreenX(0)); - float y = FComboBox.this.localToScreenY(FComboBox.this.getHeight()); - - float maxVisibleHeight = containerHeight - y; - paneSize = updateAndGetPaneSize(FComboBox.this.getWidth(), maxVisibleHeight); - - setBounds(Math.round(x), Math.round(y), Math.round(FComboBox.this.getWidth()), Math.min(Math.round(paneSize.getHeight()), maxVisibleHeight)); - } - - @Override - protected FDisplayObject getDropDownOwner() { - return FComboBox.this; - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FContainer.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FContainer.java deleted file mode 100644 index ea49fd60731..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FContainer.java +++ /dev/null @@ -1,159 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.badlogic.gdx.math.Vector2; -import forge.adventure.libgdxgui.Graphics; -import forge.gui.error.BugReporter; - -import java.util.ArrayList; -import java.util.ConcurrentModificationException; -import java.util.List; - -public abstract class FContainer extends FDisplayObject { - private final List children = new ArrayList<>(); - - public T add(T child) { - children.add(child); - return child; - } - - public boolean remove(T child) { - return children.remove(child); - } - - public void clear() { - children.clear(); - } - - public int indexOf(FDisplayObject child) { - return children.indexOf(child); - } - - public FDisplayObject getChildAt(int index) { - return children.get(index); - } - - public int getChildCount() { - return children.size(); - } - - public Iterable getChildren() { - return children; - } - - protected void drawBackground(Graphics g) { - } - - public void draw(Graphics g) { - try { - drawBackground(g); - - boolean needOverlayDrawn = true; - for (FDisplayObject child : children) { - if (child.isVisible()) { - if (child.drawAboveOverlay() && needOverlayDrawn) { - drawOverlay(g); - needOverlayDrawn = false; - } - - final boolean disabled = !child.isEnabled(); - if (disabled) { - g.setAlphaComposite(DISABLED_COMPOSITE); - } - - g.draw(child); - - if (disabled) { - g.resetAlphaComposite(); - } - - child.drawOnContainer(g); //give child an additional chance to draw additional content on container outside its bounds - } - } - - if (needOverlayDrawn) { - drawOverlay(g); - } - } - catch (ConcurrentModificationException ex) { - //ignore concurrent modification exceptions during render - } - catch (Exception ex) { - BugReporter.reportException(ex); - } - } - - protected void drawOverlay(Graphics g) { - } - - @Override - public void setBounds(float x, float y, float width, float height) { - super.setBounds(x, y, width, height); - doLayout(width, height); //always re-do layout when setBounds used - } - - @Override - public void setSize(float width, float height) { - if (getWidth() == width && getHeight() == height) { return; } - - super.setSize(width, height); - doLayout(width, height); - } - - public void revalidate() { - revalidate(false); - } - public void revalidate(boolean forced) { - if (forced) { - doLayout(getWidth(), getHeight()); - return; - } - float w = getWidth(); - float h = getHeight(); - if (w == 0 || h == 0) { return; } //don't revalidate if size not set yet - doLayout(w, h); - } - - protected abstract void doLayout(float width, float height); - - @Override - public void buildTouchListeners(float screenX, float screenY, List listeners) { - if (isEnabled() && isVisible() && screenPos.contains(screenX, screenY)) { - for (int i = children.size() - 1; i >= 0; i--) { - children.get(i).buildTouchListeners(screenX, screenY, listeners); - } - listeners.add(this); - } - } - - public final Vector2 getChildRelativePosition(FDisplayObject child) { - return getChildRelativePosition(child, 0, 0); - } - - protected Vector2 getChildRelativePosition(FDisplayObject child, float offsetX, float offsetY) { - for (FDisplayObject c : children) { //check direct children first - if (child == c) { - return new Vector2(c.getLeft() + offsetX, c.getTop() + offsetY); - } - } - for (FDisplayObject c : children) { //check each child's children next if possible - if (c instanceof FContainer) { - Vector2 pos = ((FContainer)c).getChildRelativePosition(child, c.getLeft() + offsetX, c.getTop() + offsetY); - if (pos != null) { - return pos; - } - } - } - return null; - } - - @Override - public boolean keyDown(int keyCode) { - //by default, give all enabled children a chance handle keyDown - for (FDisplayObject c : children) { - if (c.isEnabled() && c.keyDown(keyCode)) { - return true; - } - } - return false; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FDialog.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FDialog.java deleted file mode 100644 index 73eed121458..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FDialog.java +++ /dev/null @@ -1,303 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.animation.ForgeAnimation; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.FSkinTexture; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.screens.match.views.VPrompt; -import forge.adventure.libgdxgui.toolbox.FButton.Corner; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.util.PhysicsObject; -import forge.util.TextUtil; -import forge.adventure.libgdxgui.util.Utils; - -public abstract class FDialog extends FOverlay { - public static final FSkinFont MSG_FONT = FSkinFont.get(12); - public static final FSkinColor MSG_FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT).alphaColor(0.9f); - public static final FSkinColor MSG_BACK_COLOR = FScreen.Header.BACK_COLOR.alphaColor(0.75f); - public static final float MSG_HEIGHT = MSG_FONT.getCapHeight() * 2.5f; - protected static final FSkinColor BORDER_COLOR = FSkinColor.get(Colors.CLR_BORDERS).alphaColor(0.8f); - protected static final float BORDER_THICKNESS = Utils.scale(1); - private static final FSkinColor SWIPE_BAR_COLOR = FScreen.Header.BACK_COLOR; - private static final FSkinColor SWIPE_BAR_DOT_COLOR = FSkinColor.get(Colors.CLR_TEXT).alphaColor(0.75f); - private static final float SWIPE_BAR_HEIGHT = Utils.scale(12); - - private static int openDialogCount = 0; - - public static boolean isDialogOpen() { - return openDialogCount > 0; - } - - private final VPrompt prompt; - private final FButton btnMiddle; - private final String title; - private final int buttonCount; - private float totalHeight; - private float revealPercent = 0; - private float lastDy = 0; - private boolean finishedFirstReveal; - - protected FDialog(String title0, int buttonCount0) { - buttonCount = buttonCount0; - prompt = add(new VPrompt("", "", null, null)); - if (buttonCount < 3) { - title0 = TextUtil.fastReplace(title0," - ", "\n"); //breakup into lines - btnMiddle = null; - prompt.setMessage(title0); //only put title in message if no third button - } - else { //handle third button - btnMiddle = prompt.add(new FButton()); //add to prompt - btnMiddle.setCorner(Corner.BottomMiddle); - btnMiddle.setSize(VPrompt.BTN_WIDTH, VPrompt.HEIGHT); - btnMiddle.setEnabled(false); //disable until initialized - } - title = title0; - } - - protected float getBottomMargin() { - return 0; - } - - @Override - protected final void doLayout(float width, float height) { - boolean firstReveal = (totalHeight == 0); - float contentHeight = layoutAndGetHeight(width, height - VPrompt.HEIGHT - 2 * MSG_HEIGHT); - totalHeight = contentHeight + VPrompt.HEIGHT; - lastDy = 0; //reset whenever main layout occurs - - if (btnMiddle != null) { - btnMiddle.setLeft((width - btnMiddle.getWidth()) / 2); - if (!title.isEmpty()) { - totalHeight += MSG_HEIGHT; //leave room for title above middle button - } - } - prompt.setBounds(0, totalHeight - VPrompt.HEIGHT, width, VPrompt.HEIGHT); - - updateDisplayTop(); - - if (firstReveal) { //start reveal animation after dialog first laid out - updateRevealAnimation(3 * Forge.getScreenHeight()); - } - } - - private void updateDisplayTop() { - //shift all children into position - float offsetDy = lastDy; - lastDy = getHeight() - (totalHeight + getBottomMargin()) * revealPercent; - float dy = lastDy - offsetDy; - for (FDisplayObject child : getChildren()) { - child.setTop(child.getTop() + dy); - } - } - - @Override - public void setVisible(boolean visible0) { - if (this.isVisible() == visible0) { return; } - - if (visible0) { - openDialogCount++; - MatchController.instance.cancelAwaitNextInput(); //ensure "Waiting for opponent..." prompt doesn't appear while dialog awaiting input - } - else if (openDialogCount > 0) { - openDialogCount--; - } - super.setVisible(visible0); - } - - protected abstract float layoutAndGetHeight(float width, float maxHeight); - - protected void initButton(int index, String text, FEventHandler command) { - FButton button = getButton(index); - if (button == null) { return; } - - button.setText(text); - button.setCommand(command); - button.setEnabled(true); - if (button == btnMiddle) { //allow middle button to be sized to fit text - button.setWidth(button.getAutoSizeBounds().width * 1.25f); - } - } - - protected FButton getButton(int index) { - if (index >= buttonCount) { return null; } - - switch (index) { - case 0: - return prompt.getBtnOk(); - case 1: - if (buttonCount == 2) { - return prompt.getBtnCancel(); - } - return btnMiddle; - case 2: - return prompt.getBtnCancel(); - default: - return null; - } - } - - public boolean isButtonEnabled(int index) { - FButton button = getButton(index); - return button != null && button.isEnabled(); - } - - public void setButtonEnabled(int index, boolean enabled) { - FButton button = getButton(index); - if (button != null) { - button.setEnabled(enabled); - } - } - - @Override - public boolean preventInputBehindOverlay() { - return revealPercent > 0; //prevent input behind overlay unless completely hidden - } - - //allow pan, zoom, and long press behind dialog if hidden - @Override - public boolean pan(float x, float y, float deltaX, float deltaY, boolean moreVertical) { - return preventInputBehindOverlay(); - } - @Override - public boolean panStop(float x, float y) { - return preventInputBehindOverlay(); - } - @Override - public boolean zoom(float x, float y, float amount) { - return preventInputBehindOverlay(); - } - @Override - public boolean longPress(float x, float y) { - return false; //never handle long press inside dialog - } - - @Override - protected void drawBackground(Graphics g) { - super.drawBackground(g); - - if (revealPercent == 0) { return; } - - float x = 0; - float y = getHeight() - (totalHeight + getBottomMargin()) * revealPercent; - float w = getWidth(); - float h = totalHeight - VPrompt.HEIGHT; - g.drawImage(FSkinTexture.BG_TEXTURE, x, y, w, h); - g.fillRect(FScreen.TEXTURE_OVERLAY_COLOR, x, y, w, h); - } - - @Override - public void drawOverlay(Graphics g) { - //draw swipe bar - float dx = SWIPE_BAR_HEIGHT * 0.7f; - float startX = dx * 0.7f; - float x = startX; - float y = getHeight() - (totalHeight + getBottomMargin()) * revealPercent - SWIPE_BAR_HEIGHT; - float w = getWidth(); - float dotRadius = SWIPE_BAR_HEIGHT / 6; - float dotTop = y + SWIPE_BAR_HEIGHT / 2; - int dotCount = 3; - g.fillRect(SWIPE_BAR_COLOR, 0, y, w, SWIPE_BAR_HEIGHT); - for (int i = 0; i < dotCount; i++) { - g.fillCircle(SWIPE_BAR_DOT_COLOR, x, dotTop, dotRadius); - x += dx; - } - x = w - startX; - for (int i = 0; i < dotCount; i++) { - g.fillCircle(BORDER_COLOR, x, dotTop, dotRadius); - x -= dx; - } - g.drawLine(BORDER_THICKNESS, BORDER_COLOR, 0, y, w, y); - - if (revealPercent == 0) { return; } //skip rest if hidden - - y += SWIPE_BAR_HEIGHT; - g.drawLine(BORDER_THICKNESS, BORDER_COLOR, 0, y, w, y); - - //draw border above prompt - y = prompt.getTop(); - if (btnMiddle != null && !title.isEmpty()) { //render title above prompt if middle button present - y -= MSG_HEIGHT; - g.fillRect(VPrompt.BACK_COLOR, 0, y, w, MSG_HEIGHT); - g.drawText(title, VPrompt.FONT, VPrompt.FORE_COLOR, 0, y, w, MSG_HEIGHT, false, Align.center, true); - } - g.drawLine(BORDER_THICKNESS, BORDER_COLOR, 0, y, w, y); - } - - @Override - public boolean fling(float velocityX, float velocityY) { - if (!finishedFirstReveal) { return false; } - - //support toggling temporary hide via swipe - if (Math.abs(velocityY) > Math.abs(velocityX)) { - velocityY = -velocityY; //must reverse velocityY for the sake of animation - if ((revealPercent > 0) == (velocityY > 0)) { - return false; - } - updateRevealAnimation(velocityY); - return true; - } - return false; - } - - private void updateRevealAnimation(float velocity) { - if (activeRevealAnimation == null) { - activeRevealAnimation = new RevealAnimation(velocity); - activeRevealAnimation.start(); - } - else { //update existing animation with new velocity if needed - activeRevealAnimation.physicsObj.getVelocity().set(0, velocity); - } - } - - protected void onRevealFinished() { - //provide ability to handle when first reveal finished - } - - private RevealAnimation activeRevealAnimation; - - private class RevealAnimation extends ForgeAnimation { - private final PhysicsObject physicsObj; - - private RevealAnimation(float velocity) { - physicsObj = new PhysicsObject(new Vector2(0, (totalHeight + getBottomMargin()) * revealPercent), new Vector2(0, velocity)); - } - - @Override - protected boolean advance(float dt) { - if (physicsObj.isMoving()) { //avoid storing last fling stop time if scroll manually stopped - physicsObj.advance(dt); - float newRevealPercent = physicsObj.getPosition().y / (totalHeight + getBottomMargin()); - if (newRevealPercent < 0) { - newRevealPercent = 0; - } - else if (newRevealPercent > 1) { - newRevealPercent = 1; - } - if (revealPercent != newRevealPercent) { - revealPercent = newRevealPercent; - updateDisplayTop(); - return physicsObj.isMoving(); - } - } - - //end fling animation if can't reveal or hide anymore or physics object is no longer moving - return false; - } - - @Override - protected void onEnd(boolean endingAll) { - activeRevealAnimation = null; - if (!finishedFirstReveal) { - finishedFirstReveal = true; - onRevealFinished(); - } - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FDisplayObject.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FDisplayObject.java deleted file mode 100644 index 507f30d8818..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FDisplayObject.java +++ /dev/null @@ -1,168 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.badlogic.gdx.math.Rectangle; -import forge.adventure.libgdxgui.Graphics; - -import java.util.List; - -public abstract class FDisplayObject { - protected static final float DISABLED_COMPOSITE = 0.25f; - - private boolean visible = true; - private boolean enabled = true; - private boolean rotate90 = false; - private boolean rotate180 = false; - private final Rectangle bounds = new Rectangle(); - public final Rectangle screenPos = new Rectangle(); - - public void setPosition(float x, float y) { - bounds.setPosition(x, y); - } - public void setSize(float width, float height) { - bounds.setSize(width, height); - } - public void setBounds(float x, float y, float width, float height) { - bounds.set(x, y, width, height); - } - public float getLeft() { - return bounds.x; - } - public void setLeft(float x) { - bounds.x = x; - } - public float getRight() { - return bounds.x + bounds.width; - } - public float getTop() { - return bounds.y; - } - public void setTop(float y) { - bounds.y = y; - } - public float getBottom() { - return bounds.y + bounds.height; - } - public float getWidth() { - return bounds.width; - } - public void setWidth(float width) { - bounds.width = width; - } - public float getHeight() { - return bounds.height; - } - public void setHeight(float height) { - bounds.height = height; - } - public boolean contains(float x, float y) { - return visible && bounds.contains(x, y); - } - - public float screenToLocalX(float x) { - return x - screenPos.x; - } - public float screenToLocalY(float y) { - return y - screenPos.y; - } - public float localToScreenX(float x) { - return x + screenPos.x; - } - public float localToScreenY(float y) { - return y + screenPos.y; - } - - public boolean isEnabled() { - return enabled; - } - public void setEnabled(boolean b0) { - enabled = b0; - } - - public boolean isVisible() { - return visible; - } - public void setVisible(boolean b0) { - visible = b0; - } - - public boolean getRotate90() { - return rotate90; - } - public void setRotate90(boolean b0) { - rotate90 = b0; - } - public boolean getRotate180() { - return rotate180; - } - public void setRotate180(boolean b0) { - rotate180 = b0; - } - - //these tooltip functions exist for the sake of interfaces, should be overriden if values needed - public String getToolTipText() { - return null; - } - public void setToolTipText(String s0) { - } - - //override to return true if drawOverlay should be called on container before drawing this object - protected boolean drawAboveOverlay() { - return false; - } - - //override if anything should be drawn at the container level immediately after this object is drawn - //this allows drawing outside the bounds of this object - protected void drawOnContainer(Graphics g) { - } - - public abstract void draw(Graphics g); - public void buildTouchListeners(float screenX, float screenY, List listeners) { - if (enabled && visible && screenPos.contains(screenX, screenY)) { - listeners.add(this); - } - } - - public boolean press(float x, float y) { - return false; - } - - public boolean longPress(float x, float y) { - return false; - } - - public boolean release(float x, float y) { - return false; - } - - public boolean tap(float x, float y, int count) { - return false; - } - - public boolean flick(float x, float y) { - return false; - } - - public boolean fling(float velocityX, float velocityY) { - return false; - } - - public boolean flingStop(float x, float y) { - return false; - } - - public boolean pan(float x, float y, float deltaX, float deltaY, boolean moreVertical) { - return false; - } - - public boolean panStop(float x, float y) { - return false; - } - - public boolean zoom(float x, float y, float amount) { - return false; - } - - public boolean keyDown(int keyCode) { - return false; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FEvent.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FEvent.java deleted file mode 100644 index c30e4161441..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FEvent.java +++ /dev/null @@ -1,42 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -public class FEvent { - public enum FEventType { - TAP, - LONG_PRESS, - CHANGE, - ACTIVATE, - SAVE, - DELETE, - CLOSE - } - - private final FDisplayObject source; - private final FEventType type; - private final Object args; - - public FEvent(FDisplayObject source0, FEventType type0) { - this(source0, type0, null); - } - public FEvent(FDisplayObject source0, FEventType type0, Object args0) { - source = source0; - type = type0; - args = args0; - } - - public FDisplayObject getSource() { - return source; - } - - public FEventType getType() { - return type; - } - - public Object getArgs() { - return args; - } - - public interface FEventHandler { - void handleEvent(FEvent e); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FFileChooser.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FFileChooser.java deleted file mode 100644 index fd3f7506d68..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FFileChooser.java +++ /dev/null @@ -1,449 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.badlogic.gdx.Input.Keys; -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.FSkinImage; -import forge.adventure.libgdxgui.menu.FMenuItem; -import forge.adventure.libgdxgui.menu.FPopupMenu; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.util.Callback; -import forge.util.FileUtil; -import forge.util.Localizer; -import forge.adventure.libgdxgui.util.Utils; -import org.apache.commons.lang3.StringUtils; - -import java.io.File; -import java.io.FilenameFilter; - -public class FFileChooser extends FDialog { - private static final float BACK_ICON_THICKNESS = Utils.scale(2); - - public enum ChoiceType { - OpenFile, - SaveFile, - GetDirectory - } - - public static void show(String title0, ChoiceType choiceType0, Callback callback0) { - show(title0, choiceType0, "", "", callback0); - } - public static void show(String title0, ChoiceType choiceType0, String defaultFilename0, Callback callback0) { - show(title0, choiceType0, defaultFilename0, "", callback0); - } - public static void show(String title0, ChoiceType choiceType0, String defaultFilename0, String baseDir0, Callback callback0) { - FFileChooser dialog = new FFileChooser(title0, choiceType0, defaultFilename0, baseDir0, callback0); - dialog.show(); - } - - private final ChoiceType choiceType; - private final String baseDir; - private final Callback callback; - - private final FList lstFiles = add(new FileList()); - private final FTextField txtFilename = add(new FilenameField()); - - private FFileChooser(String title0, ChoiceType choiceType0, String defaultFilename0, String baseDir0, Callback callback0) { - super(title0, 3); - choiceType = choiceType0; - if (choiceType == ChoiceType.GetDirectory) { - if (defaultFilename0.endsWith(File.separator)) { //if getting directory, don't end with a slash - defaultFilename0 = defaultFilename0.substring(0, defaultFilename0.length() - 1); - } - } - txtFilename.setFont(FSkinFont.get(12)); - txtFilename.setText(defaultFilename0); - txtFilename.setChangedHandler(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - refreshFileList(); - } - }); - - initButton(0, Localizer.getInstance().getMessage("lblOK"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - activateSelectedFile(true); - } - }); - initButton(1, Localizer.getInstance().getMessage("lblNewFolder"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - final File dir = getCurrentDir(); - if (dir == null) { - FOptionPane.showErrorDialog(Localizer.getInstance().getMessage("lblCannotAddNewFolderToInvaildFolder"), Localizer.getInstance().getMessage("lblInvalidFolder")); - return; - } - - FOptionPane.showInputDialog(Localizer.getInstance().getMessage("lblEnterNewFolderName"), new Callback() { - @Override - public void run(String result) { - if (StringUtils.isEmpty(result)) { return; } - - try { - File newDir = new File(dir, result); - if (newDir.mkdirs()) { - txtFilename.setText(newDir.getAbsolutePath()); - refreshFileList(); - return; - } - } - catch (Exception e) { - e.printStackTrace(); - } - FOptionPane.showErrorDialog(Localizer.getInstance().getMessage("lblEnterFolderNameNotValid", result), Localizer.getInstance().getMessage("lblInvalidName")); - } - }); - } - }); - initButton(2, Localizer.getInstance().getMessage("lblCancel"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - hide(); - } - }); - - baseDir = baseDir0; - callback = callback0; - refreshFileList(); - } - - @Override - protected float layoutAndGetHeight(float width, float maxHeight) { - float padding = FOptionPane.PADDING; - float w = width - 2 * padding; - - float fieldHeight = txtFilename.getHeight(); - float listHeight = maxHeight - fieldHeight - 2 * padding; - float x = padding; - float y = padding; - txtFilename.setBounds(x, y, w, fieldHeight); - y += fieldHeight + padding; - lstFiles.setBounds(x, y, w, listHeight); - return maxHeight; - } - - private File getCurrentDir() { - String filename = getSelectedFilename(); - File dir = new File(filename); - if (!dir.exists() || !dir.isDirectory()) { - int idx = filename.lastIndexOf(File.separatorChar); - if (idx != -1) { - dir = new File(filename.substring(0, idx)); - } - } - if (dir.exists() && dir.isDirectory()) { - if (choiceType == ChoiceType.GetDirectory) { - dir = dir.getParentFile(); //show parent folder's files and select folder - } - return dir; - } - return null; - } - - private void refreshFileList() { - File dir = getCurrentDir(); - if (dir != null) { - setFileListForDir(dir); - } - else { - lstFiles.setListData(File.listRoots()); - } - scrollSelectionIntoView(); - } - - private void setFileListForDir(File dir) { - FilenameFilter filter = null; - if (choiceType == ChoiceType.GetDirectory) { - //don't list files if getting directory - filter = new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return new File(dir, name).isDirectory(); - } - }; - } - lstFiles.setListData(dir.listFiles(filter)); - } - - private void scrollSelectionIntoView() { - String filename = getSelectedFilename(); - for (int i = 0; i < lstFiles.getCount(); i++) { - if (lstFiles.getItemAt(i).getAbsolutePath().equals(filename)) { - lstFiles.scrollIntoView(i); - return; - } - } - } - - private String getSelectedFilename() { - return baseDir + txtFilename.getText(); - } - - private void activateSelectedFile(boolean fromOkButton) { - String filename = getSelectedFilename(); - File file = new File(filename); - boolean returnDirectory = (choiceType == ChoiceType.GetDirectory); - if (file.exists() && file.isDirectory() && (!fromOkButton || !returnDirectory)) { - //if directory activated not from OK button, open it within dialog - setFileListForDir(file); - if (lstFiles.getCount() > 0) { //select first item if any - txtFilename.setText(lstFiles.getItemAt(0).getAbsolutePath()); - } - else { - txtFilename.setText(file.getAbsolutePath() + File.separator); //indicate no selection in directory - } - scrollSelectionIntoView(); - return; - } - - //validate return value - if (returnDirectory) { - if (!file.exists() || !file.isDirectory()) { - FOptionPane.showErrorDialog(Localizer.getInstance().getMessage("lblNoFolderExistsWithSelectPath"), Localizer.getInstance().getMessage("lblInvalidFolder")); - return; - } - } - else { - if ((!file.exists() && choiceType == ChoiceType.OpenFile) || file.isDirectory()) { - FOptionPane.showErrorDialog(Localizer.getInstance().getMessage("lblNoFileExistsWithSelectPath"), Localizer.getInstance().getMessage("lblInvalidFile")); - return; - } - } - - hide(); - if (returnDirectory) { - filename += File.separator; //re-append separator if returning directory - } - callback.run(filename); - } - - private void back() { - int idx = txtFilename.getText().lastIndexOf(File.separatorChar); - if (idx != -1) { - txtFilename.setText(txtFilename.getText().substring(0, idx)); - refreshFileList(); - } - } - - private void renameFile(final File file) { - final File dir = file.getParentFile(); - if (dir == null) { - FOptionPane.showErrorDialog(Localizer.getInstance().getMessage("lblCannotRenameFileInInvalidFolder"), Localizer.getInstance().getMessage("lblInvalidFolder")); - return; - } - - String title; - if (file.isDirectory()) { - title = Localizer.getInstance().getMessage("lblEnterNewNameForFolder"); - } - else { - title = Localizer.getInstance().getMessage("lblEnterNewNameForFile"); - } - FOptionPane.showInputDialog(title, file.getName(), new Callback() { - @Override - public void run(String result) { - if (StringUtils.isEmpty(result)) { return; } - - try { - File newFile = new File(dir, result); - if (file.renameTo(newFile)) { - txtFilename.setText(newFile.getAbsolutePath()); - refreshFileList(); - return; - } - } - catch (Exception e) { - e.printStackTrace(); - } - FOptionPane.showErrorDialog(Localizer.getInstance().getMessage("lblEnterNameNotValid", result), Localizer.getInstance().getMessage("lblInvalidName")); - } - }); - } - - private void deleteFile(final Integer index, final File file) { - final String deleteBehavior = file.isDirectory() ? Localizer.getInstance().getMessage("lblDeleteFolder") : Localizer.getInstance().getMessage("lblDeleteFile"); - FOptionPane.showConfirmDialog(Localizer.getInstance().getMessage("lblAreYouSureProceedDelete"), deleteBehavior, - Localizer.getInstance().getMessage("lblDelete"), Localizer.getInstance().getMessage("lblCancel"), new Callback() { - @Override - public void run(Boolean result) { - if (result) { - try { - if (FileUtil.deleteDirectory(file)) { //this will ensure directory or file deleted - lstFiles.removeItem(file); - if (lstFiles.getCount() > index) { //select next item if possible - txtFilename.setText(lstFiles.getItemAt(index).getAbsolutePath()); - } - else if (lstFiles.getCount() > 0) { //select new last item otherwise - txtFilename.setText(lstFiles.getItemAt(lstFiles.getCount() - 1).getAbsolutePath()); - } - else { - File dir = getCurrentDir(); - if (dir != null) { - txtFilename.setText(dir.getAbsolutePath() + File.separator); //indicate no selection in directory - } - } - return; - } - } - catch (Exception ex) { - ex.printStackTrace(); - } - FOptionPane.showErrorDialog(Localizer.getInstance().getMessage("lblCouldBotDeleteFile")); - } - } - }); - } - - private class FilenameField extends FTextField { - @Override - public boolean tap(float x, float y, int count) { - if (x < getLeftPadding()) { //handle tapping on back icon - back(); - return true; - } - return super.tap(x, y, count); - } - - @Override - protected float getLeftPadding() { - return getHeight(); - } - - @Override - public void draw(Graphics g) { - super.draw(g); - - //draw back icon - float w = getHeight(); - float h = w; - float x = w * 0.35f; - float y = h / 2; - float offsetX = w / 8; - float offsetY = h / 6; - - g.drawLine(BACK_ICON_THICKNESS, FORE_COLOR, x + offsetX, y - offsetY, x - offsetX, y); - g.drawLine(BACK_ICON_THICKNESS, FORE_COLOR, x - offsetX, y, x + offsetX, y + offsetY); - - x += w * 0.3f; - - g.drawLine(BACK_ICON_THICKNESS, FORE_COLOR, x + offsetX, y - offsetY, x - offsetX, y); - g.drawLine(BACK_ICON_THICKNESS, FORE_COLOR, x - offsetX, y, x + offsetX, y + offsetY); - } - } - - private class FileList extends FList { - private FileList() { - setListItemRenderer(new ListItemRenderer() { - private int prevTapIndex = -1; - - @Override - public float getItemHeight() { - return FChoiceList.DEFAULT_ITEM_HEIGHT; - } - - @Override - public boolean tap(Integer index, File value, float x, float y, int count) { - if (count == 2 && index == prevTapIndex) { - activateSelectedFile(false); - return true; - } - - txtFilename.setText(value.getAbsolutePath()); - prevTapIndex = index; - - if (value.isDirectory() && x < getItemHeight() + 2 * FList.PADDING) { - activateSelectedFile(false); //open folders if icon single tapped - } - return true; - } - - @Override - public boolean showMenu(final Integer index, final File value, FDisplayObject owner, float x, float y) { - txtFilename.setText(value.getAbsolutePath()); - FPopupMenu menu = new FPopupMenu() { - @Override - protected void buildMenu() { - final String renameBehavior = value.isDirectory() ? Localizer.getInstance().getMessage("lblRenameFolder") : Localizer.getInstance().getMessage("lblRenameFile"); - final String deleteBehavior = value.isDirectory() ? Localizer.getInstance().getMessage("lblDeleteFolder") : Localizer.getInstance().getMessage("lblDeleteFile"); - addItem(new FMenuItem(renameBehavior, Forge.hdbuttons ? FSkinImage.HDEDIT : FSkinImage.EDIT, - new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - renameFile(value); - } - })); - addItem(new FMenuItem(deleteBehavior, Forge.hdbuttons ? FSkinImage.HDEDIT : FSkinImage.EDIT, - new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - deleteFile(index, value); - } - })); - } - }; - - menu.show(owner, x, y); - return true; - } - - @Override - public void drawValue(Graphics g, Integer index, File value, FSkinFont font, FSkinColor foreColor, FSkinColor backColor, boolean pressed, float x, float y, float w, float h) { - if (value.isDirectory()) { - float iconSize = h; - g.drawImage(Forge.hdbuttons ? FSkinImage.HDFOLDER : FSkinImage.FOLDER, x, y + (h - iconSize) / 2, iconSize, iconSize); - x += iconSize + FList.PADDING; - } - g.drawText(value.getName(), font, foreColor, x, y, w, h, false, Align.left, true); - } - }); - } - - @Override - protected void drawBackground(Graphics g) { - //draw no background - } - - @Override - public void drawOverlay(Graphics g) { - super.drawOverlay(g); - g.drawRect(1.5f, FChoiceList.BORDER_COLOR, 0, 0, getWidth(), getHeight()); - } - - @Override - protected FSkinColor getItemFillColor(int index) { - if (getItemAt(index).getAbsolutePath().equals(getSelectedFilename())) { - return FChoiceList.SEL_COLOR; //don't show SEL_COLOR if in multi-select mode - } - if (index % 2 == 1) { - return FChoiceList.ALT_ITEM_COLOR; - } - return FChoiceList.ITEM_COLOR; - } - - @Override - protected boolean drawLineSeparators() { - return false; - } - } - - @Override - public boolean keyDown(int keyCode) { - switch (keyCode) { - case Keys.ENTER: - activateSelectedFile(false); - return true; - case Keys.ESCAPE: - if (Forge.endKeyInput()) { return true; } - break; //let FDialog handle it - case Keys.BACK: - case Keys.BACKSPACE: - back(); - return true; - } - return super.keyDown(keyCode); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FGestureAdapter.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FGestureAdapter.java deleted file mode 100644 index 73cdfd8e9d9..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FGestureAdapter.java +++ /dev/null @@ -1,336 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.InputAdapter; -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.utils.Timer; -import com.badlogic.gdx.utils.Timer.Task; -import forge.localinstance.properties.ForgePreferences.FPref; -import forge.model.FModel; -import forge.adventure.libgdxgui.util.Utils; - -public abstract class FGestureAdapter extends InputAdapter { - public abstract boolean press(float x, float y); - public abstract boolean longPress(float x, float y); - public abstract boolean release(float x, float y); - public abstract boolean tap(float x, float y, int count); - public abstract boolean flick(float x, float y); - public abstract boolean fling(float velocityX, float velocityY); - public abstract boolean pan(float x, float y, float deltaX, float deltaY, boolean moreVertical); - public abstract boolean panStop(float x, float y); - public abstract boolean zoom(float x, float y, float amount); - public abstract boolean scrolled(float amountX, float amountY); - - private final float tapSquareSize; - private final float longPressDelay; - private float lastTapX; - private float lastTapY; - private float tapSquareCenterX; - private float tapSquareCenterY; - private final long tapCountInterval; - private final long flingDelay; - private long lastTapTime; - private int tapCount, lastTapButton, lastTapPointer; - private boolean inTapSquare, pressed, longPressed, longPressHandled, pinching, panning, disablePanning; - - private final VelocityTracker tracker = new VelocityTracker(); - private final Vector2 pointer1 = new Vector2(); - private final Vector2 pointer2 = new Vector2(); - private final Vector2 prevPointer1 = new Vector2(); - private final Vector2 prevPointer2 = new Vector2(); - private final Vector2 focalPoint = new Vector2(); - - private final Task longPressTask = new Task() { - @Override - public void run() { - if (pressed) { - if (Gdx.input.isTouched(0)) { - if (!longPressed) { - longPressed = true; - if (longPress(pointer1.x, pointer1.y)) { - if (FModel.getPreferences().getPrefBoolean(FPref.UI_VIBRATE_ON_LONG_PRESS)) { - Gdx.input.vibrate(25); //perform a quick vibrate to signify a successful long press - } - endPress(pointer1.x, pointer1.y); //end press immediately if long press handled - longPressHandled = true; - } - } - } - else { //end press immediately if finger no longer down - endPress(pointer1.x, pointer1.y); - } - } - } - }; - - public FGestureAdapter() { - this(Utils.AVG_FINGER_WIDTH / 2f, 0.25f, 0.5f, 0.15f); - } - - /** @param tapSquareSize0 half width in pixels of the square around an initial touch event - * @param tapCountInterval0 time in seconds that must pass for two touch down/up sequences to be detected as consecutive taps. - * @param longPressDelay0 time in seconds that must pass for a long press event to be fired. - * @param flingDelay0 time in seconds the finger must have been dragged for a fling event to be fired. */ - public FGestureAdapter(float tapSquareSize0, float tapCountInterval0, float longPressDelay0, float flingDelay0) { - tapSquareSize = tapSquareSize0; - tapCountInterval = Utils.secondsToTimeSpan(tapCountInterval0); - longPressDelay = longPressDelay0; - flingDelay = Utils.secondsToTimeSpan(flingDelay0); - } - - @Override - public boolean touchDown(int x, int y, int pointer, int button) { - return touchDown((float)x, (float)y, pointer, button); - } - private boolean touchDown(float x, float y, int pointer, int button) { - if (pointer > 1) { return false; } - - if (pointer == 0) { - pointer1.set(x, y); - if (!Gdx.input.isTouched(1)) { - // handle single finger press - tracker.start(x, y, Gdx.input.getCurrentEventTime()); - inTapSquare = true; - panning = false; - pinching = false; - tapSquareCenterX = x; - tapSquareCenterY = y; - startPress(); - return true; - } - } - else { - pointer2.set(x, y); - if (!Gdx.input.isTouched(0)) { - return true; - } - } - - // start pinch if two fingers down - inTapSquare = false; - panning = false; - pinching = true; - prevPointer1.set(pointer1); - prevPointer2.set(pointer2); - focalPoint.set(Utils.getMidpoint(pointer1, pointer2)); - endPress(pointer1.x, pointer1.y); - return true; - } - - @Override - public boolean touchDragged(int x, int y, int pointer) { - return touchDragged((float)x, (float)y, pointer); - } - private boolean touchDragged(float x, float y, int pointer) { - if (pointer > 1) { return false; } - - if (pointer == 0) { - prevPointer1.set(pointer1); - pointer1.set(x, y); - } - else { - prevPointer2.set(pointer2); - pointer2.set(x, y); - } - - // handle pinch zoom - if (pinching) { - return zoom(focalPoint.x, focalPoint.y, pointer1.dst(pointer2) - prevPointer1.dst(prevPointer2)); - } - - if (disablePanning) { - return false; //avoid updating tracker or panning if second finger just came up but first hasn't yet - } - - // update tracker - tracker.update(x, y, Gdx.input.getCurrentEventTime()); - - // check if we are still tapping. - if (inTapSquare && !isWithinTapSquare(x, y, tapSquareCenterX, tapSquareCenterY)) { - endPress(x, y); - inTapSquare = false; - } - - // if we have left the tap square, we are panning - if (!inTapSquare) { - panning = true; - boolean moreVertical = Math.abs(tracker.startY - y) > Math.abs(tracker.startX - x); - return pan(x, y, tracker.deltaX, tracker.deltaY, moreVertical); - } - return false; - } - - @Override - public boolean touchUp(int x, int y, int pointer, int button) { - return touchUp((float)x, (float)y, pointer, button); - } - private boolean touchUp(float x, float y, int pointer, int button) { - if (pointer > 1) { return false; } - - if (longPressHandled) { //do nothing more if long press handled - longPressHandled = false; //reset for next touch event - return false; - } - - // check if we are still tapping. - if (inTapSquare && !isWithinTapSquare(x, y, tapSquareCenterX, tapSquareCenterY)) { - inTapSquare = false; - } - - boolean wasPanning = panning; - panning = false; - - boolean wasPressed = pressed; - endPress(x, y); - - if (inTapSquare) { - // handle taps - long time = Gdx.input.getCurrentEventTime(); - if (tapCount == 2 //treat 3rd tap as a first tap, and 4th as a double tap - || lastTapButton != button - || lastTapPointer != pointer - || time - lastTapTime > tapCountInterval - || !isWithinTapSquare(x, y, lastTapX, lastTapY)) { - tapCount = 0; - } - tapCount++; - lastTapTime = time; - lastTapX = x; - lastTapY = y; - lastTapButton = button; - lastTapPointer = pointer; - if (wasPressed) { - return tap(x, y, tapCount); - } - return false; - } - - if (pinching) { //don't pan after finishing a pinch - pinching = false; - disablePanning = true; //disable panning until after you release both fingers, otherwise unintentional fling can result - return false; - } - - disablePanning = false; //once both fingers come off, allow panning again - - boolean handled = false; - if (wasPanning) { // handle no longer panning - handled = panStop(x, y); - - long time = Gdx.input.getCurrentEventTime(); - if (time - tracker.lastTime < flingDelay) { // handle flick/fling if needed - tracker.update(x, y, time); - float velocityX = tracker.getVelocityX(); - float velocityY = tracker.getVelocityY(); - if (velocityY < 0 && Math.abs(velocityY) > Math.abs(velocityX)) { - handled = flick(tracker.startX, tracker.startY) || handled; //flick is a special case for flinging towards the top of the screen - } - handled = fling(velocityX, velocityY) || handled; - } - } - return handled; - } - - private void startPress() { - longPressed = false; //ensure these fields reset - longPressHandled = false; - - if (!pressed) { - pressed = true; - press(pointer1.x, pointer1.y); - } - if (!longPressTask.isScheduled()) { - Timer.schedule(longPressTask, longPressDelay); - } - } - - private void endPress(float x, float y) { - longPressTask.cancel(); - - longPressed = false; - if (pressed) { - pressed = false; - release(x, y); - } - } - - private boolean isWithinTapSquare(float x, float y, float centerX, float centerY) { - return Math.abs(x - centerX) < tapSquareSize && Math.abs(y - centerY) < tapSquareSize; - } - - private static class VelocityTracker { - int sampleSize = 10; - float startX, startY; - float lastX, lastY; - float deltaX, deltaY; - long lastTime; - int numSamples; - float[] meanX = new float[sampleSize]; - float[] meanY = new float[sampleSize]; - long[] meanTime = new long[sampleSize]; - - public void start(float x, float y, long timeStamp) { - startX = x; - startY = y; - lastX = x; - lastY = y; - deltaX = 0; - deltaY = 0; - numSamples = 0; - for (int i = 0; i < sampleSize; i++) { - meanX[i] = 0; - meanY[i] = 0; - meanTime[i] = 0; - } - lastTime = timeStamp; - } - - public void update(float x, float y, long timeStamp) { - long currTime = timeStamp; - deltaX = x - lastX; - deltaY = y - lastY; - lastX = x; - lastY = y; - long deltaTime = currTime - lastTime; - lastTime = currTime; - int index = numSamples % sampleSize; - meanX[index] = deltaX; - meanY[index] = deltaY; - meanTime[index] = deltaTime; - numSamples++; - } - - public float getVelocityX() { - float meanX = getAverage(this.meanX, numSamples); - float meanTime = getAverage(this.meanTime, numSamples) / 1000000000.0f; - if (meanTime == 0) { return 0; } - return meanX / meanTime; - } - - public float getVelocityY() { - float meanY = getAverage(this.meanY, numSamples); - float meanTime = getAverage(this.meanTime, numSamples) / 1000000000.0f; - if (meanTime == 0) { return 0; } - return meanY / meanTime; - } - - private float getAverage(float[] values, int numSamples) { - numSamples = Math.min(sampleSize, numSamples); - float sum = 0; - for (int i = 0; i < numSamples; i++) { - sum += values[i]; - } - return sum / numSamples; - } - - private long getAverage(long[] values, int numSamples) { - numSamples = Math.min(sampleSize, numSamples); - long sum = 0; - for (int i = 0; i < numSamples; i++) { - sum += values[i]; - } - if (numSamples == 0) return 0; - return sum / numSamples; - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FGroupBox.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FGroupBox.java deleted file mode 100644 index 0dc8d6a1ddc..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FGroupBox.java +++ /dev/null @@ -1,53 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.util.Utils; - -public abstract class FGroupBox extends FContainer { - private static final FSkinColor FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT); - private static final FSkinFont FONT = FSkinFont.get(16); - private static final float PADDING = Utils.scale(5); - private static final float BORDER_THICKNESS = Utils.scale(1); - - private final String caption; - - public FGroupBox(String caption0) { - caption = caption0; - } - - @Override - protected void drawOverlay(Graphics g) { - float w = getWidth(); - float h = getHeight(); - float x = 2 * PADDING; - float y = FONT.getCapHeight() / 2; - - g.drawLine(BORDER_THICKNESS, FORE_COLOR, 0, y, 0, h); //draw left border - g.drawLine(BORDER_THICKNESS, FORE_COLOR, 0, h, w, h); //draw bottom border - g.drawLine(BORDER_THICKNESS, FORE_COLOR, w, h, w, y); //draw right border - - //draw caption - g.drawText(caption, FONT, FORE_COLOR, x, 0, w - x - PADDING, h, false, Align.left, false); - - //draw border left of caption - g.drawLine(BORDER_THICKNESS, FORE_COLOR, 0, y, x, y); - - //draw border right of caption if needed - float captionEnd = x + FONT.getBounds(caption).width; - if (captionEnd < w) { - g.drawLine(BORDER_THICKNESS, FORE_COLOR, captionEnd, y, w, y); - } - } - - @Override - protected void doLayout(float width, float height) { - float captionHeight = FONT.getLineHeight(); - layoutBox(PADDING, captionHeight + PADDING, getWidth() - 2 * PADDING, getHeight() - captionHeight - 2 * PADDING); - } - - protected abstract void layoutBox(float x, float y, float w, float h); -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FGroupList.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FGroupList.java deleted file mode 100644 index cacedf29e59..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FGroupList.java +++ /dev/null @@ -1,286 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.FSkinTexture; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.toolbox.FList.DefaultListItemRenderer; -import forge.adventure.libgdxgui.toolbox.FList.ListItemRenderer; -import forge.adventure.libgdxgui.util.Utils; - -import java.util.ArrayList; -import java.util.List; - -public class FGroupList extends FScrollPane { - private static final float GROUP_HEADER_HEIGHT = Math.round(Utils.AVG_FINGER_HEIGHT * 0.6f); - - private final List groups = new ArrayList<>(); - private FSkinFont font; - private ListItemRenderer renderer; - - public FGroupList() { - initialize(); - } - public FGroupList(E[] itemArray) { - for (E item : itemArray) { - addItem(item); - } - initialize(); - } - public FGroupList(Iterable items0) { - for (E item : items0) { - addItem(item); - } - initialize(); - } - - private void initialize() { - font = FSkinFont.get(14); - renderer = new DefaultListItemRenderer<>(); - } - - public void addGroup(String groupName) { - groups.add(add(new ListGroup(groupName))); - } - - public void addItem(E item) { - addItem(item, 0); - } - public void addItem(E item, int groupIndex) { - if (groups.isEmpty()) { - addGroup(null); - } - if (groupIndex > groups.size()) { - groupIndex = groups.size() - 1; - } - groups.get(groupIndex).addItem(new ListItem(item)); - } - - public void removeItem(E item) { - for (ListGroup group : groups) { - for (ListItem groupItem : group.items) { - if (groupItem.value == item) { - group.removeItem(groupItem); - if (group.items.isEmpty()) { - groups.remove(group); - } - return; - } - } - } - } - - @Override - public void clear() { - super.clear(); - groups.clear(); - } - - public void setListData(Iterable items0) { - clear(); - for (E item : items0) { - addItem(item); - } - revalidate(); - } - - public boolean isEmpty() { - return groups.isEmpty(); - } - - public int getCount() { - int count = 0; - for (ListGroup group : groups) { - count += group.items.size(); - } - return count; - } - - public ListItem getItemAt(int index) { - int count = 0; - for (ListGroup group : groups) { - for (ListItem item : group.items) { - if (index == count) { - return item; - } - count++; - } - } - return null; - } - - public E getItemValueAt(int index) { - ListItem item = getItemAt(index); - if (item == null) { return null; } - return item.value; - } - - public int getIndexOf(E value) { - int count = 0; - for (ListGroup group : groups) { - for (ListItem item : group.items) { - if (item.value == value) { - return count; - } - count++; - } - } - return -1; - } - - public void setListItemRenderer(ListItemRenderer renderer0) { - renderer = renderer0; - } - - public FSkinFont getFont() { - return font; - } - public void setFont(FSkinFont font0) { - font = font0; - } - - @Override - protected void drawBackground(Graphics g) { - //support scrolling texture with list - g.drawImage(FSkinTexture.BG_TEXTURE, -getScrollLeft(), -getScrollTop(), getScrollWidth(), getScrollHeight()); - g.fillRect(FScreen.TEXTURE_OVERLAY_COLOR, 0, 0, getWidth(), getHeight()); - } - - @Override - protected ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) { - float y = 0; - float groupHeight; - - for (ListGroup group : groups) { - if (group.isVisible()) { - groupHeight = group.getPreferredHeight(); - group.setBounds(0, y, visibleWidth, groupHeight); - y += groupHeight; - } - } - - return new ScrollBounds(visibleWidth, y); - } - - private class ListGroup extends FContainer { - private final FLabel header; - private final List items = new ArrayList<>(); - - private boolean isCollapsed; - - private ListGroup(String name0) { - if (name0 == null) { - header = null; - } - else { - header = add(new FLabel.ButtonBuilder().text(name0).command(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - isCollapsed = !isCollapsed; - FGroupList.this.revalidate(); - } - }).build()); - } - setVisible(false); //hide by default unless it has items - } - - public void addItem(ListItem item) { - items.add(item); - add(item); - setVisible(true); - } - - public boolean removeItem(ListItem item) { - if (items.remove(item)) { - remove(item); - setVisible(items.size() > 0); - return true; - } - return false; - } - - public float getPreferredHeight() { - float height = 0; - if (header != null) { - height += GROUP_HEADER_HEIGHT; - } - if (!isCollapsed) { - height += renderer.getItemHeight() * items.size() + 1; //+1 so bottom border not cut off - } - return height; - } - - @Override - protected void doLayout(float width, float height) { - float y = 0; - if (header != null) { - header.setBounds(0, y, width, GROUP_HEADER_HEIGHT); - y += GROUP_HEADER_HEIGHT; - } - - float itemHeight = renderer.getItemHeight(); - - for (ListItem item : items) { - item.setBounds(0, y, width, itemHeight); - y += itemHeight; - } - } - } - - public class ListItem extends FDisplayObject { - private final E value; - private boolean pressed; - - private ListItem(E value0) { - value = value0; - } - - public boolean press(float x, float y) { - pressed = true; - return true; - } - - public boolean release(float x, float y) { - pressed = false; - return true; - } - - public boolean tap(float x, float y, int count) { - return renderer.tap(-1, value, x, y, count); - } - - public boolean longPress(float x, float y) { - return renderer.showMenu(-1, value, this, x, y); - } - - @Override - public final void draw(Graphics g) { - float w = getWidth(); - float h = renderer.getItemHeight(); - - FSkinColor fillColor = getItemFillColor(this); - if (fillColor != null) { - g.fillRect(fillColor, 0, 0, w, h); - } - - renderer.drawValue(g, -1, value, font, FList.FORE_COLOR, fillColor, pressed, FList.PADDING, FList.PADDING, w - 2 * FList.PADDING, h - 2 * FList.PADDING); - - if (drawLineSeparators()) { - g.drawLine(1, FList.LINE_COLOR, 0, h, w, h); - } - } - } - - protected FSkinColor getItemFillColor(ListItem item) { - if (item.pressed) { - return FList.PRESSED_COLOR; - } - return null; - } - - protected boolean drawLineSeparators() { - return true; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FLabel.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FLabel.java deleted file mode 100644 index eaac0dcb354..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FLabel.java +++ /dev/null @@ -1,449 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FImage; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.TextRenderer; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventType; -import forge.adventure.libgdxgui.util.TextBounds; -import forge.adventure.libgdxgui.util.Utils; -import forge.gui.UiCommand; -import forge.gui.interfaces.IButton; -import forge.localinstance.skin.FSkinProp; - -public class FLabel extends FDisplayObject implements IButton { - public static final float DEFAULT_INSETS = Utils.scale(3); - - public static class Builder { - //========== Default values for FLabel are set here. - private float bldIconScaleFactor = 0.8f; - private FSkinFont bldFont = FSkinFont.get(14); - private float bldAlphaComposite = 0.7f; - private int bldAlignment = Align.left; - private Vector2 bldInsets = new Vector2(DEFAULT_INSETS, DEFAULT_INSETS); - - private boolean bldSelectable = false; - private boolean bldSelected = false; - private boolean bldOpaque = false; - private boolean bldIconInBackground = false; - private boolean bldIconScaleWithFont = false; - private boolean bldIconScaleAuto = true; - private boolean bldEnabled = true; - private boolean bldParseSymbols = true; - - private String bldText; - private FImage bldIcon; - private FSkinColor bldTextColor = DEFAULT_TEXT_COLOR; - private FSkinColor bldPressedColor; - private FEvent.FEventHandler bldCommand; - - public FLabel build() { return new FLabel(this); } - - // Begin builder methods. - public Builder text(final String s0) { this.bldText = s0; return this; } - public Builder icon(final FImage i0) { this.bldIcon = i0; return this; } - //public Builder align(final HAlignment a0) { this.bldAlignment = a0; return this; } - public Builder align(final int a0) { this.bldAlignment = a0; return this; } - public Builder insets(final Vector2 v0) { this.bldInsets = v0; return this; } - public Builder opaque(final boolean b0) { this.bldOpaque = b0; return this; } - public Builder opaque() { opaque(true); return this; } - public Builder selectable(final boolean b0) { this.bldSelectable = b0; return this; } - public Builder selectable() { selectable(true); return this; } - public Builder selected(final boolean b0) { this.bldSelected = b0; return this; } - public Builder selected() { selected(true); return this; } - public Builder command(final FEvent.FEventHandler c0) { this.bldCommand = c0; return this; } - public Builder font(final FSkinFont f0) { this.bldFont = f0; return this; } - public Builder alphaComposite(final float a0) { this.bldAlphaComposite = a0; return this; } - public Builder enabled(final boolean b0) { this.bldEnabled = b0; return this; } - public Builder iconScaleAuto(final boolean b0) { this.bldIconScaleAuto = b0; return this; } - public Builder iconScaleWithFont(final boolean b0) { this.bldIconScaleWithFont = b0; return this; } - public Builder iconScaleFactor(final float f0) { this.bldIconScaleFactor = f0; return this; } - public Builder iconInBackground(final boolean b0) { this.bldIconInBackground = b0; return this; } - public Builder iconInBackground() { iconInBackground(true); return this; } - public Builder textColor(final FSkinColor c0) { this.bldTextColor = c0; return this; } - public Builder pressedColor(final FSkinColor c0) { this.bldPressedColor = c0; return this; } - public Builder parseSymbols() { parseSymbols(true); return this; } - public Builder parseSymbols(final boolean b0) { this.bldParseSymbols = b0; return this; } - } - - // sets better defaults for button labels - public static class ButtonBuilder extends Builder { - public ButtonBuilder() { - opaque(); - align(Align.center); - } - } - - public static void drawButtonBackground(Graphics g, float w, float h, boolean pressed) { - if (pressed) { - g.fillGradientRect(d50, d10, true, 0, 0, w, h); - g.drawRect(BORDER_THICKNESS, d50, 0, 0, w, h); - } - else { - g.fillGradientRect(d10, l20, true, 0, 0, w, h); - g.drawRect(BORDER_THICKNESS, d10, 0, 0, w, h); - } - } - - public static final FSkinColor DEFAULT_TEXT_COLOR = FSkinColor.get(Colors.CLR_TEXT); - public static final FSkinColor INLINE_LABEL_COLOR = DEFAULT_TEXT_COLOR.alphaColor(0.7f); - private static final FSkinColor clrMain = FSkinColor.get(Colors.CLR_INACTIVE); - private static final FSkinColor d50 = clrMain.stepColor(-50); - private static final FSkinColor d30 = clrMain.stepColor(-30); - private static final FSkinColor d10 = clrMain.stepColor(-10); - private static final FSkinColor l10 = clrMain.stepColor(10); - private static final FSkinColor l20 = clrMain.stepColor(20); - public static final float BORDER_THICKNESS = Utils.scale(1); - - private final float iconScaleFactor; - private FSkinFont font; - private final float alphaComposite; - private int alignment; - private Vector2 insets; - private final boolean selectable; - private boolean selected; - private final boolean opaque; - private final boolean iconInBackground; - private boolean iconScaleAuto; - private final boolean iconScaleWithFont; - private boolean pressed; - - private String text; - private FImage icon; - private FSkinColor textColor; - private final FSkinColor pressedColor; - private FEventHandler command; - private TextRenderer textRenderer; - - // Call this using FLabel.Builder()... - protected FLabel(final Builder b0) { - iconScaleFactor = b0.bldIconScaleFactor; - font = b0.bldFont; - alphaComposite = b0.bldAlphaComposite; - alignment = b0.bldAlignment; - insets = b0.bldInsets; - selectable = b0.bldSelectable; - selected = b0.bldSelected; - opaque = b0.bldOpaque; - iconInBackground = b0.bldIconInBackground; - iconScaleAuto = b0.bldIconScaleAuto; - iconScaleWithFont = b0.bldIconScaleWithFont; - text = b0.bldText != null ? b0.bldText : ""; - icon = b0.bldIcon; - textColor = b0.bldTextColor; - pressedColor = b0.bldPressedColor; - command = b0.bldCommand; - if (b0.bldParseSymbols) { - textRenderer = new TextRenderer(); - } - setEnabled(b0.bldEnabled); - } - - public boolean isSelected() { - return selected; - } - public void setSelected(final boolean b0) { - selected = b0; - } - - public String getText() { - return text; - } - public void setText(final String text0) { - text = text0; - } - - public FSkinColor getTextColor() { - return textColor; - } - public void setTextColor(final FSkinColor textColor0) { - textColor = textColor0; - } - - public FSkinFont getFont() { - return font; - } - public void setFont(FSkinFont font0) { - font = font0; - } - - public FImage getIcon() { - return icon; - } - public void setIcon(final FImage icon0) { - icon = icon0; - } - - public boolean getIconScaleAuto() { - return iconScaleAuto; - } - public void setIconScaleAuto(boolean b0) { - iconScaleAuto = b0; - } - - public Vector2 getInsets() { - return insets; - } - public void setInsets(Vector2 insets0) { - insets = insets0; - } - - public int getAlignment() { - return alignment; - } - public void setAlignment(final int alignment0) { - alignment = alignment0; - } - - public void setCommand(final FEventHandler command0) { - command = command0; - } - - public float getAlphaComposite() { - return alphaComposite; - } - - public boolean isPressed() { - return pressed; - } - - @Override - public final boolean press(float x, float y) { - if (opaque || selectable || pressedColor != null) { - pressed = true; - return true; - } - return false; - } - - @Override - public final boolean release(float x, float y) { - if (pressed) { - pressed = false; - return true; - } - return false; - } - - @Override - public boolean tap(float x, float y, int count) { - boolean handled = false; - if (selectable) { - setSelected(!selected); - handled = true; - } - if (command != null) { - command.handleEvent(new FEvent(this, FEventType.TAP)); - handled = true; - } - return handled; - } - - public boolean trigger() { - if (isEnabled() && command != null) { - command.handleEvent(new FEvent(this, FEventType.TAP)); - return true; - } - return false; - } - - public TextBounds getAutoSizeBounds() { - TextBounds bounds; - if (text.isEmpty()) { - bounds = new TextBounds(); - bounds.height += font.getLineHeight(); - } - else { - bounds = font.getMultiLineBounds(text); - bounds.height += font.getLineHeight() - font.getCapHeight(); //account for height below baseline of final line - } - bounds.width += 2 * insets.x; - bounds.height += 2 * insets.y; - - if (icon != null) { - bounds.width += icon.getWidth() + insets.x + getExtraGapBetweenIconAndText(); - } - - return bounds; - } - - @Override - public void draw(Graphics g) { - float w = getWidth(); - float h = getHeight(); - - g.startClip(0, 0, w, h); //start clip to ensure nothing escapes bounds - - boolean applyAlphaComposite = (opaque && !pressed && isEnabled()); - if (applyAlphaComposite) { - g.setAlphaComposite(alphaComposite); - } - - if (pressed) { - if (pressedColor != null) { - g.fillRect(pressedColor, 0, 0, w, h); - } - else { - g.fillGradientRect(d50, d10, true, 0, 0, w, h); - g.drawRect(BORDER_THICKNESS, d50, 0, 0, w, h); - } - } - else if (selected && (opaque || selectable)) { - g.fillGradientRect(d30, l10, true, 0, 0, w, h); - g.drawRect(BORDER_THICKNESS, d30, 0, 0, w, h); - } - else if (opaque) { - g.fillGradientRect(d10, l20, true, 0, 0, w, h); - g.drawRect(BORDER_THICKNESS, d10, 0, 0, w, h); - } - else if (selectable) { - g.drawRect(BORDER_THICKNESS, l10, 0, 0, w, h); - } - - drawContent(g, w, h, pressed); - - if (applyAlphaComposite) { - g.resetAlphaComposite(); - } - - g.endClip(); - } - - protected void drawContent(Graphics g, float w, float h, final boolean pressed) { - float x = insets.x; - float y = insets.y; - w -= 2 * x; - h -= 2 * y; - if (pressed) { //while pressed, translate graphics so icon and text appear shifted down and to the right - x += Utils.scale(1); - y += Utils.scale(1); - } - drawContent(g, x, y, w, h); - } - - protected void drawContent(Graphics g, float x, float y, float w, float h) { - if (icon != null) { - float textY = y; - float iconWidth = icon.getWidth(); - float iconHeight = icon.getHeight(); - float aspectRatio = iconWidth / iconHeight; - - if (iconScaleWithFont) { - iconHeight = font.getLineHeight() * iconScaleFactor; - iconWidth = iconHeight * aspectRatio; - } - else if (iconInBackground || iconScaleAuto) { - iconHeight = h * iconScaleFactor; - iconWidth = iconHeight * aspectRatio; - if (iconWidth > w && iconInBackground) { //ensure background icon stays with label bounds - iconWidth = w; - iconHeight = iconWidth / aspectRatio; - } - } - - float iconOffset = iconWidth + insets.x + getExtraGapBetweenIconAndText(); - - if (iconInBackground || text.isEmpty()) { - if (alignment == Align.center) { - x += (w - iconWidth) / 2; - } - y += (h - iconHeight) / 2; - } - else { - if (alignment == Align.center) { - float dx; - while (true) { - dx = (w - iconOffset - getTextWidth()) / 2; - if (dx > 0) { - x += dx; - break; - } - if (!font.canShrink()) { - break; - } - font = font.shrink(); - } - } - else if (alignment == Align.right) { - float dx; - while (true) { - dx = (w - iconWidth - getTextWidth() - insets.x); - if (dx > 0) { - x += dx; - break; - } - if (!font.canShrink()) { - break; - } - font = font.shrink(); - } - } - y += (h - iconHeight) / 2; - } - - g.drawImage(icon, x, y, iconWidth, iconHeight); - - if (!text.isEmpty()) { - x += iconOffset; - w -= iconOffset; - drawText(g, x, textY, w, h, Align.left); - } - } - else if (!text.isEmpty()) { - drawText(g, x, y, w, h, alignment); - } - } - - private void drawText(Graphics g, float x, float y, float w, float h, int align) { - g.startClip(x, y, w, h); - if (textRenderer == null) { - g.drawText(text, font, textColor, x, y, w, h, false, align, true); - } - else { - textRenderer.drawText(g, text, font, textColor, x, y, w, h, y, h, false, align, true); - } - g.endClip(); - } - - private float getTextWidth() { - if (textRenderer == null) { - return font.getMultiLineBounds(text).width; - } - return textRenderer.getBounds(text, font).width; - } - - //use FEventHandler one except when references as IButton - @Override - public void setCommand(final UiCommand command0) { - setCommand(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - command0.run(); - } - }); - } - - @Override - public boolean requestFocusInWindow() { - return false; - } - - protected float getExtraGapBetweenIconAndText() { - return 0; - } - - @Override - public void setImage(FSkinProp color) { - setTextColor(FSkinColor.get(Colors.fromSkinProp(color))); - } - - @Override - public void setTextColor(int r, int g, int b) { - setTextColor(FSkinColor.getStandardColor(r, g, b)); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FList.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FList.java deleted file mode 100644 index b2cc3e5a2a2..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FList.java +++ /dev/null @@ -1,361 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.FSkinTexture; -import forge.item.InventoryItem; -import forge.adventure.libgdxgui.itemmanager.filters.AdvancedSearchFilter; -import forge.localinstance.properties.ForgePreferences.FPref; -import forge.model.FModel; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.util.Utils; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -public class FList extends FScrollPane implements Iterable { - public static final float PADDING = Utils.scale(3); - public static final FSkinColor FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT); - public static final FSkinColor PRESSED_COLOR = FSkinColor.get(Colors.CLR_ACTIVE).alphaColor(0.9f); - public static final FSkinColor LINE_COLOR = FORE_COLOR.alphaColor(0.5f); - public static final float LINE_THICKNESS = Utils.scale(1); - - protected final List items = new ArrayList<>(); - private FSkinFont font; - private ListItemRenderer renderer; - private int pressedIndex = -1; - - public FList() { - initialize(); - } - public FList(T[] itemArray) { - for (T item : itemArray) { - addItem(item); - } - initialize(); - } - public FList(Iterable items0) { - for (T item : items0) { - addItem(item); - } - initialize(); - } - - private void initialize() { - font = FSkinFont.get(14); - renderer = new DefaultListItemRenderer<>(); - } - - public synchronized void addItem(T item) { - items.add(item); - } - - public synchronized void removeItem(T item) { - items.remove(item); - } - - @Override - public synchronized void clear() { - super.clear(); - items.clear(); - } - - public List extractListData() { - return new ArrayList<>(items); //create copy to avoid modifying items - } - public synchronized void setListData(Iterable items0) { - clear(); - for (T item : items0) { - addItem(item); - } - revalidate(); - } - public synchronized void setListData(T[] items0) { - clear(); - for (T item : items0) { - addItem(item); - } - revalidate(); - } - - public boolean isEmpty() { - return items.isEmpty(); - } - - public int getCount() { - return items.size(); - } - - public T getItemAt(int index) { - if (index < 0 || index >= items.size()) { - return null; - } - return items.get(index); - } - - public int getIndexOf(T item) { - return items.indexOf(item); - } - - public T getItemAtPoint(float x, float y) { - return getItemAt(getIndexAtPoint(x, y)); - } - - public int getIndexAtPoint(float x, float y) { - if (renderer.layoutHorizontal()) { - return (int)((getScrollLeft() + x) / renderer.getItemHeight()); - } - return (int)((getScrollTop() + y) / renderer.getItemHeight()); - } - - public ListItemRenderer getListItemRenderer() { - return renderer; - } - public void setListItemRenderer(ListItemRenderer renderer0) { - renderer = renderer0; - } - - public FSkinFont getFont() { - return font; - } - public void setFont(FSkinFont font0) { - font = font0; - } - - @Override - protected ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) { - if (renderer.layoutHorizontal()) { - return new ScrollBounds(items.size() * renderer.getItemHeight(), visibleHeight); - } - return new ScrollBounds(visibleWidth, items.size() * renderer.getItemHeight()); - } - - @Override - public boolean press(float x, float y) { - pressedIndex = getIndexAtPoint(x, y); - return true; - } - - @Override - public boolean release(float x, float y) { - pressedIndex = -1; - return true; - } - - @Override - public boolean tap(float x, float y, int count) { - int index = getIndexAtPoint(x, y); - T item = getItemAt(index); - if (item == null) { return false; } - - if (renderer.layoutHorizontal()) { - return renderer.tap(index, item, x - getItemStartPosition(index), y, count); - } - return renderer.tap(index, item, x, y - getItemStartPosition(index), count); - } - - public boolean longPress(float x, float y) { - int index = getIndexAtPoint(x, y); - T item = getItemAt(index); - if (item == null) { return false; } - - return renderer.showMenu(index, item, this, x, y); - } - - //return scroll position based on layout orientation - public float getScrollPosition() { - if (renderer.layoutHorizontal()) { - return getScrollLeft(); - } - return getScrollTop(); - } - public void setScrollPosition(float scrollPosition) { - if (renderer.layoutHorizontal()) { - setScrollLeft(scrollPosition); - } - setScrollTop(scrollPosition); - } - public float getVisibleSize() { - if (renderer.layoutHorizontal()) { - return getWidth(); - } - return getHeight(); - } - - public float getItemStartPosition(int index) { - return index * renderer.getItemHeight() - getScrollPosition(); - } - - public void scrollIntoView(int index) { - float itemStartPos = getItemStartPosition(index); - if (itemStartPos < 0) { - setScrollPosition(getScrollPosition() + itemStartPos); - } - else { - float itemEndPosition = itemStartPos + renderer.getItemHeight(); - float visibleSize = getVisibleSize(); - if (itemEndPosition > visibleSize) { - setScrollPosition(getScrollPosition() + itemEndPosition - visibleSize); - } - } - } - - @Override - protected void drawBackground(Graphics g) { - //support scrolling texture with list - g.drawImage(FSkinTexture.BG_TEXTURE, -getScrollLeft(), -getScrollTop(), getScrollWidth(), getScrollHeight()); - g.fillRect(FScreen.TEXTURE_OVERLAY_COLOR, 0, 0, getWidth(), getHeight()); - } - - @Override - public synchronized void draw(Graphics g) { - float w = getWidth(); - float h = getHeight(); - g.startClip(0, 0, w, h); - drawBackground(g); - - //draw only items that are visible - if (!items.isEmpty()) { - int startIndex = getIndexAtPoint(0, 0); - boolean drawSeparators = drawLineSeparators(); - - float x = 0; - float y = Math.round(getItemStartPosition(startIndex)); //round y so items don't flicker from rounding error - float itemWidth = w; - float itemHeight = renderer.getItemHeight(); - - boolean layoutHorizontal = renderer.layoutHorizontal(); - if (layoutHorizontal) { - x = y; - y = 0; - itemWidth = itemHeight; - itemHeight = h; - } - - float padding = getPadding(); - float valueWidth = itemWidth - 2 * padding; - float valueHeight = itemHeight - 2 * padding; - - for (int i = startIndex; i < items.size(); i++) { - if (x > w || y > h) { break; } - - FSkinColor fillColor = getItemFillColor(i); - if (fillColor != null) { - g.fillRect(fillColor, x, y, w, itemHeight); - } - - renderer.drawValue(g, i, items.get(i), font, FORE_COLOR, fillColor, pressedIndex == i, x + padding, y + padding, valueWidth, valueHeight); - - if (layoutHorizontal) { - x += itemWidth; - } - else { - y += itemHeight; - } - - if (drawSeparators) { - if (layoutHorizontal) { - x -= LINE_THICKNESS / 2; - g.drawLine(LINE_THICKNESS, LINE_COLOR, x, 0, x, h); - } - else { - y -= LINE_THICKNESS / 2; - g.drawLine(LINE_THICKNESS, LINE_COLOR, 0, y, w, y); - } - } - } - } - - drawOverlay(g); - g.endClip(); - } - - protected FSkinColor getItemFillColor(int index) { - if (index == pressedIndex) { - return FList.PRESSED_COLOR; - } - return null; - } - - protected boolean drawLineSeparators() { - return true; - } - - protected float getPadding() { - return PADDING; - } - - public static abstract class ListItemRenderer { - public abstract float getItemHeight(); - public abstract boolean tap(Integer index, V value, float x, float y, int count); - public abstract void drawValue(Graphics g, Integer index, V value, FSkinFont font, FSkinColor foreColor, FSkinColor backColor, boolean pressed, float x, float y, float w, float h); - - public boolean showMenu(Integer index, V value, FDisplayObject owner, float x, float y) { - return false; //showing menu on long press is optional - } - - public boolean layoutHorizontal() { - return false; //this doesn't need to be overridden to specify vertical layouts - } - - public AdvancedSearchFilter getAdvancedSearchFilter(ListChooser listChooser) { - return null; //allow overriding to support advanced search - } - } - - public static class DefaultListItemRenderer extends ListItemRenderer { - @Override - public float getItemHeight() { - return Utils.AVG_FINGER_HEIGHT; - } - - @Override - public boolean tap(Integer index, V value, float x, float y, int count) { - return false; - } - - @Override - public void drawValue(Graphics g, Integer index, V value, FSkinFont font, FSkinColor foreColor, FSkinColor backColor, boolean pressed, float x, float y, float w, float h) { - g.drawText(value.toString(), font, foreColor, x, y, w, h, false, Align.left, true); - } - } - - public static class CompactModeHandler { - private static final float REQ_AMOUNT = Utils.AVG_FINGER_WIDTH; - - private float totalZoomAmount; - private boolean compactMode = FModel.getPreferences().getPrefBoolean(FPref.UI_COMPACT_LIST_ITEMS); - - public boolean isCompactMode() { - return compactMode; - } - public void setCompactMode(boolean compactMode0) { - compactMode = compactMode0; - } - - public boolean update(float amount) { - totalZoomAmount += amount; - - if (totalZoomAmount >= REQ_AMOUNT) { - compactMode = false; - totalZoomAmount = 0; - return true; - } - if (totalZoomAmount <= -REQ_AMOUNT) { - compactMode = true; - totalZoomAmount = 0; - return true; - } - return false; - } - } - - @Override - public Iterator iterator() { - return items.iterator(); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FNumericTextField.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FNumericTextField.java deleted file mode 100644 index e7e005742a1..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FNumericTextField.java +++ /dev/null @@ -1,69 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.badlogic.gdx.utils.Align; - -public class FNumericTextField extends FTextField { - private int value; - - public FNumericTextField() { - setAlignment(Align.right); - } - - public FNumericTextField(int value0) { - setAlignment(Align.right); - setValue(value0); - } - - public int getValue() { - return value; - } - public void setValue(int value0) { - if (value0 < 0) { - value0 = 0; - } - if (value == value0) { return; } - value = value0; - super.setText(String.valueOf(value)); - } - - @Override - protected boolean validate() { - return getText().matches("\\d+"); - } - - @Override - public void setText(String text0) { - if (text0.length() > 0) { - //prevent inserting non-numbers - text0 = text0.replaceAll("\\D", ""); - if (text0.length() == 0) { - return; - } - } - super.setText(text0); - if (getText().length() > 0) { - value = Integer.parseInt(getText()); - } - else { - value = 0; - } - } - - @Override - protected void insertText(String text0) { - if (text0.length() > 0) { - //prevent inserting non-numbers - text0 = text0.replaceAll("\\D", ""); - if (text0.length() == 0) { - return; - } - } - super.insertText(text0); - if (getText().length() > 0) { - value = Integer.parseInt(getText()); - } - else { - value = 0; - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FOptionPane.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FOptionPane.java deleted file mode 100644 index f6bfe246d68..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FOptionPane.java +++ /dev/null @@ -1,371 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.badlogic.gdx.Input.Keys; -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.utils.Align; -import com.google.common.collect.ImmutableList; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FImage; -import forge.adventure.libgdxgui.assets.FSkin; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.FSkinImage; -import forge.adventure.libgdxgui.card.CardRenderer; -import forge.adventure.libgdxgui.card.CardZoom; -import forge.adventure.libgdxgui.screens.match.views.VPrompt; -import forge.adventure.libgdxgui.util.Utils; -import forge.game.card.CardView; -import forge.localinstance.skin.FSkinProp; -import forge.util.Callback; -import forge.util.Localizer; -import forge.util.WaitCallback; -import org.apache.commons.lang3.StringUtils; - -import java.util.List; - -public class FOptionPane extends FDialog { - public static final FSkinImage QUESTION_ICON = FSkinImage.QUESTION; - public static final FSkinImage INFORMATION_ICON = FSkinImage.INFORMATION; - public static final FSkinImage WARNING_ICON = FSkinImage.WARNING; - public static final FSkinImage ERROR_ICON = FSkinImage.ERROR; - - public static final float PADDING = Utils.scale(10); - - public static float getMaxDisplayObjHeight() { - return Forge.getScreenHeight() - VPrompt.HEIGHT - 2 * FDialog.MSG_HEIGHT; - } - - public static void showMessageDialog(final String message) { - showMessageDialog(message, "", INFORMATION_ICON); - } - - public static void showMessageDialog(final String message, final String title) { - showMessageDialog(message, title, INFORMATION_ICON); - } - - public static void showErrorDialog(final String message) { - showMessageDialog(message, "", ERROR_ICON); - } - - public static void showErrorDialog(final String message, final String title) { - showMessageDialog(message, title, ERROR_ICON); - } - - public static void showMessageDialog(final String message, final String title, final FImage icon) { - showOptionDialog(message, title, icon, ImmutableList.of(Localizer.getInstance().getMessage("lblOK")), 0, null); - } - - public static void showMessageDialog(final String message, FSkinFont messageFont, final String title, final FImage icon) { - showOptionDialog(message, messageFont, title, icon, ImmutableList.of(Localizer.getInstance().getMessage("lblOK")), 0, null); - } - - public static void showMessageDialog(final String message, final String title, final FImage icon, final Callback callback) { - showOptionDialog(message, title, icon, ImmutableList.of(Localizer.getInstance().getMessage("lblOK")), 0, callback); - } - - public static void showConfirmDialog(final String message, final Callback callback) { - showConfirmDialog(message, "", callback); - } - - public static void showConfirmDialog(final String message, final String title, final Callback callback) { - showConfirmDialog(message, title, Localizer.getInstance().getMessage("lblYes"), Localizer.getInstance().getMessage("lblNo"), true, callback); - } - - public static void showConfirmDialog(final String message, final String title, final boolean defaultYes, final Callback callback) { - showConfirmDialog(message, title, Localizer.getInstance().getMessage("lblYes"), Localizer.getInstance().getMessage("lblNo"), defaultYes, callback); - } - - public static void showConfirmDialog(final String message, final String title, final String yesButtonText, final String noButtonText, final Callback callback) { - showConfirmDialog(message, title, yesButtonText, noButtonText, true, callback); - } - - public static void showConfirmDialog(final String message, final String title, final String yesButtonText, final String noButtonText, final boolean defaultYes, final Callback callback) { - final List options = ImmutableList.of(yesButtonText, noButtonText); - showOptionDialog(message, title, QUESTION_ICON, options, defaultYes ? 0 : 1, new Callback() { - @Override - public void run(final Integer result) { - callback.run(result == 0); - } - }); - } - - public static void showOptionDialog(final String message, final String title, final FImage icon, final List options, final Callback callback) { - showOptionDialog(message, title, icon, options, 0, callback); - } - - public static void showOptionDialog(final String message, final String title, final FImage icon, final List options, final int defaultOption, final Callback callback) { - showOptionDialog(message, null, title, icon, options, defaultOption, callback); - } - - public static void showOptionDialog(final String message, final FSkinFont messageFont, final String title, final FImage icon, final List options, final int defaultOption, final Callback callback) { - final FOptionPane optionPane = new FOptionPane(message, messageFont, title, icon, null, options, defaultOption, callback); - optionPane.show(); - } - - public static int showCardOptionDialog(final CardView card, final String message, final String title, final FSkinProp icon, final List options, final int defaultOption) { - return new WaitCallback() { - @Override - public void run() { - FOptionPane.showCardOptionDialog(card, message, title, icon == null ? null : FSkin.getImages().get(icon), options, defaultOption, this); - } - }.invokeAndWait(); - } - - public static void showCardOptionDialog(final CardView card, String message, String title, FImage icon, final List options, final int defaultOption, final Callback callback) { - final FDisplayObject cardDisplay; - if (card != null) { - cardDisplay = new FDisplayObject() { - @Override - public boolean tap(final float x, final float y, final int count) { - CardZoom.show(card); - return true; - } - @Override - public boolean longPress(final float x, final float y) { - CardZoom.show(card); - return true; - } - @Override - public void draw(final Graphics g) { - final float h = getHeight(); - final float w = h / FCardPanel.ASPECT_RATIO; - final float x = (getWidth() - w) / 2; - final float y = 0; - - CardRenderer.drawCard(g, card, x, y, w, h, CardRenderer.CardStackPosition.Top, true); - } - }; - cardDisplay.setHeight(Forge.getScreenHeight() / 2); - } - else { - cardDisplay = null; - } - - //if title not specified and message is a single line, show message as title - if (StringUtils.isEmpty(title) && !message.contains("\n")) { - title = message; - message = null; - icon = null; - } - - final FOptionPane optionPane = new FOptionPane(message, null, title, icon, cardDisplay, options, defaultOption, callback); - optionPane.show(); - } - - public static void showInputDialog(final String title, final Callback callback) { - showInputDialog(null, title, "", null, callback); - } - public static void showInputDialog(final String title, final T initialInput, final Callback callback) { - showInputDialog(null, title, initialInput, null, callback); - } - public static void showInputDialog(final String message, final String title, final T initialInput, final List inputOptions, final Callback callback) { - final FDisplayObject inputField; - final FTextField txtInput; - final FComboBox cbInput; - if (inputOptions == null) { - txtInput = new FTextField(initialInput.toString()); - cbInput = null; - inputField = txtInput; - } - else { - txtInput = null; - cbInput = new FComboBox<>(inputOptions); - cbInput.setSelectedItem(initialInput); - inputField = cbInput; - } - - final float padTop = message == null ? PADDING : 0; - - //use container to add padding above and below field - final FContainer container = new FContainer() { - @Override - protected void doLayout(final float width, final float height) { - inputField.setBounds(0, padTop, width, inputField.getHeight()); - } - }; - container.add(inputField); - container.setHeight(inputField.getHeight() + padTop + PADDING); - - final FOptionPane optionPane = new FOptionPane(message, null, title, null, container, ImmutableList.of(Localizer.getInstance().getMessage("lblOK"), Localizer.getInstance().getMessage("lblCancel")), 0, new Callback() { - @SuppressWarnings("unchecked") - @Override - public void run(final Integer result) { - if (result == 0) { - if (txtInput != null) { - callback.run((T)txtInput.getText()); - } else { - callback.run(cbInput.getSelectedItem()); - } - } else { - callback.run(null); - } - } - }) { - @Override - protected float getBottomMargin() { - return Forge.getScreenHeight() * 0.4f; //account for keyboard - } - - @Override - protected boolean padAboveAndBelow() { - return false; //let container around text field handle padding - } - - @Override - protected boolean centerPrompt() { - return true; - } - }; - optionPane.show(); - if (txtInput != null) { - txtInput.startEdit(); - } - } - - private final FLabel lblIcon; - private final FTextArea prompt; - protected final FDisplayObject displayObj; - private final Callback callback; - private final int defaultOption; - private final boolean centerIcon; - - public FOptionPane(final String message, final FSkinFont messageFont, final String title, final FImage icon, final FDisplayObject displayObj0, final List options, final int defaultOption0, final Callback callback0) { - super(title, options.size()); - - if (icon != null) { - centerIcon = icon.getWidth() >= 100; //for large icon, center in dialog - lblIcon = add(new FLabel.Builder().icon(icon).iconScaleFactor(1).insets(new Vector2(0, 0)).iconInBackground(centerIcon).build()); - if (centerIcon) { - lblIcon.setAlignment(Align.center); - } - } - else { - lblIcon = null; - centerIcon = false; - } - - if (message != null) { - prompt = add(new FTextArea(true, message)); - prompt.setFont(messageFont != null ? messageFont : FSkinFont.get(12)); - if (centerIcon || centerPrompt()) { - prompt.setAlignment(Align.center); - } - } - else { - prompt = null; - } - - displayObj = displayObj0; - if (displayObj != null) { - add(displayObj); - } - - callback = callback0; - - final int optionsSize = options.size(); - for (int i = 0; i < optionsSize; i++) { - final int option = i; - initButton(i, options.get(i), new FEvent.FEventHandler() { - @Override - public void handleEvent(final FEvent e) { - setResult(option); - } - }); - } - defaultOption = defaultOption0; - } - - public void setResult(final int option) { - hide(); - if (callback != null) { - callback.run(option); - } - } - - protected boolean padAboveAndBelow() { - return true; - } - - protected boolean centerPrompt() { - return false; - } - - @Override - protected float layoutAndGetHeight(final float width, final float maxHeight) { - float x = PADDING; - float y = PADDING; - - float maxPromptHeight = maxHeight - 2 * PADDING; - if (displayObj != null) { - maxPromptHeight -= displayObj.getHeight(); - } - - float promptHeight = 0; - if (lblIcon != null) { - final float labelWidth = Utils.scale(lblIcon.getIcon().getWidth()); - promptHeight = lblIcon.getIcon().getHeight() * labelWidth / lblIcon.getIcon().getWidth(); - if (promptHeight > maxPromptHeight) { - promptHeight = maxPromptHeight; - } - if (centerIcon) { - lblIcon.setBounds(x, y, width - 2 * PADDING, promptHeight); - y += promptHeight + PADDING; - } - else { - lblIcon.setBounds(x - Utils.scale(3), y, labelWidth, promptHeight); - x += labelWidth; - } - } - if (prompt != null) { - final float promptWidth = width - x - PADDING; - prompt.setBounds(x, y, promptWidth, prompt.getPreferredHeight(promptWidth)); - if (prompt.getHeight() < promptHeight && !centerIcon) { - //ensure prompt centered next to icon if less tall than icon - prompt.setTop(y + (promptHeight - prompt.getHeight()) / 2); - } - else if (prompt.getHeight() > maxPromptHeight) { - prompt.setHeight(maxPromptHeight); - } - if (prompt.getHeight() > promptHeight || centerIcon) { - promptHeight = prompt.getHeight(); - } - } - - if (promptHeight > 0) { - y += promptHeight + PADDING; - } - - if (displayObj != null) { - if (!padAboveAndBelow()) { - y -= PADDING; - } - displayObj.setBounds(0, y, width, displayObj.getHeight()); - y += displayObj.getHeight(); - if (padAboveAndBelow()) { - y += PADDING; - } - } - return y; - } - - @Override - public boolean keyDown(final int keyCode) { - switch (keyCode) { - case Keys.ENTER: - case Keys.SPACE: - if (isButtonEnabled(defaultOption)) { - setResult(defaultOption); //set result to default option on Enter/Space - } - return true; - case Keys.ESCAPE: - case Keys.BACK: - if (Forge.endKeyInput()) { return true; } - - if (isButtonEnabled(1)) { - setResult(1); //set result to final option on Escape or Back - } - return true; - } - return super.keyDown(keyCode); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FOverlay.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FOverlay.java deleted file mode 100644 index 67743671bda..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FOverlay.java +++ /dev/null @@ -1,210 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.badlogic.gdx.Input.Keys; -import com.badlogic.gdx.utils.Timer; -import com.badlogic.gdx.utils.Timer.Task; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.gui.FThreads; - -import java.util.ArrayList; -import java.util.List; -import java.util.Stack; - -public abstract class FOverlay extends FContainer { - public static final float ALPHA_COMPOSITE = 0.5f; - private static final Stack overlays = new Stack<>(); - private static boolean hidingAll = false; - private static FOverlay tempOverlay; - - private final FSkinColor backColor; - private FScreen openedOnScreen; - - public FOverlay() { - this(FSkinColor.get(FSkinColor.Colors.CLR_OVERLAY).alphaColor(ALPHA_COMPOSITE)); - } - public FOverlay(FSkinColor backColor0) { - backColor = backColor0; - super.setVisible(false); //hide by default - } - - public static FOverlay getTopOverlay() { - if (overlays.isEmpty()) { - return null; - } - return overlays.peek(); - } - - public static Iterable getOverlays() { - return overlays; - } - - //get list of overlays for iterating from top overlay down - public static Iterable getOverlaysTopDown() { - if (overlays.size() < 2) { - return overlays; //don't need to create new list if one or fewer overlay - } - List reversedList = new ArrayList<>(); - for (int i = overlays.size() - 1; i >= 0; i--) { - reversedList.add(overlays.get(i)); - } - return reversedList; - } - - public boolean preventInputBehindOverlay() { - return true; //prevent input behind overlay by default - } - - public static void hideAll() { - hidingAll = true; - for (int i = overlays.size() - 1; i >= 0; i--) { - overlays.get(i).hide(); - } - overlays.clear(); - hidingAll = false; - } - - private static final Task hideTempOverlayTask = new Task() { - @Override - public void run () { - tempOverlay.hide(); - tempOverlay = null; - } - }; - - public void show() { - setVisible(true); - } - - public void hide() { - setVisible(false); - } - - public void finishedloading() { - Forge.setLoadingaMatch(false); - } - - public boolean isVisibleOnScreen(FScreen screen) { - return (openedOnScreen == screen); //by default, only show overlay on the same screen it's opened on - } - - @Override - public void setVisible(boolean visible0) { - FThreads.assertExecutedByEdt(true); //prevent showing or hiding overlays from background thread - - if (this.isVisible() == visible0) { return; } - - //ensure task to hide temporary overlay cancelled and run if another overlay becomes shown or hidden - if (tempOverlay != this && hideTempOverlayTask.isScheduled()) { - hideTempOverlayTask.cancel(); - hideTempOverlayTask.run(); - } - - if (visible0) { - //rotate overlay to face top human player if needed - setRotate180(MatchController.getView() != null && MatchController.getView().isTopHumanPlayerActive()); - overlays.push(this); - openedOnScreen = Forge.getCurrentScreen(); - } - else { - openedOnScreen = null; - - if (!hidingAll) { //hiding all handles cleaning up overlay collection - if (overlays.get(overlays.size() - 1) == this) { - //after removing the top overlay, delay hiding overlay for a brief period - //to prevent back color flickering if another popup immediately follows - if (tempOverlay != this && backColor != null) { - tempOverlay = this; - Timer.schedule(hideTempOverlayTask, 0.025f); - return; - } - overlays.pop(); - } - else { - overlays.remove(this); - } - } - } - super.setVisible(visible0); - } - - public FSkinColor getBackColor() { - return backColor; - } - - @Override - protected void drawBackground(Graphics g) { - if (backColor == null) { return; } - - g.fillRect(backColor, 0, 0, this.getWidth(), this.getHeight()); - } - - //override all gesture listeners to prevent passing to display objects behind it - @Override - public boolean press(float x, float y) { - return true; - } - - @Override - public boolean longPress(float x, float y) { - return true; - } - - @Override - public boolean release(float x, float y) { - return true; - } - - @Override - public boolean tap(float x, float y, int count) { - return true; - } - - @Override - public boolean flick(float x, float y) { - return true; - } - - @Override - public boolean fling(float velocityX, float velocityY) { - return true; - } - - @Override - public boolean pan(float x, float y, float deltaX, float deltaY, boolean moreVertical) { - return true; - } - - @Override - public boolean panStop(float x, float y) { - return true; - } - - @Override - public boolean zoom(float x, float y, float amount) { - return true; - } - - @Override - public void buildTouchListeners(float screenX, float screenY, List listeners) { - if (tempOverlay == this) { return; } //suppress touch events if waiting to be hidden - - super.buildTouchListeners(screenX, screenY, listeners); - } - - @Override - public boolean keyDown(int keyCode) { - if (tempOverlay == this) { return false; } //suppress key events if waiting to be hidden - - if (keyCode == Keys.ESCAPE || keyCode == Keys.BACK) { - if (Forge.endKeyInput()) { return true; } - - hide(); //hide on escape by default - return true; - } - return super.keyDown(keyCode); - } -} \ No newline at end of file diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FPanel.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FPanel.java deleted file mode 100644 index 15c6a63162a..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FPanel.java +++ /dev/null @@ -1,27 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; - -public class FPanel extends FScrollPane { - private FSkinColor backColor; - - public FSkinColor getBackColor() { - return backColor; - } - public void setBackColor(FSkinColor backColor0) { - backColor = backColor0; - } - - @Override - public void drawBackground(Graphics g) { - if (backColor != null) { - g.fillRect(backColor, 0, 0, getWidth(), getHeight()); - } - } - - @Override - protected ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) { - return new ScrollBounds(visibleWidth, visibleHeight); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FProgressBar.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FProgressBar.java deleted file mode 100644 index c58bdbe38b5..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FProgressBar.java +++ /dev/null @@ -1,178 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.gui.interfaces.IProgressBar; -import forge.adventure.libgdxgui.util.Utils; -import org.apache.commons.lang3.tuple.Pair; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -public class FProgressBar extends FDisplayObject implements IProgressBar { - public static Color BACK_COLOR, FORE_COLOR, SEL_BACK_COLOR, SEL_FORE_COLOR; - private static FSkinFont MSG_FONT; - private static final float TRAIL_INTERVAL = 5000; //complete one trail round every 5 seconds - - private long startTime = 0; - private int maximum = 0, value = 0; - private String desc = ""; - private String message; - private boolean showETA = true; - private boolean showCount = true; - private boolean showProgressTrail = false; - private long progressTrailStart = -1; - - private boolean percentMode = false; - - /** */ - public FProgressBar() { - super(); - reset(); - } - - /** - * Sets description on bar. - * - * @param s0   A description to prepend before statistics. - */ - public void setDescription(final String s0) { - desc = s0; - message = s0; - } - - /** Increments bar. */ - public void setValue(int progress) { - value = progress; - setShowProgressTrail(false); //can't show progress trail if value set - - // String.format leads to StringBuilder anyway. Direct calls will be faster - StringBuilder sb = new StringBuilder(desc); - if (showCount) { - sb.append(" "); - if (percentMode) { - sb.append(100 * value / maximum).append("%"); - } - else { - sb.append(value).append(" of ").append(maximum); - } - } - - if (showETA && value > 0) { - long elapsed = new Date().getTime() - startTime; - float timePerUnit = elapsed / value; - int etaSecs = (int) ((float)(maximum - value) * timePerUnit / 1000f); - sb.append(", ETA").append(String.format("%02d:%02d:%02d", etaSecs / 3600, (etaSecs % 3600) / 60, etaSecs % 60 + 1)); - } - message = sb.toString(); - } - - /** Resets the various values required for this class. Must be called from EDT. */ - public void reset() { - value = 0; - startTime = new Date().getTime(); - setShowETA(true); - setShowCount(true); - setShowProgressTrail(false); - } - - /** @param b0   Boolean, show the ETA statistic or not */ - public void setShowETA(boolean b0) { - showETA = b0; - } - - /** @param b0   Boolean, show the count or not */ - public void setShowCount(boolean b0) { - showCount = b0; - } - - /** @param b0   Boolean, show the progress trail or not */ - public void setShowProgressTrail(boolean b0) { - if (showProgressTrail == b0) { return; } - showProgressTrail = b0; - progressTrailStart = -1; - } - - public boolean isPercentMode() { - return percentMode; - } - - public void setPercentMode(boolean percentMode0) { - percentMode = percentMode0; - } - - public int getMaximum() { - return maximum; - } - - public void setMaximum(int maximum0) { - maximum = maximum0; - } - - @Override - public void draw(Graphics g) { - float w = getWidth(); - float h = getHeight(); - - //draw background and progress - List> selTextRegions = new ArrayList<>(); - if (showProgressTrail) { - long now = new Date().getTime(); - if (progressTrailStart == -1) { - progressTrailStart = now; - } - float halfWidth = w / 2; - float trailPercent = ((now - progressTrailStart) % TRAIL_INTERVAL) / TRAIL_INTERVAL; - if (trailPercent == 0) { - g.fillGradientRect(BACK_COLOR, SEL_BACK_COLOR, false, 0, 0, w, h); - selTextRegions.add(Pair.of(halfWidth, halfWidth)); - } - else { - float trailX = trailPercent * w; - g.startClip(0, 0, w, h); - g.fillGradientRect(BACK_COLOR, SEL_BACK_COLOR, false, trailX - w, 0, w, h); - g.fillGradientRect(BACK_COLOR, SEL_BACK_COLOR, false, trailX, 0, w, h); - g.endClip(); - if (trailX >= halfWidth) { - selTextRegions.add(Pair.of(trailX - halfWidth, halfWidth)); - } - else { - selTextRegions.add(Pair.of(0f, trailX)); - float x = trailX + halfWidth; - selTextRegions.add(Pair.of(x, w - x)); - } - } - } - else { - g.fillRect(BACK_COLOR, 0, 0, w, h); - - float selWidth = Math.round(w * (float)value / (float)maximum); - if (selWidth > 0) { - g.fillRect(SEL_BACK_COLOR, 0, 0, selWidth, h); - selTextRegions.add(Pair.of(0f, selWidth)); - } - } - - //draw message - if (MSG_FONT == null) { //must wait to initialize until after FSkin initialized - MSG_FONT = FSkinFont.get(11); - } - - g.drawText(message, MSG_FONT, FORE_COLOR, 0, 0, w, h, false, Align.center, true); - - //draw text using selection fore color in needed regions over top of regular text using clipping - if (!SEL_FORE_COLOR.equals(FORE_COLOR)) { - for (Pair region : selTextRegions) { - g.startClip(region.getLeft(), 0, region.getRight(), h); - g.drawText(message, MSG_FONT, SEL_FORE_COLOR, 0, 0, w, h, false, Align.center, true); - g.endClip(); - } - } - - //draw border - g.drawRect(Utils.scale(1), Color.BLACK, 0, 0, w, h); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FRadioButton.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FRadioButton.java deleted file mode 100644 index 47499c2d065..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FRadioButton.java +++ /dev/null @@ -1,98 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FImage; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.util.Utils; - -import java.util.ArrayList; -import java.util.List; - -public class FRadioButton extends FLabel { - private static final FSkinColor INNER_CIRCLE_COLOR = FSkinColor.get(Colors.CLR_TEXT); - private static final FSkinColor OUTER_CIRCLE_COLOR = INNER_CIRCLE_COLOR.alphaColor(0.5f); - private static final float EXTRA_GAP = Utils.scale(3); - - private RadioButtonGroup group; - - public FRadioButton() { - this("", false); - } - public FRadioButton(String text0) { - this(text0, false); - } - public FRadioButton(String text0, boolean selected0) { - super(new Builder().text(text0).align(Align.left).selectable().selected(selected0)); - setIcon(new RadioButtonIcon()); - } - - public RadioButtonGroup getGroup() { - return group; - } - public void setGroup(RadioButtonGroup group0) { - if (group != null) { - group.buttons.remove(this); - } - group = group0; - if (group != null) { - group.buttons.add(this); - } - } - - @Override - protected float getExtraGapBetweenIconAndText() { - return EXTRA_GAP; - } - - @Override - public void setSelected(final boolean b0) { - if (isSelected() == b0 || !b0) { return; } //don't support unselecting radio button - - if (b0 && group != null) { //if selecting and in group, unselect all other radio buttons in group - for (FRadioButton button : group.buttons) { - if (button != this) { - button.superSetSelected(false); - } - } - } - superSetSelected(b0); - } - - private void superSetSelected(final boolean b0) { - super.setSelected(b0); - } - - private class RadioButtonIcon implements FImage { - @Override - public float getWidth() { - return FRadioButton.this.getHeight(); - } - - @Override - public float getHeight() { - return FRadioButton.this.getHeight(); - } - - @Override - public void draw(Graphics g, float x, float y, float w, float h) { - float radius = h / 3; - x += w - radius; - y += h / 2; - g.drawCircle(Utils.scale(1), OUTER_CIRCLE_COLOR, x, y, radius); - if (isSelected()) { - g.fillCircle(INNER_CIRCLE_COLOR, x, y, radius / 2); - } - } - } - - @Override - public void draw(Graphics g) { - drawContent(g, getWidth(), getHeight(), false); - } - - public static class RadioButtonGroup { - private final List buttons = new ArrayList<>(); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FScrollPane.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FScrollPane.java deleted file mode 100644 index b37d92dbe83..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FScrollPane.java +++ /dev/null @@ -1,323 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.badlogic.gdx.math.Vector2; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.animation.ForgeAnimation; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.localinstance.properties.ForgePreferences; -import forge.model.FModel; -import forge.adventure.libgdxgui.util.PhysicsObject; -import forge.adventure.libgdxgui.util.Utils; - -import java.util.List; - -public abstract class FScrollPane extends FContainer { - private static final float FLING_DECEL = 750f; - private static final FSkinColor INDICATOR_COLOR = FSkinColor.get(FSkinColor.Colors.CLR_TEXT).alphaColor(0.7f); - private static final float INDICATOR_SIZE = Utils.scale(5); - private static final float INDICATOR_MARGIN = Utils.scale(3); - - private float scrollLeft, scrollTop; - private ScrollBounds scrollBounds; - - public FScrollPane() { - scrollBounds = new ScrollBounds(); - } - - public float getScrollLeft() { - return scrollLeft; - } - - public void setScrollLeft(float scrollLeft0) { - setScrollPositions(scrollLeft0, scrollTop); - } - - public float getScrollTop() { - return scrollTop; - } - - public void setScrollTop(float scrollTop0) { - setScrollPositions(scrollLeft, scrollTop0); - } - - public float getScrollWidth() { - return scrollBounds.width; - } - - public float getScrollHeight() { - return scrollBounds.height; - } - - public float getMaxScrollLeft() { - return getScrollWidth() - getWidth(); - } - - public float getMaxScrollTop() { - return getScrollHeight() - getHeight(); - } - - public void scrollToLeft() { - setScrollPositions(0, scrollTop); - } - - public void scrollToRight() { - setScrollPositions(getMaxScrollLeft(), scrollTop); - } - - public void scrollToTop() { - setScrollPositions(scrollLeft, 0); - } - - public void scrollToBottom() { - setScrollPositions(scrollLeft, getMaxScrollTop()); - } - - public void scrollIntoView(FDisplayObject child) { - scrollIntoView(child, 0); - } - public void scrollIntoView(FDisplayObject child, float margin) { - Vector2 childPos = getChildRelativePosition(child); - if (childPos == null) { return; } //do nothing if not a valid child - - scrollIntoView(childPos.x, childPos.y, child.getWidth(), child.getHeight(), margin); - } - public void scrollIntoView(float childLeft, float childTop, float childWidth, float childHeight, float margin) { - float childRight = childLeft + childWidth; - float childBottom = childTop + childHeight; - - float dx = 0; - if (childLeft < margin) { - dx = childLeft - margin; - } - else if (childRight > getWidth() - margin) { - dx = childRight - getWidth() + margin; - } - float dy = 0; - if (childTop < margin) { - dy = childTop - margin; - } - else if (childBottom > getHeight() - margin) { - dy = childBottom - getHeight() + margin; - } - - if (dx == 0 && dy == 0) { return; } - - setScrollPositions(scrollLeft + dx, scrollTop + dy); - } - - private boolean setScrollPositions(float scrollLeft0, float scrollTop0) { - if (scrollLeft0 < 0) { - scrollLeft0 = 0; - } - else { - float maxScrollLeft = getMaxScrollLeft(); - if (scrollLeft0 > maxScrollLeft) { - scrollLeft0 = maxScrollLeft; - } - } - if (scrollTop0 < 0) { - scrollTop0 = 0; - } - else { - float maxScrollTop = getMaxScrollTop(); - if (scrollTop0 > maxScrollTop) { - scrollTop0 = maxScrollTop; - } - } - float dx = scrollLeft - scrollLeft0; - float dy = scrollTop - scrollTop0; - if (dx == 0 && dy == 0) { return false; } //do nothing if scroll didn't change - - scrollLeft = scrollLeft0; - scrollTop = scrollTop0; - - //shift position of all children based on change in scroll positions - for (FDisplayObject obj : getChildren()) { - obj.setPosition(obj.getLeft() + dx, obj.getTop() + dy); - } - return true; - } - - @Override - protected void doLayout(float width, float height) { - scrollBounds = layoutAndGetScrollBounds(width, height); - scrollBounds.increaseWidthTo(width); //ensure scroll bounds extends at least to visible bounds - scrollBounds.increaseHeightTo(height); - - //attempt to restore current scroll positions after reseting them in order to update positions of newly laid out stuff - float oldScrollLeft = scrollLeft; - float oldScrollTop = scrollTop; - scrollLeft = 0; - scrollTop = 0; - setScrollPositionsAfterLayout(oldScrollLeft, oldScrollTop); - } - - @Override - protected void drawOverlay(Graphics g) { - try { - boolean isFieldZoneView = toString().contains("VField")||toString().contains("VZoneDisplay"); - //if ForgePreferences.FPref.UI_ENABLE_MATCH_SCROLL_INDICATOR is missing this will return NPE and could cause lockup on Startup - if (!FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_ENABLE_MATCH_SCROLL_INDICATOR)) - return; - if (!isFieldZoneView) - return; - //TODO: Consider other ways to indicate scroll potential that fade in and out based on input - //draw triangles indicating scroll potential - if (scrollLeft > 0) { - float x = INDICATOR_MARGIN; - float y = getHeight() / 2; - g.fillTriangle(INDICATOR_COLOR, x, y, x + INDICATOR_SIZE, y - INDICATOR_SIZE, x + INDICATOR_SIZE, y + INDICATOR_SIZE); - } - if (scrollLeft < getMaxScrollLeft()) { - float x = getWidth() - INDICATOR_MARGIN; - float y = getHeight() / 2; - g.fillTriangle(INDICATOR_COLOR, x, y, x - INDICATOR_SIZE, y - INDICATOR_SIZE, x - INDICATOR_SIZE, y + INDICATOR_SIZE); - } - if (scrollTop > 0) { - float x = getWidth() / 2; - float y = INDICATOR_MARGIN; - g.fillTriangle(INDICATOR_COLOR, x, y, x - INDICATOR_SIZE, y + INDICATOR_SIZE, x + INDICATOR_SIZE, y + INDICATOR_SIZE); - } - if (scrollTop < getMaxScrollTop()) { - float x = getWidth() / 2; - float y = getHeight() - INDICATOR_MARGIN; - g.fillTriangle(INDICATOR_COLOR, x, y, x - INDICATOR_SIZE, y - INDICATOR_SIZE, x + INDICATOR_SIZE, y - INDICATOR_SIZE); - } - } catch (Exception e) {} - } - - //allow overriding to adjust what scroll positions are restored after layout - protected void setScrollPositionsAfterLayout(float scrollLeft0, float scrollTop0) { - setScrollPositions(scrollLeft0, scrollTop0); - } - - protected abstract ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight); - - public static class ScrollBounds { - private float width, height; - - protected ScrollBounds() { - this(0, 0); - } - public ScrollBounds(float width0, float height0) { - width = width0; - height = height0; - } - - public float getWidth() { - return width; - } - - public float getHeight() { - return height; - } - - //increase width the given value if it's higher - public void increaseWidthTo(float width0) { - if (width0 > width) { - width = width0; - } - } - - //increase height to the given value if it's higher - public void increaseHeightTo(float height0) { - if (height0 > height) { - height = height0; - } - } - } - - private FlingAnimation activeFlingAnimation; - - private class FlingAnimation extends ForgeAnimation { - private final PhysicsObject physicsObj; - - private FlingAnimation(float velocityX, float velocityY) { - physicsObj = new PhysicsObject(new Vector2(scrollLeft, scrollTop), new Vector2(velocityX, velocityY)); - physicsObj.setDecel(FLING_DECEL, FLING_DECEL); - } - - @Override - protected boolean advance(float dt) { - if (physicsObj.isMoving()) { //avoid storing last fling stop time if scroll manually stopped - physicsObj.advance(dt); - Vector2 pos = physicsObj.getPosition(); - return setScrollPositions(pos.x, pos.y) && physicsObj.isMoving(); - } - - //end fling animation if can't scroll anymore or physics object is no longer moving - return false; - } - - @Override - protected void onEnd(boolean endingAll) { - activeFlingAnimation = null; - } - } - - @Override - public boolean fling(float velocityX, float velocityY) { - if (Math.abs(velocityY) > Math.abs(velocityX)) { - if (getMaxScrollTop() == 0) { - return false; //if fling is more vertical and can't scroll vertically, don't scroll at all - } - } - else if (getMaxScrollLeft() == 0) { - return false; //if fling is more horizontal and can't scroll horizontally, don't scroll at all - } - - velocityX = -velocityX; //reverse velocities to account for scroll moving in opposite direction - velocityY = -velocityY; - - if (activeFlingAnimation == null) { - activeFlingAnimation = new FlingAnimation(velocityX, velocityY); - activeFlingAnimation.start(); - } - else { //update existing animation with new velocity if needed - activeFlingAnimation.physicsObj.getVelocity().set(velocityX, velocityY); - activeFlingAnimation.physicsObj.setDecel(FLING_DECEL, FLING_DECEL); - } - return true; - } - - @Override - public void buildTouchListeners(float screenX, float screenY, List listeners) { - //if fling animation active, stop it and prevent child controls handling touch events before next touch down unless already moving really slow - if (activeFlingAnimation != null) { - boolean suppressEvent = activeFlingAnimation.physicsObj.getVelocity().len() > Utils.AVG_FINGER_HEIGHT; - activeFlingAnimation.physicsObj.stop(); - if (suppressEvent) { - listeners.add(this); - return; - } - } - super.buildTouchListeners(screenX, screenY, listeners); - } - - @Override - public boolean pan(float x, float y, float deltaX, float deltaY, boolean moreVertical) { - if (getMaxScrollTop() <= 0 && (moreVertical || y < 0 || y >= getHeight() || Math.abs(deltaY) > Math.abs(deltaX))) { - //if can't scroll vertically, don't scroll at all if pan is more vertical - //or current position is above or below this scroll pane - return false; - } - if (getMaxScrollLeft() <= 0 && (!moreVertical || x < 0 || x >= getWidth() || Math.abs(deltaX) > Math.abs(deltaY))) { - //if can't scroll horizontally, don't scroll at all if pan is more horizontal - //or current position is left or right of this scroll pane - return false; - } - setScrollPositions(scrollLeft - deltaX, scrollTop - deltaY); - return true; - } - - protected void startClip(Graphics g) { - g.startClip(0, 0, getWidth(), getHeight()); - } - - @Override - public void draw(Graphics g) { - startClip(g); - super.draw(g); - g.endClip(); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FSpinner.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FSpinner.java deleted file mode 100644 index 8363e1f5184..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FSpinner.java +++ /dev/null @@ -1,61 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import forge.adventure.libgdxgui.toolbox.FEvent.FEventType; -import forge.util.Callback; -import forge.util.Localizer; - - -public class FSpinner extends FTextField { - private int value; - private final int minValue; - private final int maxValue; - - public FSpinner(int minValue0, int maxValue0) { - this(minValue0, maxValue0, minValue0); - } - - public FSpinner(int minValue0, int maxValue0, int initialValue) { - minValue = minValue0; - maxValue = maxValue0; - value = minValue - 1; //ensure value changes so text updated - setValue(initialValue); - } - - public int getValue() { - return value; - } - public void setValue(int value0) { - if (value0 < minValue) { - value0 = minValue; - } - else if (value0 > maxValue) { - value0 = maxValue; - } - if (value == value0) { return; } - value = value0; - setText(String.valueOf(value)); - } - - @Override - public boolean tap(float x, float y, int count) { - GuiChoose.getInteger(Localizer.getInstance().getMessage("lblSelectANumber"), minValue, maxValue, new Callback() { - @Override - public void run(Integer result) { - if (result != null && result != value) { - int oldValue = value; - setValue(result); - if (getChangedHandler() != null) { - //handle change event if value changed from input - getChangedHandler().handleEvent(new FEvent(FSpinner.this, FEventType.CHANGE, oldValue)); - } - } - } - }); - return true; - } - - @Override - public boolean startEdit() { - return false; //don't allow editing text - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FTextArea.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FTextArea.java deleted file mode 100644 index 8ddeb646ef7..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FTextArea.java +++ /dev/null @@ -1,83 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.TextRenderer; - -public class FTextArea extends FScrollPane { - private String text; - private FSkinFont font; - private int alignment; - private final Vector2 insets; - private FSkinColor textColor; - private final TextRenderer renderer; - private boolean centerVertically; - - public FTextArea(boolean parseReminderText0) { - this(parseReminderText0, ""); - } - public FTextArea(boolean parseReminderText0, String text0) { - text = text0; - font = FSkinFont.get(14); - alignment = Align.left; - insets = new Vector2(1, 1); //prevent text getting cut off by clip - textColor = FLabel.DEFAULT_TEXT_COLOR; - renderer = new TextRenderer(parseReminderText0); - } - - public String getText() { - return text; - } - public void setText(String text0) { - text = text0; - revalidate(); - } - - public int getAlignment() { - return alignment; - } - public void setAlignment(int alignment0) { - alignment = alignment0; - } - - public boolean getCenterVertically() { - return centerVertically; - } - public void setCenterVertically(boolean centerVertically0) { - centerVertically = centerVertically0; - } - - public FSkinFont getFont() { - return font; - } - public void setFont(FSkinFont font0) { - font = font0; - revalidate(); - } - - public FSkinColor getTextColor() { - return textColor; - } - public void setTextColor(FSkinColor textColor0) { - textColor = textColor0; - } - - public float getPreferredHeight(float width) { - return renderer.getWrappedBounds(text, font, width - 2 * insets.x).height - + font.getLineHeight() - font.getCapHeight() //need to account for difference in line and cap height - + 2 * insets.y; - } - - @Override - protected ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) { - return new ScrollBounds(visibleWidth, getPreferredHeight(visibleWidth)); - } - - @Override - protected void drawBackground(Graphics g) { - renderer.drawText(g, text, font, textColor, insets.x - getScrollLeft(), insets.y - getScrollTop(), getScrollWidth() - 2 * insets.x, getScrollHeight() - 2 * insets.y, 0, getHeight(), true, alignment, centerVertically); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FTextField.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FTextField.java deleted file mode 100644 index 17010890be5..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FTextField.java +++ /dev/null @@ -1,459 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.badlogic.gdx.Input.Keys; -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Forge.KeyInputAdapter; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.gui.interfaces.ITextField; -import forge.adventure.libgdxgui.menu.FMenuItem; -import forge.adventure.libgdxgui.menu.FPopupMenu; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventType; -import forge.util.Localizer; -import forge.adventure.libgdxgui.util.TextBounds; -import forge.adventure.libgdxgui.util.Utils; - -public class FTextField extends FDisplayObject implements ITextField { - private static final FSkinFont DEFAULT_FONT = FSkinFont.get(14); - private static final float BORDER_THICKNESS = Utils.scale(1); - public static final float PADDING = Utils.scale(5); - protected static final FSkinColor FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT); - protected static final FSkinColor BACK_COLOR = FSkinColor.get(Colors.CLR_THEME2); - protected static final FSkinColor GHOST_TEXT_COLOR = FORE_COLOR.alphaColor(0.7f); - protected static final FSkinColor SEL_COLOR = FSkinColor.get(Colors.CLR_ACTIVE); - private FEventHandler changedHandler; - - public static float getDefaultHeight() { - return getDefaultHeight(DEFAULT_FONT); - } - public static float getDefaultHeight(FSkinFont font0) { - return font0.getCapHeight() * 3; - } - - private String text, ghostText, textBeforeKeyInput; - protected FSkinFont font, renderedFont; - private int alignment; - private int selStart, selLength; - private boolean isEditing, readOnly; - - private final FPopupMenu contextMenu = new FPopupMenu() { - @Override - protected void buildMenu() { - if (text.length() > 0) { - if (!readOnly) { - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblCut"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - Forge.getClipboard().setContents(getSelectedText()); - textBeforeKeyInput = text; - insertText(""); - endEdit(); - } - })); - } - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblCopy"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - Forge.getClipboard().setContents(getSelectedText()); - } - })); - } - if (!readOnly) { - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblPaste"), new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - textBeforeKeyInput = text; - insertText(Forge.getClipboard().getContents()); - endEdit(); - } - })); - } - } - }; - - public FTextField() { - this(""); - } - public FTextField(String text0) { - text = text0; - ghostText = ""; - setFont(DEFAULT_FONT); - alignment = Align.left; - } - - public String getText() { - return text; - } - public void setText(String text0) { - if (text0 == null) { - text0 = ""; //don't allow setting null - } - text = text0; - selStart = 0; - selLength = 0; - } - - protected void insertText(String text0) { - int insertLength = text0.length(); - if (selStart > 0) { - text0 = text.substring(0, selStart) + text0; - } - int selEnd = selStart + selLength; - if (selEnd < text.length()) { - text0 += text.substring(selEnd); - } - text = text0; - selStart += insertLength; //put cursor after inserted text - selLength = 0; - } - - public String getSelectedText() { - if (selLength > 0) { - return text.substring(selStart, selLength); - } - return ""; - } - - public String getGhostText() { - return ghostText; - } - public void setGhostText(String ghostText0) { - if (ghostText0 == null) { - ghostText0 = ""; //don't allow setting null - } - ghostText = ghostText0; - } - - public boolean isEmpty() { - return text.isEmpty(); - } - - public int getAlignment() { - return alignment; - } - public void setAlignment(int alignment0) { - alignment = alignment0; - } - - public FSkinFont getFont() { - return font; - } - public void setFont(FSkinFont font0) { - font = font0; - renderedFont = font0; - setHeight(getDefaultHeight(font)); - } - - public boolean isReadOnly() { - return readOnly; - } - public void setReadOnly(boolean readOnly0) { - readOnly = readOnly0; - } - - public FEventHandler getChangedHandler() { - return changedHandler; - } - public void setChangedHandler(FEvent.FEventHandler changedHandler0) { - changedHandler = changedHandler0; - } - - public float getAutoSizeWidth() { - return getLeftPadding() + font.getBounds(text).width + getRightPadding(); - } - - private int getCharIndexAtPoint(float x, float y) { - float charLeft = getTextLeft(); - if (x < charLeft) { - return 0; - } - if (x >= charLeft + renderedFont.getBounds(text).width) { - return text.length(); - } - - //find closest character of press - float charWidth; - for (int i = 0; i < text.length(); i++) { - charWidth = renderedFont.getBounds(text.substring(i, i + 1)).width; - if (x < charLeft + charWidth / 2) { - return i; - } - charLeft += charWidth; - } - return text.length(); - } - - @Override - public boolean press(float x, float y) { - placeTextCursor(x, y); - return false; - } - - public boolean pan(float x, float y, float deltaX, float deltaY, boolean moreVertical) { - placeTextCursor(x, y); - return true; - } - - private void placeTextCursor(float x, float y) { - if (isEditing) { - selStart = getCharIndexAtPoint(x, y); - selLength = 0; - } - } - - @Override - public boolean longPress(float x, float y) { - if (isEditing) { - endEdit(); //end previous edit first - } - selStart = 0; - selLength = text.length(); //select text while context menu open - contextMenu.show(this, x, y); - return true; - } - - @Override - public boolean tap(float x, float y, int count) { - return startEdit(); - } - - @Override - public boolean keyDown(int keyCode) { - return startEdit(); //start edit if keyDown received while key input not active - } - - public boolean startEdit() { - if (readOnly) { return false; } - if (isEditing) { return true; } //do nothing if already editing - - selStart = 0; //select all before starting input - selLength = text.length(); - textBeforeKeyInput = text; //backup text before input to detect changes - - Forge.startKeyInput(new KeyInputAdapter() { - @Override - public FDisplayObject getOwner() { - return FTextField.this; - } - - @Override - public boolean allowTouchInput() { - return true; - } - - @Override - public boolean keyTyped(char ch) { - insertText(String.valueOf(ch)); - return true; - } - - @Override - public boolean keyDown(int keyCode) { - switch (keyCode) { - case Keys.TAB: - case Keys.ENTER: //end key input on Tab or Enter - Forge.endKeyInput(); - return true; - case Keys.ESCAPE: - setText(textBeforeKeyInput); //cancel edit on Escape - Forge.endKeyInput(); - return true; - case Keys.BACKSPACE: //also handles Delete since those are processed the same by libgdx - if (text.length() > 0) { - if (selLength == 0) { //delete previous or next character if selection empty - if (selStart > 0) { - selStart--; - } - selLength = 1; - } - insertText(""); - } - return true; - case Keys.LEFT: - if (selLength == 0) { - if (selStart > 0) { - selStart--; - } - } - else { - selLength = 0; - } - return true; - case Keys.RIGHT: - if (selLength == 0) { - if (selStart < text.length()) { - selStart++; - } - } - else { - selStart += selLength; - selLength = 0; - } - return true; - case Keys.A: //select all on Ctrl+A - if (KeyInputAdapter.isCtrlKeyDown()) { - selStart = 0; - selLength = text.length(); - return true; - } - break; - case Keys.C: //copy on Ctrl+C - if (KeyInputAdapter.isCtrlKeyDown()) { - if (selLength > 0) { - Forge.getClipboard().setContents(getSelectedText()); - } - return true; - } - break; - case Keys.V: //paste on Ctrl+V - if (KeyInputAdapter.isCtrlKeyDown()) { - insertText(Forge.getClipboard().getContents()); - return true; - } - break; - case Keys.X: //cut on Ctrl+X - if (KeyInputAdapter.isCtrlKeyDown()) { - if (selLength > 0) { - Forge.getClipboard().setContents(getSelectedText()); - insertText(""); - } - return true; - } - break; - case Keys.Z: //cancel edit on Ctrl+Z - if (KeyInputAdapter.isCtrlKeyDown()) { - setText(textBeforeKeyInput); - Forge.endKeyInput(); - return true; - } - break; - } - return false; - } - - @Override - public void onInputEnd() { - endEdit(); - } - }); - isEditing = true; - return true; - } - - protected boolean validate() { - return true; - } - - protected void endEdit() { - text = text.trim(); //trim text after editing - if (!text.equals(textBeforeKeyInput)) { - if (validate()) { - if (changedHandler != null) { - //handle change event if text changed during input - changedHandler.handleEvent(new FEvent(FTextField.this, FEventType.CHANGE, textBeforeKeyInput)); - } - } - else { //restore previous text if new text isn't valid - setText(textBeforeKeyInput); - } - } - isEditing = false; - selStart = 0; - selLength = 0; - textBeforeKeyInput = null; - } - - @Override - public void draw(Graphics g) { - float w = getWidth(); - float h = getHeight(); - boolean drawBackground = !readOnly; //don't draw background or border if read-only - - if (drawBackground) { - g.fillRect(BACK_COLOR, 0, 0, w, h); - } - - //determine actual rendered font so selection logic is accurate - renderedFont = font; - float availableTextWidth = w - getLeftPadding() - getRightPadding(); - TextBounds textBounds = renderedFont.getMultiLineBounds(text); - while (textBounds.width > availableTextWidth || textBounds.height > h) { - if (renderedFont.canShrink()) { //shrink font to fit if possible - renderedFont = renderedFont.shrink(); - availableTextWidth = w - getLeftPadding() - getRightPadding(); - textBounds = renderedFont.getMultiLineBounds(text); - } - else { - break; - } - } - - //draw selection if key input is active or context menu is shown - if (isEditing || contextMenu.isVisible()) { - float selLeft = getTextLeft(); - if (selStart > 0) { - selLeft += renderedFont.getBounds(text.substring(0, selStart)).width; - } - float selTop = PADDING; - float selHeight = h - 2 * PADDING; - if (selLength == 0) { - drawText(g, w, h); //draw text behind cursor - g.drawLine(BORDER_THICKNESS, FORE_COLOR, selLeft, selTop, selLeft, selTop + selHeight); - } - else if (selStart == 0 && selLength == text.length()) { - float selWidth = renderedFont.getBounds(text.substring(selStart, selStart + selLength)).width; - g.fillRect(SEL_COLOR, selLeft, selTop, selWidth, selHeight); - drawText(g, w, h); //draw text in front of selection background - } - } - else { //otherwise just draw text - drawText(g, w, h); - } - - if (drawBackground) { - g.drawRect(BORDER_THICKNESS, FORE_COLOR, BORDER_THICKNESS, BORDER_THICKNESS, w - 2 * BORDER_THICKNESS, h - 2 * BORDER_THICKNESS); //allow smooth border to fully display within bounds - } - } - - private void drawText(Graphics g, float w, float h) { - float diff = h - renderedFont.getCapHeight(); - if (diff > 0 && Math.round(diff) % 2 == 1) { - h++; //if odd difference between height and font height, increment height so text favors displaying closer to bottom - } - if (!text.isEmpty()) { - g.drawText(text, renderedFont, FORE_COLOR, getLeftPadding(), 0, w - getLeftPadding() - getRightPadding(), h, false, alignment, true); - } - else if (!ghostText.isEmpty()) { - g.drawText(ghostText, renderedFont, GHOST_TEXT_COLOR, getLeftPadding(), 0, w - getLeftPadding() - getRightPadding(), h, false, alignment, true); - } - } - - protected float getTextLeft() { - switch (alignment) { - case Align.left: - default: - return getLeftPadding(); - case Align.center: - return getLeftPadding() + (getWidth() - getRightPadding() - getLeftPadding() - renderedFont.getBounds(text).width) / 2; - case Align.right: - return getWidth() - getRightPadding() - renderedFont.getBounds(text).width; - } - } - - protected float getLeftPadding() { - return PADDING; - } - - protected float getRightPadding() { - return PADDING; - } - - @Override - public boolean requestFocusInWindow() { - return false; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FTimer.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FTimer.java deleted file mode 100644 index bc26d88cd16..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FTimer.java +++ /dev/null @@ -1,33 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import forge.adventure.libgdxgui.animation.ForgeAnimation; - -public abstract class FTimer extends ForgeAnimation { - private final float interval; - private float elapsed; - - public FTimer(float interval0) { - interval = interval0; - } - - @Override - protected boolean advance(float dt) { - elapsed += dt; - while (elapsed >= interval) { - tick(); - elapsed -= interval; - } - return true; - } - - public void restart() { - elapsed = 0; //assume this only called if already started - } - - protected abstract void tick(); - - @Override - protected void onEnd(boolean endingAll) { - elapsed = 0; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FToggleSwitch.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FToggleSwitch.java deleted file mode 100644 index b00824bae52..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/FToggleSwitch.java +++ /dev/null @@ -1,171 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.badlogic.gdx.utils.Align; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinColor; -import forge.adventure.libgdxgui.assets.FSkinColor.Colors; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventType; -import forge.adventure.libgdxgui.util.Utils; - -public class FToggleSwitch extends FDisplayObject { - private static final FSkinColor ACTIVE_COLOR = FSkinColor.get(Colors.CLR_ACTIVE); - private static final FSkinColor PRESSED_COLOR = ACTIVE_COLOR.stepColor(-30); - private static final FSkinColor INACTIVE_COLOR = FSkinColor.get(Colors.CLR_INACTIVE); - private static final FSkinColor FORE_COLOR = FSkinColor.get(Colors.CLR_TEXT); - private static final float BORDER_THICKNESS = Utils.scale(1); - private static final float INSETS = Utils.scale(2); - private static final float PADDING = Utils.scale(3); - - private FSkinFont font; - private String offText, onText; - private boolean toggled, pressed; - private FEventHandler changedHandler; - - public FToggleSwitch() { - this("Off", "On"); - } - - public FToggleSwitch(final String offText0, final String onText0) { - offText = offText0; - onText = onText0; - font = FSkinFont.get(14); - } - - public String getOffText() { - return offText; - } - public void setOffText(String offText0) { - offText = offText0; - } - public String getOnText() { - return onText; - } - public void setOnText(String onText0) { - onText = onText0; - } - - public void setFontSize(int fontSize0) { - font = FSkinFont.get(fontSize0); - } - - public boolean isToggled() { - return toggled; - } - public void setToggled(boolean b0) { - setToggled(b0, false); - } - private void setToggled(boolean b0, boolean raiseChangedEvent) { - if (toggled == b0) { return; } - toggled = b0; - - if (raiseChangedEvent && changedHandler != null) { - changedHandler.handleEvent(new FEvent(this, FEventType.CHANGE, b0)); - } - } - - public FEventHandler getChangedHandler() { - return changedHandler; - } - public void setChangedHandler(FEventHandler changedHandler0) { - changedHandler = changedHandler0; - } - - public float getAutoSizeWidth(float height) { - float width; - float onTextWidth = font.getBounds(onText).width; - float offTextWidth = font.getBounds(offText).width; - if (onTextWidth > offTextWidth) { - width = onTextWidth; - } - else { - width = offTextWidth; - } - width += 2 * (PADDING + INSETS + 1); - width += height - PADDING; //leave room for switch to move - return width; - } - - @Override - public final boolean press(float x, float y) { - pressed = true; - return true; - } - - @Override - public final boolean release(float x, float y) { - pressed = false; - return true; - } - - @Override - public final boolean tap(float x, float y, int count) { - setToggled(!toggled, true); - return true; - } - - //support dragging finger left or right to toggle on/off - @Override - public final boolean pan(float x, float y, float deltaX, float deltaY, boolean moreVertical) { - if (contains(getLeft() + x, getTop() + y)) { - if (x < getHeight()) { - setToggled(false, true); - return true; - } - if (x > getWidth() - getHeight()) { - setToggled(true, true); - return true; - } - pressed = true; - } - else { - pressed = false; - } - return false; - } - - @Override - public final boolean panStop(float x, float y) { - if (pressed) { - pressed = false; - return true; - } - return false; - } - - @Override - public boolean fling(float velocityX, float velocityY) { - return Math.abs(velocityX) > Math.abs(velocityY); //handle fling if more horizontal than vertical - } - - @Override - public void draw(Graphics g) { - float x = BORDER_THICKNESS; //leave a pixel so border displays in full - float y = BORDER_THICKNESS; - float w = getWidth() - 2 * x; - float h = getHeight() - 2 * y; - - g.fillRect(INACTIVE_COLOR, x, y, w, h); - g.drawRect(BORDER_THICKNESS, FORE_COLOR, x, y, w, h); - - final String text; - float switchWidth = w - h + PADDING; - if (toggled) { - x = w - switchWidth + 1; - text = onText; - } - else { - text = offText; - } - x += INSETS; - y += INSETS; - h -= 2 * INSETS; - w = switchWidth - 2 * INSETS; - g.fillRect(pressed ? PRESSED_COLOR : ACTIVE_COLOR, x, y, w, h); - - x += PADDING; - w -= 2 * PADDING; - g.drawText(text, font, FORE_COLOR, x, y, w, h, false, Align.center, true); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/GuiChoose.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/GuiChoose.java deleted file mode 100644 index e9281307123..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/GuiChoose.java +++ /dev/null @@ -1,340 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.google.common.base.Function; -import com.google.common.collect.Iterables; -import forge.game.card.CardView; -import forge.util.Callback; -import forge.util.Localizer; -import org.apache.commons.lang3.StringUtils; - -import java.util.*; - -public class GuiChoose { - - /** - * Convenience for getChoices(message, 0, 1, choices). - * - * @param - * is automatically inferred. - * @param message - * a {@link String} object. - * @param choices - * a T object. - * @return null if choices is missing, empty, or if the users' choices are - * empty; otherwise, returns the first item in the List returned by - * getChoices. - * @see #getChoices - */ - public static void oneOrNone(final String message, final T[] choices, final Callback callback) { - if ((choices == null) || (choices.length == 0)) { - callback.run(null); - return; - } - getChoices(message, 0, 1, choices, new Callback>() { - @Override - public void run(final List result) { - callback.run(result.isEmpty() ? null : result.get(0)); - } - }); - } - - public static void oneOrNone(final String message, final Collection choices, final Callback callback) { - if ((choices == null) || choices.isEmpty()) { - callback.run(null); - return; - } - getChoices(message, 0, 1, choices, new Callback>() { - @Override - public void run(final List result) { - callback.run(result.isEmpty() ? null : result.get(0)); - } - }); - } // getChoiceOptional(String,T...) - - // returned Object will never be null - /** - *

- * getChoice. - *

- * - * @param - * a T object. - * @param message - * a {@link String} object. - * @param choices - * a T object. - * @return a T object. - */ - public static void one(final String message, final T[] choices, final Callback callback) { - if (choices == null || choices.length == 0) { - callback.run(null); - return; - } - if (choices.length == 1) { - callback.run(choices[0]); - return; - } - - getChoices(message, 1, 1, choices, new Callback>() { - @Override - public void run(final List result) { - assert result.size() == 1; - callback.run(result.get(0)); - } - }); - } - - public static void one(final String message, final Collection choices, final Callback callback) { - if (choices == null || choices.isEmpty()) { - callback.run(null); - return; - } - if (choices.size() == 1) { - callback.run(Iterables.getFirst(choices, null)); - return; - } - - getChoices(message, 1, 1, choices, new Callback>() { - @Override - public void run(final List result) { - assert result.size() == 1; - callback.run(result.get(0)); - } - }); - } - - public static void noneOrMany(final String message, final Collection choices, final Callback> callback) { - getChoices(message, 0, choices.size(), choices, null, null, callback); - } - - // Nothing to choose here. Code uses this to just reveal one or more items - public static void reveal(final String message, final T item) { - List items = new ArrayList<>(); - items.add(item); - reveal(message, items); - } - public static void reveal(final String message, final T[] items) { - getChoices(message, -1, -1, items, null); - } - public static void reveal(final String message, final Collection items) { - getChoices(message, -1, -1, items, null); - } - - // Get Integer in range - public static void getInteger(final String message, final Callback callback) { - getInteger(message, 0, Integer.MAX_VALUE, callback); - } - public static void getInteger(final String message, int min, final Callback callback) { - getInteger(message, min, Integer.MAX_VALUE, callback); - } - public static void getInteger(final String message, int min, int max, final Callback callback) { - if (max <= min) { //just return min if max <= min - callback.run(min); - return; - } - - //force cutting off after 100 numbers at most - if (max == Integer.MAX_VALUE) { - getInteger(message, min, max, min + 99, callback); - return; - } - int count = max - min + 1; - if (count > 100) { - getInteger(message, min, max, min + 99, callback); - return; - } - - final Integer[] choices = new Integer[count]; - for (int i = 0; i < count; i++) { - choices[i] = Integer.valueOf(i + min); - } - oneOrNone(message, choices, callback); - } - public static void getInteger(final String message, final int min, final int max, final int cutoff, final Callback callback) { - if (max <= min || cutoff < min) { //just return min if max <= min or cutoff < min - callback.run(min); - return; - } - - if (cutoff >= max) { //fallback to regular integer prompt if cutoff at or after max - getInteger(message, min, max, callback); - return; - } - - List choices = new ArrayList<>(); - for (int i = min; i <= cutoff; i++) { - choices.add(Integer.valueOf(i)); - } - choices.add(Localizer.getInstance().getMessage("lblOther") + "..."); - - oneOrNone(message, choices, new Callback() { - @Override - public void run(Object choice) { - if (choice instanceof Integer || choice == null) { - callback.run((Integer)choice); - return; - } - - //if Other option picked, prompt for number input - String prompt = "Enter a number"; - if (min != Integer.MIN_VALUE) { - if (max != Integer.MAX_VALUE) { - prompt += " between " + min + " and " + max; - } - else { - prompt += " greater than or equal to " + min; - } - } - else if (max != Integer.MAX_VALUE) { - prompt += " less than or equal to " + max; - } - prompt += ":"; - getNumberInput(prompt, message, min, max, callback); - } - }); - } - - private static void getNumberInput(final String prompt, final String message, final int min, final int max, final Callback callback) { - FOptionPane.showInputDialog(prompt, message, new Callback() { - @Override - public void run(String result) { - if (result == null) { //that is 'cancel' - callback.run(null); - return; - } - if (StringUtils.isNumeric(result)) { - Integer val = Integer.valueOf(result); - if (val >= min && val <= max) { - callback.run(val); - return; - } - } - - //re-prompt if invalid input - getNumberInput(prompt, message, min, max, callback); - } - }); - } - - // returned Object will never be null - public static void getChoices(final String message, final int min, final int max, final T[] choices, final Callback> callback) { - getChoices(message, min, max, Arrays.asList(choices), null, null, callback); - } - - public static void getChoices(final String message, final int min, final int max, final Collection choices, final Callback> callback) { - getChoices(message, min, max, choices, null, null, callback); - } - - public static void getChoices(final String message, final int min, final int max, final Collection choices, final T selected, final Function display, final Callback> callback) { - if (choices == null || choices.isEmpty()) { - if (min == 0) { - callback.run(new ArrayList<>()); - return; - } - throw new RuntimeException("choice required from empty list"); - } - - ListChooser c = new ListChooser<>(message, min, max, choices, display, callback); - c.show(selected, false); - } - - public static void many(final String title, final String topCaption, int cnt, final List sourceChoices, CardView referenceCard, final Callback> callback) { - order(title, topCaption, cnt, cnt, sourceChoices, null, referenceCard, callback); - } - - public static void many(final String title, final String topCaption, int min, int max, final List sourceChoices, CardView referenceCard, final Callback> callback) { - int m1 = max >= 0 ? sourceChoices.size() - max : -1; - int m2 = min >= 0 ? sourceChoices.size() - min : -1; - order(title, topCaption, m1, m2, sourceChoices, null, referenceCard, callback); - } - - public static void order(final String title, final String top, final List sourceChoices, CardView referenceCard, final Callback> callback) { - order(title, top, 0, 0, sourceChoices, null, referenceCard, callback); - } - - public static void order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax, - final List sourceChoices, final List destChoices, final CardView referenceCard, final Callback> callback) { - // An input box for handling the order of choices. - DualListBox dual = new DualListBox<>(title, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices, callback); - dual.setSecondColumnLabelText(top); - dual.show(); - } - - // If comparer is NULL, T has to be comparable. Otherwise you'll get an exception from inside the Arrays.sort() routine - public static void sortedOneOrNone(final String message, final T[] choices, Comparator comparer, final Callback callback) { - if ((choices == null) || (choices.length == 0)) { - callback.run(null); - return; - } - sortedGetChoices(message, 0, 1, choices, comparer, new Callback>() { - @Override - public void run(List result) { - callback.run(result.isEmpty() ? null : result.get(0)); - } - }); - } - - // If comparer is NULL, T has to be comparable. Otherwise you'll get an exception from inside the Arrays.sort() routine - public static void sortedOneOrNone(final String message, final List choices, Comparator comparer, final Callback callback) { - if ((choices == null) || choices.isEmpty()) { - callback.run(null); - return; - } - sortedGetChoices(message, 0, 1, choices, comparer, new Callback>() { - @Override - public void run(List result) { - callback.run(result.isEmpty() ? null : result.get(0)); - } - }); - } - - // If comparer is NULL, T has to be comparable. Otherwise you'll get an exception from inside the Arrays.sort() routine - public static void sortedOne(final String message, final T[] choices, Comparator comparer, final Callback callback) { - if ((choices == null) || (choices.length == 0)) { - callback.run(null); - return; - } - sortedGetChoices(message, 1, 1, choices, comparer, new Callback>() { - @Override - public void run(List result) { - assert result.size() == 1; - callback.run(result.get(0)); - } - }); - } - - // If comparer is NULL, T has to be comparable. Otherwise you'll get an exception from inside the Arrays.sort() routine - public static void sortedOne(final String message, final List choices, Comparator comparer, final Callback callback) { - if ((choices == null) || (choices.size() == 0)) { - callback.run(null); - return; - } - sortedGetChoices(message, 1, 1, choices, comparer, new Callback>() { - @Override - public void run(List result) { - assert result.size() == 1; - callback.run(result.get(0)); - } - }); - } - - // If comparer is NULL, T has to be comparable. Otherwise you'll get an exception from inside the Arrays.sort() routine - public static void sortedNoneOrMany(final String message, final List choices, Comparator comparer, final Callback> callback) { - sortedGetChoices(message, 0, choices.size(), choices, comparer, callback); - } - - // If comparer is NULL, T has to be comparable. Otherwise you'll get an exception from inside the Arrays.sort() routine - public static void sortedGetChoices(final String message, final int min, final int max, final T[] choices, Comparator comparer, final Callback> callback) { - // You may create a copy of source array if callers expect the collection to be unchanged - Arrays.sort(choices, comparer); - getChoices(message, min, max, choices, callback); - } - - // If comparer is NULL, T has to be comparable. Otherwise you'll get an exception from inside the Arrays.sort() routine - public static void sortedGetChoices(final String message, final int min, final int max, final List choices, Comparator comparer, final Callback> callback) { - // You may create a copy of source list if callers expect the collection to be unchanged - Collections.sort(choices, comparer); - getChoices(message, min, max, choices, callback); - } -} - diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/GuiDialog.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/GuiDialog.java deleted file mode 100644 index 80223248c56..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/GuiDialog.java +++ /dev/null @@ -1,52 +0,0 @@ -package forge.adventure.libgdxgui.toolbox; - -import com.google.common.collect.ImmutableList; -import forge.game.card.CardView; -import forge.util.Callback; -import org.apache.commons.lang3.StringUtils; - -import java.util.List; - -/** - * Holds player interactions using standard windows - */ -public class GuiDialog { - private static final ImmutableList defaultConfirmOptions = ImmutableList.of("Yes", "No"); - - public static void confirm(final CardView c, final String question, final Callback callback) { - GuiDialog.confirm(c, question, true, null, callback); - } - public static void confirm(final CardView c, final String question, final boolean defaultChoice, final Callback callback) { - GuiDialog.confirm(c, question, defaultChoice, null, callback); - } - public static void confirm(final CardView c, final String question, final List options, final Callback callback) { - GuiDialog.confirm(c, question, true, options, callback); - } - - public static void confirm(final CardView c, final String question, final boolean defaultIsYes, final List options, final Callback callback) { - final String title = c == null ? "Question" : c + " - Ability"; - String questionToUse = StringUtils.isBlank(question) ? "Activate card's ability?" : question; - final List opts = options == null ? defaultConfirmOptions : options; - FOptionPane.showCardOptionDialog(c, questionToUse, title, FOptionPane.QUESTION_ICON, opts, defaultIsYes ? 0 : 1, new Callback() { - @Override public void run(final Integer result) { - callback.run(result.intValue() == 0); - } - }); - } - - /** - *

- * showInfoDialg. - *

- * - * @param message - * a {@link String} object. - */ - public static void message(final String message) { - message(message, "Forge"); - } - - public static void message(final String message, final String title) { - FOptionPane.showMessageDialog(message, title, null); - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/ListChooser.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/ListChooser.java deleted file mode 100644 index 731de0b6946..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/toolbox/ListChooser.java +++ /dev/null @@ -1,320 +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.adventure.libgdxgui.toolbox; - -import com.google.common.base.Function; -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.assets.FSkinFont; -import forge.adventure.libgdxgui.assets.FSkinImage; -import forge.gui.FThreads; -import forge.item.InventoryItem; -import forge.adventure.libgdxgui.itemmanager.filters.AdvancedSearchFilter; -import forge.adventure.libgdxgui.itemmanager.filters.ItemFilter; -import forge.adventure.libgdxgui.itemmanager.filters.ListLabelFilter; -import forge.adventure.libgdxgui.menu.FMenuItem; -import forge.adventure.libgdxgui.menu.FPopupMenu; -import forge.adventure.libgdxgui.toolbox.FEvent.FEventHandler; -import forge.util.Callback; -import forge.util.Localizer; -import forge.adventure.libgdxgui.util.Utils; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * A simple class that shows a list of choices in a dialog. Two properties - * influence the behavior of a list chooser: minSelection and maxSelection. - * These two give the allowed number of selected items for the dialog to be - * closed. A negative value for minSelection suggests that the list is revealed - * and the choice doesn't matter. - *
    - *
  • If minSelection is 0, there will be a Cancel button.
  • - *
  • If minSelection is -1, 0 or 1, double-clicking a choice will also close the - * dialog.
  • - *
  • If the number of selections is out of bounds, the "OK" button is - * disabled.
  • - *
  • The dialog was "committed" if "OK" was clicked or a choice was double - * clicked.
  • - *
  • The dialog was "canceled" if "Cancel" or "X" was clicked.
  • - *
  • If the dialog was canceled, the selection will be empty.
  • - *
  • - *
- * - * @param - * the generic type - * @author Forge - * @version $Id: ListChooser.java 25183 2014-03-14 23:09:45Z drdev $ - */ -public class ListChooser extends FContainer { - // Data and number of choices for the list - - // Flag: was the dialog already shown? - private boolean called; - - // initialized before; listeners may be added to it - private FTextField txtSearch; - private FLabel btnSearch; - private final ChoiceList lstChoices; - private final FOptionPane optionPane; - private final Collection list; - private final Function display; - private final Callback> callback; - private AdvancedSearchFilter advancedSearchFilter; - - public ListChooser(final String title, final int minChoices, final int maxChoices, final Collection list0, final Function display0, final Callback> callback0) { - FThreads.assertExecutedByEdt(true); - list = list0; - lstChoices = add(new ChoiceList(list, minChoices, maxChoices)); - display = display0; - callback = callback0; - - //only show search field if more than 25 items and vertical layout - if (list.size() > 25 && !lstChoices.getListItemRenderer().layoutHorizontal()) { - txtSearch = add(new FTextField()); - txtSearch.setFont(FSkinFont.get(12)); - txtSearch.setGhostText(Localizer.getInstance().getMessage("lblSearch")); - txtSearch.setChangedHandler(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - applyFilters(); - } - }); - - advancedSearchFilter = lstChoices.getListItemRenderer().getAdvancedSearchFilter(this); - if (advancedSearchFilter != null) { - btnSearch = add(new FLabel.ButtonBuilder() - .icon(Forge.hdbuttons ? FSkinImage.HDSEARCH : FSkinImage.SEARCH).iconScaleFactor(0.9f).command(new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - FPopupMenu menu = new FPopupMenu() { - @Override - protected void buildMenu() { - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblAdvancedSearch"), Forge.hdbuttons ? FSkinImage.HDSEARCH : FSkinImage.SEARCH, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - advancedSearchFilter.edit(); - } - })); - addItem(new FMenuItem(Localizer.getInstance().getMessage("lblResetFilters"), Forge.hdbuttons ? FSkinImage.HDDELETE : FSkinImage.DELETE, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - resetFilters(); - } - })); - } - }; - menu.show(btnSearch, 0, btnSearch.getHeight()); - } - }).build()); - add(advancedSearchFilter.getWidget()); - } - } - - final List options; - if (minChoices == 0) { - options = ImmutableList.of(Localizer.getInstance().getMessage("lblOK"), Localizer.getInstance().getMessage("lblCancel")); - } else { - options = ImmutableList.of(Localizer.getInstance().getMessage("lblOK")); - } - - updateHeight(); - - optionPane = new FOptionPane(null, null, title, null, this, options, 0, new Callback() { - @Override - public void run(Integer result) { - called = false; - if (result == 0) { - callback.run(lstChoices.getSelectedItems()); - } - else if (minChoices > 0) { - show(); //show if user tries to cancel when input is mandatory - } - else { - callback.run(new ArrayList<>()); - } - } - }) { - @Override - protected boolean padAboveAndBelow() { - return false; //allow list to go straight up against buttons - } - }; - } - - public void resetFilters() { - txtSearch.setText(""); - if (advancedSearchFilter != null) { - advancedSearchFilter.reset(); - ItemFilter.Widget widget = advancedSearchFilter.getWidget(); - if (widget.isVisible()) { - widget.setVisible(false); - revalidate(); - } - } - applyFilters(); - } - - @SuppressWarnings("unchecked") - public void applyFilters() { - lstChoices.clearSelection(); - - List> predicates = new ArrayList<>(); - - final String pattern = txtSearch.getText().toLowerCase(); - if (!pattern.isEmpty()) { - predicates.add(new Predicate() { - @Override - public boolean apply(T input) { - return lstChoices.getChoiceText(input).toLowerCase().contains(pattern); - } - }); - } - if (advancedSearchFilter != null && !advancedSearchFilter.isEmpty()) { - predicates.add((Predicate)advancedSearchFilter.getPredicate()); - } - - if (predicates.isEmpty()) { - lstChoices.setListData(list); - } - else { - lstChoices.setListData(Iterables.filter(list, Predicates.and(predicates))); - } - - if (!lstChoices.isEmpty() && lstChoices.getMaxChoices() > 0) { - lstChoices.addSelectedIndex(0); - } - lstChoices.setScrollTop(0); - } - - private void updateHeight() { - boolean needRevalidate = getHeight() > 0; //needs to revalidate if already has height - if (lstChoices.getListItemRenderer().layoutHorizontal()) { - setHeight(Utils.AVG_FINGER_HEIGHT); - } - else { - setHeight(Math.min(lstChoices.getListItemRenderer().getItemHeight() * list.size(), FOptionPane.getMaxDisplayObjHeight())); - } - if (needRevalidate) { - optionPane.revalidate(); - } - } - - public void show() { - show(null, false); - } - - /** - * Shows the dialog and returns after the dialog was closed. - * - */ - public void show(final T item, final boolean selectMax) { - if (called) { - throw new IllegalStateException("Already shown"); - } - called = true; - if (item == null) { - if (selectMax) { - lstChoices.clearSelection(); - int max = Math.min(lstChoices.getMaxChoices(), list.size()); - for (int i = 0; i < max; i++) { - lstChoices.addSelectedIndex(i); - } - } - else if (lstChoices.getMaxChoices() == 1) { //select first item only if single-select - lstChoices.setSelectedIndex(0); - } - else { - lstChoices.clearSelection(); - } - } - else { - lstChoices.setSelectedItem(item); - } - optionPane.show(); - } - - @Override - protected void doLayout(float width, float height) { - float y = 0; - if (txtSearch != null) { - float fieldWidth = width; - float fieldHeight = txtSearch.getHeight(); - float padding = fieldHeight * 0.25f; - y += padding; - if (btnSearch != null) { - float buttonWidth = fieldHeight; - btnSearch.setBounds(width - buttonWidth, y, buttonWidth, fieldHeight); - fieldWidth -= buttonWidth + ItemFilter.PADDING; - } - txtSearch.setBounds(0, y, fieldWidth, fieldHeight); - - if (advancedSearchFilter != null && advancedSearchFilter.getWidget().isVisible()) { - padding = ItemFilter.PADDING; - y += fieldHeight + padding; - fieldHeight = FTextField.getDefaultHeight(ListLabelFilter.LABEL_FONT); - advancedSearchFilter.getWidget().setBounds(0, y, width, fieldHeight); - } - y += fieldHeight + padding; - } - lstChoices.setBounds(0, y, width, height - y); - } - - private class ChoiceList extends FChoiceList { - private ChoiceList(Collection items, int minChoices0, int maxChoices0) { - super(items, minChoices0, maxChoices0); - } - - @Override - protected String getChoiceText(T choice) { - if (display == null) { - return choice.toString(); - } - return display.apply(choice); - } - - @Override - protected void onSelectionChange() { - final int num = getSelectionCount(); - optionPane.setButtonEnabled(0, (num >= minChoices) && (num <= maxChoices || maxChoices == -1)); - } - - @Override - protected void onItemActivate(Integer index, T value) { - if (optionPane.isButtonEnabled(0)) { - optionPane.setResult(0); - } - } - - @Override - protected void onCompactModeChange() { - updateHeight(); //update height and scroll bounds based on compact mode change - } - - @Override - public void drawOverlay(Graphics g) { - //don't draw border - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/util/LayoutHelper.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/util/LayoutHelper.java deleted file mode 100644 index 58628e92a07..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/util/LayoutHelper.java +++ /dev/null @@ -1,195 +0,0 @@ -package forge.adventure.libgdxgui.util; - -import forge.adventure.libgdxgui.toolbox.FContainer; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; - -/** - * Helper class for doing custom layout - * - */ -public final class LayoutHelper { - private final float parentWidth, parentHeight; - private float x; - private float y; - private float lineBottom; - private final float gapX; - private final float gapY; - - public LayoutHelper(FContainer parent) { - this(parent, 3, 3); - } - public LayoutHelper(FContainer parent, float gapX0, float gapY0) { - parentWidth = parent.getWidth(); - parentHeight = parent.getHeight(); - gapX = gapX0; - gapY = gapY0; - } - - /** - * Layout object to fill remaining vertical space of parent - * @param obj - */ - public void fill(final FDisplayObject obj) { - newLine(); //start new line if needed - include(obj, parentWidth, parentHeight - y); - } - - /** - * Layout object to fill remaining horizontal space of current line - * @param obj - * @param height - */ - public void fillLine(final FDisplayObject obj, float height) { - fillLine(obj, height, 0); - } - - /** - * Layout object to fill remaining horizontal space of current line - * @param obj - * @param height - * @param rightPadding - */ - public void fillLine(final FDisplayObject obj, float height, float rightPadding) { - if (x >= parentWidth) { - newLine(); - } - include(obj, parentWidth - x - rightPadding, height); - } - - /** - * Include object in layout with a percentage width and fixed height - * @param obj - * @param widthPercent - * @param height - */ - public void include(final FDisplayObject obj, double widthPercent, float height) { - include(obj, Math.round(parentWidth * widthPercent), height); - } - - /** - * Include object in layout with a fixed width and percentage height - * @param obj - * @param width - * @param heightPercent - */ - public void include(final FDisplayObject obj, float width, double heightPercent) { - include(obj, width, Math.round(parentHeight * heightPercent)); - } - - /** - * Include object in layout with a percentage width and height - * @param obj - * @param widthPercent - * @param heightPercent - */ - public void include(final FDisplayObject obj, double widthPercent, double heightPercent) { - include(obj, Math.round(parentWidth * widthPercent), Math.round(parentHeight * heightPercent)); - } - - /** - * Include object in layout with a fixed width and height - * @param obj - * @param width - * @param height - */ - public void include(final FDisplayObject obj, float width, float height) { - if (width <= 0 || height <= 0) { return; } - - if (x + width > parentWidth + 1) { //+1 to avoid wrapping from rounding error - newLine(); - if (width > parentWidth) { - width = parentWidth; - } - } - if (y + height > parentHeight) { - y = parentHeight - height; - if (y >= parentHeight) { return; } - } - obj.setBounds(x, y, width, height); - x += width + gapX; - if (y + height > lineBottom) { - lineBottom = y + height; - } - } - - /** - * Offset current layout helper position - * @param dx - * @param dy - */ - public void offset(float dx, float dy) { - x += dx; - y += dy; - } - - /** - * Start new line of layout - */ - public void newLine() { - if (lineBottom == y) { return; } - x = 0; - y = lineBottom + gapY; - lineBottom = y; - } - - /** - * Start new line of layout - */ - public void newLine(float dy) { - x = 0; - y = lineBottom + gapY + dy; - lineBottom = y; - } - - /** - * @return remaining width on current line - */ - public float getRemainingLineWidth() { - if (x >= parentWidth) { - newLine(); - } - return parentWidth - x; - } - - /** - * @return width of parent - */ - public float getParentWidth() { - return parentWidth; - } - - /** - * @return width of parent - */ - public float getParentHeight() { - return parentHeight; - } - - /** - * @return current X - */ - public float getX() { - return x; - } - - /** - * @return current Y - */ - public float getY() { - return y; - } - - /** - * @return gap X - */ - public float getGapX() { - return gapX; - } - - /** - * @return gap Y - */ - public float getGapY() { - return gapY; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/util/LibGDXImageFetcher.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/util/LibGDXImageFetcher.java deleted file mode 100644 index 4967bcb740c..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/util/LibGDXImageFetcher.java +++ /dev/null @@ -1,85 +0,0 @@ -package forge.adventure.libgdxgui.util; - -import com.badlogic.gdx.files.FileHandle; -import forge.adventure.libgdxgui.Forge; -import forge.gui.GuiBase; -import forge.util.ImageFetcher; -import forge.util.TextUtil; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; - -public class LibGDXImageFetcher extends ImageFetcher { - @Override - protected Runnable getDownloadTask(String[] downloadUrls, String destPath, Runnable notifyObservers) { - return new LibGDXDownloadTask(downloadUrls, destPath, notifyObservers); - } - - private static class LibGDXDownloadTask implements Runnable { - private final String[] downloadUrls; - private final String destPath; - private final Runnable notifyObservers; - - LibGDXDownloadTask(String[] downloadUrls, String destPath, Runnable notifyObservers) { - this.downloadUrls = downloadUrls; - this.destPath = destPath; - this.notifyObservers = notifyObservers; - } - - private void doFetch(String urlToDownload) throws IOException { - String newdespath = urlToDownload.contains(".fullborder.jpg") ? - TextUtil.fastReplace(destPath, ".full.jpg", ".fullborder.jpg") : destPath; - URL url = new URL(urlToDownload); - System.out.println("Attempting to fetch: " + url); - java.net.URLConnection c = url.openConnection(); - c.setRequestProperty("User-Agent", ""); - - InputStream is = c.getInputStream(); - // First, save to a temporary file so that nothing tries to read - // a partial download. - FileHandle destFile = new FileHandle(newdespath + ".tmp"); - System.out.println(newdespath); - destFile.parent().mkdirs(); - - // Conversion to JPEG will be handled differently depending on the platform - Forge.getDeviceAdapter().convertToJPEG(is, new FileOutputStream(destFile.file())); - destFile.moveTo(new FileHandle(newdespath)); - - System.out.println("Saved image to " + newdespath); - GuiBase.getInterface().invokeInEdtLater(notifyObservers); - } - - private String tofullBorder(String imageurl) { - if (!imageurl.contains(".full.jpg")) - return imageurl; - try { - URL url = new URL(imageurl); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - //connection.setConnectTimeout(1000 * 5); //wait 5 seconds the most - //connection.setReadTimeout(1000 * 5); - conn.setRequestProperty("User-Agent", ""); - if(conn.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) - imageurl = TextUtil.fastReplace(imageurl, ".full.jpg", ".fullborder.jpg"); - conn.disconnect(); - return imageurl; - } catch (IOException ex) { - return imageurl; - } - } - - public void run() { - for (String urlToDownload : downloadUrls) { - try { - doFetch(tofullBorder(urlToDownload)); - break; - } catch (IOException e) { - System.out.println("Failed to download card [" + destPath + "] image: " + e.getMessage()); - } - } - } - } - -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/util/PhysicsObject.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/util/PhysicsObject.java deleted file mode 100644 index abc3a30f118..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/util/PhysicsObject.java +++ /dev/null @@ -1,80 +0,0 @@ -package forge.adventure.libgdxgui.util; - -import com.badlogic.gdx.math.Vector2; - -public class PhysicsObject { - private final Vector2 position, velocity, acceleration; - private boolean allowVelocitySignChange; - - public PhysicsObject(Vector2 position0, Vector2 velocity0) { - this(position0, velocity0, new Vector2(0, 0), false); - } - public PhysicsObject(Vector2 position0, Vector2 velocity0, Vector2 acceleration0, boolean allowVelocitySignChange0) { - position = position0; - velocity = velocity0; - acceleration = acceleration0; - allowVelocitySignChange = allowVelocitySignChange0; - } - - //setup acceleration so sign of acceleration forces velocity to move towards 0 - //decelX and decelY should be positive values - public void setDecel(float decelX, float decelY) { - if (velocity.x > 0) { - decelX = -decelX; - } - if (velocity.y > 0) { - decelY = -decelY; - } - acceleration.set(decelX, decelY); - allowVelocitySignChange = false; //assume we're not allowing sign of velocity to change - } - - public Vector2 getPosition() { - return position; - } - - public Vector2 getVelocity() { - return velocity; - } - - public Vector2 getAcceleration() { - return acceleration; - } - - public void stop() { - velocity.set(0, 0); - acceleration.set(0, 0); - } - - public boolean isMoving() { - return velocity.x != 0 || velocity.y != 0 || acceleration.x != 0 || acceleration.y != 0; - } - - public void advance(float dt) { - float signum; - if (acceleration.x == 0) { - position.x += velocity.x * dt; - } - else { - signum = Math.signum(velocity.x); - position.x += (velocity.x + 0.5f * acceleration.x * dt) * dt; - velocity.x += acceleration.x * dt; - if (!allowVelocitySignChange && Math.signum(velocity.x) != signum) { - velocity.x = 0; //stop in this direction if sign changed - acceleration.x = 0; - } - } - if (acceleration.y == 0) { - position.y += velocity.y * dt; - } - else { - signum = Math.signum(velocity.y); - position.y += (velocity.y + 0.5f * acceleration.y * dt) * dt; - velocity.y += acceleration.y * dt; - if (!allowVelocitySignChange && Math.signum(velocity.y) != signum) { - velocity.y = 0; //stop in this direction if sign changed - acceleration.y = 0; - } - } - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/util/TextBounds.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/util/TextBounds.java deleted file mode 100644 index d9f390766e3..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/util/TextBounds.java +++ /dev/null @@ -1,15 +0,0 @@ -package forge.adventure.libgdxgui.util; - -public class TextBounds { - public float width; - public float height; - - public TextBounds() { - - } - - public TextBounds(float width, float height) { - this.width = width; - this.height = height; - } -} \ No newline at end of file diff --git a/forge-adventure/src/main/java/forge/adventure/libgdxgui/util/Utils.java b/forge-adventure/src/main/java/forge/adventure/libgdxgui/util/Utils.java deleted file mode 100644 index 8c6e84b6013..00000000000 --- a/forge-adventure/src/main/java/forge/adventure/libgdxgui/util/Utils.java +++ /dev/null @@ -1,117 +0,0 @@ -package forge.adventure.libgdxgui.util; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.math.Vector2; - -public class Utils { - public static final boolean DEV_SCREEN_LANDSCAPE = false; - - public static final float BASE_WIDTH = 320f; - public static final float BASE_HEIGHT = 480f; - private static final float SCREEN_WIDTH = (float)Gdx.graphics.getWidth(); - private static final float SCREEN_HEIGHT = (float)Gdx.graphics.getHeight(); - private static final float HEIGHT_RATIO = SCREEN_HEIGHT / BASE_HEIGHT; - - private static final float AVG_FINGER_SIZE_CM = 1.1f; - - //Swap commented out line below to specify average finger size - private static final float ppcX = Gdx.graphics.getPpcX(), ppcY = Gdx.graphics.getPpcY(); - //private static final float ppcX = 169f / AVG_FINGER_SIZE_CM, ppcY = 237f / AVG_FINGER_SIZE_CM; - //private static final float scaleX = 1.41f, scaleY = 1.25f; - //private static final float ppcX = Gdx.graphics.getPpcX() * scaleX, ppcY = Gdx.graphics.getPpcY() * scaleY; - - //round to nearest int to reduce floating point display issues - //reduce if either would take up too large a percentage of the screen to prevent layouts not working - private static final float MIN_FINGER_SIZE = scale(40); //scaled value of 40 is approximately how tall the Prompt buttons would need to be to fit their text - private static final float MIN_FINGERS_WIDE = 5; //ensure screen considered to be at least 5 "fingers" wide - private static final float MIN_FINGERS_TALL = MIN_FINGERS_WIDE * BASE_HEIGHT / BASE_WIDTH; //ensure screen tall enough based on fingers wide and base ratio - - public static final float AVG_FINGER_WIDTH = Math.round(Math.min(Math.max(cmToPixelsX(AVG_FINGER_SIZE_CM), MIN_FINGER_SIZE), SCREEN_WIDTH / MIN_FINGERS_WIDE)); - public static final float AVG_FINGER_HEIGHT = Math.round(Math.min(Math.max(cmToPixelsY(AVG_FINGER_SIZE_CM), MIN_FINGER_SIZE), SCREEN_HEIGHT / MIN_FINGERS_TALL)); - - public static float cmToPixelsX(float cm) { - return ppcX * cm; - } - public static float cmToPixelsY(float cm) { - return ppcY * cm; - } - - public static float scale(float value) { - //use height ratio to prioritize making fonts look good - //fonts can always auto-scale down if container not wide enough - return Math.round(value * HEIGHT_RATIO); - } - - public static long secondsToTimeSpan(float seconds) { - return (long)(seconds * 1000000000l); - } - - public static Vector2 getIntersection(Vector2 l1p1, Vector2 l1p2, Vector2 l2p1, Vector2 l2p2) { - Vector2 result = new Vector2(); - - // Denominator for ua and ub are the same, so store this calculation - float d = (l2p2.y - l2p1.y) * (l1p2.x - l1p1.x) - (l2p2.x - l2p1.x) * (l1p2.y - l1p1.y); - - //n_a and n_b are calculated as separate values for readability - float n_a = (l2p2.x - l2p1.x) * (l1p1.y - l2p1.y) - (l2p2.y - l2p1.y) * (l1p1.x - l2p1.x); - float n_b = (l1p2.x - l1p1.x) * (l1p1.y - l2p1.y) - (l1p2.y - l1p1.y) * (l1p1.x - l2p1.x); - - // Make sure there is not a division by zero - this also indicates that - // the lines are parallel. - // If n_a and n_b were both equal to zero the lines would be on top of each - // other (coincidental). This check is not done because it is not - // necessary for this implementation (the parallel check accounts for this). - if (d != 0) { - // Calculate the intermediate fractional point that the lines potentially intersect. - float ua = n_a / d; - float ub = n_b / d; - - // The fractional point will be between 0 and 1 inclusive if the lines - // intersect. If the fractional calculation is larger than 1 or smaller - // than 0 the lines would need to be longer to intersect. - if (ua >= 0d && ua <= 1d && ub >= 0d && ub <= 1d) { - result.x = l1p1.x + (ua * (l1p2.x - l1p1.x)); - result.y = l1p1.y + (ua * (l1p2.y - l1p1.y)); - return result; - } - } - - //if lines are parallel or don't intersect, just return the midpoint of first line - return getMidpoint(l1p1, l1p2); - } - - public static Vector2 getMidpoint(Vector2 p1, Vector2 p2) { - Vector2 result = new Vector2(); - result.x = (p1.x + p2.x) / 2; - result.y = (p1.y + p2.y) / 2; - return result; - } - - public static Vector2 getArbitaryPoint(float x1, float y1, float x2, float y2, float percentage) { - Vector2 result = new Vector2(); - result.x = x1 * (1 - percentage) + x2 * percentage; - result.y = y1 * (1 - percentage) + y2 * percentage; - return result; - } - - public static Rectangle getTransitionPosition(Rectangle start, Rectangle end, float percentage) { - Vector2 topLeft = getArbitaryPoint(start.x, start.y, end.x, end.y, percentage); - Vector2 bottomRight = getArbitaryPoint(start.x + start.width, start.y + start.height, end.x + end.width, end.y + end.height, percentage); - return new Rectangle(topLeft.x, topLeft.y, bottomRight.x - topLeft.x, bottomRight.y - topLeft.y); - } - - //get rectangle defining the interestion between two other rectangles - public static Rectangle getIntersection(Rectangle r1, Rectangle r2) { - float left = Math.max(r1.x, r2.x); - float right = Math.min(r1.x + r1.width, r2.x + r2.width); - if (right > left) { - float top = Math.max(r1.y, r2.y); - float bottom = Math.min(r1.y + r1.height, r2.y + r2.height); - if (bottom > top) { - return new Rectangle(left, top, right - left, bottom - top); - } - } - return null; - } -} diff --git a/forge-adventure/src/main/java/forge/adventure/scene/DeckEditScene.java b/forge-adventure/src/main/java/forge/adventure/scene/DeckEditScene.java index 81bc71d1e23..52bb3662614 100644 --- a/forge-adventure/src/main/java/forge/adventure/scene/DeckEditScene.java +++ b/forge-adventure/src/main/java/forge/adventure/scene/DeckEditScene.java @@ -1,12 +1,10 @@ package forge.adventure.scene; import com.badlogic.gdx.scenes.scene2d.Stage; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.deck.FDeckEditor; -import forge.adventure.libgdxgui.screens.FScreen; +import forge.adventure.AdventureApplicationAdapter; import forge.adventure.world.AdventurePlayer; import forge.deck.Deck; -import forge.deck.DeckProxy; +import forge.deck.FDeckEditor; import forge.gamemodes.quest.QuestMode; import forge.gamemodes.quest.QuestSpellShop; import forge.gamemodes.quest.data.DeckConstructionRules; @@ -16,6 +14,8 @@ import forge.itemmanager.ColumnDef; import forge.itemmanager.ItemColumn; import forge.itemmanager.ItemManagerConfig; import forge.model.FModel; +import forge.screens.FScreen; +import forge.toolbox.FEvent; import java.util.HashMap; import java.util.Map; @@ -27,10 +27,12 @@ import java.util.Map; public class DeckEditScene extends ForgeScene { public class AdventureDeckEditor extends FDeckEditor { public AdventureDeckEditor(boolean commander) { - super(commander ? EditorType.QuestCommander: EditorType.Quest, "", false); - } - public AdventureDeckEditor(DeckProxy editDeck, boolean commander) { - super(commander ? EditorType.QuestCommander: EditorType.Quest, editDeck, true); + super(commander ? EditorType.QuestCommander : EditorType.Quest, "", false, new FEvent.FEventHandler() { + @Override + public void handleEvent(FEvent e) { + AdventureApplicationAdapter.instance.switchToLast(); + } + }); } @Override public void onActivate() { @@ -66,7 +68,6 @@ public class DeckEditScene extends ForgeScene { } AdventureDeckEditor screen; - Graphics localGraphics; Stage stage; public DeckEditScene() { diff --git a/forge-adventure/src/main/java/forge/adventure/scene/DuelScene.java b/forge-adventure/src/main/java/forge/adventure/scene/DuelScene.java index 93c2571f47c..581fb7f61a4 100644 --- a/forge-adventure/src/main/java/forge/adventure/scene/DuelScene.java +++ b/forge-adventure/src/main/java/forge/adventure/scene/DuelScene.java @@ -4,9 +4,9 @@ import forge.LobbyPlayer; import forge.adventure.AdventureApplicationAdapter; import forge.adventure.character.EnemySprite; import forge.adventure.character.PlayerSprite; -import forge.adventure.libgdxgui.assets.FSkin; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.screens.match.MatchController; +import forge.assets.FSkin; +import forge.screens.FScreen; +import forge.screens.match.MatchController; import forge.adventure.util.Current; import forge.adventure.util.Config; import forge.adventure.world.AdventurePlayer; diff --git a/forge-adventure/src/main/java/forge/adventure/scene/ForgeInput.java b/forge-adventure/src/main/java/forge/adventure/scene/ForgeInput.java index 58fca0300be..b5d66aade45 100644 --- a/forge-adventure/src/main/java/forge/adventure/scene/ForgeInput.java +++ b/forge-adventure/src/main/java/forge/adventure/scene/ForgeInput.java @@ -1,13 +1,13 @@ package forge.adventure.scene; import com.badlogic.gdx.Input; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.screens.match.MatchController; -import forge.adventure.libgdxgui.toolbox.FContainer; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.toolbox.FGestureAdapter; -import forge.adventure.libgdxgui.toolbox.FOverlay; -import forge.adventure.libgdxgui.util.Utils; +import forge.Forge; +import forge.screens.match.MatchController; +import forge.toolbox.FContainer; +import forge.toolbox.FDisplayObject; +import forge.toolbox.FGestureAdapter; +import forge.toolbox.FOverlay; +import forge.util.Utils; import forge.gui.error.BugReporter; import java.util.ArrayList; diff --git a/forge-adventure/src/main/java/forge/adventure/scene/ForgeScene.java b/forge-adventure/src/main/java/forge/adventure/scene/ForgeScene.java index e27c9f88b73..487dd00eb2f 100644 --- a/forge-adventure/src/main/java/forge/adventure/scene/ForgeScene.java +++ b/forge-adventure/src/main/java/forge/adventure/scene/ForgeScene.java @@ -3,13 +3,13 @@ package forge.adventure.scene; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.GL20; import forge.adventure.AdventureApplicationAdapter; -import forge.adventure.libgdxgui.Forge; -import forge.adventure.libgdxgui.Graphics; -import forge.adventure.libgdxgui.animation.ForgeAnimation; -import forge.adventure.libgdxgui.assets.ImageCache; -import forge.adventure.libgdxgui.screens.FScreen; -import forge.adventure.libgdxgui.toolbox.FDisplayObject; -import forge.adventure.libgdxgui.toolbox.FOverlay; +import forge.Forge; +import forge.Graphics; +import forge.animation.ForgeAnimation; +import forge.assets.ImageCache; +import forge.screens.FScreen; +import forge.toolbox.FDisplayObject; +import forge.toolbox.FOverlay; import forge.gamemodes.match.LobbySlotType; import forge.interfaces.IUpdateable; diff --git a/forge-adventure/src/main/java/forge/adventure/scene/RewardScene.java b/forge-adventure/src/main/java/forge/adventure/scene/RewardScene.java index fe9f2054ed5..f38730eb716 100644 --- a/forge-adventure/src/main/java/forge/adventure/scene/RewardScene.java +++ b/forge-adventure/src/main/java/forge/adventure/scene/RewardScene.java @@ -8,7 +8,7 @@ import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.utils.Array; import forge.adventure.AdventureApplicationAdapter; import forge.adventure.character.ShopActor; -import forge.adventure.libgdxgui.assets.ImageCache; +import forge.assets.ImageCache; import forge.adventure.util.CardUtil; import forge.adventure.util.Current; import forge.adventure.util.Reward; diff --git a/forge-adventure/src/main/java/forge/adventure/util/RewardActor.java b/forge-adventure/src/main/java/forge/adventure/util/RewardActor.java index 9d829b17811..10ddd4f7bfd 100644 --- a/forge-adventure/src/main/java/forge/adventure/util/RewardActor.java +++ b/forge-adventure/src/main/java/forge/adventure/util/RewardActor.java @@ -16,10 +16,10 @@ import com.badlogic.gdx.scenes.scene2d.ui.Tooltip; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; import com.badlogic.gdx.utils.Disposable; -import forge.adventure.libgdxgui.assets.FSkin; -import forge.adventure.libgdxgui.assets.ImageCache; import forge.adventure.scene.RewardScene; import forge.adventure.scene.Scene; +import forge.assets.FSkin; +import forge.assets.ImageCache; import forge.gui.GuiBase; import forge.util.ImageFetcher; diff --git a/forge-gui-desktop/pom.xml b/forge-gui-desktop/pom.xml index 5ff9a83e9cd..17b4112b6c1 100644 --- a/forge-gui-desktop/pom.xml +++ b/forge-gui-desktop/pom.xml @@ -129,11 +129,6 @@ forge-gui ${project.version} - - forge - forge-adventure - ${project.version} - com.miglayout miglayout-swing diff --git a/forge-gui-mobile/src/forge/GuiMobile.java b/forge-gui-mobile/src/forge/GuiMobile.java index 44b8665f74f..f04a3fcc76c 100644 --- a/forge-gui-mobile/src/forge/GuiMobile.java +++ b/forge-gui-mobile/src/forge/GuiMobile.java @@ -1,20 +1,10 @@ package forge; -import java.io.File; -import java.util.Collection; -import java.util.List; - import com.badlogic.gdx.Application.ApplicationType; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Texture; import com.google.common.base.Function; - -import forge.assets.FBufferedImage; -import forge.assets.FDelayLoadImage; -import forge.assets.FImage; -import forge.assets.FSkin; -import forge.assets.FTextureImage; -import forge.assets.ImageCache; +import forge.assets.*; import forge.card.CardRenderer; import forge.deck.Deck; import forge.deck.FDeckViewer; @@ -37,13 +27,11 @@ import forge.sound.IAudioClip; import forge.sound.IAudioMusic; import forge.toolbox.FOptionPane; import forge.toolbox.GuiChoose; -import forge.util.Callback; -import forge.util.FileUtil; -import forge.util.ImageFetcher; -import forge.util.LibGDXImageFetcher; -import forge.util.ThreadUtil; -import forge.util.WaitCallback; -import forge.util.WaitRunnable; +import forge.util.*; + +import java.io.File; +import java.util.Collection; +import java.util.List; public class GuiMobile implements IGuiBase { private final String assetsDir; @@ -55,7 +43,7 @@ public class GuiMobile implements IGuiBase { @Override public boolean isRunningOnDesktop() { - return Gdx.app.getType() == ApplicationType.Desktop; + return Gdx.app==null ? true : Gdx.app.getType() == ApplicationType.Desktop; } @Override diff --git a/forge-gui-mobile/src/forge/assets/FSkin.java b/forge-gui-mobile/src/forge/assets/FSkin.java index 0f7137db1f5..f1c70dfcd97 100644 --- a/forge-gui-mobile/src/forge/assets/FSkin.java +++ b/forge-gui-mobile/src/forge/assets/FSkin.java @@ -1,8 +1,5 @@ package forge.assets; -import java.util.HashMap; -import java.util.Map; - import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.Color; @@ -10,7 +7,6 @@ import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.utils.Array; - import forge.Forge; import forge.assets.FSkinImage.SourceFile; import forge.card.CardFaceSymbols; @@ -26,6 +22,9 @@ import forge.screens.SplashScreen; import forge.toolbox.FProgressBar; import forge.util.WordUtil; +import java.util.HashMap; +import java.util.Map; + public class FSkin { private static final Map images = new HashMap<>(512); private static final Map avatars = new HashMap<>(150); @@ -83,7 +82,10 @@ public class FSkin { } }); } - + public static void loadLight(String skinName, final SplashScreen splashScreen,FileHandle prefDir) { + preferredDir = prefDir; + loadLight(skinName,splashScreen); + } /* * Loads a "light" version of FSkin, just enough for the splash screen: * skin name. Generates custom skin settings, fonts, and backgrounds. @@ -101,30 +103,34 @@ public class FSkin { //ensure skins directory exists final FileHandle dir = Gdx.files.absolute(ForgeConstants.CACHE_SKINS_DIR); - if (!dir.exists() || !dir.isDirectory()) { - //if skins directory doesn't exist, point to internal assets/skin directory instead for the sake of the splash screen - preferredDir = Gdx.files.internal("fallback_skin"); - } - else { - if (splashScreen != null) { - if (allSkins == null) { //initialize - allSkins = new Array<>(); - allSkins.add("Default"); //init default - final Array skinDirectoryNames = getSkinDirectoryNames(); - for (final String skinDirectoryName : skinDirectoryNames) { - allSkins.add(WordUtil.capitalize(skinDirectoryName.replace('_', ' '))); + if(preferredDir==null) + { + if (!dir.exists() || !dir.isDirectory()) { + //if skins directory doesn't exist, point to internal assets/skin directory instead for the sake of the splash screen + preferredDir = Gdx.files.internal("fallback_skin"); + } + else { + if (splashScreen != null) { + if (allSkins == null) { //initialize + allSkins = new Array<>(); + allSkins.add("Default"); //init default + final Array skinDirectoryNames = getSkinDirectoryNames(); + for (final String skinDirectoryName : skinDirectoryNames) { + allSkins.add(WordUtil.capitalize(skinDirectoryName.replace('_', ' '))); + } + allSkins.sort(); } - allSkins.sort(); + } + + // Non-default (preferred) skin name and dir. + preferredDir = Gdx.files.absolute(preferredName.equals("default") ? ForgeConstants.BASE_SKINS_DIR + preferredName : ForgeConstants.CACHE_SKINS_DIR + preferredName); + if (!preferredDir.exists() || !preferredDir.isDirectory()) { + preferredDir.mkdirs(); } } - - // Non-default (preferred) skin name and dir. - preferredDir = Gdx.files.absolute(preferredName.equals("default") ? ForgeConstants.BASE_SKINS_DIR + preferredName : ForgeConstants.CACHE_SKINS_DIR + preferredName); - if (!preferredDir.exists() || !preferredDir.isDirectory()) { - preferredDir.mkdirs(); - } } + FSkinTexture.BG_TEXTURE.load(); //load background texture early for splash screen //load theme logo while changing skins diff --git a/forge-gui-mobile/src/forge/deck/FDeckEditor.java b/forge-gui-mobile/src/forge/deck/FDeckEditor.java index f2dffbab8e4..1fbb5bb5a59 100644 --- a/forge-gui-mobile/src/forge/deck/FDeckEditor.java +++ b/forge-gui-mobile/src/forge/deck/FDeckEditor.java @@ -1,16 +1,5 @@ package forge.deck; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import forge.gui.FThreads; -import forge.screens.LoadingOverlay; -import org.apache.commons.lang3.StringUtils; - import com.badlogic.gdx.Input.Keys; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Align; @@ -18,19 +7,15 @@ import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.base.Supplier; import com.google.common.collect.ImmutableList; - import forge.Forge; import forge.Forge.KeyInputAdapter; import forge.Graphics; -import forge.assets.FImage; -import forge.assets.FSkin; -import forge.assets.FSkinFont; -import forge.assets.FSkinImage; -import forge.assets.FTextureRegionImage; +import forge.assets.*; import forge.card.CardEdition; import forge.deck.io.DeckPreferences; import forge.gamemodes.limited.BoosterDraft; import forge.gamemodes.planarconquest.ConquestUtil; +import forge.gui.FThreads; import forge.gui.card.CardPreferences; import forge.item.PaperCard; import forge.itemmanager.CardManager; @@ -46,20 +31,17 @@ import forge.menu.FMenuItem; import forge.menu.FPopupMenu; import forge.model.FModel; import forge.screens.FScreen; +import forge.screens.LoadingOverlay; import forge.screens.TabPageScreen; -import forge.toolbox.FContainer; -import forge.toolbox.FEvent; +import forge.toolbox.*; import forge.toolbox.FEvent.FEventHandler; import forge.toolbox.FEvent.FEventType; -import forge.toolbox.FLabel; -import forge.toolbox.FOptionPane; -import forge.toolbox.GuiChoose; -import forge.util.Callback; -import forge.util.ItemPool; -import forge.util.Lang; -import forge.util.Localizer; -import forge.util.Utils; +import forge.util.*; import forge.util.storage.IStorage; +import org.apache.commons.lang3.StringUtils; + +import java.util.*; +import java.util.Map.Entry; public class FDeckEditor extends TabPageScreen { public static FSkinImage MAIN_DECK_ICON = Forge.hdbuttons ? FSkinImage.HDLIBRARY :FSkinImage.DECKLIST; @@ -288,16 +270,19 @@ public class FDeckEditor extends TabPageScreen { private final FLabel btnMoreOptions = deckHeader.add(new FLabel.Builder().text("...").font(FSkinFont.get(20)).align(Align.center).pressedColor(Header.BTN_PRESSED_COLOR).build()); public FDeckEditor(EditorType editorType0, DeckProxy editDeck, boolean showMainDeck) { - this(editorType0, editDeck.getName(), editDeck.getPath(), null, showMainDeck); + this(editorType0, editDeck.getName(), editDeck.getPath(), null, showMainDeck,null); + } + public FDeckEditor(EditorType editorType0, String editDeckName, boolean showMainDeck,FEventHandler backButton) { + this(editorType0, editDeckName, "", null, showMainDeck,backButton); } public FDeckEditor(EditorType editorType0, String editDeckName, boolean showMainDeck) { - this(editorType0, editDeckName, "", null, showMainDeck); + this(editorType0, editDeckName, "", null, showMainDeck,null); } public FDeckEditor(EditorType editorType0, Deck newDeck, boolean showMainDeck) { - this(editorType0, "", "", newDeck, showMainDeck); + this(editorType0, "", "", newDeck, showMainDeck,null); } - private FDeckEditor(EditorType editorType0, String editDeckName, String editDeckPath, Deck newDeck, boolean showMainDeck) { - super(getPages(editorType0)); + private FDeckEditor(EditorType editorType0, String editDeckName, String editDeckPath, Deck newDeck, boolean showMainDeck,FEventHandler backButton) { + super(backButton,getPages(editorType0)); if (editorType0 == EditorType.QuestCommander) //fix saving quest commander editorType = EditorType.Quest; diff --git a/forge-gui-mobile/src/forge/screens/TabPageScreen.java b/forge-gui-mobile/src/forge/screens/TabPageScreen.java index 0b06722a946..0c369d6ac42 100644 --- a/forge-gui-mobile/src/forge/screens/TabPageScreen.java +++ b/forge-gui-mobile/src/forge/screens/TabPageScreen.java @@ -30,11 +30,16 @@ public class TabPageScreen> extends FScreen { public TabPageScreen(TabPage... tabPages0) { this(tabPages0, true); } + public TabPageScreen(FEventHandler backButton,TabPage... tabPages0) { + this(tabPages0, backButton); + } public TabPageScreen(TabPage[] tabPages0, boolean showBackButton) { this(new TabHeader<>(tabPages0, showBackButton)); } - + public TabPageScreen(TabPage[] tabPages0, FEventHandler backButton) { + this(new TabHeader<>(tabPages0, backButton)); + } public TabPageScreen(TabHeader tabHeader0) { super(tabHeader0); tabHeader = tabHeader0; @@ -198,7 +203,25 @@ public class TabPageScreen> extends FScreen { scroller.add(tabPage.tab); } } + public TabHeader(TabPage[] tabPages0, FEventHandler backButton) { + tabPages = tabPages0; + if(backButton==null) { + btnBack = add(new FLabel.Builder().icon(new BackIcon(BACK_BUTTON_WIDTH, BACK_BUTTON_WIDTH)).pressedColor(BTN_PRESSED_COLOR).align(Align.center).command(new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + Forge.back(); + } + }).build()); + } + else + { + btnBack = add(new FLabel.Builder().icon(new BackIcon(BACK_BUTTON_WIDTH, BACK_BUTTON_WIDTH)).pressedColor(BTN_PRESSED_COLOR).align(Align.center).command(backButton).build()); + } + for (TabPage tabPage : tabPages) { + scroller.add(tabPage.tab); + } + } protected boolean showBackButtonInLandscapeMode() { return btnBack != null; } diff --git a/pom.xml b/pom.xml index 4c5f4f24b54..b698310c92a 100644 --- a/pom.xml +++ b/pom.xml @@ -59,13 +59,13 @@ forge-game forge-ai forge-gui - forge-gui-desktop forge-gui-mobile + forge-adventure forge-gui-mobile-dev forge-gui-android forge-gui-ios + forge-gui-desktop forge-lda - forge-adventure