All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dev.robocode.tankroyale.gui.ui.console.ConsolePanel.kt Maven / Gradle / Ivy

package dev.robocode.tankroyale.gui.ui.console

import dev.robocode.tankroyale.gui.ansi.AnsiEditorPane
import dev.robocode.tankroyale.gui.ansi.AnsiTextBuilder
import dev.robocode.tankroyale.gui.ui.extensions.JComponentExt.addButton
import dev.robocode.tankroyale.gui.ui.extensions.JComponentExt.addOkButton
import dev.robocode.tankroyale.gui.util.Clipboard
import dev.robocode.tankroyale.gui.util.EDT
import dev.robocode.tankroyale.gui.util.Event
import java.awt.BorderLayout
import javax.swing.*

open class ConsolePanel : JPanel() {

    private val ansiEditorPane = AnsiEditorPane()
    private val scrollPane = JScrollPane(ansiEditorPane).apply {
        border = null
    }

    private val onOk = Event().apply {
        subscribe(this) {
            val parentFrame = SwingUtilities.getAncestorOfClass(JFrame::class.java, ansiEditorPane) as JFrame
            parentFrame.dispose()
        }
    }
    private val onClear = Event().apply {
        subscribe(this) { clear() }
    }
    private val onCopyToClipboard = Event().apply {
        subscribe(this) { copyToClipboard() }
    }

    protected val okButton = JPanel().addOkButton(onOk)
    private val clearButton = JPanel().addButton("clear", onClear)
    private val copyToClipboardButton = JPanel().addButton("copy_to_clipboard", onCopyToClipboard)

    protected open val buttonPanel
        get() = JPanel().apply {
            add(okButton)
            add(clearButton)
            add(copyToClipboardButton)
        }

    init {
        layout = BorderLayout()
        apply {
            add(scrollPane)
            add(buttonPanel, BorderLayout.SOUTH)
        }
    }

    fun clear() {
        ansiEditorPane.text = ""
    }

    fun append(text: String, turnNumber: Int? = null) {
        val ansi = AnsiTextBuilder()

        turnNumber?.let {
            ansi.cyan().text(turnNumber - 1).defaultColor().text(' ')
        }
        ansi.text(
            text.replace("\\n", "\n")
                .replace("\\t", "\t")
                .replace("\\r", "")
        )

        EDT.enqueue {
            ansiEditorPane.apply {
                ansiKit.insertAnsi(ansiDocument, ansi.build())

                // Scroll to bottom
                caretPosition = ansiDocument.length
            }
        }
    }

    fun appendBanner(banner: String) {
        append(AnsiTextBuilder().brightGreen().text(banner).defaultColor().newline().build())
    }

    fun appendInfo(info: String, turnNumber: Int? = null) {
        append(AnsiTextBuilder().brightGreen().text(info).defaultColor().newline().build(), turnNumber)
    }

    fun appendError(error: String, turnNumber: Int? = null) {
        append(AnsiTextBuilder().brightRed().text(error).defaultColor().newline().build(), turnNumber)
    }

    fun scrollToBottom() {
        scrollPane.verticalScrollBar.apply { value = maximum }
    }

    private fun copyToClipboard() {
        // trick to get the text only without HTML tags
        ansiEditorPane.select(0, ansiEditorPane.text.length)

        // Replace no-break spaces with ordinary spaces
        val text = ansiEditorPane.selectedText.replace("\u00a0", " ")

        // copy the text to the clipboard
        Clipboard.set(text)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy