diff --git a/.github/workflows/RELEASE.md b/.github/workflows/RELEASE.md index 8f4d46d3..d113617a 100644 --- a/.github/workflows/RELEASE.md +++ b/.github/workflows/RELEASE.md @@ -1,4 +1,4 @@ -See the [changelog](https://github.com/jameshball/osci-render/blob/master/CHANGELOG.md) for changes to this version. +See the [changelog](https://github.com/jameshball/osci-render/blob/master/src/main/resources/CHANGELOG.md) for changes to this version. Please report any bugs or issues on GitHub or by emailing me at [james@ball.sh](mailto:james@ball.sh). diff --git a/src/main/java/sh/ball/gui/Gui.java b/src/main/java/sh/ball/gui/Gui.java index 36b22556..3fd1ece4 100644 --- a/src/main/java/sh/ball/gui/Gui.java +++ b/src/main/java/sh/ball/gui/Gui.java @@ -6,6 +6,7 @@ import javafx.application.Platform; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; +import javafx.scene.SceneAntialiasing; import javafx.scene.image.Image; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; @@ -92,11 +93,9 @@ public class Gui extends Application { editor = new CodeEditor(); editor.initialize(); editorStage = new Stage(); - editorScene = new Scene(editor); + editorScene = new Scene(editor, 900, 600, false, SceneAntialiasing.BALANCED); editorStage.setScene(editorScene); editorStage.getIcons().add(new Image(Objects.requireNonNull(Gui.class.getResourceAsStream("/icons/icon.png")))); - editorStage.setWidth(900); - editorStage.setHeight(600); editor.prefHeightProperty().bind(editorStage.heightProperty()); editor.prefWidthProperty().bind(editorStage.widthProperty()); @@ -104,6 +103,7 @@ public class Gui extends Application { Parent projectSelectRoot = projectSelectLoader.load(); projectSelectController = projectSelectLoader.getController(); projectSelectController.setApplicationLauncher(this::launchMainApplication); + projectSelectController.setOpenBrowser(url -> getHostServices().showDocument(url)); stage.getIcons().add(new Image(Objects.requireNonNull(getClass().getResourceAsStream("/icons/icon.png")))); stage.setTitle("osci-render"); diff --git a/src/main/java/sh/ball/gui/controller/ProjectSelectController.java b/src/main/java/sh/ball/gui/controller/ProjectSelectController.java index 88c7a7f0..266168e0 100644 --- a/src/main/java/sh/ball/gui/controller/ProjectSelectController.java +++ b/src/main/java/sh/ball/gui/controller/ProjectSelectController.java @@ -1,20 +1,37 @@ package sh.ball.gui.controller; -import javafx.application.Platform; import javafx.collections.FXCollections; import javafx.collections.ObservableList; +import javafx.concurrent.Worker; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.ListView; -import javafx.scene.control.ProgressIndicator; +import javafx.scene.control.TextArea; +import javafx.scene.layout.AnchorPane; +import javafx.scene.web.WebView; +import netscape.javascript.JSObject; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.events.Event; +import org.w3c.dom.events.EventListener; +import org.w3c.dom.events.EventTarget; +import org.w3c.dom.html.HTMLAnchorElement; import sh.ball.gui.ExceptionRunnable; +import java.io.IOException; +import java.io.InputStream; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.util.ResourceBundle; +import java.util.function.Consumer; +import java.util.logging.Level; import java.util.prefs.Preferences; +import static sh.ball.gui.Gui.logger; + public class ProjectSelectController implements Initializable { private static final int MAX_ITEMS = 20; @@ -23,6 +40,7 @@ public class ProjectSelectController implements Initializable { private final Preferences userPreferences = Preferences.userNodeForPackage(getClass()); private final ObservableList recentFiles = FXCollections.observableArrayList(); private ExceptionRunnable launchMainApplication; + private Consumer openBrowser; @FXML private ListView recentFilesListView; @@ -30,6 +48,8 @@ public class ProjectSelectController implements Initializable { private Button newProjectButton; @FXML private CheckBox startMutedCheckBox; + @FXML + private WebView changelogWebView; @Override public void initialize(URL url, ResourceBundle resourceBundle) { @@ -48,9 +68,40 @@ public class ProjectSelectController implements Initializable { try { launchMainApplication.run(); } catch (Exception ex) { - throw new RuntimeException(ex); + logger.log(Level.SEVERE, ex.getMessage(), ex); } }); + + try { + String changelogHtml = new String(getClass().getResourceAsStream("/html/changelog.html").readAllBytes(), StandardCharsets.UTF_8); + changelogWebView.getEngine().loadContent(changelogHtml); + InputStream changelogInputStream = getClass().getResourceAsStream("/CHANGELOG.md"); + String changelog = new String(changelogInputStream.readAllBytes(), StandardCharsets.UTF_8); + changelogWebView.getEngine().getLoadWorker().stateProperty().addListener((e, old, state) -> { + if (state == Worker.State.SUCCEEDED) { + JSObject window = (JSObject) changelogWebView.getEngine().executeScript("window"); + window.setMember("changelog", changelog); + changelogWebView.getEngine().executeScript( + "document.getElementById('content').innerHTML = marked.parse(changelog);" + ); + Document document = changelogWebView.getEngine().getDocument(); + NodeList nodeList = document.getElementsByTagName("a"); + for (int i = 0; i < nodeList.getLength(); i++) { + Node node= nodeList.item(i); + EventTarget eventTarget = (EventTarget) node; + eventTarget.addEventListener("click", evt -> { + EventTarget target = evt.getCurrentTarget(); + HTMLAnchorElement anchorElement = (HTMLAnchorElement) target; + String href = anchorElement.getHref(); + openBrowser.accept(href); + evt.preventDefault(); + }, false); + } + } + }); + } catch (IOException e) { + logger.log(Level.SEVERE, e.getMessage(), e); + } } public void addRecentFile(String path) { @@ -81,4 +132,8 @@ public class ProjectSelectController implements Initializable { public void setApplicationLauncher(ExceptionRunnable launchMainApplication) { this.launchMainApplication = launchMainApplication; } + + public void setOpenBrowser(Consumer openBrowser) { + this.openBrowser = openBrowser; + } } diff --git a/CHANGELOG.md b/src/main/resources/CHANGELOG.md similarity index 100% rename from CHANGELOG.md rename to src/main/resources/CHANGELOG.md diff --git a/src/main/resources/css/main.css b/src/main/resources/css/main.css index 31e98d8e..5ce58372 100644 --- a/src/main/resources/css/main.css +++ b/src/main/resources/css/main.css @@ -374,4 +374,15 @@ .label.title .text { -fx-font-size: 1.5em; +} + +.text-area .content { + -fx-background-color: very_dark; +} + +.text-area { + -fx-background-color: very_dark; + -fx-border-width: 1px; + -fx-border-radius: 0; + -fx-border-color: white; } \ No newline at end of file diff --git a/src/main/resources/fxml/projectSelect.fxml b/src/main/resources/fxml/projectSelect.fxml index 6f991ffb..c2739f19 100644 --- a/src/main/resources/fxml/projectSelect.fxml +++ b/src/main/resources/fxml/projectSelect.fxml @@ -7,19 +7,22 @@ + - + - -