TODOs, license under GPL
This commit is contained in:
parent
1d48cb3f38
commit
c9f824d673
|
@ -0,0 +1,15 @@
|
||||||
|
GLaunch - A FOSS Launcher for Minecraft written in Java
|
||||||
|
Copyright (C) 2021 JFronny
|
||||||
|
|
||||||
|
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/>.
|
File diff suppressed because it is too large
Load Diff
|
@ -5,7 +5,6 @@ import com.google.gson.GsonBuilder;
|
||||||
import imgui.ImGui;
|
import imgui.ImGui;
|
||||||
import imgui.ImGuiIO;
|
import imgui.ImGuiIO;
|
||||||
import imgui.flag.ImGuiConfigFlags;
|
import imgui.flag.ImGuiConfigFlags;
|
||||||
import imgui.flag.ImGuiWindowFlags;
|
|
||||||
import imgui.gl3.ImGuiImplGl3;
|
import imgui.gl3.ImGuiImplGl3;
|
||||||
import imgui.glfw.ImGuiImplGlfw;
|
import imgui.glfw.ImGuiImplGlfw;
|
||||||
import io.gitlab.jfronny.glaunch.gson.MinecraftArgumentDeserializer;
|
import io.gitlab.jfronny.glaunch.gson.MinecraftArgumentDeserializer;
|
||||||
|
@ -62,30 +61,37 @@ public class GLaunch {
|
||||||
if (!Files.exists(LIBRARIES_DIR)) Files.createDirectories(LIBRARIES_DIR);
|
if (!Files.exists(LIBRARIES_DIR)) Files.createDirectories(LIBRARIES_DIR);
|
||||||
LOGGER.info("Initializing UI");
|
LOGGER.info("Initializing UI");
|
||||||
WINDOWS.add(new MainWindow());
|
WINDOWS.add(new MainWindow());
|
||||||
GLaunch gLaunch = new GLaunch();
|
init();
|
||||||
gLaunch.init();
|
run();
|
||||||
gLaunch.run();
|
dispose();
|
||||||
gLaunch.dispose();
|
}
|
||||||
|
|
||||||
|
public static void saveConfig() {
|
||||||
|
try {
|
||||||
|
Utils.writeObject(CONFIG_PATH, CONFIG);
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.error("Could not save config", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void open(Window window) {
|
public static void open(Window window) {
|
||||||
WINDOWS.add(window);
|
WINDOWS.add(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ImGuiImplGlfw imGuiGlfw = new ImGuiImplGlfw();
|
private static final ImGuiImplGlfw imGuiGlfw = new ImGuiImplGlfw();
|
||||||
private final ImGuiImplGl3 imGuiGl3 = new ImGuiImplGl3();
|
private static final ImGuiImplGl3 imGuiGl3 = new ImGuiImplGl3();
|
||||||
|
|
||||||
private String glslVersion = null;
|
private static String glslVersion = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pointer to the native GLFW window.
|
* Pointer to the native GLFW window.
|
||||||
*/
|
*/
|
||||||
protected long handle;
|
protected static long handle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to initialize application.
|
* Method to initialize application.
|
||||||
*/
|
*/
|
||||||
protected void init() {
|
protected static void init() {
|
||||||
initWindow();
|
initWindow();
|
||||||
initImGui();
|
initImGui();
|
||||||
imGuiGlfw.init(handle, true);
|
imGuiGlfw.init(handle, true);
|
||||||
|
@ -95,7 +101,7 @@ public class GLaunch {
|
||||||
/**
|
/**
|
||||||
* Method to dispose all used application resources and destroy its window.
|
* Method to dispose all used application resources and destroy its window.
|
||||||
*/
|
*/
|
||||||
protected void dispose() {
|
protected static void dispose() {
|
||||||
imGuiGl3.dispose();
|
imGuiGl3.dispose();
|
||||||
imGuiGlfw.dispose();
|
imGuiGlfw.dispose();
|
||||||
ImGui.destroyContext();
|
ImGui.destroyContext();
|
||||||
|
@ -108,7 +114,7 @@ public class GLaunch {
|
||||||
/**
|
/**
|
||||||
* Method to create and initialize GLFW window.
|
* Method to create and initialize GLFW window.
|
||||||
*/
|
*/
|
||||||
protected void initWindow() {
|
protected static void initWindow() {
|
||||||
GLFWErrorCallback.createPrint(System.err).set();
|
GLFWErrorCallback.createPrint(System.err).set();
|
||||||
|
|
||||||
if (!GLFW.glfwInit()) {
|
if (!GLFW.glfwInit()) {
|
||||||
|
@ -144,7 +150,7 @@ public class GLaunch {
|
||||||
renderBuffer();
|
renderBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void decideGlGlslVersions() {
|
private static void decideGlGlslVersions() {
|
||||||
final boolean isMac = System.getProperty("os.name").toLowerCase().contains("mac");
|
final boolean isMac = System.getProperty("os.name").toLowerCase().contains("mac");
|
||||||
if (isMac) {
|
if (isMac) {
|
||||||
glslVersion = "#version 150";
|
glslVersion = "#version 150";
|
||||||
|
@ -162,39 +168,40 @@ public class GLaunch {
|
||||||
/**
|
/**
|
||||||
* Method to initialize Dear ImGui context. Could be overridden to do custom Dear ImGui setup before application start.
|
* Method to initialize Dear ImGui context. Could be overridden to do custom Dear ImGui setup before application start.
|
||||||
*/
|
*/
|
||||||
protected void initImGui() {
|
protected static void initImGui() {
|
||||||
ImGui.createContext();
|
ImGui.createContext();
|
||||||
ImGuiIO io = ImGui.getIO();
|
ImGuiIO io = ImGui.getIO();
|
||||||
io.addConfigFlags(ImGuiConfigFlags.ViewportsEnable);
|
io.addConfigFlags(ImGuiConfigFlags.ViewportsEnable);
|
||||||
//io.setConfigViewportsNoDecoration(false);
|
//io.setConfigViewportsNoDecoration(false);
|
||||||
io.setConfigViewportsNoAutoMerge(true);
|
io.setConfigViewportsNoAutoMerge(true);
|
||||||
|
//TODO use included icons (https://www.nerdfonts.com/cheat-sheet)
|
||||||
|
//Nerd Fonts-patched ubuntu font
|
||||||
try (InputStream is = GLaunch.class.getClassLoader().getResourceAsStream("font.ttf")) {
|
try (InputStream is = GLaunch.class.getClassLoader().getResourceAsStream("font.ttf")) {
|
||||||
assert is != null;
|
assert is != null;
|
||||||
io.setFontDefault(io.getFonts().addFontFromMemoryTTF(is.readAllBytes(), 16f));
|
io.setFontDefault(io.getFonts().addFontFromMemoryTTF(is.readAllBytes(), 16f));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
applyTheme();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main application loop.
|
* Main application loop.
|
||||||
*/
|
*/
|
||||||
protected void run() {
|
protected static void run() {
|
||||||
while (!GLFW.glfwWindowShouldClose(handle)) {
|
while (!GLFW.glfwWindowShouldClose(handle)) {
|
||||||
//frame
|
//frame
|
||||||
clearBuffer();
|
clearBuffer();
|
||||||
imGuiGlfw.newFrame();
|
imGuiGlfw.newFrame();
|
||||||
if (CONFIG.darkTheme) ImGui.styleColorsDark();
|
|
||||||
else ImGui.styleColorsLight();
|
|
||||||
ImGui.newFrame();
|
ImGui.newFrame();
|
||||||
//render
|
//render
|
||||||
if (GLaunch.WINDOWS.isEmpty()) GLFW.glfwSetWindowShouldClose(handle, true); //TODO fix hs_error_pid
|
if (GLaunch.WINDOWS.isEmpty()) exit();
|
||||||
else {
|
else {
|
||||||
for (Window window : GLaunch.WINDOWS.toArray(new Window[0])) {
|
for (Window window : GLaunch.WINDOWS.toArray(new Window[0])) {
|
||||||
if (window.isNew()) window.preFirstDraw();
|
if (window.isNew()) window.preFirstDraw();
|
||||||
ImGui.begin(window.getName(), ImGuiWindowFlags.MenuBar);
|
if (ImGui.begin(window.getName(), window.getOpenState(), window.getFlags())) window.draw();
|
||||||
window.draw();
|
|
||||||
ImGui.end();
|
ImGui.end();
|
||||||
|
if (!window.getOpenState().get()) window.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//end frame
|
//end frame
|
||||||
|
@ -212,12 +219,20 @@ public class GLaunch {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clearBuffer() {
|
private static void clearBuffer() {
|
||||||
GL32.glClear(GL32.GL_COLOR_BUFFER_BIT | GL32.GL_DEPTH_BUFFER_BIT);
|
GL32.glClear(GL32.GL_COLOR_BUFFER_BIT | GL32.GL_DEPTH_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderBuffer() {
|
private static void renderBuffer() {
|
||||||
GLFW.glfwSwapBuffers(handle);
|
GLFW.glfwSwapBuffers(handle);
|
||||||
GLFW.glfwPollEvents();
|
GLFW.glfwPollEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void exit() {
|
||||||
|
GLFW.glfwSetWindowShouldClose(handle, true); //TODO fix hs_error_pid
|
||||||
|
}
|
||||||
|
public static void applyTheme() {
|
||||||
|
if (CONFIG.darkTheme) ImGui.styleColorsDark();
|
||||||
|
else ImGui.styleColorsLight();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package io.gitlab.jfronny.glaunch.util;
|
||||||
|
|
||||||
|
public interface ThrowingSupplier<T, TEx extends Throwable> {
|
||||||
|
T get() throws TEx;
|
||||||
|
}
|
|
@ -52,30 +52,18 @@ public class Utils {
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO generify
|
|
||||||
public static <T> T downloadObject(String url, Class<T> type) throws IOException {
|
public static <T> T downloadObject(String url, Class<T> type) throws IOException {
|
||||||
Path cache = GLaunch.CACHE_DIR.resolve(Integer.toString(url.hashCode()));
|
return downloadObject(url, () -> downloadString(url), type);
|
||||||
try {
|
|
||||||
String download = downloadString(url);
|
|
||||||
Files.writeString(cache, download);
|
|
||||||
return GLaunch.GSON.fromJson(download, type);
|
|
||||||
} catch (IOException e) {
|
|
||||||
if (Files.exists(cache)) {
|
|
||||||
GLaunch.LOGGER.info("Using cache for " + url, e);
|
|
||||||
try (BufferedReader br = Files.newBufferedReader(cache)) {
|
|
||||||
return GLaunch.GSON.fromJson(br, type);
|
|
||||||
} catch (IOException ioE) {
|
|
||||||
throw new IOException("Could not download object and failed loading cache", ioE);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
throw new IOException("Could not download object and no cache exists", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> T downloadObject(String url, String sha1, Class<T> type) throws IOException {
|
public static <T> T downloadObject(String url, String sha1, Class<T> type) throws IOException {
|
||||||
|
return downloadObject(url, () -> downloadString(url, sha1), type);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> T downloadObject(String url, ThrowingSupplier<String, IOException> sourceString, Class<T> type) throws IOException {
|
||||||
Path cache = GLaunch.CACHE_DIR.resolve(Integer.toString(url.hashCode()));
|
Path cache = GLaunch.CACHE_DIR.resolve(Integer.toString(url.hashCode()));
|
||||||
try {
|
try {
|
||||||
String download = downloadString(url, sha1);
|
String download = sourceString.get();
|
||||||
Files.writeString(cache, download);
|
Files.writeString(cache, download);
|
||||||
return GLaunch.GSON.fromJson(download, type);
|
return GLaunch.GSON.fromJson(download, type);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -98,7 +86,7 @@ public class Utils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> void writeObject(Path file, T object) throws IOException {
|
public static <T> void writeObject(Path file, T object) throws IOException {
|
||||||
try (BufferedWriter bw = Files.newBufferedWriter(file, StandardOpenOption.CREATE)) {
|
try (BufferedWriter bw = Files.newBufferedWriter(file, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) {
|
||||||
GLaunch.GSON.toJson(object, bw);
|
GLaunch.GSON.toJson(object, bw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package io.gitlab.jfronny.glaunch.windows;
|
||||||
|
|
||||||
|
import imgui.ImGui;
|
||||||
|
|
||||||
|
public class AboutWindow extends Window {
|
||||||
|
public AboutWindow() {
|
||||||
|
super("About");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw() {
|
||||||
|
ImGui.text("GLaunch Copyright (C) 2021 JFronny");
|
||||||
|
ImGui.text("This program comes with ABSOLUTELY NO WARRANTY.");
|
||||||
|
ImGui.text("This is free software, and you are welcome to redistribute it under certain conditions.");
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,4 +12,9 @@ public class LogWindow extends Window {
|
||||||
public void draw() {
|
public void draw() {
|
||||||
MapAppender.LOG.forEach(ImGui::textUnformatted);
|
MapAppender.LOG.forEach(ImGui::textUnformatted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFlags() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,52 @@
|
||||||
package io.gitlab.jfronny.glaunch.windows;
|
package io.gitlab.jfronny.glaunch.windows;
|
||||||
|
|
||||||
import imgui.ImGui;
|
import imgui.ImGui;
|
||||||
|
import imgui.flag.ImGuiWindowFlags;
|
||||||
|
import imgui.type.ImBoolean;
|
||||||
import io.gitlab.jfronny.glaunch.GLaunch;
|
import io.gitlab.jfronny.glaunch.GLaunch;
|
||||||
|
|
||||||
public class MainWindow extends Window {
|
public class MainWindow extends Window {
|
||||||
|
private final ImBoolean darkTheme = new ImBoolean(GLaunch.CONFIG.darkTheme);
|
||||||
|
private final ImBoolean debugTools = new ImBoolean(false);
|
||||||
public MainWindow() {
|
public MainWindow() {
|
||||||
super("GLaunch");
|
super("GLaunch");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFlags() {
|
||||||
|
return ImGuiWindowFlags.MenuBar | ImGuiWindowFlags.AlwaysAutoResize;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw() {
|
public void draw() {
|
||||||
if (ImGui.button("Close")) close();
|
ImGui.beginMenuBar();
|
||||||
ImGui.sameLine();
|
if (ImGui.beginMenu("File")) {
|
||||||
if (ImGui.button("New")) GLaunch.open(new NewInstanceWindow());
|
if (ImGui.menuItem("New Instance")) GLaunch.open(new NewInstanceWindow());
|
||||||
ImGui.sameLine();
|
if (ImGui.menuItem("Exit GLaunch2")) GLaunch.exit();
|
||||||
if (ImGui.button("Style")) GLaunch.open(new StyleWindow());
|
ImGui.endMenu();
|
||||||
if (ImGui.button("Log")) GLaunch.open(new LogWindow()); //TODO remember windows
|
}
|
||||||
//ImGui.showAboutWindow();
|
if (ImGui.beginMenu("Settings")) {
|
||||||
//ImGui.showUserGuide();
|
if (ImGui.checkbox("Dark Theme", darkTheme)) {
|
||||||
//ImGui.showMetricsWindow();
|
GLaunch.CONFIG.darkTheme = darkTheme.get();
|
||||||
//ImGui.showStyleEditor();
|
GLaunch.saveConfig();
|
||||||
|
GLaunch.applyTheme();
|
||||||
|
}
|
||||||
|
ImGui.endMenu();
|
||||||
|
}
|
||||||
|
if (ImGui.beginMenu("Help")) {
|
||||||
|
if (ImGui.menuItem("About")) GLaunch.open(new AboutWindow());
|
||||||
|
if (ImGui.menuItem("Log")) GLaunch.open(new LogWindow());
|
||||||
|
ImGui.checkbox("Debug Tools", debugTools);
|
||||||
|
ImGui.endMenu();
|
||||||
|
}
|
||||||
|
ImGui.endMenuBar();
|
||||||
|
|
||||||
|
if (debugTools.get()) {
|
||||||
|
ImGui.showDemoWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO if no instance
|
||||||
|
ImGui.text("You have not yet created an instance");
|
||||||
|
ImGui.text("Use File->New Instance to do so");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,12 +36,12 @@ public class NewInstanceWindow extends Window {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw() {
|
public void draw() {
|
||||||
if (ImGui.button("Cancel")) close(); //TODO use actual close button
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case Configure -> {
|
case Configure -> {
|
||||||
if (ImGui.checkbox("Show snapshots", snapshots)) {
|
if (ImGui.checkbox("Show snapshots", snapshots)) {
|
||||||
boolean prev = GLaunch.CONFIG.snapshots;
|
boolean prev = GLaunch.CONFIG.snapshots;
|
||||||
GLaunch.CONFIG.snapshots = snapshots.get();
|
GLaunch.CONFIG.snapshots = snapshots.get();
|
||||||
|
GLaunch.saveConfig();
|
||||||
//fix version index
|
//fix version index
|
||||||
int i = getVersions(GLaunch.CONFIG.snapshots).indexOf(getVersions(prev).get(version.get()));
|
int i = getVersions(GLaunch.CONFIG.snapshots).indexOf(getVersions(prev).get(version.get()));
|
||||||
if (i == -1) version.set(0);
|
if (i == -1) version.set(0);
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
package io.gitlab.jfronny.glaunch.windows;
|
|
||||||
|
|
||||||
import imgui.ImGui;
|
|
||||||
|
|
||||||
//TODO remove
|
|
||||||
public class StyleWindow extends Window {
|
|
||||||
public StyleWindow() {
|
|
||||||
super("Styles");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw() {
|
|
||||||
if (ImGui.button("Close")) close();
|
|
||||||
ImGui.showAboutWindow();
|
|
||||||
ImGui.showDemoWindow();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +1,13 @@
|
||||||
package io.gitlab.jfronny.glaunch.windows;
|
package io.gitlab.jfronny.glaunch.windows;
|
||||||
|
|
||||||
|
import imgui.flag.ImGuiWindowFlags;
|
||||||
|
import imgui.type.ImBoolean;
|
||||||
import io.gitlab.jfronny.glaunch.GLaunch;
|
import io.gitlab.jfronny.glaunch.GLaunch;
|
||||||
|
|
||||||
public abstract class Window {
|
public abstract class Window {
|
||||||
private final String name;
|
private final String name;
|
||||||
private boolean isNew = true;
|
private boolean isNew = true;
|
||||||
|
private ImBoolean openState = new ImBoolean(true);
|
||||||
|
|
||||||
public Window(String name) {
|
public Window(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
@ -19,6 +22,7 @@ public abstract class Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
|
openState.set(false);
|
||||||
GLaunch.WINDOWS.remove(this);
|
GLaunch.WINDOWS.remove(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,4 +33,12 @@ public abstract class Window {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getFlags() {
|
||||||
|
return ImGuiWindowFlags.AlwaysAutoResize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImBoolean getOpenState() {
|
||||||
|
return openState;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue