dialogs now separate, creating dirs and files for later work

This commit is contained in:
Bryson Steck 2023-05-31 22:05:25 -06:00
parent b2ffd5fc3f
commit 9a16ada0f6
9 changed files with 157 additions and 139 deletions

View file

@ -58,6 +58,9 @@ import xyz.brysonsteck.ServerCraft.server.Server
import xyz.brysonsteck.ServerCraft.server.Download import xyz.brysonsteck.ServerCraft.server.Download
import xyz.brysonsteck.ServerCraft.App import xyz.brysonsteck.ServerCraft.App
import xyz.brysonsteck.ServerCraft.dialogs.Dialog import xyz.brysonsteck.ServerCraft.dialogs.Dialog
import xyz.brysonsteck.ServerCraft.dialogs.CommonDialog
import xyz.brysonsteck.ServerCraft.dialogs.KillDialog
import xyz.brysonsteck.ServerCraft.dialogs.EulaDialog
class PrimaryController { class PrimaryController {
@FXML @FXML
@ -130,9 +133,9 @@ class PrimaryController {
lateinit private var scrollPane: ScrollPane lateinit private var scrollPane: ScrollPane
lateinit private var server: Server lateinit private var server: Server
lateinit private var killDialog: Dialog
private var building = false private var building = false
private var directory = "" private var directory = ""
private var asyncResult = false
private var started = false private var started = false
private var loading = false private var loading = false
private var showingConsole = false private var showingConsole = false
@ -235,6 +238,7 @@ class PrimaryController {
onPropChange("level-seed", new) onPropChange("level-seed", new)
} }
} }
killDialog = KillDialog()
} }
@FXML @FXML
@ -369,7 +373,7 @@ class PrimaryController {
@FXML @FXML
private fun onDefaults() { private fun onDefaults() {
val res = createDialog("info", "Reset settings to defaults?\nThere is NO GOING BACK!") val res = CommonDialog("info", "Reset all settings?", "Reset settings to defaults?\nThere is NO GOING BACK!").show()
if (res) { if (res) {
server.loadProps() server.loadProps()
applyProps() applyProps()
@ -546,11 +550,11 @@ class PrimaryController {
@FXML @FXML
private fun onStart() { private fun onStart() {
if (started) { if (started) {
createDialog("warning", "You should only kill the server if\nabsolutely necessary. Data loss may occur.\nContinue anyway?", hold=false) killDialog.show()
return; return;
} }
if (!File(directory + "eula.txt").exists()) { if (!File(directory + "eula.txt").exists()) {
val res = eulaDialog() val res = EulaDialog().show()
if (res) { if (res) {
File(directory + "eula.txt").writeText("eula=true") File(directory + "eula.txt").writeText("eula=true")
} else { } else {
@ -575,7 +579,7 @@ class PrimaryController {
var cbuf = CharArray(1000) var cbuf = CharArray(1000)
reader.read(cbuf, 0, 1000) reader.read(cbuf, 0, 1000)
while (proc.isAlive) { while (proc.isAlive) {
if (asyncResult) { if (killDialog.result) {
withContext(Dispatchers.JavaFx) { withContext(Dispatchers.JavaFx) {
statusBar.text = "Killing Minecraft server..." statusBar.text = "Killing Minecraft server..."
startButton.isDisable = true startButton.isDisable = true
@ -593,8 +597,8 @@ class PrimaryController {
withContext(Dispatchers.JavaFx) {log("Stream Closed\n")} withContext(Dispatchers.JavaFx) {log("Stream Closed\n")}
} }
withContext(Dispatchers.JavaFx) { withContext(Dispatchers.JavaFx) {
statusBar.text = if (asyncResult) { statusBar.text = if (killDialog.result) {
asyncResult = false killDialog.result = false
"Server killed." "Server killed."
} else { } else {
"Server stopped." "Server stopped."
@ -611,80 +615,6 @@ class PrimaryController {
} }
} }
private fun eulaDialog(): Boolean {
var result = false
val resources = App().javaClass.getResource("icons/warning.png")
val dialog = Stage()
dialog.icons.add(Image(App().javaClass.getResourceAsStream("app.png")))
dialog.setResizable(false)
dialog.initModality(Modality.APPLICATION_MODAL);
dialog.title = directory
val scenePane = Pane()
val dialogScene = Scene(scenePane, 400.0, 150.0);
val imagePane = Pane()
val icon = Image("$resources")
imagePane.layoutX = 14.0
imagePane.layoutY = 14.0
imagePane.scaleX = 0.7
imagePane.scaleY = 0.7
imagePane.children.add(ImageView(icon))
val label = Label("Do you agree to the terms of the Minecraft End User License Agreement?")
label.isWrapText = true
label.maxWidth = 250.0
label.layoutX = 115.0
label.layoutY = 40.0
val buttonBar = ButtonBar()
buttonBar.buttonOrder = "L+R"
buttonBar.padding = Insets(10.0, 10.0, 10.0, 10.0)
buttonBar.layoutX = 0.0
buttonBar.layoutY = 107.0
buttonBar.prefWidth = 400.0
val noButton = Button("I Disagree")
noButton.onAction = EventHandler<ActionEvent>() {
result = false
dialog.hide()
}
noButton.isDefaultButton = true
val yesButton = Button("I Agree")
yesButton.onAction = EventHandler<ActionEvent>() {
result = true
dialog.hide()
}
val eula = Button("View EULA")
eula.onAction = EventHandler<ActionEvent>() {
val desktop = Desktop.getDesktop()
if (desktop.isSupported(Desktop.Action.BROWSE)) {
// most likely running on Windows or macOS
try {
desktop.browse(URI("https://account.mojang.com/documents/minecraft_eula"))
} catch (e: Exception) {
println(e)
}
} else {
// assume running on linux
try {
Runtime.getRuntime().exec("xdg-open https://account.mojang.com/documents/minecraft_eula");
} catch (e: Exception) {
println(e)
}
}
}
ButtonBar.setButtonData(eula, ButtonBar.ButtonData.LEFT)
ButtonBar.setButtonData(noButton, ButtonBar.ButtonData.RIGHT)
ButtonBar.setButtonData(yesButton, ButtonBar.ButtonData.RIGHT)
buttonBar.buttons.add(eula)
buttonBar.buttons.add(noButton)
buttonBar.buttons.add(yesButton)
scenePane.children.addAll(imagePane, label, buttonBar)
dialog.setScene(dialogScene);
dialog.showAndWait();
return result
}
private fun createDialog(type: String, msg: String, yes: String = "Yes", no: String = "No", hold: Boolean = true): Boolean {
return Dialog(type, directory, msg, yes, no, null, hold).show()
}
private fun loadServerDir(dir: String): Boolean { private fun loadServerDir(dir: String): Boolean {
directory = dir directory = dir
// exit if doesn't exist for whatever reason // exit if doesn't exist for whatever reason
@ -711,7 +641,7 @@ class PrimaryController {
statusBar.text = "Server needs to be built before starting." statusBar.text = "Server needs to be built before starting."
} else if (!hasDummy && hasServer) { } else if (!hasDummy && hasServer) {
// server created externally // server created externally
val result = createDialog("warning", "This server directory was not created by \nServerCraft. Errors may occur; copying\nthe world directories to a new folder may be\nsafer. Proceed anyway?") val result = CommonDialog("warning", directory, "This server directory was not created by \nServerCraft. Errors may occur; copying\nthe world directories to a new folder may be\nsafer. Proceed anyway?").show()
statusBar.text = "Ready." statusBar.text = "Ready."
if (result) { if (result) {
startButton.isDisable = true startButton.isDisable = true
@ -723,7 +653,7 @@ class PrimaryController {
return result return result
} else { } else {
// assume clean directory // assume clean directory
val result = createDialog("info", "There is no server in this directory.\nCreate one?") val result = CommonDialog("info", directory, "There is no server in this directory.\nCreate one?").show()
if (result) { if (result) {
File(directory + "ServerCraft").mkdir() File(directory + "ServerCraft").mkdir()
startButton.isDisable = true startButton.isDisable = true

View file

@ -0,0 +1,34 @@
package xyz.brysonsteck.ServerCraft.dialogs
import javafx.scene.control.Button
import javafx.event.EventHandler
import javafx.event.ActionEvent
class CommonDialog: Dialog {
override var type: String
override var title: String
override var msg: String
override val neutralButton: Button?
override val yesButton: Button?
override val noButton: Button?
constructor(type: String, title: String, msg: String) {
this.type = type
this.title = title
this.msg = msg
noButton = Button("No")
noButton.onAction = EventHandler<ActionEvent>() {
result = false
dialog.hide()
}
yesButton = Button("Yes")
yesButton.onAction = EventHandler<ActionEvent>() {
result = true
dialog.hide()
}
yesButton.isDefaultButton = true
neutralButton = null
}
}

View file

@ -1,57 +1,41 @@
package xyz.brysonsteck.ServerCraft.dialogs package xyz.brysonsteck.ServerCraft.dialogs
import javafx.scene.control.Button import javafx.scene.control.Button
import javafx.scene.control.Label
import javafx.scene.control.ButtonBar import javafx.scene.control.ButtonBar
import javafx.scene.control.Label
import javafx.scene.image.Image import javafx.scene.image.Image
import javafx.scene.image.ImageView import javafx.scene.image.ImageView
import javafx.scene.layout.Pane import javafx.scene.layout.Pane
import javafx.scene.Scene import javafx.scene.Scene
import javafx.stage.Stage
import javafx.stage.Modality import javafx.stage.Modality
import javafx.stage.Stage
import javafx.geometry.Insets import javafx.geometry.Insets
import javafx.event.EventHandler import javafx.event.EventHandler
import javafx.event.ActionEvent import javafx.event.ActionEvent
import xyz.brysonsteck.ServerCraft.App import xyz.brysonsteck.ServerCraft.App
open class Dialog { abstract class Dialog {
private var result = false public var result = false
private val type: String abstract val type: String
private val title: String abstract val title: String
private val msg: String abstract val msg: String
private val yes: String abstract val neutralButton: Button?
private val no: String abstract val yesButton: Button?
private val neutral: Button? abstract val noButton: Button?
private val hold: Boolean
constructor(type: String, protected var hold: Boolean = true
title: String, protected var labelOffset: Double = 40.0
msg: String, protected val dialog = Stage()
yes: String = "Yes",
no: String = "No",
neutral: Button?,
hold: Boolean = true) {
this.type = type
this.title = title
this.msg = msg
this.yes = yes
this.no = no
this.neutral = neutral
this.hold = hold
}
public fun show(): Boolean { public fun show(): Boolean {
val resources = App().javaClass.getResource("icons/$type.png") val resources = App().javaClass.getResource("icons/$type.png")
val dialog = Stage() val icon = Image("$resources")
dialog.icons.add(Image(App().javaClass.getResourceAsStream("app.png"))) dialog.icons.add(Image(App().javaClass.getResourceAsStream("app.png")))
dialog.setResizable(false) dialog.setResizable(false)
dialog.initModality(Modality.APPLICATION_MODAL); dialog.initModality(Modality.APPLICATION_MODAL);
dialog.title = title dialog.title = title
val scenePane = Pane()
val dialogScene = Scene(scenePane, 400.0, 150.0);
val imagePane = Pane() val imagePane = Pane()
val icon = Image("$resources")
imagePane.layoutX = 14.0 imagePane.layoutX = 14.0
imagePane.layoutY = 14.0 imagePane.layoutY = 14.0
imagePane.scaleX = 0.7 imagePane.scaleX = 0.7
@ -60,30 +44,27 @@ open class Dialog {
val label = Label(msg) val label = Label(msg)
label.isWrapText = true label.isWrapText = true
label.layoutX = 115.0 label.layoutX = 115.0
label.layoutY = if (type == "warning") {10.0} else {40.0} label.layoutY = labelOffset
val buttonBar = ButtonBar() val buttonBar = ButtonBar()
buttonBar.padding = Insets(10.0, 10.0, 10.0, 10.0) buttonBar.padding = Insets(10.0)
buttonBar.layoutX = 0.0 buttonBar.layoutX = 0.0
buttonBar.layoutY = 107.0 buttonBar.layoutY = 107.0
buttonBar.prefWidth = 400.0 buttonBar.prefWidth = 400.0
val noButton = Button(no) val scenePane = Pane()
noButton.onAction = EventHandler<ActionEvent>() {
result = false
dialog.hide()
}
val yesButton = Button(yes)
yesButton.onAction = EventHandler<ActionEvent>() {
result = true
dialog.hide()
}
yesButton.isDefaultButton = true
buttonBar.buttons.add(noButton)
buttonBar.buttons.add(yesButton)
scenePane.children.addAll(imagePane, label, buttonBar) scenePane.children.addAll(imagePane, label, buttonBar)
if (noButton != null) {
ButtonBar.setButtonData(noButton, ButtonBar.ButtonData.RIGHT) ButtonBar.setButtonData(noButton, ButtonBar.ButtonData.RIGHT)
ButtonBar.setButtonData(yesButton, ButtonBar.ButtonData.RIGHT)
buttonBar.buttons.add(noButton) buttonBar.buttons.add(noButton)
}
if (yesButton != null) {
ButtonBar.setButtonData(yesButton, ButtonBar.ButtonData.RIGHT)
buttonBar.buttons.add(yesButton) buttonBar.buttons.add(yesButton)
}
if (neutralButton != null) {
ButtonBar.setButtonData(neutralButton, ButtonBar.ButtonData.LEFT)
buttonBar.buttons.add(neutralButton)
}
val dialogScene = Scene(scenePane, 400.0, 150.0);
dialog.setScene(dialogScene); dialog.setScene(dialogScene);
if (hold) { if (hold) {
dialog.showAndWait(); dialog.showAndWait();

View file

@ -2,15 +2,54 @@ package xyz.brysonsteck.ServerCraft.dialogs
import xyz.brysonsteck.ServerCraft.dialogs.Dialog import xyz.brysonsteck.ServerCraft.dialogs.Dialog
import javafx.scene.control.Button import javafx.scene.control.Button
import javafx.event.EventHandler
import javafx.event.ActionEvent
import java.awt.Desktop
import java.net.URI
class EulaDialog: Dialog { class EulaDialog: Dialog {
override val type: String
override val title: String
override val msg: String
override val neutralButton: Button?
override val yesButton: Button?
override val noButton: Button?
constructor(type: String, constructor() {
title: String, type = "warning"
msg: String, title = "Minecraft End User License Agreement (EULA)"
yes: String = "Yes", msg = "Do you agree to the terms of the Minecraft End User License Agreement?"
no: String = "No",
neutral: Button?, noButton = Button("I Disagree")
hold: Boolean = true) : super(type, title, msg, yes, no, neutral, hold) noButton.onAction = EventHandler<ActionEvent>() {
result = false
dialog.hide()
}
noButton.isDefaultButton = true
yesButton = Button("I Agree")
yesButton.onAction = EventHandler<ActionEvent>() {
result = true
dialog.hide()
}
neutralButton = Button("View EULA")
neutralButton.onAction = EventHandler<ActionEvent>() {
val desktop = Desktop.getDesktop()
if (desktop.isSupported(Desktop.Action.BROWSE)) {
// most likely running on Windows or macOS
try {
desktop.browse(URI("https://account.mojang.com/documents/minecraft_eula"))
} catch (e: Exception) {
println(e)
}
} else {
// assume running on linux
try {
Runtime.getRuntime().exec("xdg-open https://account.mojang.com/documents/minecraft_eula");
} catch (e: Exception) {
println(e)
}
}
}
}
} }

View file

@ -0,0 +1,34 @@
package xyz.brysonsteck.ServerCraft.dialogs
import javafx.scene.control.Button
import javafx.event.EventHandler
import javafx.event.ActionEvent
class KillDialog: Dialog {
override val type: String
override val title: String
override val msg: String
override val neutralButton: Button?
override val yesButton: Button?
override val noButton: Button?
constructor() {
type = "warning"
title = "Server is still running!"
msg = "You should only kill the server if absolutely necessary, i.e. not being responsive after long periods of time. Data loss may occur. Continue anyway?"
hold = false
noButton = Button("No")
noButton.onAction = EventHandler<ActionEvent>() {
result = false
dialog.hide()
}
yesButton = Button("Yes")
yesButton.onAction = EventHandler<ActionEvent>() {
result = true
dialog.hide()
}
yesButton.isDefaultButton = true
neutralButton = null
}
}