mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-23 03:23:17 -04:00
Smooth zoom when scrolling + cleanup code for listeners (#8569)
* Smooth zoom when scrolling + cleanups of listeners * Remove debug leftovers * Remove debug leftovers --------- Co-authored-by: tunerzinc@gmail.com <vfylfhby>
This commit is contained in:
parent
5fdbb7f188
commit
25c65b7da5
@ -21,7 +21,7 @@ import com.unciv.models.ruleset.Ruleset
|
|||||||
import com.unciv.models.ruleset.RulesetCache
|
import com.unciv.models.ruleset.RulesetCache
|
||||||
import com.unciv.ui.civilopedia.CivilopediaScreen
|
import com.unciv.ui.civilopedia.CivilopediaScreen
|
||||||
import com.unciv.ui.images.ImageGetter
|
import com.unciv.ui.images.ImageGetter
|
||||||
import com.unciv.ui.map.TileGroupMap
|
import com.unciv.ui.tilegroups.TileGroupMap
|
||||||
import com.unciv.ui.mapeditor.EditorMapHolder
|
import com.unciv.ui.mapeditor.EditorMapHolder
|
||||||
import com.unciv.ui.mapeditor.MapEditorScreen
|
import com.unciv.ui.mapeditor.MapEditorScreen
|
||||||
import com.unciv.ui.multiplayer.MultiplayerScreen
|
import com.unciv.ui.multiplayer.MultiplayerScreen
|
||||||
|
@ -19,7 +19,7 @@ import com.unciv.models.stats.Stat
|
|||||||
import com.unciv.ui.audio.CityAmbiencePlayer
|
import com.unciv.ui.audio.CityAmbiencePlayer
|
||||||
import com.unciv.ui.audio.SoundPlayer
|
import com.unciv.ui.audio.SoundPlayer
|
||||||
import com.unciv.ui.images.ImageGetter
|
import com.unciv.ui.images.ImageGetter
|
||||||
import com.unciv.ui.map.TileGroupMap
|
import com.unciv.ui.tilegroups.TileGroupMap
|
||||||
import com.unciv.ui.popup.ToastPopup
|
import com.unciv.ui.popup.ToastPopup
|
||||||
import com.unciv.ui.tilegroups.CityTileGroup
|
import com.unciv.ui.tilegroups.CityTileGroup
|
||||||
import com.unciv.ui.tilegroups.TileSetStrings
|
import com.unciv.ui.tilegroups.TileSetStrings
|
||||||
|
@ -8,11 +8,10 @@ import com.badlogic.gdx.scenes.scene2d.InputListener
|
|||||||
import com.badlogic.gdx.scenes.scene2d.Stage
|
import com.badlogic.gdx.scenes.scene2d.Stage
|
||||||
import com.badlogic.gdx.scenes.scene2d.Touchable
|
import com.badlogic.gdx.scenes.scene2d.Touchable
|
||||||
import com.badlogic.gdx.scenes.scene2d.actions.Actions
|
import com.badlogic.gdx.scenes.scene2d.actions.Actions
|
||||||
import com.unciv.UncivGame
|
|
||||||
import com.unciv.logic.map.HexMath
|
import com.unciv.logic.map.HexMath
|
||||||
import com.unciv.logic.map.tile.Tile
|
import com.unciv.logic.map.tile.Tile
|
||||||
import com.unciv.logic.map.TileMap
|
import com.unciv.logic.map.TileMap
|
||||||
import com.unciv.ui.map.TileGroupMap
|
import com.unciv.ui.tilegroups.TileGroupMap
|
||||||
import com.unciv.ui.tilegroups.TileGroup
|
import com.unciv.ui.tilegroups.TileGroup
|
||||||
import com.unciv.ui.tilegroups.TileSetStrings
|
import com.unciv.ui.tilegroups.TileSetStrings
|
||||||
import com.unciv.ui.utils.BaseScreen
|
import com.unciv.ui.utils.BaseScreen
|
||||||
|
@ -241,7 +241,7 @@ private fun CoroutineScope.generateScreenshots(configs:ArrayList<ScreenshotConfi
|
|||||||
newScreen.mapHolder.onTileClicked(newScreen.mapHolder.tileMap[-2, 3]) // Then click on Keshik
|
newScreen.mapHolder.onTileClicked(newScreen.mapHolder.tileMap[-2, 3]) // Then click on Keshik
|
||||||
if (currentConfig.attackCity)
|
if (currentConfig.attackCity)
|
||||||
newScreen.mapHolder.onTileClicked(newScreen.mapHolder.tileMap[-2, 2]) // Then click city again for attack table
|
newScreen.mapHolder.onTileClicked(newScreen.mapHolder.tileMap[-2, 2]) // Then click city again for attack table
|
||||||
newScreen.mapHolder.zoomIn()
|
newScreen.mapHolder.zoomIn(true)
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
Thread.sleep(300)
|
Thread.sleep(300)
|
||||||
launchOnGLThread {
|
launchOnGLThread {
|
||||||
|
@ -5,7 +5,6 @@ import com.badlogic.gdx.scenes.scene2d.Group
|
|||||||
import com.unciv.UncivGame
|
import com.unciv.UncivGame
|
||||||
import com.unciv.logic.civilization.Civilization
|
import com.unciv.logic.civilization.Civilization
|
||||||
import com.unciv.logic.map.tile.Tile
|
import com.unciv.logic.map.tile.Tile
|
||||||
import com.unciv.ui.map.TileGroupMap
|
|
||||||
import com.unciv.ui.tilegroups.layers.TileLayerBorders
|
import com.unciv.ui.tilegroups.layers.TileLayerBorders
|
||||||
import com.unciv.ui.tilegroups.layers.TileLayerCityButton
|
import com.unciv.ui.tilegroups.layers.TileLayerCityButton
|
||||||
import com.unciv.ui.tilegroups.layers.TileLayerFeatures
|
import com.unciv.ui.tilegroups.layers.TileLayerFeatures
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
package com.unciv.ui.map
|
package com.unciv.ui.tilegroups
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.g2d.Batch
|
import com.badlogic.gdx.graphics.g2d.Batch
|
||||||
|
import com.badlogic.gdx.math.Rectangle
|
||||||
import com.badlogic.gdx.math.Vector2
|
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.Group
|
||||||
import com.unciv.logic.map.HexMath
|
import com.unciv.logic.map.HexMath
|
||||||
import com.unciv.logic.map.TileMap
|
import com.unciv.logic.map.TileMap
|
||||||
import com.unciv.ui.tilegroups.CityTileGroup
|
|
||||||
import com.unciv.ui.tilegroups.TileGroup
|
|
||||||
import com.unciv.ui.tilegroups.WorldTileGroup
|
|
||||||
import com.unciv.ui.tilegroups.layers.TileLayerBorders
|
import com.unciv.ui.tilegroups.layers.TileLayerBorders
|
||||||
import com.unciv.ui.tilegroups.layers.TileLayerCityButton
|
import com.unciv.ui.tilegroups.layers.TileLayerCityButton
|
||||||
import com.unciv.ui.tilegroups.layers.TileLayerFeatures
|
import com.unciv.ui.tilegroups.layers.TileLayerFeatures
|
||||||
@ -52,6 +51,7 @@ class TileGroupMap<T: TileGroup>(
|
|||||||
* and thus not perform any [com.badlogic.gdx.scenes.scene2d.Action]s.
|
* and thus not perform any [com.badlogic.gdx.scenes.scene2d.Action]s.
|
||||||
* Most children here already do not do anything in their [act] methods. However, even iterating through all of them */
|
* Most children here already do not do anything in their [act] methods. However, even iterating through all of them */
|
||||||
var shouldAct = true
|
var shouldAct = true
|
||||||
|
var shouldHit = true
|
||||||
|
|
||||||
private var topX = -Float.MAX_VALUE
|
private var topX = -Float.MAX_VALUE
|
||||||
private var topY = -Float.MAX_VALUE
|
private var topY = -Float.MAX_VALUE
|
||||||
@ -132,6 +132,8 @@ class TileGroupMap<T: TileGroup>(
|
|||||||
// If map is not wrapped, Map's width doesn't need to be reduce by groupSize
|
// If map is not wrapped, Map's width doesn't need to be reduce by groupSize
|
||||||
if (worldWrap) setSize(topX - bottomX - groupSize, topY - bottomY)
|
if (worldWrap) setSize(topX - bottomX - groupSize, topY - bottomY)
|
||||||
else setSize(topX - bottomX, topY - bottomY)
|
else setSize(topX - bottomX, topY - bottomY)
|
||||||
|
|
||||||
|
cullingArea = Rectangle(0f, 0f, width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -146,9 +148,14 @@ class TileGroupMap<T: TileGroup>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun act(delta: Float) {
|
override fun act(delta: Float) {
|
||||||
if(shouldAct) {
|
if (shouldAct)
|
||||||
super.act(delta)
|
super.act(delta)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun hit(x: Float, y: Float, touchable: Boolean): Actor? {
|
||||||
|
if (shouldHit)
|
||||||
|
return super.hit(x, y, touchable)
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun draw(batch: Batch?, parentAlpha: Float) {
|
override fun draw(batch: Batch?, parentAlpha: Float) {
|
@ -9,7 +9,6 @@ import com.badlogic.gdx.scenes.scene2d.InputEvent
|
|||||||
open class ZoomGestureListener(
|
open class ZoomGestureListener(
|
||||||
halfTapSquareSize: Float, tapCountInterval: Float, longPressDuration: Float, maxFlingDelay: Float
|
halfTapSquareSize: Float, tapCountInterval: Float, longPressDuration: Float, maxFlingDelay: Float
|
||||||
) : EventListener {
|
) : EventListener {
|
||||||
|
|
||||||
val detector: GestureDetector
|
val detector: GestureDetector
|
||||||
var event: InputEvent? = null
|
var event: InputEvent? = null
|
||||||
|
|
||||||
@ -24,7 +23,7 @@ open class ZoomGestureListener(
|
|||||||
object : GestureDetector.GestureAdapter() {
|
object : GestureDetector.GestureAdapter() {
|
||||||
|
|
||||||
override fun zoom(initialDistance: Float, distance: Float): Boolean {
|
override fun zoom(initialDistance: Float, distance: Float): Boolean {
|
||||||
this@ZoomGestureListener.zoom(event, initialDistance, distance)
|
this@ZoomGestureListener.zoom(initialDistance, distance)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,10 +70,15 @@ open class ZoomGestureListener(
|
|||||||
detector.touchDragged(event.stageX, event.stageY, event.pointer)
|
detector.touchDragged(event.stageX, event.stageY, event.pointer)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
InputEvent.Type.scrolled -> {
|
||||||
|
return scrolled(event.scrollAmountX, event.scrollAmountY)
|
||||||
|
}
|
||||||
else -> return false
|
else -> return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
open fun zoom(event: InputEvent?, initialDistance: Float, distance: Float) {}
|
|
||||||
|
open fun scrolled(amountX: Float, amountY: Float): Boolean { return false }
|
||||||
|
open fun zoom(initialDistance: Float, distance: Float) {}
|
||||||
open fun pinch() {}
|
open fun pinch() {}
|
||||||
open fun pinchStop() {}
|
open fun pinchStop() {}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
package com.unciv.ui.utils
|
package com.unciv.ui.utils
|
||||||
|
|
||||||
import com.badlogic.gdx.math.Interpolation
|
import com.badlogic.gdx.math.Interpolation
|
||||||
|
import com.badlogic.gdx.math.MathUtils
|
||||||
import com.badlogic.gdx.math.Rectangle
|
import com.badlogic.gdx.math.Rectangle
|
||||||
import com.badlogic.gdx.math.Vector2
|
import com.badlogic.gdx.math.Vector2
|
||||||
import com.badlogic.gdx.scenes.scene2d.Action
|
import com.badlogic.gdx.scenes.scene2d.Action
|
||||||
import com.badlogic.gdx.scenes.scene2d.Actor
|
import com.badlogic.gdx.scenes.scene2d.Actor
|
||||||
import com.badlogic.gdx.scenes.scene2d.Group
|
import com.badlogic.gdx.scenes.scene2d.Group
|
||||||
import com.badlogic.gdx.scenes.scene2d.InputEvent
|
import com.badlogic.gdx.scenes.scene2d.InputEvent
|
||||||
import com.badlogic.gdx.scenes.scene2d.InputListener
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.actions.FloatAction
|
import com.badlogic.gdx.scenes.scene2d.actions.FloatAction
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.actions.TemporalAction
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane
|
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane
|
||||||
import com.badlogic.gdx.scenes.scene2d.utils.ActorGestureListener
|
import com.badlogic.gdx.scenes.scene2d.utils.ActorGestureListener
|
||||||
import com.badlogic.gdx.scenes.scene2d.utils.Cullable
|
import com.badlogic.gdx.scenes.scene2d.utils.Cullable
|
||||||
@ -31,12 +32,13 @@ open class ZoomableScrollPane(
|
|||||||
var onPanStartListener: (() -> Unit)? = null
|
var onPanStartListener: (() -> Unit)? = null
|
||||||
var onZoomStopListener: (() -> Unit)? = null
|
var onZoomStopListener: (() -> Unit)? = null
|
||||||
var onZoomStartListener: (() -> Unit)? = null
|
var onZoomStartListener: (() -> Unit)? = null
|
||||||
|
private val zoomListener = ZoomListener()
|
||||||
|
|
||||||
private val horizontalPadding get() = width / 2
|
private val horizontalPadding get() = width / 2
|
||||||
private val verticalPadding get() = height / 2
|
private val verticalPadding get() = height / 2
|
||||||
|
|
||||||
init {
|
init {
|
||||||
addZoomListeners()
|
this.addListener(zoomListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reloadMaxZoom() {
|
fun reloadMaxZoom() {
|
||||||
@ -49,6 +51,10 @@ open class ZoomableScrollPane(
|
|||||||
zoom(1f)
|
zoom(1f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We don't want default scroll listener
|
||||||
|
// which defines that mouse scroll = vertical movement
|
||||||
|
override fun addScrollListener() {}
|
||||||
|
|
||||||
override fun getActor() : Actor? {
|
override fun getActor() : Actor? {
|
||||||
val group: Group = super.getActor() as Group
|
val group: Group = super.getActor() as Group
|
||||||
return if (group.hasChildren()) group.children[0] else null
|
return if (group.hasChildren()) group.children[0] else null
|
||||||
@ -141,93 +147,160 @@ open class ZoomableScrollPane(
|
|||||||
// by half (i.e. middle) of what our size changed.
|
// by half (i.e. middle) of what our size changed.
|
||||||
// However, we also changed the padding, which is exactly equal to half of our size change, so we actually don't need to move our center at all.
|
// However, we also changed the padding, which is exactly equal to half of our size change, so we actually don't need to move our center at all.
|
||||||
}
|
}
|
||||||
fun zoomIn() {
|
fun zoomIn(immediate: Boolean = false) {
|
||||||
zoom(scaleX / 0.8f)
|
if (immediate)
|
||||||
|
zoom(scaleX / 0.8f)
|
||||||
|
else
|
||||||
|
zoomListener.zoomIn(0.8f)
|
||||||
}
|
}
|
||||||
fun zoomOut() {
|
fun zoomOut(immediate: Boolean = false) {
|
||||||
zoom(scaleX * 0.8f)
|
if (immediate)
|
||||||
|
zoom(scaleX * 0.8f)
|
||||||
|
else
|
||||||
|
zoomListener.zoomOut(0.8f)
|
||||||
}
|
}
|
||||||
|
|
||||||
class ScrollZoomListener(private val zoomableScrollPane: ZoomableScrollPane):InputListener(){
|
fun isZooming(): Boolean {
|
||||||
override fun scrolled(event: InputEvent?, x: Float, y: Float, amountX: Float, amountY: Float): Boolean {
|
return zoomListener.isZooming
|
||||||
if (amountX > 0 || amountY > 0) zoomableScrollPane.zoomOut()
|
}
|
||||||
else zoomableScrollPane.zoomIn()
|
|
||||||
return false
|
inner class ZoomListener : ZoomGestureListener() {
|
||||||
|
|
||||||
|
inner class ZoomAction : TemporalAction() {
|
||||||
|
|
||||||
|
var startingZoom: Float = 1f
|
||||||
|
var finishingZoom: Float = 1f
|
||||||
|
var currentZoom: Float = 1f
|
||||||
|
|
||||||
|
init {
|
||||||
|
duration = 0.3f
|
||||||
|
interpolation = Interpolation.fastSlow
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun begin() {
|
||||||
|
isZooming = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun end() {
|
||||||
|
zoomAction = null
|
||||||
|
isZooming = false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun update(percent: Float) {
|
||||||
|
currentZoom = MathUtils.lerp(startingZoom, finishingZoom, percent)
|
||||||
|
zoom(currentZoom)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
class ZoomListener(private val zoomableScrollPane: ZoomableScrollPane): ZoomGestureListener(){
|
private var zoomAction: ZoomAction? = null
|
||||||
|
|
||||||
private var isZooming = false
|
|
||||||
private var lastInitialDistance = 0f
|
private var lastInitialDistance = 0f
|
||||||
var lastScale = 1f
|
var lastScale = 1f
|
||||||
|
var isZooming = false
|
||||||
|
|
||||||
|
fun zoomOut(zoomMultiplier: Float = 0.82f) {
|
||||||
|
if (scaleX <= minZoom) {
|
||||||
|
if (zoomAction != null)
|
||||||
|
zoomAction!!.finish()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zoomAction != null) {
|
||||||
|
zoomAction!!.startingZoom = zoomAction!!.currentZoom
|
||||||
|
zoomAction!!.finishingZoom *= zoomMultiplier
|
||||||
|
zoomAction!!.restart()
|
||||||
|
} else {
|
||||||
|
zoomAction = ZoomAction()
|
||||||
|
zoomAction!!.startingZoom = scaleX
|
||||||
|
zoomAction!!.finishingZoom = scaleX * zoomMultiplier
|
||||||
|
addAction(zoomAction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun zoomIn(zoomMultiplier: Float = 0.82f) {
|
||||||
|
if (scaleX >= maxZoom) {
|
||||||
|
if (zoomAction != null)
|
||||||
|
zoomAction!!.finish()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zoomAction != null) {
|
||||||
|
zoomAction!!.startingZoom = zoomAction!!.currentZoom
|
||||||
|
zoomAction!!.finishingZoom /= zoomMultiplier
|
||||||
|
zoomAction!!.restart()
|
||||||
|
} else {
|
||||||
|
zoomAction = ZoomAction()
|
||||||
|
zoomAction!!.startingZoom = scaleX
|
||||||
|
zoomAction!!.finishingZoom = scaleX / zoomMultiplier
|
||||||
|
addAction(zoomAction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun pinch() {
|
override fun pinch() {
|
||||||
if (!isZooming) {
|
if (!isZooming) {
|
||||||
isZooming = true
|
isZooming = true
|
||||||
zoomableScrollPane.onZoomStartListener?.invoke()
|
onZoomStartListener?.invoke()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun pinchStop() {
|
override fun pinchStop() {
|
||||||
isZooming = false
|
isZooming = false
|
||||||
zoomableScrollPane.onZoomStopListener?.invoke()
|
onZoomStopListener?.invoke()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun zoom(event: InputEvent?, initialDistance: Float, distance: Float) {
|
override fun zoom(initialDistance: Float, distance: Float) {
|
||||||
if (lastInitialDistance != initialDistance) {
|
if (lastInitialDistance != initialDistance) {
|
||||||
lastInitialDistance = initialDistance
|
lastInitialDistance = initialDistance
|
||||||
lastScale = zoomableScrollPane.scaleX
|
lastScale = scaleX
|
||||||
}
|
}
|
||||||
val scale: Float = sqrt((distance / initialDistance).toDouble()).toFloat() * lastScale
|
val scale: Float = sqrt((distance / initialDistance).toDouble()).toFloat() * lastScale
|
||||||
zoomableScrollPane.zoom(scale)
|
zoom(scale)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun scrolled(amountX: Float, amountY: Float): Boolean {
|
||||||
|
if (amountX > 0 || amountY > 0)
|
||||||
|
zoomOut()
|
||||||
|
else
|
||||||
|
zoomIn()
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addZoomListeners() {
|
inner class FlickScrollListener : ActorGestureListener() {
|
||||||
// At first, Remove the existing inputListener
|
private var isPanning = false
|
||||||
// which defines that mouse scroll = vertical movement
|
|
||||||
val zoomListener = listeners.last { it is InputListener && it !in captureListeners }
|
|
||||||
removeListener(zoomListener)
|
|
||||||
addListener(ScrollZoomListener(this))
|
|
||||||
addListener(ZoomListener(this))
|
|
||||||
}
|
|
||||||
|
|
||||||
class FlickScrollListener(private val zoomableScrollPane: ZoomableScrollPane): ActorGestureListener(){
|
|
||||||
private var wasPanning = false
|
|
||||||
override fun pan(event: InputEvent, x: Float, y: Float, deltaX: Float, deltaY: Float) {
|
override fun pan(event: InputEvent, x: Float, y: Float, deltaX: Float, deltaY: Float) {
|
||||||
if (!wasPanning) {
|
if (!isPanning) {
|
||||||
wasPanning = true
|
isPanning = true
|
||||||
zoomableScrollPane.onPanStartListener?.invoke()
|
onPanStartListener?.invoke()
|
||||||
}
|
}
|
||||||
zoomableScrollPane.setScrollbarsVisible(true)
|
setScrollbarsVisible(true)
|
||||||
zoomableScrollPane.scrollX -= deltaX
|
scrollX -= deltaX
|
||||||
zoomableScrollPane.scrollY += deltaY
|
scrollY += deltaY
|
||||||
|
|
||||||
//this is the new feature to fake an infinite scroll
|
//this is the new feature to fake an infinite scroll
|
||||||
when {
|
when {
|
||||||
zoomableScrollPane.continuousScrollingX && zoomableScrollPane.scrollPercentX >= 1 && deltaX < 0 -> {
|
continuousScrollingX && scrollPercentX >= 1 && deltaX < 0 -> {
|
||||||
zoomableScrollPane.scrollPercentX = 0f
|
scrollPercentX = 0f
|
||||||
}
|
}
|
||||||
zoomableScrollPane.continuousScrollingX && zoomableScrollPane.scrollPercentX <= 0 && deltaX > 0-> {
|
continuousScrollingX && scrollPercentX <= 0 && deltaX > 0-> {
|
||||||
zoomableScrollPane.scrollPercentX = 1f
|
scrollPercentX = 1f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//clamp() call is missing here but it doesn't seem to make any big difference in this case
|
//clamp() call is missing here but it doesn't seem to make any big difference in this case
|
||||||
|
|
||||||
if ((zoomableScrollPane.isScrollX && deltaX != 0f || zoomableScrollPane.isScrollY && deltaY != 0f)) zoomableScrollPane.cancelTouchFocus()
|
if ((isScrollX && deltaX != 0f || isScrollY && deltaY != 0f))
|
||||||
|
cancelTouchFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun panStop(event: InputEvent?, x: Float, y: Float, pointer: Int, button: Int) {
|
override fun panStop(event: InputEvent?, x: Float, y: Float, pointer: Int, button: Int) {
|
||||||
wasPanning = false
|
isPanning = false
|
||||||
zoomableScrollPane.onPanStopListener?.invoke()
|
onPanStopListener?.invoke()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFlickScrollListener(): ActorGestureListener {
|
override fun getFlickScrollListener(): ActorGestureListener {
|
||||||
return FlickScrollListener(this)
|
return FlickScrollListener()
|
||||||
}
|
}
|
||||||
|
|
||||||
private var scrollingTo: Vector2? = null
|
private var scrollingTo: Vector2? = null
|
||||||
|
@ -34,7 +34,7 @@ import com.unciv.models.ruleset.unique.UniqueType
|
|||||||
import com.unciv.ui.UncivStage
|
import com.unciv.ui.UncivStage
|
||||||
import com.unciv.ui.audio.SoundPlayer
|
import com.unciv.ui.audio.SoundPlayer
|
||||||
import com.unciv.ui.images.ImageGetter
|
import com.unciv.ui.images.ImageGetter
|
||||||
import com.unciv.ui.map.TileGroupMap
|
import com.unciv.ui.tilegroups.TileGroupMap
|
||||||
import com.unciv.ui.tilegroups.TileGroup
|
import com.unciv.ui.tilegroups.TileGroup
|
||||||
import com.unciv.ui.tilegroups.TileSetStrings
|
import com.unciv.ui.tilegroups.TileSetStrings
|
||||||
import com.unciv.ui.tilegroups.WorldTileGroup
|
import com.unciv.ui.tilegroups.WorldTileGroup
|
||||||
@ -72,37 +72,31 @@ class WorldMapHolder(
|
|||||||
if (Gdx.app.type == Application.ApplicationType.Desktop) this.setFlingTime(0f)
|
if (Gdx.app.type == Application.ApplicationType.Desktop) this.setFlingTime(0f)
|
||||||
continuousScrollingX = tileMap.mapParameters.worldWrap
|
continuousScrollingX = tileMap.mapParameters.worldWrap
|
||||||
reloadMaxZoom()
|
reloadMaxZoom()
|
||||||
disablePointerEventsAndActionsOnPan()
|
setupZoomPanListeners()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When scrolling or zooming the world map, there are two unnecessary (at least currently) things happening that take a decent amount of time:
|
* When scrolling or zooming the world map, there are three unnecessary (at least currently) things happening that take a decent amount of time:
|
||||||
*
|
*
|
||||||
* 1. Checking which [Actor]'s bounds the pointer (mouse/finger) entered+exited and sending appropriate events to these actors
|
* 1. Checking which [Actor]'s bounds the pointer (mouse/finger) entered+exited and sending appropriate events to these actors
|
||||||
* 2. Running all [Actor.act] methods of all child [Actor]s
|
* 2. Running all [Actor.act] methods of all child [Actor]s
|
||||||
* 3. Running all [Actor.hit] methode of all chikld [Actor]s
|
* 3. Running all [Actor.hit] methods of all child [Actor]s
|
||||||
*
|
*
|
||||||
* Disabling them while panning increases the frame rate while panning by approximately 100%.
|
* Disabling them while panning/zooming increases the frame rate by approximately 100%.
|
||||||
*/
|
*/
|
||||||
private fun disablePointerEventsAndActionsOnPan() {
|
private fun setupZoomPanListeners() {
|
||||||
onPanStartListener = {
|
|
||||||
(stage as UncivStage).performPointerEnterExitEvents = false
|
fun setActHit() {
|
||||||
tileGroupMap.shouldAct = false
|
val isEnabled = !isZooming() && !isPanning
|
||||||
}
|
(stage as UncivStage).performPointerEnterExitEvents = isEnabled
|
||||||
onPanStopListener = {
|
tileGroupMap.shouldAct = isEnabled
|
||||||
(stage as UncivStage).performPointerEnterExitEvents = true
|
tileGroupMap.shouldHit = isEnabled
|
||||||
tileGroupMap.shouldAct = true
|
|
||||||
}
|
|
||||||
onZoomStartListener = {
|
|
||||||
(stage as UncivStage).performPointerEnterExitEvents = false
|
|
||||||
tileGroupMap.shouldAct = false
|
|
||||||
tileGroupMap.touchable = Touchable.disabled
|
|
||||||
}
|
|
||||||
onZoomStopListener = {
|
|
||||||
(stage as UncivStage).performPointerEnterExitEvents = true
|
|
||||||
tileGroupMap.shouldAct = true
|
|
||||||
tileGroupMap.touchable = Touchable.enabled
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onPanStartListener = { setActHit() }
|
||||||
|
onPanStopListener = { setActHit() }
|
||||||
|
onZoomStartListener = { setActHit() }
|
||||||
|
onZoomStopListener = { setActHit() }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interface for classes that contain the data required to draw a button
|
// Interface for classes that contain the data required to draw a button
|
||||||
|
Loading…
x
Reference in New Issue
Block a user