182 lines
5.6 KiB
Kotlin
182 lines
5.6 KiB
Kotlin
|
package net.shadowfacts.phycon.block.terminal
|
||
|
|
||
|
import net.minecraft.text.TranslatableText
|
||
|
import net.minecraft.util.math.MathHelper
|
||
|
import net.shadowfacts.cacao.geometry.Axis
|
||
|
import net.shadowfacts.cacao.geometry.Point
|
||
|
import net.shadowfacts.cacao.util.Color
|
||
|
import net.shadowfacts.cacao.util.LayoutGuide
|
||
|
import net.shadowfacts.cacao.util.MouseButton
|
||
|
import net.shadowfacts.cacao.view.Label
|
||
|
import net.shadowfacts.cacao.view.StackView
|
||
|
import net.shadowfacts.cacao.view.View
|
||
|
import net.shadowfacts.cacao.view.textfield.TextField
|
||
|
import net.shadowfacts.cacao.viewcontroller.ViewController
|
||
|
import net.shadowfacts.kiwidsl.dsl
|
||
|
import net.shadowfacts.phycon.client.screen.ScrollTrackView
|
||
|
import net.shadowfacts.phycon.util.TerminalSettings
|
||
|
|
||
|
/**
|
||
|
* @author shadowfacts
|
||
|
*/
|
||
|
abstract class AbstractTerminalViewController<BE: AbstractTerminalBlockEntity, S: AbstractTerminalScreen<BE, H>, H: AbstractTerminalScreenHandler<BE>>(
|
||
|
val screen: S,
|
||
|
val handler: H,
|
||
|
val terminal: BE = handler.terminal,
|
||
|
): ViewController() {
|
||
|
|
||
|
private lateinit var scrollTrack: ScrollTrackView
|
||
|
lateinit var settingsView: View
|
||
|
private set
|
||
|
lateinit var searchField: TextField
|
||
|
private set
|
||
|
|
||
|
lateinit var pane: LayoutGuide
|
||
|
private set
|
||
|
lateinit var buffer: LayoutGuide
|
||
|
private set
|
||
|
lateinit var network: LayoutGuide
|
||
|
private set
|
||
|
lateinit var playerInv: LayoutGuide
|
||
|
private set
|
||
|
|
||
|
lateinit var networkLabel: View
|
||
|
private set
|
||
|
lateinit var playerInvLabel: View
|
||
|
private set
|
||
|
lateinit var bufferLabel: View
|
||
|
private set
|
||
|
|
||
|
override fun loadView() {
|
||
|
view = ScrollHandlingView(this)
|
||
|
}
|
||
|
|
||
|
override fun viewDidLoad() {
|
||
|
super.viewDidLoad()
|
||
|
|
||
|
pane = view.addLayoutGuide()
|
||
|
view.solver.dsl {
|
||
|
pane.centerXAnchor equalTo view.centerXAnchor
|
||
|
pane.centerYAnchor equalTo view.centerYAnchor
|
||
|
pane.widthAnchor equalTo screen.terminalBackgroundWidth
|
||
|
pane.heightAnchor equalTo screen.terminalBackgroundHeight
|
||
|
}
|
||
|
|
||
|
buffer = view.addLayoutGuide()
|
||
|
view.solver.dsl {
|
||
|
buffer.leftAnchor equalTo (pane.leftAnchor + 7)
|
||
|
buffer.topAnchor equalTo (pane.topAnchor + 17)
|
||
|
buffer.widthAnchor equalTo (18 * 3)
|
||
|
buffer.heightAnchor equalTo (18 * 6)
|
||
|
}
|
||
|
|
||
|
network = view.addLayoutGuide()
|
||
|
view.solver.dsl {
|
||
|
network.leftAnchor equalTo (pane.leftAnchor + 65)
|
||
|
network.topAnchor equalTo buffer.topAnchor
|
||
|
network.widthAnchor equalTo (18 * 9)
|
||
|
network.heightAnchor equalTo (18 * 6)
|
||
|
}
|
||
|
|
||
|
playerInv = view.addLayoutGuide()
|
||
|
view.solver.dsl {
|
||
|
playerInv.leftAnchor equalTo network.leftAnchor
|
||
|
playerInv.topAnchor equalTo (pane.topAnchor + 139)
|
||
|
playerInv.widthAnchor equalTo (18 * 9)
|
||
|
playerInv.heightAnchor equalTo 76
|
||
|
}
|
||
|
|
||
|
networkLabel = view.addSubview(Label(TranslatableText("gui.phycon.terminal_network"))).apply {
|
||
|
textColor = Color.TEXT
|
||
|
}
|
||
|
playerInvLabel = view.addSubview(Label(handler.playerInv.displayName)).apply {
|
||
|
textColor = Color.TEXT
|
||
|
}
|
||
|
bufferLabel = view.addSubview(Label(TranslatableText("gui.phycon.terminal_buffer"))).apply {
|
||
|
textColor = Color.TEXT
|
||
|
}
|
||
|
|
||
|
searchField = view.addSubview(TerminalSearchField()).apply {
|
||
|
handler = ::searchFieldChanged
|
||
|
drawBackground = false
|
||
|
}
|
||
|
searchField.becomeFirstResponder()
|
||
|
|
||
|
scrollTrack = view.addSubview(ScrollTrackView(::scrollPositionChanged))
|
||
|
|
||
|
val settingsStack = view.addSubview(StackView(Axis.VERTICAL, spacing = 2.0))
|
||
|
settingsView = settingsStack
|
||
|
TerminalSettings.allKeys.forEach { key ->
|
||
|
val button = SettingButton(key)
|
||
|
button.handler = { settingsChanged() }
|
||
|
settingsStack.addArrangedSubview(button)
|
||
|
}
|
||
|
|
||
|
view.solver.dsl {
|
||
|
networkLabel.leftAnchor equalTo network.leftAnchor
|
||
|
networkLabel.topAnchor equalTo (pane.topAnchor + 6)
|
||
|
|
||
|
bufferLabel.leftAnchor equalTo buffer.leftAnchor
|
||
|
bufferLabel.topAnchor equalTo networkLabel.topAnchor
|
||
|
|
||
|
playerInvLabel.leftAnchor equalTo playerInv.leftAnchor
|
||
|
playerInvLabel.topAnchor equalTo (pane.topAnchor + 128)
|
||
|
|
||
|
searchField.leftAnchor equalTo (pane.leftAnchor + 138)
|
||
|
searchField.topAnchor equalTo (pane.topAnchor + 5)
|
||
|
searchField.widthAnchor equalTo 80
|
||
|
searchField.heightAnchor equalTo 9
|
||
|
|
||
|
scrollTrack.leftAnchor equalTo (pane.leftAnchor + 232)
|
||
|
scrollTrack.topAnchor equalTo (network.topAnchor + 1)
|
||
|
scrollTrack.bottomAnchor equalTo (network.bottomAnchor - 1)
|
||
|
scrollTrack.widthAnchor equalTo 12
|
||
|
|
||
|
settingsStack.leftAnchor equalTo (pane.rightAnchor + 4)
|
||
|
settingsStack.topAnchor equalTo pane.topAnchor
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private fun searchFieldChanged(field: TextField) {
|
||
|
screen.searchQuery = field.text
|
||
|
screen.requestUpdatedItems()
|
||
|
}
|
||
|
|
||
|
private fun scrollPositionChanged(track: ScrollTrackView) {
|
||
|
val oldOffset = handler.currentScrollOffsetInRows()
|
||
|
|
||
|
handler.scrollPosition = track.scrollPosition.toFloat()
|
||
|
screen.scrollPosition = track.scrollPosition
|
||
|
|
||
|
if (handler.currentScrollOffsetInRows() != oldOffset) {
|
||
|
screen.requestUpdatedItems()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private fun settingsChanged() {
|
||
|
screen.requestUpdatedItems()
|
||
|
}
|
||
|
|
||
|
class TerminalSearchField: TextField("") {
|
||
|
override fun mouseClickedOutside(point: Point, mouseButton: MouseButton) {
|
||
|
// no-op
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class ScrollHandlingView(val vc: AbstractTerminalViewController<*, *, *>): View() {
|
||
|
override fun mouseScrolled(point: Point, amount: Double): Boolean {
|
||
|
var newOffsetInRows = vc.handler.currentScrollOffsetInRows() - amount.toInt()
|
||
|
newOffsetInRows = MathHelper.clamp(newOffsetInRows, 0, vc.handler.maxScrollOffsetInRows())
|
||
|
if (newOffsetInRows != vc.handler.currentScrollOffsetInRows()) {
|
||
|
val newScrollPosition = newOffsetInRows / vc.handler.maxScrollOffsetInRows().toDouble()
|
||
|
vc.screen.scrollPosition = newScrollPosition
|
||
|
vc.scrollTrack.scrollPosition = newScrollPosition
|
||
|
vc.screen.requestUpdatedItems()
|
||
|
}
|
||
|
|
||
|
return true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|