diff --git a/.forgejo/workflows/publish.yml b/.forgejo/workflows/publish.yml
index 67a8415..4a0eb0c 100644
--- a/.forgejo/workflows/publish.yml
+++ b/.forgejo/workflows/publish.yml
@@ -17,11 +17,13 @@ jobs:
java-version: 8
- name: Checkout
uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
- name: Initialize Gradle
uses: https://github.com/gradle/actions/setup-gradle@v3
- name: Build
run: ./gradlew build
- name: Publish
- run: VERSION=$(git describe --always) ./gradlew publish
+ run: VERSION=$(git rev-list --count HEAD) ./gradlew publish
env:
PUBLISH_TOKEN: ${{ secrets.PUBLISH_TOKEN }}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index b63da45..79ef6cc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,10 +5,7 @@ build/
!**/src/test/**/build/
### IntelliJ IDEA ###
-.idea/modules.xml
-.idea/jarRepositories.xml
-.idea/compiler.xml
-.idea/libraries/
+/.idea
*.iws
*.iml
*.ipr
diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index 13566b8..0000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Editor-based HTTP Client requests
-/httpRequests/
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
deleted file mode 100644
index ce08eaf..0000000
--- a/.idea/gradle.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index 2266f6b..0000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 94a25f7..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..17b33d5
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+# ClientBoot
+
+It's Grub, but for Minecraft mods.
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 096ee94..8fadd36 100644
--- a/build.gradle
+++ b/build.gradle
@@ -8,13 +8,18 @@ version = '1.0-SNAPSHOT'
repositories {
mavenCentral()
+ maven { url = 'https://git.tudbut.de/api/packages/TudbuT/maven' }
+}
+
+configurations.configureEach {
+ resolutionStrategy.cacheChangingModulesFor 60, 'seconds'
}
dependencies {
+ implementation('de.tudbut:tuddylib:+')
}
test {
- useJUnitPlatform()
}
publishing {
diff --git a/src/main/java/de/com/baseband/clientboot/CBCallback.java b/src/main/java/de/com/baseband/clientboot/CBCallback.java
new file mode 100644
index 0000000..091d5ca
--- /dev/null
+++ b/src/main/java/de/com/baseband/clientboot/CBCallback.java
@@ -0,0 +1,5 @@
+package de.com.baseband.clientboot;
+
+public interface CBCallback {
+ void run(ClientBoot boot);
+}
diff --git a/src/main/java/de/com/baseband/clientboot/CBCallbackContainer.java b/src/main/java/de/com/baseband/clientboot/CBCallbackContainer.java
new file mode 100644
index 0000000..6ed3de3
--- /dev/null
+++ b/src/main/java/de/com/baseband/clientboot/CBCallbackContainer.java
@@ -0,0 +1,11 @@
+package de.com.baseband.clientboot;
+
+class CBCallbackContainer {
+ final String name;
+ final CBCallback callback;
+
+ CBCallbackContainer(String name, CBCallback callback) {
+ this.name = name;
+ this.callback = callback;
+ }
+}
diff --git a/src/main/java/de/com/baseband/clientboot/CBWindow.java b/src/main/java/de/com/baseband/clientboot/CBWindow.java
new file mode 100644
index 0000000..57d439d
--- /dev/null
+++ b/src/main/java/de/com/baseband/clientboot/CBWindow.java
@@ -0,0 +1,167 @@
+package de.com.baseband.clientboot;
+
+import de.tudbut.tools.Lock;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+public class CBWindow extends JFrame implements WindowListener {
+
+ final Lock openLock = new Lock(true);
+ final ClientBoot parent;
+
+ final Stack> options = new Stack<>();
+ {
+ options.push(new ArrayList<>());
+ }
+ int selected = 0;
+ Lock justRanSomething = new Lock();
+
+ public CBWindow(String name, ClientBoot parent) {
+ super();
+ this.parent = parent;
+ add(new RootComponent());
+ getContentPane().setBackground(new Color(0x303030));
+ setSize(600, 400);
+ setTitle(name);
+ setResizable(false);
+ setLocation(20, 20);
+ addWindowListener(this);
+ }
+
+ public void waitForClose() {
+ setVisible(true);
+ while(poll());
+ }
+
+ public boolean poll() {
+ if (openLock.isLocked()) {
+ EventQueue.invokeLater(this::repaint);
+ openLock.waitHere(20);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void setVisible(boolean b) {
+ super.setVisible(b);
+ }
+
+ @Override
+ public void windowOpened(WindowEvent e) {
+ openLock.lock(3000);
+ }
+
+ @Override
+ public void windowClosing(WindowEvent e) {
+ setVisible(false);
+ openLock.unlock();
+ }
+
+ @Override
+ public void windowClosed(WindowEvent e) {}
+
+ @Override
+ public void windowIconified(WindowEvent e) {}
+
+ @Override
+ public void windowDeiconified(WindowEvent e) {}
+
+ @Override
+ public void windowActivated(WindowEvent e) {}
+
+ @Override
+ public void windowDeactivated(WindowEvent e) {}
+
+ private class RootComponent extends Component implements MouseListener, KeyListener {
+
+ {
+ CBWindow.this.addMouseListener(this);
+ CBWindow.this.addKeyListener(this);
+ }
+
+ @Override
+ public void paint(Graphics g) {
+ Graphics2D g2 = ((Graphics2D) g);
+ g2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
+ g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ g2.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
+ g2.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
+ g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+ g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+ g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+ g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
+
+ int y = 5;
+
+ g.setFont(new Font("Fira Code", Font.BOLD, 25));
+ g.setColor(new Color(0xcc00cc));
+ g.drawString("ClientBoot", 5, y += 25);
+
+ g.setFont(new Font("Fira Code", Font.BOLD, 15));
+
+ y += 5 + 15;
+ if(openLock.timeLeft() != Long.MAX_VALUE) {
+ g.drawString("Continuing in " + openLock.timeLeft() / 1000 + "s...", 5, y);
+ }
+
+ List list = options.peek();
+ for (int i = 0; i < list.size(); i++) {
+ if(justRanSomething.isLocked() && i == selected) {
+ g.setColor(new Color(0xee00ee));
+ g.drawString("> "+ list.get(i).name, 7, y += 2 + 15);
+ g.setColor(new Color(0xcc00cc));
+ continue;
+ }
+ g.drawString((i == selected ? "> " : "") + list.get(i).name, 5, y += 2 + 15);
+ }
+ }
+
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ openLock.lock();
+ }
+
+ @Override
+ public void mousePressed(MouseEvent e) {}
+
+ @Override
+ public void mouseReleased(MouseEvent e) {}
+
+ @Override
+ public void mouseEntered(MouseEvent e) {}
+
+ @Override
+ public void mouseExited(MouseEvent e) {}
+
+ @Override
+ public void keyTyped(KeyEvent e) {}
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ openLock.lock();
+ if(options.peek().isEmpty()) {
+ return;
+ }
+ justRanSomething.unlock();
+ if(e.getKeyCode() == KeyEvent.VK_DOWN && options.peek().size() > selected + 1) {
+ selected++;
+ }
+ if(e.getKeyCode() == KeyEvent.VK_UP && selected != 0) {
+ selected--;
+ }
+ if(e.getKeyCode() == KeyEvent.VK_ENTER) {
+ justRanSomething.lock(200);
+ options.peek().get(selected).callback.run(parent);
+ }
+ }
+
+ @Override
+ public void keyReleased(KeyEvent e) {}
+ }
+}
diff --git a/src/main/java/de/com/baseband/clientboot/ClientBoot.java b/src/main/java/de/com/baseband/clientboot/ClientBoot.java
index b4c5086..2ad6bfd 100644
--- a/src/main/java/de/com/baseband/clientboot/ClientBoot.java
+++ b/src/main/java/de/com/baseband/clientboot/ClientBoot.java
@@ -1,4 +1,53 @@
package de.com.baseband.clientboot;
+import de.tudbut.parsing.TCN;
+
+import java.util.ArrayList;
+
public class ClientBoot {
+
+ public static void main(String[] args) {
+ new ClientBoot("ClientBoot Test")
+ .option("Print something", x -> x.newScreen()
+ .option("Hello!", x1 -> System.out.println("Hello!"))
+ .option("Hellorld!", x1 -> System.out.println("Hellorld!"))
+ .option("Back", ClientBoot::back))
+ .option("Exit", ClientBoot::finish)
+ .show();
+ System.exit(0);
+ }
+
+ private final CBWindow window;
+ public final TCN data = new TCN();
+
+ public ClientBoot(String name) {
+ window = new CBWindow(name, this);
+ }
+
+ public ClientBoot newScreen() {
+ window.options.push(new ArrayList<>());
+ window.selected = 0;
+ window.justRanSomething.unlock();
+ return this;
+ }
+
+ public ClientBoot option(String name, CBCallback callback) {
+ window.options.peek().add(new CBCallbackContainer(name, callback));
+ return this;
+ }
+
+ public void back() {
+ window.options.pop();
+ window.selected = 0;
+ window.justRanSomething.unlock();
+ }
+
+ public void finish() {
+ window.windowClosing(null);
+ }
+
+ public TCN show() {
+ window.waitForClose();
+ return data;
+ }
}