diff --git a/android/assets/jsons/translations/template.properties b/android/assets/jsons/translations/template.properties index 4818576302..93ac87900d 100644 --- a/android/assets/jsons/translations/template.properties +++ b/android/assets/jsons/translations/template.properties @@ -552,8 +552,27 @@ Copy user ID = Copy game ID = UserID copied to clipboard = Game ID copied to clipboard! = +Friend name = +Player ID = +Please input a name for your friend! = +Please input a player ID for your friend! = +Are you sure you want to delete this friend? = +Paste player ID from clipboard = +Player name already used! = +Player ID already used! = +Player ID is incorrect = +Friends list = +Add friend = +Edit friend = +Friend name is already in your friends list! = +Player ID is already in your friends list! = +You have to write a name for your friend! = +You have to write an ID for your friend! = +You cannot add your own player ID in your friend list! = +To add a friend, ask him to send you his player ID.\nClick the 'Add friend' button.\nInsert his player ID and a name for him.\nThen click the 'Add friend' button again.\n\nAfter that you will see him in your friends list.\n\nA new button will appear when creating a new\nmultiplayer game, which allows you to select your friend. = Set current user = Player ID from clipboard = +Player ID from friends list = To create a multiplayer game, check the 'multiplayer' toggle in the New Game screen, and for each human player insert that player's user ID. = You can assign your own user ID there easily, and other players can copy their user IDs here and send them to you for you to include them in the game. = Once you've created your game, the Game ID gets automatically copied to your clipboard so you can send it to the other players. = diff --git a/core/src/com/unciv/logic/multiplayer/FriendList.kt b/core/src/com/unciv/logic/multiplayer/FriendList.kt new file mode 100644 index 0000000000..d7773af7e0 --- /dev/null +++ b/core/src/com/unciv/logic/multiplayer/FriendList.kt @@ -0,0 +1,85 @@ +package com.unciv.logic.multiplayer + +import com.unciv.UncivGame + +class FriendList { + private val settings = UncivGame.Current.settings + var friendList = settings.multiplayer.friendList + + enum class ErrorType { + NOERROR, + NAME, + ID, + NONAME, + NOID, + YOURSELF, + ALREADYINLIST; + } + + data class Friend(val name: String, val playerID: String) { + constructor() : this("", "") + } + + fun add(friendName: String, playerID: String): ErrorType { + for(index in friendList.indices){ + if (friendList[index].name == friendName) { + return ErrorType.NAME + } else if (friendList[index].playerID == playerID) { + return ErrorType.ID + } + } + if (friendName == "") { + return ErrorType.NONAME + } else if (playerID == "") { + return ErrorType.NOID + } else if (playerID == UncivGame.Current.settings.multiplayer.userId) { + return ErrorType.YOURSELF + } + friendList.add(Friend(friendName, playerID)) + settings.save() + return ErrorType.NOERROR + } + + fun edit(friend: Friend, name: String, playerID: String) { + friendList.remove(friend) + val editedFriend = Friend(name,playerID) + friendList.add(editedFriend) + settings.save() + } + + fun delete(friend: Friend) { + friendList.remove(friend) + settings.save() + } + + fun getFriendsList(): MutableList { + return friendList + } + + fun isFriendNameInFriendList(name: String): ErrorType { + for (index in friendList.indices) { + if (name == friendList[index].name) { + return ErrorType.ALREADYINLIST + } + } + return ErrorType.NOERROR + } + + fun isFriendIDInFriendList(id: String): ErrorType { + for (index in friendList.indices) { + if (id == friendList[index].playerID) { + return ErrorType.ALREADYINLIST + } + } + return ErrorType.NOERROR + } + + fun getFriendWithId(id: String): Friend? { + for (index in friendList.indices) { + if (id == friendList[index].playerID) { + return friendList[index] + } + } + return null + } +} diff --git a/core/src/com/unciv/models/metadata/GameSettings.kt b/core/src/com/unciv/models/metadata/GameSettings.kt index 25a8acce1c..1de06ae5d7 100644 --- a/core/src/com/unciv/models/metadata/GameSettings.kt +++ b/core/src/com/unciv/models/metadata/GameSettings.kt @@ -4,6 +4,7 @@ import com.badlogic.gdx.Application import com.badlogic.gdx.Gdx import com.unciv.Constants import com.unciv.UncivGame +import com.unciv.logic.multiplayer.FriendList import com.unciv.ui.utils.Fonts import java.text.Collator import java.time.Duration @@ -159,6 +160,7 @@ enum class LocaleCode(var language: String, var country: String) { class GameSettingsMultiplayer { var userId = "" var server = Constants.dropboxMultiplayerServer + var friendList: MutableList = mutableListOf() var turnCheckerEnabled = true var turnCheckerPersistentNotificationEnabled = true var turnCheckerDelay = Duration.ofMinutes(5) diff --git a/core/src/com/unciv/ui/multiplayer/AddFriendScreen.kt b/core/src/com/unciv/ui/multiplayer/AddFriendScreen.kt new file mode 100644 index 0000000000..7c8aae2041 --- /dev/null +++ b/core/src/com/unciv/ui/multiplayer/AddFriendScreen.kt @@ -0,0 +1,71 @@ +package com.unciv.ui.multiplayer + +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.scenes.scene2d.ui.Table +import com.badlogic.gdx.scenes.scene2d.ui.TextField +import com.unciv.logic.IdChecker +import com.unciv.logic.multiplayer.FriendList +import com.unciv.models.translations.tr +import com.unciv.ui.pickerscreens.PickerScreen +import com.unciv.ui.popup.ToastPopup +import com.unciv.ui.utils.* +import java.util.* + +class AddFriendScreen(backScreen: ViewFriendsListScreen) : PickerScreen() { + init { + val friendNameTextField = TextField("", skin) + val pastePlayerIDButton = "Paste player ID from clipboard".toTextButton() + val playerIDTextField = TextField("", skin) + val friendlist = FriendList() + + topTable.add("Friend name".toLabel()).row() + friendNameTextField.messageText = "Please input a name for your friend!".tr() + topTable.add(friendNameTextField).pad(10f).padBottom(30f).width(stage.width/2).row() + + pastePlayerIDButton.onClick { + playerIDTextField.text = Gdx.app.clipboard.contents + } + + topTable.add("Player ID".toLabel()).row() + val gameIDTable = Table() + playerIDTextField.messageText = "Please input a player ID for your friend!".tr() + gameIDTable.add(playerIDTextField).pad(10f).width(2*stage.width/3 - pastePlayerIDButton.width) + gameIDTable.add(pastePlayerIDButton) + topTable.add(gameIDTable).padBottom(30f).row() + + //CloseButton Setup + closeButton.setText("Back".tr()) + closeButton.onClick { + backScreen.game.setScreen(backScreen) + } + + //RightSideButton Setup + rightSideButton.setText("Add friend".tr()) + rightSideButton.enable() + rightSideButton.onClick { + try { + UUID.fromString(IdChecker.checkAndReturnPlayerUuid(playerIDTextField.text)) + } catch (ex: Exception) { + ToastPopup("Player ID is incorrect", this) + return@onClick + } + + when (friendlist.add(friendNameTextField.text, playerIDTextField.text)) { + FriendList.ErrorType.NAME -> ToastPopup("Friend name is already in your friends list!", this) + + FriendList.ErrorType.ID -> ToastPopup("Player ID is already in your friends list!", this) + + FriendList.ErrorType.NONAME -> ToastPopup("You have to write a name for your friend!", this) + + FriendList.ErrorType.NOID -> ToastPopup("You have to write an ID for your friend!", this) + + FriendList.ErrorType.YOURSELF -> ToastPopup("You cannot add your own player ID in your friend list!", this) + + else -> { + backScreen.game.setScreen(backScreen) + backScreen.refreshFriendsList() + } + } + } + } +} diff --git a/core/src/com/unciv/ui/multiplayer/EditFriendScreen.kt b/core/src/com/unciv/ui/multiplayer/EditFriendScreen.kt new file mode 100644 index 0000000000..463f23efe9 --- /dev/null +++ b/core/src/com/unciv/ui/multiplayer/EditFriendScreen.kt @@ -0,0 +1,85 @@ +package com.unciv.ui.multiplayer + +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.graphics.Color +import com.badlogic.gdx.scenes.scene2d.ui.Table +import com.badlogic.gdx.scenes.scene2d.ui.TextField +import com.unciv.logic.IdChecker +import com.unciv.logic.multiplayer.FriendList +import com.unciv.models.translations.tr +import com.unciv.ui.pickerscreens.PickerScreen +import com.unciv.ui.popup.ToastPopup +import com.unciv.ui.popup.YesNoPopup +import com.unciv.ui.utils.* +import java.util.* + +class EditFriendScreen(selectedFriend: FriendList.Friend, backScreen: ViewFriendsListScreen) : PickerScreen() { + init { + val friendNameTextField = TextField(selectedFriend.name, skin) + val pastePlayerIDButton = "Player ID from clipboard".toTextButton() + val playerIDTextField = TextField(selectedFriend.playerID, skin) + val deleteFriendButton = "Delete".toTextButton() + val friendlist = FriendList() + + topTable.add("Friend name".toLabel()).row() + friendNameTextField.messageText = "Please input a name for your friend!".tr() + topTable.add(friendNameTextField).pad(10f).padBottom(30f).width(stage.width/2).row() + + pastePlayerIDButton.onClick { + playerIDTextField.text = Gdx.app.clipboard.contents + } + + topTable.add("Player ID".toLabel()).row() + val gameIDTable = Table() + playerIDTextField.messageText = "Please input a player ID for your friend!".tr() + gameIDTable.add(playerIDTextField).pad(10f).width(2*stage.width/3 - pastePlayerIDButton.width) + gameIDTable.add(pastePlayerIDButton) + topTable.add(gameIDTable).padBottom(30f).row() + + deleteFriendButton.onClick { + val askPopup = YesNoPopup("Are you sure you want to delete this friend?", { + friendlist.delete(selectedFriend) + backScreen.game.setScreen(backScreen) + backScreen.refreshFriendsList() + }, this) + askPopup.open() + }.apply { color = Color.RED } + topTable.add(deleteFriendButton) + + //CloseButton Setup + closeButton.setText("Back".tr()) + closeButton.onClick { + backScreen.game.setScreen(backScreen) + } + + //RightSideButton Setup + rightSideButton.setText("Save".tr()) + rightSideButton.enable() + rightSideButton.onClick { + // if no edits have been made, go back to friends list + if (selectedFriend.name == friendNameTextField.text && selectedFriend.playerID == playerIDTextField.text) { + backScreen.game.setScreen(backScreen) + backScreen.refreshFriendsList() + } + if (friendlist.isFriendNameInFriendList(friendNameTextField.text) == FriendList.ErrorType.ALREADYINLIST + && friendlist.isFriendIDInFriendList(playerIDTextField.text) == FriendList.ErrorType.ALREADYINLIST) { + ToastPopup("Player name already used!", this) + return@onClick + } + if (friendlist.isFriendIDInFriendList(playerIDTextField.text) == FriendList.ErrorType.ALREADYINLIST + && friendlist.isFriendNameInFriendList(friendNameTextField.text) == FriendList.ErrorType.ALREADYINLIST) { + ToastPopup("Player ID already used!", this) + return@onClick + } + try { + UUID.fromString(IdChecker.checkAndReturnPlayerUuid(playerIDTextField.text)) + } catch (ex: Exception) { + ToastPopup("Player ID is incorrect", this) + return@onClick + } + friendlist.edit(selectedFriend, friendNameTextField.text, playerIDTextField.text) + backScreen.game.setScreen(backScreen) + backScreen.refreshFriendsList() + } + } +} diff --git a/core/src/com/unciv/ui/multiplayer/MultiplayerScreen.kt b/core/src/com/unciv/ui/multiplayer/MultiplayerScreen.kt index ea134fc65c..b909028f7f 100644 --- a/core/src/com/unciv/ui/multiplayer/MultiplayerScreen.kt +++ b/core/src/com/unciv/ui/multiplayer/MultiplayerScreen.kt @@ -34,6 +34,9 @@ class MultiplayerScreen(previousScreen: BaseScreen) : PickerScreen() { private val copyUserIdText = "Copy user ID" private val copyUserIdButton = createCopyUserIdButton() + private val friendsListText = "Friends List" + private val friendsListButton = createFriendsListButton() + private val refreshText = "Refresh list" private val refreshButton = createRefreshButton() @@ -74,6 +77,7 @@ class MultiplayerScreen(previousScreen: BaseScreen) : PickerScreen() { table.add(copyGameIdButton).row() table.add(editButton).row() table.add(addGameButton).padBottom(30f).row() + table.add(friendsListButton).padBottom(30f).row() table.add(refreshButton).row() return table } @@ -112,6 +116,14 @@ class MultiplayerScreen(previousScreen: BaseScreen) : PickerScreen() { return btn } + fun createFriendsListButton(): TextButton { + val btn = friendsListText.toTextButton() + btn.onClick { + game.setScreen(ViewFriendsListScreen(this)) + } + return btn + } + private fun createCopyUserIdButton(): TextButton { val btn = copyUserIdText.toTextButton() btn.onClick { diff --git a/core/src/com/unciv/ui/multiplayer/ViewFriendsListScreen.kt b/core/src/com/unciv/ui/multiplayer/ViewFriendsListScreen.kt new file mode 100644 index 0000000000..68ff816df0 --- /dev/null +++ b/core/src/com/unciv/ui/multiplayer/ViewFriendsListScreen.kt @@ -0,0 +1,82 @@ +package com.unciv.ui.multiplayer + +import com.badlogic.gdx.scenes.scene2d.ui.* +import com.unciv.logic.multiplayer.FriendList +import com.unciv.ui.pickerscreens.PickerScreen +import com.unciv.ui.popup.Popup +import com.unciv.ui.utils.* +import com.unciv.ui.utils.AutoScrollPane as ScrollPane + +class ViewFriendsListScreen(previousScreen: BaseScreen) : PickerScreen() { + private val rightSideTable = Table() + private val leftSideTable = Table() + private var friendsTable = Table() + + private val addFriendButton = "Add friend".toTextButton() + private val editFriendButton = "Edit friend".toTextButton() + + private val friendsList = FriendList().getFriendsList() + private var listOfFriendsButtons = arrayListOf() + + private lateinit var selectedFriend: FriendList.Friend + + init { + setDefaultCloseAction(previousScreen) + rightSideButton.remove() + + //Help Button Setup + val tab = Table() + val helpButton = "Help".toTextButton() + helpButton.onClick { + val helpPopup = Popup(this) + helpPopup.addGoodSizedLabel("To add a friend, ask him to send you his player ID.\nClick the 'Add friend' button.\nInsert his player ID and a name for him.\nThen click the 'Add friend' button again.\n\nAfter that you will see him in your friends list.\n\nA new button will appear when creating a new\nmultiplayer game, which allows you to select your friend.").row() + + helpPopup.addCloseButton() + helpPopup.open() + } + tab.add(helpButton) + tab.x = (stage.width - helpButton.width) + tab.y = (stage.height - helpButton.height) + stage.addActor(tab) + + val mainTable = Table() + mainTable.add(ScrollPane(leftSideTable).apply { setScrollingDisabled(true, false) }).height(stage.height * 2 / 3) + mainTable.add(rightSideTable) + topTable.add(mainTable).row() + scrollPane.setScrollingDisabled(false, true) + + rightSideTable.defaults().fillX() + rightSideTable.defaults().pad(20.0f) + + addFriendButton.onClick { + game.setScreen(AddFriendScreen(this)) + } + rightSideTable.add(addFriendButton).padBottom(10f).row() + + editFriendButton.onClick { + game.setScreen(EditFriendScreen(selectedFriend,this)) + editFriendButton.disable() + } + rightSideTable.add(editFriendButton).padBottom(30f).row() + editFriendButton.disable() + + refreshFriendsList() + } + + fun refreshFriendsList() { + listOfFriendsButtons.clear() + friendsTable.clear() + + for (index in friendsList.indices) { + listOfFriendsButtons.add(friendsList[index].name.toTextButton()) + + listOfFriendsButtons[index].onClick { + selectedFriend = friendsList[index] + editFriendButton.enable() + } + friendsTable.add(listOfFriendsButtons[index]).padBottom(10f).row() + } + leftSideTable.clear() + leftSideTable.add(friendsTable) + } +} diff --git a/core/src/com/unciv/ui/newgamescreen/FriendTable.kt b/core/src/com/unciv/ui/newgamescreen/FriendTable.kt new file mode 100644 index 0000000000..590ab8d7a2 --- /dev/null +++ b/core/src/com/unciv/ui/newgamescreen/FriendTable.kt @@ -0,0 +1,38 @@ +package com.unciv.ui.newgamescreen + +import com.badlogic.gdx.graphics.Color +import com.badlogic.gdx.scenes.scene2d.Touchable +import com.badlogic.gdx.scenes.scene2d.ui.Table +import com.badlogic.gdx.utils.Align +import com.unciv.Constants +import com.unciv.logic.multiplayer.FriendList +import com.unciv.ui.utils.* + +class FriendTable(val friend: FriendList.Friend, width: Float, minHeight: Float) + : Table() { + val innerTable = Table() + + init { + val innerColor = Color.WHITE//because 0xFFFFFFFF doesn't work for some reason + val totalPadding = 30f + val internalWidth = width - totalPadding + + val titleTable = Table() + + val titleText = friend.name + val friendDisplayNameMaxWidth = internalWidth - 70f // for the friend indicator with padding + val friendDisplayLabel = WrappableLabel(titleText, friendDisplayNameMaxWidth, innerColor, Constants.headingFontSize) + if (friendDisplayLabel.prefWidth > friendDisplayNameMaxWidth - 2f) { + friendDisplayLabel.wrap = true + titleTable.add(friendDisplayLabel).width(friendDisplayNameMaxWidth) + } else { + titleTable.add(friendDisplayLabel).align(Align.center).pad(10f,0f) + } + + innerTable.add(titleTable).growX().fillY().row() + + add(innerTable).width(width).minHeight(minHeight - totalPadding) + + touchable = Touchable.enabled + } +} diff --git a/core/src/com/unciv/ui/newgamescreen/NewGameScreen.kt b/core/src/com/unciv/ui/newgamescreen/NewGameScreen.kt index 910c216b56..4d0255a46f 100644 --- a/core/src/com/unciv/ui/newgamescreen/NewGameScreen.kt +++ b/core/src/com/unciv/ui/newgamescreen/NewGameScreen.kt @@ -28,7 +28,6 @@ import java.net.URL import java.util.* import com.unciv.ui.utils.AutoScrollPane as ScrollPane - class NewGameScreen( private val previousScreen: BaseScreen, _gameSetupInfo: GameSetupInfo? = null diff --git a/core/src/com/unciv/ui/newgamescreen/PlayerPickerTable.kt b/core/src/com/unciv/ui/newgamescreen/PlayerPickerTable.kt index 97690fb57d..ea09898dcd 100644 --- a/core/src/com/unciv/ui/newgamescreen/PlayerPickerTable.kt +++ b/core/src/com/unciv/ui/newgamescreen/PlayerPickerTable.kt @@ -22,6 +22,7 @@ import com.unciv.ui.audio.MusicMood 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.pickerscreens.PickerScreen import com.unciv.ui.popup.Popup import com.unciv.ui.utils.* @@ -46,6 +47,7 @@ class PlayerPickerTable( ): Table() { val playerListTable = Table() val civBlocksWidth = if(blockWidth <= 10f) previousScreen.stage.width / 3 - 5f else blockWidth + val friendsBlocksWidth = if(blockWidth <= 10f) previousScreen.stage.width / 5 - 5f else blockWidth / 2 /** Locks player table for editing, currently unused, was previously used for scenarios and could be useful in the future.*/ var locked = false @@ -53,6 +55,8 @@ class PlayerPickerTable( /** No random civilization is available, used during map editing.*/ var noRandom = false + private val friendList = FriendList() + init { for (player in gameParameters.players) player.playerId = "" // This is to stop people from getting other users' IDs and cheating with them in multiplayer games @@ -174,6 +178,7 @@ class PlayerPickerTable( errorLabel.apply { setText("✘");setFontColor(Color.RED) } } } + onPlayerIdTextUpdated() playerIdTextField.addListener { onPlayerIdTextUpdated(); true } val currentUserId = UncivGame.Current.settings.multiplayer.userId @@ -189,7 +194,16 @@ class PlayerPickerTable( playerIdTextField.text = Gdx.app.clipboard.contents onPlayerIdTextUpdated() } - playerTable.add(copyFromClipboardButton).colspan(3).fillX().pad(5f) + playerTable.add(copyFromClipboardButton).right().colspan(3).fillX().pad(5f).row() + + //check if friends list is empty before adding the select friend button + if (friendList.friendList.isNotEmpty()) { + val selectPlayerFromFriendsList = "Player ID from friends list".toTextButton() + selectPlayerFromFriendsList.onClick { + popupFriendPicker(player) + } + playerTable.add(selectPlayerFromFriendsList).left().colspan(3).fillX().pad(5f) + } } return playerTable @@ -216,6 +230,17 @@ class PlayerPickerTable( return nationTable } + /** + * Opens Friend picking popup with all friends, + * currently available for [player] to choose, depending on current + * friends list and if another friend is selected. + * @param player current player + */ + private fun popupFriendPicker(player: Player) { + FriendPickerPopup(this, player).open() + update() + } + /** * Opens Nation picking popup with all nations, * currently available for [player] to choose, depending on current @@ -241,6 +266,119 @@ class PlayerPickerTable( .filter { it.isMajorCiv() } .filter { it.name == dontSkipNation || gameParameters.players.none { player -> player.chosenCiv == it.name } } + /** + * Returns a list of available friends. + * Skips friends already chosen. + * + * @return [Sequence] of available [FriendList.Friend]s + */ + internal fun getAvailableFriends(): Sequence { + val friendListWithRemovedFriends = friendList.friendList.toMutableList() + for (index in gameParameters.players.indices) { + val currentFriendId = previousScreen.gameSetupInfo.gameParameters.players[index].playerId + friendListWithRemovedFriends.remove(friendList.getFriendWithId(currentFriendId)) + } + return friendListWithRemovedFriends.asSequence() + } +} + +private class FriendPickerPopup( + 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 } + } + + // 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 + + 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 friends = ArrayList() + + 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) { + close() + return + } + player.playerId = selectedFriend?.playerID.toString() + close() + playerPicker.update() + } } private class NationPickerPopup(