Better friends list UI (#7054)

This commit is contained in:
alexban011 2022-06-06 04:02:45 +03:00 committed by GitHub
parent 862f368075
commit 13da7c1b9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 101 additions and 111 deletions

View File

@ -561,6 +561,8 @@ Paste player ID from clipboard =
Player name already used! =
Player ID already used! =
Player ID is incorrect =
Select friend =
Select [thingToSelect] =
Friends list =
Add friend =
Edit friend =

View File

@ -21,7 +21,7 @@ class FriendList {
}
fun add(friendName: String, playerID: String): ErrorType {
for(index in friendList.indices){
for (index in friendList.indices) {
if (friendList[index].name == friendName) {
return ErrorType.NAME
} else if (friendList[index].playerID == playerID) {
@ -52,34 +52,25 @@ class FriendList {
settings.save()
}
fun getFriendsList(): MutableList<Friend> {
return friendList
}
fun getFriendsList() = friendList
fun isFriendNameInFriendList(name: String): ErrorType {
for (index in friendList.indices) {
if (name == friendList[index].name) {
return ErrorType.ALREADYINLIST
return if (friendList.firstOrNull { it.name == name } != null ) {
ErrorType.ALREADYINLIST
} else {
ErrorType.NOERROR
}
}
return ErrorType.NOERROR
}
fun isFriendIDInFriendList(id: String): ErrorType {
for (index in friendList.indices) {
if (id == friendList[index].playerID) {
return ErrorType.ALREADYINLIST
return if (friendList.firstOrNull { it.playerID == id } != null ) {
ErrorType.ALREADYINLIST
} else {
ErrorType.NOERROR
}
}
return ErrorType.NOERROR
}
fun getFriendWithId(id: String): Friend? {
for (index in friendList.indices) {
if (id == friendList[index].playerID) {
return friendList[index]
}
}
return null
}
fun getFriendById(id: String) = friendList.firstOrNull { it.playerID == id }
fun getFriendByName(name: String) = friendList.firstOrNull { it.name == name }
}

View File

@ -0,0 +1,51 @@
package com.unciv.ui.multiplayer
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup
import com.unciv.logic.multiplayer.FriendList
import com.unciv.ui.newgamescreen.PlayerPickerTable
import com.unciv.ui.utils.BaseScreen
import com.unciv.ui.utils.onClick
class FriendPickerList(
playerPicker: PlayerPickerTable,
onSelected: (String) -> Unit
) : VerticalGroup() {
private val friendDisplays = mutableMapOf<String, FriendDisplay>()
private var friendList: MutableList<FriendList.Friend>
init {
padTop(10f)
padBottom(10f)
friendList = playerPicker.getAvailableFriends().toMutableList()
for (friend in friendList) {
addFriend(friend, onSelected)
}
}
private fun addFriend(friend: FriendList.Friend, onSelected: (String) -> Unit) {
val friendDisplay = FriendDisplay(friend, onSelected)
friendDisplays[friend.name] = friendDisplay
addActor(friendDisplay)
}
}
private class FriendDisplay(
friend: FriendList.Friend,
private val onSelected: (String) -> Unit
) : Table() {
var friendName: String = friend.name
private set
val friendButton = TextButton(friendName, BaseScreen.skin)
init {
padBottom(5f)
add(friendButton)
onClick { onSelected(friendName) }
}
}

View File

@ -23,6 +23,8 @@ import com.unciv.ui.audio.MusicTrackChooserFlags
import com.unciv.ui.images.ImageGetter
import com.unciv.ui.mapeditor.GameParametersScreen
import com.unciv.logic.multiplayer.FriendList
import com.unciv.ui.multiplayer.FriendPickerList
import com.unciv.ui.pickerscreens.PickerPane
import com.unciv.ui.pickerscreens.PickerScreen
import com.unciv.ui.popup.Popup
import com.unciv.ui.utils.*
@ -237,7 +239,7 @@ class PlayerPickerTable(
* @param player current player
*/
private fun popupFriendPicker(player: Player) {
FriendPickerPopup(this, player).open()
FriendSelectionPopup(this, player, previousScreen as BaseScreen ).open()
update()
}
@ -276,109 +278,53 @@ class PlayerPickerTable(
val friendListWithRemovedFriends = friendList.friendList.toMutableList()
for (index in gameParameters.players.indices) {
val currentFriendId = previousScreen.gameSetupInfo.gameParameters.players[index].playerId
friendListWithRemovedFriends.remove(friendList.getFriendWithId(currentFriendId))
friendListWithRemovedFriends.remove(friendList.getFriendById(currentFriendId))
}
return friendListWithRemovedFriends.asSequence()
}
}
private class FriendPickerPopup(
class FriendSelectionPopup(
private val playerPicker: PlayerPickerTable,
private val player: Player
) : Popup(playerPicker.previousScreen as BaseScreen) {
companion object {
// These are used for the Close/OK buttons in the lower left/right corners:
const val buttonsCircleSize = 70f
const val buttonsIconSize = 50f
const val buttonsOffsetFromEdge = 5f
val buttonsBackColor: Color = Color.BLACK.cpy().apply { a = 0.67f }
}
player: Player,
screen: BaseScreen,
) : Popup(screen) {
// This Popup's body has two halves of same size, either side by side or arranged vertically
// depending on screen proportions - determine height for one of those
private val partHeight = screen.stage.height * (if (screen.isNarrowerThan4to3()) 0.3f else 0.4f)
private val friendsBlocksWidth = playerPicker.friendsBlocksWidth
private val friendListTable = Table()
private val friendListScroll = ScrollPane(friendListTable)
private val friendDetailsTable = Table()
private val friendDetailsScroll = ScrollPane(friendDetailsTable)
var selectedFriend: FriendList.Friend? = null
val pickerPane = PickerPane()
private var selectedFriendId: String? = null
init {
friendListScroll.setOverscroll(false, false)
add(friendListScroll).size( friendsBlocksWidth + 10f, partHeight )
// +10, because the friend table has a 5f pad, for a total of +10f
if (screen.isNarrowerThan4to3()) row()
friendDetailsScroll.setOverscroll(false, false)
add(friendDetailsScroll).size(friendsBlocksWidth + 10f, partHeight) // Same here, see above
val pickerCell = add()
.width(700f).fillX().expandX()
.minHeight(screen.stage.height * 0.5f)
.maxHeight(screen.stage.height * 0.8f)
val friends = ArrayList<FriendList.Friend>()
friends += playerPicker.getAvailableFriends()
var friendsListScrollY = 0f
var currentY = 0f
for (friend in friends) {
val friendTable = FriendTable(friend, friendsBlocksWidth, 0f) // no need for min height
val cell = friendListTable.add(friendTable)
cell.padTop(20f)
currentY += cell.padBottom + cell.prefHeight + cell.padTop
cell.row()
friendTable.onClick {
setFriendDetails(friend)
}
}
friendListScroll.layout()
pack()
if (friendsListScrollY > 0f) {
// center the selected friend vertically, getRowHeight safe because friendListScrollY > 0f ensures at least 1 row
friendsListScrollY -= (friendListScroll.height - friendListTable.getRowHeight(0)) / 2
friendListScroll.scrollY = friendsListScrollY.coerceIn(0f, friendListScroll.maxY)
}
val closeButton = "OtherIcons/Close".toImageButton(Color.FIREBRICK)
closeButton.onClick { close() }
closeButton.setPosition(buttonsOffsetFromEdge, buttonsOffsetFromEdge, Align.bottomLeft)
innerTable.addActor(closeButton)
keyPressDispatcher[KeyCharAndCode.BACK] = { close() }
val okButton = "OtherIcons/Checkmark".toImageButton(Color.LIME)
okButton.onClick { returnSelected() }
okButton.setPosition(innerTable.width - buttonsOffsetFromEdge, buttonsOffsetFromEdge, Align.bottomRight)
innerTable.addActor(okButton)
friendDetailsTable.touchable = Touchable.enabled
friendDetailsTable.onClick { returnSelected() }
}
private fun String.toImageButton(overColor: Color): Group {
val style = ImageButton.ImageButtonStyle()
val image = ImageGetter.getDrawable(this)
style.imageUp = image
style.imageOver = image.tint(overColor)
val button = ImageButton(style)
button.setSize(buttonsIconSize, buttonsIconSize)
return button.surroundWithCircle(buttonsCircleSize, false, buttonsBackColor)
}
private fun setFriendDetails(friend: FriendList.Friend) {
friendDetailsTable.clearChildren() // .clear() also clears listeners!
friendDetailsTable.add(FriendTable(friend, friendsBlocksWidth, partHeight))
selectedFriend = friend
}
fun returnSelected() {
if (selectedFriend == null) {
val friendList = FriendPickerList(playerPicker, ::friendSelected)
pickerPane.topTable.add(friendList)
pickerPane.rightSideButton.setText("Select friend".tr())
pickerPane.closeButton.onClick(::close)
pickerCell.setActor<PickerPane>(pickerPane)
pickerPane.rightSideButton.onClick {
close()
return
}
player.playerId = selectedFriend?.playerID.toString()
val friendId = selectedFriendId
if (friendId != null) {
player.playerId = selectedFriendId.toString()
close()
playerPicker.update()
}
}
}
private fun friendSelected(friendName: String) {
val friendsList = FriendList()
val friend = friendsList.getFriendByName(friendName)
if (friend != null) {
selectedFriendId = friend.playerID
}
pickerPane.setRightSideButtonEnabled(true)
pickerPane.rightSideButton.setText("Select [$friendName]".tr())
}
}
private class NationPickerPopup(