mirror of
https://github.com/badvision/jace.git
synced 2024-05-31 19:41:33 +00:00
275 lines
9.6 KiB
Java
275 lines
9.6 KiB
Java
/*
|
|
* To change this license header, choose License Headers in Project Properties.
|
|
* To change this template file, choose Tools | Templates
|
|
* and open the template in the editor.
|
|
*/
|
|
package jace.ide;
|
|
|
|
import jace.JaceApplication;
|
|
import jace.ide.Program.DocumentType;
|
|
import jace.ide.Program.Option;
|
|
import java.io.File;
|
|
import java.net.URL;
|
|
import java.util.EnumMap;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
import java.util.Optional;
|
|
import java.util.ResourceBundle;
|
|
import javafx.collections.ListChangeListener;
|
|
import javafx.event.ActionEvent;
|
|
import javafx.event.Event;
|
|
import javafx.fxml.FXML;
|
|
import javafx.scene.control.Alert;
|
|
import javafx.scene.control.ButtonType;
|
|
import javafx.scene.control.Label;
|
|
import javafx.scene.control.Menu;
|
|
import javafx.scene.control.MenuItem;
|
|
import javafx.scene.control.Tab;
|
|
import javafx.scene.control.TabPane;
|
|
import javafx.scene.control.ToggleGroup;
|
|
import javafx.scene.control.ToolBar;
|
|
import javafx.scene.web.WebView;
|
|
import javafx.stage.FileChooser;
|
|
|
|
/**
|
|
* FXML Controller class
|
|
*
|
|
* @author blurry
|
|
*/
|
|
public class IdeController {
|
|
|
|
@FXML // ResourceBundle that was given to the FXMLLoader
|
|
private ResourceBundle resources;
|
|
|
|
@FXML // URL location of the FXML file that was given to the FXMLLoader
|
|
private URL location;
|
|
|
|
@FXML // fx:id="saveMenuItem"
|
|
private MenuItem saveMenuItem; // Value injected by FXMLLoader
|
|
|
|
@FXML // fx:id="saveAllMenuItem"
|
|
private MenuItem saveAllMenuItem; // Value injected by FXMLLoader
|
|
|
|
@FXML // fx:id="saveAsMenuItem"
|
|
private MenuItem saveAsMenuItem; // Value injected by FXMLLoader
|
|
|
|
@FXML // fx:id="closeMenuItem"
|
|
private MenuItem closeMenuItem; // Value injected by FXMLLoader
|
|
|
|
@FXML // fx:id="closeAllMenuItem"
|
|
private MenuItem closeAllMenuItem; // Value injected by FXMLLoader
|
|
|
|
@FXML // fx:id="editMenu"
|
|
private Menu editMenu; // Value injected by FXMLLoader
|
|
|
|
@FXML // fx:id="runMenu"
|
|
private Menu runMenu; // Value injected by FXMLLoader
|
|
|
|
@FXML // fx:id="autocompile"
|
|
private ToggleGroup autocompile; // Value injected by FXMLLoader
|
|
|
|
@FXML // fx:id="tabPane"
|
|
private TabPane tabPane; // Value injected by FXMLLoader
|
|
|
|
@FXML // fx:id="statusBar"
|
|
private ToolBar statusBar; // Value injected by FXMLLoader
|
|
|
|
@FXML
|
|
void onCloseAllClicked(ActionEvent event) {
|
|
openDocuments.forEach((Tab t, Program proxy) -> {
|
|
if (!event.isConsumed()) {
|
|
closeTab(t, event);
|
|
}
|
|
});
|
|
}
|
|
|
|
@FXML
|
|
void onCloseClicked(ActionEvent event) {
|
|
getCurrentTab().ifPresent((t) -> closeTab(t, event));
|
|
}
|
|
|
|
public Optional<Tab> getCurrentTab() {
|
|
return Optional.ofNullable(tabPane.getSelectionModel().getSelectedItem());
|
|
}
|
|
|
|
public Optional<Program> getCurrentProgram() {
|
|
return getCurrentTab().map(t -> openDocuments.get(t));
|
|
}
|
|
|
|
@FXML
|
|
void newApplesoftBasicClicked(ActionEvent event) {
|
|
Program tab = createTab(DocumentType.applesoft, null, true);
|
|
}
|
|
|
|
@FXML
|
|
void newApplesoftBasicFromMemoryClicked(ActionEvent event) {
|
|
Alert warningAlert = new Alert(Alert.AlertType.CONFIRMATION);
|
|
warningAlert.setTitle("Is Applesoft running?");
|
|
warningAlert.setContentText("If you proceed and applesoft is not running or there is no active program then the emulator might freeze. Press Cancel if you are unsure.");
|
|
Optional<ButtonType> result = warningAlert.showAndWait();
|
|
if (result.get() == ButtonType.OK) {
|
|
Program tab = createTab(DocumentType.applesoft, null, false);
|
|
}
|
|
}
|
|
|
|
@FXML
|
|
void newAssemblyListingClicked(ActionEvent event) {
|
|
createTab(DocumentType.assembly, null, false);
|
|
}
|
|
|
|
@FXML
|
|
void newHexdataClicked(ActionEvent event) {
|
|
createTab(DocumentType.hex, null, false);
|
|
}
|
|
|
|
@FXML
|
|
void newPlainTextClicked(ActionEvent event) {
|
|
createTab(DocumentType.plain, null, false);
|
|
}
|
|
|
|
Map<Tab, Program> openDocuments = new HashMap<>();
|
|
Map<Option, Object> globalOptions = new EnumMap<>(Option.class);
|
|
|
|
private Program createTab(DocumentType type, File document, boolean isBlank) {
|
|
WebView editor = new WebView();
|
|
Program proxy = new Program(type, globalOptions);
|
|
proxy.initEditor(editor, document, isBlank);
|
|
Tab t = new Tab(proxy.getName(), editor);
|
|
tabPane.getTabs().add(t);
|
|
openDocuments.put(t, proxy);
|
|
t.setOnCloseRequest(this::handleCloseTabRequest);
|
|
return proxy;
|
|
}
|
|
|
|
private void handleCloseTabRequest(Event e) {
|
|
Tab t = (Tab) e.getTarget();
|
|
closeTab(t, e);
|
|
}
|
|
|
|
private void closeTab(Tab t, Event e) {
|
|
tabPane.getTabs().remove(t);
|
|
openDocuments.remove(t);
|
|
}
|
|
|
|
@FXML
|
|
void onOpenClicked(ActionEvent event) {
|
|
FileChooser chooser = new FileChooser();
|
|
chooser.setTitle("Open document");
|
|
for (DocumentType type : Program.DocumentType.values()) {
|
|
chooser.getExtensionFilters().add(
|
|
new FileChooser.ExtensionFilter(type.name(), type.extensions)
|
|
);
|
|
}
|
|
chooser.getExtensionFilters().addAll(
|
|
new FileChooser.ExtensionFilter("All Files", "*.*")
|
|
);
|
|
File file = chooser.showOpenDialog(JaceApplication.getApplication().primaryStage);
|
|
if (file != null && file.isFile() && file.exists()) {
|
|
DocumentType type = DocumentType.fromFile(file);
|
|
createTab(type, file, true);
|
|
}
|
|
}
|
|
|
|
@FXML
|
|
void onSaveAllClicked(ActionEvent event) {
|
|
openDocuments.forEach((Tab t, Program p) -> {
|
|
if (p.isChanged()) {
|
|
if (p.getFile().isPresent()) {
|
|
p.save(p.getFile().get());
|
|
t.setText(p.getName());
|
|
} else {
|
|
tabPane.getSelectionModel().select(t);
|
|
onSaveAsClicked(event);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
@FXML
|
|
void onSaveAsClicked(ActionEvent event) {
|
|
getCurrentProgram().ifPresent(program -> {
|
|
program.save(chooseFileToSave(program.getType()));
|
|
getCurrentTab().get().setText(program.getName());
|
|
});
|
|
}
|
|
|
|
@FXML
|
|
void onSaveClicked(ActionEvent event) {
|
|
getCurrentProgram().ifPresent(program -> {
|
|
program.save(
|
|
program.getFile()
|
|
.orElseGet(() -> chooseFileToSave(program.getType())));
|
|
getCurrentTab().get().setText(program.getName());
|
|
});
|
|
}
|
|
|
|
private File chooseFileToSave(DocumentType type) {
|
|
FileChooser chooser = new FileChooser();
|
|
chooser.setTitle("Save " + type.name() + " document");
|
|
chooser.getExtensionFilters().addAll(
|
|
new FileChooser.ExtensionFilter(type.name(), type.extensions),
|
|
new FileChooser.ExtensionFilter("All Files", "*.*")
|
|
);
|
|
return chooser.showSaveDialog(JaceApplication.getApplication().primaryStage);
|
|
}
|
|
|
|
@FXML
|
|
void executeClicked(ActionEvent event) {
|
|
getCurrentProgram().ifPresent(program -> {
|
|
program.execute();
|
|
updateStatusMessages(program.lastResult);
|
|
});
|
|
}
|
|
|
|
@FXML
|
|
void testCompileClicked(ActionEvent event) {
|
|
getCurrentProgram().ifPresent(program -> {
|
|
program.test();
|
|
updateStatusMessages(program.lastResult);
|
|
});
|
|
}
|
|
|
|
@FXML
|
|
void viewCompilerOutputClicked(ActionEvent event) {
|
|
|
|
}
|
|
|
|
@FXML
|
|
void viewSymbolTableClicked(ActionEvent event) {
|
|
|
|
}
|
|
|
|
@FXML // This method is called by the FXMLLoader when initialization is complete
|
|
public void initialize() {
|
|
assert saveMenuItem != null : "fx:id=\"saveMenuItem\" was not injected: check your FXML file 'editor.fxml'.";
|
|
assert saveAllMenuItem != null : "fx:id=\"saveAllMenuItem\" was not injected: check your FXML file 'editor.fxml'.";
|
|
assert saveAsMenuItem != null : "fx:id=\"saveAsMenuItem\" was not injected: check your FXML file 'editor.fxml'.";
|
|
assert closeMenuItem != null : "fx:id=\"closeMenuItem\" was not injected: check your FXML file 'editor.fxml'.";
|
|
assert closeAllMenuItem != null : "fx:id=\"closeAllMenuItem\" was not injected: check your FXML file 'editor.fxml'.";
|
|
assert editMenu != null : "fx:id=\"editMenu\" was not injected: check your FXML file 'editor.fxml'.";
|
|
assert runMenu != null : "fx:id=\"runMenu\" was not injected: check your FXML file 'editor.fxml'.";
|
|
assert autocompile != null : "fx:id=\"autocompile\" was not injected: check your FXML file 'editor.fxml'.";
|
|
assert tabPane != null : "fx:id=\"tabPane\" was not injected: check your FXML file 'editor.fxml'.";
|
|
assert statusBar != null : "fx:id=\"statusBar\" was not injected: check your FXML file 'editor.fxml'.";
|
|
|
|
tabPane.getTabs().addListener((ListChangeListener.Change<? extends Tab> c) -> {
|
|
boolean hasNoItems = c.getList().isEmpty();
|
|
saveMenuItem.setDisable(hasNoItems);
|
|
saveAsMenuItem.setDisable(hasNoItems);
|
|
saveAllMenuItem.setDisable(hasNoItems);
|
|
closeMenuItem.setDisable(hasNoItems);
|
|
closeAllMenuItem.setDisable(hasNoItems);
|
|
editMenu.setDisable(hasNoItems);
|
|
runMenu.setDisable(hasNoItems);
|
|
});
|
|
}
|
|
|
|
private void updateStatusMessages(CompileResult lastResult) {
|
|
String message = "Compiler was " + (lastResult.isSuccessful() ? " successful" : " NOT SUCCESSFUL");
|
|
message += " -- ";
|
|
message += lastResult.getErrors().size() + " error(s) and "+lastResult.getWarnings().size()+" warning(s) reported.";
|
|
statusBar.getItems().clear();
|
|
statusBar.getItems().add(new Label(message));
|
|
}
|
|
}
|