Map scroll speed (#8958)

* Allow mouse panning in map editor too

* User control over map panning speed

* User control over map panning speed - german
This commit is contained in:
SomeTroglodyte 2023-03-23 22:58:18 +01:00 committed by GitHub
parent da7786a2cb
commit 90c295dc1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 80 additions and 24 deletions

View File

@ -686,7 +686,8 @@ Landscape (fixed) = Quer (fixiert)
Portrait (fixed) = Hochkant (fixiert)
Auto (sensor adjusted) = Auto (durch Sensor justiert)
Map mouse auto-scroll = Automatisches Maus-Scrollen zuweisen
Map mouse auto-scroll = Karte durch Maus am Fensterrand verschieben
Map panning speed = Geschwindigkeit der Kartenverschiebung
Order trade offers by amount = Handelsangebote nach Menge sortieren
Experimental Demographics scoreboard = Experimentelle Demographien-Übersicht
Unit icon opacity = Deckkraft des Einheitensymbols

View File

@ -686,7 +686,9 @@ Landscape (fixed) =
Portrait (fixed) =
Auto (sensor adjusted) =
### Enable panning the map when you move the mouse to the edge of the window
Map mouse auto-scroll =
Map panning speed =
Order trade offers by amount =
Experimental Demographics scoreboard =
Unit icon opacity =

View File

@ -31,7 +31,11 @@ enum class ScreenSize(val virtualWidth:Float, val virtualHeight:Float){
class GameSettings {
/** Allows panning the map by moving the pointer to the screen edges */
var mapAutoScroll: Boolean = false
/** How fast the map pans using keyboard or with [mapAutoScroll] and mouse */
var mapPanningSpeed: Float = 6f
var showWorkedTiles: Boolean = false
var showResourcesAndImprovements: Boolean = true
var showTileYields: Boolean = false

View File

@ -10,11 +10,15 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextField
class KeyboardPanningListener(
private val mapHolder: ZoomableScrollPane,
allowWASD: Boolean,
allowWASD: Boolean
) : InputListener() {
companion object {
/** The delay between panning steps */
const val deltaTime = 0.01f
}
private val pressedKeys = mutableSetOf<Int>()
private var infiniteAction: RepeatAction? = null
private val amountToMove = 6 / mapHolder.scaleX
private val allowedKeys =
setOf(Input.Keys.UP, Input.Keys.DOWN, Input.Keys.LEFT, Input.Keys.RIGHT) + (
if (allowWASD) setOf(Input.Keys.W, Input.Keys.S, Input.Keys.A, Input.Keys.D)
@ -45,7 +49,7 @@ class KeyboardPanningListener(
// create a copy of the action, because removeAction() will destroy this instance
infiniteAction = Actions.forever(
Actions.delay(
0.01f,
deltaTime,
Actions.run { whileKeyPressedLoop() })
)
mapHolder.addAction(infiniteAction)
@ -61,14 +65,16 @@ class KeyboardPanningListener(
}
private fun whileKeyPressedLoop() {
var deltaX = 0f
var deltaY = 0f
for (keycode in pressedKeys) {
when (keycode) {
Input.Keys.W, Input.Keys.UP -> mapHolder.scrollY = mapHolder.restrictY(-amountToMove)
Input.Keys.S, Input.Keys.DOWN -> mapHolder.scrollY = mapHolder.restrictY(amountToMove)
Input.Keys.A, Input.Keys.LEFT -> mapHolder.scrollX = mapHolder.restrictX(amountToMove)
Input.Keys.D, Input.Keys.RIGHT -> mapHolder.scrollX = mapHolder.restrictX(-amountToMove)
Input.Keys.W, Input.Keys.UP -> deltaY -= 1f
Input.Keys.S, Input.Keys.DOWN -> deltaY += 1f
Input.Keys.A, Input.Keys.LEFT -> deltaX += 1f
Input.Keys.D, Input.Keys.RIGHT -> deltaX -= 1f
}
}
mapHolder.updateVisualScroll()
mapHolder.doKeyOrMousePanning(deltaX, deltaY)
}
}

View File

@ -15,6 +15,7 @@ import com.badlogic.gdx.scenes.scene2d.actions.TemporalAction
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane
import com.badlogic.gdx.scenes.scene2d.utils.ActorGestureListener
import com.badlogic.gdx.scenes.scene2d.utils.Cullable
import com.unciv.models.metadata.GameSettings
import com.unciv.UncivGame
import java.lang.Float.max
import java.lang.Float.min
@ -39,7 +40,10 @@ open class ZoomableScrollPane(
private val horizontalPadding get() = width / 2
private val verticalPadding get() = height / 2
/** Will be set from [GameSettings.mapAutoScroll] */
var isAutoScrollEnabled = false
/** Will be set from [GameSettings.mapPanningSpeed] */
var mapPanningSpeed: Float = 6f
init {
this.addListener(zoomListener)
@ -274,21 +278,26 @@ open class ZoomableScrollPane(
if (isAutoScrollEnabled && !Gdx.input.isTouched) {
val posX = Gdx.input.x
val posY = Gdx.input.y
val posY = Gdx.input.y // Viewport coord: goes down, unlike world coordinates
if (posX <= 2f) {
scrollX -= 3f
} else if (posX >= stage.viewport.screenWidth - 2f) {
scrollX += 3f
val deltaX = when {
posX <= 2 -> 1
posX >= stage.viewport.screenWidth - 2 -> -1
else -> 0
}
val deltaY = when {
posY <= 6 -> -1
posY >= stage.viewport.screenHeight - 6 -> 1
else -> 0
}
if (posY <= 6f) {
scrollY -= 3f
} else if (posY >= stage.viewport.screenHeight - 6f) {
scrollY += 3f
if (deltaX != 0 || deltaY != 0) {
// if Gdx deltaTime is > KeyboardPanningListener.deltaTime, then mouse auto scroll would be slower
// (Gdx deltaTime is measured, not a constant, depends on framerate)
// The extra factor is empirical to make mouse and WASD keyboard feel the same
val relativeSpeed = Gdx.graphics.deltaTime / KeyboardPanningListener.deltaTime * 0.3f
doKeyOrMousePanning(deltaX * relativeSpeed, deltaY * relativeSpeed)
}
updateVisualScroll()
}
super.draw(batch, parentAlpha)
}
@ -319,7 +328,21 @@ open class ZoomableScrollPane(
}
open fun restrictX(deltaX: Float): Float = scrollX - deltaX
open fun restrictY(deltaY:Float): Float = scrollY + deltaY
open fun restrictY(deltaY: Float): Float = scrollY + deltaY
/**
* Perform keyboard WASD or mouse-at-edge panning.
* Called from [KeyboardPanningListener] and [draw] if [isAutoScrollEnabled] is on.
*
* Positive [deltaX] = Left, Positive [deltaY] = DOWN
*/
fun doKeyOrMousePanning(deltaX: Float, deltaY: Float) {
if (deltaX == 0f && deltaY == 0f) return
val amountToMove = mapPanningSpeed / scaleX
scrollX = restrictX(deltaX * amountToMove)
scrollY = restrictY(deltaY * amountToMove)
updateVisualScroll()
}
override fun getFlickScrollListener(): ActorGestureListener {
return FlickScrollListener()

View File

@ -45,6 +45,7 @@ fun displayTab(
if (GUI.isWorldLoaded())
GUI.getMap().isAutoScrollEnabled = settings.mapAutoScroll
}
addScrollSpeedSlider(this, settings, optionsPopup.selectBoxMinWidth)
}
optionsPopup.addCheckbox(this, "Show unit movement arrows", settings.showUnitMovements, true) { settings.showUnitMovements = it }
@ -121,6 +122,20 @@ private fun addMinimapSizeSlider(table: Table, settings: GameSettings, selectBox
table.add(minimapSlider).minWidth(selectBoxMinWidth).pad(10f).row()
}
private fun addScrollSpeedSlider(table: Table, settings: GameSettings, selectBoxMinWidth: Float) {
table.add("Map panning speed".toLabel()).left().fillX()
val scrollSpeedSlider = UncivSlider(
0.2f, 25f, 0.2f, initial = settings.mapPanningSpeed
) {
settings.mapPanningSpeed = it
settings.save()
if (GUI.isWorldLoaded())
GUI.getMap().mapPanningSpeed = settings.mapPanningSpeed
}
table.add(scrollSpeedSlider).minWidth(selectBoxMinWidth).pad(10f).row()
}
private fun addUnitIconAlphaSlider(table: Table, settings: GameSettings, selectBoxMinWidth: Float) {
table.add("Unit icon opacity".toLabel()).left().fillX()

View File

@ -28,7 +28,7 @@ class EditorMapHolder(
internal val tileMap: TileMap,
private val onTileClick: (Tile) -> Unit
): ZoomableScrollPane(20f, 20f) {
val editorScreen = parentScreen as? com.unciv.ui.screens.mapeditorscreen.MapEditorScreen
val editorScreen = parentScreen as? MapEditorScreen
val tileGroups = HashMap<Tile, TileGroup>()
private lateinit var tileGroupMap: TileGroupMap<TileGroup>
@ -47,7 +47,7 @@ class EditorMapHolder(
reloadMaxZoom()
}
internal fun addTiles(stage: Stage) {
private fun addTiles(stage: Stage) {
val tileSetStrings = TileSetStrings()
val daTileGroups = tileMap.values.map { TileGroup(it, tileSetStrings) }
@ -108,7 +108,7 @@ class EditorMapHolder(
}
/**
* Copy-pasted from [com.unciv.ui.worldscreen.WorldMapHolder.setCenterPosition]
* Copy-pasted from [com.unciv.ui.screens.worldscreen.WorldMapHolder.setCenterPosition]
* TODO remove code duplication
*/
fun setCenterPosition(vector: Vector2, blink: Boolean = false) {

View File

@ -1,5 +1,6 @@
package com.unciv.ui.screens.mapeditorscreen
import com.badlogic.gdx.Application
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.Color
import com.unciv.UncivGame
@ -136,7 +137,10 @@ class MapEditorScreen(map: TileMap? = null): BaseScreen(), RecreateOnResize {
}
for (oldPanningListener in stage.root.listeners.filterIsInstance<KeyboardPanningListener>())
stage.removeListener(oldPanningListener) // otherwise they accumulate
result.mapPanningSpeed = UncivGame.Current.settings.mapPanningSpeed
stage.addListener(KeyboardPanningListener(result, allowWASD = false))
if (Gdx.app.type == Application.ApplicationType.Desktop)
result.isAutoScrollEnabled = UncivGame.Current.settings.mapAutoScroll
stage.root.addActorAt(0, result)
stage.scrollFocus = result

View File

@ -173,6 +173,7 @@ class WorldScreen(
}
mapHolder.isAutoScrollEnabled = Gdx.app.type == Application.ApplicationType.Desktop && game.settings.mapAutoScroll
mapHolder.mapPanningSpeed = game.settings.mapPanningSpeed
// Don't select unit and change selectedCiv when centering as spectator
if (viewingCiv.isSpectator())