From e4ec3f6aa92ee40148f7fc9b6cbb0d9be9de3296 Mon Sep 17 00:00:00 2001 From: "Simon M." Date: Sun, 15 Dec 2024 01:57:05 +0200 Subject: [PATCH 1/8] [1] --- .../screens/newgamescreen/GameOptionsTable.kt | 106 ++++++++++-------- .../screens/newgamescreen/ModCheckboxTable.kt | 10 +- .../ui/screens/newgamescreen/NewGameScreen.kt | 4 +- 3 files changed, 62 insertions(+), 58 deletions(-) diff --git a/core/src/com/unciv/ui/screens/newgamescreen/GameOptionsTable.kt b/core/src/com/unciv/ui/screens/newgamescreen/GameOptionsTable.kt index 0fd89ff4a25ea..1f27c6c138fbb 100644 --- a/core/src/com/unciv/ui/screens/newgamescreen/GameOptionsTable.kt +++ b/core/src/com/unciv/ui/screens/newgamescreen/GameOptionsTable.kt @@ -30,6 +30,7 @@ import com.unciv.ui.components.widgets.AutoScrollPane import com.unciv.ui.components.widgets.ExpanderTab import com.unciv.ui.components.widgets.TranslatedSelectBox import com.unciv.ui.components.widgets.UncivSlider +import com.unciv.ui.components.widgets.TabbedPager import com.unciv.ui.images.ImageGetter import com.unciv.ui.popups.Popup import com.unciv.ui.screens.basescreen.BaseScreen @@ -44,6 +45,7 @@ class GameOptionsTable( ) : Table(BaseScreen.skin) { private var gameParameters = previousScreen.gameSetupInfo.gameParameters private var ruleset = previousScreen.ruleset + private val tabs: TabbedPager internal var locked = false private var baseRulesetHash = gameParameters.baseRuleset.hashCode() @@ -67,7 +69,11 @@ class GameOptionsTable( background = BaseScreen.skinStrings.getUiBackground("NewGameScreen/GameOptionsTable", tintColor = BaseScreen.skinStrings.skinConfig.clearColor) top() defaults().pad(5f) - update() + tabs = TabbedPager( + // These ought to be updated + this.width, this.width, 0f, previousScreen.stage.height, + headerFontSize = 21, backgroundColor = Color.CLEAR, capacity = 3 + ) } fun update() { @@ -81,27 +87,39 @@ class GameOptionsTable( modCheckboxes.setBaseRuleset(gameParameters.baseRuleset) } + add(tabs).grow() + tabs.addPage("Basic", basicTab()) + tabs.addPage("Advanced", advancedTab()) + tabs.addPage("Mods", modsTab()) + + tabs.selectPage(0) // Basic + + pack() + } + + private fun basicTab(): Table = Table().apply { + pad(10f) + defaults().pad(5f) + + addBaseRulesetSelectBox() + addDifficultySelectBox() + addGameSpeedSelectBox() + addEraSelectBox() + // align left and right edges with other SelectBoxes but allow independent dropdown width add(Table().apply { - defaults().pad(5f) - addBaseRulesetSelectBox() - addDifficultySelectBox() - addGameSpeedSelectBox() - addEraSelectBox() - // align left and right edges with other SelectBoxes but allow independent dropdown width - add(Table().apply { - val turnSlider = addMaxTurnsSlider() - if (turnSlider != null) - add(turnSlider).padTop(10f).row() - if (gameParameters.randomNumberOfPlayers) { - addMinMaxPlayersSliders() - } - if (gameParameters.randomNumberOfCityStates) { - addMinMaxCityStatesSliders() - } else { - addCityStatesSlider() - } - }).colspan(2).fillX().row() - }).row() + val turnSlider = addMaxTurnsSlider() + if (turnSlider != null) + add(turnSlider).padTop(10f).row() + if (gameParameters.randomNumberOfPlayers) { + addMinMaxPlayersSliders() + } + if (gameParameters.randomNumberOfCityStates) { + addMinMaxCityStatesSliders() + } else { + addCityStatesSlider() + } + }).colspan(2).fillX().row() + addVictoryTypeCheckboxes() val checkboxTable = Table().apply { defaults().left().pad(2.5f) } @@ -109,33 +127,27 @@ class GameOptionsTable( if (gameParameters.isOnlineMultiplayer) checkboxTable.addAnyoneCanSpectateCheckbox() add(checkboxTable).center().row() + } - val expander = ExpanderTab( - "Advanced Settings", - startsOutOpened = gameParameters.enableRandomNationsPool, - persistenceID = "GameOptionsTable.Advanced" - ) { - it.defaults().pad(5f, 0f) - it.addNoCityRazingCheckbox() - it.addNoBarbariansCheckbox() - it.addRagingBarbariansCheckbox() - it.addOneCityChallengeCheckbox() - it.addNuclearWeaponsCheckbox() - it.addEnableEspionageCheckbox() - it.addNoStartBiasCheckbox() - it.addRandomPlayersCheckbox() - it.addRandomCityStatesCheckbox() - it.addRandomNationsPoolCheckbox() - if (gameParameters.enableRandomNationsPool) { - it.addNationsSelectTextButton() - } - } - add(expander).pad(10f).row() + private fun advancedTab(): Table = Table().apply { + pad(10f) + defaults().pad(5f) - if (!isPortrait) - add(modCheckboxes).padTop(0f).row() + addNoCityRazingCheckbox() + addNoBarbariansCheckbox() + addRagingBarbariansCheckbox() + addOneCityChallengeCheckbox() + addNuclearWeaponsCheckbox() + addEnableEspionageCheckbox() + addNoStartBiasCheckbox() + addRandomPlayersCheckbox() + addRandomCityStatesCheckbox() + addRandomNationsPoolCheckbox() + addNationsSelectTextButton() + } - pack() + private fun modsTab(): Table = Table().apply { + if (!isPortrait) add(modCheckboxes).row() } private fun Table.addCheckbox( @@ -147,7 +159,7 @@ class GameOptionsTable( val checkbox = text.toCheckBox(initialState) { onChange(it) } checkbox.isDisabled = lockable && locked checkbox.align(Align.left) - add(checkbox).colspan(2).row() + add(checkbox).colspan(2).left().row() return checkbox } @@ -417,7 +429,7 @@ class GameOptionsTable( { gameParameters.startingEra = it; null } } - private fun addVictoryTypeCheckboxes() { + private fun Table.addVictoryTypeCheckboxes() { add("{Victory Conditions}:".toLabel()).colspan(2).row() // Create a checkbox for each VictoryType existing diff --git a/core/src/com/unciv/ui/screens/newgamescreen/ModCheckboxTable.kt b/core/src/com/unciv/ui/screens/newgamescreen/ModCheckboxTable.kt index cb6594d077868..0dd1d5bf9dc45 100644 --- a/core/src/com/unciv/ui/screens/newgamescreen/ModCheckboxTable.kt +++ b/core/src/com/unciv/ui/screens/newgamescreen/ModCheckboxTable.kt @@ -86,7 +86,7 @@ class ModCheckboxTable( baseRuleset = newBaseRuleset savedModcheckResult = null clear() - mods.clear() // We'll regenerate this from checked widgets + mods.clear() // We'll regenerate this from checked widgets val compatibleMods = modWidgets .filter { ModCompatibility.meetsBaseRequirements(it.mod, baseRuleset) } @@ -95,15 +95,9 @@ class ModCheckboxTable( for (mod in compatibleMods) { if (mod.widget.isChecked) mods += mod.mod.name + add(mod.widget).row() } - add(ExpanderTab("Extension mods", persistenceID = "NewGameExpansionMods") { - it.defaults().pad(5f,0f) - for (mod in compatibleMods) { - it.add(mod.widget).row() - } - }).pad(expanderPadOther).padTop(expanderPadTop).growX().row() - disableIncompatibleMods() Concurrency.run { complexModCheckReturnsErrors() } diff --git a/core/src/com/unciv/ui/screens/newgamescreen/NewGameScreen.kt b/core/src/com/unciv/ui/screens/newgamescreen/NewGameScreen.kt index e4090b177c6c2..ab8336b45976a 100644 --- a/core/src/com/unciv/ui/screens/newgamescreen/NewGameScreen.kt +++ b/core/src/com/unciv/ui/screens/newgamescreen/NewGameScreen.kt @@ -231,9 +231,7 @@ class NewGameScreen( topTable.add("Civilizations".toLabel(fontSize = Constants.headingFontSize)).pad(20f,0f) topTable.addSeparator(Color.CLEAR, height = 1f) - topTable.add(ScrollPane(newGameOptionsTable) - .apply { setOverscroll(false, false) }) - .width(stage.width / 3).top() + topTable.add(newGameOptionsTable).width(stage.width / 3).top() topTable.addSeparatorVertical(Color.CLEAR, 1f) topTable.add(ScrollPane(mapOptionsTable) .apply { setOverscroll(false, false) }) From 45aff09185b0acdd1cbebaad021145c511921f78 Mon Sep 17 00:00:00 2001 From: "Simon M." Date: Sun, 15 Dec 2024 02:00:28 +0200 Subject: [PATCH 2/8] [1] fix --- .../com/unciv/ui/screens/newgamescreen/GameOptionsTable.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/com/unciv/ui/screens/newgamescreen/GameOptionsTable.kt b/core/src/com/unciv/ui/screens/newgamescreen/GameOptionsTable.kt index 1f27c6c138fbb..e9e175070c444 100644 --- a/core/src/com/unciv/ui/screens/newgamescreen/GameOptionsTable.kt +++ b/core/src/com/unciv/ui/screens/newgamescreen/GameOptionsTable.kt @@ -74,6 +74,9 @@ class GameOptionsTable( this.width, this.width, 0f, previousScreen.stage.height, headerFontSize = 21, backgroundColor = Color.CLEAR, capacity = 3 ) + tabs.addPage("Basic", basicTab()) + tabs.addPage("Advanced", advancedTab()) + tabs.addPage("Mods", modsTab()) } fun update() { @@ -88,9 +91,6 @@ class GameOptionsTable( } add(tabs).grow() - tabs.addPage("Basic", basicTab()) - tabs.addPage("Advanced", advancedTab()) - tabs.addPage("Mods", modsTab()) tabs.selectPage(0) // Basic From 50cc30242ff0e8df540f081ff4dbf1d59d9c7c8f Mon Sep 17 00:00:00 2001 From: "Simon M." Date: Sun, 15 Dec 2024 05:14:27 +0200 Subject: [PATCH 3/8] [2] --- .../com/unciv/ui/screens/newgamescreen/MapOptionsTable.kt | 6 +++++- .../unciv/ui/screens/newgamescreen/MapParametersTable.kt | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/core/src/com/unciv/ui/screens/newgamescreen/MapOptionsTable.kt b/core/src/com/unciv/ui/screens/newgamescreen/MapOptionsTable.kt index 727d3b76748b1..84e010dcea961 100644 --- a/core/src/com/unciv/ui/screens/newgamescreen/MapOptionsTable.kt +++ b/core/src/com/unciv/ui/screens/newgamescreen/MapOptionsTable.kt @@ -74,8 +74,12 @@ class MapOptionsTable(private val newGameScreen: NewGameScreen) : Table() { internal val mapTypeSelectBox: TranslatedSelectBox init { + pad(10f) //defaults().pad(5f) - each nested table having the same can give 'stairs' effects, // better control directly. Besides, the first Labels/Buttons should have 10f to look nice + // + // re ↑: after some reorganisation, padding the parent container works again + // and is the easiest alignment solution background = BaseScreen.skinStrings.getUiBackground("NewGameScreen/MapOptionsTable", tintColor = BaseScreen.skinStrings.skinConfig.clearColor) val mapTypes = arrayListOf(MapGeneratedMainType.generated, MapGeneratedMainType.randomGenerated) @@ -123,7 +127,7 @@ class MapOptionsTable(private val newGameScreen: NewGameScreen) : Table() { val mapTypeSelectWrapper = Table() // wrap to center-align Label and SelectBox easier mapTypeSelectWrapper.add("{Map Type}:".toLabel()).left().expandX() mapTypeSelectWrapper.add(mapTypeSelectBox).right() - add(mapTypeSelectWrapper).pad(10f).fillX().row() + add(mapTypeSelectWrapper).padBottom(Constants.defaultFontSize * 1.5f).fillX().row() add(mapTypeSpecificTable).row() } diff --git a/core/src/com/unciv/ui/screens/newgamescreen/MapParametersTable.kt b/core/src/com/unciv/ui/screens/newgamescreen/MapParametersTable.kt index a657c8180c9e8..2e969336e8896 100644 --- a/core/src/com/unciv/ui/screens/newgamescreen/MapParametersTable.kt +++ b/core/src/com/unciv/ui/screens/newgamescreen/MapParametersTable.kt @@ -81,7 +81,7 @@ class MapParametersTable( clear() skin = BaseScreen.skin - defaults().pad(5f, 5f) + defaults().padTop(10f) if (mapGeneratedMainType == MapGeneratedMainType.randomGenerated) { val prompt = "Which options should be available to the random selection?" val width = (previousScreen as? NewGameScreen)?.getColumnWidth() ?: 200f From cf78d5febd964faf86932ad6287734eac3332378 Mon Sep 17 00:00:00 2001 From: "Simon M." Date: Fri, 20 Dec 2024 17:12:20 +0200 Subject: [PATCH 4/8] (rebase + fix conflicts) --- android/assets/Skin.atlas | 54 +++- android/assets/Skin.json | 265 +++++++++++++----- android/assets/Skin.png | Bin 5795 -> 6063 bytes core/src/com/unciv/models/skins/SkinConfig.kt | 4 +- .../src/com/unciv/models/skins/SkinStrings.kt | 4 + .../unciv/ui/components/SmallButtonStyle.kt | 8 +- .../com/unciv/ui/components/UncivTooltip.kt | 2 +- .../extensions/Scene2dExtensions.kt | 39 ++- .../com/unciv/ui/components/fonts/Fonts.kt | 8 + .../ui/components/widgets/ExpanderTab.kt | 2 +- .../ui/components/widgets/LanguageTable.kt | 4 +- .../ui/components/widgets/TabbedPager.kt | 29 +- .../ui/components/widgets/UncivSlider.kt | 81 +++--- .../src/com/unciv/ui/images/IconTextButton.kt | 4 +- core/src/com/unciv/ui/popups/Popup.kt | 4 +- .../unciv/ui/popups/options/AdvancedTab.kt | 13 +- .../unciv/ui/popups/options/AutomationTab.kt | 15 +- .../com/unciv/ui/popups/options/DebugTab.kt | 15 +- .../com/unciv/ui/popups/options/DisplayTab.kt | 60 ++-- .../unciv/ui/popups/options/GameplayTab.kt | 15 +- .../unciv/ui/popups/options/OptionsPopup.kt | 41 ++- .../com/unciv/ui/popups/options/SoundTab.kt | 13 +- .../unciv/ui/screens/basescreen/BaseScreen.kt | 21 +- .../cityscreen/CitizenManagementTable.kt | 4 +- .../cityscreen/CityConstructionsTable.kt | 2 +- .../screens/cityscreen/CityScreenTileTable.kt | 2 +- .../cityscreen/ConstructionInfoTable.kt | 2 +- .../screens/cityscreen/DetailedStatsPopup.kt | 2 +- .../diplomacyscreen/DiplomacyScreen.kt | 2 +- .../screens/mainmenuscreen/MainMenuScreen.kt | 30 +- .../mapeditorscreen/MapEditorToolsDrawer.kt | 2 +- .../mapeditorscreen/tabs/MapEditorEditTab.kt | 4 +- .../tabs/MapEditorOptionsTab.kt | 7 +- .../mapeditorscreen/tabs/MapEditorViewTab.kt | 5 +- .../screens/newgamescreen/GameOptionsTable.kt | 9 +- .../newgamescreen/MapParametersTable.kt | 6 +- .../newgamescreen/PlayerPickerTable.kt | 2 +- .../overviewscreen/ReligionOverviewTab.kt | 2 +- .../overviewscreen/ResourcesOverviewTab.kt | 2 +- .../overviewscreen/StatsOverviewTab.kt | 6 +- .../screens/overviewscreen/UnitSupplyTable.kt | 2 +- .../victoryscreen/VictoryScreenReplay.kt | 3 +- .../worldscreen/NotificationsScroll.kt | 2 +- .../ui/screens/worldscreen/WorldScreen.kt | 2 +- .../worldscreen/bottombar/TileInfoTable.kt | 2 +- .../mainmenu/WorldScreenMusicPopup.kt | 4 +- .../worldscreen/topbar/WorldScreenTopBar.kt | 2 +- .../ui/screens/worldscreen/unit/UnitTable.kt | 2 +- .../worldscreen/worldmap/OverlayButtonData.kt | 2 +- docs/Modders/Creating-a-UI-skin.md | 3 +- 50 files changed, 501 insertions(+), 313 deletions(-) diff --git a/android/assets/Skin.atlas b/android/assets/Skin.atlas index d7cb473130edb..a8c5f086b310e 100644 --- a/android/assets/Skin.atlas +++ b/android/assets/Skin.atlas @@ -6,7 +6,7 @@ filter: Linear, Linear repeat: none Skins/Minimal/checkbox rotate: false - xy: 291, 23 + xy: 291, 29 size: 31, 31 split: 0, 0, 0, 0 orig: 31, 31 @@ -14,15 +14,23 @@ Skins/Minimal/checkbox index: -1 Skins/Minimal/checkbox-pressed rotate: false - xy: 252, 23 + xy: 252, 29 size: 31, 31 split: 0, 0, 0, 0 orig: 31, 31 offset: 0, 0 index: -1 +Skins/Minimal/layer-container + rotate: false + xy: 64, 4 + size: 10, 10 + split: 3, 3, 3, 3 + orig: 10, 10 + offset: 0, 0 + index: -1 Skins/Minimal/rectangleWithOutline rotate: false - xy: 64, 5 + xy: 362, 37 size: 3, 3 split: 0, 0, 0, 0 orig: 3, 3 @@ -30,7 +38,7 @@ Skins/Minimal/rectangleWithOutline index: -1 Skins/Minimal/roundedEdgeRectangle rotate: false - xy: 4, 4 + xy: 4, 10 size: 52, 50 split: 19, 20, 19, 21 pad: 12, 13, 7, 7 @@ -39,7 +47,7 @@ Skins/Minimal/roundedEdgeRectangle index: -1 Skins/Minimal/roundedEdgeRectangle-mid rotate: false - xy: 110, 16 + xy: 110, 22 size: 38, 38 split: 17, 17, 15, 15 pad: 17, 17, -1, -1 @@ -48,7 +56,7 @@ Skins/Minimal/roundedEdgeRectangle-mid index: -1 Skins/Minimal/roundedEdgeRectangle-mid-border rotate: false - xy: 64, 16 + xy: 64, 22 size: 38, 38 split: 18, 18, 18, 18 orig: 38, 38 @@ -56,7 +64,7 @@ Skins/Minimal/roundedEdgeRectangle-mid-border index: -1 Skins/Minimal/roundedEdgeRectangle-small rotate: false - xy: 330, 30 + xy: 330, 36 size: 24, 24 split: 10, 10, 10, 10 pad: 10, 10, 2, 2 @@ -65,7 +73,7 @@ Skins/Minimal/roundedEdgeRectangle-small index: -1 Skins/Minimal/roundedTopEdgeRectangle-small rotate: false - xy: 394, 42 + xy: 394, 48 size: 24, 12 split: 10, 10, 10, 0 pad: 10, 10, -1, -1 @@ -74,7 +82,7 @@ Skins/Minimal/roundedTopEdgeRectangle-small index: -1 Skins/Minimal/roundedTopEdgeRectangle-small-border rotate: false - xy: 362, 42 + xy: 362, 48 size: 24, 12 split: 10, 10, 10, 0 orig: 24, 12 @@ -82,7 +90,7 @@ Skins/Minimal/roundedTopEdgeRectangle-small-border index: -1 Skins/Minimal/select-box rotate: false - xy: 204, 24 + xy: 204, 30 size: 40, 30 split: 7, 9, 7, 7 orig: 40, 30 @@ -90,9 +98,33 @@ Skins/Minimal/select-box index: -1 Skins/Minimal/select-box-pressed rotate: false - xy: 156, 24 + xy: 156, 30 size: 40, 30 split: 7, 9, 7, 7 orig: 40, 30 offset: 0, 0 index: -1 +Skins/Minimal/slider-bar + rotate: false + xy: 82, 11 + size: 12, 3 + split: 3, 3, 0, 0 + orig: 12, 3 + offset: 0, 0 + index: -1 +Skins/Minimal/tab + rotate: false + xy: 448, 46 + size: 14, 14 + split: 0, 0, 0, 0 + orig: 14, 14 + offset: 0, 0 + index: -1 +Skins/Minimal/tab-active + rotate: false + xy: 426, 46 + size: 14, 14 + split: 0, 0, 0, 3 + orig: 14, 14 + offset: 0, 0 + index: -1 diff --git a/android/assets/Skin.json b/android/assets/Skin.json index 912cc94ae1b19..8bbce9f41084b 100644 --- a/android/assets/Skin.json +++ b/android/assets/Skin.json @@ -5,18 +5,42 @@ "title": "Nativefont" }, "com.badlogic.gdx.graphics.Color": { - "black": { - "r": 0, - "g": 0, - "b": 0, - "a": 1 - }, - "color": { - "r": 0.2, - "g": 0.3, - "b": 0.5, - "a": 1 - }, + "base-10": {"r": 0.086, "g": 0.098, "b": 0.145}, + "base-20": {"r": 0.144, "g": 0.164, "b": 0.242}, + "base-30": {"r": 0.189, "g": 0.215, "b": 0.318}, + "base-40": {"r": 0.241, "g": 0.273, "b": 0.405}, + "base-50": {"r": 0.296, "g": 0.336, "b": 0.498}, + "base-60": {"r": 0.354, "g": 0.403, "b": 0.596}, + "base-70": {"r": 0.444, "g": 0.489, "b": 0.669}, + "base-80": {"r": 0.549, "g": 0.586, "b": 0.732}, + "base-90": {"r": 0.658, "g": 0.686, "b": 0.797}, + "base-100": {"r": 0.769, "g": 0.788, "b": 0.863}, + + "base-10-transparent": {"r": 0.086, "g": 0.098, "b": 0.145, "a": 0.925}, + "base-20-transparent": {"r": 0.189, "g": 0.215, "b": 0.318, "a": 0.422}, + "base-30-transparent": {"r": 0.241, "g": 0.273, "b": 0.405, "a": 0.422}, + "base-40-transparent": {"r": 0.241, "g": 0.273, "b": 0.405, "a": 0.925}, + "base-50-transparent": {"r": 0.296, "g": 0.336, "b": 0.498, "a": 0.925}, + "base-60-transparent": {"r": 0.354, "g": 0.403, "b": 0.596, "a": 0.925}, + "base-70-transparent": {"r": 0.444, "g": 0.489, "b": 0.669, "a": 0.925}, + "base-80-transparent": {"r": 0.549, "g": 0.586, "b": 0.732, "a": 0.925}, + "base-90-transparent": {"r": 0.658, "g": 0.686, "b": 0.797, "a": 0.925}, + "base-100-transparent": {"r": 0.769, "g": 0.788, "b": 0.863, "a": 0.925}, + + "negative-40": { "hex": "#722d38" }, + "negative-50": { "hex": "#833440" }, + "negative-60": { "hex": "#943b48" }, + + "primary-50": { "hex": "#833440" }, + "primary-60": { "hex": "#943b48" }, + "primary-40": { "hex": "#722d38" }, + + "text-primary": { "hex": "#f4f4f4ff" }, + "text-subdued": {"r": 0.686, "g": 0.733, "b": 0.918}, + "text-interactive": {"r": 1, "g": 1, "b": 1}, + + "black": {"r": 0.024, "g": 0.027, "b": 0.035}, + "gray": { "r": 0.5, "g": 0.5, @@ -59,12 +83,6 @@ "b": 1, "a": 1 }, - "positive": { - "r": 0.12156863, - "g": 0.49411765, - "b": 0.21960784, - "a": 1 - }, "negative": { "r": 0.5529412, "g": 0.03137255, @@ -139,45 +157,124 @@ } }, "com.badlogic.gdx.scenes.scene2d.ui.Skin$TintedDrawable": { - "button-c": { + "layer1-container": { + "name": "layer-container", + "color": "base-20" + }, + "layer1-transparent-container": { + "name": "layer-container", + "color": "base-20-transparent" + }, + "layer2-container": { + "name": "layer-container", + "color": "base-30" + }, + "layer2-transparent-container": { + "name": "layer-container", + "color": "base-30-transparent" + }, + + "button": { "name": "RoundedEdgeRectangle", - "color": "color" + "color": "base-50" }, - "button-p": { + "button-down": { "name": "RoundedEdgeRectangle", - "color": "pressed" + "color": "base-40" }, - "button-h": { + "button-hover": { "name": "RoundedEdgeRectangle", - "color": "highlight" + "color": "base-60" }, "button-disabled": { "name": "RoundedEdgeRectangle", - "color": "disabled" + "color": "base-20" + }, + + "button-main-menu": { + "name": "RoundedEdgeRectangle", + "color": "base-50-transparent" + }, + "button-main-menu-down": { + "name": "RoundedEdgeRectangle", + "color": "base-40-transparent" + }, + "button-main-menu-hover": { + "name": "RoundedEdgeRectangle", + "color": "base-60-transparent" }, - "button-positive": { + "button-main-menu-disabled": { "name": "RoundedEdgeRectangle", - "color": "positive" + "color": "base-20-transparent" }, + + "button-tab": { + "name": "tab", + "color": "base-40" + }, + "button-tab-down": { + "name": "tab", + "color": "base-30" + }, + "button-tab-hover": { + "name": "tab", + "color": "base-50" + }, + "button-tab-disabled": { + "name": "tab", + "color": "base-20" + }, + + "button-tab-active": { + "name": "tab-active", + "color": "base-50" + }, + "button-tab-active-down": { + "name": "tab-active", + "color": "base-40" + }, + "button-tab-active-hover": { + "name": "tab-active", + "color": "base-60" + }, + "button-tab-active-disabled": { + "name": "tab-active", + "color": "base-20" + }, + + "button-primary": { + "name": "RoundedEdgeRectangle", + "color": "primary-50" + }, + "button-primary-down": { + "name": "RoundedEdgeRectangle", + "color": "primary-40" + }, + "button-primary-hover": { + "name": "RoundedEdgeRectangle", + "color": "primary-60" + }, + "button-negative": { "name": "RoundedEdgeRectangle", - "color": "negative" + "color": "negative-50" }, "button-negative-pressed": { "name": "RoundedEdgeRectangle", - "color": "negative-selected" + "color": "negative-40" }, "button-negative-hover": { "name": "RoundedEdgeRectangle", - "color": "negative-highlight" + "color": "negative-60" }, + "checkbox-c": { "name": "Checkbox", - "color": "color" + "color": "base-50" }, "checkbox-pressed-c": { "name": "Checkbox-pressed", - "color": "color" + "color": "base-50" }, "checkbox-disabled-c": { "name": "Checkbox", @@ -189,15 +286,15 @@ }, "list-c": { "name": "RectangleWithOutline", - "color": "color" + "color": "base-60" }, "scrollbar-c": { "name": "Scrollbar", - "color": "color" + "color": "base-60" }, "select-box-c": { "name": "Select-box", - "color": "color" + "color": "base-60" }, "select-box-disabled": { "name": "Select-box", @@ -205,7 +302,7 @@ }, "select-box-pressed-c": { "name": "Select-box-pressed", - "color": "color" + "color": "base-60" }, "select-box-h": { "name": "Select-box", @@ -215,41 +312,47 @@ "name": "Scrollbar", "color": "default-clear" }, - "slider-knob-c": { - "name": "Circle", - "color": "color" + + "slider-knob": { + "name": "slider-knob", + "color": "base-50" }, - "slider-horizontal-s": { - "name": "Rectangle", - "color": "selection" + "slider-horizontal-bar-filled": { + "name": "slider-bar", + "color": "base-50" + }, + "slider-horizontal-bar-unfilled": { + "name": "slider-bar", + "color": "base-70" }, "slider-vertical-s": { "name": "Rectangle", "color": "selection" }, - "slider-knob-h": { - "name": "Circle", - "color": "highlight" + "slider-knob-hover": { + "name": "slider-knob", + "color": "base-60" }, - "slider-horizontal-p": { - "name": "Rectangle", - "color": "pressed" + "slider-knob-down": { + "name": "slider-knob", + "color": "base-40" }, "slider-vertical-p": { "name": "Rectangle", "color": "pressed" }, + "splitpane-horizontal-c": { "name": "RectangleWithOutline", - "color": "color" + "color": "base-60" }, "splitpane-vertical-c": { "name": "RectangleWithOutline", - "color": "color" + "color": "base-60" }, "textfield-c": { "name": "RoundedEdgeRectangle", - "color": "color" + "color": "base-60" }, "selection": { "name": "Rectangle", @@ -262,9 +365,24 @@ }, "com.badlogic.gdx.scenes.scene2d.ui.Button$ButtonStyle": { "default": { - "up": "button-c", - "down": "button-p", - "over": "button-h" + "up": "button", + "down": "button-down", + "over": "button-hover" + }, + "main-menu": { + "up": "button-main-menu", + "down": "button-main-menu-down", + "over": "button-main-menu-hover" + }, + "tab": { + "up": "button-tab", + "down": "button-tab-down", + "over": "button-tab-hover" + }, + "tab-active": { + "up": "button-tab-active", + "down": "button-tab-active-down", + "over": "button-tab-active-hover" } }, "com.badlogic.gdx.scenes.scene2d.ui.CheckBox$CheckBoxStyle": { @@ -274,7 +392,7 @@ "checkboxOff": "checkbox-c", "checkboxOffDisabled": "checkbox-disabled-c", "font": "button", - "fontColor": "color", + "fontColor": "text-primary", "downFontColor": "pressed", "overFontColor": "highlight", "disabledFontColor": "gray" @@ -283,7 +401,7 @@ "com.badlogic.gdx.scenes.scene2d.ui.Label$LabelStyle": { "default": { "font": "font", - "fontColor": "color" + "fontColor": "text-primary" } }, "com.badlogic.gdx.scenes.scene2d.ui.List$ListStyle": { @@ -320,17 +438,18 @@ }, "com.badlogic.gdx.scenes.scene2d.ui.Slider$SliderStyle": { "default-horizontal": { - "knobOver": "slider-knob-h", - "knobDown": "slider-knob-h", - "background": "slider-horizontal-p", - "knob": "slider-knob-c", - "knobBefore": "slider-horizontal-s" + "knobOver": "slider-knob-hover", + "knobDown": "slider-knob-down", + "background": "slider-bar", + "knob": "slider-knob", + "knobAfter": "slider-horizontal-bar-unfilled", + "knobBefore": "slider-horizontal-bar-filled" }, "default-vertical": { - "knobOver": "slider-knob-h", - "knobDown": "slider-knob-h", + "knobOver": "slider-knob-hover", + "knobDown": "slider-knob-down", "background": "slider-vertical-p", - "knob": "slider-knob-c", + "knob": "slider-knob", "knobBefore": "slider-vertical-s" } }, @@ -348,24 +467,24 @@ "fontColor": "white", "downFontColor": "white", "overFontColor": "dark-gray", - "up": "button-c", - "down": "button-p", - "over": "button-h" + "up": "button", + "down": "button-down", + "over": "button-hover" }, "positive": { "font": "button", "fontColor": "white", "downFontColor": "white", "overFontColor": "dark-gray", - "up": "button-positive", - "down": "button-p", - "over": "button-h" + "up": "button-primary", + "down": "button-primary-down", + "over": "button-primary-hover" }, "negative": { "font": "button", - "fontColor": "white", - "downFontColor": "white", - "overFontColor": "white", + "fontColor": "text-primary", + "downFontColor": "text-primary", + "overFontColor": "text-primary", "up": "button-negative", "down": "button-negative-pressed", "over": "button-negative-hover" diff --git a/android/assets/Skin.png b/android/assets/Skin.png index 8bc279ea4a346d141fa1460d3b97df958eeb72e3..e45594f3fb53a1c822ae0504e8e0fd73599cfa8a 100644 GIT binary patch literal 6063 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 CbH&^M literal 5795 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 UHqrK~=N`1Cy0%*BUF(Sd0ozhRvj6}9 diff --git a/core/src/com/unciv/models/skins/SkinConfig.kt b/core/src/com/unciv/models/skins/SkinConfig.kt index 9fca0333ae005..b56c32e783e64 100644 --- a/core/src/com/unciv/models/skins/SkinConfig.kt +++ b/core/src/com/unciv/models/skins/SkinConfig.kt @@ -4,8 +4,8 @@ import com.badlogic.gdx.graphics.Color import com.unciv.Constants class SkinConfig(initialCapacity: Int) { - var baseColor: Color = Color(0x004085bf) - var clearColor: Color = Color(0x000033ff) + var baseColor: Color = Color(0x2d3e84ff) + var clearColor: Color = Color(0x040a1dff) var defaultVariantTint: Color? = null var fallbackSkin: String? = Constants.defaultFallbackSkin var skinVariants: HashMap = HashMap(initialCapacity) diff --git a/core/src/com/unciv/models/skins/SkinStrings.kt b/core/src/com/unciv/models/skins/SkinStrings.kt index 6640320e66322..95c1ee5ed5a3f 100644 --- a/core/src/com/unciv/models/skins/SkinStrings.kt +++ b/core/src/com/unciv/models/skins/SkinStrings.kt @@ -23,6 +23,10 @@ class SkinStrings(skin: String = UncivGame.Current.settings.skin) { val selectBoxPressedShape = "select-box-pressed" val checkboxShape = "checkbox" val checkboxPressedShape = "checkbox-pressed" + val sliderBarShape = "slider-bar" + val layerContainerShape = "layer-container" + val tabShape = "tab" + val tabActiveShape = "tab-active" /** * Gets either a drawable which was defined inside skinConfig for the given path or the drawable diff --git a/core/src/com/unciv/ui/components/SmallButtonStyle.kt b/core/src/com/unciv/ui/components/SmallButtonStyle.kt index d0974e1be304c..fc0de35ad9379 100644 --- a/core/src/com/unciv/ui/components/SmallButtonStyle.kt +++ b/core/src/com/unciv/ui/components/SmallButtonStyle.kt @@ -21,10 +21,10 @@ class SmallButtonStyle : TextButton.TextButtonStyle(BaseScreen.skin[TextButton.T } init { - val upColor = BaseScreen.skin.getColor("color") - val downColor = BaseScreen.skin.getColor("pressed") - val overColor = BaseScreen.skin.getColor("highlight") - val disabledColor = BaseScreen.skin.getColor("disabled") + val upColor = BaseScreen.skin.getColor("base-40") + val downColor = BaseScreen.skin.getColor("base-60") + val overColor = BaseScreen.skin.getColor("base-80") + val disabledColor = BaseScreen.skin.getColor("base-40") // UiElementDocsWriter inspects source, which is why this isn't prettified better val shape = BaseScreen.run { // Let's use _one_ skinnable background lookup but with different tints diff --git a/core/src/com/unciv/ui/components/UncivTooltip.kt b/core/src/com/unciv/ui/components/UncivTooltip.kt index b27ad178d5d07..0054aeaa214e8 100644 --- a/core/src/com/unciv/ui/components/UncivTooltip.kt +++ b/core/src/com/unciv/ui/components/UncivTooltip.kt @@ -243,7 +243,7 @@ class UncivTooltip ( if (!(always || GUI.keyboardAvailable) || text.isEmpty()) return - val labelColor = BaseScreen.skinStrings.skinConfig.baseColor + val labelColor = BaseScreen.skin.getColor("base-40") val label = if (hideIcons) text.toLabel(labelColor, fontSize = 38, hideIcons = true) else ColorMarkupLabel(text, labelColor, fontSize = 38) label.setAlignment(Align.center) diff --git a/core/src/com/unciv/ui/components/extensions/Scene2dExtensions.kt b/core/src/com/unciv/ui/components/extensions/Scene2dExtensions.kt index b496b338a135d..32c924b772f69 100644 --- a/core/src/com/unciv/ui/components/extensions/Scene2dExtensions.kt +++ b/core/src/com/unciv/ui/components/extensions/Scene2dExtensions.kt @@ -199,14 +199,14 @@ fun Group.addBorderAllowOpacity(size: Float, color: Color): Group { /** get background Image for a new separator */ private fun getSeparatorImage(color: Color) = Image(ImageGetter.getWhiteDotDrawable().tint( - if (color.a != 0f) color else BaseScreen.skin.getColor("color") //0x334d80 + if (color.a != 0f) color else BaseScreen.skin.getColor("base-40") //0x334d80 )) /** * Create a horizontal separator as an empty Container with a colored background. * @param colSpan Optionally override [colspan][Cell.colspan] which defaults to the current column count. */ -fun Table.addSeparator(color: Color = BaseScreen.skin.getColor("color"), colSpan: Int = 0, height: Float = 1f): Cell { +fun Table.addSeparator(color: Color = BaseScreen.skin.getColor("base-40"), colSpan: Int = 0, height: Float = 1f): Cell { if (!cells.isEmpty && !cells.last().isEndRow) row() val separator = getSeparatorImage(color) val cell = add(separator) @@ -225,6 +225,21 @@ fun Table.addSeparatorVertical(color: Color = Color.WHITE, width: Float = 2f): C return add(getSeparatorImage(color)).width(width).fillY() } +/** + * Sets the background Drawable of a Table based on its layer in the hierarchy. + * 0 is the true background and will have no effect if used. + * For convenience, layer 1 is default. + */ +fun Table.setLayer(layer: Int = 1, transparent: Boolean = false): Table { + if (layer == 0) return this + setBackground(BaseScreen.skin.getDrawable(when (layer) { + 1 -> if (!transparent) "layer1-container" else "layer1-transparent-container" + 2 -> if (!transparent) "layer2-container" else "layer2-transparent-container" + else -> "layer1-container" + })) + return this +} + /** Alternative to [Table].[add][Table] that returns the Table instead of the new Cell to allow a different way of chaining */ fun Table.addCell(actor: T): Table { add(actor) @@ -277,7 +292,7 @@ fun String.toImageButton(iconSize: Float, circleSize: Float, circleColor: Color, fun getCloseButton( size: Float = 50f, iconSize: Float = size - 20f, - circleColor: Color = BaseScreen.skinStrings.skinConfig.baseColor, + circleColor: Color = BaseScreen.skin.getColor("base-40"), overColor: Color = Color.RED, action: () -> Unit ): Group { @@ -293,24 +308,36 @@ fun String.toLabel() = Label(this.tr(), BaseScreen.skin) fun Int.toLabel() = this.tr().toLabel() /** Translate a [String] and make a [Label] widget from it with a specified font color and size */ -fun String.toLabel(fontColor: Color = Color.WHITE, +fun String.toLabel(fontColor: Color = BaseScreen.skin.getColor("text-primary"), fontSize: Int = Constants.defaultFontSize, alignment: Int = Align.left, hideIcons: Boolean = false): Label { + // We don't want to use setFontSize and setFontColor because they set the font, - // which means we need to rebuild the font cache which means more memory allocation. + // which means we need to rebuild the font cache which means more memory allocation. var labelStyle = BaseScreen.skin.get(Label.LabelStyle::class.java) - if (fontColor != Color.WHITE || fontSize != Constants.defaultFontSize) { // if we want the default we don't need to create another style + + // if we want the default we don't need to create another style + if ( + fontColor != BaseScreen.skin.getColor("text-primary") + || fontSize != Constants.defaultFontSize + ) { labelStyle = Label.LabelStyle(labelStyle) // clone this to another labelStyle.fontColor = fontColor if (fontSize != Constants.defaultFontSize) labelStyle.font = Fonts.font } + return Label(this.tr(hideIcons), labelStyle).apply { setFontScale(fontSize / Fonts.ORIGINAL_FONT_SIZE) setAlignment(alignment) } } +fun String.toHeadingLabel() = this.toLabel( + BaseScreen.skin.getColor("text-interactive"), + Constants.headingFontSize +) + /** * Translate a [String] and make a [CheckBox] widget from it. * @param changeAction A callback to call on change, with a boolean lambda parameter containing the current [isChecked][CheckBox.isChecked]. diff --git a/core/src/com/unciv/ui/components/fonts/Fonts.kt b/core/src/com/unciv/ui/components/fonts/Fonts.kt index c32b7fd3bc247..be35bbc97df64 100644 --- a/core/src/com/unciv/ui/components/fonts/Fonts.kt +++ b/core/src/com/unciv/ui/components/fonts/Fonts.kt @@ -5,6 +5,7 @@ import com.badlogic.gdx.graphics.g2d.BitmapFont import com.badlogic.gdx.graphics.g2d.TextureRegion import com.unciv.GUI import com.unciv.UncivGame +import com.unciv.Constants import com.unciv.ui.components.MayaCalendar import com.unciv.ui.components.extensions.getReadonlyPixmap import com.unciv.ui.components.fonts.Fonts.extractPixmapFromTextureRegion @@ -74,6 +75,13 @@ object Fonts { return ratio * fontSize.toFloat() + 2.25f } + /** + * Utility for standardised, flexible, and dynamic spacing. + * @param from The desired spacing in rem. + * @return The true spacing to add via pad() or other functions. + */ + fun rem(from: Float): Float = from * Constants.defaultFontSize.toFloat() + /** * Turn a TextureRegion into a Pixmap. * diff --git a/core/src/com/unciv/ui/components/widgets/ExpanderTab.kt b/core/src/com/unciv/ui/components/widgets/ExpanderTab.kt index ef910355ef40f..8b427396e517e 100644 --- a/core/src/com/unciv/ui/components/widgets/ExpanderTab.kt +++ b/core/src/com/unciv/ui/components/widgets/ExpanderTab.kt @@ -79,7 +79,7 @@ class ExpanderTab( header.background( BaseScreen.skinStrings.getUiBackground( "General/ExpanderTab", - tintColor = BaseScreen.skinStrings.skinConfig.baseColor + tintColor = BaseScreen.skin.getColor("base-40") ) ) if (icon != null) header.add(icon) diff --git a/core/src/com/unciv/ui/components/widgets/LanguageTable.kt b/core/src/com/unciv/ui/components/widgets/LanguageTable.kt index 4765ab872f454..753207607b39d 100644 --- a/core/src/com/unciv/ui/components/widgets/LanguageTable.kt +++ b/core/src/com/unciv/ui/components/widgets/LanguageTable.kt @@ -25,8 +25,8 @@ import java.util.Locale * @see addLanguageTables */ internal class LanguageTable(val language: String, val percentComplete: Int) : Table() { - private val baseColor = BaseScreen.skinStrings.skinConfig.baseColor - private val darkBaseColor = baseColor.darken(0.5f) + private val baseColor = BaseScreen.skin.getColor("base-40") + private val darkBaseColor = BaseScreen.skin.getColor("base-40") init{ pad(10f) diff --git a/core/src/com/unciv/ui/components/widgets/TabbedPager.kt b/core/src/com/unciv/ui/components/widgets/TabbedPager.kt index cafcd9bf801bd..4b1d9b1c9e382 100644 --- a/core/src/com/unciv/ui/components/widgets/TabbedPager.kt +++ b/core/src/com/unciv/ui/components/widgets/TabbedPager.kt @@ -24,6 +24,7 @@ import com.unciv.ui.components.extensions.isEnabled import com.unciv.ui.components.extensions.packIfNeeded import com.unciv.ui.components.extensions.pad import com.unciv.ui.components.extensions.scrollTo +import com.unciv.ui.components.fonts.Fonts import com.unciv.ui.components.input.KeyCharAndCode import com.unciv.ui.components.input.keyShortcuts import com.unciv.ui.components.input.onActivation @@ -72,8 +73,7 @@ open class TabbedPager( maximumHeight: Float = Float.MAX_VALUE, private val headerFontSize: Int = Constants.defaultFontSize, private val headerFontColor: Color = Color.WHITE, - private val highlightColor: Color = Color.BLUE, - backgroundColor: Color = BaseScreen.skinStrings.skinConfig.baseColor.darken(0.5f), + backgroundColor: Color = BaseScreen.skin.getColor("base-40"), private val headerPadding: Float = 10f, separatorColor: Color = Color.CLEAR, private val shortcutScreen: BaseScreen? = null, @@ -145,11 +145,9 @@ open class TabbedPager( val button = IconTextButton(caption, icon, pager.headerFontSize, pager.headerFontColor).apply { name = caption // enable finding pages by untranslated caption without needing our own field - if (icon != null) { - if (iconSize != 0f) - iconCell.size(iconSize) - iconCell.padRight(pager.headerPadding * 0.5f) - } + setStyle(BaseScreen.skin.get("tab", Button.ButtonStyle::class.java)) + if (icon != null) + if (iconSize != 0f) iconCell.size(iconSize) } var buttonX = 0f var buttonW = 0f @@ -307,20 +305,21 @@ open class TabbedPager( dimW = DimensionMeasurement.from(minimumWidth, maximumWidth, screenWidth) dimH = DimensionMeasurement.from(minimumHeight, maximumHeight, screenHeight) - background = BaseScreen.skinStrings.getUiBackground("General/TabbedPager", tintColor = backgroundColor) + background = BaseScreen.skinStrings.getUiBackground( + "General/TabbedPager", tintColor = backgroundColor) - header.defaults().pad(headerPadding, headerPadding * 0.5f) // Measure header height, most likely its final value removePage(addPage("Dummy")) - add(headerScroll).growX().minHeight(headerHeight) - headerDecorationRightCell = add().pad(0f) + add(headerScroll).padLeft(Fonts.rem(1f)).growX().minHeight(headerHeight) + headerDecorationRightCell = add() row() if (separatorColor != Color.CLEAR) addSeparator(separatorColor) fixedContentScrollCell = add(fixedContentScroll) - fixedContentScrollCell.colspan(2).growX().row() - add(contentScroll).colspan(2).grow().row() + fixedContentScrollCell.pad(Fonts.rem(1f)).padTop(0f).colspan(2).growX().row() + + add(contentScroll).pad(Fonts.rem(1f)).padTop(0f).colspan(2).grow().row() } //endregion @@ -369,7 +368,7 @@ open class TabbedPager( if (activePage != -1) { val page = pages[activePage] (page.content as? IPageExtensions)?.deactivated(activePage, page.caption, this) - page.button.color = Color.WHITE + page.button.style = BaseScreen.skin.get("tab", Button.ButtonStyle::class.java) fixedContentScroll.actor = null page.scrollX = contentScroll.scrollX page.scrollY = contentScroll.scrollY @@ -380,7 +379,7 @@ open class TabbedPager( if (index != -1) { val page = pages[index] - page.button.color = highlightColor + page.button.style = BaseScreen.skin.get("tab-active", Button.ButtonStyle::class.java) if (page.scrollAlign != 0) { if (Align.isCenterHorizontal(page.scrollAlign)) diff --git a/core/src/com/unciv/ui/components/widgets/UncivSlider.kt b/core/src/com/unciv/ui/components/widgets/UncivSlider.kt index 882ae1a9a16ba..8d4dcd796d53d 100644 --- a/core/src/com/unciv/ui/components/widgets/UncivSlider.kt +++ b/core/src/com/unciv/ui/components/widgets/UncivSlider.kt @@ -25,6 +25,7 @@ import com.unciv.ui.components.extensions.isShiftKeyPressed import com.unciv.ui.components.extensions.surroundWithCircle import com.unciv.ui.components.extensions.toLabel import com.unciv.ui.components.input.onClick +import com.unciv.ui.components.widgets.TabbedPager import com.unciv.ui.components.widgets.UncivSlider.Companion.formatPercent import com.unciv.ui.images.IconCircleGroup import com.unciv.ui.images.ImageGetter @@ -42,6 +43,7 @@ import kotlin.math.sign * Note: No attempt is made to distinguish sources of value changes, so the initial setting * of the value when a screen is initialized will also trigger the 'tip'. This is intentional. * + * @param label A string describing what the slider controls. * @param min Initializes [Slider.min] * @param max Initializes [Slider.max] * @param step Initializes [Slider.stepSize] @@ -54,12 +56,13 @@ import kotlin.math.sign * @param onChange Optional lambda gets called with the current value on a user change (not when setting value programmatically). */ class UncivSlider ( + text: String, min: Float, max: Float, step: Float, + initial: Float, vertical: Boolean = false, plusMinus: Boolean = true, - initial: Float, sound: UncivSound = UncivSound.Slider, private val tipType: TipType = TipType.Permanent, private val getTipText: ((Float) -> String)? = null, @@ -81,10 +84,8 @@ class UncivSlider ( } // component widgets - private val slider = Slider(min, max, step, vertical, BaseScreen.skin) - private val minusButton: IconCircleGroup? - private val plusButton: IconCircleGroup? - private val tipLabel = "".toLabel(Color.LIGHT_GRAY) + private val label = text.toLabel() + private val tipLabel = "".toLabel() private val tipContainer: Container