Skip to content

Commit

Permalink
update UI for usability improvements and preparing for swiss (#15)
Browse files Browse the repository at this point in the history
Signed-off-by: John Burns <[email protected]>
  • Loading branch information
wakingrufus authored Jan 22, 2018
1 parent 4f477fa commit 8a6567e
Show file tree
Hide file tree
Showing 25 changed files with 683 additions and 218 deletions.
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
buildscript {
ext.kotlin_version = '1.2.10'
ext.kotlin_version = '1.2.20'
ext.jackson_version = '2.9.2'
dependencies {
classpath group: 'de.dynamicfiles.projects.gradle.plugins', name: 'javafx-gradle-plugin', version: '8.8.2'
Expand All @@ -13,7 +13,7 @@ plugins {
id 'java'
id 'application'
id 'idea'
id "org.jetbrains.kotlin.jvm" version "1.2.10"
id "org.jetbrains.kotlin.jvm" version "1.2.20"
id 'jacoco'
}
apply plugin: 'javafx-gradle-plugin'
Expand All @@ -24,7 +24,7 @@ repositories {
maven { url 'https://jitpack.io' }
}

version = "0.5.2"
version = "0.6.0"

dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.github.wakingrufus.eloleague.data

import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import javafx.collections.FXCollections
import java.util.*
import kotlin.collections.ArrayList

@JsonIgnoreProperties(ignoreUnknown = true)
data class LeagueData(
Expand All @@ -13,5 +15,6 @@ data class LeagueData(
var xi: Int = 1000,
var kFactorBase: Int = 32,
var trialPeriod: Int = 10,
var trialKFactorMultiplier: Int = 2
var trialKFactorMultiplier: Int = 2,
val tournamentData: List<SwissTournamentData> = ArrayList()
)
27 changes: 27 additions & 0 deletions src/main/kotlin/com/github/wakingrufus/eloleague/data/SwissData.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.github.wakingrufus.eloleague.data

import com.fasterxml.jackson.annotation.JsonIgnoreProperties


data class SwissTeamData(
val id: String,
val name: String,
val playerIds: Set<String>)

data class SwissGameData(val id: String,
val gameId: String,
val winningTeam: String)

data class SwissRound(val results: List<SwissResultData>)

data class SwissResultData(val pairing: SwissPairing, val games: List<SwissGameData>)

data class SwissPairing(val id: String,
val teamIds: Pair<String, String>)

@JsonIgnoreProperties(ignoreUnknown = true)
data class SwissTournamentData(val id: String,
val startTime: Long,
val name: String,
val teams: List<SwissTeamData>,
val rounds: Map<Int, SwissRound>)
24 changes: 11 additions & 13 deletions src/main/kotlin/com/github/wakingrufus/eloleague/game/GameItem.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,14 @@ import javafx.beans.property.SimpleIntegerProperty
import javafx.beans.property.SimpleListProperty
import javafx.beans.property.SimpleStringProperty
import javafx.collections.FXCollections
import tornadofx.getValue
import tornadofx.setValue
import tornadofx.*
import java.time.Instant
import java.time.ZoneOffset
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter


class GameItem(id: String,
timestamp: String = DateTimeFormatter.ISO_DATE_TIME.format(ZonedDateTime.now()),
timestamp: String = DateTimeFormatter.ISO_DATE_TIME.format(Instant.now().atOffset(ZoneOffset.UTC)),
team1Players: List<PlayerItem> = FXCollections.observableArrayList(),
team2Players: List<PlayerItem> = FXCollections.observableArrayList(),
team1Score: Int = 0,
Expand All @@ -32,23 +30,23 @@ class GameItem(id: String,
val team2PlayersProperty = SimpleListProperty<PlayerItem>(this, "team2Players", FXCollections.observableArrayList(team2Players))
var team2Players by team2PlayersProperty

val team1ScoreProperty = SimpleIntegerProperty(team1Score, "team1Score", team1Score)
val team1ScoreProperty = SimpleIntegerProperty(this, "team1Score", team1Score)
var team1Score by team1ScoreProperty

val team2ScoreProperty = SimpleIntegerProperty(team2Score, "team2Score", team2Score)
val team2ScoreProperty = SimpleIntegerProperty(this, "team2Score", team2Score)
var team2Score by team2ScoreProperty

}


fun toGameData(item: GameItem): GameData {
fun GameItem.toData(): GameData {
return GameData(
id = item.id,
timestamp = Instant.from(DateTimeFormatter.ISO_DATE_TIME.parse(item.timestamp)).toEpochMilli(),
team1PlayerIds = item.team1Players.toList().map { it.id },
team2PlayerIds = item.team2Players.toList().map { it.id },
team1Score = item.team1Score,
team2Score = item.team2Score
id = this.id,
timestamp = Instant.from(DateTimeFormatter.ISO_DATE_TIME.parse(this.timestamp)).toEpochMilli(),
team1PlayerIds = this.team1Players.toList().map { it.id },
team2PlayerIds = this.team2Players.toList().map { it.id },
team1Score = this.team1Score,
team2Score = this.team2Score
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.github.wakingrufus.eloleague.game

import com.github.wakingrufus.eloleague.league.LeagueModel
import javafx.beans.property.ReadOnlyStringWrapper
import javafx.stage.StageStyle
import mu.KLogging
import tornadofx.*
import java.util.*

class GameListView : Fragment("Games") {
companion object : KLogging()

val gameModel: GameModel by inject()
val leagueModel: LeagueModel by inject()

override val root = fieldset("Games") {
tableview(leagueModel.games) {
column("Time", GameItem::timestamp)
column<GameItem, String>("Team 1") {
ReadOnlyStringWrapper(it.value.team1Players.joinToString(transform = { player -> player.name }))
}
column("Team 1 score", GameItem::team1ScoreProperty)
column<GameItem, String>("Team 2") {
ReadOnlyStringWrapper(it.value.team2Players.joinToString(transform = { player -> player.name }))
}
column("Team 2 score", GameItem::team2ScoreProperty)
bindSelected(gameModel)
columnResizePolicy = SmartResize.POLICY
}
buttonbar {
button("Add Game").setOnAction {
gameModel.rebind { item = GameItem(id = UUID.randomUUID().toString()) }
editGame()
}
button("Edit Game").setOnAction {
editGame()
}
}
}

private fun editGame() {
find<GameView>().apply {
openModal(stageStyle = StageStyle.UTILITY, block = true)
}
}
}
82 changes: 16 additions & 66 deletions src/main/kotlin/com/github/wakingrufus/eloleague/game/GameView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,20 @@ package com.github.wakingrufus.eloleague.game

import com.github.wakingrufus.eloleague.isValidInt
import com.github.wakingrufus.eloleague.league.LeagueModel
import com.github.wakingrufus.eloleague.player.PlayerChooserView
import com.github.wakingrufus.eloleague.player.PlayerItem
import javafx.collections.ObservableList
import javafx.stage.StageStyle
import com.github.wakingrufus.eloleague.player.PlayerListBuilder
import mu.KLogging
import tornadofx.*
import java.time.format.DateTimeFormatter

class GameView : Fragment("Player View") {
class GameView : Fragment("Edit Game") {
companion object : KLogging()

val gameModel: GameModel by inject()
val leagueModel: LeagueModel by param()
val onSave: (GameItem) -> Unit by param({ _ -> })

val choosePlayer: (allPlayers: ObservableList<PlayerItem>, selectedPlayers: ObservableList<PlayerItem>) -> PlayerItem? = { allPlayers, selectedPlayers ->
find<PlayerChooserView>(
mapOf("players" to allPlayers.filter { lp -> !selectedPlayers.any { lp.id == it.id } }.observable())
).apply {
openModal(stageStyle = StageStyle.UTILITY, block = true)
}.choice
}
val leagueModel: LeagueModel by inject()

init {
gameModel.team1Players.onChange { gameModel.markDirty(gameModel.team1Players) }
gameModel.team2Players.onChange { gameModel.markDirty(gameModel.team2Players) }

}

override val root = form {
Expand All @@ -47,36 +34,11 @@ class GameView : Fragment("Player View") {
}
hbox {
fieldset("Team 1") {
vbox {
style {
minHeight = 8.em
}
children.bind(gameModel.team1Players.value) { player: PlayerItem ->
field(player.name) {
button("Remove") {
action {
gameModel.team1Players.value.remove(player)
}
}
}
}

}
button("Add Player") {
action {
gameModel.team1Players.value.add(choosePlayer(
leagueModel.players.value,
gameModel.team1Players.value))
}
/*
gameModel.addValidator(this, gameModel.team1Players) {
if (gameModel.team1Players.value.isEmpty()) {
tornadofx.error("team 1 required")
}
null
}
*/
}
this += find<PlayerListBuilder>(mapOf(
"selectedPlayers" to gameModel.team1Players.value,
"otherIneligiblePlayers" to gameModel.team2Players.value,
"allPlayers" to leagueModel.players.value
))
field("team 1 score") {
textfield(gameModel.team1Score).validator {
if (isValidInt(it)) null else error("must be numeric")
Expand All @@ -85,25 +47,11 @@ class GameView : Fragment("Player View") {
}

fieldset("Team 2") {
vbox {
style {
minHeight = 8.em
}
children.bind(gameModel.team2Players.value) { player: PlayerItem ->
field(player.name) {
button("Remove") {
action {
gameModel.team2Players.value.remove(player)
}
}
}
}
}
button("Add Player").setOnAction {
gameModel.team2Players.value.add(choosePlayer(
leagueModel.players.value,
gameModel.team2Players.value))
}
this += find<PlayerListBuilder>(mapOf(
"selectedPlayers" to gameModel.team2Players.value,
"otherIneligiblePlayers" to gameModel.team1Players.value,
"allPlayers" to leagueModel.players.value
))
field("team 2 score") {
textfield(gameModel.team2Score).validator {
if (isValidInt(it)) null else error("must be numeric")
Expand All @@ -116,7 +64,9 @@ class GameView : Fragment("Player View") {
enableWhen(gameModel.dirty.and(gameModel.valid))
action {
gameModel.commit()
onSave(gameModel.item)
if (leagueModel.games.value.none { it.id == gameModel.id.value }) {
leagueModel.games.value.addAll(gameModel.item)
}
close()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ package com.github.wakingrufus.eloleague.league
import com.github.wakingrufus.elo.League
import com.github.wakingrufus.eloleague.data.LeagueData
import com.github.wakingrufus.eloleague.game.GameItem
import com.github.wakingrufus.eloleague.game.toData
import com.github.wakingrufus.eloleague.player.PlayerItem
import com.github.wakingrufus.eloleague.swiss.SwissTournamentItem
import com.github.wakingrufus.eloleague.swiss.toData
import javafx.beans.property.SimpleIntegerProperty
import javafx.beans.property.SimpleListProperty
import javafx.beans.property.SimpleStringProperty
import javafx.collections.FXCollections
import tornadofx.getValue
import tornadofx.setValue
import tornadofx.*

val defaultLeague: League = League()

Expand Down Expand Up @@ -47,6 +49,9 @@ class LeagueItem(id: String,
val gamesProperty = SimpleListProperty<GameItem>(this, "games", FXCollections.observableArrayList())
var games by gamesProperty

val tournamentsProperty = SimpleListProperty<SwissTournamentItem>(this, "tournaments", FXCollections.observableArrayList())
var tournaments by tournamentsProperty

}

fun toData(leagueItem: LeagueItem): LeagueData {
Expand All @@ -59,20 +64,21 @@ fun toData(leagueItem: LeagueItem): LeagueData {
trialPeriod = leagueItem.trialPeriod,
trialKFactorMultiplier = leagueItem.trialKFactorMultiplier,
players = leagueItem.players.map { com.github.wakingrufus.eloleague.player.toData(it) }.toSet(),
games = leagueItem.games.map { com.github.wakingrufus.eloleague.game.toGameData(it) }.toList()
games = leagueItem.games.map(GameItem::toData).toList(),
tournamentData = leagueItem.tournaments.map(SwissTournamentItem::toData).toList()
)
}

fun fromData(leagueData: LeagueData): LeagueItem {
val item = LeagueItem(
id = leagueData.id,
name = leagueData.name
name = leagueData.name,
startingRating = leagueData.startingRating,
xi = leagueData.xi,
kFactorBase = leagueData.kFactorBase,
trialPeriod = leagueData.trialPeriod,
trialKFactorMultiplier = leagueData.trialKFactorMultiplier
)
item.startingRatingProperty.set(leagueData.startingRating)
item.xiProperty.set(leagueData.xi)
item.kFactorBaseProperty.set(leagueData.kFactorBase)
item.trialPeriodProperty.set(leagueData.trialPeriod)
item.trialKFactorMultiplierProperty.set(leagueData.trialKFactorMultiplier)
item.playersProperty.setAll(leagueData.players.map { com.github.wakingrufus.eloleague.player.fromData(it) })
item.gamesProperty.setAll(leagueData.games.map { com.github.wakingrufus.eloleague.game.fromData(it) })
item.games.forEach({ game ->
Expand All @@ -83,5 +89,8 @@ fun fromData(leagueData: LeagueData): LeagueItem {
player.name = item.players.first { it.id == player.id }?.name
})
})
if (leagueData.tournamentData.isNotEmpty()) {
item.tournamentsProperty.setAll(leagueData.tournamentData.map { com.github.wakingrufus.eloleague.swiss.fromData(it, item.players) })
}
return item
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.github.wakingrufus.eloleague.league

import tornadofx.ItemViewModel
import tornadofx.*

class LeagueModel : ItemViewModel<LeagueItem>() {
var id = bind { item?.idProperty }
Expand All @@ -12,5 +12,5 @@ class LeagueModel : ItemViewModel<LeagueItem>() {
var trialKFactorMultiplier = bind { item?.trialKFactorMultiplierProperty }
var players = bind { item?.playersProperty }
var games = bind { item?.gamesProperty }

var tournaments = bind { item?.tournamentsProperty }
}
Loading

0 comments on commit 8a6567e

Please sign in to comment.