diff --git a/android/Images.Skin/Skin/checkbox-pressed.png b/android/Images.Skin/Skin/checkbox-pressed.png deleted file mode 100644 index b36e6d1fb4..0000000000 Binary files a/android/Images.Skin/Skin/checkbox-pressed.png and /dev/null differ diff --git a/android/Images.Skin/Skin/checkbox.png b/android/Images.Skin/Skin/checkbox.png deleted file mode 100644 index bacb9f24c4..0000000000 Binary files a/android/Images.Skin/Skin/checkbox.png and /dev/null differ diff --git a/android/Images.Skin/Skin/rectangleWithOutline.png b/android/Images.Skin/Skin/rectangleWithOutline.png deleted file mode 100644 index 0f70a8d30a..0000000000 Binary files a/android/Images.Skin/Skin/rectangleWithOutline.png and /dev/null differ diff --git a/android/Images.Skin/Skin/roundedEdgeRectangle.png b/android/Images.Skin/Skin/roundedEdgeRectangle.png deleted file mode 100644 index e7a85cf059..0000000000 Binary files a/android/Images.Skin/Skin/roundedEdgeRectangle.png and /dev/null differ diff --git a/android/Images.Skin/Skin/select-box-pressed.png b/android/Images.Skin/Skin/select-box-pressed.png deleted file mode 100644 index 77e73e8262..0000000000 Binary files a/android/Images.Skin/Skin/select-box-pressed.png and /dev/null differ diff --git a/android/Images.Skin/Skin/select-box.png b/android/Images.Skin/Skin/select-box.png deleted file mode 100644 index 1a17c0c137..0000000000 Binary files a/android/Images.Skin/Skin/select-box.png and /dev/null differ diff --git a/android/Images.Skin/Skins/Minimal/checkbox-pressed.9.png b/android/Images.Skin/Skins/Minimal/checkbox-pressed.9.png new file mode 100644 index 0000000000..14e919143e Binary files /dev/null and b/android/Images.Skin/Skins/Minimal/checkbox-pressed.9.png differ diff --git a/android/Images.Skin/Skins/Minimal/checkbox.9.png b/android/Images.Skin/Skins/Minimal/checkbox.9.png new file mode 100644 index 0000000000..9792835ccd Binary files /dev/null and b/android/Images.Skin/Skins/Minimal/checkbox.9.png differ diff --git a/android/Images.Skin/Skins/Minimal/rectangleWithOutline.9.png b/android/Images.Skin/Skins/Minimal/rectangleWithOutline.9.png new file mode 100644 index 0000000000..6251da100a Binary files /dev/null and b/android/Images.Skin/Skins/Minimal/rectangleWithOutline.9.png differ diff --git a/android/Images.Skin/Skins/Minimal/roundedEdgeRectangle.9.png b/android/Images.Skin/Skins/Minimal/roundedEdgeRectangle.9.png new file mode 100644 index 0000000000..5c92c79853 Binary files /dev/null and b/android/Images.Skin/Skins/Minimal/roundedEdgeRectangle.9.png differ diff --git a/android/Images.Skin/Skins/Minimal/select-box-pressed.9.png b/android/Images.Skin/Skins/Minimal/select-box-pressed.9.png new file mode 100644 index 0000000000..d7d4107fed Binary files /dev/null and b/android/Images.Skin/Skins/Minimal/select-box-pressed.9.png differ diff --git a/android/Images.Skin/Skins/Minimal/select-box.9.png b/android/Images.Skin/Skins/Minimal/select-box.9.png new file mode 100644 index 0000000000..caa0fcdfe0 Binary files /dev/null and b/android/Images.Skin/Skins/Minimal/select-box.9.png differ diff --git a/core/src/com/unciv/Constants.kt b/core/src/com/unciv/Constants.kt index 7a69a88c7b..40d72cc5f9 100644 --- a/core/src/com/unciv/Constants.kt +++ b/core/src/com/unciv/Constants.kt @@ -81,6 +81,7 @@ object Constants { const val dropboxMultiplayerServer = "Dropbox" const val defaultTileset = "HexaRealm" + const val defaultSkin = "Minimal" /** * Use this to determine whether a [MapUnit][com.unciv.logic.map.MapUnit]'s movement is exhausted diff --git a/core/src/com/unciv/models/metadata/GameSettings.kt b/core/src/com/unciv/models/metadata/GameSettings.kt index 827f35cd27..04bab2f862 100644 --- a/core/src/com/unciv/models/metadata/GameSettings.kt +++ b/core/src/com/unciv/models/metadata/GameSettings.kt @@ -38,6 +38,7 @@ class GameSettings { var turnsBetweenAutosaves = 1 var tileSet: String = Constants.defaultTileset + var skin: String = Constants.defaultSkin var showTutorials: Boolean = true var autoAssignCityProduction: Boolean = true var autoBuildingRoads: Boolean = true diff --git a/core/src/com/unciv/ui/images/ImageGetter.kt b/core/src/com/unciv/ui/images/ImageGetter.kt index 60e1f12709..7796f387d1 100644 --- a/core/src/com/unciv/ui/images/ImageGetter.kt +++ b/core/src/com/unciv/ui/images/ImageGetter.kt @@ -47,6 +47,7 @@ object ImageGetter { // We then shove all the drawables into a hashmap, because the atlas specifically tells us // that the search on it is inefficient private val textureRegionDrawables = HashMap() + private val ninePatchDrawables = HashMap() fun resetAtlases() { atlases.values.forEach { it.dispose() } @@ -95,8 +96,13 @@ object ImageGetter { atlases[extraAtlas] = tempAtlas // cache the freshly loaded } for (region in tempAtlas.regions) { - val drawable = TextureRegionDrawable(region) - textureRegionDrawables[region.name] = drawable + if (region.name.startsWith("Skins")) { + val ninePatch = tempAtlas.createPatch(region.name) + ninePatchDrawables[region.name] = NinePatchDrawable(ninePatch) + } else { + val drawable = TextureRegionDrawable(region) + textureRegionDrawables[region.name] = drawable + } } } } @@ -175,36 +181,35 @@ object ImageGetter { return textureRegionDrawables[fileName] ?: textureRegionDrawables[whiteDotLocation]!! } + fun getNinePatch(fileName: String?): NinePatchDrawable { + return ninePatchDrawables[fileName] ?: NinePatchDrawable(NinePatch(textureRegionDrawables[whiteDotLocation]!!.region)) + } + fun getRoundedEdgeRectangle(tintColor: Color? = null): NinePatchDrawable { - val region = getDrawable("Skin/roundedEdgeRectangle").region - val drawable = NinePatchDrawable(NinePatch(region, 25, 25, 0, 0)) - drawable.setPadding(5f, 15f, 5f, 15f) + val drawable = getNinePatch("Skins/${UncivGame.Current.settings.skin}/roundedEdgeRectangle") if (tintColor == null) return drawable return drawable.tint(tintColor) } fun getRectangleWithOutline(): NinePatchDrawable { - val region = getDrawable("Skin/rectangleWithOutline").region - return NinePatchDrawable(NinePatch(region, 1, 1, 1, 1)) + return getNinePatch("Skins/${UncivGame.Current.settings.skin}/rectangleWithOutline") } fun getSelectBox(): NinePatchDrawable { - val region = getDrawable("Skin/select-box").region - return NinePatchDrawable(NinePatch(region, 10, 25, 5, 5)) + return getNinePatch("Skins/${UncivGame.Current.settings.skin}/select-box") } fun getSelectBoxPressed(): NinePatchDrawable { - val region = getDrawable("Skin/select-box-pressed").region - return NinePatchDrawable(NinePatch(region, 10, 25, 5, 5)) + return getNinePatch("Skins/${UncivGame.Current.settings.skin}/select-box-pressed") } - fun getCheckBox(): Drawable { - return getDrawable("Skin/checkbox") + fun getCheckBox(): NinePatchDrawable { + return getNinePatch("Skins/${UncivGame.Current.settings.skin}/checkbox") } - fun getCheckBoxPressed(): Drawable { - return getDrawable("Skin/checkbox-pressed") + fun getCheckBoxPressed(): NinePatchDrawable { + return getNinePatch("Skins/${UncivGame.Current.settings.skin}/checkbox-pressed") } fun imageExists(fileName: String) = textureRegionDrawables.containsKey(fileName) @@ -459,6 +464,8 @@ object ImageGetter { return specialist } + fun getAvailableSkins() = ninePatchDrawables.keys.asSequence().map { it.split("/")[1] }.distinct() + fun getAvailableTilesets() = textureRegionDrawables.keys.asSequence().filter { it.startsWith("TileSets") } .map { it.split("/")[1] }.distinct() } diff --git a/core/src/com/unciv/ui/options/DisplayTab.kt b/core/src/com/unciv/ui/options/DisplayTab.kt index 4a50b6fa1f..649c5fe1d4 100644 --- a/core/src/com/unciv/ui/options/DisplayTab.kt +++ b/core/src/com/unciv/ui/options/DisplayTab.kt @@ -16,14 +16,12 @@ import com.unciv.ui.utils.WrappableLabel import com.unciv.ui.utils.extensions.brighten import com.unciv.ui.utils.extensions.onChange import com.unciv.ui.utils.extensions.toLabel -import com.unciv.ui.worldscreen.WorldScreen private val resolutionArray = com.badlogic.gdx.utils.Array(arrayOf("750x500", "900x600", "1050x700", "1200x800", "1500x1000")) fun displayTab( optionsPopup: OptionsPopup, - onResolutionChange: () -> Unit, - onTilesetChange: () -> Unit + onChange: () -> Unit, ) = Table(BaseScreen.skin).apply { pad(10f) defaults().pad(2.5f) @@ -44,9 +42,11 @@ fun displayTab( addUnitIconAlphaSlider(this, settings, optionsPopup.selectBoxMinWidth) - addResolutionSelectBox(this, settings, optionsPopup.selectBoxMinWidth, onResolutionChange) + addResolutionSelectBox(this, settings, optionsPopup.selectBoxMinWidth, onChange) - addTileSetSelectBox(this, settings, optionsPopup.selectBoxMinWidth, onTilesetChange) + addTileSetSelectBox(this, settings, optionsPopup.selectBoxMinWidth, onChange) + + addSkinSelectBox(this, settings, optionsPopup.selectBoxMinWidth, onChange) optionsPopup.addCheckbox(this, "Continuous rendering", settings.continuousRendering) { settings.continuousRendering = it @@ -147,3 +147,21 @@ private fun addTileSetSelectBox(table: Table, settings: GameSettings, selectBoxM onTilesetChange() } } + +private fun addSkinSelectBox(table: Table, settings: GameSettings, selectBoxMinWidth: Float, onSkinChange: () -> Unit) { + table.add("UI Skin".toLabel()).left().fillX() + + val skinSelectBox = SelectBox(table.skin) + val skinArray = Array() + val skins = ImageGetter.getAvailableSkins() + for (skin in skins) skinArray.add(skin) + skinSelectBox.items = skinArray + skinSelectBox.selected = settings.skin + table.add(skinSelectBox).minWidth(selectBoxMinWidth).pad(10f).row() + + skinSelectBox.onChange { + settings.skin = skinSelectBox.selected + // ImageGetter ruleset should be correct no matter what screen we're on + onSkinChange() + } +} diff --git a/core/src/com/unciv/ui/options/OptionsPopup.kt b/core/src/com/unciv/ui/options/OptionsPopup.kt index 0641e57528..6ba7c01fe1 100644 --- a/core/src/com/unciv/ui/options/OptionsPopup.kt +++ b/core/src/com/unciv/ui/options/OptionsPopup.kt @@ -80,7 +80,7 @@ class OptionsPopup( ) tabs.addPage( "Display", - displayTab(this, ::reloadWorldAndOptions, ::reloadWorldAndOptions), + displayTab(this, ::reloadWorldAndOptions), ImageGetter.getImage("UnitPromotionIcons/Scouting"), 24f ) tabs.addPage( @@ -147,6 +147,7 @@ class OptionsPopup( } } withGLContext { + BaseScreen.setSkin() UncivGame.Current.screen?.openOptionsPopup(tabs.activePage) } }