mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-04 23:40:01 +07:00
City-stationed unit icons get a circular touchable area (#10866)
* Linting * Move ClickableCircle to allow reuse * Make the Unit list icons clickable only within their circle
This commit is contained in:
30
core/src/com/unciv/ui/components/input/ClickableCircle.kt
Normal file
30
core/src/com/unciv/ui/components/input/ClickableCircle.kt
Normal file
@ -0,0 +1,30 @@
|
||||
package com.unciv.ui.components.input
|
||||
|
||||
import com.badlogic.gdx.math.Vector2
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor
|
||||
import com.badlogic.gdx.scenes.scene2d.Group
|
||||
import com.badlogic.gdx.scenes.scene2d.Touchable
|
||||
|
||||
/**
|
||||
* Invisible Widget that supports detecting clicks in a circular area.
|
||||
*
|
||||
* (An Image Actor does not respect alpha for its hit area, it's always square, but we want a clickable _circle_)
|
||||
*
|
||||
* Usage: instantiate, position and overlay on something with [addActor], add listener using [onActivation].
|
||||
* Does not implement Layout at the moment - usage e.g. in a Table Cell may need that.
|
||||
*
|
||||
* Note this is a [Group] that is supposed to have no [children] - as a simple [Actor] the Scene2D framework won't know to call our [hit] method.
|
||||
*/
|
||||
class ClickableCircle(size: Float) : Group() {
|
||||
private val center = Vector2(size / 2, size / 2)
|
||||
private val maxDst2 = size * size / 4 // squared radius
|
||||
|
||||
init {
|
||||
touchable = Touchable.enabled
|
||||
setSize(size, size)
|
||||
}
|
||||
|
||||
override fun hit(x: Float, y: Float, touchable: Boolean): Actor? {
|
||||
return if (center.dst2(x, y) < maxDst2) this else null
|
||||
}
|
||||
}
|
@ -28,6 +28,7 @@ import com.unciv.ui.components.extensions.equalizeColumns
|
||||
import com.unciv.ui.components.extensions.toLabel
|
||||
import com.unciv.ui.components.extensions.toTextButton
|
||||
import com.unciv.ui.components.fonts.Fonts
|
||||
import com.unciv.ui.components.input.ClickableCircle
|
||||
import com.unciv.ui.components.input.onActivation
|
||||
import com.unciv.ui.components.input.onClick
|
||||
import com.unciv.ui.components.widgets.AutoScrollPane
|
||||
@ -536,18 +537,5 @@ class GlobalPoliticsOverviewTable(
|
||||
}
|
||||
}
|
||||
|
||||
/** An Image Actor does not respect alpha for its hit area, it's always square, but we want a clickable _circle_ */
|
||||
private class ClickableCircle(size: Float) : Group() {
|
||||
val center = Vector2(size / 2, size / 2)
|
||||
val maxDst2 = size * size / 4 // squared radius
|
||||
init {
|
||||
touchable = Touchable.enabled
|
||||
setSize(size, size)
|
||||
}
|
||||
override fun hit(x: Float, y: Float, touchable: Boolean): Actor? {
|
||||
return if (center.dst2(x, y) < maxDst2) this else null
|
||||
}
|
||||
}
|
||||
|
||||
//endregion
|
||||
}
|
||||
|
@ -41,6 +41,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.ActivationTypes
|
||||
import com.unciv.ui.components.input.ClickableCircle
|
||||
import com.unciv.ui.components.input.KeyCharAndCode
|
||||
import com.unciv.ui.components.input.KeyboardBinding
|
||||
import com.unciv.ui.components.input.keyShortcuts
|
||||
@ -480,12 +481,14 @@ class WorldMapHolder(
|
||||
val unitGroup = UnitGroup(unit, 48f).surroundWithCircle(68f, resizeActor = false)
|
||||
unitGroup.circle.color = Color.GRAY.cpy().apply { a = 0.5f }
|
||||
if (unit.currentMovement == 0f) unitGroup.color.a = 0.66f
|
||||
unitGroup.touchable = Touchable.enabled
|
||||
unitGroup.onClick {
|
||||
val clickableCircle = ClickableCircle(68f)
|
||||
clickableCircle.touchable = Touchable.enabled
|
||||
clickableCircle.onClick {
|
||||
worldScreen.bottomUnitTable.selectUnit(unit, Gdx.input.isShiftKeyPressed())
|
||||
worldScreen.shouldUpdate = true
|
||||
removeUnitActionOverlay()
|
||||
}
|
||||
unitGroup.addActor(clickableCircle)
|
||||
table.add(unitGroup)
|
||||
}
|
||||
|
||||
@ -655,7 +658,7 @@ class WorldMapHolder(
|
||||
val city = unitTable.selectedCity!!
|
||||
updateBombardableTilesForSelectedCity(city)
|
||||
// We still want to show road paths to the selected city if they are present
|
||||
if (unitTable.selectedUnitIsConnectingRoad){
|
||||
if (unitTable.selectedUnitIsConnectingRoad) {
|
||||
updateTilesForSelectedUnit(unitTable.selectedUnits[0])
|
||||
}
|
||||
}
|
||||
@ -715,11 +718,10 @@ class WorldMapHolder(
|
||||
|
||||
// Z-Layer: 0
|
||||
// Highlight suitable tiles in road connecting mode
|
||||
if (worldScreen.bottomUnitTable.selectedUnitIsConnectingRoad){
|
||||
if (worldScreen.bottomUnitTable.selectedUnitIsConnectingRoad) {
|
||||
val validTiles = unit.civ.gameInfo.tileMap.tileList.filter {
|
||||
MapPathing.isValidRoadPathTile(unit, it)
|
||||
}
|
||||
unit.civ.gameInfo.civilizations
|
||||
val connectRoadTileOverlayColor = Color.RED
|
||||
for (tile in validTiles) {
|
||||
tileGroups[tile]!!.layerOverlay.showHighlight(connectRoadTileOverlayColor, 0.3f)
|
||||
@ -796,10 +798,10 @@ class WorldMapHolder(
|
||||
if (currTileIndex != -1) {
|
||||
val futureTiles = unit.automatedRoadConnectionPath!!.filterIndexed { index, _ ->
|
||||
index > currTileIndex
|
||||
}.map{tilePos ->
|
||||
}.map { tilePos ->
|
||||
tileMap[tilePos]
|
||||
}
|
||||
for (tile in futureTiles){
|
||||
for (tile in futureTiles) {
|
||||
tileGroups[tile]!!.layerOverlay.showHighlight(Color.ORANGE, if (UncivGame.Current.settings.singleTapMove) 0.7f else 0.3f)
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ class UnitTable(val worldScreen: WorldScreen) : Table() {
|
||||
separator.isVisible = true
|
||||
val city = selectedCity!!
|
||||
var nameLabelText = city.name.tr()
|
||||
if(city.health<city.getMaxHealth()) nameLabelText+=" ("+city.health+")"
|
||||
if (city.health < city.getMaxHealth()) nameLabelText += " ("+city.health+")"
|
||||
unitNameLabel.setText(nameLabelText)
|
||||
|
||||
unitNameLabel.clearListeners()
|
||||
@ -286,10 +286,10 @@ class UnitTable(val worldScreen: WorldScreen) : Table() {
|
||||
|
||||
fun citySelected(city: City) : Boolean {
|
||||
// If the last selected unit connecting a road, keep it selected. Otherwise, clear.
|
||||
if(selectedUnitIsConnectingRoad){
|
||||
if (selectedUnitIsConnectingRoad) {
|
||||
selectUnit(selectedUnits[0])
|
||||
selectedUnitIsConnectingRoad = true // selectUnit resets this
|
||||
}else{
|
||||
} else {
|
||||
selectUnit()
|
||||
}
|
||||
if (city == selectedCity) return false
|
||||
|
Reference in New Issue
Block a user