/* * Copyright (c) 2015-2017 Dzikoysk * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.panda_lang.lily.plugin.editor; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.Tab; import javafx.scene.control.TabPane; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCodeCombination; import javafx.scene.input.KeyCombination; import javafx.scene.layout.GridPane; import javafx.scene.layout.Priority; import javafx.scene.web.WebEngine; import javafx.scene.web.WebView; import org.panda_lang.core.util.FileUtils; import org.panda_lang.core.util.IOUtils; import org.panda_lang.core.util.StringUtils; import org.panda_lang.lily.Lily; import org.panda_lang.lily.util.FXMLLoaderUtils; import org.panda_lang.lily.util.ResourcesBuilder; import java.io.File; import java.net.URL; import java.util.ResourceBundle; public class EditorTab extends Tab implements Initializable { private static final String template; static { // Initialize template ResourcesBuilder resourcesBuilder = new ResourcesBuilder(); resourcesBuilder.importCss("/libs/codemirror/style.min.css"); resourcesBuilder.importScript("/libs/codemirror/script.min.js"); resourcesBuilder.importScript("/libs/codemirror/panda.min.js"); template = IOUtils.convertStreamToString(Lily.class.getResourceAsStream("/plugins/editor/editor.html")) .replace("{imports}", resourcesBuilder.toString()); } @FXML private WebView webView; private WebEngine webEngine; private String title; private boolean changed; private boolean succeeded; public EditorTab() { super(); FXMLLoaderUtils.loadElementFromResources(this, "/plugins/editor/tab.fxml"); } public static String getTemplate() { return template; } @Override public void initialize(URL location, ResourceBundle resources) { // Style webEngine = webView.getEngine(); GridPane.setHgrow(webView, Priority.ALWAYS); GridPane.setVgrow(webView, Priority.ALWAYS); } public void run(TabPane pane, File file) { if (file == null) { return; } // Tab Settings this.title = file.getName(); setText(title); // Engine settings webView.setVisible(true); webEngine.setJavaScriptEnabled(true); // Load source String source = FileUtils.getContentOfFile(file); if (source == null) { source = ""; } else { source = StringUtils.replace(source, " ", "\t"); } // Load content String content = template.replace("{code}", source); webEngine.loadContent(content); webView.setUserData(file); // Tabs pane.getTabs().add(this); pane.getSelectionModel().select(this); // Accelerators webView.getScene().getAccelerators().put(new KeyCodeCombination(KeyCode.S, KeyCombination.CONTROL_ANY), () -> { File f = (File) webView.getUserData(); String src = (String) webEngine.executeScript("editor.getValue()"); // StringUtils.replace(src, "\t", " ") FileUtils.overrideFile(f, src); setText(title); changed = false; }); // State listener webEngine.getLoadWorker().stateProperty().addListener((obs, oldValue, newValue) -> { switch (newValue) { case SUCCEEDED: { succeeded = true; } } }); // Events webView.setOnKeyPressed(key -> { if (!changed) { KeyCode keyCode = key.getCode(); if (keyCode.isLetterKey() || keyCode.isDigitKey() || keyCode.isWhitespaceKey() || keyCode == KeyCode.BACK_SPACE) { setText(title + " *"); changed = true; } } }); } public boolean isChanged() { return changed; } public boolean isSucceeded() { return succeeded; } public WebEngine getWebEngine() { return webEngine; } public WebView getWebView() { return webView; } public void setWebView(WebView webView) { this.webView = webView; } public Tab getTab() { return this; } public String getTitle() { return title; } }