mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-12 17:07:55 -04:00
wip education ui
This commit is contained in:
parent
cd6a256b75
commit
b3812ad487
@ -38,14 +38,16 @@ Internally it is running minecraft 1.16.5 in the background.
|
||||
|
||||
## System requirements
|
||||
|
||||
- OS: Windows/Linux/macOS
|
||||
- OS: Windows/Linux/macOS (FreeBSD, [Android](https://gitlab.bixilon.de/bixilon/minosoft/-/issues/71), Chrome OS, iOS are not supported)
|
||||
- CPU: x64/x86 processor (arm 64 is supported on macOS and linux)
|
||||
- Memory: At least 150 MB free, 300 MB recommended
|
||||
- Memory: At least 150 MB free, 300 MB+ recommended
|
||||
- GPU: Pretty much anything will work, it just needs to support OpenGL 3.3+ (gpus form 2010 up)
|
||||
- Disk space: The executable (60MB) + 3 MB for assets like textures
|
||||
- Java 11+
|
||||
- No network is required (only for starting once, but it can also run completely offline, see #Offline)
|
||||
|
||||
Minosoft is really optimized and runs on really little hardware, ideal for schools/people with old computers.
|
||||
|
||||
Sadly due to not having opengl, the raspberry pi (or similar arm boards) are not supported, see [#77](https://gitlab.bixilon.de/bixilon/minosoft/-/issues/77) for more details.
|
||||
|
||||
## Offline
|
||||
|
@ -523,7 +523,7 @@ tasks.withType<JavaCompile> {
|
||||
}
|
||||
|
||||
application {
|
||||
mainClass.set("de.bixilon.minosoft.Minosoft")
|
||||
mainClass.set("de.bixilon.minosoft.education.MinosoftEducation")
|
||||
}
|
||||
|
||||
var destination: File? = null
|
||||
|
@ -17,16 +17,20 @@ import de.bixilon.kutil.observer.DataObserver.Companion.observe
|
||||
import de.bixilon.kutil.shutdown.AbstractShutdownReason
|
||||
import de.bixilon.kutil.shutdown.ShutdownManager
|
||||
import de.bixilon.minosoft.Minosoft
|
||||
import de.bixilon.minosoft.assets.IntegratedAssets
|
||||
import de.bixilon.minosoft.assets.minecraft.index.IndexAssetsType
|
||||
import de.bixilon.minosoft.assets.util.InputStreamUtil.readJson
|
||||
import de.bixilon.minosoft.config.profile.profiles.account.AccountProfileManager
|
||||
import de.bixilon.minosoft.config.profile.profiles.audio.AudioProfileManager
|
||||
import de.bixilon.minosoft.config.profile.profiles.rendering.RenderingProfileManager
|
||||
import de.bixilon.minosoft.config.profile.profiles.resources.ResourcesProfileManager
|
||||
import de.bixilon.minosoft.data.accounts.Account
|
||||
import de.bixilon.minosoft.data.accounts.types.offline.OfflineAccount
|
||||
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
|
||||
import de.bixilon.minosoft.education.config.EducationC
|
||||
import de.bixilon.minosoft.education.world.EducationGenerator
|
||||
import de.bixilon.minosoft.education.world.EducationStorage
|
||||
import de.bixilon.minosoft.gui.eros.education.EducationUI
|
||||
import de.bixilon.minosoft.local.LocalConnection
|
||||
import de.bixilon.minosoft.protocol.network.session.play.PlaySession
|
||||
import de.bixilon.minosoft.protocol.network.session.play.PlaySessionStates.Companion.disconnected
|
||||
@ -37,7 +41,7 @@ import de.bixilon.minosoft.util.logging.LogLevels
|
||||
import de.bixilon.minosoft.util.logging.LogMessageType
|
||||
|
||||
object MinosoftEducation {
|
||||
val config: EducationC = EducationC()
|
||||
var config: EducationC = EducationC()
|
||||
|
||||
private fun getAccount(): Account {
|
||||
val profile = AccountProfileManager.selected
|
||||
@ -72,6 +76,9 @@ object MinosoftEducation {
|
||||
}
|
||||
session::error.observe(this) { ShutdownManager.shutdown(reason = AbstractShutdownReason.CRASH) }
|
||||
session.connect()
|
||||
|
||||
val ui = EducationUI(session)
|
||||
ui.show()
|
||||
}
|
||||
|
||||
fun setup() {
|
||||
@ -92,13 +99,18 @@ object MinosoftEducation {
|
||||
ResourcesProfileManager.selected.assets.indexAssetsTypes += IndexAssetsType.LANGUAGE
|
||||
}
|
||||
|
||||
fun loadSettings() {
|
||||
Log.log(LogMessageType.LOADING, LogLevels.VERBOSE) { "Loading education.json" }
|
||||
val stream = IntegratedAssets.DEFAULT.getOrNull(minosoft("education.json")) ?: return
|
||||
this.config = stream.readJson()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
setup()
|
||||
Minosoft.main(emptyArray())
|
||||
Minosoft.main(args)
|
||||
postSetup()
|
||||
|
||||
// TODO: load education.json
|
||||
loadSettings()
|
||||
|
||||
start()
|
||||
}
|
||||
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2024 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.eros.education
|
||||
|
||||
import de.bixilon.kutil.shutdown.ShutdownManager
|
||||
import de.bixilon.minosoft.data.entities.entities.Entity
|
||||
import de.bixilon.minosoft.data.registries.blocks.types.Block
|
||||
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
|
||||
import de.bixilon.minosoft.gui.eros.controller.JavaFXWindowController
|
||||
import de.bixilon.minosoft.gui.eros.util.JavaFXUtil
|
||||
import de.bixilon.minosoft.protocol.network.session.play.PlaySession
|
||||
import javafx.fxml.FXML
|
||||
import javafx.scene.control.ComboBox
|
||||
import javafx.scene.control.Slider
|
||||
import javafx.scene.control.TextField
|
||||
import javafx.scene.text.TextFlow
|
||||
import java.lang.reflect.Method
|
||||
|
||||
class EducationUI(
|
||||
val session: PlaySession,
|
||||
) : JavaFXWindowController() {
|
||||
@FXML private lateinit var blockX: TextField
|
||||
@FXML private lateinit var blockY: TextField
|
||||
@FXML private lateinit var blockZ: TextField
|
||||
@FXML private lateinit var blockFX: ComboBox<Block>
|
||||
|
||||
@FXML private lateinit var entityFX: ComboBox<Entity>
|
||||
|
||||
@FXML private lateinit var timeStatus: TextFlow
|
||||
@FXML private lateinit var timeSpeed: Slider
|
||||
|
||||
@FXML private lateinit var codeStatus: TextFlow
|
||||
|
||||
@FXML private lateinit var functionsFX: ComboBox<Method>
|
||||
|
||||
public override fun show() {
|
||||
JavaFXUtil.openModalAsync("Minosoft Education UI", LAYOUT, this) { super.show() }
|
||||
}
|
||||
|
||||
override fun postInit() {
|
||||
stage.setOnCloseRequest {
|
||||
if (closing) return@setOnCloseRequest
|
||||
ShutdownManager.shutdown()
|
||||
}
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
super.close()
|
||||
ShutdownManager.shutdown()
|
||||
}
|
||||
|
||||
fun reset() = Unit
|
||||
fun killAll() = Unit
|
||||
fun freeze() = Unit
|
||||
|
||||
fun getBlock() = Unit
|
||||
fun setBlock() = Unit
|
||||
|
||||
fun kill() = Unit
|
||||
fun highlight() = Unit
|
||||
fun teleport() = Unit
|
||||
|
||||
fun pause() = Unit
|
||||
fun step() = Unit
|
||||
|
||||
|
||||
fun stop() = Unit
|
||||
fun restart() = Unit
|
||||
fun reload() = Unit
|
||||
|
||||
fun invoke() = Unit
|
||||
|
||||
companion object {
|
||||
val LAYOUT = minosoft("eros/education/education.fxml")
|
||||
}
|
||||
}
|
@ -41,11 +41,7 @@ import javafx.beans.property.BooleanPropertyBase
|
||||
import javafx.css.StyleableProperty
|
||||
import javafx.fxml.FXMLLoader
|
||||
import javafx.scene.*
|
||||
import javafx.scene.control.Alert
|
||||
import javafx.scene.control.Labeled
|
||||
import javafx.scene.control.TableColumnBase
|
||||
import javafx.scene.control.TextField
|
||||
import javafx.scene.control.Tooltip
|
||||
import javafx.scene.control.*
|
||||
import javafx.scene.image.Image
|
||||
import javafx.scene.input.KeyCode
|
||||
import javafx.scene.input.KeyEvent
|
||||
@ -59,6 +55,7 @@ import java.io.File
|
||||
|
||||
object JavaFXUtil {
|
||||
private const val DEFAULT_STYLE = "resource:minosoft:eros/style.css"
|
||||
private const val EDUCATION_STYLE = "resource:minosoft:eros/education/education.css"
|
||||
private val SHOWING_FIELD = Window::class.java.getFieldOrNull("showing")!!
|
||||
private val MARK_INVALID_METHOD = BooleanPropertyBase::class.java.getDeclaredMethod("markInvalid").apply { setUnsafeAccessible() }
|
||||
private val stages = StageList()
|
||||
@ -81,6 +78,7 @@ object JavaFXUtil {
|
||||
stage ?: break
|
||||
stage.scene.stylesheets.clear()
|
||||
stage.scene.stylesheets.add(DEFAULT_STYLE)
|
||||
stage.scene.stylesheets.add(EDUCATION_STYLE)
|
||||
stage.scene.stylesheets.add(getThemeURL(it))
|
||||
}
|
||||
}
|
||||
@ -95,6 +93,7 @@ object JavaFXUtil {
|
||||
stage.icons.setAll(MINOSOFT_LOGO)
|
||||
|
||||
stage.scene.stylesheets.add(DEFAULT_STYLE)
|
||||
stage.scene.stylesheets.add(EDUCATION_STYLE)
|
||||
val theme = ErosProfileManager.selected.theme.theme
|
||||
stage.scene.stylesheets.add(getThemeURL(theme))
|
||||
|
||||
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2024 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
.status {
|
||||
-fx-border-width: 3px;
|
||||
-fx-border-style: solid;
|
||||
}
|
||||
|
||||
.status-running {
|
||||
-fx-border-color: green;
|
||||
-fx-background-color: lightgreen;
|
||||
-fx-text-fill: white;
|
||||
}
|
||||
|
||||
.status-paused {
|
||||
-fx-border-color: orange;
|
||||
-fx-background-color: yellow;
|
||||
-fx-text-fill: black;
|
||||
}
|
||||
|
||||
.status-terminated {
|
||||
-fx-border-color: red;
|
||||
-fx-background-color: lightred;
|
||||
-fx-text-fill: black;
|
||||
}
|
140
src/main/resources/assets/minosoft/eros/education/education.fxml
Normal file
140
src/main/resources/assets/minosoft/eros/education/education.fxml
Normal file
@ -0,0 +1,140 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.Text?>
|
||||
<?import javafx.scene.text.TextFlow?>
|
||||
<!--
|
||||
~ Minosoft
|
||||
~ Copyright (C) 2020-2024 Moritz Zwerger
|
||||
~
|
||||
~ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
~
|
||||
~ This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
-->
|
||||
|
||||
<HBox xmlns:fx="http://javafx.com/fxml/1" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/18">
|
||||
<GridPane>
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="NEVER"/>
|
||||
<ColumnConstraints hgrow="ALWAYS"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints vgrow="SOMETIMES"/>
|
||||
<RowConstraints vgrow="SOMETIMES"/>
|
||||
<RowConstraints vgrow="SOMETIMES"/>
|
||||
<RowConstraints vgrow="SOMETIMES"/>
|
||||
<RowConstraints vgrow="SOMETIMES"/>
|
||||
<RowConstraints vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
|
||||
<Label text="World"/>
|
||||
<HBox GridPane.columnIndex="1">
|
||||
<Button onAction="#reset" text="Reset"/>
|
||||
<Button onAction="#killAll" text="Remove all"/>
|
||||
<Button onAction="#freeze" text="Freeze"/>
|
||||
</HBox>
|
||||
|
||||
|
||||
<Label text="Blocks" GridPane.rowIndex="1"/>
|
||||
<GridPane GridPane.columnIndex="1" GridPane.rowIndex="1">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="NEVER"/>
|
||||
<ColumnConstraints hgrow="ALWAYS"/>
|
||||
<ColumnConstraints hgrow="NEVER"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<GridPane>
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="NEVER"/>
|
||||
<ColumnConstraints hgrow="ALWAYS" minWidth="50.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints vgrow="SOMETIMES"/>
|
||||
<RowConstraints vgrow="SOMETIMES"/>
|
||||
<RowConstraints vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<Label text="X"/>
|
||||
<Label text="Y" GridPane.rowIndex="1"/>
|
||||
<Label text="Z" GridPane.rowIndex="2"/>
|
||||
<TextField fx:id="blockX" text="0" GridPane.columnIndex="1"/>
|
||||
<TextField fx:id="blockY" text="0" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
|
||||
<TextField fx:id="blockZ" text="0" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
|
||||
</GridPane>
|
||||
<ComboBox fx:id="blockFX" prefWidth="200.0" GridPane.columnIndex="1"/>
|
||||
<VBox GridPane.columnIndex="2">
|
||||
<Button onAction="#getBlock" text="Get"/>
|
||||
<Button onAction="#setBlock" text="Set"/>
|
||||
</VBox>
|
||||
</GridPane>
|
||||
|
||||
<Label text="Entities" GridPane.rowIndex="2"/>
|
||||
<GridPane GridPane.columnIndex="1" GridPane.rowIndex="2">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="NEVER" minWidth="200.0" prefWidth="200.0"/>
|
||||
<ColumnConstraints hgrow="ALWAYS"/>
|
||||
</columnConstraints>
|
||||
<ComboBox fx:id="entityFX" prefWidth="200.0"/>
|
||||
<HBox GridPane.columnIndex="1">
|
||||
<Button onAction="#kill" text="Remove"/>
|
||||
<Button onAction="#highlight" text="Highlight"/>
|
||||
<Button onAction="#teleport" text="Teleport"/>
|
||||
</HBox>
|
||||
<rowConstraints>
|
||||
<RowConstraints/>
|
||||
</rowConstraints>
|
||||
</GridPane>
|
||||
|
||||
|
||||
<Label text="Time" GridPane.rowIndex="3"/>
|
||||
<GridPane GridPane.columnIndex="1" GridPane.rowIndex="3">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<TextFlow fx:id="timeStatus" styleClass="status,status-running">
|
||||
<Text text="Running"/>
|
||||
</TextFlow>
|
||||
<Slider fx:id="timeSpeed" GridPane.columnIndex="1"/>
|
||||
<HBox GridPane.columnIndex="2">
|
||||
<Button onAction="#pause" text="Pause"/>
|
||||
<Button onAction="#step" text="Step"/>
|
||||
</HBox>
|
||||
</GridPane>
|
||||
|
||||
<Label text="Code" GridPane.rowIndex="4"/>
|
||||
<HBox GridPane.columnIndex="1" GridPane.rowIndex="4">
|
||||
<TextFlow fx:id="codeStatus" styleClass="status,status-terminated">
|
||||
<Text text="Terminated"/>
|
||||
</TextFlow>
|
||||
<Button onAction="#stop" text="Terminate"/>
|
||||
<Button onAction="#restart" text="Restart"/>
|
||||
<Button onAction="#reload" text="Reload"/>
|
||||
</HBox>
|
||||
|
||||
<Label text="Functions" GridPane.rowIndex="5"/>
|
||||
<GridPane GridPane.columnIndex="1" GridPane.rowIndex="5">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="NEVER" prefWidth="200.0"/>
|
||||
<ColumnConstraints hgrow="ALWAYS"/>
|
||||
</columnConstraints>
|
||||
<ComboBox fx:id="functionsFX" prefWidth="200.0"/>
|
||||
<HBox GridPane.columnIndex="1">
|
||||
<Button onAction="#invoke" text="Invoke"/>
|
||||
</HBox>
|
||||
<rowConstraints>
|
||||
<RowConstraints/>
|
||||
</rowConstraints>
|
||||
</GridPane>
|
||||
</GridPane>
|
||||
</HBox>
|
Loading…
x
Reference in New Issue
Block a user