Nazar Pohonchuk
03/01/2023, 9:13 PMclass TicTacToe(display: Display, textMetrics: TextMetrics) : Application {
private var playerMoves = Player.X
private fun getPlayerName(): String {
val playerName = playerMoves.toString()
playerMoves = playerMoves.next
return playerName
}
init {
val panel = GridPanel().apply {
rowSpacing = { 10.0 }
columnSpacing = { 10.0 }
rowSizingPolicy = FitPanel // FitContent, or custom policy
columnSizingPolicy = FitPanel // FitContent, or custom policy
for (i in 0..2)
for (j in 0..2) {
add(Cell(textMetrics, ::getPlayerName), row = i, column = j)
}
val panelSize = min(display.width, display.height) * 0.8
size = Size(panelSize, panelSize)
Resizer(this).apply { movable = false }
}
display += panel
display.layout = constrain(display.first(), center)
}
override fun shutdown() {}
}
class Cell(textMetrics: TextMetrics, getPlayerName: () -> String) : View() {
var text by renderProperty("")
init {
this.pointerChanged += object : PointerListener {
override fun clicked(event: PointerEvent) {
if (text.isEmpty()) text = getPlayerName()
}
}
}
override fun render(canvas: Canvas) {
canvas.rect(bounds.atOrigin, Blue.lighter(0.4f))
canvas.text(text, at = Point(width / 2, height / 2), color = White)
}
}
enum class Player {
X {
override fun toString(): String {
return "X";
}
},
O {
override fun toString(): String {
return "O";
}
};
val next
get() = if (this == X) O else X
}
fun main() {
application(modules = listOf(PointerModule)) {
TicTacToe(display = instance(), textMetrics = instance())
}
}
Nick
03/02/2023, 1:48 AMclass Cell(textMetrics: TextMetrics, getPlayerName: () -> String) : View() {
var textSize by renderProperty(Empty) // renderProperty so you repaint if the size updates
// could use a simple observable since you get repaint when textSize is updated
var text by observable("") { _, new ->
textSize = textMetrics.size(new)
}
init {
pointerChanged += clicked {
if (text.isEmpty()) text = getPlayerName()
}
}
override fun render(canvas: Canvas) {
// calculate the scale factor: half of the smaller side
val scaleFactor = (min(width, height) * 0.5) / textSize.width
canvas.rect(bounds.atOrigin, Blue.lighter(0.4f))
// scale the canvas and perform the text rendering. scale only applies in the following block
canvas.scale(around = Point(width/2, height/2), x = scaleFactor, y = scaleFactor) {
// text here will be scaled
text(text, at = Point((width - textSize.width) / 2, (height - textSize.height) / 2), fill = White.paint)
}
}
}