Initial commit
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.IScriptingLanguage;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Ryan Benasutti on 2/6/2016.
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
public class AddFileToGistController extends Application {
|
||||
@FXML
|
||||
public TextField filenameField;
|
||||
|
||||
@FXML
|
||||
public Button addFileButton, cancelButton;
|
||||
@FXML
|
||||
private ComboBox<String> extention;
|
||||
@FXML // fx:id="langaugeIcon"
|
||||
private ImageView langaugeIcon; // Value injected by FXMLLoader
|
||||
private String extentionStr = ".groovy";
|
||||
private String gitRepo;
|
||||
@FXML
|
||||
private TextArea description;
|
||||
|
||||
private MenuRefreshEvent refreshevent;
|
||||
|
||||
// private GHGist gistID;
|
||||
|
||||
public AddFileToGistController(String gitRepo,MenuRefreshEvent event) {
|
||||
this.gitRepo = gitRepo;
|
||||
// this.gistID = id;
|
||||
this.refreshevent = event;
|
||||
}
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
FXMLLoader loader = AssetFactory.loadLayout("layout/addFileToGist.fxml", true);
|
||||
Parent root;
|
||||
loader.setController(this);
|
||||
// This is needed when loading on MAC
|
||||
loader.setClassLoader(getClass().getClassLoader());
|
||||
root = loader.load();
|
||||
extention.getItems().clear();
|
||||
List<String> langs = ScriptingEngine.getAllLangauges();
|
||||
ObservableList<String> options = FXCollections.observableArrayList(langs);
|
||||
//
|
||||
for(String s:options){
|
||||
extention.getItems().add(s);
|
||||
}
|
||||
extention.getSelectionModel().select("Groovy");
|
||||
Image icon;
|
||||
String asset = "Script-Tab-" + extention.getSelectionModel().getSelectedItem() + ".png";
|
||||
|
||||
try {
|
||||
|
||||
icon = AssetFactory.loadAsset(asset);
|
||||
langaugeIcon.setImage(icon);
|
||||
} catch (Exception e2) {
|
||||
// TODO Auto-generated catch block
|
||||
e2.printStackTrace();
|
||||
}
|
||||
|
||||
extention.setOnAction(event -> {
|
||||
try {
|
||||
|
||||
langaugeIcon.setImage(AssetFactory
|
||||
.loadAsset(asset));
|
||||
String key = extention.getSelectionModel().getSelectedItem();
|
||||
IScriptingLanguage l = ScriptingEngine
|
||||
.getLangaugesMap()
|
||||
.get(key);
|
||||
if(l!=null){
|
||||
extentionStr= "."+l.getFileExtenetion()
|
||||
.get(0);
|
||||
}
|
||||
else
|
||||
extentionStr=".groovy";
|
||||
} catch (Exception e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Platform.runLater(() -> {
|
||||
primaryStage.setTitle("Add File to Git Repo "+gitRepo);
|
||||
|
||||
Scene scene = new Scene(root);
|
||||
primaryStage.setScene(scene);
|
||||
primaryStage.initModality(Modality.WINDOW_MODAL);
|
||||
primaryStage.setResizable(true);
|
||||
primaryStage.show();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@FXML
|
||||
public void onAddFile(ActionEvent event) {
|
||||
new Thread(()->{
|
||||
Platform.runLater(() -> {
|
||||
Stage stage = (Stage) addFileButton.getScene().getWindow();
|
||||
stage.close();
|
||||
});
|
||||
String text = filenameField.getText();
|
||||
if(!text.endsWith(extentionStr)){
|
||||
text=text+extentionStr;
|
||||
}
|
||||
|
||||
String message = description.getText();
|
||||
if(message == null || message.length()==0){
|
||||
message = text;
|
||||
}
|
||||
|
||||
if(gitRepo==null){
|
||||
gitRepo=GistHelper.createNewGist(text, message, true);
|
||||
}
|
||||
System.out.println("Adding new file"+text+" to "+gitRepo);
|
||||
try {
|
||||
ScriptingEngine.pushCodeToGit(gitRepo, ScriptingEngine.getFullBranch(gitRepo), text, "//Your code here",
|
||||
message);
|
||||
File nf = ScriptingEngine.fileFromGit(gitRepo, text);
|
||||
|
||||
BowlerStudio.createFileTab(nf);
|
||||
|
||||
refreshevent.setToLoggedIn();
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
}).start();
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void onCancel(ActionEvent event) {
|
||||
Platform.runLater(() -> {
|
||||
Stage stage = (Stage) cancelButton.getScene().getWindow();
|
||||
stage.close();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,788 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
//import com.neuronrobotics.kinematicschef.InverseKinematicsEngine;
|
||||
import com.neuronrobotics.bowlerkernel.BowlerKernelBuildInfo;
|
||||
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
|
||||
import com.neuronrobotics.bowlerstudio.assets.BowlerStudioResourceFactory;
|
||||
import com.neuronrobotics.bowlerstudio.assets.ConfigurationDatabase;
|
||||
import com.neuronrobotics.bowlerstudio.assets.StudioBuildInfo;
|
||||
import com.neuronrobotics.bowlerstudio.creature.MobileBaseCadManager;
|
||||
import com.neuronrobotics.bowlerstudio.creature.MobileBaseLoader;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.ArduinoLoader;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.PasswordManager;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.ScriptingFileWidget;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.StlLoader;
|
||||
import com.neuronrobotics.imageprovider.NativeResource;
|
||||
//import com.neuronrobotics.imageprovider.OpenCVJNILoader;
|
||||
import com.neuronrobotics.javacad.JavaCadBuildInfo;
|
||||
import com.neuronrobotics.replicator.driver.Slic3r;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.DHParameterKinematics;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.FirmataLink;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.JavaFXInitializer;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.LinkConfiguration;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.MobileBase;
|
||||
import com.neuronrobotics.sdk.common.*;
|
||||
import com.neuronrobotics.sdk.config.SDKBuildInfo;
|
||||
import com.neuronrobotics.sdk.util.ThreadUtil;
|
||||
|
||||
import eu.mihosoft.vrl.v3d.CSG;
|
||||
import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase;
|
||||
import eu.mihosoft.vrl.v3d.svg.ISVGLoadProgress;
|
||||
import eu.mihosoft.vrl.v3d.svg.SVGLoad;
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.embed.swing.JFXPanel;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Alert.AlertType;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import org.dockfx.DockPane;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.api.errors.InvalidRemoteException;
|
||||
import org.eclipse.jgit.api.errors.TransportException;
|
||||
import org.kohsuke.github.GHIssue;
|
||||
import org.kohsuke.github.GHIssueState;
|
||||
import org.kohsuke.github.GHRepository;
|
||||
import org.kohsuke.github.GitHub;
|
||||
import org.python.antlr.ast.Pass;
|
||||
import org.reactfx.util.FxTimer;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class BowlerStudio extends Application {
|
||||
final static SplashScreen splash = null;// = SplashScreen.getSplashScreen();
|
||||
private static Scene scene;
|
||||
private static boolean hasnetwork;
|
||||
private static Console out;
|
||||
private static TextArea logViewRefStatic = null;
|
||||
private static String firstVer = "";
|
||||
|
||||
private static Stage primaryStage2;
|
||||
private static File layoutFile;
|
||||
private static boolean deleteFlag = false;
|
||||
private static IssueReportingExceptionHandler reporter = new IssueReportingExceptionHandler();
|
||||
private static String lastVersion;
|
||||
|
||||
private static class Console extends OutputStream {
|
||||
private static final int LengthOfOutputLog = 5000;
|
||||
ByteList incoming = new ByteList();
|
||||
Thread update = new Thread() {
|
||||
public void run() {
|
||||
Thread.currentThread().setUncaughtExceptionHandler(new IssueReportingExceptionHandler());
|
||||
|
||||
while (true) {
|
||||
ThreadUtil.wait(150);
|
||||
if (incoming.size() > 0)
|
||||
try {
|
||||
String text = incoming.asString();
|
||||
incoming.clear();
|
||||
if (text != null && text.length() > 0)
|
||||
appendText(text);
|
||||
text = null;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public Console() {
|
||||
update.start();
|
||||
}
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public void appendText(String valueOf) {
|
||||
if (BowlerStudioModularFrame.getBowlerStudioModularFrame() == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
BowlerStudioModularFrame.getBowlerStudioModularFrame().showTerminal();
|
||||
} catch (Exception ex) {
|
||||
// frame not open yet
|
||||
ex.printStackTrace();
|
||||
}
|
||||
if (getLogViewRefStatic() != null) {
|
||||
String text = getLogViewRefStatic().getText();
|
||||
if (text.length() > LengthOfOutputLog) {
|
||||
|
||||
Platform.runLater(() -> {
|
||||
try {
|
||||
getLogViewRefStatic().deleteText(0, text.length() - LengthOfOutputLog);
|
||||
|
||||
getLogViewRefStatic().appendText(valueOf);
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
|
||||
});
|
||||
} else {
|
||||
Platform.runLater(() -> {
|
||||
getLogViewRefStatic().appendText(valueOf);
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
System.err.print(valueOf);
|
||||
}
|
||||
|
||||
public void write(int b) throws IOException {
|
||||
incoming.add(b);
|
||||
// appendText(String.valueOf((char)b));
|
||||
// if(b=='[')
|
||||
// new RuntimeException().printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static OutputStream getOut() {
|
||||
if (out == null)
|
||||
out = new Console();
|
||||
return out;
|
||||
}
|
||||
|
||||
public static MobileBase loadMobileBaseFromGit(String id, String file) throws Exception {
|
||||
return MobileBaseLoader.fromGit(id, file);
|
||||
}
|
||||
|
||||
public static void select(MobileBase base) {
|
||||
if (CreatureLab3dController.getEngine().isAutoHightlight()) {
|
||||
MobileBaseCadManager.get(base).selectCsgByMobileBase(base);
|
||||
}
|
||||
/*
|
||||
* try {
|
||||
*
|
||||
* ArrayList<CSG> csg =
|
||||
* MobileBaseCadManager.get(base).getBasetoCadMap().get(base);
|
||||
* CreatureLab3dController.getEngine(). setSelectedCsg(csg.get(0));
|
||||
* CreatureLab3dController.getEngine(). setSelectedCsg(csg); } catch (Exception
|
||||
* ex) { System.err.println("Base not loaded yet"); }
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
public static void select(MobileBase base, DHParameterKinematics limb) {
|
||||
if (CreatureLab3dController.getEngine().isAutoHightlight()) {
|
||||
MobileBaseCadManager.get(base).selectCsgByLimb(base, limb);
|
||||
}
|
||||
/*
|
||||
* try {
|
||||
*
|
||||
* ArrayList<CSG> limCad =
|
||||
* MobileBaseCadManager.get(base).getDHtoCadMap().get(limb); try {
|
||||
* CreatureLab3dController.getEngine() .setSelectedCsg(limCad.get(limCad.size()
|
||||
* - 1)); } catch (Exception ex) { // initialization has no csgs yet }
|
||||
* CreatureLab3dController.getEngine(). setSelectedCsg(limCad); } catch
|
||||
* (Exception ex) { System.err.println("Limb not loaded yet"); }
|
||||
*/
|
||||
}
|
||||
|
||||
public static void select(MobileBase base, LinkConfiguration limb) {
|
||||
if (CreatureLab3dController.getEngine().isAutoHightlight()) {
|
||||
MobileBaseCadManager.get(base).selectCsgByLink(base, limb);
|
||||
}
|
||||
/*
|
||||
* try {
|
||||
*
|
||||
* ArrayList<CSG> limCad =
|
||||
* MobileBaseCadManager.get(base).getLinktoCadMap().get(limb);
|
||||
* CreatureLab3dController.getEngine() .setSelectedCsg(limCad.get(limCad.size()
|
||||
* - 1)); CreatureLab3dController.getEngine(). setSelectedCsg(limCad); } catch
|
||||
* (Exception ex) { System.err.println("Limb not loaded yet"); }
|
||||
*/
|
||||
}
|
||||
|
||||
public static void select(File script, int lineNumber) {
|
||||
if (CreatureLab3dController.getEngine().isAutoHightlight())
|
||||
try {
|
||||
CreatureLab3dController.getEngine().setSelectedCsg(script, lineNumber);
|
||||
} catch (Exception ex) {
|
||||
System.err.println("File not found");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param args the command line arguments
|
||||
* @throws Exception
|
||||
*/
|
||||
|
||||
@SuppressWarnings({ "unchecked", "restriction" })
|
||||
public static void main(String[] args) throws Exception {
|
||||
Thread.currentThread().setUncaughtExceptionHandler(new IssueReportingExceptionHandler());
|
||||
if (!StudioBuildInfo.isOS64bit()) {
|
||||
|
||||
Platform.runLater(() -> {
|
||||
Alert alert = new Alert(AlertType.ERROR);
|
||||
alert.setTitle("32 Bit Java Detected");
|
||||
alert.setHeaderText("Insuffient Ram Capibilities in 32 bit mode");
|
||||
alert.setContentText("This applications uses more that 4gb of ram\nA 32 bit JVM mode detected: "
|
||||
+ System.getProperty("os.arch"));
|
||||
alert.showAndWait();
|
||||
System.exit(1);
|
||||
});
|
||||
}
|
||||
Log.enableWarningPrint();
|
||||
|
||||
renderSplashFrame(2, "Testing Internet");
|
||||
|
||||
try {
|
||||
final URL url = new URL("http://github.com");
|
||||
final URLConnection conn = url.openConnection();
|
||||
conn.connect();
|
||||
conn.getInputStream();
|
||||
setHasnetwork(true);
|
||||
|
||||
} catch (Exception e) {
|
||||
// we assuming we have no access to the server and run off of the
|
||||
// cached gists.
|
||||
setHasnetwork(false);
|
||||
|
||||
}
|
||||
CSG.setDefaultOptType(CSG.OptType.CSG_BOUND);
|
||||
CSG.setProgressMoniter((currentIndex, finalIndex, type, intermediateShape) -> {
|
||||
// Remove the default printing
|
||||
|
||||
});
|
||||
eu.mihosoft.vrl.v3d.svg.SVGLoad.getProgressDefault();
|
||||
eu.mihosoft.vrl.v3d.svg.SVGLoad.setProgressDefault(new ISVGLoadProgress() {
|
||||
@Override
|
||||
public void onShape(CSG newShape) {
|
||||
BowlerStudioController.addCsg(newShape);
|
||||
}
|
||||
});
|
||||
StudioBuildInfo.setBaseBuildInfoClass(BowlerStudio.class);
|
||||
if (args.length == 0) {
|
||||
renderSplashFrame(5, "Loging In...");
|
||||
// ScriptingEngine.logout();
|
||||
if (PasswordManager.hasNetwork()) {
|
||||
ScriptingEngine.setLoginManager(new GitHubLoginManager());
|
||||
try {
|
||||
ScriptingEngine.login();
|
||||
renderSplashFrame(10, "Login OK!");
|
||||
|
||||
} catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
ScriptingEngine.setupAnyonmous();
|
||||
renderSplashFrame(10, "No Login Found");
|
||||
}
|
||||
}
|
||||
|
||||
String myAssets = AssetFactory.getGitSource();
|
||||
if (PasswordManager.hasNetwork()) {
|
||||
if (ScriptingEngine.isLoginSuccess()) {
|
||||
|
||||
if (BowlerStudio.hasNetwork()) {
|
||||
|
||||
ScriptingEngine.setAutoupdate(true);
|
||||
|
||||
}
|
||||
renderSplashFrame(15, "Load Configs");
|
||||
try {
|
||||
firstVer = (String) ConfigurationDatabase.getObject("BowlerStudioConfigs", "firstVersion",
|
||||
StudioBuildInfo.getVersion());
|
||||
} catch (Throwable t) {
|
||||
System.out.println("Resetting the configs repo...");
|
||||
// clear the configs repo
|
||||
ScriptingEngine.deleteRepo(ConfigurationDatabase.getGitSource());
|
||||
firstVer = (String) ConfigurationDatabase.getObject("BowlerStudioConfigs", "firstVersion",
|
||||
StudioBuildInfo.getVersion());
|
||||
}
|
||||
ConfigurationDatabase.setObject("BowlerStudioConfigs", "currentVersion",
|
||||
StudioBuildInfo.getVersion());
|
||||
renderSplashFrame(16, "Done Load Configs");
|
||||
// String lastVersion = (String)
|
||||
// ConfigurationDatabase.getObject("BowlerStudioConfigs",
|
||||
// "skinBranch",
|
||||
// StudioBuildInfo.getVersion());
|
||||
myAssets = (String) ConfigurationDatabase.getObject("BowlerStudioConfigs", "skinRepo",
|
||||
"https://github.com/madhephaestus/BowlerStudioImageAssets.git");
|
||||
renderSplashFrame(20, "DL'ing Image Assets");
|
||||
File gitRepoFile = ScriptingEngine.uriToFile(myAssets);
|
||||
if (!gitRepoFile.exists()) {
|
||||
lastVersion = null;
|
||||
} else
|
||||
lastVersion = ScriptingEngine.getBranch(myAssets);
|
||||
System.err.println("Asset Repo " + myAssets);
|
||||
System.err.println("Asset current ver " + lastVersion);
|
||||
|
||||
System.err.println("Asset intended ver " + StudioBuildInfo.getVersion());
|
||||
|
||||
if (lastVersion != null && StudioBuildInfo.getVersion().contentEquals(lastVersion)) {
|
||||
ScriptingEngine.pull(myAssets, StudioBuildInfo.getVersion());
|
||||
System.err.println("Studio version is the same");
|
||||
} else {
|
||||
if (lastVersion != null)
|
||||
ScriptingEngine.cloneRepo(myAssets, lastVersion);
|
||||
System.err.println("\n\nnew version\n\n");
|
||||
try {
|
||||
if (ScriptingEngine.checkOwner(myAssets)) {
|
||||
ScriptingEngine.newBranch(myAssets, StudioBuildInfo.getVersion());
|
||||
} else
|
||||
throw new NullPointerException();
|
||||
} catch (NullPointerException ex) {
|
||||
// not the owner
|
||||
try {
|
||||
ScriptingEngine.checkout(myAssets, StudioBuildInfo.getVersion());
|
||||
} catch (Exception ex1) {
|
||||
ScriptingEngine.deleteRepo(myAssets);
|
||||
ScriptingEngine.cloneRepo(myAssets, StudioBuildInfo.getVersion());
|
||||
}
|
||||
}
|
||||
lastVersion = ScriptingEngine.getBranch(myAssets);
|
||||
ConfigurationDatabase.setObject("BowlerStudioConfigs", "skinBranch", lastVersion);
|
||||
// force the mainline in when a version update happens
|
||||
// this prevents developers from ending up with unsuable
|
||||
// version of BowlerStudio
|
||||
ConfigurationDatabase.setObject("BowlerStudioConfigs", "skinRepo", myAssets);
|
||||
ConfigurationDatabase.save();
|
||||
}
|
||||
|
||||
if (BowlerStudio.hasNetwork()) {
|
||||
renderSplashFrame(25, "Populating Menu");
|
||||
}
|
||||
} else {
|
||||
renderSplashFrame(20, "DL'ing Image Assets");
|
||||
ScriptingEngine.cloneRepo(myAssets, null);
|
||||
ScriptingEngine.checkout(myAssets, StudioBuildInfo.getVersion());
|
||||
}
|
||||
}
|
||||
layoutFile = AssetFactory.loadFile("layout/default.css");
|
||||
if (layoutFile == null || !layoutFile.exists()) {
|
||||
ScriptingEngine.deleteRepo(myAssets);
|
||||
|
||||
throw new RuntimeException("Style sheet does not exist");
|
||||
}
|
||||
// SplashManager.setIcon(AssetFactory.loadAsset("BowlerStudioTrayIcon.png"));
|
||||
renderSplashFrame(50, "Tutorials...");
|
||||
// load tutorials repo
|
||||
|
||||
Tutorial.getHomeUrl(); // Dowload and launch the Tutorial server
|
||||
// force the current version in to the version number
|
||||
ConfigurationDatabase.setObject("BowlerStudioConfigs", "skinBranch", StudioBuildInfo.getVersion());
|
||||
renderSplashFrame(53, "Loading Images");
|
||||
AssetFactory.setGitSource(
|
||||
(String) ConfigurationDatabase.getObject("BowlerStudioConfigs", "skinRepo", myAssets),
|
||||
StudioBuildInfo.getVersion());
|
||||
renderSplashFrame(54, "Load Assets");
|
||||
// Download and Load all of the assets
|
||||
|
||||
renderSplashFrame(60, "Vitamins...");
|
||||
// load the vitimins repo so the demo is always snappy
|
||||
ScriptingEngine.cloneRepo("https://github.com/CommonWealthRobotics/BowlerStudioVitamins.git", null);
|
||||
|
||||
renderSplashFrame(80, "Example Robots");
|
||||
ScriptingEngine.fileFromGit("https://github.com/CommonWealthRobotics/BowlerStudioExampleRobots.git", // git
|
||||
// repo,
|
||||
// change
|
||||
// this
|
||||
// if
|
||||
// you
|
||||
// fork
|
||||
// this
|
||||
// demo
|
||||
"exampleRobots.json"// File from within the Git repo
|
||||
);
|
||||
renderSplashFrame(81, "CSG database");
|
||||
CSGDatabase.setDbFile(new File(ScriptingEngine.getWorkspace().getAbsoluteFile() + "/csgDatabase.json"));
|
||||
|
||||
// System.out.println("Loading assets ");
|
||||
|
||||
// System.out.println("Loading Main.fxml");
|
||||
renderSplashFrame(81, "Find arduino");
|
||||
String arduino = "arduino";
|
||||
if (NativeResource.isLinux()) {
|
||||
|
||||
Slic3r.setExecutableLocation("/usr/bin/slic3r");
|
||||
|
||||
} else if (NativeResource.isWindows()) {
|
||||
arduino = "C:\\Program Files (x86)\\Arduino\\arduino.exe";
|
||||
if (!new File(arduino).exists()) {
|
||||
arduino = "C:\\Program Files\\Arduino\\arduino.exe";
|
||||
}
|
||||
|
||||
} else if (NativeResource.isOSX()) {
|
||||
arduino = "/Applications/Arduino.app/Contents/MacOS/Arduino";
|
||||
}
|
||||
try {
|
||||
if (!new File(arduino).exists() && !NativeResource.isLinux()) {
|
||||
boolean alreadyNotified = Boolean.getBoolean(ConfigurationDatabase
|
||||
.getObject("BowlerStudioConfigs", "notifiedArduinoDep", false).toString());
|
||||
if (!alreadyNotified) {
|
||||
ConfigurationDatabase.setObject("BowlerStudioConfigs", "notifiedArduinoDep", true);
|
||||
String adr = arduino;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
System.out.println("Arduino exec found at: " + arduino);
|
||||
ArduinoLoader.setARDUINOExec(arduino);
|
||||
} catch (Exception e) {
|
||||
reporter.uncaughtException(Thread.currentThread(), e);
|
||||
|
||||
}
|
||||
renderSplashFrame(82, "Set up UI");
|
||||
try {
|
||||
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
|
||||
// This is a workaround for #8 and is only relavent on osx
|
||||
// it causes the SwingNodes not to load if not called way ahead
|
||||
// of time
|
||||
javafx.scene.text.Font.getFamilies();
|
||||
} catch (Exception e) {
|
||||
reporter.uncaughtException(Thread.currentThread(), e);
|
||||
|
||||
}
|
||||
renderSplashFrame(90, "Loading STL Loader");
|
||||
// Add the engine handeler for STLs
|
||||
ScriptingEngine.addScriptingLanguage(new StlLoader());
|
||||
// add a new link provider to the link factory
|
||||
FirmataLink.addLinkFactory();
|
||||
// Log.enableInfoPrint();
|
||||
renderSplashFrame(92, "Preload done");
|
||||
// ThreadUtil.wait(100);
|
||||
|
||||
try {
|
||||
ScriptingEngine.pull("https://github.com/CommonWealthRobotics/HotfixBowlerStudio.git");
|
||||
ScriptingEngine.pull("https://github.com/CommonWealthRobotics/DeviceProviders.git");
|
||||
ScriptingEngine.gitScriptRun("https://github.com/CommonWealthRobotics/HotfixBowlerStudio.git",
|
||||
"hotfix.groovy", null);
|
||||
ScriptingEngine.gitScriptRun("https://github.com/CommonWealthRobotics/DeviceProviders.git",
|
||||
"loadAll.groovy", null);
|
||||
} catch (Exception e) {
|
||||
reporter.uncaughtException(Thread.currentThread(), e);
|
||||
|
||||
}
|
||||
launch();
|
||||
|
||||
} else {
|
||||
BowlerKernel.main(args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// private static void removeAssets(String myAssets)
|
||||
// throws InvalidRemoteException, TransportException, GitAPIException, IOException, Exception {
|
||||
// System.err.println("Clearing assets");
|
||||
// ScriptingEngine.deleteRepo(myAssets);
|
||||
// AssetFactory.setGitSource((String) ConfigurationDatabase.getObject("BowlerStudioConfigs", "skinRepo", myAssets),
|
||||
// StudioBuildInfo.getVersion());
|
||||
// }
|
||||
|
||||
public static void closeSplash() {
|
||||
SplashManager.closeSplash();
|
||||
}
|
||||
|
||||
public static void renderSplashFrame(int frame, String message) {
|
||||
SplashManager.renderSplashFrame(frame, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* open an external web page
|
||||
*
|
||||
* @param uri
|
||||
*/
|
||||
public static void openExternalWebpage(URL uri) {
|
||||
Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null;
|
||||
if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE)) {
|
||||
try {
|
||||
desktop.browse(uri.toURI());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Sainath
|
||||
* @version 1.0
|
||||
* @param url - The URL of the tab that needs to be opened
|
||||
*/
|
||||
public static void openUrlInNewTab(URL url) {
|
||||
BowlerStudioModularFrame.getBowlerStudioModularFrame().openUrlInNewTab(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Sainath
|
||||
* @version 1.0
|
||||
* @param msg - message that needs to be spoken
|
||||
* @return an integer
|
||||
*/
|
||||
public static int speak(String msg) {
|
||||
|
||||
return BowlerKernel.speak(msg);
|
||||
}
|
||||
|
||||
public static ScriptingFileWidget createFileTab(File file) {
|
||||
return BowlerStudioModularFrame.getBowlerStudioModularFrame().createFileTab(file);
|
||||
}
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public static Scene getScene() {
|
||||
return scene;
|
||||
}
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public static void setScene(Scene s) {
|
||||
scene = s;
|
||||
}
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public static void clearConsole() {
|
||||
|
||||
Platform.runLater(() -> {
|
||||
if (getLogViewRefStatic() != null)
|
||||
getLogViewRefStatic().setText("");
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean hasNetwork() {
|
||||
return hasnetwork;
|
||||
}
|
||||
|
||||
public static void setHasnetwork(boolean hasnetwork) {
|
||||
BowlerStudio.hasnetwork = hasnetwork;
|
||||
}
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public static TextArea getLogViewRefStatic() {
|
||||
return logViewRefStatic;
|
||||
}
|
||||
|
||||
public static void setLogViewRefStatic(@SuppressWarnings("restriction") TextArea logViewRefStatic) {
|
||||
BowlerStudio.logViewRefStatic = logViewRefStatic;
|
||||
}
|
||||
|
||||
public static void setCreatureLab3d(CreatureLab3dController creatureLab3dController) {
|
||||
}
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
@Override
|
||||
public void start(Stage primaryStage) {
|
||||
try { // do this ...
|
||||
Thread thread = Thread.currentThread();
|
||||
if (thread.getContextClassLoader() == null) {
|
||||
// seriously Apple??
|
||||
System.err.println("ContextClassLoader Is Missing! (OSX) ");
|
||||
thread.setContextClassLoader(getClass().getClassLoader()); // a
|
||||
// valid
|
||||
// ClassLoader
|
||||
// from
|
||||
// somewhere
|
||||
// else
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
reporter.uncaughtException(Thread.currentThread(), e);
|
||||
|
||||
}
|
||||
System.err.println("Class loader: " + Thread.currentThread().getContextClassLoader());
|
||||
new Thread(() -> {
|
||||
Thread.currentThread().setUncaughtExceptionHandler(new IssueReportingExceptionHandler());
|
||||
|
||||
try {
|
||||
|
||||
String stylesheet = Application.STYLESHEET_MODENA;// "MODENA" or
|
||||
// "CASPIAN"
|
||||
// System.setProperty("javax.userAgentStylesheetUrl",
|
||||
// stylesheet);
|
||||
setUserAgentStylesheet(stylesheet);
|
||||
} catch (Exception | Error e) {
|
||||
reporter.uncaughtException(Thread.currentThread(), e);
|
||||
|
||||
}
|
||||
// These must be changed before anything starts
|
||||
PrintStream ps = new PrintStream(getOut());
|
||||
// System.setErr(ps);
|
||||
System.setOut(ps);
|
||||
renderSplashFrame(93, "Loading resources");
|
||||
try {
|
||||
BowlerStudioResourceFactory.load();
|
||||
} catch (Exception e1) {
|
||||
reporter.uncaughtException(Thread.currentThread(), e1);
|
||||
|
||||
}
|
||||
|
||||
primaryStage2 = primaryStage;
|
||||
BowlerStudioModularFrame.setPrimaryStage(primaryStage);
|
||||
// Initialize your logic here: all @FXML variables will have been
|
||||
// injected
|
||||
FXMLLoader mainControllerPanel;
|
||||
|
||||
try {
|
||||
mainControllerPanel = AssetFactory.loadLayout("layout/BowlerStudioModularFrame.fxml");
|
||||
|
||||
renderSplashFrame(96, "Setting controller");
|
||||
mainControllerPanel.setController(new BowlerStudioModularFrame());
|
||||
// renderSplashFrame(96, "Class loader");
|
||||
// mainControllerPanel.setClassLoader(BowlerStudioModularFrame.class.getClassLoader());
|
||||
try {
|
||||
renderSplashFrame(96, "Controller load");
|
||||
|
||||
mainControllerPanel.load();
|
||||
} catch (Exception e) {
|
||||
reporter.uncaughtException(Thread.currentThread(), e);
|
||||
|
||||
}
|
||||
renderSplashFrame(96, "UI Launch...");
|
||||
|
||||
Scene scene = new Scene(mainControllerPanel.getRoot(), 1024, 768, true);
|
||||
|
||||
String nwfile = layoutFile.toURI().toString().replace("file:/", "file:///");
|
||||
|
||||
scene.getStylesheets().clear();
|
||||
scene.getStylesheets().add(nwfile);
|
||||
System.err.println("Loading CSS from " + nwfile);
|
||||
Platform.runLater(() -> {
|
||||
|
||||
primaryStage.setScene(scene);
|
||||
System.err.println("Showing main applicaiton");
|
||||
primaryStage.show();
|
||||
// initialize the default styles for the dock pane and
|
||||
// undocked
|
||||
// nodes using the DockFX
|
||||
// library's internal Default.css stylesheet
|
||||
// unlike other custom control libraries this allows the
|
||||
// user to
|
||||
// override them globally
|
||||
// using the style manager just as they can with internal
|
||||
// JavaFX
|
||||
// controls
|
||||
// this must be called after the primary stage is shown
|
||||
// https://bugs.openjdk.java.net/browse/JDK-8132900
|
||||
DockPane.initializeDefaultUserAgentStylesheet();
|
||||
});
|
||||
|
||||
primaryStage.setOnCloseRequest(arg0 -> {
|
||||
// ThreadUtil.wait(100);
|
||||
closeBowlerStudio();
|
||||
|
||||
});
|
||||
Platform.runLater(() -> {
|
||||
primaryStage.setTitle("Bowler Studio: v " + StudioBuildInfo.getVersion());
|
||||
|
||||
try {
|
||||
primaryStage.getIcons().add(AssetFactory.loadAsset("BowlerStudioTrayIcon.png"));
|
||||
} catch (Exception e) {
|
||||
reporter.uncaughtException(Thread.currentThread(), e);
|
||||
|
||||
}
|
||||
});
|
||||
;
|
||||
|
||||
primaryStage.setResizable(true);
|
||||
|
||||
DeviceManager.addDeviceAddedListener(new IDeviceAddedListener() {
|
||||
|
||||
@Override
|
||||
public void onNewDeviceAdded(BowlerAbstractDevice arg0) {
|
||||
System.err.println("Device connected: " + arg0);
|
||||
BowlerStudioModularFrame.getBowlerStudioModularFrame().showConectionManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceRemoved(BowlerAbstractDevice arg0) {
|
||||
}
|
||||
});
|
||||
Log.enableDebugPrint(false);
|
||||
// Log.enableWarningPrint();
|
||||
// Log.enableDebugPrint();
|
||||
// Log.enableErrorPrint();
|
||||
FxTimer.runLater(java.time.Duration.ofMillis((int) 2000), () -> {
|
||||
String javaVersion = System.getProperty("java.version");
|
||||
String javafxVersion = System.getProperty("javafx.version");
|
||||
System.out.println("Java Version : " + javaVersion);
|
||||
System.out.println("JavaFX Version : " + javafxVersion);
|
||||
System.out.println("BowlerStudio First Version: " + firstVer);
|
||||
System.out.println("Java-Bowler Version: " + SDKBuildInfo.getVersion());
|
||||
System.out.println("Bowler-Scripting-Kernel Version: " + BowlerKernelBuildInfo.getVersion());
|
||||
System.out.println("JavaCad Version: " + JavaCadBuildInfo.getVersion());
|
||||
System.out.println("Welcome to BowlerStudio!");
|
||||
|
||||
});
|
||||
closeSplash();
|
||||
if (!ScriptingEngine.isLoginSuccess() || PasswordManager.isAnonMode())
|
||||
BowlerStudioModularFrame.getBowlerStudioModularFrame().menueController.onLogin(null);
|
||||
|
||||
} catch (Throwable e) {
|
||||
reporter.uncaughtException(Thread.currentThread(), e);
|
||||
|
||||
}
|
||||
}).start();
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public static void closeBowlerStudio() {
|
||||
Platform.runLater(() -> {
|
||||
primaryStage2.hide();
|
||||
});
|
||||
new Thread() {
|
||||
|
||||
public void run() {
|
||||
Thread.currentThread().setUncaughtExceptionHandler(new IssueReportingExceptionHandler());
|
||||
|
||||
renderSplashFrame(100, "Saving state..");
|
||||
ConnectionManager.disconnectAll();
|
||||
if(PasswordManager.hasNetwork()) {
|
||||
if (ScriptingEngine.isLoginSuccess() && !PasswordManager.isAnonMode())
|
||||
ConfigurationDatabase.save();
|
||||
}
|
||||
if (isDeleteFlag())
|
||||
ScriptingEngine.deleteCache();
|
||||
System.exit(0);
|
||||
}
|
||||
}.start();
|
||||
|
||||
}
|
||||
|
||||
public static void printStackTrace(Throwable e) {
|
||||
printStackTrace(e, null);
|
||||
}
|
||||
|
||||
public static void printStackTrace(Throwable e, File sourceFile) {
|
||||
BowlerStudioController.highlightException(sourceFile, e);
|
||||
}
|
||||
|
||||
public static void println(CSG... toDisplay) {
|
||||
BowlerStudioController.setCsg(Arrays.asList(toDisplay));
|
||||
}
|
||||
|
||||
public static void println(ArrayList<CSG> toDisplay) {
|
||||
BowlerStudioController.setCsg(toDisplay);
|
||||
}
|
||||
|
||||
public static void print(CSG... toDisplay) {
|
||||
for (CSG c : Arrays.asList(toDisplay))
|
||||
BowlerStudioController.addCsg(c);
|
||||
}
|
||||
|
||||
public static void print(ArrayList<CSG> toDisplay) {
|
||||
for (CSG c : toDisplay)
|
||||
BowlerStudioController.addCsg(c);
|
||||
}
|
||||
|
||||
public static boolean isDeleteFlag() {
|
||||
return deleteFlag;
|
||||
}
|
||||
|
||||
public static void setDeleteFlag(boolean deleteFlag) {
|
||||
BowlerStudio.deleteFlag = deleteFlag;
|
||||
}
|
||||
|
||||
public static void exit() {
|
||||
closeBowlerStudio();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,566 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
|
||||
import com.neuronrobotics.bowlerstudio.assets.ConfigurationDatabase;
|
||||
import com.neuronrobotics.bowlerstudio.creature.IMobileBaseUI;
|
||||
import com.neuronrobotics.bowlerstudio.creature.MobileBaseCadManager;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.IScriptEventListener;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.ScriptingFileWidget;
|
||||
import com.neuronrobotics.bowlerstudio.tabs.LocalFileScriptTab;
|
||||
import com.neuronrobotics.bowlerstudio.threed.BowlerStudio3dEngine;
|
||||
import com.neuronrobotics.bowlerstudio.threed.Line3D;
|
||||
import com.neuronrobotics.imageprovider.AbstractImageProvider;
|
||||
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
|
||||
import com.neuronrobotics.sdk.common.DMDevice;
|
||||
import com.neuronrobotics.sdk.common.Log;
|
||||
import com.neuronrobotics.sdk.common.NonBowlerDevice;
|
||||
import com.neuronrobotics.sdk.util.ThreadUtil;
|
||||
import eu.mihosoft.vrl.v3d.CSG;
|
||||
import eu.mihosoft.vrl.v3d.Polygon;
|
||||
import eu.mihosoft.vrl.v3d.Vertex;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import javax.swing.text.BadLocationException;
|
||||
|
||||
import org.kohsuke.github.GHRepository;
|
||||
import org.reactfx.util.FxTimer;
|
||||
|
||||
import java.awt.Color;
|
||||
//import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.time.Duration;
|
||||
//import org.bytedeco.javacpp.DoublePointer;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class BowlerStudioController implements IScriptEventListener {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private ConnectionManager connectionManager;
|
||||
private AbstractImageProvider vrCamera;
|
||||
private static BowlerStudioController bowlerStudioControllerStaticReference = null;
|
||||
private boolean doneLoadingTutorials = false;
|
||||
private boolean runningExceptionHighlight = false;
|
||||
|
||||
public BowlerStudioController() {
|
||||
if (getBowlerStudio() != null)
|
||||
throw new RuntimeException("There can be only one Bowler Studio controller");
|
||||
bowlerStudioControllerStaticReference = this;
|
||||
size = ((Number) ConfigurationDatabase.getObject("BowlerStudioConfigs", "fontsize", 12)).intValue();
|
||||
|
||||
}
|
||||
|
||||
private HashMap<String, Tab> openFiles = new HashMap<>();
|
||||
private HashMap<String, LocalFileScriptTab> widgets = new HashMap<>();
|
||||
private int size;
|
||||
|
||||
private static IMobileBaseUI mbui = new IMobileBaseUI() {
|
||||
|
||||
@Override
|
||||
public void highlightException(File fileEngineRunByName, Exception ex) {
|
||||
BowlerStudioController.highlightException(fileEngineRunByName, ex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAllCSG(Collection<CSG> toAdd, File source) {
|
||||
try {
|
||||
BowlerStudioController.setCsg(new ArrayList<>(toAdd));
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCSG(Collection<CSG> toAdd, File source) {
|
||||
// TODO Auto-generated method stub
|
||||
for (CSG b : toAdd)
|
||||
BowlerStudioController.addCsg(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<CSG> getVisibleCSGs() {
|
||||
return CreatureLab3dController.getEngine().getCsgMap().keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelectedCsg(Collection<CSG> selectedCsg) {
|
||||
CreatureLab3dController.getEngine().setSelectedCsg(new ArrayList<>(selectedCsg));
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
public void setFontSize(int size) {
|
||||
this.size = size;
|
||||
for (String key : widgets.keySet()) {
|
||||
widgets.get(key).setFontSize(size);
|
||||
}
|
||||
ConfigurationDatabase.setObject("BowlerStudioConfigs", "fontsize", size);
|
||||
}
|
||||
|
||||
// Custom function for creation of New Tabs.
|
||||
public ScriptingFileWidget createFileTab(File file) {
|
||||
if (openFiles.get(file.getAbsolutePath()) != null && widgets.get(file.getAbsolutePath()) != null) {
|
||||
BowlerStudioModularFrame.getBowlerStudioModularFrame()
|
||||
.setSelectedTab(openFiles.get(file.getAbsolutePath()));
|
||||
return widgets.get(file.getAbsolutePath()).getScripting();
|
||||
}
|
||||
|
||||
Tab fileTab = new Tab(file.getName());
|
||||
openFiles.put(file.getAbsolutePath(), fileTab);
|
||||
|
||||
try {
|
||||
Log.warning("Loading local file from: " + file.getAbsolutePath());
|
||||
LocalFileScriptTab t = new LocalFileScriptTab(file);
|
||||
|
||||
new Thread() {
|
||||
public void run() {
|
||||
BowlerStudioMenuWorkspace.add(t.getScripting().getGitRepo());
|
||||
}
|
||||
}.start();
|
||||
|
||||
String key = t.getScripting().getGitRepo() + ":" + t.getScripting().getGitFile();
|
||||
ArrayList<String> files = new ArrayList<>();
|
||||
files.add(t.getScripting().getGitRepo());
|
||||
files.add(t.getScripting().getGitFile());
|
||||
if(key.length()>3 && files.get(0).length()>0 && files.get(1).length()>0)// catch degenerates
|
||||
ConfigurationDatabase.setObject("studio-open-git", key, files);
|
||||
|
||||
fileTab.setContent(t);
|
||||
fileTab.setGraphic(
|
||||
AssetFactory.loadIcon("Script-Tab-" + ScriptingEngine.getShellType(file.getName()) + ".png"));
|
||||
|
||||
addTab(fileTab, true);
|
||||
widgets.put(file.getAbsolutePath(), t);
|
||||
fileTab.setOnCloseRequest(event -> {
|
||||
widgets.remove(file.getAbsolutePath());
|
||||
openFiles.remove(file.getAbsolutePath());
|
||||
ConfigurationDatabase.removeObject("studio-open-git", key);
|
||||
t.getScripting().close();
|
||||
System.out.println("Closing " + file.getAbsolutePath());
|
||||
});
|
||||
|
||||
t.setFontSize(size);
|
||||
return t.getScripting();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void clearHighlits() {
|
||||
for (Entry<String, LocalFileScriptTab> set : widgets.entrySet()) {
|
||||
set.getValue().clearHighlits();
|
||||
}
|
||||
}
|
||||
|
||||
public void setHighlight(File fileEngineRunByName, int lineNumber, Color color) {
|
||||
// System.out.println("Highlighting line "+lineNumber+" in
|
||||
// "+fileEngineRunByName);
|
||||
if (openFiles.get(fileEngineRunByName.getAbsolutePath()) == null) {
|
||||
createFileTab(fileEngineRunByName);
|
||||
ThreadUtil.wait(100);
|
||||
}
|
||||
|
||||
// BowlerStudioModularFrame.getBowlerStudioModularFrame().setSelectedTab(openFiles.get(fileEngineRunByName.getAbsolutePath()));
|
||||
// System.out.println("Highlighting "+fileEngineRunByName+" at line
|
||||
// "+lineNumber+" to color "+color);
|
||||
try {
|
||||
widgets.get(fileEngineRunByName.getAbsolutePath()).setHighlight(lineNumber, color);
|
||||
} catch (BadLocationException e) {
|
||||
// e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void highlightException(File fileEngineRunByName, Throwable ex) {
|
||||
if(bowlerStudioControllerStaticReference!=null)
|
||||
bowlerStudioControllerStaticReference.highlightExceptionLocal(fileEngineRunByName, ex);
|
||||
}
|
||||
|
||||
public static void clearHighlight() {
|
||||
bowlerStudioControllerStaticReference.clearHighlits();
|
||||
}
|
||||
|
||||
private void highlightExceptionLocal(File fileEngineRunByName, Throwable ex) {
|
||||
// THis needs to gate on checking if this thread is running already
|
||||
if(runningExceptionHighlight) {
|
||||
ex.printStackTrace();
|
||||
|
||||
new RuntimeException("Only one exception Highlight can be called at once!").printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
new Thread() {
|
||||
public void run() {
|
||||
runningExceptionHighlight=true;
|
||||
setName("Highlighter thread");
|
||||
if (fileEngineRunByName != null) {
|
||||
if (openFiles.get(fileEngineRunByName.getAbsolutePath()) == null) {
|
||||
createFileTab(fileEngineRunByName);
|
||||
}
|
||||
BowlerStudioModularFrame.getBowlerStudioModularFrame()
|
||||
.setSelectedTab(openFiles.get(fileEngineRunByName.getAbsolutePath()));
|
||||
widgets.get(fileEngineRunByName.getAbsolutePath()).clearHighlits();
|
||||
// System.out.println("Highlighting "+fileEngineRunByName+" at line
|
||||
// "+lineNumber+" to color "+color);
|
||||
StackTraceElement[] stackTrace = ex.getStackTrace();
|
||||
|
||||
for (StackTraceElement el : stackTrace) {
|
||||
try {
|
||||
// System.out.println("Compairing "+fileEngineRunByName.getName()+" to
|
||||
// "+el.getFileName());
|
||||
if (el.getFileName().contentEquals(fileEngineRunByName.getName())) {
|
||||
widgets.get(fileEngineRunByName.getAbsolutePath()).setHighlight(el.getLineNumber(),
|
||||
Color.CYAN);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// StringWriter sw = new StringWriter();
|
||||
// PrintWriter pw = new PrintWriter(sw);
|
||||
// e.printStackTrace(pw);
|
||||
// System.out.println(sw.toString());
|
||||
}
|
||||
}
|
||||
if (ex.getCause() != null) {
|
||||
for (StackTraceElement el : ex.getCause().getStackTrace()) {
|
||||
try {
|
||||
// System.out.println("Compairing "+fileEngineRunByName.getName()+" to
|
||||
// "+el.getFileName());
|
||||
if (el.getFileName().contentEquals(fileEngineRunByName.getName())) {
|
||||
widgets.get(fileEngineRunByName.getAbsolutePath()).setHighlight(el.getLineNumber(),
|
||||
Color.CYAN);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// StringWriter sw = new StringWriter();
|
||||
// PrintWriter pw = new PrintWriter(sw);
|
||||
// e.printStackTrace(pw);
|
||||
// System.out.println(sw.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
try {
|
||||
if (widgets.get(fileEngineRunByName.getAbsolutePath()) != null) {
|
||||
String message = ex.getMessage();
|
||||
// System.out.println(message);
|
||||
if (message != null && message.contains(fileEngineRunByName.getName()))
|
||||
try {
|
||||
int indexOfFile = message.lastIndexOf(fileEngineRunByName.getName());
|
||||
String fileSub = message.substring(indexOfFile);
|
||||
String[] fileAndNum = fileSub.split(":");
|
||||
String FileNum = fileAndNum[1];
|
||||
int linNum = Integer.parseInt(FileNum.trim());
|
||||
widgets.get(fileEngineRunByName.getAbsolutePath()).setHighlight(linNum, Color.CYAN);
|
||||
} catch (Exception e) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
e.printStackTrace(pw);
|
||||
System.out.println(sw.toString());
|
||||
}
|
||||
}
|
||||
} catch (Exception ex1) {
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
String sw = org.apache.commons.lang.exception.ExceptionUtils
|
||||
.getStackTrace(ex);
|
||||
System.out.println(sw.toString());
|
||||
// space out the exception highlights, ensure any sub threads spawned here have time to finish
|
||||
Thread.sleep(100);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
runningExceptionHighlight=false;
|
||||
}
|
||||
}.start();
|
||||
|
||||
}
|
||||
|
||||
public void addTab(Tab tab, boolean closable) {
|
||||
|
||||
// new RuntimeException().printStackTrace();
|
||||
|
||||
Platform.runLater(() -> {
|
||||
BowlerStudioModularFrame.getBowlerStudioModularFrame().addTab(tab, closable);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public static boolean removeObject(Object p) {
|
||||
if (CSG.class.isInstance(p) ) {
|
||||
Platform.runLater(() -> {
|
||||
CreatureLab3dController.getEngine().removeObject((CSG) p);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
if ( Node.class.isInstance(p) || Polygon.class.isInstance(p)) {
|
||||
Platform.runLater(() -> {
|
||||
CreatureLab3dController.getEngine().clearUserNode();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
// ThreadUtil.wait(20);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// private boolean removeObject(Object p) {
|
||||
// if (CSG.class.isInstance(p) || Node.class.isInstance(p) || Polygon.class.isInstance(p)) {
|
||||
// Platform.runLater(() -> {
|
||||
// CreatureLab3dController.getEngine().removeObjects();
|
||||
// CreatureLab3dController.getEngine().clearUserNode();
|
||||
// });
|
||||
// return true;
|
||||
// }
|
||||
// // ThreadUtil.wait(20);
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public static void setCsg(List<CSG> toadd, File source) {
|
||||
Platform.runLater(() -> {
|
||||
CreatureLab3dController.getEngine().removeObjects();
|
||||
if (toadd != null)
|
||||
for (CSG c : toadd) {
|
||||
if(c!=null)
|
||||
Platform.runLater(() -> CreatureLab3dController.getEngine().addObject(c, source));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void setCsg(List<CSG> toadd) {
|
||||
setCsg(toadd, null);
|
||||
}
|
||||
|
||||
public static void addCsg(CSG toadd) {
|
||||
addCsg(toadd, null);
|
||||
}
|
||||
|
||||
public static void setUserNode(List<Node> toadd) {
|
||||
Platform.runLater(() -> {
|
||||
CreatureLab3dController.getEngine().clearUserNode();
|
||||
if (toadd != null)
|
||||
for (Node c : toadd) {
|
||||
CreatureLab3dController.getEngine().addUserNode(c);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void addUserNode(Node toadd) {
|
||||
Platform.runLater(() -> {
|
||||
if (toadd != null)
|
||||
CreatureLab3dController.getEngine().addUserNode(toadd);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public static void setSelectedCsg(CSG obj) {
|
||||
CreatureLab3dController.getEngine().setSelectedCsg(obj);
|
||||
}
|
||||
|
||||
public static void addCsg(CSG toadd, File source) {
|
||||
Platform.runLater(() -> {
|
||||
if (toadd != null)
|
||||
CreatureLab3dController.getEngine().addObject(toadd, source);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public void addObject(Object o, File source) {
|
||||
|
||||
if (List.class.isInstance(o)) {
|
||||
List<Object> c = (List<Object>) o;
|
||||
for (int i = 0; i < c.size(); i++) {
|
||||
// Log.warning("Loading array Lists with removals " + c.get(i));
|
||||
addObject(c.get(i), source);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (CSG.class.isInstance(o)) {
|
||||
CSG csg = (CSG) o;
|
||||
Platform.runLater(() -> {
|
||||
// new RuntimeException().printStackTrace();
|
||||
CreatureLab3dController.getEngine().addObject(csg, source);
|
||||
});
|
||||
return;
|
||||
|
||||
} else if (Tab.class.isInstance(o)) {
|
||||
|
||||
addTab((Tab) o, true);
|
||||
return;
|
||||
|
||||
} else if (Node.class.isInstance(o)) {
|
||||
|
||||
addNode((Node) o);
|
||||
return;
|
||||
|
||||
} else if (Polygon.class.isInstance(o)) {
|
||||
Polygon p = (Polygon) o;
|
||||
List<Vertex> vertices = p.vertices;
|
||||
javafx.scene.paint.Color color = new javafx.scene.paint.Color(Math.random() * 0.5 + 0.5,
|
||||
Math.random() * 0.5 + 0.5, Math.random() * 0.5 + 0.5, 1);
|
||||
double stroke = 0.5;
|
||||
for (int i = 1; i < vertices.size(); i++) {
|
||||
Line3D line = new Line3D(vertices.get(i - 1), vertices.get(i));
|
||||
line.setStrokeWidth(stroke);
|
||||
line.setStroke(color);
|
||||
addNode(line);
|
||||
}
|
||||
// Connecting line
|
||||
Line3D line = new Line3D(vertices.get(0), vertices.get(vertices.size() - 1));
|
||||
line.setStrokeWidth(stroke);
|
||||
line.setStroke(color);
|
||||
addNode(line);
|
||||
return;
|
||||
} else if (BowlerAbstractDevice.class.isInstance(o)) {
|
||||
BowlerAbstractDevice bad = (BowlerAbstractDevice) o;
|
||||
ConnectionManager.addConnection((BowlerAbstractDevice) o, bad.getScriptingName());
|
||||
return;
|
||||
} else if (DMDevice.wrappable(o)) {
|
||||
BowlerAbstractDevice bad;
|
||||
try {
|
||||
bad = new DMDevice(o);
|
||||
ConnectionManager.addConnection(bad, bad.getScriptingName());
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void addNode(Node o) {
|
||||
CreatureLab3dController.getEngine().addUserNode(o);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
@Override
|
||||
public void onScriptFinished(Object result, Object Previous, File source) {
|
||||
Log.warning("Loading script results " + result + " previous " + Previous);
|
||||
// this is added in the script engine when the connection manager is
|
||||
// loaded
|
||||
clearObjects(Previous);
|
||||
clearObjects(result);
|
||||
ThreadUtil.wait(40);
|
||||
if (List.class.isInstance(result)) {
|
||||
List<Object> c = (List<Object>) result;
|
||||
for (int i = 0; i < c.size(); i++) {
|
||||
// Log.warning("Loading array Lists with removals " + c.get(i));
|
||||
addObject(c.get(i), source);
|
||||
}
|
||||
} else {
|
||||
addObject(result, source);
|
||||
}
|
||||
}
|
||||
|
||||
private void clearObjects(Object o) {
|
||||
if (List.class.isInstance(o)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Object> c = (List<Object>) o;
|
||||
for (int i = 0; i < c.size(); i++) {
|
||||
clearObjects(c.get(i));
|
||||
}
|
||||
} else {
|
||||
removeObject(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScriptChanged(String previous, String current, File source) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScriptError(Throwable except, File source) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
ConnectionManager.disconnectAll();
|
||||
}
|
||||
|
||||
public Stage getPrimaryStage() {
|
||||
// TODO Auto-generated method stub
|
||||
return BowlerStudioModularFrame.getPrimaryStage();
|
||||
}
|
||||
|
||||
public AbstractImageProvider getVrCamera() {
|
||||
return vrCamera;
|
||||
}
|
||||
|
||||
public void setVrCamera(AbstractImageProvider vrCamera) {
|
||||
this.vrCamera = vrCamera;
|
||||
}
|
||||
|
||||
public static BowlerStudioController getBowlerStudio() {
|
||||
return bowlerStudioControllerStaticReference;
|
||||
}
|
||||
|
||||
public static void setup() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public static void clearCSG() {
|
||||
Platform.runLater(() -> {
|
||||
CreatureLab3dController.getEngine().removeObjects();
|
||||
});
|
||||
}
|
||||
|
||||
public static void setCsg(CSG legAssembly, File cadScript) {
|
||||
Platform.runLater(() -> {
|
||||
CreatureLab3dController.getEngine().removeObjects();
|
||||
if (legAssembly != null)
|
||||
|
||||
Platform.runLater(() -> CreatureLab3dController.getEngine().addObject(legAssembly, cadScript));
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public static void setCsg(MobileBaseCadManager thread, File cadScript) {
|
||||
setCsg(thread.getAllCad(), cadScript);
|
||||
}
|
||||
|
||||
|
||||
public boolean isDoneLoadingTutorials() {
|
||||
return doneLoadingTutorials;
|
||||
}
|
||||
|
||||
public void setDoneLoadingTutorials(boolean doneLoadingTutorials) {
|
||||
this.doneLoadingTutorials = doneLoadingTutorials;
|
||||
}
|
||||
|
||||
public ConnectionManager getConnectionManager() {
|
||||
return connectionManager;
|
||||
}
|
||||
|
||||
public void setConnectionManager(ConnectionManager connectionManager) {
|
||||
this.connectionManager = connectionManager;
|
||||
}
|
||||
|
||||
public static IMobileBaseUI getMobileBaseUI() {
|
||||
return mbui;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Menu;
|
||||
import javafx.scene.control.MenuBar;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
import javafx.scene.control.SplitPane;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.control.TitledPane;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
|
||||
|
||||
public class BowlerStudioFXMLController {
|
||||
|
||||
@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="BowlerStudioMenue"
|
||||
private MenuBar BowlerStudioMenue; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="CadControlsAnchor"
|
||||
private AnchorPane CadControlsAnchor; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="CadTextSplit"
|
||||
private SplitPane CadTextSplit; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="CommandLine"
|
||||
private AnchorPane CommandLine; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="CreaturesMenu"
|
||||
private Menu CreaturesMenu; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="DriveControlsAnchor"
|
||||
private AnchorPane DriveControlsAnchor; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="GitHubRoot"
|
||||
private Menu GitHubRoot; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="TempControlsAnchor"
|
||||
private AnchorPane TempControlsAnchor; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="clearCache"
|
||||
private MenuItem clearCache; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="commandLineTitledPane"
|
||||
private TitledPane commandLineTitledPane; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="createNewGist"
|
||||
private MenuItem createNewGist; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="editorContainer"
|
||||
private AnchorPane editorContainer; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="jfx3dControls"
|
||||
private AnchorPane jfx3dControls; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="logView"
|
||||
private AnchorPane logView; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="logViewRef"
|
||||
private TextArea logViewRef; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="logoutGithub"
|
||||
private MenuItem logoutGithub; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="myGists"
|
||||
private Menu myGists; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="myOrganizations"
|
||||
private Menu myOrganizations; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="myRepos"
|
||||
private Menu myRepos; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="overlayScrollPanel"
|
||||
private ScrollPane overlayScrollPanel; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="viewContainer"
|
||||
private AnchorPane viewContainer; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="watchingRepos"
|
||||
private Menu watchingRepos; // Value injected by FXMLLoader
|
||||
|
||||
|
||||
// Handler for MenuItem[fx:id="clearCache"] onAction
|
||||
@FXML
|
||||
void clearScriptCache(ActionEvent event) {
|
||||
// handle the event here
|
||||
}
|
||||
|
||||
// Handler for MenuItem[javafx.scene.control.MenuItem@3d05e65e] onAction
|
||||
@FXML
|
||||
void onClose(ActionEvent event) {
|
||||
// handle the event here
|
||||
}
|
||||
|
||||
// Handler for MenuItem[javafx.scene.control.MenuItem@6127215f] onAction
|
||||
@FXML
|
||||
void onConnect(ActionEvent event) {
|
||||
// handle the event here
|
||||
}
|
||||
|
||||
// Handler for MenuItem[javafx.scene.control.MenuItem@1d163e1a] onAction
|
||||
@FXML
|
||||
void onConnectCHDKCamera(ActionEvent event) {
|
||||
// handle the event here
|
||||
}
|
||||
|
||||
// Handler for MenuItem[javafx.scene.control.MenuItem@3cad92b8] onAction
|
||||
@FXML
|
||||
void onConnectCVCamera(ActionEvent event) {
|
||||
// handle the event here
|
||||
}
|
||||
|
||||
// Handler for MenuItem[javafx.scene.control.MenuItem@542487b1] onAction
|
||||
@FXML
|
||||
void onConnectFileSourceCamera(ActionEvent event) {
|
||||
// handle the event here
|
||||
}
|
||||
|
||||
// Handler for MenuItem[javafx.scene.control.MenuItem@4845d9d8] onAction
|
||||
@FXML
|
||||
void onConnectGamePad(ActionEvent event) {
|
||||
// handle the event here
|
||||
}
|
||||
|
||||
// Handler for MenuItem[javafx.scene.control.MenuItem@36100c4d] onAction
|
||||
@FXML
|
||||
void onConnectHokuyoURG(ActionEvent event) {
|
||||
// handle the event here
|
||||
}
|
||||
|
||||
// Handler for MenuItem[javafx.scene.control.MenuItem@7a7cbb68] onAction
|
||||
@FXML
|
||||
void onConnectPidSim(ActionEvent event) {
|
||||
// handle the event here
|
||||
}
|
||||
|
||||
// Handler for MenuItem[javafx.scene.control.MenuItem@7d3d14a7] onAction
|
||||
@FXML
|
||||
void onConnectURLSourceCamera(ActionEvent event) {
|
||||
// handle the event here
|
||||
}
|
||||
|
||||
// Handler for MenuItem[javafx.scene.control.MenuItem@68e8dfb1] onAction
|
||||
@FXML
|
||||
void onConnectVirtual(ActionEvent event) {
|
||||
// handle the event here
|
||||
}
|
||||
|
||||
// Handler for MenuItem[fx:id="createNewGist"] onAction
|
||||
@FXML
|
||||
void onCreatenewGist(ActionEvent event) {
|
||||
// handle the event here
|
||||
}
|
||||
|
||||
// Handler for MenuItem[javafx.scene.control.MenuItem@6bfd67ba] onAction
|
||||
@FXML
|
||||
void onLoadFile(ActionEvent event) {
|
||||
// handle the event here
|
||||
}
|
||||
|
||||
// Handler for MenuItem[javafx.scene.control.MenuItem@41a2e40f] onAction
|
||||
@FXML
|
||||
void onLogin(ActionEvent event) {
|
||||
// handle the event here
|
||||
}
|
||||
|
||||
// Handler for MenuItem[fx:id="logoutGithub"] onAction
|
||||
@FXML
|
||||
void onLogout(ActionEvent event) {
|
||||
// handle the event here
|
||||
}
|
||||
|
||||
// Handler for MenuItem[javafx.scene.control.MenuItem@7e3e1a61] onAction
|
||||
@FXML
|
||||
void onMobileBaseFromFile(ActionEvent event) {
|
||||
// handle the event here
|
||||
}
|
||||
|
||||
// Handler for MenuItem[javafx.scene.control.MenuItem@57184345] onAction
|
||||
@FXML
|
||||
void onMobileBaseFromGit(ActionEvent event) {
|
||||
// handle the event here
|
||||
}
|
||||
|
||||
// Handler for MenuItem[javafx.scene.control.MenuItem@d523af5] onAction
|
||||
@FXML
|
||||
void onOpenGitter(ActionEvent event) {
|
||||
// handle the event here
|
||||
}
|
||||
|
||||
// Handler for MenuItem[javafx.scene.control.MenuItem@2a1c81e] onAction
|
||||
@FXML
|
||||
void onPrint(ActionEvent event) {
|
||||
// handle the event here
|
||||
}
|
||||
|
||||
@FXML // This method is called by the FXMLLoader when initialization is complete
|
||||
void initialize() {
|
||||
assert BowlerStudioMenue != null : "fx:id=\"BowlerStudioMenue\" was not injected: check your FXML file 'Main.fxml'.";
|
||||
assert CadControlsAnchor != null : "fx:id=\"CadControlsAnchor\" was not injected: check your FXML file 'Main.fxml'.";
|
||||
assert CadTextSplit != null : "fx:id=\"CadTextSplit\" was not injected: check your FXML file 'Main.fxml'.";
|
||||
assert CommandLine != null : "fx:id=\"CommandLine\" was not injected: check your FXML file 'Main.fxml'.";
|
||||
assert CreaturesMenu != null : "fx:id=\"CreaturesMenu\" was not injected: check your FXML file 'Main.fxml'.";
|
||||
assert DriveControlsAnchor != null : "fx:id=\"DriveControlsAnchor\" was not injected: check your FXML file 'Main.fxml'.";
|
||||
assert GitHubRoot != null : "fx:id=\"GitHubRoot\" was not injected: check your FXML file 'Main.fxml'.";
|
||||
assert TempControlsAnchor != null : "fx:id=\"TempControlsAnchor\" was not injected: check your FXML file 'Main.fxml'.";
|
||||
assert clearCache != null : "fx:id=\"clearCache\" was not injected: check your FXML file 'Main.fxml'.";
|
||||
assert commandLineTitledPane != null : "fx:id=\"commandLineTitledPane\" was not injected: check your FXML file 'Main.fxml'.";
|
||||
assert createNewGist != null : "fx:id=\"createNewGist\" was not injected: check your FXML file 'Main.fxml'.";
|
||||
assert editorContainer != null : "fx:id=\"editorContainer\" was not injected: check your FXML file 'Main.fxml'.";
|
||||
assert jfx3dControls != null : "fx:id=\"jfx3dControls\" was not injected: check your FXML file 'Main.fxml'.";
|
||||
assert logView != null : "fx:id=\"logView\" was not injected: check your FXML file 'Main.fxml'.";
|
||||
assert logViewRef != null : "fx:id=\"logViewRef\" was not injected: check your FXML file 'Main.fxml'.";
|
||||
assert logoutGithub != null : "fx:id=\"logoutGithub\" was not injected: check your FXML file 'Main.fxml'.";
|
||||
assert myGists != null : "fx:id=\"myGists\" was not injected: check your FXML file 'Main.fxml'.";
|
||||
assert myOrganizations != null : "fx:id=\"myOrganizations\" was not injected: check your FXML file 'Main.fxml'.";
|
||||
assert myRepos != null : "fx:id=\"myRepos\" was not injected: check your FXML file 'Main.fxml'.";
|
||||
assert overlayScrollPanel != null : "fx:id=\"overlayScrollPanel\" was not injected: check your FXML file 'Main.fxml'.";
|
||||
assert viewContainer != null : "fx:id=\"viewContainer\" was not injected: check your FXML file 'Main.fxml'.";
|
||||
assert watchingRepos != null : "fx:id=\"watchingRepos\" was not injected: check your FXML file 'Main.fxml'.";
|
||||
|
||||
// Initialize your logic here: all @FXML variables will have been injected
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,181 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.assets.ConfigurationDatabase;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.Menu;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class BowlerStudioMenuWorkspace {
|
||||
private static Menu workspaceMenu;
|
||||
private static HashMap<String, Object> workspaceData = null;
|
||||
private static final int maxMenueSize = 15;
|
||||
private static boolean sorting = false;
|
||||
private static HashMap<String,Integer> rank = new HashMap<String, Integer>();
|
||||
private static boolean running = false;
|
||||
public static void init(Menu workspacemenu) {
|
||||
if (workspacemenu == null)
|
||||
throw new RuntimeException();
|
||||
workspaceMenu = workspacemenu;
|
||||
}
|
||||
|
||||
public static void loginEvent() {
|
||||
if(running)
|
||||
return;
|
||||
running = true;
|
||||
rank.clear();
|
||||
workspaceData = ConfigurationDatabase.getParamMap("workspace");
|
||||
new Thread(()-> {
|
||||
for (int i=0;i<workspaceData.keySet().size();i++) {
|
||||
try {
|
||||
String o = (String) workspaceData.keySet().toArray()[i];
|
||||
try {
|
||||
|
||||
ScriptingEngine.pull(o);
|
||||
} catch (Exception e) {
|
||||
workspaceData.remove(o);
|
||||
i--;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
running = false;
|
||||
|
||||
}).start();
|
||||
sort();
|
||||
}
|
||||
|
||||
public static void add(String url) {
|
||||
add(url, BowlerStudioMenu.gitURLtoMessage(url));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void add(String url, String menueMessage) {
|
||||
if (menueMessage == null || menueMessage.length() < 2)
|
||||
throw new RuntimeException();
|
||||
ArrayList<String> data;
|
||||
synchronized (workspaceData) {
|
||||
if (workspaceData.get(url) == null) {
|
||||
data = new ArrayList<String>();
|
||||
data.add(menueMessage);
|
||||
data.add(new Long(System.currentTimeMillis()).toString());
|
||||
workspaceData.put(url, data);
|
||||
System.out.println("Workspace add: "+url);
|
||||
}
|
||||
}
|
||||
//data = (ArrayList<String>) workspaceData.get(url);
|
||||
//data.set(1, new Long(System.currentTimeMillis()).toString());
|
||||
sort();
|
||||
//
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static void sort() {
|
||||
if (sorting)
|
||||
return;
|
||||
sorting = true;
|
||||
|
||||
boolean rankChanged=false;
|
||||
try {
|
||||
ArrayList<String> myOptions = new ArrayList<String>();
|
||||
synchronized (workspaceData) {
|
||||
for (String o : workspaceData.keySet()) {
|
||||
//System.out.println("Opt: "+o);
|
||||
myOptions.add(o);
|
||||
}
|
||||
}
|
||||
ArrayList<String> menu = new ArrayList<>();
|
||||
while (myOptions.size() > 0) {
|
||||
int bestIndex = 0;
|
||||
String besturl = (String) myOptions.get(bestIndex);
|
||||
long newestTime = Long.parseLong(((ArrayList<String>) workspaceData.get(besturl)).get(1));
|
||||
for (int i = 0; i < myOptions.size(); i++) {
|
||||
String nowurl = (String) myOptions.get(i);
|
||||
long myTime = Long.parseLong(((ArrayList<String>) workspaceData.get(nowurl)).get(1));
|
||||
if (myTime >= newestTime) {
|
||||
newestTime = myTime;
|
||||
besturl = nowurl;
|
||||
bestIndex = i;
|
||||
}
|
||||
}
|
||||
String removedURL = (String) myOptions.remove(bestIndex);
|
||||
if (menu.size() < maxMenueSize) {
|
||||
|
||||
// clone all repos from git
|
||||
try {
|
||||
// ScriptingEngine.pull(removedURL);
|
||||
menu.add(removedURL);
|
||||
} catch (Exception e) {
|
||||
// repo is broken or missing
|
||||
e.printStackTrace();
|
||||
System.out.println("Removing from workspace: " + removedURL);
|
||||
synchronized (workspaceData) {
|
||||
workspaceData.remove(removedURL);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
System.out.println("Removing from workspace: " + removedURL);
|
||||
synchronized (workspaceData) {
|
||||
workspaceData.remove(removedURL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0;i<menu.size();i++) {
|
||||
String url = menu.get(i);
|
||||
if(rank.get(url)==null) {
|
||||
rankChanged=true;
|
||||
rank.put(url,i);
|
||||
//System.out.println("Rank firstNoted : "+url+" "+i);
|
||||
}
|
||||
if(rank.get(url).intValue()!=i) {
|
||||
rankChanged=true;
|
||||
|
||||
}
|
||||
rank.put(url,i);
|
||||
}
|
||||
if(rankChanged) {
|
||||
Platform.runLater(() -> {
|
||||
if (workspaceMenu.getItems() != null)
|
||||
workspaceMenu.getItems().clear();
|
||||
|
||||
new Thread(() -> {
|
||||
for (String url : menu) {
|
||||
System.out.println("Workspace : "+url);
|
||||
ArrayList<String> arrayList = (ArrayList<String>) workspaceData.get(url);
|
||||
if(arrayList!=null)
|
||||
BowlerStudioMenu.setUpRepoMenue(workspaceMenu,
|
||||
url,
|
||||
false,
|
||||
false,
|
||||
arrayList.get(0));
|
||||
|
||||
}
|
||||
sorting = false;
|
||||
}).start();
|
||||
});
|
||||
}else {
|
||||
sorting = false;
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
if(rankChanged) {
|
||||
System.out.println("Sorting workspace...");
|
||||
new Thread(()->{
|
||||
ConfigurationDatabase.save();
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,407 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
/**
|
||||
* Sample Skeleton for "BowlerStudioModularFrame.fxml" Controller Class
|
||||
* You can copy and paste this code into your favorite IDE
|
||||
**/
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.PasswordManager;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.ScriptingFileWidget;
|
||||
import com.neuronrobotics.bowlerstudio.tabs.WebTab;
|
||||
import com.neuronrobotics.bowlerstudio.threed.BowlerStudio3dEngine;
|
||||
import com.neuronrobotics.sdk.util.ThreadUtil;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.InvalidationListener;
|
||||
import javafx.beans.Observable;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Stage;
|
||||
import org.dockfx.DockNode;
|
||||
import org.dockfx.DockPane;
|
||||
import org.dockfx.DockPos;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.ResourceBundle;
|
||||
@SuppressWarnings("restriction")
|
||||
public class BowlerStudioModularFrame {
|
||||
|
||||
|
||||
@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="editorContainer"
|
||||
private AnchorPane editorContainer; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="menurAnchor"
|
||||
private AnchorPane menurAnchor; // Value injected by FXMLLoader
|
||||
|
||||
private Image dockImage;
|
||||
|
||||
private DockNode tutorialDockNode;
|
||||
|
||||
private DockNode connectionManagerDockNode;
|
||||
|
||||
private DockPane dockPane;
|
||||
|
||||
public BowlerStudioMenu menueController;
|
||||
|
||||
// private InvalidationListener connectionManagerRemover;
|
||||
|
||||
private CreatureLab3dController creatureLab3dController;
|
||||
|
||||
private DockNode creatureLab3dDockNode;
|
||||
|
||||
// private InvalidationListener creatureManagerRemover;
|
||||
|
||||
|
||||
private BowlerStudioController controller;
|
||||
|
||||
private static Stage primaryStage;
|
||||
|
||||
private static BowlerStudioModularFrame bowlerStudioModularFrame;
|
||||
|
||||
private HashMap<Tab, DockNode> webTabs = new HashMap<>();
|
||||
private HashMap<String, Boolean> isOpen = new HashMap<>();
|
||||
|
||||
private Terminal terminal;
|
||||
|
||||
private DockNode terminalDockNode;
|
||||
private boolean startup = false;
|
||||
|
||||
private WebTab webtab;
|
||||
|
||||
@FXML // This method is called by the FXMLLoader when initialization is
|
||||
// complete
|
||||
void initialize() throws Exception {
|
||||
bowlerStudioModularFrame=this;
|
||||
assert editorContainer != null : "fx:id=\"editorContainer\" was not injected: check your FXML file 'BowlerStudioModularFrame.fxml'.";
|
||||
assert menurAnchor != null : "fx:id=\"menurAnchor\" was not injected: check your FXML file 'BowlerStudioModularFrame.fxml'.";
|
||||
dockPane = new DockPane();
|
||||
dockImage = AssetFactory.loadAsset("BowlerStudioModularFrameIcon.png");
|
||||
// final Tab newtab = new Tab();
|
||||
// newtab.setText("");
|
||||
// newtab.setClosable(false);
|
||||
// newtab.setGraphic(AssetFactory.loadIcon("New-Web-Tab.png"));
|
||||
String homeURL = Tutorial.getHomeUrl();
|
||||
|
||||
|
||||
controller = new BowlerStudioController();
|
||||
WebTab.setBSController(controller);
|
||||
|
||||
webtab = null;
|
||||
try {
|
||||
|
||||
Platform.runLater(()->{
|
||||
try {
|
||||
webtab = new WebTab("Tutorial", homeURL, true);
|
||||
setTutorialDockNode(new DockNode(webtab.getContent(), webtab.getText(), webtab.getGraphic()));
|
||||
getTutorialDockNode().setPrefSize(1024, 730);
|
||||
} catch (IOException | InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
});;
|
||||
} catch (Exception e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
|
||||
connectionManagerDockNode = new DockNode(ConnectionManager.getConnectionManager().getContent(),
|
||||
ConnectionManager.getConnectionManager().getText(),
|
||||
ConnectionManager.getConnectionManager().getGraphic());
|
||||
connectionManagerDockNode.setPrefSize(200, 700);
|
||||
|
||||
// Initial docked setup
|
||||
addTutorial();
|
||||
|
||||
// Add the dock pane to the window
|
||||
editorContainer.getChildren().add(dockPane);
|
||||
AnchorPane.setTopAnchor(dockPane, 0.0);
|
||||
AnchorPane.setRightAnchor(dockPane, 0.0);
|
||||
AnchorPane.setLeftAnchor(dockPane, 0.0);
|
||||
AnchorPane.setBottomAnchor(dockPane, 0.0);
|
||||
|
||||
FXMLLoader WindowLoader3d;
|
||||
WindowLoader3d = AssetFactory.loadLayout("layout/CreatureLab.fxml");
|
||||
creatureLab3dController = new CreatureLab3dController();
|
||||
BowlerStudio.setCreatureLab3d(creatureLab3dController);
|
||||
WindowLoader3d.setController(creatureLab3dController);
|
||||
WindowLoader3d.setClassLoader(CreatureLab3dController.class.getClassLoader());
|
||||
FXMLLoader commandLine;
|
||||
commandLine = AssetFactory.loadLayout("layout/Terminal.fxml");
|
||||
terminal = new Terminal();
|
||||
commandLine.setController(terminal);
|
||||
commandLine.setClassLoader(Terminal.class.getClassLoader());
|
||||
FXMLLoader menueBar;
|
||||
menueBar = AssetFactory.loadLayout("layout/BowlerStudioMenuBar.fxml");
|
||||
menueController = new BowlerStudioMenu(this);
|
||||
menueBar.setController(menueController);
|
||||
menueBar.setClassLoader(BowlerStudioMenu.class.getClassLoader());
|
||||
|
||||
try {
|
||||
menueBar.load();
|
||||
WindowLoader3d.load();
|
||||
commandLine.load();
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
BorderPane menue = (BorderPane) menueBar.getRoot();
|
||||
BorderPane threed = (BorderPane) WindowLoader3d.getRoot();
|
||||
VBox cmd = (VBox) commandLine.getRoot();
|
||||
creatureLab3dDockNode = new DockNode(threed, "Creature Lab", AssetFactory.loadIcon("CreatureLab-Tab.png"));
|
||||
creatureLab3dDockNode.setPrefSize(400, 400);
|
||||
|
||||
|
||||
|
||||
terminalDockNode = new DockNode(cmd, "Terminal", AssetFactory.loadIcon("Command-Line.png"));
|
||||
terminalDockNode.setPrefSize(400, 400);
|
||||
|
||||
// Add the dock pane to the window
|
||||
menurAnchor.getChildren().add(menue);
|
||||
AnchorPane.setTopAnchor(menue, 0.0);
|
||||
AnchorPane.setRightAnchor(menue, 0.0);
|
||||
AnchorPane.setLeftAnchor(menue, 0.0);
|
||||
AnchorPane.setBottomAnchor(menue, 0.0);
|
||||
isOpen.put("showCreatureLab", false);
|
||||
isOpen.put("showTerminal", false);
|
||||
isOpen.put("showDevices", false);
|
||||
|
||||
// focus on the tutorial to start
|
||||
Platform.runLater(() -> getTutorialDockNode().requestFocus());
|
||||
connectionManagerDockNode.onMouseClickedProperty().addListener((a, b, c) -> {
|
||||
System.err.println("Cloick");
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void loadMobilebaseFromGit(String id, String file) {
|
||||
menueController.loadMobilebaseFromGit(id, file);
|
||||
}
|
||||
|
||||
private void addTutorial() {
|
||||
Platform.runLater(() -> getTutorialDockNode().dock(dockPane, DockPos.LEFT));
|
||||
|
||||
}
|
||||
|
||||
public void showConectionManager() {
|
||||
String key = "showDevices";
|
||||
if (isOpen.get(key) == null) {
|
||||
isOpen.put(key, false);
|
||||
}
|
||||
if (isOpen.get("showTerminal") == null) {
|
||||
isOpen.put("showTerminal", false);
|
||||
}
|
||||
Platform.runLater(() -> {
|
||||
if (!isOpen.get(key)) {
|
||||
isOpen.put(key, true);
|
||||
if (isOpen.get("showTerminal"))
|
||||
connectionManagerDockNode.dock(dockPane, DockPos.RIGHT, terminalDockNode);
|
||||
else
|
||||
connectionManagerDockNode.dock(dockPane, DockPos.BOTTOM, getTutorialDockNode());
|
||||
connectionManagerDockNode.requestFocus();
|
||||
|
||||
connectionManagerDockNode.closedProperty().addListener(new InvalidationListener() {
|
||||
@Override
|
||||
public void invalidated(Observable event) {
|
||||
connectionManagerDockNode.closedProperty().removeListener(this);
|
||||
isOpen.put(key, false);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
Platform.runLater(() -> connectionManagerDockNode.requestFocus());
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void showTerminal() {
|
||||
|
||||
String key = "showTerminal";
|
||||
if (isOpen.get(key) == null || getTutorialDockNode()==null ||terminalDockNode==null) {
|
||||
isOpen.put(key, false);
|
||||
return;
|
||||
}
|
||||
if (isOpen.get("showDevices") == null) {
|
||||
isOpen.put("showDevices", false);
|
||||
}
|
||||
if (!isOpen.get(key)) {
|
||||
isOpen.put(key, true);
|
||||
Platform.runLater(() -> {
|
||||
|
||||
if (isOpen.get("showDevices"))
|
||||
terminalDockNode.dock(dockPane, DockPos.LEFT, connectionManagerDockNode);
|
||||
else
|
||||
terminalDockNode.dock(dockPane, DockPos.BOTTOM, getTutorialDockNode());
|
||||
terminalDockNode.requestFocus();
|
||||
|
||||
if (ScriptingEngine.isLoginSuccess()) {
|
||||
|
||||
}
|
||||
|
||||
terminalDockNode.closedProperty().addListener(new InvalidationListener() {
|
||||
@Override
|
||||
public void invalidated(Observable event) {
|
||||
terminalDockNode.closedProperty().removeListener(this);
|
||||
isOpen.put(key, false);
|
||||
}
|
||||
});
|
||||
|
||||
Platform.runLater(() -> terminalDockNode.requestFocus());
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void showCreatureLab() {
|
||||
showCreatureLab(0);
|
||||
}
|
||||
|
||||
public void showCreatureLab(int depth) {
|
||||
String key = "showCreatureLab";
|
||||
if (!isOpen.get(key)) {
|
||||
isOpen.put(key, true);
|
||||
new Thread(() -> {
|
||||
ThreadUtil.wait(100);
|
||||
|
||||
Platform.runLater(() -> {
|
||||
try {
|
||||
creatureLab3dDockNode.dock(dockPane, DockPos.RIGHT);
|
||||
isOpen.put(key, true);
|
||||
return;
|
||||
} catch (NullPointerException e) {
|
||||
// keep trying to open
|
||||
// e.printStackTrace();
|
||||
isOpen.put(key, false);
|
||||
if (depth < 2) {
|
||||
showCreatureLab(depth + 1);
|
||||
} else
|
||||
BowlerStudio.printStackTrace(e);// fail and show
|
||||
// user
|
||||
} catch (Exception e) {
|
||||
isOpen.put(key, false);
|
||||
BowlerStudio.printStackTrace(e);// fail and show user
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Platform.runLater(() -> creatureLab3dDockNode.closedProperty().addListener(new InvalidationListener() {
|
||||
@Override
|
||||
public void invalidated(Observable event) {
|
||||
creatureLab3dDockNode.closedProperty().removeListener(this);
|
||||
isOpen.put(key, false);
|
||||
}
|
||||
}));
|
||||
|
||||
}).start();
|
||||
}
|
||||
// else
|
||||
// Platform.runLater(() -> creatureLab3dDockNode.requestFocus());
|
||||
|
||||
}
|
||||
|
||||
public DockNode getTutorialDockNode() {
|
||||
|
||||
return tutorialDockNode;
|
||||
}
|
||||
|
||||
public void setTutorialDockNode(DockNode tutorialDockNode) {
|
||||
this.tutorialDockNode = tutorialDockNode;
|
||||
tutorialDockNode.closableProperty().set(false);
|
||||
}
|
||||
|
||||
public static Stage getPrimaryStage() {
|
||||
return primaryStage;
|
||||
}
|
||||
|
||||
public static void setPrimaryStage(Stage primaryStage) {
|
||||
BowlerStudioModularFrame.primaryStage = primaryStage;
|
||||
}
|
||||
|
||||
public ScriptingFileWidget createFileTab(File file) {
|
||||
// TODO Auto-generated method stub
|
||||
return controller.createFileTab(file);
|
||||
}
|
||||
|
||||
public void openUrlInNewTab(URL url) {
|
||||
Platform.runLater(() -> {
|
||||
try {
|
||||
if (PasswordManager.getUsername() != null) {
|
||||
WebTab newTab = new WebTab("Web", url.toExternalForm(), false);
|
||||
|
||||
addTab(newTab, true);
|
||||
}
|
||||
} catch (IOException | InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void closeTab(Tab newTab) {
|
||||
if (webTabs.get(newTab) != null) {
|
||||
System.err.println("Closing tab: " + newTab.getText());
|
||||
DockNode dn=webTabs.get(newTab);
|
||||
webTabs.remove(newTab);
|
||||
if(dn!=null)
|
||||
Platform.runLater(() -> {
|
||||
try {
|
||||
dn.undock();
|
||||
}catch(java.lang.NullPointerException ex) {}
|
||||
Platform.runLater(() -> dn.close());
|
||||
if(newTab!=null)
|
||||
if (newTab.getOnCloseRequest() != null) {
|
||||
newTab.getOnCloseRequest().handle(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void addTab(Tab newTab, boolean b) {
|
||||
System.err.println("Loading a new tab: " + newTab.getText());
|
||||
if (webTabs.get(newTab) != null) {
|
||||
Platform.runLater(() -> webTabs.get(newTab).requestFocus());
|
||||
} else {
|
||||
Platform.runLater(() -> {
|
||||
DockNode dn = new DockNode(newTab.getContent(), newTab.getText(), newTab.getGraphic());
|
||||
dn.closedProperty().addListener(event -> {
|
||||
closeTab(newTab);
|
||||
});
|
||||
|
||||
webTabs.put(newTab, dn);
|
||||
dn.dock(dockPane, DockPos.CENTER, getTutorialDockNode());
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static BowlerStudioModularFrame getBowlerStudioModularFrame() {
|
||||
return bowlerStudioModularFrame;
|
||||
}
|
||||
|
||||
|
||||
public void setSelectedTab(Tab tab) {
|
||||
if (webTabs.get(tab) != null)
|
||||
Platform.runLater(() -> webTabs.get(tab).requestFocus());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
|
||||
import com.neuronrobotics.bowlerstudio.assets.ConfigurationDatabase;
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* Created by Ryan Benasutti on 2/6/2016.
|
||||
*/
|
||||
|
||||
public class ChangeAssetRepoController extends Application {
|
||||
@FXML
|
||||
private TextField repoField;
|
||||
|
||||
@FXML
|
||||
private Button changeRepoButton, cancelButton;
|
||||
|
||||
public ChangeAssetRepoController() {}
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
FXMLLoader loader = AssetFactory.loadLayout("layout/changeAssetRepo.fxml", true);
|
||||
Parent root;
|
||||
loader.setController(this);
|
||||
// This is needed when loading on MAC
|
||||
loader.setClassLoader(getClass().getClassLoader());
|
||||
root = loader.load();
|
||||
|
||||
Platform.runLater(() -> {
|
||||
primaryStage.setTitle("Change Asset Repository");
|
||||
|
||||
Scene scene = new Scene(root);
|
||||
primaryStage.setScene(scene);
|
||||
primaryStage.initModality(Modality.WINDOW_MODAL);
|
||||
primaryStage.setResizable(true);
|
||||
primaryStage.show();
|
||||
});
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void onChangeRepo(ActionEvent event)
|
||||
{
|
||||
String repo = repoField.getText()
|
||||
.replaceAll("git://", "https://");
|
||||
new Thread(()->{
|
||||
ConfigurationDatabase.setObject("BowlerStudioConfigs", "skinRepo",
|
||||
repo);
|
||||
ConfigurationDatabase.save();
|
||||
|
||||
}).start();
|
||||
|
||||
Stage stage = (Stage) changeRepoButton.getScene().getWindow();
|
||||
stage.close();
|
||||
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void onCancel(ActionEvent event) {
|
||||
Platform.runLater(() -> {
|
||||
Stage stage = (Stage) cancelButton.getScene().getWindow();
|
||||
stage.close();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,561 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
import com.neuronrobotics.addons.driving.HokuyoURGDevice;
|
||||
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
|
||||
import com.neuronrobotics.bowlerstudio.threed.VirtualCameraDevice;
|
||||
import com.neuronrobotics.bowlerstudio.utils.BowlerConnectionMenu;
|
||||
import com.neuronrobotics.imageprovider.AbstractImageProvider;
|
||||
//import com.neuronrobotics.imageprovider.OpenCVImageProvider;
|
||||
import com.neuronrobotics.imageprovider.StaticFileProvider;
|
||||
import com.neuronrobotics.imageprovider.URLImageProvider;
|
||||
import com.neuronrobotics.sdk.addons.gamepad.BowlerJInputDevice;
|
||||
import com.neuronrobotics.sdk.addons.gamepad.IJInputEventListener;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.FirmataBowler;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.gcodebridge.GcodeDevice;
|
||||
import com.neuronrobotics.sdk.common.*;
|
||||
import com.neuronrobotics.sdk.javaxusb.UsbCDCSerialConnection;
|
||||
import com.neuronrobotics.sdk.network.BowlerTCPClient;
|
||||
import com.neuronrobotics.sdk.network.UDPBowlerConnection;
|
||||
import com.neuronrobotics.sdk.serial.SerialConnection;
|
||||
import com.neuronrobotics.sdk.ui.AbstractConnectionPanel;
|
||||
import com.neuronrobotics.sdk.util.ThreadUtil;
|
||||
import com.neuronrobotics.sdk.wireless.bluetooth.BluetoothSerialConnection;
|
||||
import gnu.io.NRSerialPort;
|
||||
import javafx.application.Platform;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.control.Alert.AlertType;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
import net.java.games.input.Component;
|
||||
import net.java.games.input.Controller;
|
||||
import net.java.games.input.ControllerEnvironment;
|
||||
import net.java.games.input.Event;
|
||||
import org.reactfx.util.FxTimer;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
//import org.bytedeco.javacv.OpenCVFrameGrabber;
|
||||
|
||||
public class ConnectionManager extends Tab implements IDeviceAddedListener ,EventHandler<ActionEvent> {
|
||||
|
||||
private static VBox rootItem;
|
||||
private static final ArrayList<PluginManagerWidget> plugins = new ArrayList<PluginManagerWidget>();
|
||||
//private BowlerStudioController bowlerStudioController;
|
||||
String formatStr="%1$-40s %2$-60s %3$-40s";
|
||||
private static final ConnectionManager connectionManager;
|
||||
private static Button disconnectAll;
|
||||
private static HBox topLine;
|
||||
final static Accordion accordion = new Accordion ();
|
||||
static{
|
||||
connectionManager = new ConnectionManager();
|
||||
}
|
||||
|
||||
|
||||
private Node getIcon(String s) {
|
||||
return new ImageView(new Image(
|
||||
AbstractConnectionPanel.class.getResourceAsStream(s)));
|
||||
}
|
||||
|
||||
public ConnectionManager() {
|
||||
if(connectionManager!=null){
|
||||
throw new RuntimeException("Connection manager is a static singleton, access it using ConnectionManager.getConnectionmanager()");
|
||||
}
|
||||
setText("My Devices");
|
||||
setGraphic(AssetFactory.loadIcon("My-Devices.png"));
|
||||
rootItem = new VBox(10);
|
||||
|
||||
// rootItem.getColumnConstraints().add(new ColumnConstraints(30)); // column 1 is 75 wide
|
||||
// rootItem. getColumnConstraints().add(new ColumnConstraints(80)); // column 2 is 300 wide
|
||||
// rootItem.getColumnConstraints().add(new ColumnConstraints(100)); // column 2 is 100 wide
|
||||
// rootItem.getColumnConstraints().add(new ColumnConstraints(50)); // column 2 is 100 wide
|
||||
//
|
||||
topLine = new HBox(20);
|
||||
|
||||
disconnectAll = new Button("Disconnect All",AssetFactory.loadIcon("Disconnect-All.png"));
|
||||
disconnectAll.setOnAction(new EventHandler<ActionEvent>() {
|
||||
@Override public void handle(ActionEvent e) {
|
||||
disconnectAll();
|
||||
}
|
||||
});
|
||||
disconnectAll.setDisable(true);
|
||||
topLine.getChildren().addAll(AssetFactory.loadIcon("Connected-Devices.png"),new Text("Connected Devices"),disconnectAll);
|
||||
rootItem.getChildren().add(topLine);
|
||||
|
||||
rootItem.getChildren().add(accordion);
|
||||
// rootItem = new CheckBoxTreeItem<String>( String.format(" "+formatStr, "SCRIPTING NAME","DEVICE TYPE","MAC ADDRESS"),
|
||||
// getIcon("images/connection-icon.png"
|
||||
// // "images/usb-icon.png"
|
||||
// ));
|
||||
// rootItem.setExpanded(true);
|
||||
// rootItem.setSelected(true);
|
||||
// rootItem.selectedProperty().addListener(b -> {
|
||||
// if (!rootItem.isSelected()) {
|
||||
// disconnectAll();
|
||||
// }
|
||||
// });
|
||||
|
||||
|
||||
setContent(rootItem);
|
||||
|
||||
DeviceManager.addDeviceAddedListener(this);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void addConnection(BowlerAbstractDevice newDevice, String name) {
|
||||
if(!VirtualCameraDevice.class.isInstance(newDevice))
|
||||
DeviceManager.addConnection(newDevice, name);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public static ArrayList<PluginManagerWidget> getPlugins() {
|
||||
return plugins;
|
||||
}
|
||||
//
|
||||
// public BowlerStudioController getBowlerStudioController() {
|
||||
// return bowlerStudioController;
|
||||
// }
|
||||
//
|
||||
// public void setBowlerStudioController(
|
||||
// BowlerStudioController bowlerStudioController) {
|
||||
// this.bowlerStudioController = bowlerStudioController;
|
||||
// }
|
||||
|
||||
public static BowlerAbstractDevice pickConnectedDevice(@SuppressWarnings("rawtypes") Class class1) {
|
||||
List<String> choices = DeviceManager.listConnectedDevice(class1);
|
||||
|
||||
if(!choices.isEmpty()){
|
||||
ChoiceDialog<String> dialog = new ChoiceDialog<>(choices.get(0),
|
||||
choices);
|
||||
dialog.setTitle("Bowler Device Chooser");
|
||||
dialog.setHeaderText("Choose connected bowler device");
|
||||
dialog.setContentText("Device Name:");
|
||||
|
||||
// Traditional way to get the response value.
|
||||
Optional<String> result = dialog.showAndWait();
|
||||
if (result.isPresent()) {
|
||||
for (int i = 0; i < plugins.size(); i++) {
|
||||
if (plugins.get(i).getManager().getName().contains(result.get())) {
|
||||
return plugins.get(i).getManager().getDevice();
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
Alert alert = new Alert(AlertType.INFORMATION);
|
||||
alert.setTitle("Device not availible");
|
||||
alert.setHeaderText("Connect a "+class1.getSimpleName());
|
||||
alert.setContentText("A device of type "+class1.getSimpleName()+" is needed");
|
||||
alert .initModality(Modality.APPLICATION_MODAL);
|
||||
alert.show();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// public BowlerAbstractDevice pickConnectedDevice() {
|
||||
//
|
||||
// return pickConnectedDevice(null);
|
||||
// }
|
||||
|
||||
public static void disconnectAll() {
|
||||
|
||||
//extract list int thread safe object
|
||||
Object [] pms= plugins.toArray();
|
||||
for (int i=0;i<pms.length;i++) {
|
||||
disconectAndRemoveDevice(((PluginManagerWidget)pms[i]).getManager());
|
||||
//ThreadUtil.wait(50);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// public static OpenCVImageProvider onConnectCVCamera() {
|
||||
// List<String> choices = new ArrayList<>();
|
||||
// choices.add("0");
|
||||
// choices.add("1");
|
||||
// choices.add("2");
|
||||
// choices.add("3");
|
||||
// choices.add("4");
|
||||
//
|
||||
// ChoiceDialog<String> dialog = new ChoiceDialog<>("0", choices);
|
||||
// dialog.setTitle("OpenCV Camera Index Chooser");
|
||||
// dialog.setHeaderText("Choose an OpenCV camera");
|
||||
// dialog.setContentText("Camera Index:");
|
||||
//
|
||||
// // Traditional way to get the response value.
|
||||
// Optional<String> result = dialog.showAndWait();
|
||||
//
|
||||
// // The Java 8 way to get the response value (with lambda expression).
|
||||
// if (result !=null) {
|
||||
// String letter = result.get();
|
||||
// OpenCVImageProvider p = new OpenCVImageProvider(Integer.parseInt(letter));
|
||||
// String name = "camera"+letter;
|
||||
// addConnection(p,name);
|
||||
// return p;
|
||||
// }
|
||||
// return null;
|
||||
//// OpenCVImageProvider p = new OpenCVImageProvider(0);
|
||||
//// String name = "camera0";
|
||||
//// application.addConnection(p,name);
|
||||
//
|
||||
// }
|
||||
//
|
||||
|
||||
|
||||
public static void onConnectJavaCVCamera() {
|
||||
// onConnectCVCamera();
|
||||
// List<String> choices = new ArrayList<>();
|
||||
// try {
|
||||
// String[] des = OpenCVFrameGrabber.getDeviceDescriptions();
|
||||
// if(des.length==0)
|
||||
// return;
|
||||
// for (String s: des){
|
||||
// choices.add(s);
|
||||
// }
|
||||
// } catch (org.bytedeco.javacv.FrameGrabber.Exception |UnsupportedOperationException e1) {
|
||||
// choices.add("0");
|
||||
// choices.add("1");
|
||||
// choices.add("2");
|
||||
// choices.add("3");
|
||||
// choices.add("4");
|
||||
// }
|
||||
//
|
||||
// ChoiceDialog<String> dialog = new ChoiceDialog<>(choices.get(0), choices);
|
||||
// dialog.setTitle("JavaCV Camera Index Chooser");
|
||||
// dialog.setHeaderText("Choose an JavaCV camera");
|
||||
// dialog.setContentText("Camera Index:");
|
||||
//
|
||||
// // Traditional way to get the response value.
|
||||
// Optional<String> result = dialog.showAndWait();
|
||||
//
|
||||
// // The Java 8 way to get the response value (with lambda expression).
|
||||
// result.ifPresent(letter -> {
|
||||
// JavaCVImageProvider p;
|
||||
// try {
|
||||
// p = new JavaCVImageProvider(Integer.parseInt(letter));
|
||||
// String name = "camera"+letter;
|
||||
// addConnection(p,name);
|
||||
// } catch (Exception e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// });
|
||||
//
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void onConnectFileSourceCamera() {
|
||||
Platform.runLater(()->{});
|
||||
|
||||
FileChooser fileChooser = new FileChooser();
|
||||
fileChooser.setTitle("Open Image File");
|
||||
File f = fileChooser.showOpenDialog(BowlerStudioModularFrame.getPrimaryStage());
|
||||
if(f!=null){
|
||||
AbstractImageProvider p = new StaticFileProvider(f);
|
||||
String name = "image";
|
||||
addConnection(p,name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void onConnectURLSourceCamera() {
|
||||
TextInputDialog dialog = new TextInputDialog("http://neuronrobotics.com/img/AndrewHarrington/2014-09-15-86.jpg");
|
||||
dialog.setTitle("URL Image Source");
|
||||
dialog.setHeaderText("This url will be loaded each capture.");
|
||||
dialog.setContentText("URL ");
|
||||
|
||||
// Traditional way to get the response value.
|
||||
Optional<String> result = dialog.showAndWait();
|
||||
if (result.isPresent()){
|
||||
URLImageProvider p;
|
||||
try {
|
||||
p = new URLImageProvider(new URL(result.get()));
|
||||
String name = "url";
|
||||
addConnection(p,name);
|
||||
} catch (MalformedURLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void onMarlinGCODE() {
|
||||
Set<String> ports = NRSerialPort.getAvailableSerialPorts();
|
||||
List<String> choices = new ArrayList<>();
|
||||
if(ports.isEmpty())
|
||||
return;
|
||||
for (String s: ports){
|
||||
choices.add(s);
|
||||
}
|
||||
|
||||
|
||||
ChoiceDialog<String> dialog = new ChoiceDialog<>(choices.get(0), choices);
|
||||
dialog.setTitle("GCODE Device Serial Port Chooser");
|
||||
dialog.setHeaderText("Supports Marlin");
|
||||
dialog.setContentText("GCODE Device Port:");
|
||||
|
||||
// Traditional way to get the response value.
|
||||
Optional<String> result = dialog.showAndWait();
|
||||
|
||||
// The Java 8 way to get the response value (with lambda expression).
|
||||
result.ifPresent(letter -> {
|
||||
GcodeDevice p = new GcodeDevice(new NRSerialPort(letter, 115200));
|
||||
p.connect();
|
||||
String name = "GCODE";
|
||||
addConnection(p,name);
|
||||
});
|
||||
|
||||
}
|
||||
public static void onConnectHokuyoURG() {
|
||||
Set<String> ports = NRSerialPort.getAvailableSerialPorts();
|
||||
List<String> choices = new ArrayList<>();
|
||||
if(ports.isEmpty())
|
||||
return;
|
||||
for (String s: ports){
|
||||
choices.add(s);
|
||||
}
|
||||
|
||||
|
||||
ChoiceDialog<String> dialog = new ChoiceDialog<>(choices.get(0), choices);
|
||||
dialog.setTitle("LIDAR Serial Port Chooser");
|
||||
dialog.setHeaderText("Supports URG-04LX-UG01");
|
||||
dialog.setContentText("Lidar Port:");
|
||||
|
||||
// Traditional way to get the response value.
|
||||
Optional<String> result = dialog.showAndWait();
|
||||
|
||||
// The Java 8 way to get the response value (with lambda expression).
|
||||
result.ifPresent(letter -> {
|
||||
HokuyoURGDevice p = new HokuyoURGDevice(new NRSerialPort(letter, 115200));
|
||||
p.connect();
|
||||
String name = "lidar";
|
||||
addConnection(p,name);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void onConnectGamePad(String name ) {
|
||||
Controller[] ca = ControllerEnvironment.getDefaultEnvironment().getControllers();
|
||||
|
||||
List<String> choices = new ArrayList<>();
|
||||
if(ca.length==0)
|
||||
return;
|
||||
for (Controller s: ca){
|
||||
choices.add(s.getName());
|
||||
}
|
||||
|
||||
|
||||
ChoiceDialog<String> dialog = new ChoiceDialog<>(choices.get(0), choices);
|
||||
dialog.setTitle("JInput Game Controller Select");
|
||||
dialog.setHeaderText("Connect a game controller");
|
||||
dialog.setContentText("Controller:");
|
||||
|
||||
// Traditional way to get the response value.
|
||||
Optional<String> result = dialog.showAndWait();
|
||||
|
||||
// The Java 8 way to get the response value (with lambda expression).
|
||||
result.ifPresent(letter -> {
|
||||
for(Controller s: ca){
|
||||
if(letter.contains(s.getName())){
|
||||
BowlerJInputDevice p =new BowlerJInputDevice(s);
|
||||
p.connect();
|
||||
IJInputEventListener l=new IJInputEventListener() {
|
||||
@Override
|
||||
public void onEvent(Component comp, Event event1,
|
||||
float value, String eventString) {
|
||||
//System.out.println(comp.getName()+" is value= "+value);
|
||||
}
|
||||
};
|
||||
p.addListeners(l);
|
||||
addConnection(p,name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewDeviceAdded(BowlerAbstractDevice newDevice) {
|
||||
if(VirtualCameraDevice.class.isInstance(newDevice))
|
||||
return;
|
||||
PluginManager mp;
|
||||
Log.debug("Adding a "+newDevice.getClass().getName()+" with name "+newDevice.getScriptingName() );
|
||||
mp = new PluginManager(newDevice);
|
||||
|
||||
|
||||
BowlerAbstractConnection con = newDevice.getConnection();
|
||||
Node icon = getIcon("images/connection-icon.png"
|
||||
// "images/usb-icon.png"
|
||||
);
|
||||
if (SerialConnection.class.isInstance(con)) {
|
||||
icon = getIcon(
|
||||
// "images/ethernet-icon.png"
|
||||
"images/usb-icon.png");
|
||||
} else if (UsbCDCSerialConnection.class.isInstance(con)) {
|
||||
icon = getIcon(
|
||||
// "images/ethernet-icon.png"
|
||||
"images/usb-icon.png");
|
||||
} else if (BluetoothSerialConnection.class.isInstance(con)) {
|
||||
icon = getIcon(
|
||||
// "images/ethernet-icon.png"
|
||||
"images/bluetooth-icon.png");
|
||||
} else if (UDPBowlerConnection.class.isInstance(con)
|
||||
|| BowlerTCPClient.class.isInstance(con)) {
|
||||
icon = getIcon(
|
||||
// "images/ethernet-icon.png"
|
||||
"images/ethernet-icon.png");
|
||||
}
|
||||
String line = String.format(formatStr,
|
||||
newDevice.getScriptingName(),
|
||||
newDevice.getClass().getSimpleName(),
|
||||
newDevice.getAddress());
|
||||
PluginManagerWidget e = new PluginManagerWidget(mp,icon);
|
||||
plugins.add(e);
|
||||
Platform.runLater(() -> accordion.getPanes().add(e));
|
||||
Platform.runLater(() -> disconnectAll.setDisable(false));
|
||||
|
||||
|
||||
mp.setName(newDevice.getScriptingName());
|
||||
|
||||
newDevice.addConnectionEventListener(
|
||||
new IDeviceConnectionEventListener() {
|
||||
@Override
|
||||
public void onDisconnect(BowlerAbstractDevice source) {
|
||||
// clean up after yourself...
|
||||
//disconectAndRemoveDevice(mp);
|
||||
|
||||
for(int i=0;i<plugins.size();i++){
|
||||
PluginManager p=plugins.get(i).getManager();
|
||||
if(p.getDevice()==source){
|
||||
DeviceManager.remove(p.getDevice());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ignore
|
||||
@Override
|
||||
public void onConnect(BowlerAbstractDevice source) {
|
||||
}
|
||||
});
|
||||
if( getBowlerStudioController()!=null)
|
||||
BowlerStudioModularFrame.getBowlerStudioModularFrame().setSelectedTab(this);
|
||||
}
|
||||
private BowlerStudioController getBowlerStudioController() {
|
||||
// TODO Auto-generated method stub
|
||||
return BowlerStudioController.getBowlerStudio();
|
||||
}
|
||||
|
||||
|
||||
private static void disconectAndRemoveDevice(PluginManager mp){
|
||||
System.out.println("CM Disconnecting " + mp.getName());
|
||||
Log.warning("Disconnecting " + mp.getName());
|
||||
if(mp.getDevice().isAvailable() || NonBowlerDevice.class.isInstance(mp))
|
||||
mp.getDevice().disconnect();
|
||||
DeviceManager.remove(mp.getDevice());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceRemoved(BowlerAbstractDevice bad) {
|
||||
Log.warning("Removing Device " + bad.getScriptingName());
|
||||
//new RuntimeException().printStackTrace();
|
||||
for(int i=0;i<plugins.size();i++){
|
||||
PluginManager p=plugins.get(i).getManager();
|
||||
if(p.getDevice()==bad){
|
||||
Log.warning("Found Device " + bad.getScriptingName());
|
||||
//new RuntimeException().printStackTrace();
|
||||
PluginManagerWidget torem = plugins.remove(i);
|
||||
Platform.runLater(() ->accordion.getPanes().remove(torem));
|
||||
if (plugins.isEmpty()){
|
||||
Platform.runLater(() ->disconnectAll.setDisable(true));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void addConnection() {
|
||||
Stage s = new Stage();
|
||||
new Thread() {
|
||||
public void run() {
|
||||
BowlerDatagram.setUseBowlerV4(true);
|
||||
BowlerConnectionMenu controller = new BowlerConnectionMenu();
|
||||
try {
|
||||
controller.start(s);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
//DeviceManager.addConnection();
|
||||
}
|
||||
|
||||
|
||||
public static ConnectionManager getConnectionManager() {
|
||||
return connectionManager;
|
||||
}
|
||||
|
||||
public static void onFirmata() {
|
||||
Set<String> ports = NRSerialPort.getAvailableSerialPorts();
|
||||
List<String> choices = new ArrayList<>();
|
||||
if(ports.isEmpty())
|
||||
return;
|
||||
for (String s: ports){
|
||||
choices.add(s);
|
||||
}
|
||||
|
||||
|
||||
ChoiceDialog<String> dialog = new ChoiceDialog<>(choices.get(0), choices);
|
||||
dialog.setTitle("Firmata Device Serial Port Chooser");
|
||||
dialog.setHeaderText("Supports Firmata");
|
||||
dialog.setContentText("Firmata Device Port:");
|
||||
|
||||
// Traditional way to get the response value.
|
||||
Optional<String> result = dialog.showAndWait();
|
||||
|
||||
// The Java 8 way to get the response value (with lambda expression).
|
||||
result.ifPresent(letter -> {
|
||||
new Thread(()->{
|
||||
System.out.print("\nConnecting Firmata...");
|
||||
FirmataBowler p = new FirmataBowler(letter);
|
||||
p.connect();
|
||||
String name = "firmata";
|
||||
addConnection(p,name);
|
||||
System.out.print("Done!\n");
|
||||
}).start();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
|
||||
/**
|
||||
* Sample Skeleton for "CreatureLab.fxml" Controller Class
|
||||
* You can copy and paste this code into your favorite IDE
|
||||
**/
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.threed.BowlerStudio3dEngine;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Bounds;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.SubScene;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
import javafx.scene.control.TreeView;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
|
||||
|
||||
public class CreatureLab3dController {
|
||||
|
||||
@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="CadControlsAnchor"
|
||||
private AnchorPane CadControlsAnchor; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="DriveControlsAnchor"
|
||||
private AnchorPane DriveControlsAnchor; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="TempControlsAnchor"
|
||||
private AnchorPane TempControlsAnchor; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="jfx3dControls"
|
||||
private AnchorPane jfx3dControls; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="overlayScrollPanel"
|
||||
private ScrollPane overlayScrollPanel; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="viewContainer"
|
||||
private AnchorPane viewContainer; // Value injected by FXMLLoader
|
||||
//private SubScene subScene;
|
||||
protected EventHandler<? super KeyEvent> normalKeyPessHandle = null;
|
||||
|
||||
private static BowlerStudio3dEngine engine;
|
||||
|
||||
public CreatureLab3dController (){
|
||||
|
||||
setEngine(new BowlerStudio3dEngine());
|
||||
}
|
||||
|
||||
public void setOverlayLeft(Node content) {
|
||||
Platform.runLater(() -> {
|
||||
|
||||
overlayScrollPanel.setFitToHeight(true);
|
||||
overlayScrollPanel.setContent(content);
|
||||
content.setOpacity(1);
|
||||
overlayScrollPanel.viewportBoundsProperty()
|
||||
.addListener((ObservableValue<? extends Bounds> arg0, Bounds arg1, Bounds arg2) -> {
|
||||
// Node content = overlayScrollPanel.getContent();
|
||||
//
|
||||
// System.out.println("Resizing " + arg2);
|
||||
Platform.runLater(() -> {
|
||||
overlayScrollPanel.setFitToHeight(true);
|
||||
/// content.seth
|
||||
overlayScrollPanel.setContent(content);
|
||||
|
||||
});
|
||||
});
|
||||
overlayScrollPanel.setVisible(true);
|
||||
});
|
||||
}
|
||||
|
||||
public void clearOverlayLeft() {
|
||||
Platform.runLater(() -> {
|
||||
overlayScrollPanel.setContent(null);
|
||||
overlayScrollPanel.setVisible(false);
|
||||
});
|
||||
}
|
||||
|
||||
public void setOverlayTop(Group content) {
|
||||
Platform.runLater(() -> {
|
||||
CadControlsAnchor.getChildren().clear();
|
||||
CadControlsAnchor.getChildren().add(content);
|
||||
|
||||
AnchorPane.setTopAnchor(content, 0.0);
|
||||
AnchorPane.setRightAnchor(content, 0.0);
|
||||
AnchorPane.setLeftAnchor(content, 0.0);
|
||||
AnchorPane.setBottomAnchor(content, 0.0);
|
||||
CadControlsAnchor.setVisible(true);
|
||||
});
|
||||
}
|
||||
|
||||
public void clearOverlayTop() {
|
||||
Platform.runLater(() -> {
|
||||
CadControlsAnchor.getChildren().clear();
|
||||
CadControlsAnchor.setVisible(false);
|
||||
});
|
||||
}
|
||||
|
||||
public void setOverlayTopRight(Group content) {
|
||||
Platform.runLater(() -> {
|
||||
DriveControlsAnchor.getChildren().clear();
|
||||
DriveControlsAnchor.getChildren().add(content);
|
||||
AnchorPane.setTopAnchor(content, 0.0);
|
||||
AnchorPane.setRightAnchor(content, 0.0);
|
||||
AnchorPane.setLeftAnchor(content, 0.0);
|
||||
AnchorPane.setBottomAnchor(content, 0.0);
|
||||
DriveControlsAnchor.setVisible(true);
|
||||
});
|
||||
}
|
||||
|
||||
public void clearOverlayTopRight() {
|
||||
Platform.runLater(() -> {
|
||||
DriveControlsAnchor.getChildren().clear();
|
||||
DriveControlsAnchor.setVisible(false);
|
||||
});
|
||||
}
|
||||
|
||||
public void setOverlayBottomRight(Group content) {
|
||||
Platform.runLater(() -> {
|
||||
TempControlsAnchor.getChildren().clear();
|
||||
TempControlsAnchor.getChildren().add(content);
|
||||
AnchorPane.setTopAnchor(content, 0.0);
|
||||
AnchorPane.setRightAnchor(content, 0.0);
|
||||
AnchorPane.setLeftAnchor(content, 0.0);
|
||||
AnchorPane.setBottomAnchor(content, 0.0);
|
||||
TempControlsAnchor.setVisible(true);
|
||||
});
|
||||
}
|
||||
|
||||
public void clearOverlayBottomRight() {
|
||||
Platform.runLater(() -> {
|
||||
TempControlsAnchor.getChildren().clear();
|
||||
TempControlsAnchor.setVisible(false);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@FXML // This method is called by the FXMLLoader when initialization is complete
|
||||
void initialize() {
|
||||
assert CadControlsAnchor != null : "fx:id=\"CadControlsAnchor\" was not injected: check your FXML file 'CreatureLab.fxml'.";
|
||||
assert DriveControlsAnchor != null : "fx:id=\"DriveControlsAnchor\" was not injected: check your FXML file 'CreatureLab.fxml'.";
|
||||
assert TempControlsAnchor != null : "fx:id=\"TempControlsAnchor\" was not injected: check your FXML file 'CreatureLab.fxml'.";
|
||||
assert jfx3dControls != null : "fx:id=\"jfx3dControls\" was not injected: check your FXML file 'CreatureLab.fxml'.";
|
||||
assert overlayScrollPanel != null : "fx:id=\"overlayScrollPanel\" was not injected: check your FXML file 'CreatureLab.fxml'.";
|
||||
assert viewContainer != null : "fx:id=\"viewContainer\" was not injected: check your FXML file 'CreatureLab.fxml'.";
|
||||
clearOverlayLeft();
|
||||
// Initialize your logic here: all @FXML variables will have been injected
|
||||
setupUi();
|
||||
|
||||
}
|
||||
|
||||
private void setupUi() {
|
||||
Platform.runLater(() -> {
|
||||
getEngine() .getSubScene().setFocusTraversable(false);
|
||||
getEngine() .getSubScene().widthProperty().bind(viewContainer.widthProperty());
|
||||
getEngine() .getSubScene().heightProperty().bind(viewContainer.heightProperty());
|
||||
});
|
||||
Platform.runLater(() -> {
|
||||
jfx3dControls.getChildren().add(getEngine().getControlsBox());
|
||||
viewContainer.getChildren().add(getEngine() .getSubScene());
|
||||
AnchorPane.setTopAnchor(getEngine() .getSubScene(), 0.0);
|
||||
AnchorPane.setRightAnchor(getEngine() .getSubScene(), 0.0);
|
||||
AnchorPane.setLeftAnchor(getEngine() .getSubScene(), 0.0);
|
||||
AnchorPane.setBottomAnchor(getEngine() .getSubScene(), 0.0);
|
||||
});
|
||||
}
|
||||
|
||||
public static BowlerStudio3dEngine getEngine() {
|
||||
return engine;
|
||||
}
|
||||
|
||||
public static void setEngine(BowlerStudio3dEngine engine) {
|
||||
CreatureLab3dController.engine = engine;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.tabs.AbstractBowlerStudioTab;
|
||||
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
|
||||
import com.neuronrobotics.sdk.namespace.bcs.pid.IPidControlNamespace;
|
||||
|
||||
public class DeviceSupportPluginMap implements PluginFactory{
|
||||
|
||||
private Class<?> device;
|
||||
private Class<?> plugin;
|
||||
private PluginFactory factory=null;
|
||||
|
||||
|
||||
DeviceSupportPluginMap(Class<?> device,Class<?> plugin){
|
||||
this.setDevice(device);
|
||||
this.setPlugin(plugin);
|
||||
|
||||
}
|
||||
public DeviceSupportPluginMap(Class<?> device,Class<?> plugin, PluginFactory factory){
|
||||
this.factory = factory;
|
||||
this.setDevice(device);
|
||||
this.setPlugin(plugin);
|
||||
|
||||
}
|
||||
|
||||
public boolean isFactoryProvided(){
|
||||
return factory!=null;
|
||||
}
|
||||
|
||||
public Class<?> getDevice() {
|
||||
return device;
|
||||
}
|
||||
|
||||
private void setDevice(Class<?> device) {
|
||||
if(BowlerAbstractDevice.class.isAssignableFrom(device) || IPidControlNamespace.class.isAssignableFrom(device) )
|
||||
this.device = device;
|
||||
else
|
||||
throw new RuntimeException("Devices must subclass BowlerAbstractDevice or NonBowlerDevice");
|
||||
}
|
||||
|
||||
public Class<?> getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
private void setPlugin(Class<?> plugin) {
|
||||
if(AbstractBowlerStudioTab.class.isAssignableFrom(plugin) )
|
||||
this.plugin = plugin;
|
||||
else
|
||||
throw new RuntimeException("Plugins must subclass AbstractBowlerStudioTab");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "Device: "+device.getCanonicalName()+" Plugin: "+plugin.getCanonicalName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractBowlerStudioTab generateNewPlugin() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
|
||||
if(factory!=null)
|
||||
return factory.generateNewPlugin();
|
||||
return (AbstractBowlerStudioTab) Class.forName(
|
||||
plugin.getName()
|
||||
).cast(plugin.newInstance()// This is where the new tab allocation is called
|
||||
)
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.scripting.PasswordManager;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
|
||||
import com.neuronrobotics.sdk.util.ThreadUtil;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.jfree.util.Log;
|
||||
import org.kohsuke.github.GHGist;
|
||||
import org.kohsuke.github.GHGistBuilder;
|
||||
import org.kohsuke.github.GHGistFile;
|
||||
import org.kohsuke.github.GitHub;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Created by Ryan Benasutti on 2/5/2016.
|
||||
*/
|
||||
|
||||
public class GistHelper
|
||||
{
|
||||
private GistHelper() {}
|
||||
|
||||
public static String createNewGist(String filename, String description, boolean isPublic)
|
||||
{
|
||||
//TODO: Perhaps this method should throw GitAPIException and IOException
|
||||
//Setup gist
|
||||
GitHub gitHub = PasswordManager.getGithub();
|
||||
GHGistBuilder builder = gitHub.createGist();
|
||||
builder.file(filename, "//Your code here");
|
||||
builder.description(description);
|
||||
builder.public_(isPublic);
|
||||
|
||||
//Make gist
|
||||
return createGistFromBuilder(builder, filename);
|
||||
}
|
||||
|
||||
public static String addFileToGist(String filename, String content, GHGist gistID)
|
||||
{
|
||||
GitHub gitHub = PasswordManager.getGithub();
|
||||
try
|
||||
{
|
||||
//Copy from old gist
|
||||
GHGist oldGist = gistID;
|
||||
GHGistBuilder builder = gitHub.createGist();
|
||||
|
||||
builder.description(oldGist.getDescription());
|
||||
builder.public_(oldGist.isPublic());
|
||||
|
||||
for (String key : oldGist.getFiles().keySet())
|
||||
builder.file(key, oldGist.getFiles().get(key).getContent());
|
||||
|
||||
//Add new file
|
||||
builder.file(filename, content);
|
||||
|
||||
//Make new gist with old filename
|
||||
return createGistFromBuilder(builder, oldGist.getFiles().values().iterator().next().getFileName());
|
||||
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String createGistFromBuilder(GHGistBuilder builder, String filename)
|
||||
{
|
||||
GHGist gist;
|
||||
try
|
||||
{
|
||||
gist = builder.create();
|
||||
//String gistID = ScriptingEngine.urlToGist(gist.getHtmlUrl());
|
||||
|
||||
//BowlerStudio.openUrlInNewTab(new URL(gist.getHtmlUrl()));
|
||||
System.out.println("Creating repo");
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
ScriptingEngine.fileFromGit(gist.getGitPullUrl(), filename);
|
||||
break;
|
||||
}
|
||||
catch (GitAPIException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
ThreadUtil.wait(500);
|
||||
Log.warn(filename + " not built yet");
|
||||
}
|
||||
|
||||
System.out.println("Creating gist at " + filename);
|
||||
return gist.getGitPullUrl();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.assets.BowlerStudioResourceFactory;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.GithubLoginFX;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.IGitHubLoginManager;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.IGithubLoginListener;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
|
||||
import com.neuronrobotics.sdk.util.ThreadUtil;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
public class GitHubLoginManager implements IGitHubLoginManager {
|
||||
private boolean loginWindowOpen = false;
|
||||
private GithubLoginFX githublogin = null;
|
||||
private Stage stage;
|
||||
private boolean AnonSelected = false;
|
||||
private String[] creds;
|
||||
|
||||
public GitHubLoginManager() {
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
@Override
|
||||
public String[] prompt(String username) {
|
||||
if (AnonSelected) {
|
||||
return null;
|
||||
}
|
||||
boolean loginWas = loginWindowOpen;
|
||||
|
||||
if (githublogin != null)
|
||||
githublogin.reset();
|
||||
if (stage == null) {
|
||||
if (!loginWas && githublogin != null)
|
||||
githublogin.reset();
|
||||
githublogin = null;
|
||||
// System.out.println("Calling login from BowlerStudio "+username);
|
||||
// new RuntimeException().printStackTrace();
|
||||
FXMLLoader fxmlLoader = BowlerStudioResourceFactory.getGithubLogin();
|
||||
if (fxmlLoader == null)
|
||||
return null;
|
||||
Parent root = fxmlLoader.getRoot();
|
||||
if (githublogin == null) {
|
||||
githublogin = fxmlLoader.getController();
|
||||
githublogin.reset();
|
||||
Platform.runLater(() -> {
|
||||
if (!loginWindowOpen) {
|
||||
githublogin.reset();
|
||||
githublogin.getUsername().setText(username);
|
||||
stage = new Stage();
|
||||
stage.setTitle("GitHub Login");
|
||||
// stage.initModality(Modality.APPLICATION_MODAL);
|
||||
githublogin.setStage(stage, root);
|
||||
stage.centerOnScreen();
|
||||
|
||||
loginWindowOpen = true;
|
||||
stage.setAlwaysOnTop(true);
|
||||
stage.show();
|
||||
|
||||
stage = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// setContent(root);
|
||||
do {
|
||||
// System.err.println("Waiting for user login");
|
||||
|
||||
ThreadUtil.wait(100);
|
||||
} while (!githublogin.isDone());
|
||||
creds = githublogin.getCreds();
|
||||
// System.err.println(" login = "+creds);
|
||||
if (creds == null) {
|
||||
// System.err.println("Anon mode");
|
||||
AnonSelected = true;
|
||||
}
|
||||
loginWindowOpen = false;
|
||||
return creds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String twoFactorAuthCodePrompt() {
|
||||
JFrame jframe = new JFrame();
|
||||
String answer = JOptionPane.showInputDialog(jframe, "Enter 2 factor auth code:");
|
||||
jframe.dispose();
|
||||
return answer;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
import javafx.scene.control.Menu;
|
||||
|
||||
public interface INewVitaminCallback {
|
||||
void addVitaminType(String s);
|
||||
|
||||
Menu getTypeMenu(String type);
|
||||
|
||||
void addSizesToMenu(String size,String type);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class MeasurmentConfig {
|
||||
private String key;
|
||||
private HashMap<String, Object> configs;
|
||||
public MeasurmentConfig(String key,HashMap<String, Object> configs){
|
||||
this.configs = configs;
|
||||
this.setKey(key);
|
||||
System.out.println("Adding Measurment "+key+" "+getMeasurment());
|
||||
}
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
public String getMeasurment() {
|
||||
return configs.get(key).toString();
|
||||
}
|
||||
public void setMeasurment(String measurment) {
|
||||
System.out.println("Setting field "+key+" to "+measurment);
|
||||
configs.put(key, measurment);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
public interface MenuRefreshEvent {
|
||||
void setToLoggedIn();
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
import javafx.event.Event;
|
||||
import javafx.event.EventHandler;
|
||||
|
||||
public abstract class MenuResettingEventHandler implements EventHandler<Event> {
|
||||
private Runnable menuReset = null;
|
||||
|
||||
public Runnable getMenuReset() {
|
||||
if(menuReset==null)
|
||||
menuReset=new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
};
|
||||
return menuReset;
|
||||
}
|
||||
|
||||
public void setMenuReset(Runnable menuReset) {
|
||||
this.menuReset = menuReset;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
public class NewCreatureWizard {
|
||||
|
||||
public static void run() {
|
||||
new Thread(()->{
|
||||
Thread.setDefaultUncaughtExceptionHandler(new IssueReportingExceptionHandler());
|
||||
|
||||
}).start();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,577 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
/**
|
||||
* Sample Skeleton for 'newVitaminWizard.fxml' Controller Class
|
||||
*/
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Optional;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import org.kohsuke.github.GHCreateRepositoryBuilder;
|
||||
import org.kohsuke.github.GHRepository;
|
||||
import org.kohsuke.github.GitHub;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.PasswordManager;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
|
||||
import com.neuronrobotics.bowlerstudio.vitamins.Vitamins;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.JavaFXInitializer;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Alert.AlertType;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Menu;
|
||||
import javafx.scene.control.RadioButton;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.TextInputDialog;
|
||||
import javafx.scene.control.ToggleGroup;
|
||||
import javafx.scene.control.cell.PropertyValueFactory;
|
||||
import javafx.scene.control.cell.TextFieldTableCell;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.text.Font;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.StageStyle;
|
||||
|
||||
public class NewVitaminWizardController extends Application {
|
||||
@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="typePane"
|
||||
private AnchorPane typePane; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="x1"
|
||||
private Font x1; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="x2"
|
||||
private Color x2; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="existingTypeRadio"
|
||||
private RadioButton existingTypeRadio; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="newTypeRadio"
|
||||
private RadioButton newTypeRadio; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="typeComboBox"
|
||||
private ComboBox<String> typeComboBox; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="sizePane"
|
||||
private AnchorPane sizePane; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="sizeComboBox"
|
||||
private ComboBox<String> sizeComboBox; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="measurmentPane"
|
||||
private AnchorPane measurmentPane; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="measurmentsTable"
|
||||
private TableView<MeasurmentConfig> measurmentsTable; // Value injected by FXMLLoader
|
||||
@FXML
|
||||
private TextField newTypeNameField;
|
||||
@FXML
|
||||
private TextField newSizeField;
|
||||
@FXML // fx:id="nameColumn"
|
||||
private TableColumn<MeasurmentConfig, String> nameColumn; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="measurmentColumn"
|
||||
private TableColumn<MeasurmentConfig, String> measurmentColumn; // Value injected by FXMLLoader
|
||||
@FXML // fx:id="isMotor"
|
||||
private CheckBox isMotor; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="isShaft"
|
||||
private CheckBox isShaft; // Value injected by FXMLLoader
|
||||
@FXML // fx:id="editExisting"
|
||||
private CheckBox editExisting; // Value injected by FXMLLoader
|
||||
@FXML // fx:id="editExisting"
|
||||
private Button newMeasurmentButton;
|
||||
|
||||
private static INewVitaminCallback callback=null;
|
||||
|
||||
private static Stage primaryStage;
|
||||
private static String typeOfVitaminString = null;
|
||||
|
||||
private static String sizeOfVitaminString = null;
|
||||
|
||||
@FXML
|
||||
void onConfirmAndCreate(ActionEvent event) {
|
||||
sizePane.setDisable(true);
|
||||
measurmentPane.setDisable(true);
|
||||
typePane.setDisable(true);
|
||||
new Thread(() -> {
|
||||
try {
|
||||
|
||||
if(newTypeRadio.isSelected()) {
|
||||
if(isShaft.isSelected())
|
||||
Vitamins.setIsShaft(typeOfVitaminString);
|
||||
if(isMotor.isSelected())
|
||||
Vitamins.setIsActuator(typeOfVitaminString);
|
||||
GitHub github = PasswordManager.getGithub();
|
||||
|
||||
String newName =typeOfVitaminString+"CadGenerator";
|
||||
GHCreateRepositoryBuilder builder = github.createRepository(newName );
|
||||
builder.description(newName + " Generates CAD vitamins " );
|
||||
GHRepository gist=null;
|
||||
try {
|
||||
gist = builder.create();
|
||||
}catch(org.kohsuke.github.HttpException ex) {
|
||||
if(ex.getMessage().contains("name already exists on this account")) {
|
||||
gist = github.getRepository(PasswordManager.getLoginID()+"/"+newName);
|
||||
}
|
||||
}
|
||||
String gitURL = gist.getHtmlUrl().toExternalForm()+".git";
|
||||
String filename = typeOfVitaminString+".groovy";
|
||||
Vitamins.setScript(typeOfVitaminString, gitURL, filename);
|
||||
|
||||
String measurments ="";
|
||||
for(String key:Vitamins.getConfiguration( typeOfVitaminString,sizeOfVitaminString).keySet()) {
|
||||
measurments+="\n def "+key+"Value = measurments."+key;
|
||||
}
|
||||
for(String key:Vitamins.getConfiguration( typeOfVitaminString,sizeOfVitaminString).keySet()) {
|
||||
String string = key+"Value";
|
||||
measurments+="\n println \"Measurment "+string+" = \"+"+string;
|
||||
}
|
||||
String loader = "import eu.mihosoft.vrl.v3d.parametrics.*;\n" +
|
||||
"CSG generate(){\n" +
|
||||
" String type= \""+typeOfVitaminString+"\"\n" +
|
||||
" if(args==null)\n" +
|
||||
" args=[\""+sizeOfVitaminString+"\"]\n" +
|
||||
" // The variable that stores the current size of this vitamin\n"
|
||||
+ " StringParameter size = new StringParameter( type+\" Default\"," +
|
||||
"args.get(0)," +
|
||||
"Vitamins.listVitaminSizes(type))\n" +
|
||||
" HashMap<String,Object> measurments = Vitamins.getConfiguration( type,size.getStrValue())\n" +
|
||||
measurments+"\n"+
|
||||
" // Stub of a CAD object\n"+
|
||||
" CSG part = new Cube().toCSG()\n"+
|
||||
" return part\n" +
|
||||
" .setParameter(size)\n" +
|
||||
" .setRegenerate({generate()})\n" +
|
||||
"}\n" +
|
||||
"return generate() ";
|
||||
ScriptingEngine.pushCodeToGit(gitURL, ScriptingEngine.getFullBranch(gitURL), filename,
|
||||
loader, "new CAD loader script");
|
||||
new Thread(() -> BowlerStudio.createFileTab(Vitamins.getScriptFile(typeOfVitaminString))).start();
|
||||
}
|
||||
|
||||
Vitamins.saveDatabaseForkIfMissing(typeOfVitaminString);
|
||||
|
||||
if(newTypeRadio.isSelected()) {
|
||||
callback.addVitaminType(typeOfVitaminString);
|
||||
}else
|
||||
if(!editExisting.isSelected())
|
||||
callback.addSizesToMenu(sizeOfVitaminString, typeOfVitaminString);
|
||||
} catch (Exception e1) {
|
||||
// TODO Auto-generated catch block
|
||||
new IssueReportingExceptionHandler().uncaughtException(Thread.currentThread(), e1);
|
||||
}
|
||||
try {
|
||||
Platform.runLater(() -> {
|
||||
this.primaryStage.close();
|
||||
primaryStage=null;
|
||||
});
|
||||
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
new IssueReportingExceptionHandler().uncaughtException(Thread.currentThread(), e);
|
||||
|
||||
}
|
||||
|
||||
}).start();
|
||||
|
||||
}
|
||||
|
||||
@FXML
|
||||
void onConfirmSize(ActionEvent event) {
|
||||
if(!editExisting.isSelected()) {
|
||||
sizeOfVitaminString = newSizeField.getText();
|
||||
if(sizeOfVitaminString.length()<2) {
|
||||
Platform.runLater(() -> {
|
||||
Alert alert = new Alert(AlertType.WARNING);
|
||||
alert.setTitle("No name specified!");
|
||||
alert.setHeaderText("Names must be at least 2 charrectors long");
|
||||
alert.setContentText("Try again...");
|
||||
alert.showAndWait();
|
||||
});
|
||||
return;
|
||||
}
|
||||
String slug = BowlerStudioMenu.slugify(sizeOfVitaminString);
|
||||
if(!sizeOfVitaminString.contentEquals(slug)) {
|
||||
Platform.runLater(() -> {
|
||||
Alert alert = new Alert(AlertType.WARNING);
|
||||
alert.setTitle("Name Format Wrong");
|
||||
alert.setHeaderText("Name must be without spaces or special chars");
|
||||
alert.setContentText("Changed to "+slug+" confirm to continue...");
|
||||
alert.showAndWait();
|
||||
Platform.runLater(() -> newSizeField.setText(slug));
|
||||
});
|
||||
return;
|
||||
}
|
||||
sizeOfVitaminString=slug;
|
||||
}else {
|
||||
sizeOfVitaminString=sizeComboBox.getSelectionModel().getSelectedItem();
|
||||
}
|
||||
|
||||
Platform.runLater(() ->nameColumn.setCellValueFactory(new PropertyValueFactory<MeasurmentConfig, String>("key")));
|
||||
Platform.runLater(() ->measurmentColumn.setCellValueFactory(new PropertyValueFactory<MeasurmentConfig, String>("measurment")));
|
||||
Platform.runLater(() ->
|
||||
measurmentColumn
|
||||
.setCellFactory(
|
||||
TextFieldTableCell.forTableColumn())
|
||||
);
|
||||
|
||||
Platform.runLater(() ->measurmentsTable.getSelectionModel().cellSelectionEnabledProperty().set(true));
|
||||
measurmentsTable.setEditable(true);
|
||||
nameColumn.setEditable(false);
|
||||
measurmentColumn.setEditable(true);
|
||||
measurmentColumn.setOnEditCommit(ev -> {
|
||||
final String value = ev.getNewValue() != null ? (String) ev.getNewValue() : (String) ev.getOldValue();
|
||||
((MeasurmentConfig) ev.getTableView().getItems().get(ev.getTablePosition().getRow()))
|
||||
.setMeasurment(value);
|
||||
measurmentsTable.refresh();
|
||||
});
|
||||
|
||||
|
||||
if(existingTypeRadio.isSelected()) {
|
||||
if(!editExisting.isSelected()) {
|
||||
boolean exists = false;
|
||||
// for existing types check for existing sizes
|
||||
ArrayList<String> sizes = Vitamins.listVitaminSizes(typeOfVitaminString);
|
||||
for(String size:sizes) {
|
||||
if(size.contentEquals(sizeOfVitaminString))
|
||||
exists=true;
|
||||
}
|
||||
if(exists) {
|
||||
Platform.runLater(() -> {
|
||||
Alert alert = new Alert(AlertType.WARNING);
|
||||
alert.setTitle("Size already Exists");
|
||||
alert.setHeaderText("Name must be unique");
|
||||
alert.setContentText("Rename and confirm to continue...");
|
||||
alert.showAndWait();
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
new Thread(() -> {
|
||||
HashMap<String, Object> configsOld = Vitamins.getConfiguration(typeOfVitaminString, sizeComboBox.getSelectionModel().getSelectedItem());
|
||||
for(String key:configsOld.keySet()) {
|
||||
setupKeyValueToTable(key, configsOld.get(key),sizeOfVitaminString);
|
||||
}
|
||||
}).start();
|
||||
|
||||
}
|
||||
if(newTypeRadio.isSelected()) {
|
||||
Vitamins.getConfiguration(typeOfVitaminString, sizeOfVitaminString);
|
||||
}
|
||||
|
||||
if(Vitamins.isActuator(typeOfVitaminString) ||
|
||||
(newTypeRadio.isSelected() && isMotor.isSelected())
|
||||
) {
|
||||
new Thread(() -> {
|
||||
HashMap<String, Object> required = new HashMap<String, Object>();
|
||||
required.put("MaxTorqueNewtonmeters", 0.001);
|
||||
required.put("MaxFreeSpeedRadPerSec", 1);
|
||||
required.put("massKg", 0.001);
|
||||
required.put("shaftType", "dShaft");
|
||||
required.put("shaftSize", "5mm");
|
||||
setRequiredFields(required);
|
||||
}).start();
|
||||
}
|
||||
new Thread(() -> {
|
||||
HashMap<String, Object> required = new HashMap<String, Object>();
|
||||
required.put("massKg", 0.001);
|
||||
required.put("source", "https://commonwealthrobotics.com");
|
||||
required.put("price", 0.01);
|
||||
required.put("massCentroidX", 0.0);
|
||||
required.put("massCentroidY", 0.0);
|
||||
required.put("massCentroidZ", 0.0);
|
||||
setRequiredFields(required);
|
||||
}).start();
|
||||
sizePane.setDisable(true);
|
||||
measurmentPane.setDisable(false);
|
||||
typePane.setDisable(true);
|
||||
}
|
||||
|
||||
private void setRequiredFields(HashMap<String, Object> required) {
|
||||
// For each vitamin size in a given type
|
||||
|
||||
for(String size:Vitamins.listVitaminSizes(typeOfVitaminString)) {
|
||||
HashMap<String, Object> configs = Vitamins.getConfiguration(typeOfVitaminString, size);
|
||||
// For every required key
|
||||
for(String key:required.keySet()) {
|
||||
// check to see if the current size has this key already
|
||||
if(!configs.containsKey(key)) {
|
||||
// enter a default value, but ensure that the key exists for downstream code
|
||||
setupKeyValueToTable(key, required.get(key),size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setupKeyValueToTable(String key, Object value, String size) {
|
||||
Vitamins.getConfiguration(typeOfVitaminString, size).put(key, value);
|
||||
if (size.contentEquals(sizeOfVitaminString))
|
||||
Platform.runLater(() -> measurmentsTable.getItems()
|
||||
.add(new MeasurmentConfig(key, Vitamins.getConfiguration(typeOfVitaminString, sizeOfVitaminString))));
|
||||
}
|
||||
|
||||
@FXML
|
||||
void onConfirmType(ActionEvent event) {
|
||||
|
||||
if(newTypeRadio.isSelected()) {
|
||||
typeOfVitaminString=newTypeNameField.getText();
|
||||
if(typeOfVitaminString.length()<2) {
|
||||
Platform.runLater(() -> {
|
||||
Alert alert = new Alert(AlertType.WARNING);
|
||||
alert.setTitle("No name specified!");
|
||||
alert.setHeaderText("Names must be at least 2 charrectors long");
|
||||
alert.setContentText("Try again...");
|
||||
alert.showAndWait();
|
||||
});
|
||||
return;
|
||||
}
|
||||
String slug = BowlerStudioMenu.slugify(typeOfVitaminString);
|
||||
if(!typeOfVitaminString.contentEquals(slug)) {
|
||||
Platform.runLater(() -> {
|
||||
Alert alert = new Alert(AlertType.WARNING);
|
||||
alert.setTitle("Name Format Wrong");
|
||||
alert.setHeaderText("Name must be without spaces or special chars");
|
||||
alert.setContentText("Changed to "+slug+" confirm to continue...");
|
||||
alert.showAndWait();
|
||||
Platform.runLater(() -> newTypeNameField.setText(slug));
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
typeOfVitaminString=slug;
|
||||
sizeComboBox.setDisable(true);
|
||||
editExisting.setDisable(true);
|
||||
saveAndFork();
|
||||
}else {
|
||||
typeOfVitaminString=typeComboBox.getSelectionModel().getSelectedItem();
|
||||
saveAndFork();
|
||||
ArrayList<String> sizes = Vitamins.listVitaminSizes(typeOfVitaminString);
|
||||
boolean hasSize=false;
|
||||
|
||||
for(String size:sizes) {
|
||||
sizeComboBox.getItems().add(size);
|
||||
if(typeOfVitaminString!=null)
|
||||
if(size.contentEquals(typeOfVitaminString)) {
|
||||
hasSize=true;
|
||||
}
|
||||
}
|
||||
if(sizes.size()>0) {
|
||||
if(hasSize) {
|
||||
sizeComboBox.getSelectionModel().select(typeOfVitaminString);
|
||||
}else {
|
||||
sizeComboBox.getSelectionModel().select(sizes.get(0));
|
||||
}
|
||||
}else {
|
||||
sizeComboBox.setDisable(true);
|
||||
editExisting.setDisable(true);
|
||||
editExisting.setSelected(false);
|
||||
|
||||
}
|
||||
}
|
||||
measurmentPane.setDisable(true);
|
||||
typePane.setDisable(true);
|
||||
|
||||
}
|
||||
|
||||
private void saveAndFork() {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Vitamins.saveDatabaseForkIfMissing(typeOfVitaminString);
|
||||
sizePane.setDisable(false);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
new IssueReportingExceptionHandler().uncaughtException(Thread.currentThread(), e);
|
||||
|
||||
}
|
||||
}).start();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@FXML
|
||||
void onNewMeasurment(ActionEvent event) {
|
||||
newMeasurmentButton.setDisable(true);
|
||||
TextInputDialog dialog = new TextInputDialog("lengthOfThing");
|
||||
dialog.setTitle("Add new measurment to "+typeOfVitaminString);
|
||||
dialog.setHeaderText("This measurment will be added to all instances of the vitamin");
|
||||
dialog.setContentText("New measurment name:");
|
||||
|
||||
// Traditional way to get the response value.
|
||||
Optional<String> result = dialog.showAndWait();
|
||||
// The Java 8 way to get the response value (with lambda expression).
|
||||
result.ifPresent(name -> {
|
||||
TextInputDialog dialog2 = new TextInputDialog("0.0");
|
||||
dialog2.setTitle("Set value of "+name);
|
||||
dialog2.setHeaderText("This value will be added to all instances of the vitamin");
|
||||
dialog2.setContentText(name+" = ");
|
||||
|
||||
// Traditional way to get the response value.
|
||||
Optional<String> result2 = dialog2.showAndWait();
|
||||
result2.ifPresent(name2 -> {
|
||||
setupKeyValueToTable(name,name2,sizeOfVitaminString);
|
||||
for(String size:Vitamins.listVitaminSizes(typeOfVitaminString)) {
|
||||
Vitamins.getConfiguration(typeOfVitaminString, size).put(name,name2);
|
||||
}
|
||||
});
|
||||
newMeasurmentButton.setDisable(false);
|
||||
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
@FXML
|
||||
void onSelectExistingTypeMode(ActionEvent event) {
|
||||
newTypeNameField.setEditable(false);
|
||||
typeComboBox.setDisable(false);
|
||||
isShaft.setDisable(true);
|
||||
isMotor.setDisable(true);
|
||||
}
|
||||
|
||||
@FXML
|
||||
void onSelectNewTypeMode(ActionEvent event) {
|
||||
newTypeNameField.setEditable(true);
|
||||
typeComboBox.setDisable(true);
|
||||
isShaft.setDisable(false);
|
||||
isMotor.setDisable(false);
|
||||
}
|
||||
@FXML
|
||||
void onEditExisting(ActionEvent event) {
|
||||
if(editExisting.isSelected()) {
|
||||
newSizeField.setEditable(false);
|
||||
}else {
|
||||
|
||||
newSizeField.setEditable(true);
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
void onIsMotor(ActionEvent event) {
|
||||
if(isMotor.isSelected())
|
||||
isShaft.setSelected(false);
|
||||
}
|
||||
|
||||
@FXML
|
||||
void onIsShaft(ActionEvent event) {
|
||||
|
||||
if(isShaft.isSelected())
|
||||
isMotor.setSelected(false);
|
||||
|
||||
}
|
||||
@FXML // This method is called by the FXMLLoader when initialization is complete
|
||||
void initialize() {
|
||||
assert x1 != null : "fx:id=\"x1\" was not injected: check your FXML file 'newVitaminWizard.fxml'.";
|
||||
assert x2 != null : "fx:id=\"x2\" was not injected: check your FXML file 'newVitaminWizard.fxml'.";
|
||||
assert existingTypeRadio != null : "fx:id=\"existingTypeRadio\" was not injected: check your FXML file 'newVitaminWizard.fxml'.";
|
||||
assert newTypeRadio != null : "fx:id=\"newTypeRadio\" was not injected: check your FXML file 'newVitaminWizard.fxml'.";
|
||||
assert typeComboBox != null : "fx:id=\"typeComboBox\" was not injected: check your FXML file 'newVitaminWizard.fxml'.";
|
||||
assert sizeComboBox != null : "fx:id=\"sizeComboBox\" was not injected: check your FXML file 'newVitaminWizard.fxml'.";
|
||||
assert measurmentsTable != null : "fx:id=\"measurmentsTable\" was not injected: check your FXML file 'newVitaminWizard.fxml'.";
|
||||
|
||||
sizePane.setDisable(true);
|
||||
measurmentPane.setDisable(true);
|
||||
ToggleGroup groupForType= new ToggleGroup();
|
||||
existingTypeRadio.setSelected(true);
|
||||
newTypeRadio.setSelected(false);
|
||||
existingTypeRadio.setToggleGroup(groupForType);
|
||||
newTypeRadio.setToggleGroup(groupForType);
|
||||
newTypeNameField.setEditable(false);
|
||||
ArrayList<String> types = Vitamins.listVitaminTypes();
|
||||
for(String s:types) {
|
||||
typeComboBox.getItems().add(s);
|
||||
}
|
||||
if(typeOfVitaminString==null)
|
||||
typeComboBox.getSelectionModel().select(types.get(0));
|
||||
else
|
||||
typeComboBox.getSelectionModel().select(typeOfVitaminString);
|
||||
isShaft.setDisable(true);
|
||||
isMotor.setDisable(true);
|
||||
}
|
||||
|
||||
public static void launchWizard(INewVitaminCallback callback) throws Exception {
|
||||
NewVitaminWizardController.callback=callback;
|
||||
Platform.runLater(() -> {
|
||||
Stage s = new Stage();
|
||||
primaryStage = s;
|
||||
new Thread(() -> {
|
||||
NewVitaminWizardController controller = new NewVitaminWizardController();
|
||||
|
||||
try {
|
||||
controller.start(s);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
}
|
||||
|
||||
public static void main(String [] args) throws Exception {
|
||||
JavaFXInitializer.go();
|
||||
|
||||
NewVitaminWizardController.launchWizard(new INewVitaminCallback() {
|
||||
|
||||
@Override
|
||||
public Menu getTypeMenu(String type) {
|
||||
System.out.println("Get Vitamin Menu");
|
||||
|
||||
return new Menu(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addVitaminType(String s) {
|
||||
getTypeMenu(s);
|
||||
ArrayList<String> sizes = Vitamins.listVitaminSizes(s);
|
||||
for(String size:sizes) {
|
||||
addSizesToMenu(size,s);
|
||||
}
|
||||
System.out.println("Add addVitaminType "+s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSizesToMenu(String size, String type) {
|
||||
System.out.println("Add addSizesToMenu "+type+" "+size );
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
FXMLLoader loader = AssetFactory.loadLayout("layout/newVitaminWizard.fxml",true);
|
||||
Parent root;
|
||||
//loader.setController(this);
|
||||
// This is needed when loading on MAC
|
||||
loader.setClassLoader(getClass().getClassLoader());
|
||||
root = loader.load();
|
||||
Platform.runLater(() -> {
|
||||
primaryStage.setTitle("Edit Vitamins Wizard");
|
||||
|
||||
Scene scene = new Scene(root);
|
||||
primaryStage.setScene(scene);
|
||||
primaryStage.initModality(Modality.WINDOW_MODAL);
|
||||
primaryStage.setResizable(true);
|
||||
primaryStage.show();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* 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 com.neuronrobotics.bowlerstudio;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Michael Hoffer <info@michaelhoffer.de>
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface OutputFilter {
|
||||
public boolean onMatch(String s);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.tabs.AbstractBowlerStudioTab;
|
||||
|
||||
public interface PluginFactory {
|
||||
AbstractBowlerStudioTab generateNewPlugin() throws ClassNotFoundException, InstantiationException, IllegalAccessException ;
|
||||
}
|
||||
@@ -0,0 +1,310 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
|
||||
import com.neuronrobotics.bowlerstudio.creature.CreatureLab;
|
||||
import com.neuronrobotics.bowlerstudio.creature.DhLab;
|
||||
import com.neuronrobotics.bowlerstudio.tabs.*;
|
||||
import com.neuronrobotics.imageprovider.AbstractImageProvider;
|
||||
import com.neuronrobotics.nrconsole.plugin.BowlerCam.BowlerCamController;
|
||||
import com.neuronrobotics.nrconsole.plugin.DeviceConfig.PrinterConiguration;
|
||||
import com.neuronrobotics.nrconsole.plugin.DyIO.Secheduler.AnamationSequencer;
|
||||
import com.neuronrobotics.nrconsole.plugin.PID.PIDControl;
|
||||
import com.neuronrobotics.nrconsole.plugin.bootloader.BootloaderPanel;
|
||||
import com.neuronrobotics.pidsim.LinearPhysicsEngine;
|
||||
import com.neuronrobotics.pidsim.PidLab;
|
||||
import com.neuronrobotics.replicator.driver.NRPrinter;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.FirmataBowler;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.MobileBase;
|
||||
import com.neuronrobotics.sdk.bootloader.NRBootLoader;
|
||||
import com.neuronrobotics.sdk.bowlercam.device.BowlerCamDevice;
|
||||
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
|
||||
import com.neuronrobotics.sdk.common.Log;
|
||||
import com.neuronrobotics.sdk.common.RpcEncapsulation;
|
||||
import com.neuronrobotics.sdk.dyio.DyIO;
|
||||
import com.neuronrobotics.sdk.namespace.bcs.pid.IPidControlNamespace;
|
||||
import javafx.application.Platform;
|
||||
import javafx.event.Event;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.control.cell.CheckBoxTreeCell;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.StageStyle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
//import com.neuronrobotics.nrconsole.plugin.DyIO.DyIOConsole;
|
||||
|
||||
public class PluginManager {
|
||||
|
||||
private BowlerAbstractDevice dev;
|
||||
|
||||
private static ArrayList<DeviceSupportPluginMap> deviceSupport = new ArrayList<>();
|
||||
private ArrayList<AbstractBowlerStudioTab> liveTabs = new ArrayList<>();
|
||||
|
||||
// add tabs to the support list based on thier class
|
||||
// adding additional classes here will show up in the default
|
||||
// tabs list for objects of that type
|
||||
static{
|
||||
//DyIO
|
||||
addPlugin(new DeviceSupportPluginMap(DyIO.class, DyIOControl.class));
|
||||
addPlugin(new DeviceSupportPluginMap(DyIO.class, AnamationSequencer.class));
|
||||
|
||||
//Ipid
|
||||
addPlugin(new DeviceSupportPluginMap(IPidControlNamespace.class, PIDControl.class));
|
||||
// Image s
|
||||
// addPlugin(new DeviceSupportPluginMap(AbstractImageProvider.class, CameraTab.class));
|
||||
// addPlugin(new DeviceSupportPluginMap(AbstractImageProvider.class, SalientTab.class));
|
||||
// Bootloader
|
||||
addPlugin(new DeviceSupportPluginMap(NRBootLoader.class, BootloaderPanel.class));
|
||||
//BowlerBoard Specific
|
||||
//addPlugin(new DeviceSupportPlugginMap(BowlerBoardDevice.class, //none yet));
|
||||
//AbstractKinematicsNR
|
||||
//addPlugin(new DeviceSupportPluginMap(AbstractKinematicsNR.class, JogKinematicsDevice.class));
|
||||
//addPlugin(new DeviceSupportPluginMap(AbstractKinematicsNR.class, AdvancedKinematicsController.class));
|
||||
//addPlugin(new DeviceSupportPluginMap(AbstractKinematicsNR.class, DhLab.class));
|
||||
addPlugin(new DeviceSupportPluginMap(MobileBase.class, CreatureLab.class));
|
||||
//NRPrinter
|
||||
addPlugin(new DeviceSupportPluginMap(NRPrinter.class, PrinterConiguration.class));
|
||||
//Bowler Cam
|
||||
addPlugin(new DeviceSupportPluginMap(BowlerCamDevice.class, BowlerCamController.class));
|
||||
//LinearPhysicsEngine
|
||||
addPlugin(new DeviceSupportPluginMap(LinearPhysicsEngine.class, PidLab.class));
|
||||
//Firmata
|
||||
addPlugin(new DeviceSupportPluginMap(FirmataBowler.class, FirmataTab.class));
|
||||
}
|
||||
|
||||
public PluginManager(BowlerAbstractDevice dev){
|
||||
this.dev = dev;
|
||||
if(!dev.isAvailable())
|
||||
throw new RuntimeException("Device is not reporting availible "+dev.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public static void addPlugin(DeviceSupportPluginMap newMap){
|
||||
|
||||
for(int i=0;i<deviceSupport.size();i++){
|
||||
try{
|
||||
if( deviceSupport.get(i).getDevice() == newMap.getDevice() &&
|
||||
deviceSupport.get(i).getPlugin() == newMap.getPlugin() ){
|
||||
System.out.println("Removing duplicate plugin: "+deviceSupport.remove(i));
|
||||
}
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Log.debug("Adding Plugin "+newMap);
|
||||
deviceSupport.add(newMap);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setName(String name) {
|
||||
dev.setScriptingName(name);
|
||||
}
|
||||
|
||||
public String getName(){
|
||||
return dev.getScriptingName();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public BowlerAbstractDevice getDevice() {
|
||||
return dev;
|
||||
}
|
||||
|
||||
private AbstractBowlerStudioTab generateTab(DeviceSupportPluginMap c) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
|
||||
for(AbstractBowlerStudioTab t: liveTabs){
|
||||
if(c.getPlugin().isInstance(t)){
|
||||
// tab already exists, wake it up and return it
|
||||
t.onTabReOpening();
|
||||
return t;
|
||||
}
|
||||
}
|
||||
AbstractBowlerStudioTab t=c.generateNewPlugin();
|
||||
|
||||
t.setDevice(dev);
|
||||
liveTabs.add(t);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
public void setTree(TreeItem<String> item) {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public BowlerStudioController getBowlerStudioController() {
|
||||
return BowlerStudioController.getBowlerStudio();
|
||||
}
|
||||
|
||||
public Node getBowlerBrowser(){
|
||||
|
||||
CheckBoxTreeItem<String> rpc = new CheckBoxTreeItem<> ("Bowler RPC");
|
||||
TreeView<String> treeView =new TreeView<>(rpc);
|
||||
treeView.setCellFactory(CheckBoxTreeCell.forTreeView());
|
||||
|
||||
if(dev.getConnection()!=null){
|
||||
rpc.setExpanded(true);
|
||||
ArrayList<String> nameSpaceList = dev.getNamespaces();
|
||||
for(String namespace:nameSpaceList){
|
||||
CheckBoxTreeItem<String> ns = new CheckBoxTreeItem<> (namespace);
|
||||
ns.setExpanded(false);
|
||||
rpc.getChildren().add(ns);
|
||||
ArrayList<RpcEncapsulation> rpcList = dev.getRpcList(namespace);
|
||||
CheckBoxTreeItem<String> get = new CheckBoxTreeItem<> ("GET");
|
||||
CheckBoxTreeItem<String> post = new CheckBoxTreeItem<> ("POST");
|
||||
CheckBoxTreeItem<String> async = new CheckBoxTreeItem<> ("ASYNC");
|
||||
CheckBoxTreeItem<String> crit = new CheckBoxTreeItem<> ("CRITICAL");
|
||||
get.setExpanded(false);
|
||||
ns.getChildren().add(get);
|
||||
post.setExpanded(false);
|
||||
ns.getChildren().add(post);
|
||||
async.setExpanded(false);
|
||||
ns.getChildren().add(async);
|
||||
crit.setExpanded(false);
|
||||
ns.getChildren().add(crit);
|
||||
for(RpcEncapsulation rpcEnc:rpcList){
|
||||
CheckBoxTreeItem<String> rc = new CheckBoxTreeItem<> (rpcEnc.getRpc());
|
||||
rc.setExpanded(false);
|
||||
switch(rpcEnc.getDownstreamMethod()){
|
||||
case ASYNCHRONOUS:
|
||||
async.getChildren().add(rc);
|
||||
break;
|
||||
case CRITICAL:
|
||||
crit.getChildren().add(rc);
|
||||
break;
|
||||
case GET:
|
||||
get.getChildren().add(rc);
|
||||
break;
|
||||
case POST:
|
||||
post.getChildren().add(rc);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
RpcCommandPanel panel =new RpcCommandPanel(rpcEnc, dev,rc);
|
||||
|
||||
// Platform.runLater(()->{
|
||||
// SwingNode sn = new SwingNode();
|
||||
// Stage dialog = new Stage();
|
||||
// dialog.setHeight(panel.getHeight());
|
||||
// dialog.setWidth(panel.getWidth());
|
||||
// dialog.initStyle(StageStyle.UTILITY);
|
||||
// sn.setContent(panel);
|
||||
// Scene scene = new Scene(new Group(sn));
|
||||
// dialog.setScene(scene);
|
||||
// dialog.setOnCloseRequest(event -> {
|
||||
// rc.setSelected(false);
|
||||
// });
|
||||
// rc.selectedProperty().addListener(b ->{
|
||||
// if(rc.isSelected()){
|
||||
// dialog.show();
|
||||
// }else{
|
||||
// dialog.hide();
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return treeView;
|
||||
|
||||
}
|
||||
|
||||
public ArrayList<TitledPane> getPlugins() {
|
||||
ArrayList<TitledPane> plugins = new ArrayList<>();
|
||||
|
||||
VBox pluginLauncher = new VBox(20);
|
||||
|
||||
for( DeviceSupportPluginMap c:deviceSupport){
|
||||
if(c.getDevice().isInstance(dev)){
|
||||
Button launcher = new Button("Launch "+c.getPlugin().getSimpleName(), AssetFactory.loadIcon("Plugin-Icon.png"));
|
||||
try {// These tabs are the select few to autoload when a device of theis type is connected
|
||||
if( DyIOControl.class ==c.getPlugin() ||
|
||||
BootloaderPanel.class ==c.getPlugin()||
|
||||
CreatureLab.class ==c.getPlugin()
|
||||
){
|
||||
if(getBowlerStudioController()!=null){
|
||||
System.out.println("Auto loading "+c.getPlugin().getSimpleName());
|
||||
Log.warning("Attempting Autoloading "+c);
|
||||
//if(CreatureLab.class !=c.getPlugin())
|
||||
launchTab( c,launcher);
|
||||
//else
|
||||
// generateTab(c);// dont add the creature lab it uses the overlays
|
||||
}
|
||||
}else{
|
||||
Log.warning("Not autoloading "+c);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
|
||||
}
|
||||
launcher.setOnAction(b ->{
|
||||
launchTab( c,launcher);
|
||||
});
|
||||
|
||||
pluginLauncher.getChildren().add(launcher);
|
||||
}
|
||||
}
|
||||
TitledPane info = new TitledPane("Device Info", new Text(dev.getClass().getSimpleName()));
|
||||
TitledPane protocol = new TitledPane("Bowler Protocol", getBowlerBrowser());
|
||||
TitledPane pluginsPane = new TitledPane("Plugins", pluginLauncher);
|
||||
info.setGraphic(AssetFactory.loadIcon("Info.png"));
|
||||
protocol.setGraphic(AssetFactory.loadIcon("BowlerStudio.png"));
|
||||
pluginsPane.setGraphic(AssetFactory.loadIcon("Plugins.png"));
|
||||
plugins.add(info);
|
||||
if(dev.getConnection()!=null)
|
||||
plugins.add(protocol);
|
||||
plugins.add(pluginsPane);
|
||||
return plugins;
|
||||
}
|
||||
|
||||
private void launchTab(DeviceSupportPluginMap c,Button launcher){
|
||||
new Thread(){
|
||||
public void run(){
|
||||
Thread.currentThread().setUncaughtExceptionHandler(new IssueReportingExceptionHandler());
|
||||
|
||||
setName("Launching "+c.getPlugin().getSimpleName());
|
||||
try {
|
||||
AbstractBowlerStudioTab t = generateTab(c);
|
||||
|
||||
// allow the threads to finish before adding
|
||||
//ThreadUtil.wait(50);
|
||||
getBowlerStudioController().addTab(t, true);
|
||||
|
||||
t.setOnCloseRequest(new EventHandler<Event>() {
|
||||
@Override
|
||||
public void handle(Event arg0) {
|
||||
System.out.println("PM is Closing "+t.getText());
|
||||
t.onTabClosing();
|
||||
Platform.runLater(()->launcher.setDisable(false));
|
||||
|
||||
}
|
||||
});
|
||||
Platform.runLater(()->{
|
||||
launcher.setDisable(true);
|
||||
});
|
||||
System.out.println("Launching "+c.getPlugin().getSimpleName());
|
||||
|
||||
} catch (Exception e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
|
||||
import com.neuronrobotics.sdk.common.Log;
|
||||
import javafx.application.Platform;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Accordion;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.TitledPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class PluginManagerWidget extends TitledPane {
|
||||
private PluginManager manager;
|
||||
private TextField deviceName = new TextField();
|
||||
private Button disconnectTHis;
|
||||
final Accordion accordion = new Accordion ();
|
||||
|
||||
public PluginManagerWidget(PluginManager m, Node graphic){
|
||||
HBox content = new HBox(20);
|
||||
|
||||
content.setPadding(new Insets(0, 20, 10, 20));
|
||||
this.manager = m;
|
||||
ArrayList<TitledPane> plugins = manager.getPlugins();
|
||||
accordion.getPanes().addAll(plugins);
|
||||
disconnectTHis = new Button("Disconnect "+manager.getName(), AssetFactory.loadIcon("Disconnect-Device.png"));
|
||||
|
||||
disconnectTHis.setOnMousePressed( event -> {
|
||||
new Thread(){
|
||||
public void run(){
|
||||
Thread.currentThread().setUncaughtExceptionHandler(new IssueReportingExceptionHandler());
|
||||
|
||||
setName("disconnect plugins");
|
||||
Log.warning("Disconnect button for "+manager.getName()+" pressed");
|
||||
getManager().getDevice().disconnect();
|
||||
|
||||
}
|
||||
}.start();
|
||||
|
||||
});
|
||||
setGraphic(AssetFactory.loadIcon("Bowler-Device-In-Manager.png"));
|
||||
deviceName.setOnAction(event -> {
|
||||
getManager().setName(deviceName.getText());
|
||||
setText(manager.getName());
|
||||
disconnectTHis.setText("Disconnect "+manager.getName());
|
||||
});
|
||||
Platform.runLater(()->deviceName.setText(manager.getName()));
|
||||
content.setHgrow(accordion, Priority.ALWAYS);
|
||||
content.getChildren().addAll(graphic,disconnectTHis,deviceName,accordion);
|
||||
setContent(content);
|
||||
setText(manager.getName());
|
||||
}
|
||||
|
||||
public PluginManager getManager() {
|
||||
return manager;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
|
||||
import javafx.scene.image.Image;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UnsupportedLookAndFeelException;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.assets.StudioBuildInfo;
|
||||
|
||||
public class PsudoSplash {
|
||||
JFrame interfaceFrame;
|
||||
private String message = "";
|
||||
|
||||
class CustomPanel extends JPanel {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 8749662598444052868L;
|
||||
private BufferedImage image;
|
||||
|
||||
public CustomPanel() {
|
||||
setOpaque(false);
|
||||
try {
|
||||
/*
|
||||
* Since Images are Application Resources, it's always best to access them in
|
||||
* the form of a URL, instead of File, as you are doing. Uncomment this below
|
||||
* line and watch this answer of mine, as to HOW TO ADD IMAGES TO THE PROJECT
|
||||
* https://stackoverflow.com/a/9866659/1057230 In order to access images with
|
||||
* getClass().getResource(path) here your Directory structure has to be like
|
||||
* this Project | ------------------------ | | bin src | | --------- .java files
|
||||
* | | package image(folder) ( or | .class 404error.jpg files, if no package
|
||||
* exists.)
|
||||
*/
|
||||
image = ImageIO.read(getClass().getResource("splash.png"));
|
||||
|
||||
} catch (IOException ioe) {
|
||||
System.out.println("Unable to fetch image.");
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Make this one customary habbit, of overriding this method, when you extends a
|
||||
* JPanel/JComponent, to define it's Preferred Size. Now in this case we want it
|
||||
* to be as big as the Image itself.
|
||||
*/
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return (new Dimension(image.getWidth(), image.getHeight()));
|
||||
}
|
||||
|
||||
/*
|
||||
* This is where the actual Painting Code for the JPanel/JComponent goes. Here
|
||||
* we will draw the image. Here the first line super.paintComponent(...), means
|
||||
* we want the JPanel to be drawn the usual Java way first, then later on we
|
||||
* will add our image to it, by writing the other line, g.drawImage(...).
|
||||
*/
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
|
||||
super.paintComponent(g);
|
||||
g.drawImage(image, 0, 0, this);
|
||||
Graphics2D splashGraphics = (Graphics2D) g;
|
||||
splashGraphics.setComposite(AlphaComposite.Clear);
|
||||
// splashGraphics.fillRect(65, 270, 200, 40);
|
||||
splashGraphics.setPaintMode();
|
||||
splashGraphics.setColor(Color.WHITE);
|
||||
splashGraphics.drawString(StudioBuildInfo.getVersion(), 65, 45);
|
||||
|
||||
splashGraphics.setComposite(AlphaComposite.Clear);
|
||||
// splashGraphics.fillRect(65, 270, 200, 40);
|
||||
splashGraphics.setPaintMode();
|
||||
splashGraphics.setColor(Color.WHITE);
|
||||
splashGraphics.drawString(getMessage(), 65, 280);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public PsudoSplash() {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
} catch (ClassNotFoundException ex) {
|
||||
} catch (InstantiationException ex) {
|
||||
} catch (IllegalAccessException ex) {
|
||||
} catch (UnsupportedLookAndFeelException ex) {
|
||||
}
|
||||
|
||||
interfaceFrame = new JFrame("Loading BowlerStudio...");
|
||||
interfaceFrame.setUndecorated(true);
|
||||
interfaceFrame.setLayout(new BorderLayout());
|
||||
CustomPanel contentPane = new CustomPanel();
|
||||
// interfaceFrame.setBackground(Color.black);
|
||||
interfaceFrame.setContentPane(contentPane);
|
||||
interfaceFrame.pack();
|
||||
interfaceFrame.setLocationRelativeTo(null);
|
||||
interfaceFrame.setVisible(true);
|
||||
interfaceFrame.setBackground(new Color(0, 0, 0, 0));
|
||||
try {
|
||||
interfaceFrame.setIconImage( ImageIO.read(getClass().getResource("splash.png")));
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
while (interfaceFrame == null)
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
// public void setIcon(Image img) {
|
||||
// BufferedImage image = javafx.embed.swing.SwingFXUtils.fromFXImage(img, null);
|
||||
// if (interfaceFrame != null)
|
||||
// interfaceFrame.setIconImage(image);
|
||||
// }
|
||||
boolean isVisableSplash() {
|
||||
if (interfaceFrame != null)
|
||||
return interfaceFrame.isVisible();
|
||||
return false;
|
||||
}
|
||||
|
||||
void closeSplashLocal() {
|
||||
if (interfaceFrame != null)
|
||||
interfaceFrame.setVisible(false);
|
||||
}
|
||||
|
||||
void updateSplash() {
|
||||
if (interfaceFrame != null) {
|
||||
interfaceFrame.invalidate();
|
||||
interfaceFrame.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
if (message.length() > 23) {
|
||||
this.message = message.subSequence(0, 23).toString();
|
||||
//new RuntimeException().printStackTrace();
|
||||
} else
|
||||
this.message = message;
|
||||
if (interfaceFrame != null) {
|
||||
interfaceFrame.setVisible(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
|
||||
/*
|
||||
* RedirectableStream.java
|
||||
*
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
||||
*
|
||||
* Copyright (c) 2009–2012 Steinbeis Forschungszentrum (STZ Ölbronn),
|
||||
* Copyright (c) 2006–2012 by Michael Hoffer
|
||||
*
|
||||
* This file is part of Visual Reflection Library (VRL).
|
||||
*
|
||||
* VRL is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License version 3
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* see: http://opensource.org/licenses/LGPL-3.0
|
||||
* file://path/to/VRL/src/eu/mihosoft/vrl/resources/license/lgplv3.txt
|
||||
*
|
||||
* VRL 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 Lesser General Public License for more details.
|
||||
*
|
||||
* This version of VRL includes copyright notice and attribution requirements.
|
||||
* According to the LGPL this information must be displayed even if you modify
|
||||
* the source code of VRL. Neither the VRL Canvas attribution icon nor any
|
||||
* copyright statement/attribution may be removed.
|
||||
*
|
||||
* Attribution Requirements:
|
||||
*
|
||||
* If you create derived work you must do three things regarding copyright
|
||||
* notice and author attribution.
|
||||
*
|
||||
* First, the following text must be displayed on the Canvas:
|
||||
* "based on VRL source code". In this case the VRL canvas icon must be removed.
|
||||
*
|
||||
* Second, the copyright notice must remain. It must be reproduced in any
|
||||
* program that uses VRL.
|
||||
*
|
||||
* Third, add an additional notice, stating that you modified VRL. In addition
|
||||
* you must cite the publications listed below. A suitable notice might read
|
||||
* "VRL source code modified by YourName 2012".
|
||||
*
|
||||
* Note, that these requirements are in full accordance with the LGPL v3
|
||||
* (see 7. Additional Terms, b).
|
||||
*
|
||||
* Publications:
|
||||
*
|
||||
* M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library -
|
||||
* A Framework for Declarative GUI Programming on the Java Platform.
|
||||
* Computing and Visualization in Science, 2011, in press.
|
||||
*/
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.TextArea;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Michael Hoffer info@michaelhoffer.de
|
||||
*/
|
||||
public class RedirectableStream extends PrintStream {
|
||||
|
||||
public static PrintStream ORIGINAL_SOUT = System.out;
|
||||
public static PrintStream ORIGINAL_SERR = System.err;
|
||||
|
||||
private final List<TextArea> views = new ArrayList<>();
|
||||
private boolean redirectToUi;
|
||||
private boolean redirectToStdOut;
|
||||
private final List<OutputFilter> filters = new ArrayList<>();
|
||||
|
||||
public RedirectableStream(OutputStream out, TextArea... views) {
|
||||
super(out);
|
||||
this.views.clear();
|
||||
|
||||
for (TextArea textArea : views) {
|
||||
addView(textArea);
|
||||
}
|
||||
|
||||
setRedirectToStdOut(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void write(byte[] buf, int off, int len) {
|
||||
if (isRedirectToUi()) {
|
||||
|
||||
invokeAndWait(() -> {
|
||||
|
||||
int i = 0;
|
||||
for (TextArea view : views) {
|
||||
|
||||
String s = new String(buf, off, len);
|
||||
|
||||
if (filters.get(i).onMatch(s)) {
|
||||
try {
|
||||
int startOffSet = view.getText().length();
|
||||
view.insertText(startOffSet, s);
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
});
|
||||
|
||||
// view.setCaretPosition(startOffSet + len);
|
||||
// }
|
||||
// catch (BadLocationException e) {
|
||||
// e.printStackTrace();
|
||||
// Platform.invokeLater(new Runnable() {
|
||||
//
|
||||
// @Override
|
||||
// public void run() {
|
||||
// // automatically scroll down to the last line
|
||||
//// view.scrollRectToVisible(
|
||||
//// new Rectangle(0, view.getHeight() - 1, 1, 1));
|
||||
//
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
if (isRedirectToStdOut()) {
|
||||
super.write(buf, off, len);
|
||||
}
|
||||
}
|
||||
|
||||
public final void addView(TextArea view) {
|
||||
views.add(view);
|
||||
filters.add((OutputFilter) (String s) -> {
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
public void setFilter(TextArea view, OutputFilter filter) {
|
||||
int i = views.indexOf(view);
|
||||
filters.set(i, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the redirectToUi
|
||||
*/
|
||||
public boolean isRedirectToUi() {
|
||||
return redirectToUi;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param redirectToUi the redirectToUi to set
|
||||
*/
|
||||
public void setRedirectToUi(boolean redirectToUi) {
|
||||
this.redirectToUi = redirectToUi;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the redirectToStdOut
|
||||
*/
|
||||
public boolean isRedirectToStdOut() {
|
||||
return redirectToStdOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param redirectToStdOut the redirectToStdOut to set
|
||||
*/
|
||||
public final void setRedirectToStdOut(boolean redirectToStdOut) {
|
||||
this.redirectToStdOut = redirectToStdOut;
|
||||
}
|
||||
|
||||
private static void invokeAndWait(Runnable r) {
|
||||
if (Platform.isFxApplicationThread()) {
|
||||
r.run();
|
||||
} else {
|
||||
FutureTask<Boolean> task = new FutureTask<>(r, true);
|
||||
|
||||
Platform.runLater(task);
|
||||
|
||||
try {
|
||||
task.get(); // like join()
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
Logger.getLogger(RedirectableStream.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javafx.scene.control.CheckBoxTreeItem;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
|
||||
import com.neuronrobotics.sdk.common.BowlerDataType;
|
||||
import com.neuronrobotics.sdk.common.BowlerDatagram;
|
||||
import com.neuronrobotics.sdk.common.RpcEncapsulation;
|
||||
import com.neuronrobotics.sdk.genericdevice.GenericDevice;
|
||||
|
||||
|
||||
public class RpcCommandPanel extends JPanel implements ActionListener {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -9199252749669892888L;
|
||||
private BowlerAbstractDevice device;
|
||||
private RpcEncapsulation rpc;
|
||||
private CheckBoxTreeItem<?> rpcDhild;
|
||||
private boolean commandsEnabled=false;
|
||||
private ArrayList<JTextField> tx = new ArrayList<>();
|
||||
private ArrayList<JLabel> rx = new ArrayList<>();
|
||||
private JButton send = new JButton("Send");
|
||||
private JLabel txRpc = new JLabel("****");
|
||||
private JLabel rxRpc = new JLabel("****");
|
||||
|
||||
public RpcCommandPanel(RpcEncapsulation rpc,BowlerAbstractDevice device, CheckBoxTreeItem<?> rpcDhild){
|
||||
this.setRpcDhild(rpcDhild);
|
||||
this.setRpc(rpc);
|
||||
this.setDevice(device);
|
||||
setLayout(new MigLayout());
|
||||
add(new JLabel("Namespace"), "cell 0 0,alignx leading");
|
||||
add(new JLabel(rpc.getNamespace().split(";")[0]), "cell 1 0,alignx leading");
|
||||
|
||||
add(new JLabel("Method"), "cell 0 1,alignx leading");
|
||||
add(new JLabel(rpc.getDownstreamMethod().toString()), "cell 1 1,alignx leading");
|
||||
|
||||
add(new JLabel("RPC"), "cell 0 2,alignx leading");
|
||||
add(new JLabel(rpc.getRpc()), "cell 1 2,alignx leading");
|
||||
|
||||
add(new JLabel("Tx>>"), "cell 0 3,alignx leading");
|
||||
txRpc.setText(rpc.getRpc());
|
||||
add(txRpc, "cell 0 3,alignx leading");
|
||||
add(new JLabel("Rx<<"), "cell 0 4,alignx leading");
|
||||
add(rxRpc, "cell 0 4,alignx leading");
|
||||
add(send,"cell 2 3,alignx leading");
|
||||
|
||||
JPanel txPanel = new JPanel(new MigLayout());
|
||||
JPanel rxPanel = new JPanel(new MigLayout());
|
||||
|
||||
int i=0;
|
||||
for (BowlerDataType s:rpc.getDownstreamArguments()){
|
||||
JTextField tmp= new JTextField(5);
|
||||
tmp.setText("0");
|
||||
txPanel.add(new JLabel(s.toString()), "cell "+i+" 0,alignx leading");
|
||||
tx.add(tmp);
|
||||
i++;
|
||||
}
|
||||
i=0;
|
||||
for (BowlerDataType s:rpc.getUpstreamArguments()){
|
||||
JLabel tmp= new JLabel();
|
||||
tmp.setText("0");
|
||||
rxPanel.add(new JLabel(s.toString()), "cell "+i+" 0,alignx leading");
|
||||
rx.add(tmp);
|
||||
i++;
|
||||
}
|
||||
i=0;
|
||||
for(JTextField t:tx){
|
||||
txPanel.add(t, "cell "+i+" 1,alignx leading");
|
||||
i++;
|
||||
}
|
||||
i=0;
|
||||
for(JLabel t:rx){
|
||||
rxPanel.add(t, "cell "+i+" 1,alignx leading");
|
||||
i++;
|
||||
}
|
||||
|
||||
add(txPanel, "cell 1 3,alignx leading");
|
||||
add(rxPanel, "cell 1 4,alignx leading");
|
||||
|
||||
send.addActionListener(this);
|
||||
}
|
||||
|
||||
public RpcEncapsulation getRpc() {
|
||||
return rpc;
|
||||
}
|
||||
|
||||
private void setRpc(RpcEncapsulation rpc) {
|
||||
this.rpc = rpc;
|
||||
}
|
||||
|
||||
public BowlerAbstractDevice getDevice() {
|
||||
return device;
|
||||
}
|
||||
|
||||
private void setDevice(BowlerAbstractDevice device) {
|
||||
this.device = device;
|
||||
}
|
||||
|
||||
public CheckBoxTreeItem<?> getRpcDhild() {
|
||||
return rpcDhild;
|
||||
}
|
||||
|
||||
public void setRpcDhild(CheckBoxTreeItem<?> rpcDhild) {
|
||||
this.rpcDhild = rpcDhild;
|
||||
}
|
||||
|
||||
public void enableCommands() {
|
||||
if(commandsEnabled)
|
||||
return;
|
||||
|
||||
commandsEnabled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
Object[] values = new Object[tx.size()];
|
||||
for (int i=0;i<values.length;i++){
|
||||
if(rpc.getDownstreamArguments()[i] == BowlerDataType.ASCII)
|
||||
values[i] = tx.get(i).getText();
|
||||
else
|
||||
values[i] = Integer.parseInt(tx.get(i).getText());
|
||||
}
|
||||
BowlerDatagram bd =device.send(rpc.getCommand(values));
|
||||
rxRpc.setText(bd.getRPC());
|
||||
Object [] up = rpc.parseResponse(bd);
|
||||
for(int i=0;i<up.length;i++){
|
||||
if(up[i]!=null)
|
||||
rx.get(i).setText(up[i].toString());
|
||||
else{
|
||||
rx.get(i).setText("Null");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.assets.StudioBuildInfo;
|
||||
|
||||
import javafx.scene.image.Image;
|
||||
|
||||
public class SplashManager {
|
||||
private static Graphics2D splashGraphics;
|
||||
|
||||
private static boolean loadFirst = true;
|
||||
private static PsudoSplash psudo = null;
|
||||
|
||||
public static void closeSplash() {
|
||||
if(isVisableSplash())
|
||||
closeSplashLocal();
|
||||
|
||||
}
|
||||
|
||||
private static void closeSplashLocal() {
|
||||
if (BowlerStudio.splash != null) {
|
||||
BowlerStudio.splash.close();
|
||||
splashGraphics = null;
|
||||
return;
|
||||
}
|
||||
psudo.closeSplashLocal();
|
||||
}
|
||||
|
||||
private static boolean isVisableSplash() {
|
||||
if (BowlerStudio.splash != null)
|
||||
return BowlerStudio.splash.isVisible();
|
||||
return psudo.isVisableSplash();
|
||||
}
|
||||
|
||||
private static void updateSplash() {
|
||||
if (BowlerStudio.splash != null) {
|
||||
BowlerStudio.splash.update();
|
||||
return;
|
||||
}
|
||||
psudo.updateSplash();
|
||||
}
|
||||
|
||||
public static void renderSplashFrame(int frame, String message) {
|
||||
if (loadFirst) {
|
||||
loadFirst = false;
|
||||
initialize();
|
||||
}
|
||||
String string = frame + "% " + message;
|
||||
System.err.println(" Splash Rendering " + frame + " " + message);
|
||||
if (psudo != null) {
|
||||
psudo.setMessage(string);
|
||||
updateSplash();
|
||||
}else if (splashGraphics != null && isVisableSplash()) {
|
||||
splashGraphics.setComposite(AlphaComposite.Clear);
|
||||
splashGraphics.fillRect(65, 270, 200, 40);
|
||||
splashGraphics.setPaintMode();
|
||||
splashGraphics.setColor(Color.WHITE);
|
||||
|
||||
splashGraphics.drawString(string, 65, 280);
|
||||
// Platform.runLater(() -> {
|
||||
updateSplash();
|
||||
// });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void initialize() {
|
||||
if (BowlerStudio.splash != null) {
|
||||
try {
|
||||
splashGraphics = BowlerStudio.splash.createGraphics();
|
||||
} catch (IllegalStateException e) {
|
||||
}
|
||||
} else {
|
||||
System.err.println("No splash screen availible!");
|
||||
psudo = new PsudoSplash();
|
||||
}
|
||||
if (psudo == null)
|
||||
if (splashGraphics != null && isVisableSplash()) {
|
||||
splashGraphics.setComposite(AlphaComposite.Clear);
|
||||
splashGraphics.fillRect(65, 270, 200, 40);
|
||||
splashGraphics.setPaintMode();
|
||||
splashGraphics.setColor(Color.WHITE);
|
||||
splashGraphics.drawString(StudioBuildInfo.getVersion(), 65, 45);
|
||||
updateSplash();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
/**
|
||||
* Sample Skeleton for "Terminal.fxml" Controller Class
|
||||
* You can copy and paste this code into your favorite IDE
|
||||
**/
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
|
||||
//import com.neuronrobotics.imageprovider.OpenCVImageProvider;
|
||||
import com.neuronrobotics.sdk.common.Log;
|
||||
import com.neuronrobotics.sdk.util.ThreadUtil;
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Alert.AlertType;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class Terminal {
|
||||
|
||||
@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="executionBox"
|
||||
private TextField executionBox; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="langaugeIcon"
|
||||
private ImageView langaugeIcon; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="langauges"
|
||||
private ComboBox<String> langauges; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="outputBox"
|
||||
private TextArea outputBox; // Value injected by FXMLLoader
|
||||
|
||||
private ArrayList<String> history = new ArrayList<>();
|
||||
|
||||
private int historyIndex = 0;
|
||||
private boolean running = false;
|
||||
private Thread scriptRunner = null;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
@FXML // This method is called by the FXMLLoader when initialization is
|
||||
// complete
|
||||
void initialize() {
|
||||
assert executionBox != null : "fx:id=\"executionBox\" was not injected: check your FXML file 'Terminal.fxml'.";
|
||||
assert langaugeIcon != null : "fx:id=\"langaugeIcon\" was not injected: check your FXML file 'Terminal.fxml'.";
|
||||
assert langauges != null : "fx:id=\"langauges\" was not injected: check your FXML file 'Terminal.fxml'.";
|
||||
assert outputBox != null : "fx:id=\"outputBox\" was not injected: check your FXML file 'Terminal.fxml'.";
|
||||
BowlerStudio.setLogViewRefStatic(outputBox);
|
||||
// Initialize your logic here: all @FXML variables will have been
|
||||
// injected
|
||||
langauges.getItems().clear();
|
||||
executionBox.setOnAction(event -> {
|
||||
new Thread() {
|
||||
public void run() {
|
||||
Thread.currentThread().setUncaughtExceptionHandler(new IssueReportingExceptionHandler());
|
||||
|
||||
startStopAction();
|
||||
}
|
||||
}.start();
|
||||
|
||||
});
|
||||
executionBox.setPrefWidth(80 * 4);
|
||||
executionBox.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
|
||||
// Platform.runLater(() -> {
|
||||
if ((event.getCode() == KeyCode.UP || event.getCode() == KeyCode.DOWN)) {
|
||||
System.err.println("Key pressed " + event.getCode() + " history index = " + historyIndex
|
||||
+ " history size= " + history.size());
|
||||
if (historyIndex == 0) {
|
||||
String text = executionBox.getText();
|
||||
if (text.length() > 0) {
|
||||
// store what was in the box into he history
|
||||
history.add(text);
|
||||
}
|
||||
}
|
||||
|
||||
if (event.getCode() == KeyCode.UP)
|
||||
historyIndex++;
|
||||
else
|
||||
historyIndex--;
|
||||
if (!history.isEmpty()) {
|
||||
if (historyIndex > history.size()) {
|
||||
historyIndex = history.size();
|
||||
}
|
||||
if (historyIndex < 0)
|
||||
historyIndex = 0;
|
||||
// History index established
|
||||
if (historyIndex > 0)
|
||||
Platform.runLater(() -> {
|
||||
executionBox.setText(history.get(history.size() - historyIndex));
|
||||
});
|
||||
else
|
||||
Platform.runLater(() -> {
|
||||
executionBox.setText("");
|
||||
});
|
||||
}
|
||||
event.consume();
|
||||
}
|
||||
// });
|
||||
});
|
||||
try {
|
||||
history = BowlerKernel.loadHistory();
|
||||
} catch (IOException e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
}
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
BowlerKernel.writeHistory(history);
|
||||
}
|
||||
});
|
||||
List<String> langs = ScriptingEngine.getAllLangauges();
|
||||
ObservableList<String> options = FXCollections.observableArrayList(langs);
|
||||
//
|
||||
for(String s:options){
|
||||
langauges.getItems().add(s);
|
||||
}
|
||||
langauges.getSelectionModel().select("Groovy");
|
||||
Image icon;
|
||||
try {
|
||||
icon = AssetFactory.loadAsset("Script-Tab-" + langauges.getSelectionModel().getSelectedItem() + ".png");
|
||||
langaugeIcon.setImage(icon);
|
||||
} catch (Exception e2) {
|
||||
// TODO Auto-generated catch block
|
||||
e2.printStackTrace();
|
||||
}
|
||||
|
||||
langauges.setOnAction(event -> {
|
||||
try {
|
||||
|
||||
langaugeIcon.setImage(AssetFactory
|
||||
.loadAsset("Script-Tab-" + langauges.getSelectionModel().getSelectedItem() + ".png"));
|
||||
} catch (Exception e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
running = false;
|
||||
|
||||
}
|
||||
|
||||
private void start(String code) {
|
||||
|
||||
running = true;
|
||||
|
||||
scriptRunner = new Thread() {
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public void run() {
|
||||
|
||||
try {
|
||||
ScriptingEngine.inlineScriptStringRun(code, null,
|
||||
langauges.getSelectionModel().getSelectedItem());
|
||||
reset();
|
||||
} catch (groovy.lang.MissingPropertyException | org.python.core.PyException d) {
|
||||
Platform.runLater(() -> {
|
||||
Alert alert = new Alert(AlertType.ERROR);
|
||||
alert.setTitle("Device missing error");
|
||||
String message = "This script needs a device connected: ";
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
d.printStackTrace(pw);
|
||||
BowlerStudioController.highlightException(null, d);
|
||||
|
||||
String stackTrace = sw.toString();
|
||||
|
||||
if (stackTrace.contains("dyio"))
|
||||
message += "dyio";
|
||||
else if (stackTrace.contains("camera"))
|
||||
message += "camera";
|
||||
else if (stackTrace.contains("gamepad"))
|
||||
message += "gamepad";
|
||||
else
|
||||
message += stackTrace;
|
||||
alert.setHeaderText(message);
|
||||
alert.setContentText("You need to connect it before running again");
|
||||
alert.showAndWait();
|
||||
if (stackTrace.contains("dyio"))
|
||||
ConnectionManager.addConnection();
|
||||
// else if (stackTrace.contains("camera"))
|
||||
// ConnectionManager.addConnection(new OpenCVImageProvider(0), "camera0");
|
||||
else if (stackTrace.contains("gamepad"))
|
||||
ConnectionManager.onConnectGamePad("gamepad");
|
||||
reset();
|
||||
});
|
||||
|
||||
} catch (Exception ex) {
|
||||
System.err.println("Script exception of type= " + ex.getClass().getName());
|
||||
Platform.runLater(() -> {
|
||||
reset();
|
||||
});
|
||||
|
||||
BowlerStudioController.highlightException(null, ex);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
scriptRunner.start();
|
||||
|
||||
}
|
||||
|
||||
private void startStopAction() {
|
||||
String text = executionBox.getText();
|
||||
text += "\r\n";
|
||||
Platform.runLater(() -> {
|
||||
executionBox.setText("");
|
||||
});
|
||||
System.out.println(text);
|
||||
history.add(text);
|
||||
BowlerKernel.writeHistory(history);
|
||||
if (historyIndex != 0)
|
||||
historyIndex--;
|
||||
else
|
||||
historyIndex = 0;
|
||||
if (running)
|
||||
stop();
|
||||
else
|
||||
start(text);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
reset();
|
||||
if (scriptRunner != null)
|
||||
while (scriptRunner.isAlive()) {
|
||||
|
||||
Log.debug("Interrupting");
|
||||
ThreadUtil.wait(10);
|
||||
try {
|
||||
scriptRunner.interrupt();
|
||||
scriptRunner.join();
|
||||
} catch (InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
|
||||
import com.neuronrobotics.sdk.common.BowlerDataType;
|
||||
import com.neuronrobotics.sdk.common.BowlerDatagram;
|
||||
import com.neuronrobotics.sdk.common.BowlerMethod;
|
||||
import com.neuronrobotics.sdk.common.DeviceManager;
|
||||
import com.neuronrobotics.sdk.common.Log;
|
||||
import com.neuronrobotics.sdk.common.MACAddress;
|
||||
import com.neuronrobotics.sdk.common.RpcEncapsulation;
|
||||
import com.neuronrobotics.sdk.common.device.server.BowlerAbstractDeviceServerNamespace;
|
||||
import com.neuronrobotics.sdk.common.device.server.BowlerAbstractServer;
|
||||
import com.neuronrobotics.sdk.common.device.server.IBowlerCommandProcessor;
|
||||
import com.neuronrobotics.sdk.network.BowlerTCPClient;
|
||||
import com.neuronrobotics.sdk.network.UDPBowlerConnection;
|
||||
|
||||
public class TestServer {
|
||||
|
||||
private TestServer() {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
class SampleBowlerServer extends BowlerAbstractServer {
|
||||
BowlerAbstractDeviceServerNamespace ns = new BowlerAbstractDeviceServerNamespace(
|
||||
getMacAddress(), "test.thingy.*;0.3;;") {
|
||||
};
|
||||
|
||||
public SampleBowlerServer() {
|
||||
super(new MACAddress());
|
||||
|
||||
ns.addRpc(new RpcEncapsulation(ns.getNamespaceIndex(), ns
|
||||
.getNamespace(), "test", BowlerMethod.GET,
|
||||
new BowlerDataType[] { BowlerDataType.I32,
|
||||
BowlerDataType.I32, BowlerDataType.I32 },// send 3
|
||||
// integers
|
||||
BowlerMethod.POST, new BowlerDataType[] {
|
||||
BowlerDataType.I32, BowlerDataType.I32,
|
||||
BowlerDataType.I32 }, // get 3 integers back
|
||||
new IBowlerCommandProcessor() {
|
||||
public Object[] process(Object[] data) {
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
System.out.println("Server Got # " + data[i]);
|
||||
}
|
||||
return new Object[] { 37,42, 999999};
|
||||
}
|
||||
}));
|
||||
addBowlerDeviceServerNamespace(ns);
|
||||
|
||||
Log.info("Starting UDP");
|
||||
try {
|
||||
startNetworkServer(1865);
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}// starts the UDP server
|
||||
// this also starts tcp server on port+1, in this case 1866
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class SampleBowlerClient extends BowlerAbstractDevice {
|
||||
|
||||
public void runCommand() {
|
||||
Object[] args = send("test.thingy.*;0.3;;", BowlerMethod.GET, "test",
|
||||
new Object[] { 36, 83, 13 });// send some numbers
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
System.out.println("Client Received # " + args[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAsyncResponse(BowlerDatagram data) {
|
||||
}// no async in this demo
|
||||
}
|
||||
|
||||
SampleBowlerClient client = new SampleBowlerClient();
|
||||
|
||||
//client.setConnection(new UDPBowlerConnection(InetAddress.getByName("127.0.0.1"), 1865));
|
||||
// Alternately you can use the tcp connection
|
||||
client.setConnection( new BowlerTCPClient("127.0.0.1",1866));
|
||||
DeviceManager.addConnection(client, "sampleClient");
|
||||
|
||||
client.runCommand();// runs our test command from client to server and
|
||||
// back
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.neuronrobotics.bowlerstudio;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.server.handler.DefaultHandler;
|
||||
import org.eclipse.jetty.server.handler.HandlerList;
|
||||
import org.eclipse.jetty.server.handler.ResourceHandler;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.api.errors.InvalidRemoteException;
|
||||
import org.eclipse.jgit.api.errors.TransportException;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.assets.ConfigurationDatabase;
|
||||
import com.neuronrobotics.bowlerstudio.assets.StudioBuildInfo;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
|
||||
import com.neuronrobotics.sdk.util.ThreadUtil;
|
||||
|
||||
public class Tutorial {
|
||||
private static int WEBSERVER_PORT = 37037;
|
||||
private static String HOME_Local_URL_ROOT = null;
|
||||
private static String HOME_URL =null;
|
||||
private static String HOME_Local_URL = null;
|
||||
private static boolean doneLoadingTutorials;
|
||||
private static Boolean startedLoadingTutorials = false;
|
||||
public static String getHomeUrl() throws Exception{
|
||||
File i=null;
|
||||
do{
|
||||
i= ScriptingEngine.fileFromGit(
|
||||
(String)ConfigurationDatabase.getObject("BowlerStudioConfigs", "tutorialSource",
|
||||
"https://github.com/CommonWealthRobotics/CommonWealthRobotics.github.io.git"),
|
||||
(String)ConfigurationDatabase.getObject("BowlerStudioConfigs", "tutorialBranch",
|
||||
"master"), // the default branch is source, so this needs to
|
||||
// be specified
|
||||
"index.html");
|
||||
}while(!i.exists());
|
||||
HOME_Local_URL_ROOT=(String)ConfigurationDatabase.getObject("BowlerStudioConfigs", "tutorialBaseUrl",
|
||||
"/BowlerStudio/Welcome-To-BowlerStudio/");
|
||||
File indexOfTutorial=i;
|
||||
if(!doneLoadingTutorials ){
|
||||
if(!startedLoadingTutorials){
|
||||
//synchronized(startedLoadingTutorials){
|
||||
startedLoadingTutorials = true;
|
||||
//}
|
||||
new Thread(){
|
||||
public void run(){
|
||||
Thread.currentThread().setUncaughtExceptionHandler(new IssueReportingExceptionHandler());
|
||||
|
||||
//HOME_Local_URL = indexOfTutorial.toURI().toString().replace("file:/", "file:///");
|
||||
Server server = new Server(WEBSERVER_PORT);
|
||||
ServerConnector connector = new ServerConnector(server);
|
||||
server.setConnectors(new Connector[] { connector });
|
||||
ResourceHandler resource_handler = new ResourceHandler();
|
||||
resource_handler.setDirectoriesListed(true);
|
||||
resource_handler.setWelcomeFiles(new String[] { "index.html" });
|
||||
System.out.println("Serving "+ indexOfTutorial.getParent());
|
||||
resource_handler.setResourceBase(indexOfTutorial.getParent());
|
||||
|
||||
HandlerList handlers = new HandlerList();
|
||||
handlers.setHandlers(new Handler[] { resource_handler, new DefaultHandler() });
|
||||
server.setHandler(handlers);
|
||||
|
||||
try {
|
||||
server.start();
|
||||
WEBSERVER_PORT= connector.getLocalPort();
|
||||
HOME_Local_URL = "http://localhost:"+WEBSERVER_PORT+HOME_Local_URL_ROOT;
|
||||
doneLoadingTutorials = true;
|
||||
server.join();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
long start = System.currentTimeMillis();
|
||||
// wait up to 30 seconds for menue to load, then fail over to the web version
|
||||
while(! doneLoadingTutorials && (System.currentTimeMillis()-start<3000)){
|
||||
ThreadUtil.wait(100);
|
||||
}
|
||||
|
||||
if(doneLoadingTutorials )
|
||||
HOME_URL = HOME_Local_URL;
|
||||
else
|
||||
HOME_URL= "http://CommonWealthRobotics.com"+HOME_Local_URL_ROOT;
|
||||
}
|
||||
return HOME_URL;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
package com.neuronrobotics.bowlerstudio.assets;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.api.errors.InvalidRemoteException;
|
||||
import org.eclipse.jgit.api.errors.TransportException;
|
||||
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.BowlerStudio;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.GithubLoginFX;
|
||||
import com.neuronrobotics.bowlerstudio.tabs.DyIOPanel;
|
||||
import com.neuronrobotics.bowlerstudio.tabs.DyIOchannelWidget;
|
||||
//import com.neuronrobotics.nrconsole.plugin.DyIO.DyIOConsole;
|
||||
import com.neuronrobotics.sdk.dyio.DyIOChannelMode;
|
||||
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.image.Image;
|
||||
|
||||
public class BowlerStudioResourceFactory {
|
||||
private static final Map<DyIOChannelMode, Image> lookup = new HashMap<>();
|
||||
private static Image chanHighlight;
|
||||
private static Image chanUpdate;
|
||||
private static Image chanDefault;
|
||||
private static final ArrayList<FXMLLoader> fxmlLoaders = new ArrayList<>();
|
||||
private static FXMLLoader mainPanel;
|
||||
private static FXMLLoader githubLogin;
|
||||
private static FXMLLoader mainControllerPanel;
|
||||
private static boolean loaded=false;
|
||||
private BowlerStudioResourceFactory() {
|
||||
}
|
||||
|
||||
public static FXMLLoader getLoader(int channelIndex) {
|
||||
return fxmlLoaders.get(channelIndex);
|
||||
}
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public static void load() throws Exception {
|
||||
if(loaded)
|
||||
return;
|
||||
loaded=true;
|
||||
try {
|
||||
BowlerStudio.renderSplashFrame( 94,"Loading DyIO");
|
||||
mainPanel = AssetFactory.loadLayout("layout/DyIOPanel.fxml");
|
||||
//mainPanel.setController(new DyIOPanel());
|
||||
mainPanel.setClassLoader(DyIOPanel.class.getClassLoader());
|
||||
BowlerStudio.renderSplashFrame( 95,"Loading GitHub");
|
||||
|
||||
githubLogin = AssetFactory.loadLayout("layout/githublogin.fxml");
|
||||
//githubLogin.setController(new GithubLoginFX());
|
||||
githubLogin.setClassLoader(GithubLoginFX.class.getClassLoader());
|
||||
} catch (InvalidRemoteException e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
} catch (TransportException e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
} catch (GitAPIException e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
} catch (IOException e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
} catch (Exception e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
for (DyIOChannelMode cm : EnumSet.allOf(DyIOChannelMode.class)) {
|
||||
Image image;
|
||||
//
|
||||
try {
|
||||
image = AssetFactory.loadAsset("dyio/icon-" + cm.toSlug() + ".png");
|
||||
} catch (NullPointerException e) {
|
||||
image = AssetFactory.loadAsset("dyio/icon-off.png");
|
||||
}
|
||||
lookup.put(cm, image);
|
||||
}
|
||||
setChanHighlight(AssetFactory.loadAsset("dyio/channel-highlight.png"));
|
||||
setChanDefault(AssetFactory.loadAsset("dyio/channel-default.png"));
|
||||
setChanUpdate(AssetFactory.loadAsset("dyio/channel-update.png"));
|
||||
|
||||
for (int i = 0; i < 24; i++) {
|
||||
// generate the control widgets
|
||||
FXMLLoader fxmlLoader;
|
||||
try {
|
||||
fxmlLoader = AssetFactory.loadLayout("layout/DyIOChannelContorol.fxml", true);
|
||||
//fxmlLoader.setController(new DyIOchannelWidget());
|
||||
fxmlLoader.setClassLoader(DyIOchannelWidget.class.getClassLoader());
|
||||
try {
|
||||
fxmlLoader.load();
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
fxmlLoaders.add(fxmlLoader);
|
||||
} catch (InvalidRemoteException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (TransportException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (GitAPIException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
try {
|
||||
mainPanel.load();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(BowlerStudio.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
try {
|
||||
githubLogin.load();
|
||||
} catch (IOException e) {
|
||||
Logger.getLogger(BowlerStudio.class.getName()).log(Level.SEVERE, null, e);
|
||||
}
|
||||
|
||||
}// stub to force a load from the static in a specific thread
|
||||
|
||||
public static Image getModeImage(DyIOChannelMode mode) {
|
||||
return lookup.get(mode);
|
||||
}
|
||||
|
||||
public static Image getChanHighlight() {
|
||||
return chanHighlight;
|
||||
}
|
||||
|
||||
public static void setChanHighlight(Image chanHighlight) {
|
||||
BowlerStudioResourceFactory.chanHighlight = chanHighlight;
|
||||
}
|
||||
|
||||
public static Image getChanUpdate() {
|
||||
return chanUpdate;
|
||||
}
|
||||
|
||||
public static void setChanUpdate(Image chanUpdate) {
|
||||
BowlerStudioResourceFactory.chanUpdate = chanUpdate;
|
||||
}
|
||||
|
||||
public static Image getChanDefault() {
|
||||
return chanDefault;
|
||||
}
|
||||
|
||||
public static void setChanDefault(Image chanDefault) {
|
||||
BowlerStudioResourceFactory.chanDefault = chanDefault;
|
||||
}
|
||||
|
||||
public static FXMLLoader getMainPanel() {
|
||||
return mainPanel;
|
||||
}
|
||||
|
||||
public static void setMainPanel(FXMLLoader mainPanel) {
|
||||
BowlerStudioResourceFactory.mainPanel = mainPanel;
|
||||
}
|
||||
|
||||
public static FXMLLoader getGithubLogin() {
|
||||
return githubLogin;
|
||||
}
|
||||
|
||||
public static void setGithubLogin(FXMLLoader githubLogin) {
|
||||
BowlerStudioResourceFactory.githubLogin = githubLogin;
|
||||
}
|
||||
|
||||
public static FXMLLoader getMainControllerPanel() {
|
||||
return mainControllerPanel;
|
||||
}
|
||||
|
||||
public static void setMainControllerPanel(FXMLLoader mainControllerPanel) {
|
||||
BowlerStudioResourceFactory.mainControllerPanel = mainControllerPanel;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.neuronrobotics.bowlerstudio.creature;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public abstract class AbstractGameController {
|
||||
private ArrayList<IGameControllerUpdateListener> listeners = new ArrayList<>();
|
||||
|
||||
public void addIGameControllerUpdateListener(IGameControllerUpdateListener l){
|
||||
if(!listeners.contains(l))
|
||||
listeners.add(l);
|
||||
}
|
||||
public void removeIGameControllerUpdateListener(IGameControllerUpdateListener l){
|
||||
if(listeners.contains(l))
|
||||
listeners.remove(l);
|
||||
}
|
||||
public void clearIGameControllerUpdateListener(){
|
||||
listeners.clear();
|
||||
}
|
||||
|
||||
protected void fireGameControllerUpdate(){
|
||||
|
||||
}
|
||||
|
||||
public abstract double getControls0Plus();
|
||||
public abstract double getControls0Minus();
|
||||
|
||||
public abstract double getControls1Plus();
|
||||
public abstract double getControls1Minus();
|
||||
|
||||
public abstract double getControls2Plus();
|
||||
public abstract double getControls2Minus();
|
||||
|
||||
public abstract double getControls3Plus();
|
||||
public abstract double getControls3Minus();
|
||||
|
||||
public abstract double getNavUp();
|
||||
public abstract double getNavDown();
|
||||
|
||||
public abstract double getNavLeft();
|
||||
public abstract double getNavRight();
|
||||
|
||||
|
||||
public abstract double getActionLeft();
|
||||
public abstract double getActionRight();
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.neuronrobotics.bowlerstudio.creature;
|
||||
|
||||
import com.neuronrobotics.sdk.addons.kinematics.MobileBase;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR;
|
||||
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.text.Text;
|
||||
|
||||
public class AdjustbodyMassWidget extends Group {
|
||||
|
||||
|
||||
private MobileBase device;
|
||||
private MobileBaseCadManager manager;
|
||||
double textToNum(TextField mass) {
|
||||
try {
|
||||
return Double.parseDouble(mass.getText().trim());
|
||||
}catch(Throwable t) {
|
||||
mass.setText("0");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public AdjustbodyMassWidget(MobileBase device) {
|
||||
this.device = device;
|
||||
manager = MobileBaseCadManager.get(device);
|
||||
GridPane pane = new GridPane();
|
||||
|
||||
TextField mass = new TextField(CreatureLab.getFormatted(device.getMassKg()));
|
||||
mass.setOnAction(event -> {
|
||||
device.setMassKg(textToNum(mass));
|
||||
if(manager!=null)manager.generateCad();
|
||||
});
|
||||
TransformNR currentCentroid = device.getCenterOfMassFromCentroid();
|
||||
TextField massx = new TextField(CreatureLab.getFormatted(currentCentroid.getX()));
|
||||
massx.setOnAction(event -> {
|
||||
currentCentroid.setX(textToNum(massx));
|
||||
device.setCenterOfMassFromCentroid(currentCentroid);
|
||||
;
|
||||
if(manager!=null)manager.generateCad();
|
||||
|
||||
});
|
||||
|
||||
TextField massy = new TextField(CreatureLab.getFormatted(currentCentroid.getY()));
|
||||
massy.setOnAction(event -> {
|
||||
currentCentroid.setY(textToNum(massy));
|
||||
device.setCenterOfMassFromCentroid(currentCentroid);
|
||||
;
|
||||
if(manager!=null)manager.generateCad();
|
||||
|
||||
});
|
||||
|
||||
TextField massz = new TextField(CreatureLab.getFormatted(currentCentroid.getZ()));
|
||||
massz.setOnAction(event -> {
|
||||
currentCentroid.setZ(textToNum(massz));
|
||||
device.setCenterOfMassFromCentroid(currentCentroid);
|
||||
;
|
||||
if(manager!=null)manager.generateCad();
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
pane.add(new Text("Mass"), 0, 0);
|
||||
pane.add(mass, 1, 0);
|
||||
|
||||
pane.add(new Text("Mass Centroid x"), 0, 1);
|
||||
pane.add(massx, 1, 1);
|
||||
|
||||
pane.add(new Text("Mass Centroid y"), 0, 2);
|
||||
pane.add(massy, 1, 2);
|
||||
pane.add(new Text("Mass Centroid z"), 0, 3);
|
||||
pane.add(massz, 1,3);
|
||||
getChildren().add(pane);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
package com.neuronrobotics.bowlerstudio.creature;
|
||||
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
import com.neuronrobotics.replicator.driver.BowlerBoardDevice;
|
||||
import com.neuronrobotics.replicator.driver.NRPrinter;
|
||||
|
||||
|
||||
public class CartesianPanel extends JPanel{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
private BowlerBoardDevice delt;
|
||||
private NRPrinter printer;
|
||||
private JLabel jLabel0;
|
||||
private JLabel jLabel1;
|
||||
private JLabel jLabel2;
|
||||
private JLabel jLabel3;
|
||||
private JLabel jLabel4;
|
||||
private JTextField jTextField0;
|
||||
private JTextField jTextField1;
|
||||
private JTextField jTextField2;
|
||||
private JTextField jTextField3;
|
||||
private JTextField jTextField4;
|
||||
private JButton jButton0;
|
||||
|
||||
public void setDevices(BowlerBoardDevice delt, NRPrinter printer) {
|
||||
this.delt = delt;
|
||||
this.printer = printer;
|
||||
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
setLayout(new GridLayout(6, 4));
|
||||
add(getJLabel0());
|
||||
add(getJTextField0());
|
||||
add(getJLabel1());
|
||||
add(getJTextField1());
|
||||
add(getJLabel2());
|
||||
add(getJTextField2());
|
||||
add(getJLabel3());
|
||||
add(getJTextField3());
|
||||
add(getJLabel4());
|
||||
add(getJTextField4());
|
||||
add(getJButton0());
|
||||
setSize(358, 291);
|
||||
}
|
||||
|
||||
private JButton getJButton0() {
|
||||
if (jButton0 == null) {
|
||||
jButton0 = new JButton();
|
||||
jButton0.setText("Update Robot");
|
||||
}
|
||||
return jButton0;
|
||||
}
|
||||
|
||||
private JTextField getJTextField4() {
|
||||
if (jTextField4 == null) {
|
||||
jTextField4 = new JTextField();
|
||||
jTextField4.setText("tempTarget");
|
||||
jTextField4.addActionListener(new ActionListener() {
|
||||
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
jTextField4ActionActionPerformed(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
return jTextField4;
|
||||
}
|
||||
|
||||
private JTextField getJTextField3() {
|
||||
if (jTextField3 == null) {
|
||||
jTextField3 = new JTextField();
|
||||
jTextField3.setText("extrudeTarget");
|
||||
jTextField3.addActionListener(new ActionListener() {
|
||||
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
jTextField3ActionActionPerformed(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
return jTextField3;
|
||||
}
|
||||
|
||||
private JTextField getJTextField2() {
|
||||
if (jTextField2 == null) {
|
||||
jTextField2 = new JTextField();
|
||||
jTextField2.setText("ztarget");
|
||||
jTextField2.addActionListener(new ActionListener() {
|
||||
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
jTextField2ActionActionPerformed(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
return jTextField2;
|
||||
}
|
||||
|
||||
private JTextField getJTextField1() {
|
||||
if (jTextField1 == null) {
|
||||
jTextField1 = new JTextField();
|
||||
jTextField1.setText("ytarget");
|
||||
jTextField1.addActionListener(new ActionListener() {
|
||||
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
jTextField1ActionActionPerformed(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
return jTextField1;
|
||||
}
|
||||
|
||||
private JTextField getJTextField0() {
|
||||
if (jTextField0 == null) {
|
||||
jTextField0 = new JTextField();
|
||||
jTextField0.setText("xtarget");
|
||||
jTextField0.addActionListener(new ActionListener() {
|
||||
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
jTextField0ActionActionPerformed(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
return jTextField0;
|
||||
}
|
||||
|
||||
private JLabel getJLabel4() {
|
||||
if (jLabel4 == null) {
|
||||
jLabel4 = new JLabel();
|
||||
jLabel4.setText("Temp");
|
||||
}
|
||||
return jLabel4;
|
||||
}
|
||||
|
||||
private JLabel getJLabel3() {
|
||||
if (jLabel3 == null) {
|
||||
jLabel3 = new JLabel();
|
||||
jLabel3.setText("Extrude");
|
||||
}
|
||||
return jLabel3;
|
||||
}
|
||||
|
||||
private JLabel getJLabel2() {
|
||||
if (jLabel2 == null) {
|
||||
jLabel2 = new JLabel();
|
||||
jLabel2.setText("Z");
|
||||
}
|
||||
return jLabel2;
|
||||
}
|
||||
|
||||
private JLabel getJLabel1() {
|
||||
if (jLabel1 == null) {
|
||||
jLabel1 = new JLabel();
|
||||
jLabel1.setText("Y");
|
||||
}
|
||||
return jLabel1;
|
||||
}
|
||||
|
||||
private JLabel getJLabel0() {
|
||||
if (jLabel0 == null) {
|
||||
jLabel0 = new JLabel();
|
||||
jLabel0.setText("X");
|
||||
}
|
||||
return jLabel0;
|
||||
}
|
||||
|
||||
public CartesianPanel() {
|
||||
initComponents();
|
||||
}
|
||||
|
||||
private void jTextField4ActionActionPerformed(ActionEvent event) {
|
||||
//set temp
|
||||
}
|
||||
|
||||
private void jTextField3ActionActionPerformed(ActionEvent event) {
|
||||
//set extrude
|
||||
|
||||
}
|
||||
|
||||
private void jTextField2ActionActionPerformed(ActionEvent event) {
|
||||
//set z
|
||||
}
|
||||
|
||||
private void jTextField1ActionActionPerformed(ActionEvent event) {
|
||||
//set y
|
||||
}
|
||||
|
||||
private void jTextField0ActionActionPerformed(ActionEvent event) {
|
||||
// set x
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
package com.neuronrobotics.bowlerstudio.creature;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.BowlerStudio;
|
||||
import com.neuronrobotics.bowlerstudio.BowlerStudioController;
|
||||
import com.neuronrobotics.bowlerstudio.BowlerStudioModularFrame;
|
||||
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
|
||||
import com.neuronrobotics.bowlerstudio.tabs.AbstractBowlerStudioTab;
|
||||
import com.neuronrobotics.bowlerstudio.util.FileWatchDeviceWrapper;
|
||||
import com.neuronrobotics.sdk.addons.gamepad.BowlerJInputDevice;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.DHParameterKinematics;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.DhInverseSolver;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.IDriveEngine;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.MobileBase;
|
||||
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
|
||||
import com.neuronrobotics.sdk.common.IDeviceConnectionEventListener;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.layout.HBox;
|
||||
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.api.errors.InvalidRemoteException;
|
||||
import org.eclipse.jgit.api.errors.TransportException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import javafx.scene.control.ToggleButton;
|
||||
|
||||
public class CreatureLab extends AbstractBowlerStudioTab implements IOnEngineeringUnitsChange {
|
||||
|
||||
private BowlerAbstractDevice pm;
|
||||
|
||||
private IDriveEngine defaultDriveEngine;
|
||||
// private DhInverseSolver defaultDHSolver;
|
||||
private Menu localMenue;
|
||||
private ProgressIndicator pi;
|
||||
|
||||
private MobileBaseCadManager baseManager;
|
||||
private CheckBox autoRegen = new CheckBox("Auto-Regnerate CAD");
|
||||
Parent root;
|
||||
private BowlerJInputDevice gameController = null;
|
||||
CreatureLabControlsTab tab = new CreatureLabControlsTab();;
|
||||
|
||||
@Override
|
||||
public void onTabClosing() {
|
||||
baseManager.onTabClosing();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getMyNameSpaces() {
|
||||
// TODO Auto-generated method stub
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "restriction", "restriction" })
|
||||
@Override
|
||||
public void initializeUI(BowlerAbstractDevice pm) {
|
||||
setGraphic(AssetFactory.loadIcon("CreatureLab-Tab.png"));
|
||||
this.pm = pm;
|
||||
autoRegen.setSelected(true);
|
||||
autoRegen.setOnAction(event -> {
|
||||
baseManager.setAutoRegen(autoRegen.isSelected());
|
||||
if (autoRegen.isSelected()) {
|
||||
generateCad();
|
||||
}
|
||||
});
|
||||
// TODO Auto-generated method stub
|
||||
setText(pm.getScriptingName());
|
||||
|
||||
try {
|
||||
ScriptingEngine.setAutoupdate(true);
|
||||
} catch (IOException e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
}
|
||||
MobileBase device = (MobileBase) pm;
|
||||
|
||||
// Button save = new Button("Save Configuration");
|
||||
|
||||
FXMLLoader loader;
|
||||
try {
|
||||
loader = AssetFactory.loadLayout("layout/CreatureLabControlsTab.fxml", true);
|
||||
Platform.runLater(() -> {
|
||||
loader.setController(tab);
|
||||
// This is needed when loading on MAC
|
||||
loader.setClassLoader(getClass().getClassLoader());
|
||||
try {
|
||||
root = loader.load();
|
||||
finishLoading(device);
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
} catch (Exception e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void finishLoading(MobileBase device) {
|
||||
|
||||
TreeView<String> tree = null;
|
||||
TreeItem<String> rootItem = null;
|
||||
|
||||
try {
|
||||
rootItem = new TreeItem<String>(device.getScriptingName(), AssetFactory.loadIcon("creature.png"));
|
||||
} catch (Exception e) {
|
||||
rootItem = new TreeItem<String>(device.getScriptingName());
|
||||
}
|
||||
tree = new TreeView<>(rootItem);
|
||||
AnchorPane treebox1 = tab.getTreeBox();
|
||||
treebox1.getChildren().clear();
|
||||
treebox1.getChildren().add(tree);
|
||||
AnchorPane.setTopAnchor(tree, 0.0);
|
||||
AnchorPane.setLeftAnchor(tree, 0.0);
|
||||
AnchorPane.setRightAnchor(tree, 0.0);
|
||||
AnchorPane.setBottomAnchor(tree, 0.0);
|
||||
|
||||
rootItem.setExpanded(true);
|
||||
HashMap<TreeItem<String>, Runnable> callbackMapForTreeitems = new HashMap<>();
|
||||
HashMap<TreeItem<String>, Group> widgetMapForTreeitems = new HashMap<>();
|
||||
try {
|
||||
MobleBaseMenueFactory.load(device, tree, rootItem, callbackMapForTreeitems, widgetMapForTreeitems, this);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
tree.setPrefWidth(325);
|
||||
tree.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
|
||||
JogWidget walkWidget = new JogWidget(device);
|
||||
tree.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Object>() {
|
||||
|
||||
@Override
|
||||
public void changed(ObservableValue<?> observable, Object oldValue, Object newValue) {
|
||||
@SuppressWarnings("unchecked")
|
||||
TreeItem<String> treeItem = (TreeItem<String>) newValue;
|
||||
new Thread() {
|
||||
public void run() {
|
||||
if (walkWidget.getGameController() != null)
|
||||
setGameController(walkWidget.getGameController());
|
||||
if (callbackMapForTreeitems.get(treeItem) != null) {
|
||||
callbackMapForTreeitems.get(treeItem).run();
|
||||
}
|
||||
if (widgetMapForTreeitems.get(treeItem) != null) {
|
||||
|
||||
Platform.runLater(() -> {
|
||||
tab.getControlsBox().getChildren().clear();
|
||||
Group g = widgetMapForTreeitems.get(treeItem);
|
||||
tab.getControlsBox().getChildren().add(g);
|
||||
AnchorPane.setTopAnchor(g, 0.0);
|
||||
AnchorPane.setLeftAnchor(g, 0.0);
|
||||
AnchorPane.setRightAnchor(g, 0.0);
|
||||
AnchorPane.setBottomAnchor(g, 0.0);
|
||||
});
|
||||
} else {
|
||||
Platform.runLater(() -> {
|
||||
tab.getControlsBox().getChildren().clear();
|
||||
});
|
||||
BowlerStudio.select(device);
|
||||
walkWidget.setGameController(getController());
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
|
||||
}
|
||||
});
|
||||
VBox progress = new VBox(10);
|
||||
|
||||
final ToggleGroup group = new ToggleGroup();
|
||||
|
||||
RadioButton rb1 = new RadioButton();
|
||||
rb1.setToggleGroup(group);
|
||||
rb1.setSelected(true);
|
||||
rb1.setOnAction(event -> {
|
||||
setCadMode(false);
|
||||
});
|
||||
|
||||
RadioButton rb2 = new RadioButton();
|
||||
rb2.setToggleGroup(group);
|
||||
rb2.fire();
|
||||
rb2.setOnAction(event -> {
|
||||
setCadMode(true);
|
||||
});
|
||||
|
||||
HBox radioOptions = new HBox(10);
|
||||
radioOptions.getChildren().addAll(new Label("Cad"), rb1, rb2, new Label("Config"));
|
||||
|
||||
pi = new ProgressIndicator(0);
|
||||
baseManager = MobileBaseCadManager.get(device, BowlerStudioController.getMobileBaseUI());
|
||||
pi.progressProperty().bindBidirectional(baseManager.getProcesIndictor());
|
||||
HBox progressIndicatorPanel = new HBox(10);
|
||||
progressIndicatorPanel.getChildren().addAll(new Label("Cad Progress:"), pi);
|
||||
progress.getChildren().addAll(progressIndicatorPanel, autoRegen, radioOptions);
|
||||
|
||||
progress.setStyle("-fx-background-color: #FFFFFF;");
|
||||
progress.setOpacity(.7);
|
||||
// progress.setMinHeight(150);
|
||||
progress.setPrefSize(325, 150);
|
||||
tab.setOverlayTop(progress);
|
||||
tab.setOverlayTopRight(walkWidget);
|
||||
|
||||
BowlerStudioModularFrame.getBowlerStudioModularFrame().showCreatureLab();
|
||||
setCadMode(true);// start the UI in config mode
|
||||
generateCad();
|
||||
|
||||
setContent(root);
|
||||
|
||||
}
|
||||
|
||||
private void setCadMode(boolean mode) {
|
||||
new Thread(() -> {
|
||||
baseManager.setConfigurationViewerMode(mode);
|
||||
baseManager.setAutoRegen(autoRegen.isSelected());
|
||||
if (autoRegen.isSelected()) {
|
||||
generateCad();
|
||||
}
|
||||
}).start();
|
||||
|
||||
}
|
||||
|
||||
public void generateCad() {
|
||||
// new Exception().printStackTrace();
|
||||
baseManager.generateCad();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabReOpening() {
|
||||
baseManager.setCadScript(baseManager.getCadScript());
|
||||
try {
|
||||
if (autoRegen.isSelected())
|
||||
generateCad();
|
||||
} catch (Exception ex) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static String getFormatted(double value) {
|
||||
return String.format("%4.3f%n", (double) value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSliderMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSliderDoneMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
|
||||
if (autoRegen.isSelected())
|
||||
generateCad();
|
||||
}
|
||||
|
||||
public BowlerJInputDevice getController() {
|
||||
|
||||
return getGameController();
|
||||
}
|
||||
|
||||
public BowlerJInputDevice getGameController() {
|
||||
return gameController;
|
||||
}
|
||||
|
||||
public void setGameController(BowlerJInputDevice bowlerJInputDevice) {
|
||||
this.gameController = bowlerJInputDevice;
|
||||
}
|
||||
|
||||
public void setGitDhEngine(String gitsId, String file, DHParameterKinematics dh) {
|
||||
MobileBaseLoader.get(baseManager.getMobileBase()).setDefaultDhParameterKinematics(dh);
|
||||
|
||||
}
|
||||
|
||||
public void setGitCadEngine(String gitsId, String file, MobileBase device)
|
||||
throws InvalidRemoteException, TransportException, GitAPIException, IOException {
|
||||
baseManager.setGitCadEngine(gitsId, file, device);
|
||||
}
|
||||
|
||||
public void setGitCadEngine(String gitsId, String file, DHParameterKinematics dh)
|
||||
throws InvalidRemoteException, TransportException, GitAPIException, IOException {
|
||||
baseManager.setGitCadEngine(gitsId, file, dh);
|
||||
}
|
||||
|
||||
public void setGitWalkingEngine(String git, String file, MobileBase device) {
|
||||
|
||||
MobileBaseLoader.get(baseManager.getMobileBase()).setGitWalkingEngine(git, file, device);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.neuronrobotics.bowlerstudio.creature;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.TreeView;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
public class CreatureLabControlsTab {
|
||||
@FXML
|
||||
private AnchorPane walkingBox;
|
||||
|
||||
@FXML
|
||||
private AnchorPane controlsBox;
|
||||
|
||||
@FXML
|
||||
private AnchorPane progressBar;
|
||||
|
||||
@FXML
|
||||
private AnchorPane treeBox;
|
||||
|
||||
|
||||
public AnchorPane getWalkingBox() {
|
||||
return walkingBox;
|
||||
}
|
||||
|
||||
public void setWalkingBox(AnchorPane walkingBox) {
|
||||
this.walkingBox = walkingBox;
|
||||
}
|
||||
|
||||
public AnchorPane getControlsBox() {
|
||||
return controlsBox;
|
||||
}
|
||||
|
||||
public void setControlsBox(AnchorPane controlsBox) {
|
||||
this.controlsBox = controlsBox;
|
||||
}
|
||||
|
||||
// public AnchorPane getProgressBar() {
|
||||
// return progressBar;
|
||||
// }
|
||||
|
||||
public void setProgressBar(AnchorPane progressBar) {
|
||||
this.progressBar = progressBar;
|
||||
}
|
||||
|
||||
public AnchorPane getTreeBox() {
|
||||
return treeBox;
|
||||
}
|
||||
|
||||
public void setTreeBox(AnchorPane treeBox) {
|
||||
this.treeBox = treeBox;
|
||||
}
|
||||
|
||||
|
||||
public void setOverlayTop(VBox progress) {
|
||||
// TODO Auto-generated method stub
|
||||
progressBar.getChildren().clear();
|
||||
progressBar.getChildren().add(progress);
|
||||
AnchorPane.setTopAnchor(progress, 0.0);
|
||||
AnchorPane.setLeftAnchor(progress, 0.0);
|
||||
AnchorPane.setRightAnchor(progress, 0.0);
|
||||
AnchorPane.setBottomAnchor(progress, 0.0);
|
||||
}
|
||||
|
||||
public void setOverlayTopRight(JogWidget walkWidget) {
|
||||
// TODO Auto-generated method stub
|
||||
walkingBox.getChildren().clear();
|
||||
walkingBox.getChildren().add(walkWidget);
|
||||
AnchorPane.setTopAnchor(walkWidget, 0.0);
|
||||
AnchorPane.setLeftAnchor(walkWidget, 0.0);
|
||||
AnchorPane.setRightAnchor(walkWidget, 0.0);
|
||||
AnchorPane.setBottomAnchor(walkWidget, 0.0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
package com.neuronrobotics.bowlerstudio.creature;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.BowlerStudioController;
|
||||
import com.neuronrobotics.bowlerstudio.CreatureLab3dController;
|
||||
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
|
||||
import com.neuronrobotics.bowlerstudio.physics.MobileBasePhysicsManager;
|
||||
import com.neuronrobotics.bowlerstudio.physics.PhysicsEngine;
|
||||
import com.neuronrobotics.bowlerstudio.threed.BowlerStudio3dEngine;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.LinkConfiguration;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.MobileBase;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.imu.IMUUpdate;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.imu.IMUUpdateListener;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.math.RotationNR;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR;
|
||||
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
|
||||
import com.neuronrobotics.sdk.common.IDeviceConnectionEventListener;
|
||||
import com.neuronrobotics.sdk.util.ThreadUtil;
|
||||
import eu.mihosoft.vrl.v3d.CSG;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.GridPane;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
|
||||
public class CreaturePhysicsWidget extends GridPane implements IMUUpdateListener {
|
||||
Button runstop = new Button("Run", AssetFactory.loadIcon("Run.png"));
|
||||
Button pauseresume = new Button("Pause", AssetFactory.loadIcon("Pause.png"));
|
||||
Button step = new Button("Step", AssetFactory.loadIcon("Step.png"));
|
||||
TextField msLoopTime =new TextField("20") ;
|
||||
int msLoopTimeInt =0;
|
||||
private boolean run=false;
|
||||
private boolean takestep=false;
|
||||
private boolean pause=false;
|
||||
Thread physicsThread =null;
|
||||
private Set<CSG> oldParts=null;
|
||||
private MobileBase base;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public CreaturePhysicsWidget(MobileBase base){
|
||||
|
||||
this.base = base;
|
||||
base.addConnectionEventListener(new IDeviceConnectionEventListener() {
|
||||
|
||||
@Override
|
||||
public void onDisconnect(BowlerAbstractDevice arg0) {
|
||||
Platform.runLater(()->{
|
||||
stop();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnect(BowlerAbstractDevice arg0) {}
|
||||
});
|
||||
add(runstop,0,0);
|
||||
add(pauseresume,1,0);
|
||||
add(step,2,0);
|
||||
add(new Label("MS loop"),3,0);
|
||||
add(msLoopTime,4,0);
|
||||
pauseresume.setDisable(true);
|
||||
step.setDisable(true);
|
||||
pauseresume.setOnAction(event->{
|
||||
if(!isPause()){
|
||||
pauseresume.setGraphic(AssetFactory.loadIcon("Resume.png"));
|
||||
pauseresume.setText("Resume");
|
||||
step.setDisable(false);
|
||||
}else{
|
||||
pauseresume.setGraphic(AssetFactory.loadIcon("Pause.png"));
|
||||
pauseresume.setText("Pause");
|
||||
step.setDisable(true);
|
||||
}
|
||||
setPause(!isPause());
|
||||
});
|
||||
step.setOnAction(event->{
|
||||
setTakestep(true);
|
||||
});
|
||||
runstop.setOnAction(event->{
|
||||
if(isRun()){
|
||||
stop();
|
||||
// new Thread(){
|
||||
// public void run(){
|
||||
// ThreadUtil.wait(50);
|
||||
// System.gc();// clean up any objects created by the physics engine
|
||||
// }
|
||||
// }.start();
|
||||
}else{
|
||||
//System.gc();// clean up any objects created by the physics engine
|
||||
runstop.setGraphic(AssetFactory.loadIcon("Stop.png"));
|
||||
runstop.setText("Stop");
|
||||
msLoopTime.setDisable(true);
|
||||
pauseresume.setDisable(false);
|
||||
base.getImu().addvirtualListeners(this);
|
||||
new Thread(){
|
||||
|
||||
|
||||
public void run(){
|
||||
while(MobileBaseCadManager.get( base).getProcesIndictor().get()<1){
|
||||
ThreadUtil.wait(10);
|
||||
}
|
||||
HashMap<LinkConfiguration, ArrayList<CSG>> simplecad = MobileBaseCadManager.getSimplecad(base) ;
|
||||
ArrayList<CSG> baseCad=MobileBaseCadManager.getBaseCad(base);
|
||||
base.DriveArc(new TransformNR(.01,0,0,new RotationNR()), 0);
|
||||
PhysicsEngine.get().clear();
|
||||
MobileBasePhysicsManager m =new MobileBasePhysicsManager(base, baseCad, simplecad);
|
||||
//BowlerStudio3dEngine threeD = BowlerStudioController.getBowlerStudio().getJfx3dmanager();
|
||||
oldParts = CreatureLab3dController.getEngine().getCsgMap().keySet();
|
||||
BowlerStudioController.setCsg(PhysicsEngine.get().getCsgFromEngine());
|
||||
int loopTiming = (int) Double.parseDouble(msLoopTime.getText());
|
||||
|
||||
physicsThread = new Thread(){
|
||||
public void run(){
|
||||
try{
|
||||
while(!Thread.interrupted() && isRun()){
|
||||
while(!Thread.interrupted() && isPause() && isTakestep()==false){
|
||||
ThreadUtil.wait(loopTiming);
|
||||
}
|
||||
setTakestep(false);
|
||||
long start = System.currentTimeMillis();
|
||||
PhysicsEngine.get().stepMs(loopTiming);
|
||||
long took = (System.currentTimeMillis() - start);
|
||||
if (took < loopTiming)
|
||||
ThreadUtil.wait((int) (loopTiming - took)/4);
|
||||
else{
|
||||
if(took>loopTiming*2)
|
||||
System.out.println("ERROR Real time broken by: "+took+"ms");
|
||||
}
|
||||
}
|
||||
PhysicsEngine.get().clear();
|
||||
m.clear();
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
physicsThread.start();
|
||||
}
|
||||
}.start();
|
||||
|
||||
}
|
||||
setRun(!isRun());
|
||||
});
|
||||
|
||||
}
|
||||
private void stop() {
|
||||
runstop.setGraphic(AssetFactory.loadIcon("Run.png"));
|
||||
runstop.setText("Run");
|
||||
if(physicsThread!=null)
|
||||
physicsThread.interrupt();
|
||||
|
||||
msLoopTime.setDisable(false);
|
||||
pauseresume.setDisable(true);
|
||||
if(oldParts!=null){
|
||||
ArrayList<CSG>oldp=new ArrayList<>();
|
||||
for(CSG c:oldParts){
|
||||
oldp.add(c);
|
||||
}
|
||||
BowlerStudioController.setCsg(oldp);
|
||||
oldParts=null;
|
||||
}
|
||||
base.getImu().removevirtualListeners(this);
|
||||
}
|
||||
public boolean isTakestep() {
|
||||
return takestep;
|
||||
}
|
||||
public void setTakestep(boolean takestep) {
|
||||
this.takestep = takestep;
|
||||
}
|
||||
public boolean isPause() {
|
||||
return pause;
|
||||
}
|
||||
public void setPause(boolean pause) {
|
||||
this.pause = pause;
|
||||
}
|
||||
public boolean isRun() {
|
||||
return run;
|
||||
}
|
||||
public void setRun(boolean run) {
|
||||
this.run = run;
|
||||
}
|
||||
@Override
|
||||
public void onIMUUpdate(IMUUpdate arg0) {
|
||||
// System.err.println("X = "+arg0.getxAcceleration()+
|
||||
// " Y = "+arg0.getyAcceleration()+
|
||||
// " Z = "+arg0.getzAcceleration()+
|
||||
// " rX = "+arg0.getRotxAcceleration()+
|
||||
// " rY = "+arg0.getRotyAcceleration()+
|
||||
// " rZ = "+arg0.getRotzAcceleration()
|
||||
//
|
||||
// );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
package com.neuronrobotics.bowlerstudio.creature;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import org.reactfx.util.FxTimer;
|
||||
|
||||
import com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.AbstractLink;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.DHLink;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.DHParameterKinematics;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.DhLinkType;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.IJointSpaceUpdateListenerNR;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.JointLimit;
|
||||
import com.neuronrobotics.sdk.common.Log;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.control.Accordion;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Slider;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.TitledPane;
|
||||
import javafx.scene.layout.ColumnConstraints;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.RowConstraints;
|
||||
import javafx.scene.text.Text;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class DHLinkWidget extends Group implements IJointSpaceUpdateListenerNR {
|
||||
private AbstractKinematicsNR device;
|
||||
private DHParameterKinematics dhdevice;
|
||||
|
||||
private int linkIndex;
|
||||
private EngineeringUnitsSliderWidget setpoint;
|
||||
private Button del;
|
||||
|
||||
|
||||
|
||||
|
||||
public DHLinkWidget(int linkIndex, DHLink dhlink, AbstractKinematicsNR device2, Button del,IOnEngineeringUnitsChange externalListener, MobileBaseCadManager manager ) {
|
||||
|
||||
this.linkIndex = linkIndex;
|
||||
this.device = device2;
|
||||
if(DHParameterKinematics.class.isInstance(device2)){
|
||||
dhdevice=(DHParameterKinematics)device2;
|
||||
}
|
||||
this.del = del;
|
||||
AbstractLink abstractLink = device2.getAbstractLink(linkIndex);
|
||||
|
||||
|
||||
TextField name = new TextField(abstractLink.getLinkConfiguration().getName());
|
||||
name.setMaxWidth(100.0);
|
||||
name.setOnAction(event -> {
|
||||
abstractLink.getLinkConfiguration().setName(name.getText());
|
||||
});
|
||||
|
||||
setpoint = new EngineeringUnitsSliderWidget(new IOnEngineeringUnitsChange() {
|
||||
|
||||
@Override
|
||||
public void onSliderMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSliderDoneMoving(EngineeringUnitsSliderWidget source,
|
||||
double newAngleDegrees) {
|
||||
try {
|
||||
device2.setDesiredJointAxisValue(linkIndex, setpoint.getValue(), 2);
|
||||
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
};
|
||||
}
|
||||
},
|
||||
abstractLink.getMinEngineeringUnits(),
|
||||
abstractLink.getMaxEngineeringUnits(),
|
||||
device2.getCurrentJointSpaceVector()[linkIndex],
|
||||
180,dhlink.getLinkType()==DhLinkType.ROTORY?"degrees":"mm");
|
||||
|
||||
|
||||
|
||||
final Accordion accordion = new Accordion();
|
||||
|
||||
if(dhdevice!=null)
|
||||
accordion.getPanes().add(new TitledPane("Configure D-H", new DhSettingsWidget(dhdevice.getChain().getLinks().get(linkIndex),dhdevice,externalListener)));
|
||||
accordion.getPanes().add(new TitledPane("Configure Link", new LinkConfigurationWidget(abstractLink.getLinkConfiguration(), device2.getFactory(),setpoint,manager)));
|
||||
|
||||
GridPane panel = new GridPane();
|
||||
|
||||
panel.getColumnConstraints().add(new ColumnConstraints(80)); // column 1 is 75 wide
|
||||
panel.getColumnConstraints().add(new ColumnConstraints(30)); // column 1 is 75 wide
|
||||
panel.getColumnConstraints().add(new ColumnConstraints(120)); // column 2 is 300 wide
|
||||
|
||||
|
||||
panel.add( del,
|
||||
0,
|
||||
0);
|
||||
panel.add( new Text("#"+linkIndex),
|
||||
1,
|
||||
0);
|
||||
panel.add( name,
|
||||
2,
|
||||
0);
|
||||
panel.add( setpoint,
|
||||
3,
|
||||
0);
|
||||
panel.add( accordion,
|
||||
2,
|
||||
1);
|
||||
|
||||
getChildren().add(panel);
|
||||
}
|
||||
|
||||
|
||||
public void changed(ObservableValue<? extends Boolean> observableValue,
|
||||
Boolean wasChanging,
|
||||
Boolean changing) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onJointSpaceUpdate(AbstractKinematicsNR source, double[] joints) {
|
||||
Platform.runLater(()->{
|
||||
try{
|
||||
setpoint.setValue(joints[linkIndex]);
|
||||
}catch(ArrayIndexOutOfBoundsException ex){
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onJointSpaceTargetUpdate(AbstractKinematicsNR source,
|
||||
double[] joints) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onJointSpaceLimit(AbstractKinematicsNR source, int axis,
|
||||
JointLimit event) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.neuronrobotics.bowlerstudio.creature;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import com.neuronrobotics.replicator.driver.NRPrinter;
|
||||
import com.neuronrobotics.replicator.driver.StateBasedControllerConfiguration;
|
||||
|
||||
public abstract class DeviceSettingsBase extends JPanel {
|
||||
|
||||
private NRPrinter printer;
|
||||
public DeviceSettingsBase(NRPrinter _printer){
|
||||
printer = _printer;
|
||||
|
||||
}
|
||||
public abstract StateBasedControllerConfiguration getStateBasedControllerSettings();
|
||||
|
||||
public abstract void setStateBasedControllerSettings(StateBasedControllerConfiguration _state);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,287 @@
|
||||
package com.neuronrobotics.bowlerstudio.creature;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import eu.mihosoft.vrl.v3d.STL;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.WatchEvent;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.BowlerStudioController;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
|
||||
import com.neuronrobotics.bowlerstudio.util.FileWatchDeviceWrapper;
|
||||
import com.neuronrobotics.nrconsole.util.FileSelectionFactory;
|
||||
import com.neuronrobotics.nrconsole.util.GroovyFilter;
|
||||
import com.neuronrobotics.nrconsole.util.XmlFilter;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.DHChain;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.DHLink;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.DHParameterKinematics;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.DhInverseSolver;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.IDriveEngine;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.LinkConfiguration;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.LinkFactory;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.MobileBase;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR;
|
||||
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
|
||||
import com.neuronrobotics.sdk.common.IDeviceConnectionEventListener;
|
||||
import com.neuronrobotics.sdk.common.Log;
|
||||
import com.neuronrobotics.sdk.util.IFileChangeListener;
|
||||
|
||||
import eu.mihosoft.vrl.v3d.CSG;
|
||||
import eu.mihosoft.vrl.v3d.Cube;
|
||||
import eu.mihosoft.vrl.v3d.Transform;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.control.Accordion;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
import javafx.scene.control.TitledPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.stage.FileChooser.ExtensionFilter;
|
||||
|
||||
public class DhChainWidget extends Group implements IDeviceConnectionEventListener{
|
||||
private File currentFile=null;
|
||||
private VBox links;
|
||||
private VBox controls;
|
||||
JogWidget jog = null;
|
||||
|
||||
private AbstractKinematicsNR device;
|
||||
private DHParameterKinematics dhdevice=null;
|
||||
private MobileBase mbase=null;
|
||||
private MobileBaseCadManager manager=null;
|
||||
private File kinematicsFile;
|
||||
|
||||
private ArrayList<DHLinkWidget> widgets = new ArrayList<>();
|
||||
private IOnEngineeringUnitsChange externalListener;
|
||||
public DhChainWidget(AbstractKinematicsNR device2,IOnEngineeringUnitsChange externalListener){
|
||||
this.device = device2;
|
||||
this.externalListener = externalListener;
|
||||
|
||||
device.addConnectionEventListener(this);
|
||||
if(DHParameterKinematics.class.isInstance(device2)){
|
||||
dhdevice=(DHParameterKinematics)device2;
|
||||
}
|
||||
if(MobileBase.class.isInstance(device2)){
|
||||
mbase=(MobileBase)device2;
|
||||
manager=MobileBaseCadManager.get(mbase);
|
||||
}
|
||||
links = new VBox(20);
|
||||
controls = new VBox(10);
|
||||
jog = new JogWidget(device);
|
||||
|
||||
VBox advanced = new VBox(10);
|
||||
|
||||
|
||||
|
||||
Button save = new Button("Save Configuration");
|
||||
Button add = new Button("Add Link");
|
||||
Button refresh = new Button("Generate CAD");
|
||||
Button kinematics = new Button("Set Kinematics");
|
||||
kinematics.setOnAction(event -> {
|
||||
new Thread(){
|
||||
|
||||
|
||||
|
||||
public void run(){
|
||||
if(getKinematicsFile()==null)
|
||||
setKinematicsFile(ScriptingEngine.getLastFile());
|
||||
setKinematicsFile(FileSelectionFactory.GetFile(getKinematicsFile(),
|
||||
new ExtensionFilter("Kinematics Script","*.groovy","*.java","*.txt")));
|
||||
|
||||
if (getKinematicsFile() == null) {
|
||||
return;
|
||||
}
|
||||
setKinematics();
|
||||
}
|
||||
}.start();
|
||||
});
|
||||
save.setOnAction(event -> {
|
||||
new Thread(){
|
||||
public void run(){
|
||||
File last = FileSelectionFactory.GetFile(currentFile==null?
|
||||
ScriptingEngine.getWorkspace():
|
||||
new File(ScriptingEngine.getWorkspace().getAbsolutePath()+"/"+currentFile.getName()),
|
||||
new ExtensionFilter("MobileBase XML","*.xml","*.XML"));
|
||||
if (last != null) {
|
||||
try {
|
||||
Files.write(Paths.get(last.getAbsolutePath()),device.getXml().getBytes() );
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
});
|
||||
add.setOnAction(event -> {
|
||||
LinkConfiguration newLink = new LinkConfiguration();
|
||||
if(dhdevice!=null)dhdevice.addNewLink(newLink,new DHLink(0, 0, 0, 0));
|
||||
onTabReOpening();
|
||||
});
|
||||
refresh.setOnAction(event -> {
|
||||
onTabReOpening();
|
||||
});
|
||||
|
||||
|
||||
advanced.getChildren().add(new TransformWidget("Base to Global",
|
||||
device.getFiducialToGlobalTransform(),new IOnTransformChange() {
|
||||
|
||||
@Override
|
||||
public void onTransformFinished(TransformNR newTrans) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransformChaging(TransformNR newTrans) {
|
||||
Log.debug("Base to Global"+newTrans.toString());
|
||||
device.setGlobalToFiducialTransform(newTrans);
|
||||
device.getCurrentTaskSpaceTransform();
|
||||
}
|
||||
}
|
||||
));
|
||||
|
||||
|
||||
advanced.getChildren().add(save);
|
||||
advanced.getChildren().add(add);
|
||||
advanced.getChildren().add(refresh);
|
||||
advanced.getChildren().add(kinematics);
|
||||
Accordion advancedPanel = new Accordion();
|
||||
advancedPanel.getPanes().add(new TitledPane("Advanced Options", advanced));
|
||||
controls.getChildren().add(jog);
|
||||
if(mbase==null){
|
||||
|
||||
controls.getChildren().add(advancedPanel);
|
||||
controls.getChildren().add(new TransformWidget("Place Limb",
|
||||
device.getRobotToFiducialTransform(), new IOnTransformChange() {
|
||||
|
||||
@Override
|
||||
public void onTransformFinished(TransformNR newTrans) {
|
||||
// Force a cad regeneration
|
||||
externalListener.onSliderDoneMoving(null, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransformChaging(TransformNR newTrans) {
|
||||
Log.debug("Limb to base"+newTrans.toString());
|
||||
device.setRobotToFiducialTransform(newTrans);
|
||||
device.getCurrentTaskSpaceTransform();
|
||||
//this calls the render update function attachec as the on jointspace update
|
||||
double[] joint=device2.getCurrentJointSpaceVector();
|
||||
dhdevice.getChain().getChain(joint);
|
||||
Platform.runLater(()->dhdevice.onJointSpaceUpdate(dhdevice, joint));
|
||||
}
|
||||
}
|
||||
));
|
||||
}else{
|
||||
controls.getChildren().add(kinematics);
|
||||
|
||||
}
|
||||
onTabReOpening();
|
||||
getChildren().add(new ScrollPane(links));
|
||||
}
|
||||
|
||||
private void setKinematics(){
|
||||
if(getKinematicsFile()!=null){
|
||||
try{
|
||||
if(mbase!=null){
|
||||
mbase.setWalkingDriveEngine( (IDriveEngine) ScriptingEngine.inlineFileScriptRun(getKinematicsFile(), null));
|
||||
}else if (dhdevice != null){
|
||||
dhdevice.setInverseSolver((DhInverseSolver) ScriptingEngine.inlineFileScriptRun(getKinematicsFile(), null));
|
||||
}
|
||||
}catch(Exception e){
|
||||
BowlerStudioController.highlightException(getKinematicsFile(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onTabReOpening() {
|
||||
for(DHLinkWidget wid:widgets){
|
||||
device.removeJointSpaceUpdateListener(wid);
|
||||
}
|
||||
widgets.clear();
|
||||
links.getChildren().clear();
|
||||
ArrayList<DHLink> dhLinks=null;
|
||||
if(dhdevice!=null)
|
||||
dhLinks = dhdevice.getChain().getLinks();
|
||||
links.getChildren().add(controls);
|
||||
|
||||
|
||||
for(int i=0;i<device.getFactory().getLinkConfigurations().size();i++){
|
||||
Log.warning("Adding Link Widget: "+i);
|
||||
|
||||
DHLink dh=null;
|
||||
if(dhdevice!=null)
|
||||
dh=dhLinks.get(i);
|
||||
Button del = new Button("Delete");
|
||||
final int linkIndex=i;
|
||||
del.setOnAction(event -> {
|
||||
LinkFactory factory =device.getFactory();
|
||||
//remove the link listener while the number of links could chnage
|
||||
factory.removeLinkListener(device);
|
||||
if(dhdevice!=null){
|
||||
DHChain chain = dhdevice.getDhChain() ;
|
||||
chain.getLinks().remove(linkIndex);
|
||||
factory.deleteLink(linkIndex);
|
||||
//set the modified kinematics chain
|
||||
dhdevice.setChain(chain);
|
||||
}else{
|
||||
factory.deleteLink(linkIndex);
|
||||
}
|
||||
|
||||
|
||||
//once the new link configuration is set up, re add the listener
|
||||
factory.addLinkListener(device);
|
||||
onTabReOpening();
|
||||
|
||||
});
|
||||
DHLinkWidget w = new DHLinkWidget(i,
|
||||
dh,
|
||||
device,
|
||||
del,
|
||||
externalListener,manager);
|
||||
widgets.add(w);
|
||||
links.getChildren().add(w);
|
||||
device.addJointSpaceListener(w);
|
||||
}
|
||||
//BowlerStudioController.setCsg(csg);
|
||||
jog.home();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public File getKinematicsFile() {
|
||||
return kinematicsFile;
|
||||
}
|
||||
|
||||
public void setKinematicsFile(File kinematicsFile) {
|
||||
FileWatchDeviceWrapper.watch(device, kinematicsFile, (fileThatChanged, event) -> {
|
||||
|
||||
try {
|
||||
setKinematics();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
});
|
||||
this.kinematicsFile = kinematicsFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnect(BowlerAbstractDevice source) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnect(BowlerAbstractDevice source) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.neuronrobotics.bowlerstudio.creature;
|
||||
|
||||
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
import javafx.scene.layout.GridPane;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.tabs.AbstractBowlerStudioTab;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.DHParameterKinematics;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.MobileBase;
|
||||
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
|
||||
import com.neuronrobotics.sdk.common.Log;
|
||||
|
||||
public class DhLab extends CreatureLab {
|
||||
|
||||
@Override
|
||||
public void initializeUI(BowlerAbstractDevice pm) {
|
||||
super.initializeUI(pm);
|
||||
setText("DH Lab");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package com.neuronrobotics.bowlerstudio.creature;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.Accordion;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.TitledPane;
|
||||
import javafx.scene.layout.ColumnConstraints;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.RowConstraints;
|
||||
import javafx.scene.text.Text;
|
||||
|
||||
import com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.DHLink;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.DHParameterKinematics;
|
||||
|
||||
|
||||
public class DhSettingsWidget extends javafx.scene.Group implements IOnEngineeringUnitsChange {
|
||||
|
||||
private DHLink dhLink;
|
||||
private EngineeringUnitsSliderWidget delta;
|
||||
private EngineeringUnitsSliderWidget theta;
|
||||
private EngineeringUnitsSliderWidget alpha;
|
||||
private EngineeringUnitsSliderWidget radius;
|
||||
private DHParameterKinematics device2;
|
||||
private IOnEngineeringUnitsChange externalListener;
|
||||
|
||||
public DhSettingsWidget(DHLink dhLink,DHParameterKinematics device2,IOnEngineeringUnitsChange externalListener ){
|
||||
this.dhLink = dhLink;
|
||||
this.device2 = device2;
|
||||
|
||||
this.externalListener = externalListener;
|
||||
|
||||
delta= new EngineeringUnitsSliderWidget(this,
|
||||
0,
|
||||
200,
|
||||
dhLink.getDelta(),
|
||||
180," mm ");
|
||||
|
||||
theta = new EngineeringUnitsSliderWidget(this,
|
||||
-180,
|
||||
180,
|
||||
Math.toDegrees(dhLink.getTheta()),
|
||||
180,"degrees");
|
||||
|
||||
|
||||
|
||||
radius= new EngineeringUnitsSliderWidget(this,
|
||||
0,
|
||||
200,
|
||||
dhLink.getRadius(),
|
||||
180," mm ");
|
||||
|
||||
alpha = new EngineeringUnitsSliderWidget(this,
|
||||
-180,
|
||||
180,
|
||||
Math.toDegrees(dhLink.getAlpha()),
|
||||
180,"degrees");
|
||||
|
||||
GridPane gridpane = new GridPane();
|
||||
gridpane.getColumnConstraints().add(new ColumnConstraints(120)); // column 1 is 75 wide
|
||||
gridpane.getColumnConstraints().add(new ColumnConstraints(320)); // column 2 is 300 wide
|
||||
gridpane.getColumnConstraints().add(new ColumnConstraints(100)); // column 2 is 100 wide
|
||||
gridpane.getRowConstraints().add(new RowConstraints(50)); //
|
||||
gridpane.getRowConstraints().add(new RowConstraints(50)); //
|
||||
gridpane.getRowConstraints().add(new RowConstraints(50)); //
|
||||
gridpane.getRowConstraints().add(new RowConstraints(50)); //
|
||||
gridpane.add(new Text("Delta (Height)"), 0, 0);
|
||||
gridpane.add(delta, 1, 0);
|
||||
gridpane.add(new Text("Radius (Length)"), 0, 1);
|
||||
gridpane.add(radius, 1, 1);
|
||||
|
||||
gridpane.getColumnConstraints().add(new ColumnConstraints(120)); // column 1 is 75 wide
|
||||
gridpane.getColumnConstraints().add(new ColumnConstraints(320)); // column 2 is 300 wide
|
||||
gridpane.getColumnConstraints().add(new ColumnConstraints(100)); // column 2 is 100 wide
|
||||
gridpane.getRowConstraints().add(new RowConstraints(50)); //
|
||||
gridpane.getRowConstraints().add(new RowConstraints(50)); //
|
||||
gridpane.add(new Text("Theta"), 0, 2);
|
||||
gridpane.add(theta, 1, 2);
|
||||
gridpane.add(new Text("Alpha"), 0, 3);
|
||||
gridpane.add(alpha, 1, 3);
|
||||
|
||||
getChildren().add(gridpane);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onSliderMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
|
||||
dhLink.setTheta(Math.toRadians(theta.getValue()));
|
||||
dhLink.setAlpha(Math.toRadians(alpha.getValue()));
|
||||
dhLink.setRadius(radius.getValue());
|
||||
dhLink.setDelta(delta.getValue());
|
||||
|
||||
if(externalListener!=null)
|
||||
externalListener.onSliderMoving(source, newAngleDegrees);
|
||||
//this calls the render update function attachec as the on jointspace update
|
||||
double[] joint=device2.getCurrentJointSpaceVector();
|
||||
device2.getChain().getChain(joint);
|
||||
Platform.runLater(()->device2.onJointSpaceUpdate(device2, joint));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSliderDoneMoving(EngineeringUnitsSliderWidget source,
|
||||
double newAngleDegrees) {
|
||||
// TODO Auto-generated method stub
|
||||
if(externalListener!=null)
|
||||
externalListener.onSliderDoneMoving(source, newAngleDegrees);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
package com.neuronrobotics.bowlerstudio.creature;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Slider;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.ColumnConstraints;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.text.Text;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class EngineeringUnitsSliderWidget extends GridPane implements ChangeListener<Number>{
|
||||
private TextField setpointValue;
|
||||
private Slider setpoint;
|
||||
private IOnEngineeringUnitsChange listener;
|
||||
private boolean intCast=false;
|
||||
private boolean allowResize=true;
|
||||
public EngineeringUnitsSliderWidget(IOnEngineeringUnitsChange listener,double min, double max, double current, double width, String units, boolean intCast){
|
||||
this(listener, min, max, current, width, units);
|
||||
this.intCast = intCast;
|
||||
}
|
||||
public EngineeringUnitsSliderWidget(IOnEngineeringUnitsChange listener, double current, double width, String units){
|
||||
this(listener, current/2, current*2, current, width, units);
|
||||
|
||||
}
|
||||
public EngineeringUnitsSliderWidget(IOnEngineeringUnitsChange listener, double min, double max, double current, double width, String units){
|
||||
this.setListener(listener);
|
||||
setpoint = new Slider();
|
||||
|
||||
if(min>max){
|
||||
double minStart = min;
|
||||
min=max;
|
||||
max=minStart;
|
||||
}
|
||||
if(min>current)
|
||||
min=current;
|
||||
if(max<current)
|
||||
max=current;
|
||||
double range = Math.abs(max-min);
|
||||
if(range<1){
|
||||
min=min-100;
|
||||
max = max+100;
|
||||
range=200;
|
||||
}
|
||||
setpoint.setMin(min);
|
||||
setpoint.setMax(max);
|
||||
setpoint.setValue(current);
|
||||
setpoint.setShowTickLabels(true);
|
||||
setpoint.setShowTickMarks(true);
|
||||
//setpoint.setSnapToTicks(true);
|
||||
setpoint.setMajorTickUnit(range);
|
||||
setpoint.setMinorTickCount(5);
|
||||
//setpoint.setBlockIncrement(range/100);
|
||||
setpointValue = new TextField(getFormatted(current));
|
||||
setpointValue.setOnAction(event -> {
|
||||
String txt =setpointValue.getText();
|
||||
double val =Double.parseDouble(txt);
|
||||
System.out.println("Setpoint Text changed to "+val);
|
||||
|
||||
Platform.runLater(() -> {
|
||||
setValueLocal(val);
|
||||
|
||||
getListener().onSliderMoving(this,val);
|
||||
getListener().onSliderDoneMoving(this,val);
|
||||
});
|
||||
});
|
||||
setpoint.setMaxWidth(width);
|
||||
setpoint.valueChangingProperty().addListener((ChangeListener<Boolean>) (observable, oldValue, newValue) -> {
|
||||
try {
|
||||
double val =Double.parseDouble(setpointValue.getText());
|
||||
System.err.println("Slider done moving = "+newValue);
|
||||
if(!newValue)
|
||||
getListener().onSliderDoneMoving(this,val);
|
||||
}catch(java.lang.NumberFormatException ex) {
|
||||
setValueLocal(0);
|
||||
return;
|
||||
}
|
||||
|
||||
});
|
||||
setpoint.valueProperty().addListener(this);
|
||||
|
||||
String unitsString = "("+units+")";
|
||||
getColumnConstraints().add(new ColumnConstraints(width+20)); // column 2 is 100 wide
|
||||
getColumnConstraints().add(new ColumnConstraints(100)); // column 2 is 100 wide
|
||||
getColumnConstraints().add(new ColumnConstraints(unitsString.length()*7)); // column 2 is 100 wide
|
||||
|
||||
|
||||
add( setpoint,
|
||||
0,
|
||||
0);
|
||||
add( setpointValue,
|
||||
1,
|
||||
0);
|
||||
add( new Text(unitsString),
|
||||
2,
|
||||
0);
|
||||
}
|
||||
public void setUpperBound(double newBound){
|
||||
setpoint.setMax(newBound);
|
||||
}
|
||||
public void setLowerBound(double newBound){
|
||||
setpoint.setMin(newBound);
|
||||
}
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends Number> observable,
|
||||
Number oldValue, Number newValue) {
|
||||
updateValue();
|
||||
}
|
||||
|
||||
private void updateValue(){
|
||||
Platform.runLater(() -> {
|
||||
setpointValue.setText(getFormatted(setpoint.getValue()));
|
||||
getListener().onSliderMoving(this,setpoint.getValue());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void setValue(double value){
|
||||
|
||||
Platform.runLater(() -> {
|
||||
setValueLocal(value);
|
||||
});
|
||||
|
||||
}
|
||||
private void setValueLocal(double value) {
|
||||
setpoint.valueProperty().removeListener(this);
|
||||
double val = value;
|
||||
if(val>setpoint.getMax()){
|
||||
if(isAllowResize())
|
||||
setpoint.setMax(val);
|
||||
else
|
||||
val=setpoint.getMax();
|
||||
}if(val<setpoint.getMin()){
|
||||
if(isAllowResize())
|
||||
setpoint.setMin(val);
|
||||
else
|
||||
val=setpoint.getMin();
|
||||
}
|
||||
double range = Math.abs(setpoint.getMax()-setpoint.getMin());
|
||||
setpoint.setMajorTickUnit(range);
|
||||
setpoint.setValue(val);
|
||||
setpointValue.setText(getFormatted(setpoint.getValue()));
|
||||
setpoint.valueProperty().addListener(this);
|
||||
//System.out.println("Setpoint changed to "+val);
|
||||
}
|
||||
|
||||
public double getValue(){
|
||||
return setpoint.getValue();
|
||||
}
|
||||
|
||||
public String getFormatted(double value){
|
||||
if(intCast)
|
||||
return String.valueOf((int)value);
|
||||
return String.format("%8.2f", (double)value);
|
||||
}
|
||||
public IOnEngineeringUnitsChange getListener() {
|
||||
if(listener==null)
|
||||
return new IOnEngineeringUnitsChange() {
|
||||
|
||||
@Override
|
||||
public void onSliderMoving(EngineeringUnitsSliderWidget source,
|
||||
double newAngleDegrees) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSliderDoneMoving(EngineeringUnitsSliderWidget source,
|
||||
double newAngleDegrees) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
return listener;
|
||||
}
|
||||
public void setListener(IOnEngineeringUnitsChange listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
public boolean isAllowResize() {
|
||||
return allowResize;
|
||||
}
|
||||
public void setAllowResize(boolean allowResize) {
|
||||
this.allowResize = allowResize;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.neuronrobotics.bowlerstudio.creature;
|
||||
|
||||
public interface IGameControllerUpdateListener {
|
||||
public void onControllerUpdate(AbstractGameController source);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.neuronrobotics.bowlerstudio.creature;
|
||||
|
||||
public interface IGistPromptCompletionListener {
|
||||
public void done(String gitsId, String file);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.neuronrobotics.bowlerstudio.creature;
|
||||
|
||||
public interface IOnEngineeringUnitsChange {
|
||||
public void onSliderMoving(EngineeringUnitsSliderWidget source,double newAngleDegrees);
|
||||
public void onSliderDoneMoving(EngineeringUnitsSliderWidget source,double newAngleDegrees);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.neuronrobotics.bowlerstudio.creature;
|
||||
|
||||
import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR;
|
||||
|
||||
public interface IOnTransformChange {
|
||||
public abstract void onTransformChaging(TransformNR newTrans);
|
||||
public abstract void onTransformFinished(TransformNR newTrans);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.neuronrobotics.bowlerstudio.creature;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.tabs.AbstractBowlerStudioTab;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR;
|
||||
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
|
||||
|
||||
public class JogKinematicsDevice extends AbstractBowlerStudioTab{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onTabClosing() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getMyNameSpaces() {
|
||||
// TODO Auto-generated method stub
|
||||
return new String[]{"bcs.cartesian.*"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeUI(BowlerAbstractDevice pm) {
|
||||
|
||||
setContent(new JogWidget((AbstractKinematicsNR) pm));
|
||||
setText("Jog Kinematics Devices");
|
||||
onTabReOpening();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabReOpening() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
package com.neuronrobotics.bowlerstudio.creature;
|
||||
/**
|
||||
* Sample Skeleton for "jogTrainerWidget.fxml" Controller Class
|
||||
* You can copy and paste this code into your favorite IDE
|
||||
**/
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
|
||||
import com.neuronrobotics.bowlerstudio.assets.ConfigurationDatabase;
|
||||
import com.neuronrobotics.sdk.addons.gamepad.BowlerJInputDevice;
|
||||
import com.neuronrobotics.sdk.addons.gamepad.IJInputEventListener;
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
import net.java.games.input.Component;
|
||||
import net.java.games.input.Event;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
|
||||
public class JogTrainerWidget extends Application implements IJInputEventListener {
|
||||
|
||||
@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="linkMinus"
|
||||
private ImageView linkMinus; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="linkPlus"
|
||||
private ImageView linkPlus; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="linkval"
|
||||
private TextField linkval; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="rotzMinus"
|
||||
private ImageView rotzMinus; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="rotzPlus"
|
||||
private ImageView rotzPlus; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="rzval"
|
||||
private TextField rzval; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="xminus"
|
||||
private ImageView xminus; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="xplus"
|
||||
private ImageView xplus; // Value injected by FXMLLoader
|
||||
|
||||
// WARNING: fx:id="xval" cannot be injected: several objects share the same fx:id;
|
||||
|
||||
@FXML // fx:id="yminus"
|
||||
private ImageView yminus; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="yplus"
|
||||
private ImageView yplus; // Value injected by FXMLLoader
|
||||
@FXML // fx:id="yval"
|
||||
private TextField xval; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="yval"
|
||||
private TextField yval; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="zminus"
|
||||
private ImageView zminus; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="zplus"
|
||||
private ImageView zplus; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="zval"
|
||||
private TextField zval; // Value injected by FXMLLoader
|
||||
|
||||
private Stage primaryStage;
|
||||
|
||||
private BowlerJInputDevice gameController;
|
||||
|
||||
private String paramsKey;
|
||||
private TextField selected=null;
|
||||
|
||||
public JogTrainerWidget(BowlerJInputDevice gameController) {
|
||||
this.gameController = gameController;
|
||||
paramsKey = gameController.getController().getName();
|
||||
gameController.addListeners(this);
|
||||
}
|
||||
// Handler for Button[Button[id=null, styleClass=button]] onAction
|
||||
@FXML
|
||||
void configure(ActionEvent event) {
|
||||
primaryStage.close();
|
||||
new Thread(()->{
|
||||
//linkval.setText((String) ConfigurationDatabase.getObject(paramsKey, "jogLink", "x"));
|
||||
ConfigurationDatabase.setObject(paramsKey, "jogLink", linkval.getText());
|
||||
// xval.setText((String) ConfigurationDatabase.getObject(paramsKey, "jogKinx", "x"));
|
||||
ConfigurationDatabase.setObject(paramsKey, "jogKinx", xval.getText());
|
||||
//yval.setText((String) ConfigurationDatabase.getObject(paramsKey, "jogKiny", "y"));
|
||||
ConfigurationDatabase.setObject(paramsKey, "jogKiny", yval.getText());
|
||||
//zval.setText((String) ConfigurationDatabase.getObject(paramsKey, "jogKinz", "rz"));
|
||||
ConfigurationDatabase.setObject(paramsKey, "jogKinz", zval.getText());
|
||||
//rzval.setText((String) ConfigurationDatabase.getObject(paramsKey, "jogKinslider", "slider"));
|
||||
ConfigurationDatabase.setObject(paramsKey, "jogKinslider", rzval.getText());
|
||||
ConfigurationDatabase.save();
|
||||
|
||||
}).start();
|
||||
|
||||
gameController.removeListeners(this);
|
||||
}
|
||||
@FXML
|
||||
void selectTraining(MouseEvent event) {
|
||||
if(TextField.class.isInstance(event.getSource()))
|
||||
selected = (TextField) event.getSource();
|
||||
}
|
||||
@SuppressWarnings("restriction")
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception
|
||||
{
|
||||
this.primaryStage = primaryStage;
|
||||
FXMLLoader loader = AssetFactory.loadLayout("layout/jogTrainerWidget.fxml", true);
|
||||
Parent root;
|
||||
loader.setController(this);
|
||||
// This is needed when loading on MAC
|
||||
loader.setClassLoader(getClass().getClassLoader());
|
||||
root = loader.load();
|
||||
Platform.runLater(() -> {
|
||||
primaryStage.setTitle("Configure the controller");
|
||||
|
||||
Scene scene = new Scene(root);
|
||||
primaryStage.setScene(scene);
|
||||
primaryStage.initModality(Modality.WINDOW_MODAL);
|
||||
primaryStage.setResizable(true);
|
||||
primaryStage.show();
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@FXML // This method is called by the FXMLLoader when initialization is complete
|
||||
void initialize() {
|
||||
assert linkMinus != null : "fx:id=\"linkMinus\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
|
||||
assert linkPlus != null : "fx:id=\"linkPlus\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
|
||||
assert linkval != null : "fx:id=\"linkval\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
|
||||
assert rotzMinus != null : "fx:id=\"rotzMinus\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
|
||||
assert rotzPlus != null : "fx:id=\"rotzPlus\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
|
||||
assert rzval != null : "fx:id=\"rzval\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
|
||||
assert xminus != null : "fx:id=\"xminus\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
|
||||
assert xplus != null : "fx:id=\"xplus\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
|
||||
assert yminus != null : "fx:id=\"yminus\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
|
||||
assert yplus != null : "fx:id=\"yplus\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
|
||||
assert yval != null : "fx:id=\"yval\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
|
||||
assert zminus != null : "fx:id=\"zminus\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
|
||||
assert zplus != null : "fx:id=\"zplus\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
|
||||
assert zval != null : "fx:id=\"zval\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
|
||||
|
||||
// Initialize your logic here: all @FXML variables will have been injected
|
||||
try {
|
||||
xplus.setImage(AssetFactory.loadAsset("Plus-X.png"));
|
||||
xminus.setImage(AssetFactory.loadAsset("Minus-X.png"));
|
||||
yplus.setImage(AssetFactory.loadAsset("Plus-Y.png"));
|
||||
yminus.setImage(AssetFactory.loadAsset("Minus-Y.png"));
|
||||
zplus.setImage(AssetFactory.loadAsset("Plus-Z.png"));
|
||||
zminus.setImage(AssetFactory.loadAsset("Minus-Z.png"));
|
||||
rotzPlus.setImage(AssetFactory.loadAsset("Rotation-Z.png"));
|
||||
rotzMinus.setImage(AssetFactory.loadAsset("Rotation-Neg-Z.png"));
|
||||
linkPlus.setImage(AssetFactory.loadAsset("Move-Single-Motor.png"));
|
||||
linkMinus.setImage(AssetFactory.loadAsset("Move-Single-Motor.png"));
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
Platform.runLater(()->{
|
||||
linkval.setText((String) ConfigurationDatabase.getObject(paramsKey, "jogLink", "x"));
|
||||
xval.setText((String) ConfigurationDatabase.getObject(paramsKey, "jogKinx", "x"));
|
||||
yval.setText((String) ConfigurationDatabase.getObject(paramsKey, "jogKiny", "y"));
|
||||
zval.setText((String) ConfigurationDatabase.getObject(paramsKey, "jogKinz", "rz"));
|
||||
rzval.setText((String) ConfigurationDatabase.getObject(paramsKey, "jogKinslider", "slider"));
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
@Override
|
||||
public void onEvent(Component arg0, Event arg1, float value, String arg3) {
|
||||
if(Math.abs(value)>0.75 && selected!=null){
|
||||
Platform.runLater(()->selected.setText(arg0.getName()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,548 @@
|
||||
package com.neuronrobotics.bowlerstudio.creature;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.ConnectionManager;
|
||||
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
|
||||
import com.neuronrobotics.bowlerstudio.assets.ConfigurationDatabase;
|
||||
import com.neuronrobotics.sdk.addons.gamepad.BowlerJInputDevice;
|
||||
import com.neuronrobotics.sdk.addons.gamepad.IJInputEventListener;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.DHParameterKinematics;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.ITaskSpaceUpdateListenerNR;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.MobileBase;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.math.RotationNR;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR;
|
||||
import com.neuronrobotics.sdk.common.DeviceManager;
|
||||
import com.neuronrobotics.sdk.common.Log;
|
||||
import com.neuronrobotics.sdk.util.ThreadUtil;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.ColumnConstraints;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.RowConstraints;
|
||||
import javafx.stage.Stage;
|
||||
import net.java.games.input.Component;
|
||||
import net.java.games.input.Controller;
|
||||
import org.reactfx.util.FxTimer;
|
||||
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import javax.management.RuntimeErrorException;
|
||||
|
||||
public class JogWidget extends GridPane implements ITaskSpaceUpdateListenerNR, IOnTransformChange,IJInputEventListener {
|
||||
double defauletSpeed=0.05;
|
||||
private AbstractKinematicsNR kin;
|
||||
private MobileBase mobilebase=null;
|
||||
Button px = new Button("", AssetFactory.loadIcon("Plus-X.png"));
|
||||
Button nx = new Button("",AssetFactory.loadIcon("Minus-X.png"));
|
||||
Button py = new Button("",AssetFactory.loadIcon("Plus-Y.png"));
|
||||
Button ny = new Button("",AssetFactory.loadIcon("Minus-Y.png"));
|
||||
Button pz = new Button("",AssetFactory.loadIcon("Plus-Z.png"));
|
||||
Button nz = new Button("",AssetFactory.loadIcon("Minus-Z.png"));
|
||||
Button home = new Button("",AssetFactory.loadIcon("Home.png"));
|
||||
Button game = new Button("Add Game Controller",AssetFactory.loadIcon("Add-Game-Controller.png"));
|
||||
Button conf = new Button("Configure...",AssetFactory.loadIcon("Configure-Game-Controller.png"));
|
||||
TextField increment=new TextField(Double.toString(defauletSpeed));
|
||||
TextField sec=new TextField("0.01");
|
||||
private TransformWidget transform;
|
||||
private BowlerJInputDevice gameController=null;
|
||||
double x,y,rz,slider=0;
|
||||
private boolean stop=true;
|
||||
private jogThread jogTHreadHandle;
|
||||
private String paramsKey;
|
||||
private GridPane buttons;
|
||||
private static ArrayList<JogWidget> allWidgets=new ArrayList<JogWidget>();
|
||||
|
||||
public JogWidget(AbstractKinematicsNR kinimatics){
|
||||
allWidgets.add(this);
|
||||
this.setKin(kinimatics);
|
||||
|
||||
if(MobileBase.class.isInstance(kinimatics)){
|
||||
py = new Button("",AssetFactory.loadIcon("Rotation-Z.png"));
|
||||
ny = new Button("",AssetFactory.loadIcon("Rotation-Neg-Z.png"));
|
||||
|
||||
}
|
||||
|
||||
getKin().addPoseUpdateListener(this);
|
||||
|
||||
|
||||
px.setOnMousePressed( event -> {try {handle( (Button)event.getSource()); }catch(Throwable T) {T.printStackTrace();}});
|
||||
nx.setOnMousePressed( event ->{try { handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
|
||||
py.setOnMousePressed( event ->{try { handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
|
||||
ny.setOnMousePressed( event -> {try {handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
|
||||
pz.setOnMousePressed( event -> {try {handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
|
||||
nz.setOnMousePressed( event -> {try {handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
|
||||
home.setOnMousePressed( event -> {try {handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
|
||||
|
||||
px.setOnMouseReleased( event -> {try {handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
|
||||
nx.setOnMouseReleased( event -> {try {handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
|
||||
py.setOnMouseReleased( event -> {try {handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
|
||||
ny.setOnMouseReleased( event -> {try {handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
|
||||
pz.setOnMouseReleased( event -> {try {handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
|
||||
nz.setOnMouseReleased( event -> {try {handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
|
||||
home.setOnMouseReleased( event -> {try {handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
|
||||
game.setOnAction(event -> {
|
||||
if(getGameController() == null){
|
||||
setGameController((BowlerJInputDevice) DeviceManager.getSpecificDevice(BowlerJInputDevice.class, "jogController"));
|
||||
if(getGameController()==null){
|
||||
ConnectionManager.onConnectGamePad("jogController");
|
||||
setGameController((BowlerJInputDevice) DeviceManager.getSpecificDevice(BowlerJInputDevice.class, "jogController"));
|
||||
}
|
||||
|
||||
}else{
|
||||
RemoveGameController();
|
||||
}
|
||||
});
|
||||
conf.setOnAction(event -> {
|
||||
if(getGameController() != null){
|
||||
runControllerMap();
|
||||
}
|
||||
});
|
||||
|
||||
buttons = new GridPane();
|
||||
buttons.getColumnConstraints().add(new ColumnConstraints(80)); // column 1 is 75 wide
|
||||
buttons.getColumnConstraints().add(new ColumnConstraints(80)); // column 2 is 300 wide
|
||||
buttons.getColumnConstraints().add(new ColumnConstraints(80)); // column 2 is 100 wide
|
||||
|
||||
buttons.getRowConstraints().add(new RowConstraints(40)); //
|
||||
buttons. getRowConstraints().add(new RowConstraints(40)); //
|
||||
buttons. getRowConstraints().add(new RowConstraints(40)); //
|
||||
buttons.getRowConstraints().add(new RowConstraints(40)); //
|
||||
|
||||
buttons.add( py,
|
||||
0,
|
||||
1);
|
||||
buttons.add( home,
|
||||
1,
|
||||
1);
|
||||
buttons.add( ny,
|
||||
2,
|
||||
1);
|
||||
|
||||
|
||||
buttons.add( px,
|
||||
1,
|
||||
0);
|
||||
|
||||
buttons.add( nx,
|
||||
1,
|
||||
2);
|
||||
buttons.add( increment,
|
||||
0,
|
||||
3);
|
||||
buttons.add( new Label("m/s"),
|
||||
1,
|
||||
3);
|
||||
|
||||
buttons.add( sec,
|
||||
2,
|
||||
3);
|
||||
buttons.add( new Label("sec"),
|
||||
3,
|
||||
3);
|
||||
if(!MobileBase.class.isInstance(kinimatics)){
|
||||
buttons.add( pz,
|
||||
3,
|
||||
0);
|
||||
buttons.add( nz,
|
||||
3,
|
||||
1);
|
||||
}
|
||||
|
||||
add( buttons,
|
||||
0,
|
||||
0);
|
||||
setTransform(new TransformWidget("Current Pose", getKin().getCurrentPoseTarget(), this));
|
||||
Accordion advancedPanel = new Accordion();
|
||||
advancedPanel.getPanes().add(new TitledPane("Current Position", getTransform()));
|
||||
add( advancedPanel,
|
||||
0,
|
||||
1);
|
||||
jogTHreadHandle = new jogThread();
|
||||
jogTHreadHandle.start();
|
||||
controllerLoop();
|
||||
|
||||
}
|
||||
|
||||
private BowlerJInputDevice RemoveGameController() {
|
||||
BowlerJInputDevice stale = getGameController();
|
||||
getGameController().removeListeners(this);
|
||||
game.setText("Add Game Controller");
|
||||
setGameController(null);
|
||||
return stale;
|
||||
}
|
||||
|
||||
private void handle(final Button button ){
|
||||
|
||||
if(!button.isPressed()){
|
||||
// button released
|
||||
//Log.info(button.getText()+" Button released ");
|
||||
try {
|
||||
TransformNR t = getKin().getCurrentTaskSpaceTransform();
|
||||
getKin().setDesiredTaskSpaceTransform(t, 0);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(button == px){
|
||||
x=0;
|
||||
}
|
||||
if(button == nx){
|
||||
x=0;
|
||||
}
|
||||
if(mobilebase==null){
|
||||
if(button == py){
|
||||
y=0;
|
||||
}
|
||||
if(button == ny){
|
||||
y=0;
|
||||
}
|
||||
}else{
|
||||
if(button == py){
|
||||
rz=0;
|
||||
}
|
||||
if(button == ny){
|
||||
rz=0;
|
||||
}
|
||||
}
|
||||
if(button == pz){
|
||||
slider=0;
|
||||
}
|
||||
if(button == nz){
|
||||
slider=0;
|
||||
}
|
||||
stop=true;
|
||||
return;
|
||||
}else{
|
||||
Log.warning(button.getText()+" Button pressed ");
|
||||
}
|
||||
if(button == px){
|
||||
x=1;
|
||||
}
|
||||
if(button == nx){
|
||||
x=-1;
|
||||
}
|
||||
if(mobilebase==null){
|
||||
if(button == py){
|
||||
y=1;
|
||||
}
|
||||
if(button == ny){
|
||||
y=-1;
|
||||
}
|
||||
}else{
|
||||
if(button == py){
|
||||
rz=1;
|
||||
}
|
||||
if(button == ny){
|
||||
rz=-1;
|
||||
}
|
||||
}
|
||||
if(button == pz){
|
||||
slider=1;
|
||||
}
|
||||
if(button == nz){
|
||||
slider=-1;
|
||||
}
|
||||
if(button == home){
|
||||
home();
|
||||
stop=true;
|
||||
return;
|
||||
}
|
||||
stop=false;
|
||||
controllerLoop();
|
||||
}
|
||||
|
||||
public void home(){
|
||||
|
||||
if(getMobilebase()!=null){
|
||||
getMobilebase().setGlobalToFiducialTransform(new TransformNR());
|
||||
for(DHParameterKinematics c:getMobilebase().getAllDHChains()){
|
||||
homeLimb(c);
|
||||
}
|
||||
}else{
|
||||
homeLimb(getKin());
|
||||
}
|
||||
}
|
||||
|
||||
private void homeLimb(AbstractKinematicsNR c) {
|
||||
double[] joints = c.getCurrentJointSpaceVector();
|
||||
for (int i = 0; i < c.getNumberOfLinks(); i++) {
|
||||
joints[i] = 0;
|
||||
}
|
||||
try {
|
||||
c.setDesiredJointSpaceVector(joints, 0);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTaskSpaceUpdate(AbstractKinematicsNR source, TransformNR pose) {
|
||||
// TODO Auto-generated method stub
|
||||
if(pose != null &&getTransform()!=null)
|
||||
Platform.runLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
getTransform().updatePose(pose);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTargetTaskSpaceUpdate(AbstractKinematicsNR source,
|
||||
TransformNR pose) {
|
||||
if(pose != null &&getTransform()!=null)
|
||||
Platform.runLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
getTransform().updatePose(pose);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransformChaging(TransformNR newTrans) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
@Override
|
||||
public void onTransformFinished(TransformNR newTrans) {
|
||||
try {
|
||||
getKin().setDesiredTaskSpaceTransform(newTrans, Double.parseDouble(sec.getText()));
|
||||
} catch (NumberFormatException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
public AbstractKinematicsNR getKin() {
|
||||
|
||||
return kin;
|
||||
}
|
||||
public void setKin(AbstractKinematicsNR kin) {
|
||||
if(!kin.isAvailable())
|
||||
kin.connect();
|
||||
if(MobileBase.class.isInstance(kin))
|
||||
setMobilebase((MobileBase)kin);
|
||||
this.kin = kin;
|
||||
try {
|
||||
kin.setDesiredTaskSpaceTransform( kin.calcHome(),0);
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
|
||||
|
||||
private void controllerLoop(){
|
||||
//System.out.println("controllerLoop");
|
||||
double seconds=.1;
|
||||
if(getGameController()!=null || stop==false){
|
||||
try{
|
||||
seconds =Double.parseDouble(sec.getText());
|
||||
if(!stop){
|
||||
|
||||
|
||||
double inc;
|
||||
try{
|
||||
inc = Double.parseDouble(increment.getText())*1000*seconds;//convert to mm
|
||||
|
||||
}catch(Exception e){
|
||||
inc=defauletSpeed;
|
||||
Platform.runLater(() -> {
|
||||
try{
|
||||
increment.setText(Double.toString(defauletSpeed));
|
||||
}catch(Exception ex){
|
||||
ex.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
//double rxl=0;
|
||||
double ryl=inc/20*slider;
|
||||
double rzl=inc/2*rz;
|
||||
TransformNR current = new TransformNR(0,0,0,new RotationNR( 0,rzl, 0));
|
||||
current.translateX(inc*x);
|
||||
current.translateY(inc*y);
|
||||
current.translateZ(inc*slider);
|
||||
|
||||
try {
|
||||
if(getMobilebase()==null){
|
||||
current = getKin().getCurrentPoseTarget();
|
||||
current.translateX(inc*x);
|
||||
current.translateY(inc*y);
|
||||
current.translateZ(inc*slider);
|
||||
current.setRotation(new RotationNR());
|
||||
TransformNR toSet = current.copy();
|
||||
double toSeconds=seconds;
|
||||
jogTHreadHandle.setToSet(toSet, toSeconds);
|
||||
//Log.enableDebugPrint();
|
||||
//System.out.println("Loop Jogging to: "+toSet);
|
||||
}else{
|
||||
TransformNR toSet = current.copy();
|
||||
double toSeconds=seconds;
|
||||
jogTHreadHandle.setToSet(toSet, toSeconds);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(seconds<.01){
|
||||
seconds=.01;
|
||||
sec.setText(".01");
|
||||
}
|
||||
FxTimer.runLater(
|
||||
Duration.ofMillis((int)(seconds*1000.0)) ,new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
controllerLoop();
|
||||
//System.out.println("Controller loop!");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private class jogThread extends Thread{
|
||||
private boolean controlThreadRunning=false;
|
||||
private TransformNR toSet;
|
||||
private double toSeconds=.016;
|
||||
public void run(){
|
||||
setName("Jog Widget Set Drive Arc Command "+getKin().getScriptingName());
|
||||
while(kin.isAvailable()){
|
||||
//System.out.println("Jog loop");
|
||||
if(controlThreadRunning){
|
||||
if(getMobilebase()==null){
|
||||
try {
|
||||
//Log.enableDebugPrint();
|
||||
//System.out.println("Jogging to: "+toSet);
|
||||
getKin().setDesiredTaskSpaceTransform(toSet, toSeconds);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
//BowlerStudioController.highlightException(null, e);
|
||||
}
|
||||
}else{
|
||||
//toSet.setZ(0);
|
||||
try {
|
||||
getMobilebase().DriveArc(toSet, toSeconds);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
//BowlerStudioController.highlightException(null, e);
|
||||
}
|
||||
}
|
||||
controlThreadRunning=false;
|
||||
}
|
||||
ThreadUtil.wait((int) (toSeconds*1000));
|
||||
}
|
||||
new RuntimeException("Jog thread finished").printStackTrace();
|
||||
}
|
||||
|
||||
public void setToSet(TransformNR toSet,double toSeconds) {
|
||||
this.toSet = toSet.copy();
|
||||
this.toSeconds = toSeconds;
|
||||
controlThreadRunning=true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onEvent(Component comp, net.java.games.input.Event event,
|
||||
float value, String eventString) {
|
||||
|
||||
if(comp.getName().toLowerCase().contentEquals((String) ConfigurationDatabase.getObject(paramsKey, "jogKiny", "y")))
|
||||
x=value;
|
||||
if(comp.getName().toLowerCase().contentEquals((String) ConfigurationDatabase.getObject(paramsKey, "jogKinz", "rz")))
|
||||
y=value;
|
||||
if(comp.getName().toLowerCase().contentEquals((String) ConfigurationDatabase.getObject(paramsKey, "jogKinx", "x")))
|
||||
rz=-value;
|
||||
if(comp.getName().toLowerCase().contentEquals((String) ConfigurationDatabase.getObject(paramsKey, "jogKinslider", "slider")))
|
||||
slider=-value;
|
||||
if(Math.abs(x)<.01)
|
||||
x=0;
|
||||
if(Math.abs(y)<.01)
|
||||
y=0;
|
||||
if(Math.abs(rz)<.01)
|
||||
rz=0;
|
||||
if(Math.abs(slider)<.01)
|
||||
slider=0;
|
||||
if(x==0.0&&y==0.0 &&rz==0.0&&slider==0) {
|
||||
//System.out.println("Stoping on="+comp.getName());
|
||||
stop=true;
|
||||
try {
|
||||
getKin().setDesiredTaskSpaceTransform(getKin().getCurrentTaskSpaceTransform(), 0);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}else
|
||||
stop=false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public MobileBase getMobilebase() {
|
||||
return mobilebase;
|
||||
}
|
||||
|
||||
public void setMobilebase(MobileBase mobilebase) {
|
||||
this.mobilebase = mobilebase;
|
||||
}
|
||||
|
||||
public BowlerJInputDevice getGameController() {
|
||||
return gameController;
|
||||
}
|
||||
|
||||
public void setGameController(BowlerJInputDevice gameController) {
|
||||
this.gameController = gameController;
|
||||
if(gameController!=null){
|
||||
getGameController().clearListeners();
|
||||
getGameController().addListeners(this);
|
||||
game.setText("Remove Game Controller");
|
||||
controllerLoop();
|
||||
Controller hwController = gameController.getController();
|
||||
paramsKey = hwController.getName();
|
||||
HashMap<String, Object> map = ConfigurationDatabase.getParamMap(paramsKey);
|
||||
boolean hasmap = false;
|
||||
if(map.containsKey("jogKinx")&&
|
||||
map.containsKey("jogKiny") &&
|
||||
map.containsKey("jogKinz") &&
|
||||
map.containsKey("jogKinslider")
|
||||
){
|
||||
hasmap=true;
|
||||
}
|
||||
|
||||
if(!hasmap){
|
||||
runControllerMap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void runControllerMap() {
|
||||
Stage s = new Stage();
|
||||
new Thread(){
|
||||
public void run(){
|
||||
JogTrainerWidget controller = new JogTrainerWidget(gameController);
|
||||
try {
|
||||
controller.start( s);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
public TransformWidget getTransform() {
|
||||
return transform;
|
||||
}
|
||||
|
||||
public void setTransform(TransformWidget transform) {
|
||||
this.transform = transform;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,625 @@
|
||||
package com.neuronrobotics.bowlerstudio.creature;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.kohsuke.github.GHRepository;
|
||||
import org.kohsuke.github.GitHub;
|
||||
import org.reactfx.util.FxTimer;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.BowlerStudio;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.PasswordManager;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
|
||||
import com.neuronrobotics.bowlerstudio.vitamins.Vitamins;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.AbstractLink;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.LinkConfiguration;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.LinkFactory;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.LinkType;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Alert.AlertType;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.TextInputDialog;
|
||||
import javafx.scene.layout.ColumnConstraints;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.text.Text;
|
||||
import java.time.Duration;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class LinkConfigurationWidget extends GridPane {
|
||||
|
||||
// private int index;
|
||||
private LinkConfiguration conf;
|
||||
private EngineeringUnitsSliderWidget zero;
|
||||
private EngineeringUnitsSliderWidget lowerBound;
|
||||
private EngineeringUnitsSliderWidget upperBound;
|
||||
private AbstractLink activLink;
|
||||
private MobileBaseCadManager manager;
|
||||
private EngineeringUnitsSliderWidget setpointSLider;
|
||||
|
||||
double textToNum(TextField mass) {
|
||||
try {
|
||||
return Double.parseDouble(mass.getText().trim());
|
||||
} catch (Throwable t) {
|
||||
mass.setText("0");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public LinkConfigurationWidget(LinkConfiguration congiuration, LinkFactory factory,
|
||||
EngineeringUnitsSliderWidget slide, MobileBaseCadManager manager) {
|
||||
// this.index = index;
|
||||
// this.congiuration = congiuration;
|
||||
conf = congiuration;
|
||||
this.setpointSLider = slide;
|
||||
this.manager = manager;
|
||||
activLink = factory.getLink(conf);
|
||||
getColumnConstraints().add(new ColumnConstraints(150)); // column 1 is 75 wide
|
||||
getColumnConstraints().add(new ColumnConstraints(200)); // column 2 is 300 wide
|
||||
getColumnConstraints().add(new ColumnConstraints(200)); // column 2 is 300 wide
|
||||
setHgap(20);
|
||||
|
||||
TextField mass = new TextField(CreatureLab.getFormatted(conf.getMassKg()));
|
||||
mass.setOnAction(event -> {
|
||||
conf.setMassKg(textToNum(mass));
|
||||
activLink.setTargetEngineeringUnits(0);
|
||||
activLink.flush(0);
|
||||
if (manager != null)
|
||||
manager.generateCad();
|
||||
});
|
||||
TransformNR currentCentroid = conf.getCenterOfMassFromCentroid();
|
||||
TextField massx = new TextField(CreatureLab.getFormatted(currentCentroid.getX()));
|
||||
massx.setOnAction(event -> {
|
||||
currentCentroid.setX(textToNum(massx));
|
||||
conf.setCenterOfMassFromCentroid(currentCentroid);
|
||||
;
|
||||
activLink.setTargetEngineeringUnits(0);
|
||||
activLink.flush(0);
|
||||
if (manager != null)
|
||||
manager.generateCad();
|
||||
|
||||
});
|
||||
|
||||
TextField massy = new TextField(CreatureLab.getFormatted(currentCentroid.getY()));
|
||||
massy.setOnAction(event -> {
|
||||
currentCentroid.setY(textToNum(massy));
|
||||
conf.setCenterOfMassFromCentroid(currentCentroid);
|
||||
;
|
||||
activLink.setTargetEngineeringUnits(0);
|
||||
activLink.flush(0);
|
||||
if (manager != null)
|
||||
manager.generateCad();
|
||||
|
||||
});
|
||||
|
||||
TextField massz = new TextField(CreatureLab.getFormatted(currentCentroid.getZ()));
|
||||
massz.setOnAction(event -> {
|
||||
currentCentroid.setZ(textToNum(massz));
|
||||
conf.setCenterOfMassFromCentroid(currentCentroid);
|
||||
;
|
||||
activLink.setTargetEngineeringUnits(0);
|
||||
activLink.flush(0);
|
||||
if (manager != null)
|
||||
manager.generateCad();
|
||||
|
||||
});
|
||||
|
||||
TextField scale = new TextField(CreatureLab.getFormatted(conf.getScale()));
|
||||
scale.setOnAction(event -> {
|
||||
conf.setScale(textToNum(scale));
|
||||
activLink.setTargetEngineeringUnits(0);
|
||||
activLink.flush(0);
|
||||
if (manager != null)
|
||||
manager.generateCad();
|
||||
|
||||
});
|
||||
Button editShaft = new Button("Edit " + conf.getShaftSize());
|
||||
editShaft.setOnAction(event -> {
|
||||
new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
String type = conf.getShaftType();
|
||||
String id = conf.getShaftSize();
|
||||
edit(type, id, Vitamins.getConfiguration(type, id));
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
|
||||
});
|
||||
Button newShaft = new Button("New " + conf.getShaftType());
|
||||
newShaft.setOnAction(event -> {
|
||||
TextInputDialog d = new TextInputDialog("NewSize");
|
||||
d.setTitle("Wizard for new " + conf.getShaftType());
|
||||
d.setHeaderText("Enter th Side ID for a new " + conf.getShaftType());
|
||||
d.setContentText("Size:");
|
||||
|
||||
// Traditional way to get the response value.
|
||||
Optional<String> result = d.showAndWait();
|
||||
if (result.isPresent()) {
|
||||
// Create the custom dialog.
|
||||
String id = result.get();
|
||||
String type = conf.getShaftType();
|
||||
|
||||
new Thread() {
|
||||
public void run() {
|
||||
|
||||
try {
|
||||
test(type);
|
||||
Vitamins.newVitamin(id, type);
|
||||
edit(type, id, Vitamins.getConfiguration(type, conf.getShaftSize()));
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
Button newHardware = new Button("New " + conf.getElectroMechanicalType());
|
||||
|
||||
Button editHardware = new Button("Edit " + conf.getElectroMechanicalSize());
|
||||
final ComboBox<String> shaftSize = new ComboBox<>();
|
||||
final ComboBox<String> shaftType = new ComboBox<>();
|
||||
for (String s : Vitamins.listVitaminSizes(conf.getShaftType())) {
|
||||
shaftSize.getItems().add(s);
|
||||
}
|
||||
shaftSize.setOnAction(event -> {
|
||||
String motorsize = shaftSize.getSelectionModel().getSelectedItem();
|
||||
String motortype = shaftType.getSelectionModel().getSelectedItem();
|
||||
if (motorsize == null || motortype == null)
|
||||
return;
|
||||
conf.setShaftSize(motorsize);
|
||||
conf.setShaftType(motortype);
|
||||
setShaftSize(editShaft, newShaft, motorsize);
|
||||
if (manager != null)
|
||||
manager.generateCad();
|
||||
|
||||
});
|
||||
shaftSize.getSelectionModel().select(conf.getShaftSize());
|
||||
|
||||
for (String vitaminsType : Vitamins.listVitaminTypes()) {
|
||||
HashMap<String, Object> meta = Vitamins.getMeta(vitaminsType);
|
||||
if (meta != null && meta.containsKey("shaft"))
|
||||
shaftType.getItems().add(vitaminsType);
|
||||
}
|
||||
|
||||
shaftType.setOnAction(event -> {
|
||||
String selectedItem = shaftType.getSelectionModel().getSelectedItem();
|
||||
setShaftType(editShaft, newShaft, shaftSize, selectedItem);
|
||||
});
|
||||
shaftType.getSelectionModel().select(conf.getShaftType());
|
||||
final ComboBox<String> emHardwareType = new ComboBox<>();
|
||||
final ComboBox<String> emHardwareSize = new ComboBox<>();
|
||||
for (String s : Vitamins.listVitaminSizes(conf.getElectroMechanicalType())) {
|
||||
emHardwareSize.getItems().add(s);
|
||||
}
|
||||
emHardwareSize.setOnAction(new EventHandler<ActionEvent>() {
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
String motortype = emHardwareType.getSelectionModel().getSelectedItem();
|
||||
String motorsize = emHardwareSize.getSelectionModel().getSelectedItem();
|
||||
if (motorsize == null || motortype == null)
|
||||
return;
|
||||
conf.setElectroMechanicalType(motortype);
|
||||
conf.setElectroMechanicalSize(motorsize);
|
||||
newHardware.setText("New " + conf.getElectroMechanicalType());
|
||||
editHardware.setText("Edit " + conf.getElectroMechanicalSize());
|
||||
HashMap<String, Object> vitaminData = Vitamins.getConfiguration(conf.getElectroMechanicalType(),
|
||||
conf.getElectroMechanicalSize());
|
||||
System.out.println("New size " + vitaminData);
|
||||
String shafttype = (String) vitaminData.get("shaftType");
|
||||
String shaftsize = (String) vitaminData.get("shaftSize");
|
||||
|
||||
Platform.runLater(() -> {
|
||||
setShaftType(editShaft, newShaft, shaftSize, shafttype);
|
||||
FxTimer.runLater(Duration.ofMillis(20), () -> {
|
||||
setShaftSize(editShaft, newShaft, shaftsize);
|
||||
FxTimer.runLater(Duration.ofMillis(200), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
System.out.println("Settting shaft size: " + shaftsize + " of " + shafttype);
|
||||
|
||||
Platform.runLater(() -> shaftType.getSelectionModel().select(shafttype));
|
||||
Platform.runLater(() -> shaftSize.getSelectionModel().select(shaftsize));
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
conf.setShaftSize(shaftsize);
|
||||
conf.setShaftType(shafttype);
|
||||
if (manager != null)
|
||||
manager.generateCad();
|
||||
|
||||
}
|
||||
});
|
||||
emHardwareSize.getSelectionModel().select(conf.getElectroMechanicalSize());
|
||||
|
||||
for (String vitaminsType : Vitamins.listVitaminTypes()) {
|
||||
HashMap<String, Object> meta = Vitamins.getMeta(vitaminsType);
|
||||
if (meta != null && meta.containsKey("actuator"))
|
||||
emHardwareType.getItems().add(vitaminsType);
|
||||
}
|
||||
emHardwareType.setOnAction(event -> {
|
||||
String selectedItem = emHardwareType.getSelectionModel().getSelectedItem();
|
||||
if (selectedItem == null)
|
||||
return;
|
||||
System.out.println("New hwType " + selectedItem);
|
||||
|
||||
emHardwareSize.getItems().clear();
|
||||
for (String s : Vitamins.listVitaminSizes(selectedItem)) {
|
||||
emHardwareSize.getItems().add(s);
|
||||
}
|
||||
newHardware.setText("New " + conf.getElectroMechanicalType());
|
||||
editHardware.setText("Edit " + conf.getElectroMechanicalSize());
|
||||
|
||||
});
|
||||
emHardwareType.getSelectionModel().select(conf.getElectroMechanicalType());
|
||||
|
||||
// Actuator editing
|
||||
|
||||
editHardware.setOnAction(event -> {
|
||||
new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
String type = conf.getElectroMechanicalType();
|
||||
String id = conf.getElectroMechanicalSize();
|
||||
edit(type, id, Vitamins.getConfiguration(type, id));
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
|
||||
});
|
||||
newHardware.setOnAction(event -> {
|
||||
TextInputDialog d = new TextInputDialog("NewSize");
|
||||
d.setTitle("Wizard for new " + conf.getElectroMechanicalType());
|
||||
d.setHeaderText("Enter th Side ID for a new " + conf.getElectroMechanicalType());
|
||||
d.setContentText("Size:");
|
||||
|
||||
// Traditional way to get the response value.
|
||||
Optional<String> result = d.showAndWait();
|
||||
if (result.isPresent()) {
|
||||
// Create the custom dialog.
|
||||
String id = result.get();
|
||||
String type = conf.getElectroMechanicalType();
|
||||
|
||||
new Thread() {
|
||||
public void run() {
|
||||
|
||||
try {
|
||||
test(type);
|
||||
Vitamins.newVitamin(id, type);
|
||||
edit(type, id, Vitamins.getConfiguration(type, conf.getElectroMechanicalSize()));
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
TextField deviceName = new TextField(congiuration.getDeviceScriptingName());
|
||||
deviceName.setOnAction(event -> {
|
||||
conf.setDeviceScriptingName(deviceName.getText());
|
||||
factory.refreshHardwareLayer(conf);
|
||||
activLink = factory.getLink(conf);
|
||||
System.out.println("Link device to " + conf.getDeviceScriptingName());
|
||||
if (manager != null)
|
||||
manager.generateCad();
|
||||
|
||||
});
|
||||
|
||||
add(new Text("Scale To Degrees "), 0, 0);
|
||||
add(scale, 1, 0);
|
||||
add(new Text("(unitless)"), 2, 0);
|
||||
|
||||
lowerBound = new EngineeringUnitsSliderWidget(new IOnEngineeringUnitsChange() {
|
||||
|
||||
@Override
|
||||
public void onSliderMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
|
||||
double eng = setLowerBound(newAngleDegrees);
|
||||
activLink.setUseLimits(false);
|
||||
activLink.setTargetEngineeringUnits(eng);
|
||||
activLink.flush(0);
|
||||
activLink.setUseLimits(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSliderDoneMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
|
||||
try {
|
||||
activLink.setUseLimits(false);
|
||||
activLink.setTargetEngineeringUnits(setLowerBound(newAngleDegrees) + 0.01);
|
||||
activLink.flush(0);
|
||||
activLink.setUseLimits(true);
|
||||
if (manager != null)
|
||||
manager.generateCad();
|
||||
zero.setLowerBound(newAngleDegrees);
|
||||
|
||||
} catch (Exception ex) {
|
||||
BowlerStudio.printStackTrace(ex);
|
||||
}
|
||||
}
|
||||
}, conf.getLowerLimit() < 1 ? conf.getLowerLimit() : 1, // min
|
||||
conf.getStaticOffset(), // max
|
||||
conf.getLowerLimit(), // current
|
||||
150, "device units", true);
|
||||
|
||||
upperBound = new EngineeringUnitsSliderWidget(new IOnEngineeringUnitsChange() {
|
||||
|
||||
@Override
|
||||
public void onSliderMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
|
||||
double eng = setUpperBound(newAngleDegrees - 0.00001);
|
||||
activLink.setUseLimits(false);
|
||||
activLink.setTargetEngineeringUnits(eng);
|
||||
activLink.flush(0);
|
||||
activLink.setUseLimits(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSliderDoneMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
|
||||
activLink.setUseLimits(false);
|
||||
activLink.setTargetEngineeringUnits(setUpperBound(newAngleDegrees) - 0.00001);
|
||||
activLink.flush(0);
|
||||
activLink.setUseLimits(true);
|
||||
zero.setUpperBound(newAngleDegrees);
|
||||
if (manager != null)
|
||||
manager.generateCad();
|
||||
|
||||
}
|
||||
}, conf.getStaticOffset(), conf.getUpperLimit() > 180 ? conf.getUpperLimit() : 180, conf.getUpperLimit(), 150,
|
||||
"device units", true);
|
||||
|
||||
zero = new EngineeringUnitsSliderWidget(new IOnEngineeringUnitsChange() {
|
||||
|
||||
@Override
|
||||
public void onSliderMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
|
||||
conf.setStaticOffset(newAngleDegrees);
|
||||
|
||||
activLink.setTargetEngineeringUnits(0);
|
||||
activLink.flush(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSliderDoneMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
|
||||
setLowerBound(conf.getLowerLimit());
|
||||
setUpperBound(conf.getUpperLimit());
|
||||
setpointSLider.setValue(0);
|
||||
activLink.setTargetEngineeringUnits(0);
|
||||
activLink.flush(0);
|
||||
upperBound.setLowerBound(newAngleDegrees);
|
||||
lowerBound.setUpperBound(newAngleDegrees);
|
||||
if (manager != null)
|
||||
manager.generateCad();
|
||||
|
||||
}
|
||||
}, conf.getLowerLimit(), conf.getUpperLimit(), conf.getStaticOffset(), 150, "device units", true);
|
||||
|
||||
final ComboBox<String> channel = new ComboBox<>();
|
||||
for (int i = 0; i < 24; i++) {
|
||||
channel.getItems().add(Integer.toString(i));
|
||||
}
|
||||
channel.setOnAction(new EventHandler<ActionEvent>() {
|
||||
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
conf.setHardwareIndex(Integer.parseInt(channel.getSelectionModel().getSelectedItem()));
|
||||
factory.refreshHardwareLayer(conf);
|
||||
activLink = factory.getLink(conf);
|
||||
System.out.println("Link channel to " + conf.getTypeString());
|
||||
if (manager != null)
|
||||
manager.generateCad();
|
||||
|
||||
}
|
||||
});
|
||||
channel.getSelectionModel().select(conf.getHardwareIndex());
|
||||
|
||||
final ComboBox<String> comboBox = new ComboBox<>();
|
||||
for (LinkType type : LinkType.values()) {
|
||||
comboBox.getItems().add(type.getName());
|
||||
}
|
||||
comboBox.setOnAction(new EventHandler<ActionEvent>() {
|
||||
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
conf.setType(LinkType.fromString(comboBox.getSelectionModel().getSelectedItem()));
|
||||
System.out.println("Link type changed to " + conf.getTypeString());
|
||||
if (manager != null)
|
||||
manager.generateCad();
|
||||
|
||||
}
|
||||
});
|
||||
comboBox.getSelectionModel().select(conf.getTypeString().toString());
|
||||
|
||||
add(new Text("Zero Degrees Value"), 0, 1);
|
||||
add(zero, 1, 1);
|
||||
|
||||
add(new Text("Upper bound"), 0, 2);
|
||||
add(upperBound, 1, 2);
|
||||
|
||||
add(new Text("Lower bound"), 0, 3);
|
||||
add(lowerBound, 1, 3);
|
||||
|
||||
add(new Text("Link Type"), 0, 4);
|
||||
add(comboBox, 1, 4);
|
||||
add(new Text("Link Hardware Index"), 0, 5);
|
||||
add(channel, 1, 5);
|
||||
|
||||
add(new Text("Device Scripting Name"), 0, 6);
|
||||
add(deviceName, 1, 6);
|
||||
|
||||
add(new Text("Mass"), 0, 7);
|
||||
add(mass, 1, 7);
|
||||
|
||||
add(new Text("Mass Centroid x"), 0, 8);
|
||||
add(massx, 1, 8);
|
||||
|
||||
add(new Text("Mass Centroid y"), 0, 9);
|
||||
add(massy, 1, 9);
|
||||
add(new Text("Mass Centroid z"), 0, 10);
|
||||
add(massz, 1, 10);
|
||||
// link hardware
|
||||
add(new Text("Hardware Type"), 0, 11);
|
||||
add(emHardwareType, 1, 11);
|
||||
add(new Text("Hardware Size"), 0, 12);
|
||||
add(emHardwareSize, 1, 12);
|
||||
add(editHardware, 2, 12);
|
||||
add(newHardware, 1, 13);
|
||||
|
||||
// link shaft
|
||||
add(new Text("Shaft Type"), 0, 14);
|
||||
add(shaftType, 1, 14);
|
||||
add(new Text("Shaft Size"), 0, 15);
|
||||
add(shaftSize, 1, 15);
|
||||
add(editShaft, 2, 15);
|
||||
add(newShaft, 1, 16);
|
||||
|
||||
}
|
||||
|
||||
private double setUpperBound(double newAngleDegrees) {
|
||||
conf.setUpperLimit(newAngleDegrees);
|
||||
double eng = 0;
|
||||
if (conf.getScale() < 0) {
|
||||
eng = (activLink.getMinEngineeringUnits());
|
||||
setpointSLider.setLowerBound(eng);
|
||||
} else {
|
||||
eng = (activLink.getMaxEngineeringUnits());
|
||||
setpointSLider.setUpperBound(eng);
|
||||
}
|
||||
|
||||
return eng;
|
||||
}
|
||||
|
||||
private double setLowerBound(double newAngleDegrees) {
|
||||
conf.setLowerLimit(newAngleDegrees);
|
||||
|
||||
double eng = 0;
|
||||
if (conf.getScale() > 0) {
|
||||
eng = (activLink.getMinEngineeringUnits());
|
||||
setpointSLider.setLowerBound(eng);
|
||||
} else {
|
||||
eng = (activLink.getMaxEngineeringUnits());
|
||||
setpointSLider.setUpperBound(eng);
|
||||
}
|
||||
|
||||
return eng;
|
||||
|
||||
}
|
||||
|
||||
private void setShaftSize(Button editShaft, Button newShaft, String selectedItem) {
|
||||
if (selectedItem == null) {
|
||||
newShaft.setText("");
|
||||
editShaft.setText("");
|
||||
return;
|
||||
}
|
||||
editShaft.setText("Edit " + selectedItem);
|
||||
}
|
||||
|
||||
private void setShaftType(Button editShaft, Button newShaft, final ComboBox<String> shaftSize,
|
||||
String selectedItem) {
|
||||
shaftSize.getItems().clear();
|
||||
if (selectedItem == null)
|
||||
return;
|
||||
for (String s : Vitamins.listVitaminSizes(selectedItem)) {
|
||||
shaftSize.getItems().add(s);
|
||||
}
|
||||
newShaft.setText("New " + selectedItem);
|
||||
// editShaft.setText("Edit "+ conf.getShaftSize());
|
||||
}
|
||||
|
||||
private void test(String type) throws IOException {
|
||||
try {
|
||||
Vitamins.saveDatabase(type);
|
||||
|
||||
} catch (org.eclipse.jgit.api.errors.TransportException e) {
|
||||
GitHub github = PasswordManager.getGithub();
|
||||
|
||||
GHRepository repo = github.getUser("madhephaestus").getRepository("Hardware-Dimensions");
|
||||
GHRepository forked = repo.fork();
|
||||
System.out.println("Vitamins forked to " + forked.getGitTransportUrl());
|
||||
Vitamins.setGitRepoDatabase(
|
||||
"https://github.com/" + github.getMyself().getLogin() + "/Hardware-Dimensions.git");
|
||||
System.out.println("Loading new files");
|
||||
//
|
||||
|
||||
} catch (Exception ex) {
|
||||
// ex.printStackTrace(MainController.getOut());
|
||||
}
|
||||
}
|
||||
|
||||
private void edit(String type, String id, HashMap<String, Object> startingConf) throws Exception {
|
||||
System.out.println("Configuration for " + conf.getElectroMechanicalSize());
|
||||
System.out.println("Saving to for " + id);
|
||||
test(type);
|
||||
Platform.runLater(() -> {
|
||||
Alert dialog = new Alert(AlertType.CONFIRMATION);
|
||||
dialog.setTitle("Edit Hardware Wizard");
|
||||
dialog.setHeaderText("Update the hardare configurations");
|
||||
|
||||
// Create the username and password labels and fields.
|
||||
GridPane grid = new GridPane();
|
||||
grid.setHgap(10);
|
||||
grid.setVgap(10);
|
||||
grid.setPadding(new Insets(20, 150, 10, 10));
|
||||
|
||||
HashMap<String, TextField> valueFields = new HashMap<>();
|
||||
|
||||
int row = 0;
|
||||
for (Map.Entry<String, Object> entry : startingConf.entrySet()) {
|
||||
TextField username = new TextField();
|
||||
username.setText(entry.getValue().toString());
|
||||
grid.add(new Label(entry.getKey()), 0, row);
|
||||
grid.add(username, 1, row);
|
||||
valueFields.put(entry.getKey(), username);
|
||||
row++;
|
||||
}
|
||||
|
||||
dialog.getDialogPane().setContent(grid);
|
||||
Optional<ButtonType> r = dialog.showAndWait();
|
||||
if (r.get() == ButtonType.OK) {
|
||||
new Thread() {
|
||||
public void run() {
|
||||
for (Map.Entry<String, TextField> entry : valueFields.entrySet()) {
|
||||
try {
|
||||
Vitamins.setParameter(type, id, entry.getKey(), (Object) entry.getValue().getText());
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
try {
|
||||
Vitamins.saveDatabase(type);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
package com.neuronrobotics.bowlerstudio.creature;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import org.reactfx.util.FxTimer;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.assets.ConfigurationDatabase;
|
||||
import com.neuronrobotics.sdk.addons.gamepad.BowlerJInputDevice;
|
||||
import com.neuronrobotics.sdk.addons.gamepad.IJInputEventListener;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.AbstractLink;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.DHLink;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.DHParameterKinematics;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.DhLinkType;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.IJointSpaceUpdateListenerNR;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.ILinkListener;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.JointLimit;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.math.RotationNR;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR;
|
||||
import com.neuronrobotics.sdk.common.Log;
|
||||
import com.neuronrobotics.sdk.pid.PIDLimitEvent;
|
||||
import com.neuronrobotics.sdk.util.ThreadUtil;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.control.Accordion;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Slider;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.TitledPane;
|
||||
import javafx.scene.layout.ColumnConstraints;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.RowConstraints;
|
||||
import javafx.scene.text.Text;
|
||||
import net.java.games.input.Component;
|
||||
import net.java.games.input.Controller;
|
||||
import net.java.games.input.Event;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class LinkSliderWidget extends Group implements IJInputEventListener, IOnEngineeringUnitsChange, ILinkListener {
|
||||
private AbstractKinematicsNR device;
|
||||
private DHParameterKinematics dhdevice;
|
||||
|
||||
private int linkIndex;
|
||||
private EngineeringUnitsSliderWidget setpoint;
|
||||
private BowlerJInputDevice controller;
|
||||
private jogThread jogTHreadHandle;
|
||||
private double slider;
|
||||
private boolean stop;
|
||||
private double seconds;
|
||||
private String paramsKey;
|
||||
private AbstractLink abstractLink;
|
||||
// private EngineeringUnitsSliderWidget slide;
|
||||
|
||||
public LinkSliderWidget(int linkIndex, DHLink dhlink, AbstractKinematicsNR d) {
|
||||
|
||||
this.linkIndex = linkIndex;
|
||||
this.device = d;
|
||||
if (DHParameterKinematics.class.isInstance(device)) {
|
||||
dhdevice = (DHParameterKinematics) device;
|
||||
}
|
||||
|
||||
abstractLink = device.getAbstractLink(linkIndex);
|
||||
|
||||
TextField name = new TextField(abstractLink.getLinkConfiguration().getName());
|
||||
name.setMaxWidth(100.0);
|
||||
name.setOnAction(event -> {
|
||||
abstractLink.getLinkConfiguration().setName(name.getText());
|
||||
});
|
||||
|
||||
setSetpoint(new EngineeringUnitsSliderWidget(this, abstractLink.getMinEngineeringUnits(),
|
||||
abstractLink.getMaxEngineeringUnits(), device.getCurrentJointSpaceVector()[linkIndex], 180,
|
||||
dhlink.getLinkType() == DhLinkType.ROTORY ? "degrees" : "mm"));
|
||||
|
||||
GridPane panel = new GridPane();
|
||||
|
||||
panel.getColumnConstraints().add(new ColumnConstraints(30)); // column 1
|
||||
// is 75
|
||||
// wide
|
||||
panel.getColumnConstraints().add(new ColumnConstraints(120)); // column
|
||||
// 1 is
|
||||
// 75
|
||||
// wide
|
||||
panel.getColumnConstraints().add(new ColumnConstraints(120)); // column
|
||||
// 2 is
|
||||
// 300
|
||||
// wide
|
||||
|
||||
panel.add(new Text("#" + linkIndex), 0, 0);
|
||||
panel.add(name, 1, 0);
|
||||
panel.add(getSetpoint(), 2, 0);
|
||||
|
||||
getChildren().add(panel);
|
||||
abstractLink.addLinkListener(this);
|
||||
// device.addJointSpaceListener(this);
|
||||
|
||||
}
|
||||
|
||||
public void setUpperBound(double newBound) {
|
||||
getSetpoint().setUpperBound(newBound);
|
||||
}
|
||||
|
||||
public void setLowerBound(double newBound) {
|
||||
getSetpoint().setLowerBound(newBound);
|
||||
}
|
||||
|
||||
// public void changed(ObservableValue<? extends Boolean> observableValue,
|
||||
// Boolean wasChanging,
|
||||
// Boolean changing) {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onJointSpaceUpdate(AbstractKinematicsNR source, double[] joints)
|
||||
// {
|
||||
//
|
||||
// try {
|
||||
// setpoint.setValue(joints[linkIndex]);
|
||||
// } catch (ArrayIndexOutOfBoundsException ex) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onJointSpaceTargetUpdate(AbstractKinematicsNR source, double[]
|
||||
// joints) {
|
||||
// // TODO Auto-generated method stub
|
||||
// System.out.println("targe update");
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onJointSpaceLimit(AbstractKinematicsNR source, int axis,
|
||||
// JointLimit event) {
|
||||
// // TODO Auto-generated method stub
|
||||
// System.out.println("limit update");
|
||||
//
|
||||
// }
|
||||
|
||||
private void controllerLoop() {
|
||||
seconds = .1;
|
||||
if (getGameController() != null || stop == false) {
|
||||
|
||||
if (!stop) {
|
||||
jogTHreadHandle.setToSet(slider + getSetpoint().getValue(), seconds);
|
||||
}
|
||||
|
||||
FxTimer.runLater(Duration.ofMillis((int) (seconds * 1000.0)), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
controllerLoop();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private class jogThread extends Thread {
|
||||
private boolean controlThreadRunning = false;
|
||||
|
||||
private double toSeconds = seconds;
|
||||
|
||||
private double newValue;
|
||||
|
||||
public void run() {
|
||||
setName("Jog Link Slider");
|
||||
while (device.isAvailable()) {
|
||||
if (controlThreadRunning) {
|
||||
try {
|
||||
device.setDesiredJointAxisValue(linkIndex, newValue, toSeconds);
|
||||
getSetpoint().setValue(newValue);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
controlThreadRunning = false;
|
||||
}
|
||||
ThreadUtil.wait((int) (toSeconds * 1000));
|
||||
}
|
||||
}
|
||||
|
||||
public void setToSet(double newValue, double toSeconds) {
|
||||
|
||||
this.newValue = newValue;
|
||||
this.toSeconds = toSeconds;
|
||||
controlThreadRunning = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setGameController(BowlerJInputDevice controller) {
|
||||
this.controller = controller;
|
||||
if (controller != null && jogTHreadHandle == null) {
|
||||
jogTHreadHandle = new jogThread();
|
||||
jogTHreadHandle.start();
|
||||
}
|
||||
|
||||
if (controller != null) {
|
||||
Controller hwController = controller.getController();
|
||||
paramsKey = hwController.getName();
|
||||
System.err.println("Controller key: " + paramsKey);
|
||||
getGameController().clearListeners();
|
||||
getGameController().addListeners(this);
|
||||
controllerLoop();
|
||||
}
|
||||
}
|
||||
|
||||
public BowlerJInputDevice getGameController() {
|
||||
return controller;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(Component comp, net.java.games.input.Event event, float value, String eventString) {
|
||||
|
||||
if (comp.getName().toLowerCase()
|
||||
.contentEquals((String) ConfigurationDatabase.getObject(paramsKey, "jogLink", "x")))
|
||||
slider = -value;
|
||||
|
||||
if (Math.abs(slider) < .01)
|
||||
slider = 0;
|
||||
if (slider == 0) {
|
||||
// System.out.println("Stoping on="+comp.getName());
|
||||
stop = true;
|
||||
} else
|
||||
stop = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSliderMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
|
||||
// TODO Auto-generated method stub
|
||||
try {
|
||||
if (newAngleDegrees > device.getAbstractLink(linkIndex).getMaxEngineeringUnits()) {
|
||||
newAngleDegrees=device.getAbstractLink(linkIndex).getMaxEngineeringUnits();
|
||||
}
|
||||
if(newAngleDegrees <device.getAbstractLink(linkIndex).getMinEngineeringUnits()) {
|
||||
newAngleDegrees=device.getAbstractLink(linkIndex).getMinEngineeringUnits();
|
||||
}
|
||||
device.setDesiredJointAxisValue(linkIndex, newAngleDegrees, 0);
|
||||
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
//e.printStackTrace();
|
||||
}
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSliderDoneMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLinkLimit(AbstractLink arg0, PIDLimitEvent arg1) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLinkPositionUpdate(AbstractLink arg0, double arg1) {
|
||||
// TODO Auto-generated method stub
|
||||
try {
|
||||
getSetpoint().setValue(arg1);
|
||||
} catch (ArrayIndexOutOfBoundsException ex) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public EngineeringUnitsSliderWidget getSetpoint() {
|
||||
return setpoint;
|
||||
}
|
||||
|
||||
public void setSetpoint(EngineeringUnitsSliderWidget setpoint) {
|
||||
this.setpoint = setpoint;
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,109 @@
|
||||
package com.neuronrobotics.bowlerstudio.creature;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import com.neuronrobotics.replicator.driver.NRPrinter;
|
||||
import com.neuronrobotics.replicator.driver.StateBasedControllerConfiguration;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR;
|
||||
//import com.neuronrobotics.sdk.addons.kinematics.gui.SampleGuiNR;
|
||||
|
||||
public class PrinterConfiguration extends JPanel {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -1890177802795201269L;
|
||||
//private SampleGuiNR gui = new SampleGuiNR();
|
||||
private StateBasedControllerConfiguration state;
|
||||
private JTextField kp = new JTextField(10);
|
||||
private JTextField ki = new JTextField(10);
|
||||
private JTextField kd = new JTextField(10);
|
||||
private JTextField vkp = new JTextField(10);
|
||||
private JTextField vkd = new JTextField(10);
|
||||
private JTextField mmPos = new JTextField(10);
|
||||
private JTextField maxVel = new JTextField(10);
|
||||
private JTextField baseRad = new JTextField(10);
|
||||
private JTextField EErad = new JTextField(10);
|
||||
private JTextField maxz = new JTextField(10);
|
||||
private JTextField minz = new JTextField(10);
|
||||
private JTextField rodlen = new JTextField(10);
|
||||
private JCheckBox hardPos = new JCheckBox("Use Hard Positioning");
|
||||
|
||||
private JButton update=new JButton("Update");
|
||||
private NRPrinter printer;
|
||||
private JPanel controls;
|
||||
|
||||
public PrinterConfiguration(){
|
||||
setLayout(new MigLayout());
|
||||
controls = new JPanel(new MigLayout());
|
||||
controls.add(new JLabel("kP"));controls.add(kp,"wrap");
|
||||
controls.add(new JLabel("kI"));controls.add(ki,"wrap");
|
||||
controls.add(new JLabel("kD"));controls.add(kd,"wrap");
|
||||
controls.add(new JLabel("VkP"));controls.add(vkp,"wrap");
|
||||
controls.add(new JLabel("VkD"));controls.add(vkd,"wrap");
|
||||
controls.add(new JLabel("Resolution (mm)"));controls.add(mmPos,"wrap");
|
||||
controls.add(new JLabel("Maximum Velocity (mm/s)"));controls.add(maxVel,"wrap");
|
||||
controls.add(new JLabel("Base Radius(mm)"));controls.add(baseRad,"wrap");
|
||||
controls.add(new JLabel("End Effector Radius(mm)"));controls.add(EErad,"wrap");
|
||||
controls.add(new JLabel("Maximum Z(mm)"));controls.add(maxz,"wrap");
|
||||
controls.add(new JLabel("Minimum Z(mm)"));controls.add(minz,"wrap");
|
||||
controls.add(new JLabel("Rod Length(mm)"));controls.add(rodlen,"wrap");
|
||||
controls.add(hardPos,"wrap");
|
||||
|
||||
controls.add(update,"wrap");
|
||||
|
||||
|
||||
update.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
state.setkP(Double.parseDouble(kp.getText()));
|
||||
state.setkI(Double.parseDouble(ki.getText()));
|
||||
state.setkD(Double.parseDouble(kd.getText()));
|
||||
state.setvKP(Double.parseDouble(vkp.getText()));
|
||||
state.setvKD(Double.parseDouble(vkd.getText()));
|
||||
state.setMmPositionResolution(Double.parseDouble(mmPos.getText()));
|
||||
state.setMaximumMMperSec(Double.parseDouble(maxVel.getText()));
|
||||
state.setBaseRadius(Double.parseDouble(baseRad.getText()));
|
||||
state.setEndEffectorRadius(Double.parseDouble(EErad.getText()));
|
||||
state.setMaxZ(Double.parseDouble(maxz.getText()));
|
||||
state.setMinZ(Double.parseDouble(minz.getText()));
|
||||
state.setRodLength(Double.parseDouble(rodlen.getText()));
|
||||
state.setUseHardPositioning(hardPos.isSelected());
|
||||
printer.setStateBasedControllerConfiguration(state);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setKinematicsModel(AbstractKinematicsNR p) {
|
||||
|
||||
// gui.setKinematicsModel(p);
|
||||
// if(NRPrinter.class.isInstance(p)){
|
||||
// this.printer = (NRPrinter)p;
|
||||
// state = printer.getStateBasedControllerConfiguration();
|
||||
// kp.setText(Double.toString(state.getkP()));
|
||||
// ki.setText(Double.toString(state.getkI()));
|
||||
// kd.setText(Double.toString(state.getkD()));
|
||||
// vkp.setText(Double.toString(state.getvKP()));
|
||||
// vkd.setText(Double.toString(state.getvKD()));
|
||||
// mmPos.setText(Double.toString(state.getMmPositionResolution()));
|
||||
// maxVel.setText(Double.toString(state.getMaximumMMperSec()));
|
||||
// baseRad.setText(Double.toString(state.getBaseRadius()));
|
||||
// EErad.setText(Double.toString(state.getEndEffectorRadius()));
|
||||
// maxz.setText(Double.toString(state.getMaxZ()));
|
||||
// minz.setText(Double.toString(state.getMinZ()));
|
||||
// rodlen.setText(Double.toString(state.getRodLength()));
|
||||
// hardPos.setSelected(state.isUseHardPositioning());
|
||||
// add(controls,"wrap");
|
||||
// }
|
||||
// add(gui,"wrap");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
package com.neuronrobotics.bowlerstudio.creature;
|
||||
|
||||
import Jama.Matrix;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.threed.BowlerStudio3dEngine;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.math.RotationNR;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR;
|
||||
import com.neuronrobotics.sdk.common.Log;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.ColumnConstraints;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.text.Text;
|
||||
|
||||
public class TransformWidget extends GridPane implements IOnEngineeringUnitsChange, EventHandler<ActionEvent> {
|
||||
|
||||
private IOnTransformChange onChange;
|
||||
//EngineeringUnitsSliderWidget rw;
|
||||
private EngineeringUnitsSliderWidget tilt;
|
||||
private EngineeringUnitsSliderWidget elevation;
|
||||
private EngineeringUnitsSliderWidget azimeth;
|
||||
private EngineeringUnitsSliderWidget tx;
|
||||
private EngineeringUnitsSliderWidget ty;
|
||||
private EngineeringUnitsSliderWidget tz;
|
||||
// private TextField tx;
|
||||
// private TextField ty;
|
||||
// private TextField tz;
|
||||
private TransformNR initialState;
|
||||
|
||||
|
||||
public TransformWidget(String title, TransformNR is, IOnTransformChange onChange){
|
||||
this.initialState = is;
|
||||
this.onChange = onChange;
|
||||
// tx = new TextField(CreatureLab.getFormatted(initialState.getX()));
|
||||
// ty = new TextField(CreatureLab.getFormatted(initialState.getY()));
|
||||
// tz = new TextField(CreatureLab.getFormatted(initialState.getZ()));
|
||||
// tx.setOnAction(this);
|
||||
// ty.setOnAction(this);
|
||||
// tz.setOnAction(this);
|
||||
tx = new EngineeringUnitsSliderWidget(this, initialState.getX(), 100,"mm");
|
||||
ty = new EngineeringUnitsSliderWidget(this, initialState.getY(), 100,"mm");
|
||||
tz = new EngineeringUnitsSliderWidget(this, initialState.getZ(), 100,"mm");
|
||||
|
||||
RotationNR rot = initialState.getRotation();
|
||||
double t=0;
|
||||
try{
|
||||
t=Math.toDegrees(rot.getRotationTilt());
|
||||
}catch(Exception ex){
|
||||
ex.printStackTrace();
|
||||
}
|
||||
double e=0;
|
||||
try{
|
||||
e=Math.toDegrees(rot.getRotationElevation());
|
||||
}catch(Exception ex){
|
||||
ex.printStackTrace();
|
||||
}
|
||||
double a=0;
|
||||
try{
|
||||
a=Math.toDegrees(rot.getRotationAzimuth());
|
||||
}catch(Exception ex){
|
||||
ex.printStackTrace();
|
||||
}
|
||||
tilt = new EngineeringUnitsSliderWidget(this, -179.99, 179.99, t, 100,"degrees");
|
||||
elevation = new EngineeringUnitsSliderWidget(this, -89.99, 89.99, e, 100,"degrees");
|
||||
azimeth = new EngineeringUnitsSliderWidget(this, -179.99, 179.99, a, 100,"degrees");
|
||||
tilt.setAllowResize(false);
|
||||
elevation.setAllowResize(false);
|
||||
azimeth.setAllowResize(false);
|
||||
getColumnConstraints().add(new ColumnConstraints(30)); // translate text
|
||||
getColumnConstraints().add(new ColumnConstraints(200)); // translate values
|
||||
getColumnConstraints().add(new ColumnConstraints(60)); // units
|
||||
getColumnConstraints().add(new ColumnConstraints(60)); // rotate text
|
||||
setHgap(20);// gab between elements
|
||||
|
||||
|
||||
add( new Text(title),
|
||||
1, 0);
|
||||
// add( new Text("(r)W"),
|
||||
// 3, 0);
|
||||
// add( rw,
|
||||
// 4, 0);
|
||||
// These all seem out of order here, but it is because the
|
||||
// screen is rotating the orenation of this interface from BowlerStudio3dEngine.getOffsetforvisualization()
|
||||
//X line
|
||||
add( new Text("X"),
|
||||
0, 1);
|
||||
add( tx,
|
||||
1, 1);
|
||||
|
||||
add( new Text("Tilt"),
|
||||
3, 1);
|
||||
add( tilt,
|
||||
4, 1);
|
||||
//Y line
|
||||
add( new Text("Y"),
|
||||
0, 2);
|
||||
add( ty,
|
||||
1, 2);
|
||||
|
||||
add( new Text("Elevation"),
|
||||
3, 2);
|
||||
add( elevation,
|
||||
4, 2);
|
||||
//Z line
|
||||
add( new Text("Z"),
|
||||
0, 3);
|
||||
add( tz,
|
||||
1, 3);
|
||||
|
||||
add( new Text("Azimuth"),
|
||||
3, 3);
|
||||
add( azimeth,
|
||||
4, 3);
|
||||
}
|
||||
|
||||
private TransformNR getCurrent(){
|
||||
TransformNR tmp = new TransformNR(
|
||||
tx.getValue(),
|
||||
ty.getValue(),
|
||||
tz.getValue(),
|
||||
new RotationNR(
|
||||
tilt.getValue(),
|
||||
azimeth.getValue(),
|
||||
elevation.getValue()
|
||||
));
|
||||
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSliderMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
|
||||
onChange.onTransformChaging(getCurrent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSliderDoneMoving(EngineeringUnitsSliderWidget source,
|
||||
double newAngleDegrees) {
|
||||
handle(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(ActionEvent event) {
|
||||
onChange.onTransformChaging(getCurrent());
|
||||
onChange.onTransformFinished(getCurrent());
|
||||
}
|
||||
|
||||
public void updatePose(TransformNR p) {
|
||||
TransformNR pose = p;
|
||||
|
||||
|
||||
tx.setValue(pose.getX());
|
||||
ty.setValue(pose.getY());
|
||||
tz.setValue(pose.getZ());
|
||||
|
||||
RotationNR rot = pose.getRotation();
|
||||
double t=0;
|
||||
try{
|
||||
t=Math.toDegrees(rot.getRotationTilt());
|
||||
}catch(Exception ex){
|
||||
ex.printStackTrace();
|
||||
}
|
||||
double e=0;
|
||||
try{
|
||||
e=Math.toDegrees(rot.getRotationElevation());
|
||||
}catch(Exception ex){
|
||||
ex.printStackTrace();
|
||||
}
|
||||
double a=0;
|
||||
try{
|
||||
a=Math.toDegrees(rot.getRotationAzimuth());
|
||||
}catch(Exception ex){
|
||||
ex.printStackTrace();
|
||||
}
|
||||
tilt.setValue(t);
|
||||
elevation .setValue(e);
|
||||
azimeth .setValue(a);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package com.neuronrobotics.bowlerstudio.scripting;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.PasswordField;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
|
||||
|
||||
public class GithubLoginFX implements javafx.fxml.Initializable {
|
||||
|
||||
@FXML
|
||||
private TextField username;
|
||||
@FXML PasswordField password;
|
||||
|
||||
private boolean done=false;
|
||||
|
||||
private String [] creds = new String[]{"",""};
|
||||
private Stage stage;
|
||||
private Parent root;
|
||||
private Scene scene;
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
public void reset(){
|
||||
done=false;
|
||||
setCreds(new String[]{"",""});
|
||||
password.clear();
|
||||
getUsername().clear();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@FXML public void anonMode() {
|
||||
setCreds(null);
|
||||
try {
|
||||
// this should make anon mode stick
|
||||
ScriptingEngine.setupAnyonmous();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
finish();
|
||||
}
|
||||
private void finish(){
|
||||
stage.close();
|
||||
stage.hide();
|
||||
done=true;
|
||||
}
|
||||
|
||||
@FXML public void login() {
|
||||
getCreds()[0]= getUsername().getText();
|
||||
getCreds()[1]= password.getText();
|
||||
if(getCreds()[0]==null||getCreds()[1]==null){
|
||||
setCreds(null);
|
||||
}else if(getCreds()[0].equals("")||getCreds()[1].equals("")){
|
||||
setCreds(null);
|
||||
}
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
@FXML public void focusOnPw() {
|
||||
password.requestFocus();
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
return done;
|
||||
}
|
||||
|
||||
public void setDone(boolean done) {
|
||||
this.done = done;
|
||||
}
|
||||
|
||||
public String [] getCreds() {
|
||||
return creds;
|
||||
}
|
||||
|
||||
public void setCreds(String [] creds) {
|
||||
this.creds = creds;
|
||||
}
|
||||
|
||||
public void setStage(Stage stage, Parent root) {
|
||||
this.stage = stage;
|
||||
if(this.root==null){
|
||||
this.root = root;
|
||||
scene= new Scene(root);
|
||||
}
|
||||
stage.setScene(scene);
|
||||
}
|
||||
|
||||
public TextField getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(TextField username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.neuronrobotics.bowlerstudio.scripting;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import groovy.lang.GroovyShell;
|
||||
import groovy.lang.Script;
|
||||
|
||||
public interface IScriptEventListener {
|
||||
|
||||
void onScriptFinished( Object result,Object pervious, File source);
|
||||
|
||||
void onScriptChanged(String previous, String current, File source);
|
||||
|
||||
void onScriptError( Throwable except, File source);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,569 @@
|
||||
package com.neuronrobotics.bowlerstudio.scripting;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.BowlerStudio;
|
||||
import com.neuronrobotics.bowlerstudio.BowlerStudioController;
|
||||
import com.neuronrobotics.bowlerstudio.ConnectionManager;
|
||||
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
|
||||
import com.neuronrobotics.bowlerstudio.util.FileChangeWatcher;
|
||||
//import com.neuronrobotics.imageprovider.OpenCVImageProvider;
|
||||
import com.neuronrobotics.nrconsole.util.CommitWidget;
|
||||
import com.neuronrobotics.nrconsole.util.FileSelectionFactory;
|
||||
import com.neuronrobotics.sdk.common.Log;
|
||||
import com.neuronrobotics.sdk.util.IFileChangeListener;
|
||||
import com.neuronrobotics.sdk.util.ThreadUtil;
|
||||
|
||||
import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Alert.AlertType;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.*;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.stage.FileChooser.ExtensionFilter;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.reactfx.util.FxTimer;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.WatchEvent;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Scanner;
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class ScriptingFileWidget extends BorderPane implements
|
||||
IFileChangeListener {
|
||||
|
||||
private boolean running = false;
|
||||
private Thread scriptRunner = null;
|
||||
private Dimension codeDimentions = new Dimension(1168, 768);
|
||||
//Label fileLabel = new Label();
|
||||
private Object scriptResult;
|
||||
private String codeText="";
|
||||
|
||||
private ArrayList<IScriptEventListener> listeners = new ArrayList<>();
|
||||
|
||||
private Button runfx = new Button("Run");
|
||||
private Button publish = new Button("Publish");
|
||||
|
||||
private String addr;
|
||||
boolean loadGist = false;
|
||||
|
||||
private ScriptingWidgetType type;
|
||||
|
||||
final TextField fileListBox = new TextField();
|
||||
final TextField fileNameBox = new TextField();
|
||||
private File currentFile = null;
|
||||
|
||||
private HBox controlPane;
|
||||
private String currentGist;
|
||||
private boolean updateneeded = false;
|
||||
private IScriptingLanguage langaugeType;
|
||||
private ImageView image=new ImageView();
|
||||
|
||||
public ScriptingFileWidget(File currentFile) throws IOException {
|
||||
this(ScriptingWidgetType.FILE);
|
||||
this.currentFile = currentFile;
|
||||
loadCodeFromFile(currentFile);
|
||||
boolean isOwnedByLoggedInUser= ScriptingEngine.checkOwner(currentFile);
|
||||
publish.setDisable(!isOwnedByLoggedInUser);
|
||||
runfx.setGraphic(AssetFactory.loadIcon("Run.png"));
|
||||
publish.setGraphic(AssetFactory.loadIcon("Publish.png"));
|
||||
try {
|
||||
image.setImage(AssetFactory.loadAsset("Script-Tab-"+ScriptingEngine.getShellType(currentFile.getName())+".png"));
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void startStopAction(){
|
||||
runfx.setDisable(true);
|
||||
if (running)
|
||||
stop();
|
||||
else
|
||||
start();
|
||||
runfx.setDisable(false);
|
||||
}
|
||||
|
||||
private ScriptingFileWidget(ScriptingWidgetType type) {
|
||||
this.type = type;
|
||||
|
||||
runfx.setOnAction(e -> {
|
||||
new Thread(){
|
||||
public void run(){
|
||||
|
||||
if(langaugeType.getIsTextFile())
|
||||
save();
|
||||
//do not attempt to save no binary files
|
||||
startStopAction();
|
||||
}
|
||||
}.start();
|
||||
});
|
||||
|
||||
publish.setOnAction(e -> {
|
||||
new Thread(()->{
|
||||
save();
|
||||
CommitWidget.commit(currentFile, getCode());
|
||||
}).start();
|
||||
|
||||
});
|
||||
|
||||
|
||||
// runsaveAs.setOnAction(e -> {
|
||||
// new Thread(){
|
||||
// public void run(){
|
||||
// updateFile();
|
||||
// save();
|
||||
// }
|
||||
// }.start();
|
||||
//
|
||||
// });
|
||||
|
||||
// String ctrlSave = "CTRL Save";
|
||||
// fileLabel.setOnMouseEntered(e -> {
|
||||
// Platform.runLater(() -> {
|
||||
// ThreadUtil.wait(10);
|
||||
// fileLabel.setText(currentFile.getAbsolutePath());
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// fileLabel.setOnMouseExited(e -> {
|
||||
// Platform.runLater(() -> {
|
||||
// ThreadUtil.wait(10);
|
||||
// fileLabel.setText(currentFile.getName());
|
||||
// });
|
||||
// });
|
||||
|
||||
|
||||
// Set up the run controls and the code area
|
||||
// The BorderPane has the same areas laid out as the
|
||||
// BorderLayout layout manager
|
||||
setPadding(new Insets(1, 0, 3, 10));
|
||||
|
||||
controlPane = new HBox(20);
|
||||
double lengthScalar = fileNameBox.getFont().getSize()*1.5;
|
||||
fileNameBox.textProperty().addListener((ov, prevText, currText) -> {
|
||||
// Do this in a Platform.runLater because of Textfield has no padding at first time and so on
|
||||
Platform.runLater(() -> {
|
||||
Text text = new Text(currText);
|
||||
text.setFont(fileNameBox.getFont()); // Set the same font, so the size is the same
|
||||
double width = text.getLayoutBounds().getWidth() // This big is the Text in the TextField
|
||||
+ fileNameBox.getPadding().getLeft() + fileNameBox.getPadding().getRight() // Add the padding of the TextField
|
||||
+ lengthScalar; // Add some spacing
|
||||
fileNameBox.setPrefWidth(width); // Set the width
|
||||
fileNameBox.positionCaret(fileNameBox.getCaretPosition()); // If you remove this line, it flashes a little bit
|
||||
});
|
||||
});
|
||||
fileListBox.textProperty().addListener((ov, prevText, currText) -> {
|
||||
// Do this in a Platform.runLater because of Textfield has no padding at first time and so on
|
||||
Platform.runLater(() -> {
|
||||
Text text = new Text(currText);
|
||||
text.setFont(fileListBox.getFont()); // Set the same font, so the size is the same
|
||||
double width = text.getLayoutBounds().getWidth() // This big is the Text in the TextField
|
||||
+ fileListBox.getPadding().getLeft() + fileListBox.getPadding().getRight() // Add the padding of the TextField
|
||||
+ lengthScalar; // Add some spacing
|
||||
fileListBox.setPrefWidth(width); // Set the width
|
||||
fileListBox.positionCaret(fileListBox.getCaretPosition()); // If you remove this line, it flashes a little bit
|
||||
});
|
||||
});
|
||||
|
||||
controlPane.getChildren().add(runfx);
|
||||
controlPane.getChildren().add(image);
|
||||
controlPane.getChildren().add(publish);
|
||||
controlPane.getChildren().add(new Label("file:"));
|
||||
controlPane.getChildren().add(fileNameBox);
|
||||
fileNameBox.setMaxWidth(Double.MAX_VALUE);
|
||||
controlPane.getChildren().add(new Label("git:"));
|
||||
controlPane.getChildren().add(fileListBox);
|
||||
fileListBox.setMaxWidth(Double.MAX_VALUE);
|
||||
controlPane.setMaxWidth(Double.MAX_VALUE);
|
||||
|
||||
|
||||
|
||||
// put the flowpane in the top area of the BorderPane
|
||||
setTop(controlPane);
|
||||
|
||||
addIScriptEventListener(BowlerStudioController.getBowlerStudio());
|
||||
reset();
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
running = false;
|
||||
Platform.runLater(() -> {
|
||||
runfx.setText("Run");
|
||||
runfx.setGraphic(AssetFactory.loadIcon("Run.png"));
|
||||
runfx.setBackground(new Background(new BackgroundFill(Color.LIGHTGREEN, CornerRadii.EMPTY, Insets.EMPTY)));
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void addIScriptEventListener(IScriptEventListener l) {
|
||||
if (!listeners.contains(l))
|
||||
listeners.add(l);
|
||||
}
|
||||
|
||||
public void removeIScriptEventListener(IScriptEventListener l) {
|
||||
if (listeners.contains(l))
|
||||
listeners.remove(l);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
reset();
|
||||
if (scriptRunner != null)
|
||||
while (scriptRunner.isAlive()) {
|
||||
|
||||
Log.debug("Interrupting");
|
||||
ThreadUtil.wait(10);
|
||||
try {
|
||||
scriptRunner.interrupt();
|
||||
scriptRunner.join();
|
||||
} catch (InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void loadCodeFromFile(File currentFile) throws IOException {
|
||||
if (!currentFile.exists()) {
|
||||
currentFile.createNewFile();
|
||||
}
|
||||
setUpFile(currentFile);
|
||||
if(!langaugeType.getIsTextFile())
|
||||
setCode("Binary File");
|
||||
else
|
||||
setCode(new String(Files.readAllBytes(currentFile.toPath())));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void start() {
|
||||
try{
|
||||
if(!currentFile.getName().contentEquals("csgDatabase.json")){
|
||||
String[] gitID = ScriptingEngine.findGitTagFromFile(currentFile);
|
||||
String remoteURI=gitID[0];
|
||||
ArrayList<String> f = ScriptingEngine.filesInGit(remoteURI);
|
||||
for (String s:f){
|
||||
if(s.contentEquals("csgDatabase.json")){
|
||||
File dbFile = ScriptingEngine.fileFromGit(gitID[0], s);
|
||||
if(!CSGDatabase.getDbFile().equals(dbFile))
|
||||
CSGDatabase.setDbFile(dbFile);
|
||||
CSGDatabase.saveDatabase();
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(Exception e){
|
||||
//ignore CSG database
|
||||
e.printStackTrace();
|
||||
}
|
||||
BowlerStudio.clearConsole();
|
||||
BowlerStudioController.clearHighlight();
|
||||
try {
|
||||
ScriptingEngine.setAutoupdate(false);
|
||||
} catch (IOException e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
}
|
||||
running = true;
|
||||
Platform.runLater(()->{
|
||||
runfx.setText("Stop");
|
||||
runfx.setGraphic(AssetFactory.loadIcon("Stop.png"));
|
||||
runfx.setBackground(new Background(new BackgroundFill(Color.RED, CornerRadii.EMPTY, Insets.EMPTY)));
|
||||
});
|
||||
scriptRunner = new Thread() {
|
||||
|
||||
public void run() {
|
||||
// String name;
|
||||
// try{
|
||||
// name = currentFile.getName();
|
||||
// }catch (NullPointerException e){
|
||||
// name="";
|
||||
// }
|
||||
try {
|
||||
Object obj = ScriptingEngine.inlineFileScriptRun(currentFile, null);
|
||||
for (IScriptEventListener l : listeners) {
|
||||
l.onScriptFinished(obj, scriptResult,currentFile);
|
||||
}
|
||||
|
||||
scriptResult = obj;
|
||||
reset();
|
||||
|
||||
}
|
||||
catch (groovy.lang.MissingPropertyException |org.python.core.PyException d){
|
||||
Platform.runLater(() -> {
|
||||
Alert alert = new Alert(AlertType.ERROR);
|
||||
alert.setTitle("Variable missing error");
|
||||
String message = "This script needs a variable defined before you use it: ";
|
||||
|
||||
String stackTrace = d.getMessage();
|
||||
|
||||
if(stackTrace.contains("dyio"))
|
||||
message+="dyio";
|
||||
else if(stackTrace.contains("camera"))
|
||||
message+="camera";
|
||||
else if(stackTrace.contains("gamepad"))
|
||||
message+="gamepad";
|
||||
else
|
||||
message+=stackTrace;
|
||||
alert.setHeaderText(message);
|
||||
alert.showAndWait();
|
||||
if(stackTrace.contains("dyio"))
|
||||
ConnectionManager.addConnection();
|
||||
// else if(stackTrace.contains("camera"))
|
||||
// ConnectionManager.addConnection(new OpenCVImageProvider(0),"camera0");
|
||||
else if(stackTrace.contains("gamepad"))
|
||||
ConnectionManager.onConnectGamePad("gamepad");
|
||||
reset();
|
||||
});
|
||||
BowlerStudioController.highlightException(currentFile, d);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
System.err.println("Script exception of type= "+ex.getClass().getName());
|
||||
|
||||
try{
|
||||
if (ex.getMessage().contains("sleep interrupted")) {
|
||||
append("\n" + currentFile + " Interupted\n");
|
||||
} else{
|
||||
BowlerStudioController.highlightException(currentFile, new Exception(ex));
|
||||
}
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
BowlerStudioController.highlightException(currentFile, new Exception(ex));
|
||||
}
|
||||
|
||||
reset();
|
||||
|
||||
for (IScriptEventListener l : listeners) {
|
||||
try {
|
||||
l.onScriptError(new Exception(ex),currentFile);
|
||||
}catch (Throwable e) {}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
|
||||
scriptRunner.start();
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void append(String s) {
|
||||
System.out.println(s);
|
||||
}
|
||||
|
||||
public String getGitRepo(){
|
||||
return fileListBox.getText();
|
||||
}
|
||||
public String getGitFile(){
|
||||
return fileNameBox.getText();
|
||||
}
|
||||
private void setUpFile(File f) {
|
||||
currentFile = f;
|
||||
String langType = ScriptingEngine.getShellType(currentFile.getName());
|
||||
try {
|
||||
image.setImage(AssetFactory.loadAsset("Script-Tab-"+ScriptingEngine.getShellType(currentFile.getName())+".png"));
|
||||
} catch (Exception e2) {
|
||||
// TODO Auto-generated catch block
|
||||
e2.printStackTrace();
|
||||
}
|
||||
langaugeType = ScriptingEngine.getLangaugesMap().get(langType);
|
||||
//ScriptingEngine.setLastFile(f);
|
||||
Git git;
|
||||
try {
|
||||
git = ScriptingEngine.locateGit(currentFile);
|
||||
String remote= git.getRepository().getConfig().getString("remote", "origin", "url");
|
||||
Platform.runLater(() -> {
|
||||
//fileListBox.setMinWidth(remote.getBytes().length*10);
|
||||
fileListBox.setText(remote);
|
||||
//fileListBox.res
|
||||
fileNameBox.setText(ScriptingEngine.findLocalPath(f, git));
|
||||
// These values are display only, so if hte user tries to change them, they reset
|
||||
// the use of text field for static dats is so the user cna copy the vlaues and use them in their scritpts
|
||||
fileNameBox.textProperty().addListener((observable, oldValue, newValue) -> {
|
||||
fileNameBox.setText(ScriptingEngine.findLocalPath(f, git));
|
||||
});
|
||||
fileListBox.textProperty().addListener((observable, oldValue, newValue) -> {
|
||||
fileListBox.setText(remote);
|
||||
});
|
||||
|
||||
git.close();
|
||||
});
|
||||
} catch (Exception e1) {
|
||||
Platform.runLater(() -> {
|
||||
fileListBox.setText("none");
|
||||
fileListBox.setMinWidth(40);
|
||||
fileNameBox.setText(f.getAbsolutePath());
|
||||
// These values are display only, so if hte user tries to change them, they reset
|
||||
// the use of text field for static dats is so the user cna copy the vlaues and use them in their scritpts
|
||||
fileNameBox.textProperty().addListener((observable, oldValue, newValue) -> {
|
||||
fileNameBox.setText(f.getAbsolutePath());
|
||||
});
|
||||
fileListBox.textProperty().addListener((observable, oldValue, newValue) -> {
|
||||
fileListBox.setText("none");
|
||||
});
|
||||
|
||||
});
|
||||
e1.printStackTrace();
|
||||
}
|
||||
if(!langaugeType.getIsTextFile())
|
||||
return;
|
||||
try {
|
||||
getWatcher().addIFileChangeListener(this);
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateFile() {
|
||||
|
||||
File last = FileSelectionFactory.GetFile( currentFile==null?
|
||||
ScriptingEngine.getWorkspace():
|
||||
new File(ScriptingEngine.getWorkspace().getAbsolutePath()+"/"+currentFile.getName()),
|
||||
true,
|
||||
new ExtensionFilter("Save Script","*"));
|
||||
if (last != null) {
|
||||
setUpFile(last);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void open() {
|
||||
|
||||
updateFile();
|
||||
try {
|
||||
setCode(new String(Files.readAllBytes(currentFile.toPath())));
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void save() {
|
||||
// TODO Auto-generated method stub
|
||||
try {
|
||||
System.out.println("Writing file contents");
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(
|
||||
currentFile));
|
||||
writer.write(getCode());
|
||||
writer.close();
|
||||
} catch (Exception ex) {
|
||||
// ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFileChange(File fileThatChanged,
|
||||
@SuppressWarnings("rawtypes") WatchEvent event) {
|
||||
if(updateneeded)
|
||||
return;
|
||||
updateneeded=true;
|
||||
try {
|
||||
getWatcher().removeIFileChangeListener(this);
|
||||
FxTimer.runLater(
|
||||
Duration.ofMillis(500) ,new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateneeded=false;
|
||||
// TODO Auto-generated method stub
|
||||
if (fileThatChanged.getAbsolutePath().contains(
|
||||
currentFile.getAbsolutePath())) {
|
||||
|
||||
System.out.println("Code in " + fileThatChanged.getAbsolutePath()
|
||||
+ " changed");
|
||||
Platform.runLater(() -> {
|
||||
try {
|
||||
String content = new String(Files.readAllBytes(Paths
|
||||
.get(fileThatChanged.getAbsolutePath())));
|
||||
if(content.length()>2)// ensures tha the file contents never get wiped out on the user
|
||||
setCode(content);
|
||||
} catch (UnsupportedEncodingException e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
} catch (IOException e2) {
|
||||
// TODO Auto-generated catch block
|
||||
e2.printStackTrace();
|
||||
}
|
||||
try {
|
||||
getWatcher().addIFileChangeListener(ScriptingFileWidget.this);
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
// System.out.println("Othr Code in "+fileThatChanged.getAbsolutePath()+" changed");
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return codeText;
|
||||
}
|
||||
|
||||
public void setCode(String string) {
|
||||
String pervious = codeText;
|
||||
codeText = string;
|
||||
// System.out.println(codeText);
|
||||
for (int i=0;i<listeners.size();i++ ) {
|
||||
listeners.get(i).onScriptChanged(pervious, string,currentFile);
|
||||
}
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
if(currentFile!=null)
|
||||
return currentFile.getName();
|
||||
else
|
||||
return "Web";
|
||||
}
|
||||
|
||||
public FileChangeWatcher getWatcher() throws IOException {
|
||||
return FileChangeWatcher.watch(currentFile);
|
||||
}
|
||||
public void close(){
|
||||
try {
|
||||
getWatcher().removeIFileChangeListener(this);
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,419 @@
|
||||
package com.neuronrobotics.bowlerstudio.scripting;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.BowlerStudio;
|
||||
import com.neuronrobotics.bowlerstudio.BowlerStudioController;
|
||||
import com.neuronrobotics.bowlerstudio.ConnectionManager;
|
||||
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
|
||||
//import com.neuronrobotics.imageprovider.OpenCVImageProvider;
|
||||
import com.neuronrobotics.sdk.common.Log;
|
||||
import com.neuronrobotics.sdk.util.ThreadUtil;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Alert.AlertType;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.*;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.web.WebEngine;
|
||||
import org.kohsuke.github.GHGist;
|
||||
import org.kohsuke.github.GHGistFile;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings({ "unused", "restriction" })
|
||||
public class ScriptingWebWidget extends BorderPane implements ChangeListener<Object> {
|
||||
|
||||
private boolean running = false;
|
||||
private Thread scriptRunner = null;
|
||||
|
||||
private Dimension codeDimentions = new Dimension(1168, 768);
|
||||
// Label fileLabel = new Label();
|
||||
private Object scriptResult;
|
||||
private String codeText = "";
|
||||
|
||||
private ArrayList<IScriptEventListener> listeners = new ArrayList<>();
|
||||
|
||||
private Button runfx = new Button("Run");;
|
||||
private Button edit = new Button("Edit...");
|
||||
private WebEngine engine;
|
||||
|
||||
private String addr;
|
||||
boolean loadGist = false;
|
||||
|
||||
private ScriptingWidgetType type;
|
||||
|
||||
final ComboBox<String> fileListBox = new ComboBox<>();
|
||||
private File currentFile = null;
|
||||
|
||||
private HBox controlPane;
|
||||
private String currentGit;
|
||||
private String currentGist;
|
||||
private boolean isOwnedByLoggedInUser;
|
||||
private ImageView image = new ImageView();
|
||||
|
||||
public ScriptingWebWidget(File currentFile, String currentGist, WebEngine engine)
|
||||
throws IOException, InterruptedException {
|
||||
this(ScriptingWidgetType.GIST);
|
||||
runfx.setGraphic(AssetFactory.loadIcon("Run.png"));
|
||||
edit.setGraphic(AssetFactory.loadIcon("Edit-Script.png"));
|
||||
this.currentFile = currentFile;
|
||||
try {
|
||||
loadCodeFromGist(currentGist, engine);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void startStopAction() {
|
||||
runfx.setDisable(true);
|
||||
if (running)
|
||||
stop();
|
||||
else
|
||||
start();
|
||||
runfx.setDisable(false);
|
||||
}
|
||||
|
||||
public ScriptingWebWidget(ScriptingWidgetType type) {
|
||||
this.type = type;
|
||||
|
||||
runfx.setOnAction(e -> {
|
||||
new Thread() {
|
||||
public void run() {
|
||||
|
||||
startStopAction();
|
||||
}
|
||||
}.start();
|
||||
});
|
||||
edit.setOnAction(e -> {
|
||||
new Thread() {
|
||||
public void run() {
|
||||
if (isOwnedByLoggedInUser)
|
||||
BowlerStudio.createFileTab(currentFile);
|
||||
else {
|
||||
// todo fork git repo
|
||||
System.out.println("Making Fork...");
|
||||
GHGist newGist;
|
||||
try {
|
||||
newGist = ScriptingEngine.fork(currentGist);
|
||||
Map<String, GHGistFile> fileMap = newGist.getFiles();
|
||||
if (fileMap.size() == 1) {
|
||||
String filename = (String) fileMap.keySet().toArray()[0];
|
||||
String url = newGist.getGitPullUrl();
|
||||
File file = ScriptingEngine.fileFromGit(url, filename);
|
||||
BowlerStudio.createFileTab(file);
|
||||
} else {
|
||||
BowlerStudio.openUrlInNewTab(newGist.getHtmlUrl());
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
BowlerStudioController.highlightException(currentFile, e1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}.start();
|
||||
|
||||
});
|
||||
|
||||
setPadding(new Insets(1, 0, 3, 10));
|
||||
|
||||
controlPane = new HBox(20);
|
||||
|
||||
controlPane.getChildren().add(runfx);
|
||||
controlPane.getChildren().add(image);
|
||||
controlPane.getChildren().add(edit);
|
||||
|
||||
controlPane.getChildren().add(fileListBox);
|
||||
|
||||
// put the flowpane in the top area of the BorderPane
|
||||
setTop(controlPane);
|
||||
|
||||
addIScriptEventListener(BowlerStudioController.getBowlerStudio());
|
||||
reset();
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
running = false;
|
||||
Platform.runLater(() -> {
|
||||
runfx.setText("Run");
|
||||
runfx.setGraphic(AssetFactory.loadIcon("Run.png"));
|
||||
runfx.setBackground(new Background(new BackgroundFill(Color.LIGHTGREEN, CornerRadii.EMPTY, Insets.EMPTY)));
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void addIScriptEventListener(IScriptEventListener l) {
|
||||
if (!listeners.contains(l))
|
||||
listeners.add(l);
|
||||
}
|
||||
|
||||
public void removeIScriptEventListener(IScriptEventListener l) {
|
||||
if (listeners.contains(l))
|
||||
listeners.remove(l);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
reset();
|
||||
if (scriptRunner != null)
|
||||
while (scriptRunner.isAlive()) {
|
||||
|
||||
Log.debug("Interrupting");
|
||||
ThreadUtil.wait(10);
|
||||
try {
|
||||
scriptRunner.interrupt();
|
||||
scriptRunner.join();
|
||||
} catch (InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// public void loadCodeFromFile(File currentFile) throws IOException {
|
||||
// if (!currentFile.exists()) {
|
||||
// currentFile.createNewFile();
|
||||
// }
|
||||
// setUpFile(currentFile);
|
||||
// setCode(new String(Files.readAllBytes(currentFile.toPath())));
|
||||
// }
|
||||
|
||||
private void loadGitLocal(String id, String file) {
|
||||
// System.out.println("Loading "+file+" from "+id);
|
||||
String[] code;
|
||||
try {
|
||||
code = ScriptingEngine.codeFromGit(id, file);
|
||||
|
||||
if (code != null) {
|
||||
setCode(code[0]);
|
||||
currentFile = ScriptingEngine.fileFromGit(id, file);
|
||||
}
|
||||
isOwnedByLoggedInUser = ScriptingEngine.checkOwner(currentFile);
|
||||
Platform.runLater(() -> {
|
||||
if (isOwnedByLoggedInUser) {
|
||||
edit.setText("Edit...");
|
||||
edit.setGraphic(AssetFactory.loadIcon("Edit-Script.png"));
|
||||
} else {
|
||||
edit.setText("Make Copy");
|
||||
edit.setGraphic(AssetFactory.loadIcon("Make-Copy-Script.png"));
|
||||
}
|
||||
});
|
||||
try {
|
||||
image.setImage(AssetFactory
|
||||
.loadAsset("Script-Tab-" + ScriptingEngine.getShellType(currentFile.getName()) + ".png"));
|
||||
} catch (Exception e2) {
|
||||
// TODO Auto-generated catch block
|
||||
e2.printStackTrace();
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
e.printStackTrace(pw);
|
||||
System.out.println(sw.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public void loadCodeFromGist(String a, WebEngine e) throws Exception {
|
||||
// new Thread(()->{
|
||||
addr = a;
|
||||
engine = e;
|
||||
loadGist = true;
|
||||
fileListBox.valueProperty().removeListener(this);
|
||||
Platform.runLater(() -> runfx.setDisable(true));
|
||||
Platform.runLater(() -> edit.setDisable(true));
|
||||
Platform.runLater(() -> fileListBox.getItems().clear());
|
||||
List<String> gists = ScriptingEngine.getCurrentGist(addr, engine);
|
||||
ArrayList<String> fileList;
|
||||
if (!gists.isEmpty()) {
|
||||
currentGist = gists.get(0);
|
||||
currentGit = "https://gist.github.com/" + currentGist + ".git";
|
||||
} else if (addr.contains("https://github.com/")) {
|
||||
|
||||
if (a.endsWith("/")) {
|
||||
a = a.substring(0, a.length() - 1);
|
||||
}
|
||||
currentGit = a + ".git";
|
||||
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
ArrayList<String> tmp = ScriptingEngine.filesInGit(currentGit);
|
||||
fileList = new ArrayList<>();
|
||||
for (String s : tmp) {
|
||||
if (!s.contains("csgDatabase.json"))// filter out configuration files from the list
|
||||
fileList.add(s);
|
||||
}
|
||||
// for(String s:fileList){
|
||||
// System.out.println("GITS: "+s);
|
||||
// }
|
||||
if (!fileList.isEmpty())
|
||||
loadGitLocal(currentGit, fileList.get(0));
|
||||
|
||||
Platform.runLater(() -> {
|
||||
|
||||
for (String s : fileList) {
|
||||
fileListBox.getItems().add(s);
|
||||
}
|
||||
if (!fileList.isEmpty()) {
|
||||
fileListBox.setValue(fileList.get(0));
|
||||
fileListBox.valueProperty().addListener(this);
|
||||
Platform.runLater(() -> runfx.setDisable(false));
|
||||
Platform.runLater(() -> edit.setDisable(false));
|
||||
}
|
||||
});
|
||||
// }).start();
|
||||
|
||||
}
|
||||
|
||||
private void start() {
|
||||
BowlerStudio.clearConsole();
|
||||
try {
|
||||
ScriptingEngine.setAutoupdate(true);
|
||||
} catch (IOException e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
}
|
||||
running = true;
|
||||
Platform.runLater(() -> {
|
||||
runfx.setText("Stop");
|
||||
runfx.setGraphic(AssetFactory.loadIcon("Stop.png"));
|
||||
runfx.setBackground(new Background(new BackgroundFill(Color.RED, CornerRadii.EMPTY, Insets.EMPTY)));
|
||||
|
||||
});
|
||||
scriptRunner = new Thread() {
|
||||
|
||||
public void run() {
|
||||
String name;
|
||||
try {
|
||||
name = currentFile.getName();
|
||||
} catch (NullPointerException e) {
|
||||
name = "";
|
||||
}
|
||||
try {
|
||||
Object obj = ScriptingEngine.inlineScriptRun(currentFile, null, ScriptingEngine.getShellType(name));
|
||||
for (IScriptEventListener l : listeners) {
|
||||
l.onScriptFinished(obj, scriptResult, currentFile);
|
||||
}
|
||||
|
||||
scriptResult = obj;
|
||||
reset();
|
||||
|
||||
} catch (groovy.lang.MissingPropertyException | org.python.core.PyException d) {
|
||||
Platform.runLater(() -> {
|
||||
Alert alert = new Alert(AlertType.ERROR);
|
||||
alert.setTitle("Device missing error");
|
||||
String message = "This script needs a device connected: ";
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
d.printStackTrace(pw);
|
||||
|
||||
String stackTrace = sw.toString();
|
||||
|
||||
if (stackTrace.contains("dyio"))
|
||||
message += "dyio";
|
||||
else if (stackTrace.contains("camera"))
|
||||
message += "camera";
|
||||
else if (stackTrace.contains("gamepad"))
|
||||
message += "gamepad";
|
||||
else
|
||||
message += stackTrace;
|
||||
alert.setHeaderText(message);
|
||||
alert.setContentText("You need to connect it before running again");
|
||||
alert.showAndWait();
|
||||
if (stackTrace.contains("dyio"))
|
||||
ConnectionManager.addConnection();
|
||||
// else if (stackTrace.contains("camera"))
|
||||
// ConnectionManager.addConnection(new OpenCVImageProvider(0), "camera0");
|
||||
else if (stackTrace.contains("gamepad"))
|
||||
ConnectionManager.onConnectGamePad("gamepad");
|
||||
reset();
|
||||
});
|
||||
|
||||
} catch (Throwable ex) {
|
||||
System.err.println("Script exception of type= " + ex.getClass().getName());
|
||||
Platform.runLater(() -> {
|
||||
try {
|
||||
if (ex.getMessage().contains("sleep interrupted")) {
|
||||
append("\n" + currentFile + " Interupted\n");
|
||||
} else {
|
||||
BowlerStudio.printStackTrace(ex,currentFile);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
ex.printStackTrace(pw);
|
||||
append("\n" + currentFile + " \n" + sw + "\n");
|
||||
}
|
||||
|
||||
reset();
|
||||
});
|
||||
for (IScriptEventListener l : listeners) {
|
||||
l.onScriptError(ex, currentFile);
|
||||
}
|
||||
BowlerStudio.printStackTrace(ex,currentFile);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
// if (loadGist)
|
||||
// loadCodeFromGist(addr, engine);
|
||||
|
||||
scriptRunner.start();
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void append(String s) {
|
||||
System.out.println(s);
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return codeText;
|
||||
}
|
||||
|
||||
public void setCode(String string) {
|
||||
String pervious = codeText;
|
||||
codeText = string;
|
||||
// System.out.println(codeText);
|
||||
for (IScriptEventListener l : listeners) {
|
||||
l.onScriptChanged(pervious, string, currentFile);
|
||||
}
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
if (currentFile != null)
|
||||
return currentFile.getName();
|
||||
else
|
||||
return "Web";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changed(@SuppressWarnings("rawtypes") ObservableValue observable, Object oldValue, Object newValue) {
|
||||
loadGitLocal(currentGit, (String) newValue);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.neuronrobotics.bowlerstudio.scripting;
|
||||
|
||||
public enum ScriptingWidgetType {
|
||||
FILE,
|
||||
WEB,
|
||||
GIST,
|
||||
CREATURE
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.neuronrobotics.bowlerstudio.scripting;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.vitamins.Vitamins;
|
||||
|
||||
import eu.mihosoft.vrl.v3d.CSG;
|
||||
|
||||
public class StlLoader implements IScriptingLanguage {
|
||||
|
||||
@Override
|
||||
public Object inlineScriptRun(File code, ArrayList<Object> args) throws Exception {
|
||||
CSG sllLoaded = Vitamins.get(code);
|
||||
return sllLoaded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object inlineScriptRun(String code, ArrayList<Object> args) throws Exception {
|
||||
throw new RuntimeException("This engine only supports files");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getShellType() {
|
||||
// TODO Auto-generated method stub
|
||||
return "Stl";
|
||||
}
|
||||
@Override
|
||||
public boolean getIsTextFile() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public ArrayList<String> getFileExtenetion() {
|
||||
// TODO Auto-generated method stub
|
||||
return new ArrayList<>(Arrays.asList("stl"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
package com.neuronrobotics.bowlerstudio.tabs;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.BowlerStudioController;
|
||||
import com.neuronrobotics.bowlerstudio.BowlerStudioModularFrame;
|
||||
import com.neuronrobotics.bowlerstudio.creature.MobileBaseCadManager;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.DHParameterKinematics;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.MobileBase;
|
||||
import com.neuronrobotics.sdk.common.BowlerAbstractConnection;
|
||||
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
|
||||
import com.neuronrobotics.sdk.common.IConnectionEventListener;
|
||||
import com.neuronrobotics.sdk.common.IDeviceConnectionEventListener;
|
||||
import com.sun.javafx.scene.control.behavior.TabPaneBehavior;
|
||||
import com.sun.javafx.scene.control.skin.TabPaneSkin;
|
||||
|
||||
import eu.mihosoft.vrl.v3d.CSG;
|
||||
import javafx.application.Platform;
|
||||
import javafx.event.Event;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.control.Tab;
|
||||
|
||||
public abstract class AbstractBowlerStudioTab extends Tab implements EventHandler<Event> {
|
||||
|
||||
private boolean active = false;
|
||||
ArrayList<String> myNames =null;
|
||||
private EventHandler<Event> localCopyOfEventHandler;
|
||||
|
||||
public abstract void onTabClosing();
|
||||
public abstract String[] getMyNameSpaces();
|
||||
public abstract void initializeUI(BowlerAbstractDevice pm);
|
||||
public abstract void onTabReOpening();
|
||||
|
||||
|
||||
public void setDevice(BowlerAbstractDevice pm){
|
||||
myNames = new ArrayList<> ();
|
||||
if(getMyNameSpaces().length>0){
|
||||
for(int i=0;i<getMyNameSpaces().length;i++){
|
||||
myNames.add(getMyNameSpaces()[i]);
|
||||
}
|
||||
if(!isMyNamespace(pm.getNamespaces())){
|
||||
throw new RuntimeException("Device and namespaces are incompatible ");
|
||||
}
|
||||
}
|
||||
setOnCloseRequest(this);
|
||||
initializeUI(pm);
|
||||
pm.addConnectionEventListener(new IDeviceConnectionEventListener() {
|
||||
|
||||
@Override
|
||||
public void onDisconnect(BowlerAbstractDevice source) {
|
||||
//if the device disconnects, close the tab
|
||||
if(source ==pm && source !=null ) {
|
||||
requestClose();
|
||||
if(MobileBase.class.isInstance(pm)) {
|
||||
MobileBase dev = (MobileBase)pm;
|
||||
try {
|
||||
for(CSG p:MobileBaseCadManager.get(dev).getBasetoCadMap().get(dev))
|
||||
BowlerStudioController.removeObject(p);
|
||||
for(DHParameterKinematics leg:dev.getAllDHChains())
|
||||
for(CSG p:MobileBaseCadManager.get(dev).getDHtoCadMap().get(leg))
|
||||
BowlerStudioController.removeObject(p);
|
||||
}catch(Throwable e) {}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Not a bug, expected to ensure one device disconnects the rest of the dependent devices
|
||||
// System.err.println("Device type was "+source.getClass()+" named "+source.getScriptingName()+" expected "+pm.getClass()+" named "+pm.getScriptingName());
|
||||
// new Exception().printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnect(BowlerAbstractDevice source) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public boolean isMyNamespace(ArrayList<String> names) {
|
||||
if (names == null)
|
||||
return false;
|
||||
for(String s:names){
|
||||
for(String m:myNames){
|
||||
if(s.contains(m)){
|
||||
setActive(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isAcvive();
|
||||
}
|
||||
@Override
|
||||
public void setOnCloseRequest(EventHandler<Event> value){
|
||||
this.localCopyOfEventHandler = value;
|
||||
super.setOnCloseRequest(value);
|
||||
System.err.println(" A close requested for "+getText());
|
||||
}
|
||||
public void requestClose() {
|
||||
BowlerStudioModularFrame.getBowlerStudioModularFrame().closeTab(this);
|
||||
}
|
||||
//
|
||||
private TabPaneBehavior getBehavior() {
|
||||
return ((TabPaneSkin) getTabPane().getSkin()).getBehavior();
|
||||
}
|
||||
|
||||
public void setActive(boolean a){
|
||||
active=a;
|
||||
}
|
||||
|
||||
public boolean isAcvive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Event event){
|
||||
System.out.println("Closing "+getText());
|
||||
onTabClosing();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.neuronrobotics.bowlerstudio.tabs;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
|
||||
import com.neuronrobotics.bowlerstudio.assets.BowlerStudioResourceFactory;
|
||||
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
|
||||
import com.neuronrobotics.sdk.dyio.DyIO;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
|
||||
public class DyIOControl extends AbstractBowlerStudioTab {
|
||||
|
||||
private DyIO dyio;
|
||||
DyIOPanel controller ;
|
||||
@Override
|
||||
public void onTabClosing() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getMyNameSpaces() {
|
||||
// TODO Auto-generated method stub
|
||||
return new String[]{"neuronrobotics.dyio.*"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeUI(BowlerAbstractDevice pm) {
|
||||
this.dyio = (DyIO)pm;
|
||||
setGraphic(AssetFactory.loadIcon("DyIO-Tab.png"));
|
||||
|
||||
setText(dyio.getScriptingName());
|
||||
FXMLLoader fxmlLoader = BowlerStudioResourceFactory.getMainPanel();
|
||||
Parent root = fxmlLoader.getRoot();
|
||||
controller = fxmlLoader.getController();
|
||||
controller.setDyIO(dyio);
|
||||
setContent(root);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onTabReOpening() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,425 @@
|
||||
package com.neuronrobotics.bowlerstudio.tabs;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
|
||||
import com.neuronrobotics.bowlerstudio.assets.BowlerStudioResourceFactory;
|
||||
import com.neuronrobotics.sdk.dyio.DyIO;
|
||||
import com.neuronrobotics.sdk.dyio.DyIOChannel;
|
||||
import com.neuronrobotics.sdk.dyio.DyIOChannelMode;
|
||||
import com.neuronrobotics.sdk.util.ThreadUtil;
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.Event;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Circle;
|
||||
import javafx.util.Callback;
|
||||
import org.reactfx.util.FxTimer;
|
||||
|
||||
import java.net.URL;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
//import com.neuronrobotics.nrconsole.plugin.DyIO.DyIOConsole;
|
||||
|
||||
public class DyIOPanel implements Initializable {
|
||||
|
||||
private ArrayList<ComboBox<String>> channelTypeSelectors = new ArrayList<>() ;
|
||||
private ArrayList<ImageView> channelButtonSelectors = new ArrayList<>() ;
|
||||
private ArrayList<Label> channelValue = new ArrayList<>() ;
|
||||
private ArrayList<Parent> controlWidgets = new ArrayList<>() ;
|
||||
private ArrayList<Boolean> displayFlash = new ArrayList<>() ;
|
||||
|
||||
private DyIO dyio;
|
||||
private boolean initialized=false;
|
||||
|
||||
@FXML ImageView chanButton23;
|
||||
@FXML ImageView chanButton22;
|
||||
@FXML ImageView chanButton21;
|
||||
@FXML ImageView chanButton20;
|
||||
@FXML ImageView chanButton19;
|
||||
@FXML ImageView chanButton18;
|
||||
@FXML ImageView chanButton17;
|
||||
@FXML ImageView chanButton16;
|
||||
@FXML ImageView chanButton15;
|
||||
@FXML ImageView chanButton14;
|
||||
@FXML ImageView chanButton13;
|
||||
@FXML ImageView chanButton12;
|
||||
|
||||
@FXML ImageView chanButton11;
|
||||
@FXML ImageView chanButton10;
|
||||
@FXML ImageView chanButton9;
|
||||
@FXML ImageView chanButton8;
|
||||
@FXML ImageView chanButton7;
|
||||
@FXML ImageView chanButton6;
|
||||
@FXML ImageView chanButton5;
|
||||
@FXML ImageView chanButton4;
|
||||
@FXML ImageView chanButton3;
|
||||
@FXML ImageView chanButton2;
|
||||
@FXML ImageView chanButton1;
|
||||
@FXML ImageView chanButton0;
|
||||
@FXML ImageView background;
|
||||
|
||||
@FXML ComboBox<String> channelType23;
|
||||
@FXML ComboBox<String> channelType22;
|
||||
@FXML ComboBox<String> channelType21;
|
||||
@FXML ComboBox<String> channelType20;
|
||||
@FXML ComboBox<String> channelType19;
|
||||
@FXML ComboBox<String> channelType18;
|
||||
@FXML ComboBox<String> channelType17;
|
||||
@FXML ComboBox<String> channelType16;
|
||||
@FXML ComboBox<String> channelType15;
|
||||
@FXML ComboBox<String> channelType14;
|
||||
@FXML ComboBox<String> channelType13;
|
||||
@FXML ComboBox<String> channelType12;
|
||||
@FXML ComboBox<String> channelType11;
|
||||
@FXML ComboBox<String> channelType10;
|
||||
@FXML ComboBox<String> channelType9;
|
||||
@FXML ComboBox<String> channelType8;
|
||||
|
||||
@FXML ComboBox<String> channelType7;
|
||||
@FXML ComboBox<String> channelType6;
|
||||
@FXML ComboBox<String> channelType5;
|
||||
@FXML ComboBox<String> channelType4;
|
||||
@FXML ComboBox<String> channelType3;
|
||||
@FXML ComboBox<String> channelType2;
|
||||
@FXML ComboBox<String> channelType1;
|
||||
@FXML ComboBox<String> channelType0;
|
||||
|
||||
|
||||
@FXML Circle centerled;
|
||||
@FXML Label channelValue0;
|
||||
@FXML Label channelValue1;
|
||||
@FXML Label channelValue2;
|
||||
@FXML Label channelValue3;
|
||||
@FXML Label channelValue4;
|
||||
@FXML Label channelValue5;
|
||||
@FXML Label channelValue6;
|
||||
@FXML Label channelValue7;
|
||||
@FXML Label channelValue8;
|
||||
@FXML Label channelValue9;
|
||||
@FXML Label channelValue10;
|
||||
@FXML Label channelValue11;
|
||||
@FXML Label channelValue12;
|
||||
@FXML Label channelValue13;
|
||||
@FXML Label channelValue14;
|
||||
@FXML Label channelValue15;
|
||||
@FXML Label channelValue16;
|
||||
@FXML Label channelValue17;
|
||||
@FXML Label channelValue18;
|
||||
@FXML Label channelValue19;
|
||||
@FXML Label channelValue20;
|
||||
@FXML Label channelValue21;
|
||||
@FXML Label channelValue22;
|
||||
@FXML Label channelValue23;
|
||||
@FXML AnchorPane controlWidgetPanel;
|
||||
|
||||
|
||||
|
||||
public void setDyIO(DyIO d){
|
||||
d.setServoPowerSafeMode(false);// disable the browout when using the UI
|
||||
channelTypeSelectors.add( channelType0);
|
||||
channelTypeSelectors.add( channelType1);
|
||||
channelTypeSelectors.add( channelType2);
|
||||
channelTypeSelectors.add( channelType3);
|
||||
channelTypeSelectors.add( channelType4);
|
||||
channelTypeSelectors.add( channelType5);
|
||||
channelTypeSelectors.add( channelType6);
|
||||
channelTypeSelectors.add( channelType7);
|
||||
channelTypeSelectors.add( channelType8);
|
||||
channelTypeSelectors.add( channelType9);
|
||||
channelTypeSelectors.add( channelType10);
|
||||
channelTypeSelectors.add( channelType11);
|
||||
channelTypeSelectors.add( channelType12);
|
||||
channelTypeSelectors.add( channelType13);
|
||||
channelTypeSelectors.add( channelType14);
|
||||
channelTypeSelectors.add( channelType15);
|
||||
channelTypeSelectors.add( channelType16);
|
||||
channelTypeSelectors.add( channelType17);
|
||||
channelTypeSelectors.add( channelType18);
|
||||
channelTypeSelectors.add( channelType19);
|
||||
channelTypeSelectors.add( channelType20);
|
||||
channelTypeSelectors.add( channelType21);
|
||||
channelTypeSelectors.add( channelType22);
|
||||
channelTypeSelectors.add( channelType23);
|
||||
|
||||
channelButtonSelectors.add( chanButton0);
|
||||
channelButtonSelectors.add( chanButton1);
|
||||
channelButtonSelectors.add( chanButton2);
|
||||
channelButtonSelectors.add( chanButton3);
|
||||
channelButtonSelectors.add( chanButton4);
|
||||
channelButtonSelectors.add( chanButton5);
|
||||
channelButtonSelectors.add( chanButton6);
|
||||
channelButtonSelectors.add( chanButton7);
|
||||
channelButtonSelectors.add( chanButton8);
|
||||
channelButtonSelectors.add( chanButton9);
|
||||
channelButtonSelectors.add( chanButton10);
|
||||
channelButtonSelectors.add( chanButton11);
|
||||
channelButtonSelectors.add( chanButton12);
|
||||
channelButtonSelectors.add( chanButton13);
|
||||
channelButtonSelectors.add( chanButton14);
|
||||
channelButtonSelectors.add( chanButton15);
|
||||
channelButtonSelectors.add( chanButton16);
|
||||
channelButtonSelectors.add( chanButton17);
|
||||
channelButtonSelectors.add( chanButton18);
|
||||
channelButtonSelectors.add( chanButton19);
|
||||
channelButtonSelectors.add( chanButton20);
|
||||
channelButtonSelectors.add( chanButton21);
|
||||
channelButtonSelectors.add( chanButton22);
|
||||
channelButtonSelectors.add( chanButton23);
|
||||
|
||||
//Values
|
||||
channelValue.add( channelValue0);
|
||||
channelValue.add( channelValue1);
|
||||
channelValue.add( channelValue2);
|
||||
channelValue.add( channelValue3);
|
||||
channelValue.add( channelValue4);
|
||||
channelValue.add( channelValue5);
|
||||
channelValue.add( channelValue6);
|
||||
channelValue.add( channelValue7);
|
||||
channelValue.add( channelValue8);
|
||||
channelValue.add( channelValue9);
|
||||
channelValue.add( channelValue10);
|
||||
channelValue.add( channelValue11);
|
||||
channelValue.add( channelValue12);
|
||||
channelValue.add( channelValue13);
|
||||
channelValue.add( channelValue14);
|
||||
channelValue.add( channelValue15);
|
||||
channelValue.add( channelValue16);
|
||||
channelValue.add( channelValue17);
|
||||
channelValue.add( channelValue18);
|
||||
channelValue.add( channelValue19);
|
||||
channelValue.add( channelValue20);
|
||||
channelValue.add( channelValue21);
|
||||
channelValue.add( channelValue22);
|
||||
channelValue.add( channelValue23);
|
||||
|
||||
try {
|
||||
background.setImage(AssetFactory.loadAsset("dyio/dyio-red2.png"));
|
||||
} catch (Exception e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
this.dyio = d;
|
||||
for (int i = 0; i < 24; i++) {
|
||||
int index = i;
|
||||
ObservableList<String> items = FXCollections.observableArrayList();
|
||||
DyIOChannel chan = dyio.getChannel(index);
|
||||
displayFlash.add(new Boolean(true));
|
||||
Platform.runLater(()->channelValue.get(index).setText(Integer.toString(chan.getValue())));
|
||||
Platform.runLater(()->displayFlash( index,chan.getCachedValue()));
|
||||
chan.addChannelEventListener(e -> {
|
||||
displayFlash( index,e.getValue());
|
||||
});
|
||||
channelButtonSelectors.get(index).setOnMouseEntered(event -> {
|
||||
Platform.runLater(()->
|
||||
channelButtonSelectors.get(index).setImage(BowlerStudioResourceFactory.getChanHighlight()));
|
||||
});
|
||||
channelButtonSelectors.get(index).setOnMouseExited(event -> {
|
||||
Platform.runLater(()->
|
||||
channelButtonSelectors.get(index).setImage(BowlerStudioResourceFactory.getChanDefault()));
|
||||
});
|
||||
channelTypeSelectors.get(index);
|
||||
ArrayList<DyIOChannelMode> modesAvailible = dyio
|
||||
.getAvailibleChannelModes(index);
|
||||
for (DyIOChannelMode m : modesAvailible) {
|
||||
|
||||
items.add(m.toSlug());
|
||||
}
|
||||
Callback<ListView<String>, ListCell<String>> callback =new Callback<ListView<String>, ListCell<String>>() {
|
||||
@Override
|
||||
public ListCell<String> call(ListView<String> p) {
|
||||
return new ListCell<String>() {
|
||||
Label name = new Label();
|
||||
Label icon = new Label();
|
||||
private final HBox cell;
|
||||
{
|
||||
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
|
||||
cell = new HBox(5);
|
||||
|
||||
//HERE, ADD YOUR PRE-MADE HBOX CODE
|
||||
name.setTextFill(Color.BLACK);
|
||||
cell.getChildren().add(icon);
|
||||
cell.getChildren().add(name);
|
||||
}
|
||||
|
||||
@Override protected void updateItem(String item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
|
||||
if (item == null || empty) {
|
||||
setGraphic(null);
|
||||
} else {
|
||||
|
||||
name.setText(item);
|
||||
icon.setGraphic(new ImageView(BowlerStudioResourceFactory.getModeImage(DyIOChannelMode.getFromSlug(item))));
|
||||
setGraphic(cell);
|
||||
//HERE IS WHERE YOU GET THE LABEL AND NAME
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
};
|
||||
Platform.runLater(()->{
|
||||
channelTypeSelectors.get(index).setButtonCell(callback.call(null));
|
||||
channelTypeSelectors.get(index).setCellFactory(callback);
|
||||
channelTypeSelectors.get(index).setItems(items);
|
||||
});
|
||||
setChannelModeList(index);
|
||||
dyio.getChannel(index).addChannelModeChangeListener(newMode -> {
|
||||
setChannelModeList(index);
|
||||
});
|
||||
|
||||
|
||||
|
||||
}
|
||||
new Thread(){
|
||||
public void run(){
|
||||
setName("DyIOchannelWidget Setting channel value ");
|
||||
for (int index = 0; index < 24; index++) {
|
||||
int i=index;
|
||||
|
||||
FXMLLoader fxmlLoader= BowlerStudioResourceFactory.getLoader(i);
|
||||
Parent root = fxmlLoader.getRoot();
|
||||
DyIOchannelWidget controller = fxmlLoader.getController();
|
||||
controller.setChannel(dyio.getChannel(i));
|
||||
controller.setVisable(false);
|
||||
controlWidgets.add(root);
|
||||
|
||||
}
|
||||
initialized=true;
|
||||
while(dyio.isAvailable()){
|
||||
for(int i=0;i<24;i++){
|
||||
DyIOchannelWidget controller =BowlerStudioResourceFactory.getLoader(i).getController();
|
||||
if(controller.isFireValue()){
|
||||
controller.setFireValue(false);
|
||||
dyio.setValue(i,controller.getLatestValue());
|
||||
if(dyio.getMode(i)==DyIOChannelMode.SERVO_OUT && dyio.getChannel(i).getCachedMode()){
|
||||
dyio.getChannel(i).flush();
|
||||
}
|
||||
}
|
||||
|
||||
controller.updateValue();
|
||||
}
|
||||
ThreadUtil.wait(50);
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
|
||||
}
|
||||
|
||||
private void displayFlash(int index,int value){
|
||||
// set the value label text
|
||||
if(displayFlash.get(index)){
|
||||
displayFlash.set(index, false);
|
||||
Platform.runLater(()->{
|
||||
channelValue.get(index).setText(Integer.toString(value));
|
||||
channelButtonSelectors.get(index).setImage(BowlerStudioResourceFactory.getChanUpdate());
|
||||
FxTimer.runLater(
|
||||
Duration.ofMillis(200) ,new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
channelButtonSelectors.get(index).setImage(BowlerStudioResourceFactory.getChanDefault());
|
||||
displayFlash.set(index, true);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@FXML public void channelClicked(MouseEvent event) {
|
||||
int index=getIndex( event);
|
||||
System.err.println("Channel was clicked: "+index);
|
||||
if(!initialized)
|
||||
return;
|
||||
|
||||
setControlWidget( index);
|
||||
}
|
||||
|
||||
private int getIndex(Event event){
|
||||
for(int i=0;i<24;i++){
|
||||
if(channelTypeSelectors.get(i).equals(event.getSource())){
|
||||
return i;
|
||||
}
|
||||
if(channelButtonSelectors.get(i).equals(event.getSource())){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("This event did not come from this system...");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void setChannelModeList(int index){
|
||||
DyIOChannel chan =dyio.getChannel(index);
|
||||
Platform.runLater(()->{
|
||||
ComboBox<String> selector = channelTypeSelectors.get(index);
|
||||
|
||||
String current =null;
|
||||
for(String m:selector.getItems()){
|
||||
if(chan.getMode().toSlug().contentEquals(m)){
|
||||
current=m;
|
||||
}
|
||||
}
|
||||
String tmp =current;
|
||||
selector.setValue(tmp);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void setControlWidget(int index){
|
||||
for(int i=0;i<24;i++){
|
||||
DyIOchannelWidget controller =BowlerStudioResourceFactory.getLoader(i).getController();
|
||||
controller.setVisable(false);
|
||||
}
|
||||
DyIOchannelWidget mine = BowlerStudioResourceFactory.getLoader(index).getController();
|
||||
Platform.runLater(()->{
|
||||
if(!initialized)
|
||||
return;
|
||||
synchronized (controlWidgetPanel) {
|
||||
controlWidgetPanel.getChildren().clear();
|
||||
controlWidgetPanel.getChildren().add(controlWidgets.get(index));
|
||||
}
|
||||
mine.setVisable(true);
|
||||
});
|
||||
}
|
||||
|
||||
@FXML public void onChannelSelect(ActionEvent event) {
|
||||
int index =getIndex( event);
|
||||
ComboBox<String> comboBox = channelTypeSelectors.get(index);
|
||||
String v = comboBox.getValue();
|
||||
if(v==null)
|
||||
return;
|
||||
|
||||
DyIOChannelMode value = DyIOChannelMode.getFromSlug(v);
|
||||
|
||||
if(!initialized)
|
||||
return;
|
||||
new Thread(){
|
||||
public void run(){
|
||||
setName("Running set mode thread");
|
||||
dyio.setMode(index, value);
|
||||
setControlWidget( index);
|
||||
}
|
||||
}.start();
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,376 @@
|
||||
package com.neuronrobotics.bowlerstudio.tabs;
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
||||
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
|
||||
import org.fife.ui.rtextarea.RTextScrollPane;
|
||||
import org.python.core.exceptions;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.BowlerStudioController;
|
||||
import com.neuronrobotics.bowlerstudio.assets.BowlerStudioResourceFactory;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
|
||||
import com.neuronrobotics.sdk.common.Log;
|
||||
//import com.neuronrobotics.nrconsole.plugin.DyIO.DyIOConsole;
|
||||
import com.neuronrobotics.sdk.dyio.DyIOChannel;
|
||||
import com.neuronrobotics.sdk.dyio.DyIOChannelEvent;
|
||||
import com.neuronrobotics.sdk.dyio.DyIOChannelMode;
|
||||
import com.neuronrobotics.sdk.dyio.IChannelEventListener;
|
||||
import com.neuronrobotics.sdk.dyio.peripherals.ServoChannel;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.embed.swing.SwingNode;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.chart.LineChart;
|
||||
import javafx.scene.chart.NumberAxis;
|
||||
import javafx.scene.chart.XYChart;
|
||||
import javafx.scene.chart.XYChart.Data;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Slider;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.Background;
|
||||
import javafx.scene.layout.BackgroundFill;
|
||||
import javafx.scene.layout.CornerRadii;
|
||||
import javafx.scene.paint.Color;
|
||||
|
||||
public class DyIOchannelWidget {
|
||||
|
||||
private boolean fireValue=false;
|
||||
private int latestValue=0;
|
||||
private boolean isVisable=false;
|
||||
private final class ChangeListenerImplementation implements
|
||||
ChangeListener<Number> {
|
||||
public void changed(ObservableValue<? extends Number> ov,
|
||||
Number old_val, Number new_val) {
|
||||
int newVal = new_val.intValue();
|
||||
chanValue.setText(Integer.toString(newVal));
|
||||
if(currentMode==DyIOChannelMode.SERVO_OUT ){
|
||||
if(timeSlider.getValue()>.1){
|
||||
//servo should only set on release when time is defined
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
setLatestValue(newVal);
|
||||
setFireValue(true);
|
||||
}
|
||||
}
|
||||
|
||||
@FXML Button setListenerButton;
|
||||
@FXML AnchorPane listenerCodeBox;
|
||||
@FXML LineChart<Integer,Integer> channelGraph;
|
||||
@FXML Slider timeSlider;
|
||||
@FXML Slider positionSlider;
|
||||
@FXML Label chanValue;
|
||||
@FXML Label deviceType;
|
||||
@FXML Label deviceNumber;
|
||||
@FXML ImageView deviceModeIcon;
|
||||
private DyIOChannel channel;
|
||||
private XYChart.Series<Integer, Integer> series = new XYChart.Series<Integer, Integer>();
|
||||
private long startTime=0;
|
||||
@FXML Label secondsLabel;
|
||||
private IChannelEventListener myLocalListener=null;
|
||||
private RSyntaxTextArea textArea;
|
||||
private SwingNode sn;
|
||||
private RTextScrollPane sp;
|
||||
private ServoChannel srv= null;
|
||||
private DyIOChannelMode currentMode;
|
||||
private ChangeListenerImplementation imp = new ChangeListenerImplementation();
|
||||
@FXML NumberAxis graphValueAxis;
|
||||
@FXML NumberAxis graphTimeAxis;
|
||||
private Integer value=null;
|
||||
|
||||
public void setChannel(DyIOChannel c){
|
||||
|
||||
this.channel = c;
|
||||
startTime=System.currentTimeMillis();
|
||||
setMode( channel.getMode());
|
||||
Platform.runLater(()->deviceNumber.setText(Integer.toString(channel.getChannelNumber())));
|
||||
Platform.runLater(()->chanValue.setText(Integer.toString(channel.getValue())));
|
||||
Platform.runLater(()->secondsLabel.setText(String.format("%.2f", 0.0)));
|
||||
Platform.runLater(()->positionSlider.setValue(channel.getValue()));
|
||||
Platform.runLater(()->graphValueAxis.setAnimated(false));
|
||||
Platform.runLater(()->graphTimeAxis.setAnimated(false));
|
||||
Platform.runLater(()->positionSlider.valueProperty().addListener(imp));
|
||||
|
||||
positionSlider.valueChangingProperty().addListener((ChangeListener<Boolean>) (observable, oldValue, newValue) -> {
|
||||
|
||||
chanValue.setText(Integer.toString((int) positionSlider.getValue()));
|
||||
if(currentMode==DyIOChannelMode.SERVO_OUT && timeSlider.getValue()>.1){
|
||||
new Thread(){
|
||||
public void run(){
|
||||
Platform.runLater(()->setName("Setting servo Pos"));
|
||||
//int ll = Log.getMinimumPrintLevel();
|
||||
try{
|
||||
//Log.enableInfoPrint();
|
||||
srv.SetPosition((int) positionSlider.getValue(), timeSlider.getValue());
|
||||
if(srv.getChannel().getCachedMode())
|
||||
srv.getChannel().flush();
|
||||
}catch(Exception ex){
|
||||
ex.printStackTrace();
|
||||
}
|
||||
//Log.setMinimumPrintLevel(ll);
|
||||
}
|
||||
}.start();
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
timeSlider.valueProperty().addListener(new ChangeListener<Number>() {
|
||||
public void changed(ObservableValue<? extends Number> ov,
|
||||
Number old_val, Number new_val) {
|
||||
secondsLabel.setText(String.format("%.2f", new_val));
|
||||
}
|
||||
});
|
||||
channel.addChannelModeChangeListener(newMode -> {
|
||||
setMode( newMode);
|
||||
});
|
||||
|
||||
|
||||
channel.addChannelEventListener(new IChannelEventListener() {
|
||||
|
||||
|
||||
@Override
|
||||
public void onChannelEvent(DyIOChannelEvent dyioEvent) {
|
||||
if(isVisable()){
|
||||
setValue(new Integer(dyioEvent.getValue()));
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
Platform.runLater(()->{
|
||||
channelGraph.getData().clear();
|
||||
try{
|
||||
channelGraph.getData().add(series);
|
||||
}catch(Exception e){}
|
||||
|
||||
});
|
||||
|
||||
setUpListenerPanel();
|
||||
Platform.runLater(()->setListenerButton.setBackground(new Background(new BackgroundFill(Color.GREEN, CornerRadii.EMPTY, Insets.EMPTY))));
|
||||
|
||||
}
|
||||
|
||||
public void updateValue(){
|
||||
|
||||
if(getValue()!=null){
|
||||
int current = getValue();
|
||||
Data<Integer, Integer> newChart = new XYChart.Data<Integer, Integer>(
|
||||
(int) (startTime-System.currentTimeMillis()),
|
||||
current);
|
||||
Platform.runLater(()->chanValue.setText(Integer.toString(current)));
|
||||
if(!positionSlider.isValueChanging()){// only updae the slider position if the user is not sliding it
|
||||
Platform.runLater(()->{
|
||||
if(positionSlider==null)
|
||||
return;
|
||||
positionSlider.valueProperty().removeListener(imp);
|
||||
positionSlider.setValue(current);
|
||||
setLatestValue(current);
|
||||
setFireValue(false);
|
||||
positionSlider.valueProperty().addListener(imp);
|
||||
});
|
||||
}
|
||||
Platform.runLater(()->{
|
||||
if(series.getData().size()>10){// if you keep many more points in the graph it will lag the rendering realy badly
|
||||
series.getData().remove(0);
|
||||
}
|
||||
|
||||
Platform.runLater(()->{
|
||||
series.getData().add(newChart);
|
||||
value=null;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void setMode(DyIOChannelMode newMode){
|
||||
currentMode = newMode;
|
||||
Platform.runLater(()->{
|
||||
|
||||
deviceModeIcon.setImage(BowlerStudioResourceFactory.getModeImage(newMode));
|
||||
series.setName(currentMode.toSlug()+" values");
|
||||
deviceType.setText(currentMode.toSlug());
|
||||
//set slider bounds
|
||||
graphValueAxis.setAutoRanging(false);
|
||||
switch(currentMode){
|
||||
case ANALOG_IN:
|
||||
positionSlider.setMin(0);
|
||||
positionSlider.setMax(1024);
|
||||
graphValueAxis.setLowerBound(0);
|
||||
graphValueAxis.setUpperBound(1024);
|
||||
|
||||
break;
|
||||
case COUNT_IN_DIR:
|
||||
case COUNT_IN_HOME:
|
||||
case COUNT_IN_INT:
|
||||
case COUNT_OUT_DIR:
|
||||
case COUNT_OUT_HOME:
|
||||
case COUNT_OUT_INT:
|
||||
positionSlider.setMin(-5000);
|
||||
positionSlider.setMax(5000);
|
||||
graphValueAxis.setLowerBound(-5000);
|
||||
graphValueAxis.setUpperBound(5000);
|
||||
break;
|
||||
case DC_MOTOR_DIR:
|
||||
case DC_MOTOR_VEL:
|
||||
case PWM_OUT:
|
||||
case SERVO_OUT:
|
||||
positionSlider.setMin(0);
|
||||
positionSlider.setMax(255);
|
||||
graphValueAxis.setLowerBound(0);
|
||||
graphValueAxis.setUpperBound(255);
|
||||
break;
|
||||
case DIGITAL_IN:
|
||||
case DIGITAL_OUT:
|
||||
positionSlider.setMin(0);
|
||||
positionSlider.setMax(1);
|
||||
graphValueAxis.setLowerBound(0);
|
||||
graphValueAxis.setUpperBound(1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
// allow slider to be disabled for inputs
|
||||
switch(currentMode){
|
||||
case ANALOG_IN:
|
||||
case COUNT_IN_DIR:
|
||||
case COUNT_IN_HOME:
|
||||
case COUNT_IN_INT:
|
||||
case DIGITAL_IN:
|
||||
timeSlider.setDisable(true);
|
||||
positionSlider.setDisable(true);
|
||||
break;
|
||||
|
||||
default:
|
||||
timeSlider.setDisable(false);
|
||||
positionSlider.setDisable(false);
|
||||
break;
|
||||
|
||||
}
|
||||
setLatestValue(channel.getValue());
|
||||
if(currentMode==DyIOChannelMode.SERVO_OUT && srv==null){
|
||||
new Thread(){
|
||||
public void run(){
|
||||
setName("Connectiong servo object");
|
||||
srv = new ServoChannel(channel);
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@FXML public void onListenerButtonClicked(ActionEvent event) {
|
||||
new Thread(){
|
||||
public void run(){
|
||||
setName("compiling listener");
|
||||
try{
|
||||
if(myLocalListener==null){
|
||||
Platform.runLater(()->{
|
||||
sn.setDisable(true);
|
||||
textArea.setEditable(false);
|
||||
});
|
||||
myLocalListener=(IChannelEventListener) ScriptingEngine.inlineScriptStringRun(textArea.getText(), null, "Groovy");
|
||||
channel.addChannelEventListener(myLocalListener);
|
||||
Platform.runLater(()->{
|
||||
setListenerButton.setText("Kill Listener");
|
||||
setListenerButton.setBackground(new Background(new BackgroundFill(Color.RED, CornerRadii.EMPTY, Insets.EMPTY)));
|
||||
});
|
||||
}else{
|
||||
channel.removeChannelEventListener(myLocalListener);
|
||||
Platform.runLater(()->{
|
||||
sn.setDisable(false);
|
||||
textArea.setEditable(true);
|
||||
myLocalListener=null;
|
||||
setListenerButton.setBackground(new Background(new BackgroundFill(Color.GREEN, CornerRadii.EMPTY, Insets.EMPTY)));
|
||||
setListenerButton.setText("Set Listener");
|
||||
});
|
||||
}
|
||||
}catch(Exception e){
|
||||
BowlerStudioController.highlightException(null, e);
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void setUpListenerPanel(){
|
||||
//Platform.runLater(()->{
|
||||
textArea = new RSyntaxTextArea(15, 80);
|
||||
textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_GROOVY);
|
||||
textArea.setCodeFoldingEnabled(true);
|
||||
textArea.setText("return new IChannelEventListener() { \n"+
|
||||
"\tpublic \n"
|
||||
+ "\tvoid onChannelEvent(DyIOChannelEvent dyioEvent){\n"+
|
||||
"\t\tprintln \"From Listener=\"+dyioEvent.getValue();\n"+
|
||||
"\t}\n"+
|
||||
"}"
|
||||
);
|
||||
sp = new RTextScrollPane(textArea);
|
||||
|
||||
sn = new SwingNode();
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
sn.setContent(sp);
|
||||
}
|
||||
});
|
||||
|
||||
Platform.runLater(()->listenerCodeBox.getChildren().setAll(sn));
|
||||
|
||||
listenerCodeBox.setFocusTraversable(false);
|
||||
|
||||
sn.setOnMouseEntered(mouseEvent -> {
|
||||
sn.requestFocus();
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
textArea.requestFocusInWindow();
|
||||
}
|
||||
});
|
||||
});
|
||||
//});
|
||||
}
|
||||
|
||||
public boolean isVisable() {
|
||||
return isVisable;
|
||||
}
|
||||
|
||||
public void setVisable(boolean isVisable) {
|
||||
Platform.runLater(()->series.getData().clear());
|
||||
this.isVisable = isVisable;
|
||||
}
|
||||
|
||||
public boolean isFireValue() {
|
||||
return fireValue;
|
||||
}
|
||||
|
||||
public void setFireValue(boolean fireValue) {
|
||||
this.fireValue = fireValue;
|
||||
}
|
||||
|
||||
public int getLatestValue() {
|
||||
return latestValue;
|
||||
}
|
||||
|
||||
public void setLatestValue(int latestValue) {
|
||||
this.latestValue = latestValue;
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Integer value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.neuronrobotics.bowlerstudio.tabs;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
|
||||
import org.firmata4j.IODevice;
|
||||
import org.firmata4j.firmata.FirmataDevice;
|
||||
import org.firmata4j.ui.JPinboard;
|
||||
|
||||
import com.neuronrobotics.sdk.addons.kinematics.FirmataBowler;
|
||||
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
|
||||
|
||||
import javafx.embed.swing.SwingNode;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
|
||||
public class FirmataTab extends AbstractBowlerStudioTab {
|
||||
|
||||
@Override
|
||||
public void onTabClosing() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getMyNameSpaces() {
|
||||
// TODO Auto-generated method stub
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeUI(BowlerAbstractDevice pm) {
|
||||
FirmataDevice device =( (FirmataBowler) pm).getFirmataDevice();
|
||||
// TODO Auto-generated method stub
|
||||
JFrame frame = new JFrame("Pinboard Example");
|
||||
frame.add(new JPinboard(device ));
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
|
||||
JPinboard pinboard = new JPinboard(device );
|
||||
pinboard.setVisible(true);
|
||||
SwingNode sn = new SwingNode();
|
||||
sn.setContent(pinboard);
|
||||
ScrollPane s1 = new ScrollPane();
|
||||
|
||||
s1.setContent(sn);
|
||||
setContent(s1);
|
||||
setText("Firmata Pinpoard");
|
||||
onTabReOpening();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabReOpening() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,510 @@
|
||||
package com.neuronrobotics.bowlerstudio.tabs;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.ComponentListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
import java.time.Duration;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
||||
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
|
||||
import org.fife.ui.rtextarea.RTextScrollPane;
|
||||
import org.reactfx.util.FxTimer;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.CaretEvent;
|
||||
import javax.swing.event.CaretListener;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.DefaultHighlighter;
|
||||
import javax.swing.text.Highlighter;
|
||||
import javax.swing.text.Highlighter.HighlightPainter;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.embed.swing.MySwingNode;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.BowlerStudio;
|
||||
import com.neuronrobotics.bowlerstudio.IssueReportingExceptionHandler;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.IScriptEventListener;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.ScriptingFileWidget;
|
||||
import com.neuronrobotics.bowlerstudio.utils.FindTextWidget;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.WindowEvent;
|
||||
|
||||
public class LocalFileScriptTab extends VBox implements IScriptEventListener, EventHandler<WindowEvent> {
|
||||
private static final UncaughtExceptionHandler ISSUE_REPORTING_EXCEPTION_HANDLER =new UncaughtExceptionHandler() {
|
||||
IssueReportingExceptionHandler reporter = new IssueReportingExceptionHandler();
|
||||
@Override
|
||||
public void uncaughtException(Thread t, Throwable e) {
|
||||
if(reporter.getTitle(e).contains("java.awt.datatransfer.DataFlavor at line 503")) {
|
||||
System.err.println("Known bug in the Swing system, nothing we can do but ignore it");
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
reporter.uncaughtException(t, e);
|
||||
}
|
||||
};// new IssueReportingExceptionHandler();
|
||||
private long lastRefresh = 0;
|
||||
private ScriptingFileWidget scripting;
|
||||
|
||||
IScriptEventListener l = null;
|
||||
|
||||
private MySwingNode swingNode;
|
||||
private RTextScrollPane spscrollPane;
|
||||
|
||||
private Highlighter highlighter;
|
||||
|
||||
private HighlightPainter painter;
|
||||
private int lineSelected = 0;
|
||||
|
||||
private MyRSyntaxTextArea textArea = new MyRSyntaxTextArea(200, 300);
|
||||
|
||||
private final File file;
|
||||
|
||||
private Font myFont;
|
||||
|
||||
private static HashMap<String, String> langaugeMapping = new HashMap<>();
|
||||
|
||||
private static LocalFileScriptTab selectedTab = null;
|
||||
static {
|
||||
SwingUtilities.invokeLater(() -> Thread.setDefaultUncaughtExceptionHandler(new IssueReportingExceptionHandler()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class MyRSyntaxTextArea extends RSyntaxTextArea implements ComponentListener {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public MyRSyntaxTextArea() {
|
||||
this.addComponentListener(this);
|
||||
}
|
||||
|
||||
public MyRSyntaxTextArea(int i, int j) {
|
||||
super(i, j);
|
||||
}
|
||||
|
||||
public void componentResized(ComponentEvent e) {
|
||||
System.err.println("componentResized");
|
||||
|
||||
}
|
||||
|
||||
public void componentHidden(ComponentEvent e) {
|
||||
System.err.println("componentHidden");
|
||||
}
|
||||
|
||||
public void componentMoved(ComponentEvent e) {
|
||||
System.err.println("componentMoved");
|
||||
}
|
||||
|
||||
public void componentShown(ComponentEvent e) {
|
||||
System.err.println("componentShown");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void setExtentionSyntaxType(String shellType, String syntax) {
|
||||
langaugeMapping.put(shellType, syntax);
|
||||
}
|
||||
|
||||
public LocalFileScriptTab(File file) throws IOException {
|
||||
Thread.setDefaultUncaughtExceptionHandler(new IssueReportingExceptionHandler());
|
||||
this.file = file;
|
||||
setScripting(new ScriptingFileWidget(file));
|
||||
setSpacing(5);
|
||||
l = this;
|
||||
|
||||
getScripting().addIScriptEventListener(l);
|
||||
String type;
|
||||
|
||||
String shellType = ScriptingEngine.getShellType(file.getName());
|
||||
switch (shellType) {
|
||||
case "Clojure":
|
||||
type = SyntaxConstants.SYNTAX_STYLE_CLOJURE;
|
||||
break;
|
||||
default:
|
||||
type = langaugeMapping.get(shellType);
|
||||
if (type == null) {
|
||||
type = SyntaxConstants.SYNTAX_STYLE_NONE;
|
||||
if (shellType.toLowerCase().contains("arduino")) {
|
||||
type = SyntaxConstants.SYNTAX_STYLE_CPLUSPLUS;
|
||||
}
|
||||
}
|
||||
case "JSON":
|
||||
type = SyntaxConstants.SYNTAX_STYLE_JSON;
|
||||
break;
|
||||
case "ArduingScriptingLangauge":
|
||||
type = SyntaxConstants.SYNTAX_STYLE_LISP;
|
||||
break;
|
||||
case "Arduino":
|
||||
type = SyntaxConstants.SYNTAX_STYLE_CPLUSPLUS;
|
||||
break;
|
||||
case "Groovy":
|
||||
type = SyntaxConstants.SYNTAX_STYLE_GROOVY;
|
||||
break;
|
||||
case "Jython":
|
||||
type = SyntaxConstants.SYNTAX_STYLE_PYTHON;
|
||||
break;
|
||||
case "MobilBaseXML":
|
||||
type = SyntaxConstants.SYNTAX_STYLE_XML;
|
||||
break;
|
||||
case "Kotlin":
|
||||
type = SyntaxConstants.SYNTAX_STYLE_JAVA;
|
||||
break;
|
||||
case "SVG":
|
||||
type = SyntaxConstants.SYNTAX_STYLE_XML;
|
||||
break;
|
||||
}
|
||||
textArea.setSyntaxEditingStyle(type);
|
||||
textArea.setCodeFoldingEnabled(true);
|
||||
|
||||
textArea.getDocument().addDocumentListener(new DocumentListener() {
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent arg0) {
|
||||
System.err.println("changedUpdate " + file);
|
||||
new Thread() {
|
||||
public void run() {
|
||||
getScripting().removeIScriptEventListener(l);
|
||||
getScripting().setCode(textArea.getText());
|
||||
getScripting().addIScriptEventListener(l);
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
});
|
||||
textArea.addCaretListener(new CaretListener() {
|
||||
|
||||
@Override
|
||||
public void caretUpdate(CaretEvent e) {
|
||||
|
||||
// Lets start with some default values for the line and column.
|
||||
int linenum = 1;
|
||||
int columnnum = 1;
|
||||
|
||||
// We create a try catch to catch any exceptions. We will simply
|
||||
// ignore such an error for our demonstration.
|
||||
try {
|
||||
// First we find the position of the caret. This is the
|
||||
// number of where the caret is in relation to the start of
|
||||
// the JTextArea
|
||||
// in the upper left corner. We use this position to find
|
||||
// offset values (eg what line we are on for the given
|
||||
// position as well as
|
||||
// what position that line starts on.
|
||||
int caretpos = textArea.getCaretPosition();
|
||||
linenum = textArea.getLineOfOffset(caretpos);
|
||||
|
||||
// We subtract the offset of where our line starts from the
|
||||
// overall caret position.
|
||||
// So lets say that we are on line 5 and that line starts at
|
||||
// caret position 100, if our caret position is currently
|
||||
// 106
|
||||
// we know that we must be on column 6 of line 5.
|
||||
columnnum = caretpos - textArea.getLineStartOffset(linenum);
|
||||
|
||||
// We have to add one here because line numbers start at 0
|
||||
// for getLineOfOffset and we want it to start at 1 for
|
||||
// display.
|
||||
linenum += 1;
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
if (lineSelected != linenum) {
|
||||
lineSelected = linenum;
|
||||
// System.err.println("Select "+lineSelected);
|
||||
new Thread(() -> {
|
||||
BowlerStudio.select(file, lineSelected);
|
||||
}).start();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
textArea.addMouseListener(new MouseAdapter() {
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() > 2) {
|
||||
highlighter.removeAllHighlights();
|
||||
}
|
||||
// System.out.println("Number of click: " + e.getClickCount());
|
||||
// System.out.println("Click position (X, Y): " + e.getX() + ",
|
||||
// " + e.getY());
|
||||
}
|
||||
});
|
||||
|
||||
spscrollPane = new RTextScrollPane(textArea);
|
||||
|
||||
swingNode = new MySwingNode(this);
|
||||
|
||||
SwingUtilities.invokeLater(() -> swingNode.setContent(spscrollPane));
|
||||
|
||||
getScripting().setFocusTraversable(false);
|
||||
|
||||
getChildren().setAll(swingNode, getScripting());
|
||||
swingNode.setOnMouseEntered(mouseEvent -> {
|
||||
//System.err.println("On mouse entered " + file.getName());
|
||||
//resizeEvent();
|
||||
SwingUtilities.invokeLater(() ->{
|
||||
resizeEvent();
|
||||
setSelectedTab(this);
|
||||
// spscrollPane.setSize((int) spscrollPane.getWidth(), (int) spscrollPane.getHeight());
|
||||
// spscrollPane.invalidate();
|
||||
// spscrollPane.repaint();
|
||||
// textArea.invalidate();
|
||||
// textArea.repaint();
|
||||
// textArea.requestFocusInWindow();
|
||||
// FxTimer.runLater(Duration.ofMillis((int) 16), () -> {
|
||||
// swingNode.requestFocus();
|
||||
// });
|
||||
});
|
||||
});
|
||||
// textArea
|
||||
KeyStroke keystroke = KeyStroke.getKeyStroke(KeyEvent.VK_F, KeyEvent.CTRL_MASK);
|
||||
textArea.getInputMap().put(keystroke, "f");
|
||||
textArea.getActionMap().put("f", new AbstractAction() {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -4698223073831405851L;
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
||||
findTextWidget();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
myFont = textArea.getFont();
|
||||
highlighter = textArea.getHighlighter();
|
||||
painter = new DefaultHighlighter.DefaultHighlightPainter(Color.pink);
|
||||
|
||||
highlighter.removeAllHighlights();
|
||||
|
||||
// widthProperty().addListener((w, o, n) -> {
|
||||
// resizeEvent();
|
||||
//
|
||||
// });
|
||||
// heightProperty().addListener((w, o, n) -> {
|
||||
// resizeEvent();
|
||||
// });
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
if (getScripting() != null && getScripting().getCode() != null) {
|
||||
onScriptChanged(null, getScripting().getCode(), file);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void resizeEvent() {
|
||||
if (!((lastRefresh + 60) < System.currentTimeMillis())||
|
||||
spscrollPane.getVerticalScrollBar().getValueIsAdjusting()||
|
||||
spscrollPane.getHorizontalScrollBar().getValueIsAdjusting()) {
|
||||
return;
|
||||
}
|
||||
lastRefresh = System.currentTimeMillis();
|
||||
SwingUtilities.invokeLater(() ->{
|
||||
spscrollPane.setSize((int) spscrollPane.getWidth(), (int) spscrollPane.getHeight());
|
||||
spscrollPane.invalidate();
|
||||
spscrollPane.repaint();
|
||||
textArea.invalidate();
|
||||
textArea.repaint();
|
||||
|
||||
textArea.requestFocusInWindow();
|
||||
FxTimer.runLater(Duration.ofMillis((int) 16), () -> {
|
||||
swingNode.setContent(spscrollPane);
|
||||
swingNode.requestFocus();
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScriptFinished(Object result, Object previous, File source) {
|
||||
// SwingUtilities.invokeLater(new Runnable() {
|
||||
// @Override
|
||||
// public void run() {
|
||||
// textArea.requestFocusInWindow();
|
||||
// }
|
||||
// });
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScriptChanged(String previous, String current, File source) {
|
||||
// int place = textArea.getCaretPosition();
|
||||
// System.err.println("Carrot position is= "+place);
|
||||
// codeArea.replaceText(current);
|
||||
// codeArea.setCursor(place);
|
||||
|
||||
if (current.length() > 3 && !textArea.getText().contentEquals(current)) {// no
|
||||
// empty
|
||||
// writes
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
textArea.setText(current);
|
||||
if (previous == null)
|
||||
SwingUtilities.invokeLater(() -> textArea.setCaretPosition(0));
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScriptError(Throwable except, File source) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println("script error");
|
||||
textArea.requestFocusInWindow();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void findTextWidget() {
|
||||
Platform.runLater(() -> {
|
||||
Stage s = new Stage();
|
||||
new Thread() {
|
||||
public void run() {
|
||||
Thread.setDefaultUncaughtExceptionHandler(ISSUE_REPORTING_EXCEPTION_HANDLER);
|
||||
|
||||
FindTextWidget controller = new FindTextWidget();
|
||||
controller.setTextArea(textArea);
|
||||
try {
|
||||
controller.start(s);
|
||||
} catch (Exception e) {
|
||||
ISSUE_REPORTING_EXCEPTION_HANDLER.uncaughtException(Thread.currentThread(), e);
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(WindowEvent event) {
|
||||
getScripting().stop();
|
||||
}
|
||||
|
||||
public ScriptingFileWidget getScripting() {
|
||||
return scripting;
|
||||
}
|
||||
|
||||
public void setScripting(ScriptingFileWidget scripting) {
|
||||
this.scripting = scripting;
|
||||
}
|
||||
|
||||
public void setHighlight(int lineNumber, Color color) throws BadLocationException {
|
||||
if (textArea == null) {
|
||||
return;
|
||||
}
|
||||
painter = new DefaultHighlighter.DefaultHighlightPainter(color);
|
||||
int startIndex = textArea.getLineStartOffset(lineNumber - 1);
|
||||
int endIndex = textArea.getLineEndOffset(lineNumber - 1);
|
||||
|
||||
try {
|
||||
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
textArea.moveCaretPosition(startIndex);
|
||||
});
|
||||
} catch (Error | Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
try {
|
||||
textArea.getHighlighter().addHighlight(startIndex, endIndex, painter);
|
||||
} catch (BadLocationException e) {
|
||||
ISSUE_REPORTING_EXCEPTION_HANDLER.uncaughtException(Thread.currentThread(), e);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void clearHighlits() {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
highlighter.removeAllHighlights();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public int getFontSize() {
|
||||
return myFont.getSize();
|
||||
}
|
||||
|
||||
public void setFontSize(int size) {
|
||||
myFont = new Font(myFont.getName(), myFont.getStyle(), size);
|
||||
setFontLoop();
|
||||
}
|
||||
|
||||
private void setFontLoop() {
|
||||
FxTimer.runLater(Duration.ofMillis(200), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Thread.setDefaultUncaughtExceptionHandler(ISSUE_REPORTING_EXCEPTION_HANDLER);
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
try {
|
||||
textArea.setFont(myFont);
|
||||
} catch (Throwable ex) {
|
||||
//ISSUE_REPORTING_EXCEPTION_HANDLER.uncaughtException(Thread.currentThread(), ex);
|
||||
setFontLoop();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static LocalFileScriptTab getSelectedTab() {
|
||||
return selectedTab;
|
||||
}
|
||||
|
||||
public static void setSelectedTab(LocalFileScriptTab selectedTab) {
|
||||
//System.err.println("Currently selected "+selectedTab.file.getAbsolutePath());
|
||||
LocalFileScriptTab.selectedTab = selectedTab;
|
||||
}
|
||||
|
||||
public void insertString(String string) {
|
||||
int caretpos = textArea.getCaretPosition();
|
||||
String text = textArea.getText();
|
||||
String substring = text.substring(0,caretpos);
|
||||
String substring2;
|
||||
try {
|
||||
substring2 = text.substring(caretpos,text.length());
|
||||
}catch(java.lang.StringIndexOutOfBoundsException ex) {
|
||||
substring2="";
|
||||
}
|
||||
String combined = substring+string+substring2;
|
||||
onScriptChanged(text, combined, file);
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
textArea.setCaretPosition(caretpos+string.length());
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,384 @@
|
||||
package com.neuronrobotics.bowlerstudio.tabs;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.BowlerStudioController;
|
||||
import com.neuronrobotics.bowlerstudio.Tutorial;
|
||||
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.PasswordManager;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
|
||||
import com.neuronrobotics.bowlerstudio.scripting.ScriptingWebWidget;
|
||||
import com.neuronrobotics.sdk.common.Log;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.concurrent.Worker.State;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.Event;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.web.WebEngine;
|
||||
import javafx.scene.web.WebHistory;
|
||||
import javafx.scene.web.WebView;
|
||||
import org.reactfx.util.FxTimer;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.time.Duration;
|
||||
|
||||
public class WebTab extends Tab implements EventHandler<Event>{
|
||||
|
||||
private String Current_URL = "http://gist.github.com/";
|
||||
|
||||
private WebTab myTab;
|
||||
boolean loaded=false;
|
||||
boolean initialized=false;
|
||||
private WebView webView;
|
||||
private WebEngine webEngine;
|
||||
private VBox vBox;
|
||||
private Button goButton = new Button("");
|
||||
private Button homeButton = new Button("");
|
||||
private Button backButton = new Button("");
|
||||
private Button forwardButton = new Button("");
|
||||
|
||||
private TextField urlField;
|
||||
//private String currentAddress;
|
||||
private ScriptingWebWidget scripting;
|
||||
private Graphics2D splashGraphics;
|
||||
private static boolean firstBoot=true;
|
||||
|
||||
private boolean isTutorialTab =false;
|
||||
|
||||
private boolean finishedLoadingScriptingWidget;
|
||||
|
||||
private static BowlerStudioController controller;
|
||||
|
||||
public WebTab(String title, String Url) throws IOException, InterruptedException{
|
||||
this(title,Url,false);
|
||||
}
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public WebTab(String title, String Url,boolean isTutorialTab) throws IOException, InterruptedException{
|
||||
|
||||
if(isTutorialTab){
|
||||
setGraphic(AssetFactory.loadIcon("Tutorial-Tab.png"));
|
||||
}else
|
||||
setGraphic(AssetFactory.loadIcon("Web-Tab.png"));
|
||||
goButton.setGraphic(AssetFactory.loadIcon("Go-Refresh.png"));
|
||||
homeButton.setGraphic(AssetFactory.loadIcon("Home.png"));
|
||||
backButton.setGraphic(AssetFactory.loadIcon("Back-Button.png"));
|
||||
forwardButton.setGraphic(AssetFactory.loadIcon("Forward-Button.png"));
|
||||
|
||||
this.isTutorialTab = isTutorialTab;
|
||||
myTab = this;
|
||||
|
||||
if(title==null)
|
||||
myTab.setText(" ");
|
||||
else
|
||||
myTab.setText(title);
|
||||
Log.debug("Loading Gist Tab: "+Url);
|
||||
webView = new WebView();
|
||||
webEngine = webView.getEngine();
|
||||
//webEngine.setUserAgent("bowlerstudio");
|
||||
if(Url!=null)
|
||||
Current_URL=Url;
|
||||
|
||||
|
||||
|
||||
loaded=false;
|
||||
setOnCloseRequest(this);
|
||||
webEngine.getLoadWorker().workDoneProperty().addListener((ChangeListener<Number>) (observableValue, oldValue, newValue) -> Platform.runLater(() -> {
|
||||
if(!(newValue.intValue()<100)){
|
||||
//System.err.println("Just finished! "+webEngine.getLocation());
|
||||
|
||||
new Thread(){
|
||||
public void run(){
|
||||
if(!initialized){
|
||||
initialized=true;
|
||||
loaded=true;
|
||||
setName("Start finalizing components");
|
||||
finishLoadingComponents();
|
||||
}
|
||||
|
||||
else{
|
||||
try {
|
||||
getScripting().loadCodeFromGist(Current_URL, webEngine);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
//e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
|
||||
|
||||
}else{
|
||||
loaded=false;
|
||||
// if(splashGraphics!=null && splash.isVisible()){
|
||||
// //BowlerStudio.renderSplashFrame(splashGraphics, newValue.intValue());
|
||||
// //splash.update();
|
||||
// }
|
||||
//System.err.println("Not Done Loading to: "+webEngine.getLocation());
|
||||
}
|
||||
}));
|
||||
urlField = new TextField(Current_URL);
|
||||
webEngine.locationProperty().addListener(new ChangeListener<String>() {
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends String> observable1,String oldValue, String newValue) {
|
||||
|
||||
//System.out.println("Location Changed: "+newValue);
|
||||
Platform.runLater(() -> {
|
||||
urlField.setText(newValue);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
//goButton.setDefaultButton(true);
|
||||
|
||||
webEngine.getLoadWorker().stateProperty().addListener(
|
||||
new ChangeListener<Object>() {
|
||||
public void changed(ObservableValue<?> observable,
|
||||
Object oldValue, Object newValue) {
|
||||
if (State.SUCCEEDED == newValue) {
|
||||
Current_URL = urlField.getText().startsWith("http://")|| urlField.getText().startsWith("https://")|| urlField.getText().startsWith("file:")
|
||||
? urlField.getText()
|
||||
: "http://" + urlField.getText();
|
||||
|
||||
Log.debug("Load Worker State Changed "+Current_URL);
|
||||
if( !processNewTab(urlField.getText())){
|
||||
goBack();
|
||||
}
|
||||
}else{
|
||||
//Log.error("State load fault: "+newValue+" object:" +observable);
|
||||
}
|
||||
}
|
||||
});
|
||||
backButton.setOnAction(arg0 -> {
|
||||
goBack();
|
||||
});
|
||||
forwardButton.setOnAction(arg0 -> {
|
||||
// TODO Auto-generated method stub
|
||||
goForward();
|
||||
});
|
||||
homeButton.setOnAction(arg0 -> {
|
||||
// TODO Auto-generated method stub
|
||||
try {
|
||||
loadUrl(Tutorial.getHomeUrl());
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
// Layout logic
|
||||
HBox hBox = new HBox(5);
|
||||
hBox.getChildren().setAll(backButton,forwardButton,homeButton,goButton,urlField);
|
||||
HBox.setHgrow(urlField, Priority.ALWAYS);
|
||||
|
||||
vBox = new VBox(5);
|
||||
vBox.getChildren().setAll(hBox, webView);
|
||||
VBox.setVgrow(webView, Priority.ALWAYS);
|
||||
|
||||
myTab.setContent(vBox);
|
||||
//Action definition for the Button Go.
|
||||
EventHandler<ActionEvent> goAction = event -> {
|
||||
Log.debug("Hitting load");
|
||||
if(processNewTab(urlField.getText())){
|
||||
Log.debug("Loading "+Current_URL);
|
||||
loadUrl( Current_URL);
|
||||
}
|
||||
};
|
||||
urlField.setOnAction(goAction);
|
||||
goButton.setOnAction(goAction);
|
||||
//Once all components are loaded, load URL
|
||||
FxTimer.runLater(
|
||||
Duration.ofMillis(200) ,new Runnable() {
|
||||
@Override
|
||||
public void run() { goAction.handle(null);}
|
||||
});
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void loadUrl(String url){
|
||||
|
||||
if(processNewTab(Current_URL)){
|
||||
Platform.runLater(() -> {
|
||||
webEngine.load(url);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean processNewTab(String url){
|
||||
Current_URL = urlField.getText().startsWith("http://") || urlField.getText().startsWith("https://") || urlField.getText().startsWith("file:")
|
||||
? urlField.getText()
|
||||
: "http://" + urlField.getText();
|
||||
if(isTutorialTab ){
|
||||
if( !((Current_URL.toLowerCase().contains("commonwealthrobotics.com") ||
|
||||
Current_URL.contains("gist.github.com/"+PasswordManager.getUsername() )||
|
||||
Current_URL.contains("localhost") ))){
|
||||
try {
|
||||
|
||||
Log.error("Non demo page found, opening new tab "+Current_URL);
|
||||
BowlerStudioController.getBowlerStudio().addTab(new WebTab(null, Current_URL), true);
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}else{
|
||||
Log.debug("no load new tab");
|
||||
if(getScripting()!=null){
|
||||
try{
|
||||
myTab.setText(getScripting().getFileName());
|
||||
}catch(java.lang.NullPointerException ex){
|
||||
try {
|
||||
getScripting().loadCodeFromGist(Current_URL, webEngine);
|
||||
myTab.setText(getScripting().getFileName());
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private void finishLoadingComponents(){
|
||||
//System.err.println("Finalizing: "+webEngine.getLocation());
|
||||
try{
|
||||
|
||||
if(getScripting()!=null){
|
||||
//when navagating to a new file, stop the script that is running
|
||||
getScripting().stop();
|
||||
}
|
||||
}catch(Exception E){
|
||||
E.printStackTrace();
|
||||
}
|
||||
new Thread() {
|
||||
public void run() {
|
||||
finishedLoadingScriptingWidget=false;
|
||||
try{
|
||||
setScripting(new ScriptingWebWidget( null ,Current_URL, webEngine));
|
||||
Platform.runLater(() -> {
|
||||
vBox.getChildren().add(getScripting());
|
||||
if(!isTutorialTab){
|
||||
Platform.runLater(()->{
|
||||
try{
|
||||
|
||||
myTab.setText(getScripting().getFileName());
|
||||
}catch(java.lang.NullPointerException ex){
|
||||
// web page contains no gist
|
||||
ex.printStackTrace();
|
||||
myTab.setText("Web");
|
||||
}
|
||||
loadCode();
|
||||
|
||||
});
|
||||
}
|
||||
else
|
||||
finishedLoadingScriptingWidget=true;
|
||||
});
|
||||
|
||||
}catch(Exception ex){
|
||||
ex.printStackTrace();
|
||||
finishedLoadingScriptingWidget=true;
|
||||
}
|
||||
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
private void loadCode(){
|
||||
new Thread(()->{
|
||||
System.out.println("Downloading code from "+Current_URL);
|
||||
try {
|
||||
getScripting().loadCodeFromGist(Current_URL, webEngine);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public String goBack()
|
||||
{
|
||||
//new Exception().printStackTrace(System.err);
|
||||
final WebHistory history=webEngine.getHistory();
|
||||
ObservableList<WebHistory.Entry> entryList=history.getEntries();
|
||||
int currentIndex=history.getCurrentIndex();
|
||||
// Out("currentIndex = "+currentIndex);
|
||||
// Out(entryList.toString().replace("],","]\n"));
|
||||
|
||||
Platform.runLater(() ->{
|
||||
try{
|
||||
history.go(-1);
|
||||
}catch(Exception e){
|
||||
// e.printStackTrace();
|
||||
}
|
||||
});
|
||||
return entryList.get(currentIndex>0?currentIndex-1:currentIndex).getUrl();
|
||||
}
|
||||
|
||||
public String goForward()
|
||||
{
|
||||
final WebHistory history=webEngine.getHistory();
|
||||
ObservableList<WebHistory.Entry> entryList=history.getEntries();
|
||||
int currentIndex=history.getCurrentIndex();
|
||||
// Out("currentIndex = "+currentIndex);
|
||||
// Out(entryList.toString().replace("],","]\n"));
|
||||
|
||||
Platform.runLater(() -> {
|
||||
try {
|
||||
history.go(1);
|
||||
} catch (IndexOutOfBoundsException ex) {
|
||||
}
|
||||
});
|
||||
return entryList.get(currentIndex<entryList.size()-1?currentIndex+1:currentIndex).getUrl();
|
||||
}
|
||||
|
||||
|
||||
public static String getDomainName(String url) throws URISyntaxException {
|
||||
URI uri = new URI(url);
|
||||
String domain = uri.getHost();
|
||||
return domain.startsWith("www.") ? domain.substring(4) : domain;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Event event) {
|
||||
if(getScripting()!=null)
|
||||
getScripting().stop();
|
||||
}
|
||||
|
||||
public ScriptingWebWidget getScripting() {
|
||||
return scripting;
|
||||
}
|
||||
|
||||
public void setScripting(ScriptingWebWidget scripting) {
|
||||
this.scripting = scripting;
|
||||
|
||||
scripting.addIScriptEventListener(controller);
|
||||
}
|
||||
|
||||
public static void setBSController(BowlerStudioController controller) {
|
||||
WebTab.controller = controller;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
package com.neuronrobotics.bowlerstudio.threed;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
/*
|
||||
* Axis.java 1.0 98/11/25
|
||||
*
|
||||
* Copyright (c) 1998 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
|
||||
* modify and redistribute this software in source and binary code form,
|
||||
* provided that i) this copyright notice and license appear on all copies of
|
||||
* the software; and ii) Licensee does not utilize the software in a manner
|
||||
* which is disparaging to Sun.
|
||||
*
|
||||
* This software is provided "AS IS," without a warranty of any kind. ALL
|
||||
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
|
||||
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
|
||||
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
|
||||
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
|
||||
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
|
||||
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
|
||||
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
|
||||
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
|
||||
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*
|
||||
* This software is not designed or intended for use in on-line control of
|
||||
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
|
||||
* the design, construction, operation or maintenance of any nuclear
|
||||
* facility. Licensee represents and warrants that it will not use or
|
||||
* redistribute the Software for such purposes.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Getting Started with the Java 3D API
|
||||
* written in Java 3D
|
||||
*
|
||||
* This program demonstrates:
|
||||
* 1. writing a visual object class
|
||||
* In this program, Axis class defines a visual object
|
||||
* This particular class extends Shape3D
|
||||
* See the text for a discussion.
|
||||
* 2. Using LineArray to draw 3D lines.
|
||||
*/
|
||||
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.paint.PhongMaterial;
|
||||
import javafx.scene.shape.Box;
|
||||
import javafx.scene.shape.Line;
|
||||
import javafx.scene.shape.Sphere;
|
||||
import javafx.scene.transform.Affine;
|
||||
|
||||
// TODO: Auto-generated Javadoc
|
||||
/**
|
||||
* The Class Axis.
|
||||
*/
|
||||
public class Axis extends Group {
|
||||
|
||||
private Line3D xAxis;
|
||||
private Line3D yAxis;
|
||||
private Line3D zAxis;
|
||||
private Label xText;
|
||||
private Label yText;
|
||||
private Label zText;
|
||||
/**
|
||||
* Instantiates a new axis.
|
||||
*/
|
||||
public Axis() {
|
||||
this(50);
|
||||
}
|
||||
// //////////////////////////////////////////
|
||||
//
|
||||
// create axis visual object
|
||||
/**
|
||||
* Instantiates a new axis.
|
||||
*
|
||||
* @param i the i
|
||||
*/
|
||||
//
|
||||
public Axis(int i) {
|
||||
|
||||
|
||||
|
||||
|
||||
Affine xp = new Affine();
|
||||
xp.setTx(i/2);
|
||||
xText = new Label("+X");
|
||||
xText.getTransforms().add(xp);
|
||||
|
||||
Affine yp = new Affine();
|
||||
yp.setTy(i/2);
|
||||
yText = new Label("+Y");
|
||||
yText.getTransforms().add(yp);
|
||||
|
||||
//zp.setTz(i/2);
|
||||
Affine zTextAffine = new Affine();
|
||||
zTextAffine.setTz(i/2);
|
||||
zTextAffine.setTx(i/2);
|
||||
zTextAffine.appendRotation(-90, 0, 0, 0, 1, 0, 0);
|
||||
zTextAffine.appendRotation(180, 0, 0, 0, 0, 0, 1);
|
||||
zText = new Label("+Z");
|
||||
zText.getTransforms().add(zTextAffine);
|
||||
//zText.smoothProperty().set(false);
|
||||
double strokWidth=0.1;
|
||||
double inset = 0;
|
||||
xAxis = new Line3D(0,inset,0,i,inset,0);
|
||||
yAxis = new Line3D(inset,0,0,inset,i,0);
|
||||
zAxis = new Line3D(inset,0,0,inset,0,i);
|
||||
|
||||
xAxis.setStrokeWidth(strokWidth);
|
||||
xAxis.setStroke(Color.RED);
|
||||
|
||||
yAxis.setStrokeWidth(strokWidth);
|
||||
yAxis.setStroke(Color.GREEN);
|
||||
|
||||
zAxis.setStrokeWidth(strokWidth);
|
||||
zAxis.setStroke(Color.BLUE);
|
||||
|
||||
show();
|
||||
}
|
||||
|
||||
public void show(){
|
||||
Platform.runLater(()->getChildren().addAll(xAxis,yAxis,zAxis,xText,yText,zText));
|
||||
}
|
||||
public void hide(){
|
||||
Platform.runLater(()->getChildren().removeAll(xAxis,yAxis,zAxis,xText,yText,zText));
|
||||
}
|
||||
|
||||
|
||||
} // end of class Axis
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,56 @@
|
||||
package com.neuronrobotics.bowlerstudio.threed;
|
||||
|
||||
/**
|
||||
* Sample Skeleton for "CreatureLab.fxml" Controller Class
|
||||
* You can copy and paste this code into your favorite IDE
|
||||
**/
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
|
||||
|
||||
public class CreaturelLabController {
|
||||
|
||||
@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="CadControlsAnchor"
|
||||
private AnchorPane CadControlsAnchor; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="DriveControlsAnchor"
|
||||
private AnchorPane DriveControlsAnchor; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="TempControlsAnchor"
|
||||
private AnchorPane TempControlsAnchor; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="jfx3dControls"
|
||||
private AnchorPane jfx3dControls; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="overlayScrollPanel"
|
||||
private ScrollPane overlayScrollPanel; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="viewContainer"
|
||||
private AnchorPane viewContainer; // Value injected by FXMLLoader
|
||||
|
||||
|
||||
@FXML // This method is called by the FXMLLoader when initialization is complete
|
||||
void initialize() {
|
||||
assert CadControlsAnchor != null : "fx:id=\"CadControlsAnchor\" was not injected: check your FXML file 'CreatureLab.fxml'.";
|
||||
assert DriveControlsAnchor != null : "fx:id=\"DriveControlsAnchor\" was not injected: check your FXML file 'CreatureLab.fxml'.";
|
||||
assert TempControlsAnchor != null : "fx:id=\"TempControlsAnchor\" was not injected: check your FXML file 'CreatureLab.fxml'.";
|
||||
assert jfx3dControls != null : "fx:id=\"jfx3dControls\" was not injected: check your FXML file 'CreatureLab.fxml'.";
|
||||
assert overlayScrollPanel != null : "fx:id=\"overlayScrollPanel\" was not injected: check your FXML file 'CreatureLab.fxml'.";
|
||||
assert viewContainer != null : "fx:id=\"viewContainer\" was not injected: check your FXML file 'CreatureLab.fxml'.";
|
||||
|
||||
// Initialize your logic here: all @FXML variables will have been injected
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.neuronrobotics.bowlerstudio.threed;
|
||||
|
||||
import javax.vecmath.Matrix4f;
|
||||
import javax.vecmath.Quat4f;
|
||||
import javax.vecmath.Vector3f;
|
||||
|
||||
import com.bulletphysics.collision.broadphase.BroadphaseInterface;
|
||||
import com.bulletphysics.collision.broadphase.DbvtBroadphase;
|
||||
import com.bulletphysics.collision.dispatch.CollisionDispatcher;
|
||||
import com.bulletphysics.collision.dispatch.DefaultCollisionConfiguration;
|
||||
import com.bulletphysics.collision.shapes.CollisionShape;
|
||||
import com.bulletphysics.collision.shapes.SphereShape;
|
||||
import com.bulletphysics.collision.shapes.StaticPlaneShape;
|
||||
import com.bulletphysics.dynamics.DiscreteDynamicsWorld;
|
||||
import com.bulletphysics.dynamics.RigidBody;
|
||||
import com.bulletphysics.dynamics.RigidBodyConstructionInfo;
|
||||
import com.bulletphysics.dynamics.constraintsolver.SequentialImpulseConstraintSolver;
|
||||
import com.bulletphysics.linearmath.DefaultMotionState;
|
||||
import com.bulletphysics.linearmath.Transform;
|
||||
|
||||
public class Jbullet {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
BroadphaseInterface broadphase = new DbvtBroadphase();
|
||||
DefaultCollisionConfiguration collisionConfiguration = new DefaultCollisionConfiguration();
|
||||
CollisionDispatcher dispatcher = new CollisionDispatcher(collisionConfiguration);
|
||||
|
||||
SequentialImpulseConstraintSolver solver = new SequentialImpulseConstraintSolver();
|
||||
|
||||
DiscreteDynamicsWorld dynamicsWorld = new DiscreteDynamicsWorld(dispatcher, broadphase, solver,
|
||||
collisionConfiguration);
|
||||
|
||||
// set the gravity of our world
|
||||
dynamicsWorld.setGravity(new Vector3f(0, -10, 0));
|
||||
|
||||
// setup our collision shapes
|
||||
CollisionShape groundShape = new StaticPlaneShape(new Vector3f(0, 1, 0), 1);
|
||||
CollisionShape fallShape = new SphereShape(1);
|
||||
|
||||
// setup the motion state
|
||||
DefaultMotionState groundMotionState = new DefaultMotionState(
|
||||
new Transform(new Matrix4f(new Quat4f(0, 0, 0, 1), new Vector3f(0, -1, 0), 1.0f)));
|
||||
|
||||
RigidBodyConstructionInfo groundRigidBodyCI = new RigidBodyConstructionInfo(0, groundMotionState, groundShape,
|
||||
new Vector3f(0, 0, 0));
|
||||
RigidBody groundRigidBody = new RigidBody(groundRigidBodyCI);
|
||||
|
||||
dynamicsWorld.addRigidBody(groundRigidBody); // add our ground to the
|
||||
// dynamic world..
|
||||
|
||||
// setup the motion state for the ball
|
||||
DefaultMotionState fallMotionState = new DefaultMotionState(
|
||||
new Transform(new Matrix4f(new Quat4f(0, 0, 0, 1), new Vector3f(0, 100, 0), 1.0f)));
|
||||
|
||||
// This we're going to give mass so it responds to gravity
|
||||
int mass = 1;
|
||||
|
||||
Vector3f fallInertia = new Vector3f(0, 0, 0);
|
||||
fallShape.calculateLocalInertia(mass, fallInertia);
|
||||
|
||||
RigidBodyConstructionInfo fallRigidBodyCI = new RigidBodyConstructionInfo(mass, fallMotionState, fallShape,
|
||||
fallInertia);
|
||||
RigidBody fallRigidBody = new RigidBody(fallRigidBodyCI);
|
||||
|
||||
// now we add it to our physics simulation
|
||||
dynamicsWorld.addRigidBody(fallRigidBody);
|
||||
|
||||
for (int i = 0; i < 300; i++) {
|
||||
dynamicsWorld.stepSimulation(1 / 60.f, 10);
|
||||
|
||||
Transform trans = new Transform();
|
||||
fallRigidBody.getMotionState().getWorldTransform(trans);
|
||||
|
||||
System.out.println("sphere height: " + trans.origin.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package com.neuronrobotics.bowlerstudio.threed;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.paint.PhongMaterial;
|
||||
import javafx.scene.shape.Cylinder;
|
||||
import javafx.scene.transform.Affine;
|
||||
import eu.mihosoft.vrl.v3d.Vector3d;
|
||||
import eu.mihosoft.vrl.v3d.Vertex;
|
||||
|
||||
public class Line3D extends Cylinder {
|
||||
|
||||
private double endZ = 0;
|
||||
private double startZ=0;
|
||||
|
||||
public Line3D(Vertex start, Vertex end){
|
||||
this(start.pos,
|
||||
end.pos );
|
||||
}
|
||||
public Line3D(double [] start, double[] end){
|
||||
this(start[0],start[1],start[2],
|
||||
end[0],end[1],end[2] );
|
||||
}
|
||||
public Line3D(Vector3d start, Vector3d end){
|
||||
this(start.x,start.y,start.z,
|
||||
end.x,end.y,end.z );
|
||||
}
|
||||
|
||||
public Line3D(
|
||||
double endX,
|
||||
double endY,
|
||||
double endZ){
|
||||
this(0,0,0,endX,endY,endZ);
|
||||
}
|
||||
|
||||
public Line3D(double startX,
|
||||
double startY,
|
||||
double startZ,
|
||||
double endX,
|
||||
double endY,
|
||||
double endZ){
|
||||
super(0.1,
|
||||
Math.sqrt( Math.pow(endX-startX, 2)+
|
||||
Math.pow(endY-startY, 2)+
|
||||
Math.pow(endZ-startZ, 2))
|
||||
);
|
||||
double xdiff = endX-startX;
|
||||
double ydiff = endY-startY;
|
||||
double zdiff = endZ-startZ;
|
||||
|
||||
double lineLen = getHeight();
|
||||
|
||||
double xyProjection = Math.sqrt( Math.pow(xdiff, 2)+
|
||||
Math.pow(ydiff, 2)
|
||||
);
|
||||
|
||||
double rotZ = Math.toDegrees(Math.atan2(xdiff, ydiff));
|
||||
double rotY = Math.toDegrees(Math.atan2(xyProjection, zdiff));
|
||||
Affine xy = new Affine();
|
||||
xy.appendRotation(-90-rotY, 0, 0, 0, 0, 1, 0);
|
||||
|
||||
Affine orent = new Affine();
|
||||
orent.appendRotation(90, 0, 0, 0, 0, 0, 1);
|
||||
|
||||
Affine orent2 = new Affine();
|
||||
orent.setTx(lineLen/2);
|
||||
|
||||
Affine zp = new Affine();
|
||||
zp.appendRotation(-90-rotZ, 0, 0, 0, 0, 0, 1);
|
||||
Affine zTrans = new Affine();
|
||||
zTrans.setTx(startX);
|
||||
zTrans.setTy(startY);
|
||||
zTrans.setTz(startZ);
|
||||
|
||||
|
||||
getTransforms().add(zTrans);
|
||||
getTransforms().add(zp);
|
||||
getTransforms().add(xy);
|
||||
|
||||
getTransforms().add(orent);
|
||||
getTransforms().add(orent2);
|
||||
}
|
||||
|
||||
public double getEndZ() {
|
||||
return endZ;
|
||||
}
|
||||
public void setEndZ(double endZ) {
|
||||
this.endZ = endZ;
|
||||
}
|
||||
public double getStartZ() {
|
||||
return startZ;
|
||||
}
|
||||
public void setStartZ(double startZ) {
|
||||
this.startZ = startZ;
|
||||
}
|
||||
public void setStrokeWidth(double radius){
|
||||
setRadius(radius/2);
|
||||
}
|
||||
public void setStroke(Color color) {
|
||||
Platform.runLater(() -> setMaterial(new PhongMaterial(color)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
package com.neuronrobotics.bowlerstudio.threed;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.physics.TransformFactory;
|
||||
import com.neuronrobotics.imageprovider.AbstractImageProvider;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.math.RotationNR;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.PerspectiveCamera;
|
||||
import javafx.scene.transform.Affine;
|
||||
import javafx.scene.transform.Translate;
|
||||
|
||||
public class VirtualCameraDevice extends AbstractImageProvider {
|
||||
|
||||
private static final int DEFAULT_ZOOM_DEPTH = -1500;
|
||||
private PerspectiveCamera camera;
|
||||
private Group hand;
|
||||
private final Group cameraFrame = new Group();
|
||||
|
||||
private double zoomDepth = getDefaultZoomDepth();
|
||||
private Affine zoomAffine = new Affine();
|
||||
private static final Affine offset =new Affine();
|
||||
private Group manipulationFrame;
|
||||
static {
|
||||
Platform.runLater(()->TransformFactory.nrToAffine(
|
||||
new TransformNR(0, 0, 0, new RotationNR(180,0,0)),offset
|
||||
));
|
||||
}
|
||||
public VirtualCameraDevice(PerspectiveCamera camera, Group hand){
|
||||
this.hand = hand;
|
||||
this.setCamera(camera);
|
||||
setScriptingName("virtualCameraDevice");
|
||||
//System.out.println("Setting camera frame transform");
|
||||
|
||||
manipulationFrame = new Group();
|
||||
camera.getTransforms().add(zoomAffine);
|
||||
|
||||
cameraFrame.getTransforms().add(getOffset());
|
||||
manipulationFrame.getChildren().addAll(camera, hand);
|
||||
cameraFrame.getChildren().add(manipulationFrame);
|
||||
//new RuntimeException().printStackTrace();
|
||||
setZoomDepth(DEFAULT_ZOOM_DEPTH);
|
||||
}
|
||||
@Override
|
||||
public void setGlobalPositionListener(Affine affine) {
|
||||
super.setGlobalPositionListener(affine);
|
||||
manipulationFrame.getTransforms().clear();
|
||||
manipulationFrame.getTransforms().add(affine);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean captureNewImage(BufferedImage imageData) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnectDeviceImp() { }
|
||||
|
||||
@Override
|
||||
public boolean connectDeviceImp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayList<String> getNamespacesImp() {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
public PerspectiveCamera getCamera() {
|
||||
return camera;
|
||||
}
|
||||
public Group getCameraGroup() {
|
||||
return getCameraFrame();
|
||||
}
|
||||
|
||||
private void setCamera(PerspectiveCamera camera) {
|
||||
this.camera = camera;
|
||||
}
|
||||
public Group getCameraFrame() {
|
||||
return cameraFrame;
|
||||
}
|
||||
|
||||
public double getZoomDepth() {
|
||||
return zoomDepth;
|
||||
}
|
||||
public void setZoomDepth(double zoomDepth) {
|
||||
if(zoomDepth>-2)
|
||||
zoomDepth=-2;
|
||||
if(zoomDepth<-5000)
|
||||
zoomDepth=-5000;
|
||||
this.zoomDepth = zoomDepth;
|
||||
zoomAffine.setTz(getZoomDepth());
|
||||
}
|
||||
public BufferedImage captureNewImage() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
public static int getDefaultZoomDepth() {
|
||||
return DEFAULT_ZOOM_DEPTH;
|
||||
}
|
||||
public static Affine getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.neuronrobotics.bowlerstudio.threed;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.IDriveEngine;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.MobileBase;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.math.RotationNR;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class VirtualCameraMobileBase extends MobileBase {
|
||||
|
||||
private final static class IDriveEngineImplementation implements IDriveEngine {
|
||||
|
||||
double azOffset =0;
|
||||
double elOffset =0;
|
||||
double tlOffset =0;
|
||||
TransformNR pureTrans = new TransformNR();
|
||||
@Override
|
||||
public void DriveVelocityStraight(MobileBase source, double cmPerSecond) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void DriveVelocityArc(MobileBase source, double degreesPerSecond, double cmRadius) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void DriveArc(MobileBase source, TransformNR newPose, double seconds) {
|
||||
try{
|
||||
pureTrans.setX(newPose.getX());
|
||||
pureTrans.setY(newPose.getY());
|
||||
pureTrans.setZ(newPose.getZ());
|
||||
|
||||
TransformNR global= source.getFiducialToGlobalTransform().times(pureTrans);
|
||||
//RotationNR finalRot = TransformNR(0,0,0,globalRot).times(newPose).getRotation();
|
||||
//System.out.println("Azumuth = "+az+" elevation = "+el+" tilt = "+tl);
|
||||
// Rotation n = newPose.getRotation().getStorage();
|
||||
// Rotation g = global.getRotation().getStorage();
|
||||
// Rotation nr =n.compose(g, RotationNR.getConvention());
|
||||
|
||||
global.setRotation( new RotationNR(
|
||||
tlOffset+(Math.toDegrees(newPose.getRotation().getRotationTilt() + global.getRotation().getRotationTilt())%360),
|
||||
azOffset+(Math.toDegrees(newPose.getRotation().getRotationAzimuth() + global.getRotation().getRotationAzimuth())%360),
|
||||
elOffset+Math.toDegrees(newPose.getRotation().getRotationElevation() + global.getRotation().getRotationElevation())
|
||||
));
|
||||
// global.getRotation().setStorage(nr);
|
||||
//System.err.println("Camera tilt="+global);
|
||||
// New target calculated appliaed to global offset
|
||||
source.setGlobalToFiducialTransform(global);
|
||||
}catch (Exception ex){
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
private static IDriveEngine de = new IDriveEngineImplementation();
|
||||
private static ArrayList<VirtualCameraMobileBase> bases= new ArrayList<VirtualCameraMobileBase>();
|
||||
public VirtualCameraMobileBase() throws Exception{
|
||||
//super (IOUtils.toInputStream(ScriptingEngine.codeFromGistID("bfa504cdfba41b132c5d","flyingCamera.xml")[0], "UTF-8"));
|
||||
super(new FileInputStream(AssetFactory.loadFile("layout/flyingCamera.xml")));
|
||||
//setDriveType(DrivingType.WALKING);
|
||||
|
||||
setWalkingDriveEngine(getDriveEngine());
|
||||
bases.add(this);
|
||||
}
|
||||
public static IDriveEngine getDriveEngine() {
|
||||
return de;
|
||||
}
|
||||
public static void setDriveEngine(IDriveEngine de) {
|
||||
VirtualCameraMobileBase.de = de;
|
||||
for(VirtualCameraMobileBase base:bases){
|
||||
base.setWalkingDriveEngine(getDriveEngine());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,336 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2013 Oracle and/or its affiliates.
|
||||
* All rights reserved. Use is subject to license terms.
|
||||
*
|
||||
* This file is available and licensed under the following license:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package com.neuronrobotics.bowlerstudio.threed;
|
||||
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.transform.Rotate;
|
||||
import javafx.scene.transform.Scale;
|
||||
import javafx.scene.transform.Translate;
|
||||
|
||||
// TODO: Auto-generated Javadoc
|
||||
/**
|
||||
* The Class Xform.
|
||||
*/
|
||||
public class Xform extends Group {
|
||||
|
||||
/**
|
||||
* The Enum RotateOrder.
|
||||
*/
|
||||
public enum RotateOrder {
|
||||
|
||||
/** The xyz. */
|
||||
XYZ,
|
||||
/** The xzy. */
|
||||
XZY,
|
||||
/** The yxz. */
|
||||
YXZ,
|
||||
/** The yzx. */
|
||||
YZX,
|
||||
/** The zxy. */
|
||||
ZXY,
|
||||
/** The zyx. */
|
||||
ZYX
|
||||
}
|
||||
|
||||
/** The t. */
|
||||
public Translate t = new Translate();
|
||||
|
||||
/** The p. */
|
||||
public Translate p = new Translate();
|
||||
|
||||
/** The ip. */
|
||||
public Translate ip = new Translate();
|
||||
|
||||
/** The rx. */
|
||||
public Rotate rx = new Rotate();
|
||||
{ rx.setAxis(Rotate.X_AXIS); }
|
||||
|
||||
/** The ry. */
|
||||
public Rotate ry = new Rotate();
|
||||
{ ry.setAxis(Rotate.Y_AXIS); }
|
||||
|
||||
/** The rz. */
|
||||
public Rotate rz = new Rotate();
|
||||
{ rz.setAxis(Rotate.Z_AXIS); }
|
||||
|
||||
/** The s. */
|
||||
public Scale s = new Scale();
|
||||
|
||||
/**
|
||||
* Instantiates a new xform.
|
||||
*/
|
||||
public Xform() {
|
||||
super();
|
||||
getTransforms().addAll(t, rz, ry, rx, s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new xform.
|
||||
*
|
||||
* @param rotateOrder the rotate order
|
||||
*/
|
||||
public Xform(RotateOrder rotateOrder) {
|
||||
super();
|
||||
// choose the order of rotations based on the rotateOrder
|
||||
switch (rotateOrder) {
|
||||
case XYZ:
|
||||
getTransforms().addAll(t, p, rz, ry, rx, s, ip);
|
||||
break;
|
||||
case XZY:
|
||||
getTransforms().addAll(t, p, ry, rz, rx, s, ip);
|
||||
break;
|
||||
case YXZ:
|
||||
getTransforms().addAll(t, p, rz, rx, ry, s, ip);
|
||||
break;
|
||||
case YZX:
|
||||
getTransforms().addAll(t, p, rx, rz, ry, s, ip); // For Camera
|
||||
break;
|
||||
case ZXY:
|
||||
getTransforms().addAll(t, p, ry, rx, rz, s, ip);
|
||||
break;
|
||||
case ZYX:
|
||||
getTransforms().addAll(t, p, rx, ry, rz, s, ip);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the translate.
|
||||
*
|
||||
* @param x the x
|
||||
* @param y the y
|
||||
* @param z the z
|
||||
*/
|
||||
public void setTranslate(double x, double y, double z) {
|
||||
t.setX(x);
|
||||
t.setY(y);
|
||||
t.setZ(z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the translate.
|
||||
*
|
||||
* @param x the x
|
||||
* @param y the y
|
||||
*/
|
||||
public void setTranslate(double x, double y) {
|
||||
t.setX(x);
|
||||
t.setY(y);
|
||||
}
|
||||
|
||||
// Cannot override these methods as they are final:
|
||||
// public void setTranslateX(double x) { t.setX(x); }
|
||||
// public void setTranslateY(double y) { t.setY(y); }
|
||||
// public void setTranslateZ(double z) { t.setZ(z); }
|
||||
/**
|
||||
* Sets the tx.
|
||||
*
|
||||
* @param x the new tx
|
||||
*/
|
||||
// Use these methods instead:
|
||||
public void setTx(double x) { t.setX(x); }
|
||||
|
||||
/**
|
||||
* Sets the ty.
|
||||
*
|
||||
* @param y the new ty
|
||||
*/
|
||||
public void setTy(double y) { t.setY(y); }
|
||||
|
||||
/**
|
||||
* Sets the tz.
|
||||
*
|
||||
* @param z the new tz
|
||||
*/
|
||||
public void setTz(double z) { t.setZ(z); }
|
||||
|
||||
/**
|
||||
* Sets the rotate.
|
||||
*
|
||||
* @param x the x
|
||||
* @param y the y
|
||||
* @param z the z
|
||||
*/
|
||||
public void setRotate(double x, double y, double z) {
|
||||
rx.setAngle(x);
|
||||
ry.setAngle(y);
|
||||
rz.setAngle(z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the rotate x.
|
||||
*
|
||||
* @param x the new rotate x
|
||||
*/
|
||||
public void setRotateX(double x) { rx.setAngle(x); }
|
||||
|
||||
/**
|
||||
* Sets the rotate y.
|
||||
*
|
||||
* @param y the new rotate y
|
||||
*/
|
||||
public void setRotateY(double y) { ry.setAngle(y); }
|
||||
|
||||
/**
|
||||
* Sets the rotate z.
|
||||
*
|
||||
* @param z the new rotate z
|
||||
*/
|
||||
public void setRotateZ(double z) { rz.setAngle(z); }
|
||||
|
||||
/**
|
||||
* Sets the rx.
|
||||
*
|
||||
* @param x the new rx
|
||||
*/
|
||||
public void setRx(double x) { rx.setAngle(x); }
|
||||
|
||||
/**
|
||||
* Sets the ry.
|
||||
*
|
||||
* @param y the new ry
|
||||
*/
|
||||
public void setRy(double y) { ry.setAngle(y); }
|
||||
|
||||
/**
|
||||
* Sets the rz.
|
||||
*
|
||||
* @param z the new rz
|
||||
*/
|
||||
public void setRz(double z) { rz.setAngle(z); }
|
||||
|
||||
/**
|
||||
* Sets the scale.
|
||||
*
|
||||
* @param scaleFactor the new scale
|
||||
*/
|
||||
public void setScale(double scaleFactor) {
|
||||
s.setX(scaleFactor);
|
||||
s.setY(scaleFactor);
|
||||
s.setZ(scaleFactor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the scale.
|
||||
*
|
||||
* @param x the x
|
||||
* @param y the y
|
||||
* @param z the z
|
||||
*/
|
||||
public void setScale(double x, double y, double z) {
|
||||
s.setX(x);
|
||||
s.setY(y);
|
||||
s.setZ(z);
|
||||
}
|
||||
|
||||
// Cannot override these methods as they are final:
|
||||
// public void setScaleX(double x) { s.setX(x); }
|
||||
// public void setScaleY(double y) { s.setY(y); }
|
||||
// public void setScaleZ(double z) { s.setZ(z); }
|
||||
/**
|
||||
* Sets the sx.
|
||||
*
|
||||
* @param x the new sx
|
||||
*/
|
||||
// Use these methods instead:
|
||||
public void setSx(double x) { s.setX(x); }
|
||||
|
||||
/**
|
||||
* Sets the sy.
|
||||
*
|
||||
* @param y the new sy
|
||||
*/
|
||||
public void setSy(double y) { s.setY(y); }
|
||||
|
||||
/**
|
||||
* Sets the sz.
|
||||
*
|
||||
* @param z the new sz
|
||||
*/
|
||||
public void setSz(double z) { s.setZ(z); }
|
||||
|
||||
/**
|
||||
* Sets the pivot.
|
||||
*
|
||||
* @param x the x
|
||||
* @param y the y
|
||||
* @param z the z
|
||||
*/
|
||||
public void setPivot(double x, double y, double z) {
|
||||
p.setX(x);
|
||||
p.setY(y);
|
||||
p.setZ(z);
|
||||
ip.setX(-x);
|
||||
ip.setY(-y);
|
||||
ip.setZ(-z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset.
|
||||
*/
|
||||
public void reset() {
|
||||
t.setX(0.0);
|
||||
t.setY(0.0);
|
||||
t.setZ(0.0);
|
||||
rx.setAngle(0.0);
|
||||
ry.setAngle(0.0);
|
||||
rz.setAngle(0.0);
|
||||
s.setX(1.0);
|
||||
s.setY(1.0);
|
||||
s.setZ(1.0);
|
||||
p.setX(0.0);
|
||||
p.setY(0.0);
|
||||
p.setZ(0.0);
|
||||
ip.setX(0.0);
|
||||
ip.setY(0.0);
|
||||
ip.setZ(0.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset tsp.
|
||||
*/
|
||||
public void resetTSP() {
|
||||
t.setX(0.0);
|
||||
t.setY(0.0);
|
||||
t.setZ(0.0);
|
||||
s.setX(1.0);
|
||||
s.setY(1.0);
|
||||
s.setZ(1.0);
|
||||
p.setX(0.0);
|
||||
p.setY(0.0);
|
||||
p.setZ(0.0);
|
||||
ip.setX(0.0);
|
||||
ip.setY(0.0);
|
||||
ip.setZ(0.0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
package com.neuronrobotics.bowlerstudio.utils;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.BowlerStudioController;
|
||||
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
|
||||
import com.neuronrobotics.sdk.common.BowlerDatagram;
|
||||
import com.neuronrobotics.sdk.common.DeviceManager;
|
||||
import com.neuronrobotics.sdk.common.Log;
|
||||
import com.neuronrobotics.sdk.network.BowlerTCPClient;
|
||||
import com.neuronrobotics.sdk.network.UDPBowlerConnection;
|
||||
import com.neuronrobotics.sdk.serial.SerialConnection;
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* Sample Skeleton for "BowlerConnectionMenue.fxml" Controller Class
|
||||
* You can copy and paste this code into your favorite IDE
|
||||
**/
|
||||
|
||||
public class BowlerConnectionMenu extends Application {
|
||||
|
||||
@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="baudrate"
|
||||
private TextField baudrate; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="connectNetwork"
|
||||
private Button connectNetwork; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="connectSerial"
|
||||
private Button connectSerial; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="portOptions"
|
||||
private ComboBox<String> portOptions; // Value injected by FXMLLoader
|
||||
@FXML
|
||||
private ComboBox<String> ipSelector;
|
||||
|
||||
@FXML // fx:id="portType"
|
||||
private ToggleGroup portType; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="searchNetwork"
|
||||
private Button searchNetwork; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="searchSerial"
|
||||
private Button searchSerial; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="tcpPort"
|
||||
private TextField tcpPort; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="tcpSelect"
|
||||
private RadioButton tcpSelect; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="udpPort"
|
||||
private TextField udpPort; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="udpSelect"
|
||||
private RadioButton udpSelect; // Value injected by FXMLLoader
|
||||
|
||||
private UDPBowlerConnection clnt;
|
||||
|
||||
private int defaultPortNum = 1865;
|
||||
|
||||
private Stage primaryStage;
|
||||
|
||||
private String port;
|
||||
|
||||
private int baud;
|
||||
|
||||
@FXML // This method is called by the FXMLLoader when initialization is
|
||||
// complete
|
||||
void initialize() {
|
||||
System.err.println("Initializing conection Dialog");
|
||||
assert baudrate != null : "fx:id=\"baudrate\" was not injected: check your FXML file 'BowlerConnectionMenue.fxml'.";
|
||||
assert connectNetwork != null : "fx:id=\"connectNetwork\" was not injected: check your FXML file 'BowlerConnectionMenue.fxml'.";
|
||||
assert connectSerial != null : "fx:id=\"connectSerial\" was not injected: check your FXML file 'BowlerConnectionMenue.fxml'.";
|
||||
assert portOptions != null : "fx:id=\"portOptions\" was not injected: check your FXML file 'BowlerConnectionMenue.fxml'.";
|
||||
assert portType != null : "fx:id=\"portType\" was not injected: check your FXML file 'BowlerConnectionMenue.fxml'.";
|
||||
assert searchNetwork != null : "fx:id=\"searchNetwork\" was not injected: check your FXML file 'BowlerConnectionMenue.fxml'.";
|
||||
assert searchSerial != null : "fx:id=\"searchSerial\" was not injected: check your FXML file 'BowlerConnectionMenue.fxml'.";
|
||||
assert tcpPort != null : "fx:id=\"tcpPort\" was not injected: check your FXML file 'BowlerConnectionMenue.fxml'.";
|
||||
assert tcpSelect != null : "fx:id=\"tcpSelect\" was not injected: check your FXML file 'BowlerConnectionMenue.fxml'.";
|
||||
assert udpPort != null : "fx:id=\"udpPort\" was not injected: check your FXML file 'BowlerConnectionMenue.fxml'.";
|
||||
assert udpSelect != null : "fx:id=\"udpSelect\" was not injected: check your FXML file 'BowlerConnectionMenue.fxml'.";
|
||||
assert ipSelector != null : "fx:id=\"ipSelector\" was not injected: check your FXML file 'BowlerConnectionMenu.fxml'.";
|
||||
runsearchSerial();
|
||||
runsearchNetwork();
|
||||
|
||||
searchNetwork.setOnAction(event -> {
|
||||
runsearchNetwork();
|
||||
});
|
||||
searchSerial.setOnAction(event -> {
|
||||
runsearchSerial();
|
||||
});
|
||||
|
||||
connectNetwork.setOnAction(event -> {
|
||||
runconnectNetwork();
|
||||
primaryStage.hide();
|
||||
});
|
||||
connectSerial.setOnAction(event -> {
|
||||
runconnectSerial();
|
||||
primaryStage.hide();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void runconnectSerial() {
|
||||
new Thread(() -> {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
SerialConnection ser=null;
|
||||
try {
|
||||
BowlerDatagram.setUseBowlerV4(true);
|
||||
baud = Integer.parseInt(baudrate.getText());
|
||||
if (baud < 0) {
|
||||
throw new NumberFormatException();
|
||||
}
|
||||
port = portOptions.getSelectionModel().getSelectedItem().toString();
|
||||
int level = Log.getMinimumPrintLevel();
|
||||
//Log.enableInfoPrint();
|
||||
ser = new SerialConnection(port, baud);
|
||||
|
||||
DeviceManager.addConnection(ser);
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
System.out.println("false start " + port + " at baud " + baud + " is not responding");
|
||||
BowlerStudioController.highlightException(null, e);
|
||||
e.printStackTrace();
|
||||
if (ser!=null)
|
||||
ser.disconnect();
|
||||
}
|
||||
}
|
||||
System.out.println("Connection failed! " + port + " at baud " + baud + " is not responding");
|
||||
}).start();
|
||||
|
||||
}
|
||||
|
||||
private void runconnectNetwork() {
|
||||
new Thread(() -> {
|
||||
int port;
|
||||
String ip = ipSelector.getSelectionModel().getSelectedItem().toString();
|
||||
|
||||
if (udpSelect.isSelected()) {
|
||||
port = Integer.parseInt(udpPort.getText());
|
||||
try {
|
||||
clnt = new UDPBowlerConnection(InetAddress.getByName(ip), port);
|
||||
DeviceManager.addConnection(clnt);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Connection failed! " + ip + " at port " + ip + " is not responding");
|
||||
BowlerStudioController.highlightException(null, e);
|
||||
if (clnt != null)
|
||||
clnt.disconnect();
|
||||
}
|
||||
|
||||
} else {
|
||||
port = Integer.parseInt(tcpPort.getText());
|
||||
BowlerTCPClient tcp = null;
|
||||
try {
|
||||
tcp = new BowlerTCPClient(ip, port);
|
||||
DeviceManager.addConnection(tcp);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Connection failed! " + ip + " at port " + ip + " is not responding");
|
||||
BowlerStudioController.highlightException(null, e);
|
||||
if (tcp != null)
|
||||
tcp.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void runsearchSerial() {
|
||||
Platform.runLater(() -> {
|
||||
portOptions.getItems().clear();
|
||||
new Thread(() -> {
|
||||
|
||||
for (String s : SerialConnection.getAvailableSerialPorts()) {
|
||||
Platform.runLater(() -> portOptions.getItems().add(s));
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void runsearchNetwork() {
|
||||
Platform.runLater(() -> {
|
||||
ipSelector.getItems().clear();
|
||||
Platform.runLater(() -> ipSelector.getItems().add("127.0.0.1"));
|
||||
new Thread(() -> {
|
||||
// System.out.println("Searching for UDP devices, please
|
||||
// wait...");
|
||||
int prt;
|
||||
try {
|
||||
prt = new Integer(udpPort.getText());
|
||||
} catch (NumberFormatException e) {
|
||||
prt = defaultPortNum;
|
||||
Platform.runLater(() -> udpPort.setText(new Integer(defaultPortNum).toString()));
|
||||
}
|
||||
clnt = new UDPBowlerConnection(prt);
|
||||
ArrayList<InetAddress> addrs = clnt.getAllAddresses();
|
||||
|
||||
for (InetAddress i : addrs) {
|
||||
Platform.runLater(() -> ipSelector.getItems().add(i.getHostAddress()));
|
||||
}
|
||||
|
||||
}).start();
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
this.primaryStage = primaryStage;
|
||||
FXMLLoader loader = AssetFactory.loadLayout("layout/BowlerConnectionMenu.fxml", true);
|
||||
Parent root;
|
||||
loader.setController(this);
|
||||
// This is needed when loading on MAC
|
||||
loader.setClassLoader(getClass().getClassLoader());
|
||||
root = loader.load();
|
||||
|
||||
Platform.runLater(() -> {
|
||||
primaryStage.setTitle("Bowler Device Connection");
|
||||
|
||||
Scene scene = new Scene(root);
|
||||
primaryStage.setScene(scene);
|
||||
primaryStage.initModality(Modality.WINDOW_MODAL);
|
||||
primaryStage.setResizable(true);
|
||||
primaryStage.show();
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
package com.neuronrobotics.bowlerstudio.utils;
|
||||
/**
|
||||
* Sample Skeleton for 'findWidget.fxml' Controller Class
|
||||
*/
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.stage.Stage;
|
||||
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.Document;
|
||||
import java.awt.*;
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class FindTextWidget extends Application {
|
||||
|
||||
@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="matchCase"
|
||||
private CheckBox matchCase; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="findBox"
|
||||
private TextField findBox; // Value injected by FXMLLoader
|
||||
|
||||
@FXML // fx:id="replaceBox"
|
||||
private TextField replaceBox; // Value injected by FXMLLoader
|
||||
|
||||
private Stage primaryStage;
|
||||
|
||||
private RSyntaxTextArea textArea;
|
||||
private int pos = 0;
|
||||
|
||||
private int find(double direction) {
|
||||
// SwingUtilities.invokeLater(() -> {
|
||||
try {
|
||||
// System.out.println("Got ctrl f "+
|
||||
// textArea.getSelectedText());
|
||||
// Get the text to find...convert it to
|
||||
// lower
|
||||
// case for eaiser comparision
|
||||
|
||||
String find = findBox.getText();
|
||||
if (!matchCase.isSelected()) {
|
||||
find = find.toLowerCase();
|
||||
}
|
||||
// Focus the text area, otherwise the
|
||||
// highlighting won't show up
|
||||
textArea.requestFocusInWindow();
|
||||
// Make sure we have a valid search term
|
||||
if (find != null && find.length() > 0) {
|
||||
Document document = textArea.getDocument();
|
||||
int findLength = find.length();
|
||||
try {
|
||||
boolean found = false;
|
||||
// Rest the search position if we're
|
||||
// at
|
||||
// the end of the document
|
||||
if (pos + findLength > document.getLength()) {
|
||||
pos = 0;
|
||||
}
|
||||
if (pos < 0) {
|
||||
pos = document.getLength() - findLength;
|
||||
}
|
||||
// While we haven't reached the
|
||||
// end...
|
||||
// "<=" Correction
|
||||
while (pos + findLength <= document.getLength() && pos >= 0) {
|
||||
// Extract the text from teh
|
||||
// docuemnt
|
||||
String match = document.getText(pos, findLength);
|
||||
if (!matchCase.isSelected()) {
|
||||
match = match.toLowerCase();
|
||||
}
|
||||
// Check to see if it matches or
|
||||
// request
|
||||
if (match.equals(find)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
pos += 1 * direction;
|
||||
}
|
||||
int baseOfFind = pos;
|
||||
// Did we find something...
|
||||
if (found) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
// Get the rectangle of the
|
||||
// where
|
||||
// the text would be visible...
|
||||
Rectangle viewRect;
|
||||
try {
|
||||
viewRect = textArea.modelToView(pos);
|
||||
// Scroll to make the rectangle
|
||||
// visible
|
||||
textArea.scrollRectToVisible(viewRect);
|
||||
// Highlight the text
|
||||
textArea.setCaretPosition((int) (pos));
|
||||
textArea.moveCaretPosition(pos + findLength);
|
||||
// Move the search position
|
||||
// beyond
|
||||
// the current match
|
||||
pos += findLength * direction;
|
||||
} catch (BadLocationException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
return baseOfFind;
|
||||
|
||||
} catch (Exception exp) {
|
||||
exp.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
// });
|
||||
return pos;
|
||||
}
|
||||
|
||||
private void replace(double direction) {
|
||||
new Thread(() -> {
|
||||
String find = findBox.getText();
|
||||
String replace = replaceBox.getText();
|
||||
if(replace==null)
|
||||
replace="";
|
||||
String current = textArea.getText();
|
||||
int intLengthOfRemove = find.length();
|
||||
|
||||
if(pos>=intLengthOfRemove){
|
||||
String firstHalf = current.substring(0,pos-intLengthOfRemove);
|
||||
String secondtHalf = current.substring(pos );
|
||||
if(direction>0) {
|
||||
if(secondtHalf.length()<=intLengthOfRemove) {
|
||||
//bail
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(firstHalf.length()<=intLengthOfRemove) {
|
||||
//bail
|
||||
return;
|
||||
}
|
||||
}
|
||||
String newContent = firstHalf + replace + secondtHalf;
|
||||
SwingUtilities.invokeLater(() ->{
|
||||
textArea.setText(newContent);
|
||||
find(direction);
|
||||
});
|
||||
}else{
|
||||
find(direction);
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
@FXML
|
||||
void findPrevious(ActionEvent event) {
|
||||
find(-1);
|
||||
}
|
||||
|
||||
@FXML
|
||||
void findNext(ActionEvent event) {
|
||||
find(1);
|
||||
}
|
||||
|
||||
@FXML
|
||||
void replaceNext(ActionEvent event) {
|
||||
replace(1);
|
||||
}
|
||||
|
||||
@FXML
|
||||
void replacePrevious(ActionEvent event) {
|
||||
replace(-1);
|
||||
}
|
||||
|
||||
@FXML // This method is called by the FXMLLoader when initialization is
|
||||
// complete
|
||||
void initialize() {
|
||||
assert matchCase != null : "fx:id=\"matchCase\" was not injected: check your FXML file 'findWidget.fxml'.";
|
||||
assert findBox != null : "fx:id=\"findBox\" was not injected: check your FXML file 'findWidget.fxml'.";
|
||||
assert replaceBox != null : "fx:id=\"replaceBox\" was not injected: check your FXML file 'findWidget.fxml'.";
|
||||
|
||||
if (textArea.getSelectedText() != null) {
|
||||
Platform.runLater(() -> findBox.setText(textArea.getSelectedText()));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
this.primaryStage = primaryStage;
|
||||
FXMLLoader loader = AssetFactory.loadLayout("layout/findWidget.fxml", true);
|
||||
Parent root;
|
||||
loader.setController(this);
|
||||
// This is needed when loading on MAC
|
||||
loader.setClassLoader(getClass().getClassLoader());
|
||||
root = loader.load();
|
||||
|
||||
Platform.runLater(() -> {
|
||||
primaryStage.setTitle("Find/Replace");
|
||||
Scene scene = new Scene(root);
|
||||
primaryStage.setScene(scene);
|
||||
// primaryStage.initModality(Modality.WINDOW_MODAL);
|
||||
primaryStage.setResizable(true);
|
||||
primaryStage.show();
|
||||
});
|
||||
}
|
||||
|
||||
public void setTextArea(RSyntaxTextArea textArea) {
|
||||
this.textArea = textArea;
|
||||
pos = 0;
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,35 @@
|
||||
package com.neuronrobotics.bowlerstudio.utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import com.neuronrobotics.nrconsole.util.FileSelectionFactory;
|
||||
import eu.mihosoft.vrl.v3d.CSG;
|
||||
import eu.mihosoft.vrl.v3d.Polygon;
|
||||
import eu.mihosoft.vrl.v3d.Slice;
|
||||
import eu.mihosoft.vrl.v3d.Transform;
|
||||
import eu.mihosoft.vrl.v3d.svg.SVGExporter;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class SVGFactory{
|
||||
|
||||
|
||||
public static File exportSVG(CSG currentCsg, File defaultDir) {
|
||||
System.out.println("Starting SVG ...");
|
||||
|
||||
File baseDirForFiles = FileSelectionFactory.GetFile(defaultDir, true);
|
||||
|
||||
if (!baseDirForFiles.getAbsolutePath().toLowerCase().endsWith(".svg"))
|
||||
baseDirForFiles = new File(baseDirForFiles.getAbsolutePath() + ".svg");
|
||||
try {
|
||||
SVGExporter.export(currentCsg, baseDirForFiles);
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println("SVG at "+baseDirForFiles);
|
||||
return baseDirForFiles.getParentFile();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.neuronrobotics.graphing;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import com.neuronrobotics.sdk.common.SDKInfo;
|
||||
|
||||
public class CSVWriter {
|
||||
private CSVWriter() {
|
||||
}
|
||||
|
||||
public static void WriteToCSV(ArrayList<GraphDataElement> dataTable, String filename) {
|
||||
String out = "";
|
||||
synchronized(dataTable){
|
||||
for(int j =0;j< dataTable.size();j++) {
|
||||
out+=dataTable.get(j).getTimestamp();
|
||||
for (int i=0;i<dataTable.get(j).getData().length;i++) {
|
||||
out+=","+dataTable.get(j).getData()[i];
|
||||
}
|
||||
out+="\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
try{
|
||||
// Create file
|
||||
FileWriter fstream = new FileWriter(filename);
|
||||
BufferedWriter outPut = new BufferedWriter(fstream);
|
||||
outPut.write(out);
|
||||
//Close the output stream
|
||||
outPut.close();
|
||||
}catch (Exception e){//Catch exception if any
|
||||
System.err.println("Error: " + e.getMessage());
|
||||
}
|
||||
File dir1 = new File (".");
|
||||
|
||||
try {
|
||||
String dir;
|
||||
if(SDKInfo.isWindows)
|
||||
dir=dir1.getCanonicalPath()+"\\";
|
||||
else
|
||||
dir=dir1.getCanonicalPath()+"/";
|
||||
JOptionPane.showMessageDialog(null, "Saved data to file: "+dir+filename, "PID Save", JOptionPane.INFORMATION_MESSAGE);
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.neuronrobotics.graphing;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
import org.jfree.data.xy.XYSeries;
|
||||
|
||||
public class DataChannel {
|
||||
private String title;
|
||||
private XYSeries series;
|
||||
private static long startTime = System.currentTimeMillis();
|
||||
private long lastTime = System.currentTimeMillis();
|
||||
|
||||
public DataChannel(String title) {
|
||||
this.title = title;
|
||||
series = new XYSeries(toString());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void graphValue(double value) {
|
||||
if((lastTime+100)>System.currentTimeMillis())
|
||||
return;
|
||||
lastTime= System.currentTimeMillis();
|
||||
// try{
|
||||
// Platform.runLater(()-> {
|
||||
// long time = System.currentTimeMillis() - startTime ;
|
||||
// if(series != null)
|
||||
// series.add((double) time/1000, value);
|
||||
// while(series.getItemCount()>3000){
|
||||
// Platform.runLater(()-> {
|
||||
// series.remove(0);
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
// }catch(IllegalStateException ex){
|
||||
// //application not yet loaded
|
||||
// }
|
||||
}
|
||||
|
||||
public XYSeries getSeries() {
|
||||
return series;
|
||||
}
|
||||
|
||||
public static void restart() {
|
||||
startTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
series.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.neuronrobotics.graphing;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public interface DataWriter {
|
||||
public void setFile(File f);
|
||||
public void addData(DataChannel c);
|
||||
public void cleanup();
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.neuronrobotics.graphing;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import jxl.Workbook;
|
||||
import jxl.WorkbookSettings;
|
||||
import jxl.write.Label;
|
||||
import jxl.write.Number;
|
||||
import jxl.write.WritableSheet;
|
||||
import jxl.write.WritableWorkbook;
|
||||
import jxl.write.WriteException;
|
||||
import jxl.write.biff.RowsExceededException;
|
||||
|
||||
import org.jfree.data.xy.XYDataItem;
|
||||
|
||||
public class ExcelWriter implements DataWriter {
|
||||
|
||||
private WorkbookSettings wbSettings = new WorkbookSettings();
|
||||
private WritableWorkbook workbook;
|
||||
private WritableSheet excelSheet;
|
||||
private int lineOffset = 0;
|
||||
public ExcelWriter() {
|
||||
wbSettings.setLocale(new Locale("en", "EN"));
|
||||
}
|
||||
|
||||
private void addNumber(int column, int row, double d) throws WriteException, RowsExceededException {
|
||||
Number number;
|
||||
number = new Number(column, row, d);
|
||||
excelSheet.addCell(number);
|
||||
}
|
||||
|
||||
private void addLabel(int column, int row, String s) throws WriteException, RowsExceededException {
|
||||
Label label;
|
||||
label = new Label(column, row, s);
|
||||
excelSheet.addCell(label);
|
||||
}
|
||||
|
||||
|
||||
public void setFile(File f) {
|
||||
try {
|
||||
workbook = Workbook.createWorkbook(f, wbSettings);
|
||||
workbook.createSheet("Data", 0);
|
||||
excelSheet = workbook.getSheet(0);
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void addData(DataChannel c) {
|
||||
try {
|
||||
int col = 1;
|
||||
addLabel(lineOffset, 0, c.toString() + " Time (ms)");
|
||||
addLabel(lineOffset+1, 0, c.toString() + " Value");
|
||||
|
||||
for(Object o : c.getSeries().getItems()) {
|
||||
XYDataItem i = (XYDataItem) o;
|
||||
addNumber(lineOffset, col, i.getXValue());
|
||||
addNumber(lineOffset+1, col, i.getYValue());
|
||||
col++;
|
||||
}
|
||||
} catch (RowsExceededException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (WriteException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
lineOffset+=2;
|
||||
}
|
||||
|
||||
|
||||
public void cleanup() {
|
||||
try {
|
||||
workbook.write();
|
||||
workbook.close();
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.neuronrobotics.graphing;
|
||||
|
||||
public class GraphDataElement {
|
||||
private long ms;
|
||||
private double [] data;
|
||||
public GraphDataElement(long currentTimeMillis, double [] data) {
|
||||
setTimestamp(currentTimeMillis);
|
||||
this.setData(data);
|
||||
}
|
||||
public void setData(double [] data) {
|
||||
this.data = data;
|
||||
}
|
||||
public double [] getData() {
|
||||
return data;
|
||||
}
|
||||
public void setTimestamp(long ms) {
|
||||
this.ms = ms;
|
||||
}
|
||||
public long getTimestamp() {
|
||||
return ms;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.neuronrobotics.graphing;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
public class GraphingOptionsDialog extends JFrame {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
@SuppressWarnings("unused")
|
||||
private GraphingWindow window;
|
||||
|
||||
public GraphingOptionsDialog(GraphingWindow window) {
|
||||
this.window = window;
|
||||
setLayout(new MigLayout());
|
||||
setTitle("Graphing Options");
|
||||
|
||||
add(new JLabel("Graphing Options"));
|
||||
|
||||
pack();
|
||||
setLocationRelativeTo(null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
package com.neuronrobotics.graphing;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JSlider;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import org.jfree.chart.ChartFactory;
|
||||
import org.jfree.chart.ChartPanel;
|
||||
import org.jfree.chart.JFreeChart;
|
||||
import org.jfree.chart.axis.ValueAxis;
|
||||
import org.jfree.chart.plot.PlotOrientation;
|
||||
import org.jfree.chart.plot.XYPlot;
|
||||
import org.jfree.data.Range;
|
||||
import org.jfree.data.xy.XYSeriesCollection;
|
||||
|
||||
|
||||
|
||||
public class GraphingWindow extends JPanel {
|
||||
private XYSeriesCollection xyDataset;
|
||||
private ChartPanel chartPanel;
|
||||
private ValueAxis axis;
|
||||
private JTextField length = new JTextField(5);
|
||||
private JSlider window = new JSlider(1, 100);
|
||||
private JSlider scale = new JSlider(1, 100);
|
||||
private ArrayList<DataChannel> dataChannels = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* long
|
||||
*/
|
||||
private static final long serialVersionUID = 2171583604829088880L;
|
||||
public GraphingWindow() {
|
||||
setName("DyIO Graph");
|
||||
xyDataset = new XYSeriesCollection();
|
||||
|
||||
JFreeChart chart = ChartFactory.createXYLineChart(
|
||||
"Live Data",
|
||||
"Time",
|
||||
"Value",
|
||||
xyDataset,
|
||||
PlotOrientation.VERTICAL,
|
||||
true,
|
||||
false,
|
||||
false);
|
||||
|
||||
chartPanel = new ChartPanel(chart);
|
||||
|
||||
XYPlot plot = (XYPlot) chart.getPlot();
|
||||
axis = plot.getDomainAxis();
|
||||
scale.setValue(100);
|
||||
setDefaultWindow();
|
||||
|
||||
scale.addChangeListener(new ChangeListener() {
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
if(window.getValue() ==100) {
|
||||
setDefaultWindow();
|
||||
}else {
|
||||
setMovedWindow(window.getValue());
|
||||
}
|
||||
}
|
||||
});
|
||||
window.setValue(100);
|
||||
window.addChangeListener(new ChangeListener() {
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
if(window.getValue() ==100) {
|
||||
setDefaultWindow();
|
||||
}else {
|
||||
setMovedWindow(window.getValue());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
length.addKeyListener(new KeyListener() {
|
||||
|
||||
|
||||
public void keyTyped(KeyEvent e) {
|
||||
if(e.getKeyChar() != '\n' && (e.getKeyChar() < '0' || e.getKeyChar() > '9')) {
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void keyReleased(KeyEvent e) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void keyPressed(KeyEvent e) {
|
||||
|
||||
}
|
||||
});
|
||||
length.addActionListener(new ActionListener() {
|
||||
|
||||
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
int value;
|
||||
try {
|
||||
value = Integer.parseInt(length.getText());
|
||||
} catch(Exception e) {
|
||||
value = scale.getMaximum();
|
||||
}
|
||||
|
||||
axis.setFixedAutoRange(value);
|
||||
length.setText(String.valueOf(value));
|
||||
scale.setValue(value);
|
||||
|
||||
invalidate();
|
||||
repaint();
|
||||
}
|
||||
});
|
||||
|
||||
JButton clearBtn = new JButton("Clear Data");
|
||||
clearBtn.addActionListener(new ActionListener() {
|
||||
|
||||
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
for(DataChannel dc : dataChannels) {
|
||||
dc.clear();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
JPanel options = new JPanel(new MigLayout());
|
||||
options.add(new JLabel("Range Size:"));
|
||||
options.add(scale);
|
||||
options.add(length);
|
||||
options.add(new JLabel("seconds"));
|
||||
options.add(clearBtn, "east");
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
setSize(new Dimension(500, 400));
|
||||
add(chartPanel, BorderLayout.CENTER);
|
||||
add(options, BorderLayout.SOUTH);
|
||||
|
||||
|
||||
JPanel opt= new JPanel(new MigLayout());
|
||||
opt.add(new JLabel("View Window"));
|
||||
opt.add(window);
|
||||
|
||||
JPanel slidingWindow= new JPanel(new MigLayout());
|
||||
slidingWindow.add(options, "wrap");
|
||||
slidingWindow.add(opt, "wrap");
|
||||
add(slidingWindow, BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
private void setDefaultWindow() {
|
||||
|
||||
axis.setAutoRange(true);
|
||||
axis.setFixedAutoRange(scale.getValue());
|
||||
length.setText(String.valueOf(scale.getValue()));
|
||||
//invalidate();
|
||||
repaint();
|
||||
}
|
||||
private void setMovedWindow(double percent) {
|
||||
|
||||
axis.setAutoRange(false);
|
||||
Range total = xyDataset.getDomainBounds(true);
|
||||
double lower =total.getLowerBound();
|
||||
double upper =total.getUpperBound();
|
||||
double loc = (upper -lower)*percent/100;
|
||||
|
||||
|
||||
double sLower =loc-(scale.getValue()/2);
|
||||
double sUpper =loc+(scale.getValue()/2);
|
||||
axis.setRange(sLower, sUpper);
|
||||
length.setText(String.valueOf(scale.getValue()));
|
||||
//invalidate();
|
||||
//repaint();
|
||||
}
|
||||
|
||||
public void addDataset(DataChannel data) {
|
||||
if(!dataChannels.contains(data)) {
|
||||
dataChannels.add(data);
|
||||
}
|
||||
|
||||
if(!(xyDataset.indexOf(data.getSeries()) > -1)) {
|
||||
showDataChannel(data);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeDataset(DataChannel data) {
|
||||
if(!dataChannels.contains(data)) {
|
||||
dataChannels.add(data);
|
||||
}
|
||||
|
||||
if(xyDataset.indexOf(data.getSeries()) > -1) {
|
||||
hideDataChannel(data);
|
||||
}
|
||||
}
|
||||
|
||||
public void hideDataChannel(DataChannel data) {
|
||||
xyDataset.removeSeries(data.getSeries());
|
||||
}
|
||||
|
||||
public void showDataChannel(DataChannel data) {
|
||||
xyDataset.addSeries(data.getSeries());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.neuronrobotics.nrconsole.plugin.BowlerCam;
|
||||
|
||||
import javafx.embed.swing.SwingNode;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.tabs.AbstractBowlerStudioTab;
|
||||
import com.neuronrobotics.sdk.bowlercam.device.BowlerCamDevice;
|
||||
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
|
||||
|
||||
public class BowlerCamController extends AbstractBowlerStudioTab{
|
||||
|
||||
private BowlerCamPanel bcp = new BowlerCamPanel();
|
||||
|
||||
@Override
|
||||
public void onTabClosing() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getMyNameSpaces() {
|
||||
// TODO Auto-generated method stub
|
||||
return new String[] {"neuronrobotics.bowlercam.*"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeUI(BowlerAbstractDevice pm) {
|
||||
|
||||
bcp.setConnection((BowlerCamDevice)pm);
|
||||
|
||||
SwingNode sn = new SwingNode();
|
||||
sn.setContent(bcp);
|
||||
ScrollPane s1 = new ScrollPane();
|
||||
|
||||
s1.setContent(sn);
|
||||
setContent(s1);
|
||||
setText("BowlerCam Control");
|
||||
onTabReOpening();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabReOpening() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
package com.neuronrobotics.nrconsole.plugin.BowlerCam;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.text.NumberFormat;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JFormattedTextField;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JSlider;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import com.neuronrobotics.sdk.bowlercam.device.BowlerCamDevice;
|
||||
import com.neuronrobotics.sdk.bowlercam.device.IWebcamImageListener;
|
||||
import com.neuronrobotics.sdk.common.BowlerAbstractConnection;
|
||||
import com.neuronrobotics.sdk.util.ThreadUtil;
|
||||
|
||||
public class BowlerCamPanel extends JPanel implements IWebcamImageListener {
|
||||
/**
|
||||
* long
|
||||
*/
|
||||
private static final long serialVersionUID = 8710018539364791015L;
|
||||
private BowlerCamDevice cam = new BowlerCamDevice();
|
||||
private JPanel directPanel = new JPanel(new MigLayout());
|
||||
private JPanel bcPanel = new JPanel(new MigLayout());
|
||||
private JPanel images = new JPanel(new MigLayout());
|
||||
private JPanel controls = new JPanel(new MigLayout());
|
||||
private JPanel sliders = new JPanel(new MigLayout());
|
||||
private JLabel fps = new JLabel("FPS: ");
|
||||
private JLabel thr = new JLabel("");
|
||||
|
||||
private RGBSlider target = new RGBSlider("Target Color");
|
||||
//private RGBSlider vector = new RGBSlider("Vector Color");
|
||||
private JSlider threshhold = new JSlider(SwingConstants.HORIZONTAL, 0, 255, 104);
|
||||
private JFormattedTextField min = new JFormattedTextField(NumberFormat.getNumberInstance());
|
||||
private JFormattedTextField max = new JFormattedTextField(NumberFormat.getNumberInstance());
|
||||
private JFormattedTextField scale = new JFormattedTextField(NumberFormat.getNumberInstance());
|
||||
private JCheckBox within = new JCheckBox("Within Threshhold");
|
||||
private JButton update = new JButton("Update Processor");
|
||||
private BufferedImage unaltered=null;
|
||||
private BufferedImage processedIm=null;
|
||||
private long time;
|
||||
double scaleSet = 1;
|
||||
|
||||
public BowlerCamPanel() {
|
||||
setName("Bowler Camera");
|
||||
images.add(directPanel);
|
||||
images.add(bcPanel);
|
||||
bcPanel.addMouseListener(new MouseListener() {
|
||||
|
||||
public void mouseReleased(MouseEvent arg0) {}
|
||||
|
||||
public void mousePressed(MouseEvent arg0) {}
|
||||
|
||||
public void mouseExited(MouseEvent arg0) {}
|
||||
|
||||
public void mouseEntered(MouseEvent arg0) {}
|
||||
|
||||
public void mouseClicked(MouseEvent arg0) {
|
||||
Color cl = new Color(unaltered.getRGB(arg0.getX(), arg0.getY()));
|
||||
getTargetColor().setColor(cl);
|
||||
}
|
||||
});
|
||||
|
||||
sliders.add(fps,"wrap");
|
||||
target.setColor(33,240, 246);
|
||||
sliders.add(target);
|
||||
controls.add(new JLabel("Threshhold"),"wrap");
|
||||
controls.add(threshhold);
|
||||
controls.add(thr,"wrap");
|
||||
thr.setText(Integer.toString(threshhold.getValue()));
|
||||
controls.add(within,"wrap");
|
||||
within.setSelected(true);
|
||||
|
||||
controls.add(new JLabel("Image Scale"));
|
||||
controls.add(scale,"wrap");
|
||||
scale.setText(Double.toString(scaleSet));
|
||||
|
||||
min.setText("5");
|
||||
max.setText("100000");
|
||||
controls.add(new JLabel("Minimum pixles per blob"));
|
||||
controls.add(min,"wrap");
|
||||
controls.add(new JLabel("Maximum pixles per blob"));
|
||||
controls.add(max,"wrap");
|
||||
update.addActionListener(new ActionListener() {
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
int minimum= Integer.parseInt(min.getText());
|
||||
int maximum= Integer.parseInt(max.getText());
|
||||
cam.updateFilter(target.getColor(), threshhold.getValue(), within.isSelected(),minimum, maximum);
|
||||
}
|
||||
});
|
||||
controls.add(update);
|
||||
|
||||
JPanel tmp2 = new JPanel(new MigLayout());
|
||||
tmp2.add(sliders);
|
||||
tmp2.add(controls);
|
||||
add(tmp2,"wrap");
|
||||
add(images,"wrap");
|
||||
}
|
||||
|
||||
public boolean setConnection(BowlerCamDevice connection) {
|
||||
try {
|
||||
cam=connection;
|
||||
cam.addWebcamImageListener(this);
|
||||
cam.startHighSpeedAutoCapture(0,scaleSet,5);
|
||||
cam.startHighSpeedAutoCapture(1,scaleSet,5);
|
||||
new displayThread().start();
|
||||
}catch(Exception ex) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private void displayImage() {
|
||||
thr.setText(Integer.toString(threshhold.getValue()));
|
||||
target.getColor();
|
||||
if(scaleSet != Double.parseDouble(scale.getText())){
|
||||
//System.out.println("Resetting scale : "+scale.getText());
|
||||
scaleSet = Double.parseDouble(scale.getText());
|
||||
cam.startHighSpeedAutoCapture(0,scaleSet,0);
|
||||
}
|
||||
updateImage(unaltered ,bcPanel);
|
||||
updateImage(processedIm,directPanel);
|
||||
}
|
||||
|
||||
protected RGBSlider getTargetColor() {
|
||||
return target;
|
||||
}
|
||||
private void updateImage(BufferedImage imageUpdate, JPanel p){
|
||||
if(imageUpdate ==null)
|
||||
return;
|
||||
p.removeAll();
|
||||
JLabel l = new JLabel();
|
||||
l.setIcon(new ImageIcon(imageUpdate));
|
||||
p.add(l);
|
||||
p.invalidate();
|
||||
}
|
||||
|
||||
public void onNewImage(int camera,BufferedImage image) {
|
||||
//System.out.println("Got image: "+camera+" at "+System.currentTimeMillis());
|
||||
if(camera == 0){
|
||||
double s=((double)(System.currentTimeMillis()-time))/1000.0;
|
||||
fps.setText("FPS: "+(int)(1/(s)));
|
||||
time = System.currentTimeMillis();
|
||||
unaltered=image;
|
||||
//process();
|
||||
//displayImage();
|
||||
}
|
||||
if(camera == 1){
|
||||
processedIm=image;
|
||||
}
|
||||
|
||||
}
|
||||
private class displayThread extends Thread{
|
||||
public void run() {
|
||||
while(cam.isAvailable()) {
|
||||
ThreadUtil.wait(200);
|
||||
displayImage();
|
||||
}
|
||||
cam.disconnect();
|
||||
cam.stopAutoCapture(0);
|
||||
cam.stopAutoCapture(1);
|
||||
//System.out.println("Bowler cam exiting");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package com.neuronrobotics.nrconsole.plugin.BowlerCam;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JSlider;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
public class RGBSlider extends JPanel {
|
||||
JSlider r = new JSlider(SwingConstants.VERTICAL, 0, 255, 128);
|
||||
JSlider g = new JSlider(SwingConstants.VERTICAL, 0, 255, 128);
|
||||
JSlider b = new JSlider(SwingConstants.VERTICAL, 0, 255, 128);
|
||||
|
||||
JLabel rl = new JLabel("128");
|
||||
JLabel gl = new JLabel("128");
|
||||
JLabel bl = new JLabel("128");
|
||||
ColorBox c = new ColorBox(Color.gray);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public RGBSlider(String name){
|
||||
setLayout(new MigLayout());
|
||||
r.setMajorTickSpacing(15);
|
||||
g.setMajorTickSpacing(15);
|
||||
b.setMajorTickSpacing(15);
|
||||
|
||||
r.setPaintTicks(true);
|
||||
g.setPaintTicks(true);
|
||||
b.setPaintTicks(true);
|
||||
|
||||
JPanel rc = new JPanel(new MigLayout());
|
||||
JPanel gc = new JPanel(new MigLayout());
|
||||
JPanel bc = new JPanel(new MigLayout());
|
||||
|
||||
rc.add(new JLabel("R"));
|
||||
rc.add(rl,"wrap");
|
||||
rc.add(r);
|
||||
|
||||
gc.add(new JLabel("G"));
|
||||
gc.add(gl,"wrap");
|
||||
gc.add(g);
|
||||
|
||||
bc.add(new JLabel("B"));
|
||||
bc.add(bl,"wrap");
|
||||
bc.add(b);
|
||||
|
||||
JPanel slides = new JPanel(new MigLayout());
|
||||
slides.add(new JLabel(name),"wrap");
|
||||
slides.add(rc);
|
||||
slides.add(gc);
|
||||
slides.add(bc);
|
||||
|
||||
add(slides,"wrap");
|
||||
add(c,"wrap");
|
||||
|
||||
}
|
||||
public void setColor(int r,int g,int b){
|
||||
this.r.setValue(r);
|
||||
this.g.setValue(g);
|
||||
this.b.setValue(b);
|
||||
getColor();
|
||||
}
|
||||
public void setColor(Color c){
|
||||
this.r.setValue(c.getRed());
|
||||
this.g.setValue(c.getGreen());
|
||||
this.b.setValue(c.getBlue());
|
||||
getColor();
|
||||
}
|
||||
public Color getColor(){
|
||||
rl.setText(Integer.toString(r.getValue()));
|
||||
gl.setText(Integer.toString(g.getValue()));
|
||||
bl.setText(Integer.toString(b.getValue()));
|
||||
Color now =new Color(r.getValue(),g.getValue(),b.getValue());
|
||||
c.setColor(now);
|
||||
setBackground(now);
|
||||
return now;
|
||||
}
|
||||
private class ColorBox extends JPanel
|
||||
{
|
||||
/**
|
||||
* long
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
public ColorBox(Color backColor){
|
||||
setSize(400, 400);
|
||||
setColor(backColor);
|
||||
}
|
||||
public void setColor(Color c) {
|
||||
setBackground(c);
|
||||
}
|
||||
public void paintComponent(Graphics g){
|
||||
super.paintComponent(g);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
package com.neuronrobotics.nrconsole.plugin.DeviceConfig;
|
||||
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.ListModel;
|
||||
import javax.swing.ScrollPaneConstants;
|
||||
|
||||
import com.neuronrobotics.sdk.addons.kinematics.LinkConfiguration;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.LinkType;
|
||||
import com.neuronrobotics.sdk.namespace.bcs.pid.IPidControlNamespace;
|
||||
|
||||
import java.awt.FlowLayout;
|
||||
|
||||
import javax.swing.JList;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.swing.JButton;
|
||||
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class AxisPanel extends JPanel {
|
||||
private LinkConfiguration thisLink;
|
||||
private JList list;
|
||||
private JScrollPane scrollPane;
|
||||
private JPanel viewPanel;
|
||||
private JButton btnNewButton;
|
||||
private JButton btnNewButton_1;
|
||||
|
||||
private SettingsListItem setLinkName;
|
||||
private SettingsListItem setLinkType;
|
||||
private SettingsListItem setHardwareIndex;
|
||||
private SettingsListItem setHomingTicksPerSecond;
|
||||
private SettingsListItem setIndexLatch;
|
||||
private SettingsListItem setKP;
|
||||
private SettingsListItem setKI;
|
||||
private SettingsListItem setKD;
|
||||
private SettingsListItem setLowerLimit;
|
||||
private SettingsListItem setUpperLimit;
|
||||
private SettingsListItem setLowerVelocity;
|
||||
private SettingsListItem setUpperVelocity;
|
||||
private SettingsListItem setLinkIndex;
|
||||
private SettingsListItem setScale;
|
||||
public AxisPanel(LinkConfiguration _thisLink){
|
||||
setLayout(new BorderLayout(0, 0));
|
||||
add(getScrollPane());
|
||||
thisLink = _thisLink;
|
||||
|
||||
//getScrollPane().add(new SettingsListItem());
|
||||
|
||||
viewPanel.add(setLinkName = new SettingsListItem("Link Name", thisLink.getName()), "cell 0 0");
|
||||
FlowLayout flowLayout = (FlowLayout) setLinkName.getLayout();
|
||||
flowLayout.setAlignment(FlowLayout.LEFT);
|
||||
viewPanel.add(setLinkType = new SettingsListItem("Link Type", thisLink.getTypeEnum().getName()), "cell 0 1");
|
||||
FlowLayout flowLayout_1 = (FlowLayout) setLinkType.getLayout();
|
||||
flowLayout_1.setAlignment(FlowLayout.LEFT);
|
||||
viewPanel.add(setHardwareIndex = new SettingsListItem("Hardware Index", thisLink.getHardwareIndex()), "cell 0 2");
|
||||
FlowLayout flowLayout_2 = (FlowLayout) setHardwareIndex.getLayout();
|
||||
flowLayout_2.setAlignment(FlowLayout.LEFT);
|
||||
viewPanel.add(setHomingTicksPerSecond = new SettingsListItem("Homing Ticks per Second", thisLink.getHomingTicksPerSecond()), "cell 0 3");
|
||||
FlowLayout flowLayout_3 = (FlowLayout) setHomingTicksPerSecond.getLayout();
|
||||
flowLayout_3.setAlignment(FlowLayout.LEFT);
|
||||
viewPanel.add(setIndexLatch = new SettingsListItem("Index Latch",thisLink.getIndexLatch()), "cell 0 4");
|
||||
FlowLayout flowLayout_4 = (FlowLayout) setIndexLatch.getLayout();
|
||||
flowLayout_4.setAlignment(FlowLayout.LEFT);
|
||||
viewPanel.add(setKP = new SettingsListItem("KP",thisLink.getKP()), "cell 0 5");
|
||||
FlowLayout flowLayout_5 = (FlowLayout) setKP.getLayout();
|
||||
flowLayout_5.setAlignment(FlowLayout.LEFT);
|
||||
viewPanel.add(setKI = new SettingsListItem("KI", thisLink.getKI()), "cell 0 6");
|
||||
FlowLayout flowLayout_6 = (FlowLayout) setKI.getLayout();
|
||||
flowLayout_6.setAlignment(FlowLayout.LEFT);
|
||||
viewPanel.add(setKD = new SettingsListItem("KD", thisLink.getKD()), "cell 0 7");
|
||||
FlowLayout flowLayout_7 = (FlowLayout) setKD.getLayout();
|
||||
flowLayout_7.setAlignment(FlowLayout.LEFT);
|
||||
viewPanel.add(setLowerLimit = new SettingsListItem("Lower Limit", thisLink.getLowerLimit()), "cell 0 8");
|
||||
FlowLayout flowLayout_8 = (FlowLayout) setLowerLimit.getLayout();
|
||||
flowLayout_8.setAlignment(FlowLayout.LEFT);
|
||||
viewPanel.add(setUpperLimit = new SettingsListItem("Upper Limit", thisLink.getUpperLimit()), "cell 0 9");
|
||||
FlowLayout flowLayout_9 = (FlowLayout) setUpperLimit.getLayout();
|
||||
flowLayout_9.setAlignment(FlowLayout.LEFT);
|
||||
viewPanel.add(setLowerVelocity = new SettingsListItem("Lower Velocity", thisLink.getLowerVelocity()), "cell 0 10");
|
||||
FlowLayout flowLayout_10 = (FlowLayout) setLowerVelocity.getLayout();
|
||||
flowLayout_10.setAlignment(FlowLayout.LEFT);
|
||||
viewPanel.add(setUpperVelocity = new SettingsListItem("Upper Velocity", thisLink.getUpperVelocity()), "cell 0 11");
|
||||
FlowLayout flowLayout_11 = (FlowLayout) setUpperVelocity.getLayout();
|
||||
flowLayout_11.setAlignment(FlowLayout.LEFT);
|
||||
viewPanel.add(setLinkIndex = new SettingsListItem("Link Index",thisLink.getLinkIndex()), "cell 0 12");
|
||||
FlowLayout flowLayout_12 = (FlowLayout) setLinkIndex.getLayout();
|
||||
flowLayout_12.setAlignment(FlowLayout.LEFT);
|
||||
viewPanel.add(setScale = new SettingsListItem("Scale" ,thisLink.getScale()), "cell 0 13");
|
||||
FlowLayout flowLayout_13 = (FlowLayout) setScale.getLayout();
|
||||
flowLayout_13.setAlignment(FlowLayout.LEFT);
|
||||
//viewPanel.add(new SettingsListItem(), "cell 0 14");
|
||||
//viewPanel.add(new SettingsListItem(), "cell 0 15");
|
||||
//viewPanel.add(new SettingsListItem(), "cell 0 16");
|
||||
//viewPanel.add(new SettingsListItem(), "cell 0 17");
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
public LinkConfiguration getLink(){
|
||||
return thisLink;
|
||||
}
|
||||
private JList getList() {
|
||||
if (list == null) {
|
||||
list = new JList();
|
||||
}
|
||||
return list;
|
||||
}
|
||||
private void reloadSettings(){
|
||||
setLinkName.loadValues("Link Name", thisLink.getName());
|
||||
setLinkType.loadValues("Link Type", thisLink.getTypeEnum().getName());
|
||||
setHardwareIndex.loadValues("Hardware Index", thisLink.getHardwareIndex());
|
||||
setHomingTicksPerSecond.loadValues("Homing Ticks per Second", thisLink.getHomingTicksPerSecond());
|
||||
setIndexLatch.loadValues("Index Latch",thisLink.getIndexLatch());
|
||||
setKP.loadValues("KP",thisLink.getKP());
|
||||
setKI.loadValues("KI", thisLink.getKI());
|
||||
setKD.loadValues("KD", thisLink.getKD());
|
||||
setLowerLimit.loadValues("Lower Limit", thisLink.getLowerLimit());
|
||||
setUpperLimit.loadValues("Upper Limit", thisLink.getUpperLimit());
|
||||
setLowerVelocity.loadValues("Lower Velocity", thisLink.getLowerVelocity());
|
||||
setUpperVelocity.loadValues("Upper Velocity", thisLink.getUpperVelocity());
|
||||
setLinkIndex.loadValues("Link Index",thisLink.getLinkIndex());
|
||||
setScale.loadValues("Scale" ,thisLink.getScale());
|
||||
|
||||
}
|
||||
public void writeSettings(){
|
||||
thisLink.setName(setLinkName.getStringValue());
|
||||
thisLink.setType(LinkType.fromString(setLinkType.getStringValue()));
|
||||
thisLink.setHardwareIndex(setHardwareIndex.getIntValue());
|
||||
thisLink.setHomingTicksPerSecond(setHomingTicksPerSecond.getIntValue());
|
||||
thisLink.setIndexLatch(setIndexLatch.getIntValue());
|
||||
thisLink.setKP(setKP.getDoubleValue());
|
||||
thisLink.setKI(setKI.getDoubleValue());
|
||||
thisLink.setKD(setKD.getDoubleValue());
|
||||
thisLink.setLowerLimit(setLowerLimit.getIntValue());
|
||||
thisLink.setUpperLimit(setUpperLimit.getIntValue());
|
||||
thisLink.setLowerVelocity(setLowerVelocity.getDoubleValue());
|
||||
thisLink.setUpperVelocity(setUpperVelocity.getDoubleValue());
|
||||
thisLink.setLinkIndex(setLinkIndex.getIntValue());
|
||||
thisLink.setScale(setScale.getDoubleValue());
|
||||
reloadSettings();
|
||||
}
|
||||
|
||||
private JScrollPane getScrollPane() {
|
||||
if (scrollPane == null) {
|
||||
scrollPane = new JScrollPane();
|
||||
scrollPane.setViewportView(getViewPanel());
|
||||
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
|
||||
}
|
||||
return scrollPane;
|
||||
}
|
||||
private JPanel getViewPanel() {
|
||||
if (viewPanel == null) {
|
||||
viewPanel = new JPanel();
|
||||
viewPanel.setLayout(new MigLayout("", "[grow,fill]", "[][]"));
|
||||
|
||||
}
|
||||
return viewPanel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
package com.neuronrobotics.nrconsole.plugin.DeviceConfig;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import com.neuronrobotics.replicator.driver.BowlerBoardDevice;
|
||||
import com.neuronrobotics.replicator.driver.NRPrinter;
|
||||
import com.neuronrobotics.replicator.driver.Slic3r;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.LinkConfiguration;
|
||||
import com.neuronrobotics.sdk.addons.kinematics.LinkFactory;
|
||||
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
//import com.sun.deploy.uitoolkit.impl.fx.Utils;
|
||||
//import com.sun.deploy.uitoolkit.impl.fx.Utils;
|
||||
|
||||
public class DeviceConfigPanel extends JPanel {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 12345L;
|
||||
private NRPrinter printer;
|
||||
File gCodes = null;
|
||||
FileInputStream gCodeStream;
|
||||
double currpos = 0;
|
||||
|
||||
|
||||
|
||||
long lastUpdate = 0;
|
||||
public String fileName = "None";
|
||||
|
||||
private JPanel pnlAction;
|
||||
private JButton btnReloadConfigs;
|
||||
private JButton btnWriteConfigs;
|
||||
private JTabbedPane tabPnlSettings;
|
||||
private JScrollPane pnlSlic3rSetts;
|
||||
|
||||
private Slic3rMasterPanel slic3rSettingsPanel = new Slic3rMasterPanel();
|
||||
private LocalSettingsPanel localSettingsPanel = new LocalSettingsPanel();
|
||||
private JPanel axisConfigsPanel;
|
||||
private JTabbedPane AxisTabs;
|
||||
private ArrayList<AxisPanel> axisPanels = new ArrayList<>();
|
||||
public DeviceConfigPanel() {
|
||||
|
||||
java.awt.EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
initComponents();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void setDevices(BowlerBoardDevice delt, NRPrinter printer) {
|
||||
this.printer = printer;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void initComponents() {
|
||||
setLayout(new MigLayout("", "[grow]", "[][grow]"));
|
||||
add(getPnlAction(), "cell 0 0,grow");
|
||||
add(getTabPnlSettings(), "cell 0 1,grow");
|
||||
}
|
||||
|
||||
|
||||
public void updateSettings(){
|
||||
printer.reloadSlic3rSettings();
|
||||
|
||||
|
||||
slic3rSettingsPanel.setValue(0, new MachineSetting<Double>("NozzleDia" ,printer.getSlicer().getNozzle_diameter()));
|
||||
slic3rSettingsPanel.setValue(1, new MachineSetting<Double>("PCenterX" ,printer.getSlicer().getPrintCenter()[0]));
|
||||
slic3rSettingsPanel.setValue(2, new MachineSetting<Double>("PCenterY" ,printer.getSlicer().getPrintCenter()[1]));
|
||||
slic3rSettingsPanel.setValue(3, new MachineSetting<Double>("FilaDia" ,printer.getSlicer().getFilimentDiameter()));
|
||||
slic3rSettingsPanel.setValue(4, new MachineSetting<Double>("ExtMult" ,printer.getSlicer().getExtrusionMultiplier()));
|
||||
slic3rSettingsPanel.setValue(5, new MachineSetting<Integer>("PTemp" , printer.getSlicer().getTempreture()));
|
||||
slic3rSettingsPanel.setValue(6, new MachineSetting<Integer>("BTemp" , printer.getSlicer().getBedTempreture()));
|
||||
slic3rSettingsPanel.setValue(7, new MachineSetting<Double>("LayerHeight" ,printer.getSlicer().getLayerHeight()));
|
||||
slic3rSettingsPanel.setValue(8, new MachineSetting<Integer>("WallThickness" , printer.getSlicer().getWallThickness()));
|
||||
slic3rSettingsPanel.setValue(9, new MachineSetting<Boolean>("UseSupport" ,printer.getSlicer().isUseSupportMaterial()));
|
||||
slic3rSettingsPanel.setValue(10, new MachineSetting<Double>("RetractLength" ,printer.getSlicer().getRetractLength()));
|
||||
slic3rSettingsPanel.setValue(11, new MachineSetting<Integer>("TravelSpd" ,printer.getSlicer().getTravilSpeed()));
|
||||
slic3rSettingsPanel.setValue(12, new MachineSetting<Integer>("PeriSpd" ,printer.getSlicer().getPerimeterSpeed()));
|
||||
slic3rSettingsPanel.setValue(13, new MachineSetting<Integer>("BridgeSpd" ,printer.getSlicer().getBridgeSpeed()));
|
||||
slic3rSettingsPanel.setValue(14, new MachineSetting<Integer>("GapFillSpd" ,printer.getSlicer().getGapFillSpeed()));
|
||||
slic3rSettingsPanel.setValue(15, new MachineSetting<Integer>("InfillSpd" ,printer.getSlicer().getInfillSpeed()));
|
||||
slic3rSettingsPanel.setValue(16, new MachineSetting<Integer>("SupPeriSpdPcnt" ,printer.getSlicer().getSupportMaterialInterfaceSpeedPercent()));
|
||||
slic3rSettingsPanel.setValue(17, new MachineSetting<Integer>("SmPeriSpdPcnt" ,printer.getSlicer().getSmallPerimeterSpeedPercent()));
|
||||
slic3rSettingsPanel.setValue(18, new MachineSetting<Integer>("ExtPeriSpdPcnt" ,printer.getSlicer().getExternalPerimeterSpeedPercent()));
|
||||
slic3rSettingsPanel.setValue(19, new MachineSetting<Integer>("SolidInfillSpdPcnt" ,printer.getSlicer().getSolidInfillSpeedPercent()));
|
||||
slic3rSettingsPanel.setValue(20, new MachineSetting<Integer>("TopSolidInfillSpdPcnt" ,printer.getSlicer().getTopSolidInfillSpeedPercent()));
|
||||
slic3rSettingsPanel.setValue(21, new MachineSetting<Integer>("SupportMatIntSpdPcnt" ,printer.getSlicer().getSupportMaterialSpeed()));
|
||||
slic3rSettingsPanel.setValue(22, new MachineSetting<Integer>("FirstLayerSpdPcnt" ,printer.getSlicer().getFirstLayerSpeedPercent()));
|
||||
|
||||
System.out.println(printer.getLinkConfigurations().size());
|
||||
|
||||
|
||||
getAxisTabs().removeAll();
|
||||
axisPanels.clear();
|
||||
|
||||
for (LinkConfiguration lCfg : printer.getLinkConfigurations()) {
|
||||
AxisPanel aPNL = new AxisPanel(lCfg);
|
||||
axisPanels.add(aPNL);
|
||||
getAxisTabs().addTab(lCfg.getName(), aPNL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
localSettingsPanel.reloadAllSettings();
|
||||
|
||||
}
|
||||
|
||||
public void writeSettings(){
|
||||
slic3rSettingsPanel.checkNewSettings();
|
||||
|
||||
Slic3r newSettings = new Slic3r(
|
||||
slic3rSettingsPanel.getDoubleValue(0),
|
||||
new double[]{slic3rSettingsPanel.getDoubleValue(1),slic3rSettingsPanel.getDoubleValue(2)},
|
||||
slic3rSettingsPanel.getDoubleValue(3),
|
||||
slic3rSettingsPanel.getDoubleValue(4),
|
||||
slic3rSettingsPanel.getIntegerValue(5),
|
||||
slic3rSettingsPanel.getIntegerValue(6),
|
||||
slic3rSettingsPanel.getDoubleValue(7),
|
||||
slic3rSettingsPanel.getIntegerValue(8),
|
||||
slic3rSettingsPanel.getBooleanValue(9),
|
||||
slic3rSettingsPanel.getDoubleValue(10),
|
||||
slic3rSettingsPanel.getIntegerValue(11),
|
||||
slic3rSettingsPanel.getIntegerValue(12),
|
||||
slic3rSettingsPanel.getIntegerValue(13),
|
||||
slic3rSettingsPanel.getIntegerValue(14),
|
||||
slic3rSettingsPanel.getIntegerValue(15),
|
||||
slic3rSettingsPanel.getIntegerValue(16),
|
||||
slic3rSettingsPanel.getIntegerValue(17),
|
||||
slic3rSettingsPanel.getIntegerValue(18),
|
||||
slic3rSettingsPanel.getIntegerValue(19),
|
||||
slic3rSettingsPanel.getIntegerValue(20),
|
||||
slic3rSettingsPanel.getIntegerValue(21),
|
||||
slic3rSettingsPanel.getIntegerValue(22));
|
||||
printer.getDeltaDevice().setSlic3rConfiguration(newSettings);
|
||||
for (AxisPanel axisPanel : axisPanels) {
|
||||
axisPanel.writeSettings();
|
||||
printer.getDeltaDevice().setLinkConfiguration(axisPanels.indexOf(axisPanel), axisPanel.getLink());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private JPanel getPnlAction() {
|
||||
if (pnlAction == null) {
|
||||
pnlAction = new JPanel();
|
||||
pnlAction.setLayout(new MigLayout("", "[][]", "[]"));
|
||||
pnlAction.add(getBtnReloadConfigs(), "cell 0 0");
|
||||
pnlAction.add(getBtnWriteConfigs(), "cell 1 0");
|
||||
}
|
||||
return pnlAction;
|
||||
}
|
||||
private JButton getBtnReloadConfigs() {
|
||||
if (btnReloadConfigs == null) {
|
||||
btnReloadConfigs = new JButton("Reload Configs");
|
||||
btnReloadConfigs.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
updateSettings();
|
||||
}
|
||||
});
|
||||
}
|
||||
return btnReloadConfigs;
|
||||
}
|
||||
private JButton getBtnWriteConfigs() {
|
||||
if (btnWriteConfigs == null) {
|
||||
btnWriteConfigs = new JButton("Write Configs");
|
||||
btnWriteConfigs.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
writeSettings();
|
||||
}
|
||||
});
|
||||
}
|
||||
return btnWriteConfigs;
|
||||
}
|
||||
private JTabbedPane getTabPnlSettings() {
|
||||
if (tabPnlSettings == null) {
|
||||
tabPnlSettings = new JTabbedPane(JTabbedPane.TOP);
|
||||
tabPnlSettings.addChangeListener(new ChangeListener() {
|
||||
public void stateChanged(ChangeEvent arg0) {
|
||||
try {
|
||||
updateSettings();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
tabPnlSettings.addTab(slic3rSettingsPanel.getPanelName(), null, slic3rSettingsPanel, null);
|
||||
tabPnlSettings.addTab(localSettingsPanel.getPanelName(), null, localSettingsPanel, null);
|
||||
tabPnlSettings.addTab("Axis Configs", null, getAxisConfigsPanel(), null);
|
||||
|
||||
}
|
||||
return tabPnlSettings;
|
||||
}
|
||||
|
||||
|
||||
private JPanel getAxisConfigsPanel() {
|
||||
if (axisConfigsPanel == null) {
|
||||
axisConfigsPanel = new JPanel();
|
||||
axisConfigsPanel.setLayout(new BorderLayout(0, 0));
|
||||
axisConfigsPanel.add(getAxisTabs(), BorderLayout.CENTER);
|
||||
}
|
||||
return axisConfigsPanel;
|
||||
}
|
||||
private JTabbedPane getAxisTabs() {
|
||||
if (AxisTabs == null) {
|
||||
AxisTabs = new JTabbedPane(JTabbedPane.TOP);
|
||||
}
|
||||
return AxisTabs;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
package com.neuronrobotics.nrconsole.plugin.DeviceConfig;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javafx.stage.FileChooser.ExtensionFilter;
|
||||
|
||||
import javax.swing.GroupLayout;
|
||||
import javax.swing.GroupLayout.Alignment;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.LayoutStyle.ComponentPlacement;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import com.neuronrobotics.nrconsole.util.FileSelectionFactory;
|
||||
import com.neuronrobotics.nrconsole.util.PrefsLoader;
|
||||
import com.neuronrobotics.nrconsole.util.Slic3rFilter;
|
||||
|
||||
public class LocalSettingsPanel extends SettingsPanel {
|
||||
private JTextField tfSlic3rLocation;
|
||||
private JButton btnChangeSlicr;
|
||||
private JLabel lblCurrentLocationOf;
|
||||
String slic3rPath;
|
||||
PrefsLoader prefs = new PrefsLoader();
|
||||
private JButton btnLoadDefaults;
|
||||
/**
|
||||
* Create the panel.
|
||||
*/
|
||||
public LocalSettingsPanel() {
|
||||
initComponents();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String getPanelName() {
|
||||
return "Local Settings";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initComponents() {
|
||||
GroupLayout groupLayout = new GroupLayout(this);
|
||||
groupLayout.setHorizontalGroup(
|
||||
groupLayout.createParallelGroup(Alignment.LEADING)
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
|
||||
.addGroup(Alignment.TRAILING, groupLayout.createSequentialGroup()
|
||||
.addComponent(getTfSlic3rLocation(), GroupLayout.DEFAULT_SIZE, 283, Short.MAX_VALUE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getBtnChangeSlicr()))
|
||||
.addComponent(getBtnLoadDefaults(), Alignment.TRAILING)
|
||||
.addComponent(getLblCurrentLocationOf()))
|
||||
.addContainerGap())
|
||||
);
|
||||
groupLayout.setVerticalGroup(
|
||||
groupLayout.createParallelGroup(Alignment.LEADING)
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(getLblCurrentLocationOf())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(getTfSlic3rLocation(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(getBtnChangeSlicr()))
|
||||
.addPreferredGap(ComponentPlacement.RELATED, 212, Short.MAX_VALUE)
|
||||
.addComponent(getBtnLoadDefaults())
|
||||
.addContainerGap())
|
||||
);
|
||||
setLayout(groupLayout);
|
||||
getTfSlic3rLocation().setText(prefs.getSlic3rLocation());
|
||||
|
||||
}
|
||||
public void reloadAllSettings(){
|
||||
getTfSlic3rLocation().setText(prefs.getSlic3rLocation());
|
||||
}
|
||||
private void changeSlic3rLocation(){
|
||||
slic3rPath = FileSelectionFactory.GetFile(null, new ExtensionFilter("Slicer Executable","*")).getPath();
|
||||
prefs.setSlic3rLocation(slic3rPath);
|
||||
getTfSlic3rLocation().setText(prefs.getSlic3rLocation());
|
||||
}
|
||||
private JTextField getTfSlic3rLocation() {
|
||||
if (tfSlic3rLocation == null) {
|
||||
tfSlic3rLocation = new JTextField();
|
||||
tfSlic3rLocation.setHorizontalAlignment(SwingConstants.LEFT);
|
||||
tfSlic3rLocation.setEditable(false);
|
||||
tfSlic3rLocation.setColumns(10);
|
||||
}
|
||||
return tfSlic3rLocation;
|
||||
}
|
||||
private JButton getBtnChangeSlicr() {
|
||||
if (btnChangeSlicr == null) {
|
||||
btnChangeSlicr = new JButton("Change Slic3r Location");
|
||||
btnChangeSlicr.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
changeSlic3rLocation();
|
||||
}
|
||||
});
|
||||
}
|
||||
return btnChangeSlicr;
|
||||
}
|
||||
private JLabel getLblCurrentLocationOf() {
|
||||
if (lblCurrentLocationOf == null) {
|
||||
lblCurrentLocationOf = new JLabel("Current Location of slic3r-console.exe:");
|
||||
}
|
||||
return lblCurrentLocationOf;
|
||||
}
|
||||
private JButton getBtnLoadDefaults() {
|
||||
if (btnLoadDefaults == null) {
|
||||
btnLoadDefaults = new JButton("Load Defaults");
|
||||
btnLoadDefaults.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
|
||||
java.awt.EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
if (JOptionPane.showConfirmDialog(null, "This operation could be dangerous and break things.\n"
|
||||
+ "You should restart NrConsole immediately after performing this action to avoid problems.", "This could be risky...", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION){
|
||||
prefs.loadDefaults();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
reloadAllSettings();
|
||||
}
|
||||
});
|
||||
}
|
||||
return btnLoadDefaults;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.neuronrobotics.nrconsole.plugin.DeviceConfig;
|
||||
|
||||
public class MachineSetting<V> {
|
||||
|
||||
private final String name;
|
||||
private V value;
|
||||
|
||||
public MachineSetting(String _name,V v) {
|
||||
name = _name;
|
||||
value = v;
|
||||
}
|
||||
public MachineSetting(String _name) {
|
||||
name = _name;
|
||||
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public V getValue() {
|
||||
return value;
|
||||
}
|
||||
public void setValue(V _value) {
|
||||
value = _value;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "(" + name + ", " + value + ")";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.neuronrobotics.nrconsole.plugin.DeviceConfig;
|
||||
|
||||
import javafx.embed.swing.SwingNode;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
|
||||
import com.neuronrobotics.bowlerstudio.tabs.AbstractBowlerStudioTab;
|
||||
import com.neuronrobotics.replicator.driver.BowlerBoardDevice;
|
||||
import com.neuronrobotics.replicator.driver.NRPrinter;
|
||||
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
|
||||
|
||||
public class PrinterConiguration extends AbstractBowlerStudioTab{
|
||||
|
||||
private DeviceConfigPanel gui = new DeviceConfigPanel();
|
||||
|
||||
@Override
|
||||
public void onTabClosing() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getMyNameSpaces() {
|
||||
return new String[]{"bcs.cartesian.*"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeUI(BowlerAbstractDevice pm) {
|
||||
NRPrinter printer = (NRPrinter)pm;
|
||||
BowlerBoardDevice delt = printer.getDeltaDevice();
|
||||
|
||||
if (delt.isAvailable()){
|
||||
gui.setDevices(delt,printer);
|
||||
}
|
||||
if (delt.isAvailable()){
|
||||
gui.updateSettings();
|
||||
}
|
||||
|
||||
SwingNode sn = new SwingNode();
|
||||
sn.setContent(gui);
|
||||
ScrollPane s1 = new ScrollPane();
|
||||
|
||||
s1.setContent(sn);
|
||||
setContent(s1);
|
||||
setText("Printer Config");
|
||||
onTabReOpening();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabReOpening() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.neuronrobotics.nrconsole.plugin.DeviceConfig;
|
||||
|
||||
public interface SettingsChangeListener {
|
||||
public void settingsChanged();
|
||||
public void settingsRequest();
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package com.neuronrobotics.nrconsole.plugin.DeviceConfig;
|
||||
|
||||
import java.awt.List;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.beans.VetoableChangeListener;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.Color;
|
||||
|
||||
import javax.swing.JFormattedTextField;
|
||||
import javax.swing.event.CaretEvent;
|
||||
import javax.swing.event.CaretListener;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
import java.awt.event.InputMethodListener;
|
||||
import java.awt.event.InputMethodEvent;
|
||||
|
||||
public class SettingsListItem extends JPanel {
|
||||
private JLabel lblNewLabel;
|
||||
private JTextField txtSetVal;
|
||||
private String labelTxt;
|
||||
private String currentValue;
|
||||
public SettingsListItem() {
|
||||
add(getLblNewLabel());
|
||||
add(getTxtSetVal());
|
||||
|
||||
}
|
||||
public SettingsListItem(String _lblText, String _value) {
|
||||
add(getLblNewLabel());
|
||||
add(getTxtSetVal());
|
||||
loadValues( _lblText, _value);
|
||||
|
||||
}
|
||||
public SettingsListItem(String _lblText, int _value) {
|
||||
add(getLblNewLabel());
|
||||
add(getTxtSetVal());
|
||||
loadValues( _lblText, _value);
|
||||
|
||||
}
|
||||
public SettingsListItem(String _lblText, double _value) {
|
||||
add(getLblNewLabel());
|
||||
add(getTxtSetVal());
|
||||
loadValues( _lblText, _value);
|
||||
|
||||
}
|
||||
|
||||
public void loadValues(String _lblTxt, String _value){
|
||||
currentValue = _value;
|
||||
labelTxt =_lblTxt;
|
||||
getLblNewLabel().setText(_lblTxt);
|
||||
getTxtSetVal().setText(_value);
|
||||
}
|
||||
public void loadValues(String _lblTxt, int _value){
|
||||
currentValue = Integer.toString(_value);
|
||||
labelTxt =_lblTxt;
|
||||
getLblNewLabel().setText(_lblTxt);
|
||||
getTxtSetVal().setText(Integer.toString(_value));
|
||||
}
|
||||
public void loadValues(String _lblTxt, double _value){
|
||||
currentValue = Double.toString(_value);
|
||||
labelTxt =_lblTxt;
|
||||
getLblNewLabel().setText(_lblTxt);
|
||||
getTxtSetVal().setText(Double.toString(_value));
|
||||
}
|
||||
|
||||
private JLabel getLblNewLabel() {
|
||||
if (lblNewLabel == null) {
|
||||
lblNewLabel = new JLabel("New label");
|
||||
}
|
||||
return lblNewLabel;
|
||||
}
|
||||
public int getIntValue(){
|
||||
try {
|
||||
return Integer.valueOf(getTxtSetVal().getText());
|
||||
} catch (Exception e) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
public double getDoubleValue(){
|
||||
try {
|
||||
|
||||
return Double.valueOf(getTxtSetVal().getText());
|
||||
} catch (Exception e) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
public String getStringValue(){
|
||||
return getTxtSetVal().getText();
|
||||
}
|
||||
private JTextField getTxtSetVal() {
|
||||
if (txtSetVal == null) {
|
||||
txtSetVal = new JTextField();
|
||||
txtSetVal.setText("Setting");
|
||||
|
||||
txtSetVal.addCaretListener(new CaretListener() {
|
||||
|
||||
@Override
|
||||
public void caretUpdate(CaretEvent e) {
|
||||
if (txtSetVal.getText().equals(currentValue)){
|
||||
txtSetVal.setBackground(Color.WHITE);
|
||||
}
|
||||
else{
|
||||
txtSetVal.setBackground(Color.ORANGE);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
txtSetVal.setColumns(10);
|
||||
}
|
||||
return txtSetVal;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
package com.neuronrobotics.nrconsole.plugin.DeviceConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
public abstract class SettingsPanel extends JPanel {
|
||||
private ArrayList<MachineSetting> settings = new ArrayList<>();
|
||||
private List<SettingsChangeListener> listeners = new ArrayList<>();
|
||||
|
||||
|
||||
|
||||
public abstract String getPanelName();
|
||||
|
||||
public abstract void initComponents();
|
||||
public void addListener(SettingsChangeListener toAdd) {
|
||||
listeners.add(toAdd);
|
||||
}
|
||||
public void removeListeners() {
|
||||
listeners.clear();
|
||||
}
|
||||
public void notifySettingsChanged(){
|
||||
for (SettingsChangeListener ptl : listeners) {
|
||||
ptl.settingsChanged();
|
||||
}
|
||||
}
|
||||
public void notifySettingsRequest(){
|
||||
for (SettingsChangeListener ptl : listeners) {
|
||||
ptl.settingsRequest();
|
||||
}
|
||||
}
|
||||
|
||||
public void checkNewSettings(){
|
||||
notifySettingsRequest();
|
||||
}
|
||||
|
||||
public ArrayList<MachineSetting> getValues(){
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
public void setValues(ArrayList<MachineSetting> values) {
|
||||
settings = values;
|
||||
notifySettingsChanged();
|
||||
}
|
||||
|
||||
public boolean settingExists(String _name){
|
||||
for (MachineSetting machineSetting : settings) {
|
||||
if (machineSetting.getName() == _name){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public MachineSetting getSetting(String _name){
|
||||
|
||||
for (MachineSetting machineSetting : settings) {
|
||||
if (machineSetting.getName() == _name){
|
||||
return machineSetting;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public int numSettings(){
|
||||
return settings.size();
|
||||
}
|
||||
|
||||
public MachineSetting getSetting(int index){
|
||||
|
||||
return settings.get(index);
|
||||
}
|
||||
public void setValue(int index, MachineSetting item){
|
||||
|
||||
if (settings.size() <= index){
|
||||
settings.add(index, item);
|
||||
}
|
||||
else{
|
||||
settings.set(index, item);
|
||||
}
|
||||
notifySettingsChanged();
|
||||
}
|
||||
|
||||
public Object getSetValue(String _name){
|
||||
|
||||
for (MachineSetting machineSetting : settings) {
|
||||
if (machineSetting.getName() == _name){
|
||||
return machineSetting.getValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public Object getSetValue(int index){
|
||||
|
||||
return settings.get(index).getValue();
|
||||
}
|
||||
public int getIntValue(String _name){
|
||||
|
||||
for (MachineSetting machineSetting : settings) {
|
||||
if (machineSetting.getName() == _name){
|
||||
return (Integer) machineSetting.getValue();
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
public boolean getBooleanValue(String _name){
|
||||
|
||||
for (MachineSetting machineSetting : settings) {
|
||||
if (machineSetting.getName() == _name){
|
||||
return (Boolean) machineSetting.getValue();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public double getDoubleValue(String _name){
|
||||
|
||||
for (MachineSetting machineSetting : settings) {
|
||||
if (machineSetting.getName() == _name){
|
||||
return (Double) machineSetting.getValue();
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
public double getDoubleValue(int index){
|
||||
|
||||
return (Double) settings.get(index).getValue();
|
||||
}
|
||||
|
||||
public int getIntegerValue(int index){
|
||||
|
||||
return (Integer) settings.get(index).getValue();
|
||||
}
|
||||
|
||||
public boolean getBooleanValue(int index){
|
||||
|
||||
return (Boolean) settings.get(index).getValue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,909 @@
|
||||
package com.neuronrobotics.nrconsole.plugin.DeviceConfig;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
|
||||
import javax.swing.GroupLayout;
|
||||
import javax.swing.GroupLayout.Alignment;
|
||||
import javax.swing.JFormattedTextField;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.LayoutStyle.ComponentPlacement;
|
||||
|
||||
public class Slic3rAll extends SettingsPanel implements SettingsChangeListener{
|
||||
private JLabel lblNozzleDiameter;
|
||||
private JLabel lblPrintCenter;
|
||||
private JLabel lblFilamentDiameter;
|
||||
private JLabel lblExtrusionMultiplier;
|
||||
private JLabel lblPrintTemperature;
|
||||
private JLabel lblBedTemperature;
|
||||
private JLabel lblLayerHeight;
|
||||
private JLabel lblWallThickness;
|
||||
private JLabel lblUseSupportMaterial;
|
||||
private JLabel lblRetractLength;
|
||||
private JLabel lblTravelSpeed;
|
||||
private JLabel lblPerimeterSpeed;
|
||||
private JLabel lblBridgeSpeed;
|
||||
private JLabel lblGapFillSpeed;
|
||||
private JLabel lblInfillSpeed;
|
||||
private JLabel lblSupportMaterialSpeed;
|
||||
private JLabel lblSmallPerimeterSpeed;
|
||||
private JLabel lblExternalPerimeterSpeed;
|
||||
private JLabel lblSolidInfillSpeed;
|
||||
private JLabel lblTopSolidInfill;
|
||||
private JLabel lblSupportMaterialInterface;
|
||||
private JLabel lblFirstLayerSpeed;
|
||||
private JFormattedTextField tfNozzleDia;
|
||||
private JLabel lblX;
|
||||
private JFormattedTextField tfPrintCenterX;
|
||||
private JLabel lblY;
|
||||
private JFormattedTextField tfPrintCenterY;
|
||||
private JFormattedTextField tfFilaDia;
|
||||
private JFormattedTextField tfExtrusionMult;
|
||||
private JFormattedTextField tfPTemp;
|
||||
private JFormattedTextField tfBTemp;
|
||||
private JFormattedTextField tfLayerHeight;
|
||||
private JFormattedTextField tfWallThickness;
|
||||
private JFormattedTextField tfRetractLength;
|
||||
private JFormattedTextField tfTravelSpeed;
|
||||
private JFormattedTextField tfPerimeterSpeed;
|
||||
private JFormattedTextField tfBridgeSpeed;
|
||||
private JFormattedTextField tfGapFillSpeed;
|
||||
private JFormattedTextField tfInfillSpeed;
|
||||
private JFormattedTextField tfSupportMaterialSpeed;
|
||||
private JFormattedTextField tfSmallPerimeterSpeedPercent;
|
||||
private JFormattedTextField tfExternalPerimeterSpeedPercent;
|
||||
private JFormattedTextField tfSolidInfillSpeedPercent;
|
||||
private JFormattedTextField tfTopSolidInfillSpeedPercent;
|
||||
private JFormattedTextField tfSupportMaterialInterSpeedPercent;
|
||||
private JFormattedTextField tfFirstLayerSpeedPercent;
|
||||
private JLabel lblMm;
|
||||
private JLabel lblMm_1;
|
||||
private JLabel lblMm_2;
|
||||
private JLabel lblMm_3;
|
||||
private JLabel lblc;
|
||||
private JLabel lblc_1;
|
||||
private JLabel lblMm_4;
|
||||
private JLabel lblMm_5;
|
||||
private JLabel lblMm_6;
|
||||
private JLabel lblMms;
|
||||
private JLabel lblMms_1;
|
||||
private JLabel lblMms_2;
|
||||
private JLabel lblMms_3;
|
||||
private JLabel lblMms_4;
|
||||
private JLabel lblMms_5;
|
||||
private JLabel label;
|
||||
private JLabel label_1;
|
||||
private JLabel label_2;
|
||||
private JLabel label_3;
|
||||
private JLabel label_4;
|
||||
private JLabel label_5;
|
||||
private Slic3rMasterPanel master;
|
||||
public Slic3rAll(Slic3rMasterPanel _master) {
|
||||
master = _master;
|
||||
java.awt.EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
initComponents();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getPanelName() {
|
||||
return "Slic3r Settings";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void settingsChanged() {
|
||||
|
||||
if (master.numSettings() > 22){
|
||||
tfNozzleDia.setValue(master.getSetting(0).getValue());
|
||||
tfPrintCenterX.setValue(master.getSetting(1).getValue());
|
||||
tfPrintCenterY.setValue(master.getSetting(2).getValue());
|
||||
tfFilaDia.setValue(master.getSetting(3).getValue());
|
||||
tfExtrusionMult.setValue(master.getSetting(4).getValue());
|
||||
tfPTemp.setValue(master.getSetting(5).getValue());
|
||||
tfBTemp.setValue(master.getSetting(6).getValue());
|
||||
tfLayerHeight.setValue(master.getSetting(7).getValue());
|
||||
tfWallThickness.setValue(master.getSetting(8).getValue());
|
||||
//TODO Use Support Material?
|
||||
tfRetractLength.setValue(master.getSetting(10).getValue());
|
||||
tfTravelSpeed.setValue(master.getSetting(11).getValue());
|
||||
tfPerimeterSpeed.setValue(master.getSetting(12).getValue());
|
||||
tfBridgeSpeed.setValue(master.getSetting(13).getValue());
|
||||
tfGapFillSpeed.setValue(master.getSetting(14).getValue());
|
||||
tfInfillSpeed.setValue(master.getSetting(15).getValue());
|
||||
tfSupportMaterialSpeed.setValue(master.getSetting(16).getValue());
|
||||
tfSmallPerimeterSpeedPercent.setValue(master.getSetting(17).getValue());
|
||||
tfExternalPerimeterSpeedPercent.setValue(master.getSetting(18).getValue());
|
||||
tfSolidInfillSpeedPercent.setValue(master.getSetting(19).getValue());
|
||||
tfTopSolidInfillSpeedPercent.setValue(master.getSetting(20).getValue());
|
||||
tfSupportMaterialInterSpeedPercent.setValue(master.getSetting(21).getValue());
|
||||
tfFirstLayerSpeedPercent.setValue(master.getSetting(22).getValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void initComponents() {
|
||||
|
||||
GroupLayout groupLayout = new GroupLayout(this);
|
||||
groupLayout.setHorizontalGroup(
|
||||
groupLayout.createParallelGroup(Alignment.LEADING)
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(getLblNozzleDiameter())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getTfNozzleDia(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLblMm()))
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(getLblPrintCenter())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLblX())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getTfPrintCenterX(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLblMm_1())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLblY())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getTfPrintCenterY(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLblMm_2()))
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(getLblFilamentDiameter())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getTfFilaDia(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLblMm_3()))
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(getLblExtrusionMultiplier())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getTfExtrusionMult(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(getLblPrintTemperature())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getTfPTemp(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLblc()))
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(getLblBedTemperature())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getTfBTemp(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLblc_1()))
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(getLblLayerHeight())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getTfLayerHeight(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLblMm_4()))
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(getLblWallThickness())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getTfWallThickness(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLblMm_5()))
|
||||
.addComponent(getLblUseSupportMaterial())
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(getLblRetractLength())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getTfRetractLength(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLblMm_6()))
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(getLblTravelSpeed())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getTfTravelSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLblMms()))
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(getLblPerimeterSpeed())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getTfPerimeterSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLblMms_1()))
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(getLblInfillSpeed())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getTfInfillSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLblMms_4()))
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(getLblSupportMaterialSpeed())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getTfSupportMaterialSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLblMms_5()))
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(getLblSmallPerimeterSpeed())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getTfSmallPerimeterSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLabel()))
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(getLblExternalPerimeterSpeed())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getTfExternalPerimeterSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLabel_1()))
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(getLblSolidInfillSpeed())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getTfSolidInfillSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLabel_2()))
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(getLblTopSolidInfill())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getTfTopSolidInfillSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLabel_3()))
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(getLblSupportMaterialInterface())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getTfSupportMaterialInterSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLabel_4()))
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(getLblFirstLayerSpeed())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getTfFirstLayerSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLabel_5()))
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
|
||||
.addComponent(getLblBridgeSpeed())
|
||||
.addComponent(getLblGapFillSpeed()))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(getTfGapFillSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLblMms_3()))
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(getTfBridgeSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLblMms_2())))))
|
||||
.addContainerGap(140, Short.MAX_VALUE))
|
||||
);
|
||||
groupLayout.setVerticalGroup(
|
||||
groupLayout.createParallelGroup(Alignment.LEADING)
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(getLblNozzleDiameter())
|
||||
.addComponent(getTfNozzleDia(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(getLblMm()))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(getLblPrintCenter())
|
||||
.addComponent(getLblX())
|
||||
.addComponent(getTfPrintCenterX(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(getLblY())
|
||||
.addComponent(getTfPrintCenterY(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(getLblMm_1())
|
||||
.addComponent(getLblMm_2()))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(getLblFilamentDiameter())
|
||||
.addComponent(getTfFilaDia(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(getLblMm_3()))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(getLblExtrusionMultiplier())
|
||||
.addComponent(getTfExtrusionMult(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(getLblPrintTemperature())
|
||||
.addComponent(getTfPTemp(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(getLblc()))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(getLblBedTemperature())
|
||||
.addComponent(getTfBTemp(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(getLblc_1()))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(getLblLayerHeight())
|
||||
.addComponent(getTfLayerHeight(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(getLblMm_4()))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(getLblWallThickness())
|
||||
.addComponent(getTfWallThickness(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(getLblMm_5()))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(getLblUseSupportMaterial())
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(getLblRetractLength())
|
||||
.addComponent(getTfRetractLength(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(getLblMm_6()))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(getLblTravelSpeed())
|
||||
.addComponent(getTfTravelSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(getLblMms()))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(getLblPerimeterSpeed())
|
||||
.addComponent(getTfPerimeterSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(getLblMms_1()))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(getLblBridgeSpeed())
|
||||
.addComponent(getTfBridgeSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(getLblMms_2()))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(getLblGapFillSpeed())
|
||||
.addComponent(getTfGapFillSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(getLblMms_3()))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(getLblInfillSpeed())
|
||||
.addComponent(getTfInfillSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(getLblMms_4()))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(getLblSupportMaterialSpeed())
|
||||
.addComponent(getTfSupportMaterialSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(getLblMms_5()))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(getLblSmallPerimeterSpeed())
|
||||
.addComponent(getTfSmallPerimeterSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(getLabel()))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(getLblExternalPerimeterSpeed())
|
||||
.addComponent(getTfExternalPerimeterSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(getLabel_1()))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(getLblSolidInfillSpeed())
|
||||
.addComponent(getTfSolidInfillSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(getLabel_2()))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(getLblTopSolidInfill())
|
||||
.addComponent(getTfTopSolidInfillSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(getLabel_3()))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(getLblSupportMaterialInterface())
|
||||
.addComponent(getTfSupportMaterialInterSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(getLabel_4()))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(getLblFirstLayerSpeed())
|
||||
.addComponent(getTfFirstLayerSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(getLabel_5()))
|
||||
.addContainerGap(25, Short.MAX_VALUE))
|
||||
);
|
||||
setLayout(groupLayout);
|
||||
this.addListener(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public NumberFormat getNumFormat(int numInts, int numDec){
|
||||
NumberFormat x = NumberFormat.getNumberInstance();
|
||||
x.setMaximumFractionDigits(numDec);
|
||||
x.setMinimumFractionDigits(numDec);
|
||||
x.setMaximumIntegerDigits(numInts);
|
||||
x.setMinimumIntegerDigits(numInts);
|
||||
return x;
|
||||
}
|
||||
|
||||
private JLabel getLblNozzleDiameter() {
|
||||
if (lblNozzleDiameter == null) {
|
||||
lblNozzleDiameter = new JLabel("Nozzle Diameter");
|
||||
}
|
||||
return lblNozzleDiameter;
|
||||
}
|
||||
private JLabel getLblPrintCenter() {
|
||||
if (lblPrintCenter == null) {
|
||||
lblPrintCenter = new JLabel("Print Center");
|
||||
}
|
||||
return lblPrintCenter;
|
||||
}
|
||||
private JLabel getLblFilamentDiameter() {
|
||||
if (lblFilamentDiameter == null) {
|
||||
lblFilamentDiameter = new JLabel("Filament Diameter");
|
||||
}
|
||||
return lblFilamentDiameter;
|
||||
}
|
||||
private JLabel getLblExtrusionMultiplier() {
|
||||
if (lblExtrusionMultiplier == null) {
|
||||
lblExtrusionMultiplier = new JLabel("Extrusion Multiplier");
|
||||
}
|
||||
return lblExtrusionMultiplier;
|
||||
}
|
||||
private JLabel getLblPrintTemperature() {
|
||||
if (lblPrintTemperature == null) {
|
||||
lblPrintTemperature = new JLabel("Print Temperature");
|
||||
}
|
||||
return lblPrintTemperature;
|
||||
}
|
||||
private JLabel getLblBedTemperature() {
|
||||
if (lblBedTemperature == null) {
|
||||
lblBedTemperature = new JLabel("Bed Temperature");
|
||||
}
|
||||
return lblBedTemperature;
|
||||
}
|
||||
private JLabel getLblLayerHeight() {
|
||||
if (lblLayerHeight == null) {
|
||||
lblLayerHeight = new JLabel("Layer Height");
|
||||
}
|
||||
return lblLayerHeight;
|
||||
}
|
||||
private JLabel getLblWallThickness() {
|
||||
if (lblWallThickness == null) {
|
||||
lblWallThickness = new JLabel("Wall Thickness");
|
||||
}
|
||||
return lblWallThickness;
|
||||
}
|
||||
private JLabel getLblUseSupportMaterial() {
|
||||
if (lblUseSupportMaterial == null) {
|
||||
lblUseSupportMaterial = new JLabel("Use Support Material");
|
||||
}
|
||||
return lblUseSupportMaterial;
|
||||
}
|
||||
private JLabel getLblRetractLength() {
|
||||
if (lblRetractLength == null) {
|
||||
lblRetractLength = new JLabel("Retract Length");
|
||||
}
|
||||
return lblRetractLength;
|
||||
}
|
||||
private JLabel getLblTravelSpeed() {
|
||||
if (lblTravelSpeed == null) {
|
||||
lblTravelSpeed = new JLabel("Travel Speed");
|
||||
}
|
||||
return lblTravelSpeed;
|
||||
}
|
||||
private JLabel getLblPerimeterSpeed() {
|
||||
if (lblPerimeterSpeed == null) {
|
||||
lblPerimeterSpeed = new JLabel("Perimeter Speed");
|
||||
}
|
||||
return lblPerimeterSpeed;
|
||||
}
|
||||
private JLabel getLblBridgeSpeed() {
|
||||
if (lblBridgeSpeed == null) {
|
||||
lblBridgeSpeed = new JLabel("Bridge Speed");
|
||||
}
|
||||
return lblBridgeSpeed;
|
||||
}
|
||||
private JLabel getLblGapFillSpeed() {
|
||||
if (lblGapFillSpeed == null) {
|
||||
lblGapFillSpeed = new JLabel("Gap Fill Speed");
|
||||
}
|
||||
return lblGapFillSpeed;
|
||||
}
|
||||
private JLabel getLblInfillSpeed() {
|
||||
if (lblInfillSpeed == null) {
|
||||
lblInfillSpeed = new JLabel("Infill Speed");
|
||||
}
|
||||
return lblInfillSpeed;
|
||||
}
|
||||
private JLabel getLblSupportMaterialSpeed() {
|
||||
if (lblSupportMaterialSpeed == null) {
|
||||
lblSupportMaterialSpeed = new JLabel("Support Material Speed");
|
||||
}
|
||||
return lblSupportMaterialSpeed;
|
||||
}
|
||||
private JLabel getLblSmallPerimeterSpeed() {
|
||||
if (lblSmallPerimeterSpeed == null) {
|
||||
lblSmallPerimeterSpeed = new JLabel("Small Perimeter Speed Percent");
|
||||
}
|
||||
return lblSmallPerimeterSpeed;
|
||||
}
|
||||
private JLabel getLblExternalPerimeterSpeed() {
|
||||
if (lblExternalPerimeterSpeed == null) {
|
||||
lblExternalPerimeterSpeed = new JLabel("External Perimeter Speed Percent");
|
||||
}
|
||||
return lblExternalPerimeterSpeed;
|
||||
}
|
||||
private JLabel getLblSolidInfillSpeed() {
|
||||
if (lblSolidInfillSpeed == null) {
|
||||
lblSolidInfillSpeed = new JLabel("Solid Infill Speed Percent");
|
||||
}
|
||||
return lblSolidInfillSpeed;
|
||||
}
|
||||
private JLabel getLblTopSolidInfill() {
|
||||
if (lblTopSolidInfill == null) {
|
||||
lblTopSolidInfill = new JLabel("Top Solid Infill Speed Percent");
|
||||
}
|
||||
return lblTopSolidInfill;
|
||||
}
|
||||
private JLabel getLblSupportMaterialInterface() {
|
||||
if (lblSupportMaterialInterface == null) {
|
||||
lblSupportMaterialInterface = new JLabel("Support Material Interface Speed Percent");
|
||||
}
|
||||
return lblSupportMaterialInterface;
|
||||
}
|
||||
private JLabel getLblFirstLayerSpeed() {
|
||||
if (lblFirstLayerSpeed == null) {
|
||||
lblFirstLayerSpeed = new JLabel("First Layer Speed Percent");
|
||||
}
|
||||
return lblFirstLayerSpeed;
|
||||
}
|
||||
private JLabel getLblX() {
|
||||
if (lblX == null) {
|
||||
lblX = new JLabel("X:");
|
||||
}
|
||||
return lblX;
|
||||
}
|
||||
private JLabel getLblY() {
|
||||
if (lblY == null) {
|
||||
lblY = new JLabel("Y:");
|
||||
}
|
||||
return lblY;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private JFormattedTextField getTfNozzleDia() {
|
||||
if (tfNozzleDia == null) {
|
||||
tfNozzleDia = new JFormattedTextField(getNumFormat(2,3));
|
||||
tfNozzleDia.setColumns(5);
|
||||
}
|
||||
return tfNozzleDia;
|
||||
}
|
||||
|
||||
private JFormattedTextField getTfPrintCenterX() {
|
||||
if (tfPrintCenterX == null) {
|
||||
|
||||
tfPrintCenterX = new JFormattedTextField(getNumFormat(3,0));
|
||||
tfPrintCenterX.setColumns(5);
|
||||
|
||||
}
|
||||
return tfPrintCenterX;
|
||||
}
|
||||
|
||||
private JFormattedTextField getTfPrintCenterY() {
|
||||
if (tfPrintCenterY == null) {
|
||||
|
||||
tfPrintCenterY = new JFormattedTextField(getNumFormat(3,0));
|
||||
tfPrintCenterY.setColumns(5);
|
||||
|
||||
}
|
||||
return tfPrintCenterY;
|
||||
}
|
||||
private JFormattedTextField getTfFilaDia() {
|
||||
if (tfFilaDia == null) {
|
||||
|
||||
tfFilaDia = new JFormattedTextField(getNumFormat(2,2));
|
||||
tfFilaDia.setColumns(5);
|
||||
|
||||
}
|
||||
return tfFilaDia;
|
||||
}
|
||||
private JFormattedTextField getTfExtrusionMult() {
|
||||
if (tfExtrusionMult == null) {
|
||||
|
||||
tfExtrusionMult = new JFormattedTextField(getNumFormat(2,4));
|
||||
tfExtrusionMult.setColumns(5);
|
||||
|
||||
}
|
||||
return tfExtrusionMult;
|
||||
}
|
||||
private JFormattedTextField getTfPTemp() {
|
||||
if (tfPTemp == null) {
|
||||
|
||||
tfPTemp = new JFormattedTextField(getNumFormat(3,0));
|
||||
tfPTemp.setColumns(5);
|
||||
|
||||
}
|
||||
return tfPTemp;
|
||||
}
|
||||
private JFormattedTextField getTfBTemp() {
|
||||
if (tfBTemp == null) {
|
||||
|
||||
tfBTemp = new JFormattedTextField(getNumFormat(3,0));
|
||||
tfBTemp.setColumns(5);
|
||||
|
||||
}
|
||||
return tfBTemp;
|
||||
}
|
||||
private JFormattedTextField getTfLayerHeight() {
|
||||
if (tfLayerHeight == null) {
|
||||
|
||||
tfLayerHeight = new JFormattedTextField(getNumFormat(2,2));
|
||||
tfLayerHeight.setColumns(5);
|
||||
|
||||
}
|
||||
return tfLayerHeight;
|
||||
}
|
||||
private JFormattedTextField getTfWallThickness() {
|
||||
if (tfWallThickness == null) {
|
||||
|
||||
tfWallThickness = new JFormattedTextField(getNumFormat(2,2));
|
||||
tfWallThickness.setColumns(5);
|
||||
|
||||
}
|
||||
return tfWallThickness;
|
||||
}
|
||||
private JFormattedTextField getTfRetractLength() {
|
||||
if (tfRetractLength == null) {
|
||||
|
||||
tfRetractLength = new JFormattedTextField(getNumFormat(3,0));
|
||||
tfRetractLength.setColumns(5);
|
||||
|
||||
}
|
||||
return tfRetractLength;
|
||||
}
|
||||
private JFormattedTextField getTfTravelSpeed() {
|
||||
if (tfTravelSpeed == null) {
|
||||
|
||||
tfTravelSpeed = new JFormattedTextField(getNumFormat(3,0));
|
||||
tfTravelSpeed.setColumns(5);
|
||||
|
||||
}
|
||||
return tfTravelSpeed;
|
||||
}
|
||||
private JFormattedTextField getTfPerimeterSpeed() {
|
||||
if (tfPerimeterSpeed == null) {
|
||||
|
||||
tfPerimeterSpeed = new JFormattedTextField(getNumFormat(3,0));
|
||||
tfPerimeterSpeed.setColumns(5);
|
||||
|
||||
}
|
||||
return tfPerimeterSpeed;
|
||||
}
|
||||
private JFormattedTextField getTfBridgeSpeed() {
|
||||
if (tfBridgeSpeed == null) {
|
||||
|
||||
tfBridgeSpeed = new JFormattedTextField(getNumFormat(3,0));
|
||||
tfBridgeSpeed.setColumns(5);
|
||||
|
||||
}
|
||||
return tfBridgeSpeed;
|
||||
}
|
||||
private JFormattedTextField getTfGapFillSpeed() {
|
||||
if (tfGapFillSpeed == null) {
|
||||
|
||||
tfGapFillSpeed = new JFormattedTextField(getNumFormat(3,0));
|
||||
tfGapFillSpeed.setColumns(5);
|
||||
|
||||
}
|
||||
return tfGapFillSpeed;
|
||||
}
|
||||
private JFormattedTextField getTfInfillSpeed() {
|
||||
if (tfInfillSpeed == null) {
|
||||
|
||||
tfInfillSpeed = new JFormattedTextField(getNumFormat(3,0));
|
||||
tfInfillSpeed.setColumns(5);
|
||||
|
||||
}
|
||||
return tfInfillSpeed;
|
||||
}
|
||||
private JFormattedTextField getTfSupportMaterialSpeed() {
|
||||
if (tfSupportMaterialSpeed == null) {
|
||||
|
||||
tfSupportMaterialSpeed = new JFormattedTextField(getNumFormat(3,0));
|
||||
tfSupportMaterialSpeed.setColumns(5);
|
||||
|
||||
}
|
||||
return tfSupportMaterialSpeed;
|
||||
}
|
||||
private JFormattedTextField getTfSmallPerimeterSpeedPercent() {
|
||||
if (tfSmallPerimeterSpeedPercent == null) {
|
||||
|
||||
tfSmallPerimeterSpeedPercent = new JFormattedTextField(getNumFormat(3,0));
|
||||
tfSmallPerimeterSpeedPercent.setColumns(5);
|
||||
|
||||
}
|
||||
return tfSmallPerimeterSpeedPercent;
|
||||
}
|
||||
private JFormattedTextField getTfExternalPerimeterSpeedPercent() {
|
||||
if (tfExternalPerimeterSpeedPercent == null) {
|
||||
|
||||
tfExternalPerimeterSpeedPercent = new JFormattedTextField(getNumFormat(3,0));
|
||||
tfExternalPerimeterSpeedPercent.setColumns(5);
|
||||
|
||||
}
|
||||
return tfExternalPerimeterSpeedPercent;
|
||||
}
|
||||
private JFormattedTextField getTfSolidInfillSpeedPercent() {
|
||||
if (tfSolidInfillSpeedPercent == null) {
|
||||
|
||||
tfSolidInfillSpeedPercent = new JFormattedTextField(getNumFormat(3,0));
|
||||
tfSolidInfillSpeedPercent.setColumns(5);
|
||||
|
||||
}
|
||||
return tfSolidInfillSpeedPercent;
|
||||
}
|
||||
private JFormattedTextField getTfTopSolidInfillSpeedPercent() {
|
||||
if (tfTopSolidInfillSpeedPercent == null) {
|
||||
|
||||
tfTopSolidInfillSpeedPercent = new JFormattedTextField(getNumFormat(3,0));
|
||||
tfTopSolidInfillSpeedPercent.setColumns(5);
|
||||
|
||||
}
|
||||
return tfTopSolidInfillSpeedPercent;
|
||||
}
|
||||
private JFormattedTextField getTfSupportMaterialInterSpeedPercent() {
|
||||
if (tfSupportMaterialInterSpeedPercent == null) {
|
||||
|
||||
tfSupportMaterialInterSpeedPercent = new JFormattedTextField(getNumFormat(3,0));
|
||||
tfSupportMaterialInterSpeedPercent.setColumns(5);
|
||||
|
||||
}
|
||||
return tfSupportMaterialInterSpeedPercent;
|
||||
}
|
||||
private JFormattedTextField getTfFirstLayerSpeedPercent() {
|
||||
if (tfFirstLayerSpeedPercent == null) {
|
||||
|
||||
tfFirstLayerSpeedPercent = new JFormattedTextField(getNumFormat(3,0));
|
||||
tfFirstLayerSpeedPercent.setColumns(5);
|
||||
|
||||
}
|
||||
return tfFirstLayerSpeedPercent;
|
||||
}
|
||||
private JLabel getLblMm() {
|
||||
if (lblMm == null) {
|
||||
lblMm = new JLabel("mm");
|
||||
}
|
||||
return lblMm;
|
||||
}
|
||||
private JLabel getLblMm_1() {
|
||||
if (lblMm_1 == null) {
|
||||
lblMm_1 = new JLabel("mm");
|
||||
}
|
||||
return lblMm_1;
|
||||
}
|
||||
private JLabel getLblMm_2() {
|
||||
if (lblMm_2 == null) {
|
||||
lblMm_2 = new JLabel("mm");
|
||||
}
|
||||
return lblMm_2;
|
||||
}
|
||||
private JLabel getLblMm_3() {
|
||||
if (lblMm_3 == null) {
|
||||
lblMm_3 = new JLabel("mm");
|
||||
}
|
||||
return lblMm_3;
|
||||
}
|
||||
private JLabel getLblc() {
|
||||
if (lblc == null) {
|
||||
lblc = new JLabel("\u00B0C");
|
||||
}
|
||||
return lblc;
|
||||
}
|
||||
private JLabel getLblc_1() {
|
||||
if (lblc_1 == null) {
|
||||
lblc_1 = new JLabel("\u00B0C");
|
||||
}
|
||||
return lblc_1;
|
||||
}
|
||||
private JLabel getLblMm_4() {
|
||||
if (lblMm_4 == null) {
|
||||
lblMm_4 = new JLabel("mm");
|
||||
}
|
||||
return lblMm_4;
|
||||
}
|
||||
private JLabel getLblMm_5() {
|
||||
if (lblMm_5 == null) {
|
||||
lblMm_5 = new JLabel("mm");
|
||||
}
|
||||
return lblMm_5;
|
||||
}
|
||||
private JLabel getLblMm_6() {
|
||||
if (lblMm_6 == null) {
|
||||
lblMm_6 = new JLabel("mm");
|
||||
}
|
||||
return lblMm_6;
|
||||
}
|
||||
private JLabel getLblMms() {
|
||||
if (lblMms == null) {
|
||||
lblMms = new JLabel("mm/s");
|
||||
}
|
||||
return lblMms;
|
||||
}
|
||||
private JLabel getLblMms_1() {
|
||||
if (lblMms_1 == null) {
|
||||
lblMms_1 = new JLabel("mm/s");
|
||||
}
|
||||
return lblMms_1;
|
||||
}
|
||||
private JLabel getLblMms_2() {
|
||||
if (lblMms_2 == null) {
|
||||
lblMms_2 = new JLabel("mm/s");
|
||||
}
|
||||
return lblMms_2;
|
||||
}
|
||||
private JLabel getLblMms_3() {
|
||||
if (lblMms_3 == null) {
|
||||
lblMms_3 = new JLabel("mm/s");
|
||||
}
|
||||
return lblMms_3;
|
||||
}
|
||||
private JLabel getLblMms_4() {
|
||||
if (lblMms_4 == null) {
|
||||
lblMms_4 = new JLabel("mm/s");
|
||||
}
|
||||
return lblMms_4;
|
||||
}
|
||||
private JLabel getLblMms_5() {
|
||||
if (lblMms_5 == null) {
|
||||
lblMms_5 = new JLabel("mm/s");
|
||||
}
|
||||
return lblMms_5;
|
||||
}
|
||||
private JLabel getLabel() {
|
||||
if (label == null) {
|
||||
label = new JLabel("%");
|
||||
}
|
||||
return label;
|
||||
}
|
||||
private JLabel getLabel_1() {
|
||||
if (label_1 == null) {
|
||||
label_1 = new JLabel("%");
|
||||
}
|
||||
return label_1;
|
||||
}
|
||||
private JLabel getLabel_2() {
|
||||
if (label_2 == null) {
|
||||
label_2 = new JLabel("%");
|
||||
}
|
||||
return label_2;
|
||||
}
|
||||
private JLabel getLabel_3() {
|
||||
if (label_3 == null) {
|
||||
label_3 = new JLabel("%");
|
||||
}
|
||||
return label_3;
|
||||
}
|
||||
private JLabel getLabel_4() {
|
||||
if (label_4 == null) {
|
||||
label_4 = new JLabel("%");
|
||||
}
|
||||
return label_4;
|
||||
}
|
||||
private JLabel getLabel_5() {
|
||||
if (label_5 == null) {
|
||||
label_5 = new JLabel("%");
|
||||
}
|
||||
return label_5;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void settingsRequest() {
|
||||
|
||||
master.setValue(0, new MachineSetting<Double>("NozzleDia" ,(Double) tfNozzleDia.getValue()));
|
||||
master.setValue(1, new MachineSetting<Double>("PCenterX" ,(Double) tfPrintCenterX.getValue()));
|
||||
master.setValue(2, new MachineSetting<Double>("PCenterY" ,(Double) tfPrintCenterY.getValue()));
|
||||
master.setValue(3, new MachineSetting<Double>("FilaDia" ,(Double) tfFilaDia.getValue()));
|
||||
master.setValue(4, new MachineSetting<Double>("ExtMult" ,(Double) tfExtrusionMult.getValue()));
|
||||
master.setValue(5, new MachineSetting<Integer>("PTemp" ,(Integer) tfPTemp.getValue()));
|
||||
master.setValue(6, new MachineSetting<Integer>("BTemp" ,(Integer) tfBTemp.getValue()));
|
||||
master.setValue(7, new MachineSetting<Double>("LayerHeight" ,(Double) tfLayerHeight.getValue()));
|
||||
master.setValue(8, new MachineSetting<Integer>("WallThickness" ,(Integer) tfWallThickness.getValue()));
|
||||
//master.setValue(9, new MachineSetting<Boolean>("UseSupport" ,(Boolean) tfRetractLength.getValue()));
|
||||
master.setValue(10, new MachineSetting<Double>("RetractLength" ,(Double) tfRetractLength.getValue()));
|
||||
master.setValue(11, new MachineSetting<Integer>("TravelSpd" ,(Integer) tfTravelSpeed.getValue()));
|
||||
master.setValue(12, new MachineSetting<Integer>("PeriSpd" ,(Integer) tfPerimeterSpeed.getValue()));
|
||||
master.setValue(13, new MachineSetting<Integer>("BridgeSpd" ,(Integer) tfBridgeSpeed.getValue()));
|
||||
master.setValue(14, new MachineSetting<Integer>("GapFillSpd" ,(Integer) tfGapFillSpeed.getValue()));
|
||||
master.setValue(15, new MachineSetting<Integer>("InfillSpd" ,(Integer) tfInfillSpeed.getValue()));
|
||||
master.setValue(16, new MachineSetting<Integer>("SupportMatSpd" ,(Integer) tfSupportMaterialSpeed.getValue()));
|
||||
master.setValue(17, new MachineSetting<Integer>("SmPeriSpdPcnt" ,(Integer) tfSmallPerimeterSpeedPercent.getValue()));
|
||||
master.setValue(18, new MachineSetting<Integer>("ExtPeriSpdPcnt" ,(Integer) tfExternalPerimeterSpeedPercent.getValue()));
|
||||
master.setValue(19, new MachineSetting<Integer>("SolidInfillSpdPcnt" ,(Integer) tfSolidInfillSpeedPercent.getValue()));
|
||||
master.setValue(20, new MachineSetting<Integer>("TopSolidInfillSpdPcnt" ,(Integer) tfTopSolidInfillSpeedPercent.getValue()));
|
||||
master.setValue(21, new MachineSetting<Integer>("SupportMatIntSpdPcnt" ,(Integer) tfSupportMaterialInterSpeedPercent.getValue()));
|
||||
master.setValue(22, new MachineSetting<Integer>("FirstLayerSpdPcnt" ,(Integer) tfFirstLayerSpeedPercent.getValue()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
package com.neuronrobotics.nrconsole.plugin.DeviceConfig;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.ButtonGroup;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JRadioButton;
|
||||
import javax.swing.JScrollPane;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import com.neuronrobotics.nrconsole.util.PrefsLoader;
|
||||
|
||||
public class Slic3rMasterPanel extends SettingsPanel {
|
||||
private JScrollPane scrollPane;
|
||||
private JPanel panel;
|
||||
private JRadioButton rdbtnShowAllSettings;
|
||||
private JPanel panel_1;
|
||||
PrefsLoader prefs = new PrefsLoader();
|
||||
private Slic3rAll pnlAll = new Slic3rAll(this);
|
||||
private Slic3rPrinter pnlPrinter = new Slic3rPrinter(this);
|
||||
private Slic3rPrints pnlPrints = new Slic3rPrints(this);
|
||||
private JRadioButton rdbtnShowOnlyPrinter;
|
||||
private JRadioButton rdbtnShowOnlyPrint;
|
||||
private final ButtonGroup buttonGroup = new ButtonGroup();
|
||||
|
||||
/**
|
||||
* Create the panel.
|
||||
*/
|
||||
public Slic3rMasterPanel() {
|
||||
|
||||
initComponents();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private SettingsPanel whichPanel(){
|
||||
if (rdbtnShowAllSettings.isSelected()){
|
||||
removeListeners();
|
||||
addListener(pnlAll);
|
||||
notifySettingsChanged();
|
||||
return pnlAll;
|
||||
}
|
||||
else if (rdbtnShowOnlyPrinter.isSelected()){
|
||||
removeListeners();
|
||||
addListener(pnlPrinter);
|
||||
notifySettingsChanged();
|
||||
return pnlPrinter;
|
||||
}
|
||||
else if(rdbtnShowOnlyPrint.isSelected()){
|
||||
removeListeners();
|
||||
addListener(pnlPrints);
|
||||
notifySettingsChanged();
|
||||
return pnlPrints;
|
||||
}
|
||||
removeListeners();
|
||||
addListener(pnlAll);
|
||||
notifySettingsChanged();
|
||||
return pnlAll;
|
||||
|
||||
|
||||
}
|
||||
private void changePanels(){
|
||||
scrollPane.setViewportView(whichPanel());
|
||||
}
|
||||
|
||||
|
||||
private JScrollPane getScrollPane() {
|
||||
if (scrollPane == null) {
|
||||
scrollPane = new JScrollPane();
|
||||
scrollPane.setColumnHeaderView(getPanel());
|
||||
|
||||
}
|
||||
return scrollPane;
|
||||
}
|
||||
private JPanel getPanel() {
|
||||
if (panel == null) {
|
||||
panel = new JPanel();
|
||||
panel.add(getRdbtnShowOnlyPrinter());
|
||||
panel.add(getRdbtnShowOnlyPrint());
|
||||
panel.add(getRdbtnShowAllSettings());
|
||||
}
|
||||
return panel;
|
||||
}
|
||||
private JRadioButton getRdbtnShowAllSettings() {
|
||||
if (rdbtnShowAllSettings == null) {
|
||||
rdbtnShowAllSettings = new JRadioButton("Show All Settings");
|
||||
rdbtnShowAllSettings.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (rdbtnShowAllSettings.isSelected()){
|
||||
prefs.setSlic3rRDBTNLast(0);
|
||||
}
|
||||
changePanels();
|
||||
}
|
||||
});
|
||||
|
||||
buttonGroup.add(rdbtnShowAllSettings);
|
||||
}
|
||||
return rdbtnShowAllSettings;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getPanelName() {
|
||||
|
||||
return "Slic3r Settings";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initComponents() {
|
||||
setLayout(new MigLayout("", "[grow]", "[grow]"));
|
||||
add(getScrollPane(), "cell 0 0,grow");
|
||||
switch (prefs.getSlic3rRDBTNLast()) {
|
||||
case 0:
|
||||
getRdbtnShowAllSettings().setSelected(true);
|
||||
break;
|
||||
case 1:
|
||||
getRdbtnShowOnlyPrinter().setSelected(true);
|
||||
break;
|
||||
case 2:
|
||||
getRdbtnShowOnlyPrint().setSelected(true);
|
||||
break;
|
||||
default:
|
||||
getRdbtnShowAllSettings().setSelected(true);
|
||||
break;
|
||||
}
|
||||
changePanels();
|
||||
|
||||
}
|
||||
private JRadioButton getRdbtnShowOnlyPrinter() {
|
||||
if (rdbtnShowOnlyPrinter == null) {
|
||||
rdbtnShowOnlyPrinter = new JRadioButton("Show Only Printer Settings");
|
||||
rdbtnShowOnlyPrinter.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
if (rdbtnShowOnlyPrinter.isSelected()){
|
||||
prefs.setSlic3rRDBTNLast(1);
|
||||
}
|
||||
changePanels();
|
||||
}
|
||||
});
|
||||
|
||||
buttonGroup.add(rdbtnShowOnlyPrinter);
|
||||
|
||||
}
|
||||
return rdbtnShowOnlyPrinter;
|
||||
}
|
||||
|
||||
private JRadioButton getRdbtnShowOnlyPrint() {
|
||||
if (rdbtnShowOnlyPrint == null) {
|
||||
rdbtnShowOnlyPrint = new JRadioButton("Show Only Print Job Settings");
|
||||
rdbtnShowOnlyPrint.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (rdbtnShowOnlyPrint.isSelected()){
|
||||
prefs.setSlic3rRDBTNLast(2);
|
||||
}
|
||||
changePanels();
|
||||
}
|
||||
});
|
||||
|
||||
buttonGroup.add(rdbtnShowOnlyPrint);
|
||||
}
|
||||
return rdbtnShowOnlyPrint;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user