diff --git a/.gitignore b/.gitignore
index 6ba8608..1431ddf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,5 @@
/.settings/
/bin/
/target/
-/*.iml
\ No newline at end of file
+/*.iml
+.pmd
\ No newline at end of file
diff --git a/.project b/.project
index c429fdf..470e4bd 100644
--- a/.project
+++ b/.project
@@ -20,10 +20,16 @@
+
+ net.sourceforge.pmd.eclipse.plugin.pmdBuilder
+
+
+ org.eclipse.m2e.core.maven2Natureorg.eclipse.jdt.core.javanaturenet.sf.eclipsecs.core.CheckstyleNature
+ net.sourceforge.pmd.eclipse.plugin.pmdNature
diff --git a/.ruleset b/.ruleset
new file mode 100644
index 0000000..5f7408a
--- /dev/null
+++ b/.ruleset
@@ -0,0 +1,354 @@
+
+
+ PMD Plugin preferences rule set
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index e66b197..81ee086 100644
--- a/README.md
+++ b/README.md
@@ -19,3 +19,6 @@ The software is made for the Windows operating system and might not work as inte
###IDE
This software can be developed with both Eclipse and IntelliJ, though they require a different process to set up.
+
+###Note about preset creation/editing
+For now, VLC is required to make the connection to the camera or to the mocked live feed. It is important to have the same VLC version as your java version, e.g. 32bit java requires 32bit VLC, and 64bit java requires 64bit VLC. Also, other systems than Windows are untested and might not work with the current implementation.
\ No newline at end of file
diff --git a/doc/Architecture Design.pdf b/doc/Architecture Design.pdf
index 429d1ac..9606843 100644
Binary files a/doc/Architecture Design.pdf and b/doc/Architecture Design.pdf differ
diff --git a/doc/Sprint plans/Sprintplan7.pdf b/doc/Sprint plans/Sprintplan7.pdf
new file mode 100644
index 0000000..ff423b8
Binary files /dev/null and b/doc/Sprint plans/Sprintplan7.pdf differ
diff --git a/doc/Sprint retrospectives/Sprint retrospective 6.pdf b/doc/Sprint retrospectives/Sprint retrospective 6.pdf
new file mode 100644
index 0000000..4e8a684
Binary files /dev/null and b/doc/Sprint retrospectives/Sprint retrospective 6.pdf differ
diff --git a/pmd.xml b/pmd.xml
new file mode 100644
index 0000000..518a955
--- /dev/null
+++ b/pmd.xml
@@ -0,0 +1,39 @@
+
+
+
+
+ Custom rules for PMD.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 8da962a..dccc96e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
nl.tudelftContext-TFP
- 0.5
+ 0.6Team Free PizzaTU Delft Contextproject Multi-Media 2016 from Team Free Pizza
@@ -77,6 +77,18 @@
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+ true
+ true
+
+
+
+
@@ -92,6 +104,26 @@
mockito-core2.0.53-beta
+
+ uk.co.caprica
+ vlcj
+ 3.10.1
+
+
+ net.java.dev.jna
+ jna-platform
+ 4.2.2
+
+
+ org.slf4j
+ slf4j-api
+ 1.7.21
+
+
+ net.java.dev.jna
+ jna
+ 4.2.2
+
diff --git a/src/main/java/nl/tudelft/contextproject/ContextTFP.java b/src/main/java/nl/tudelft/contextproject/ContextTFP.java
index a5dc2a7..6601f3f 100644
--- a/src/main/java/nl/tudelft/contextproject/ContextTFP.java
+++ b/src/main/java/nl/tudelft/contextproject/ContextTFP.java
@@ -9,13 +9,15 @@
package nl.tudelft.contextproject;
import javafx.application.Application;
+import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
-
import nl.tudelft.contextproject.camera.Camera;
import nl.tudelft.contextproject.camera.CameraSettings;
+import nl.tudelft.contextproject.camera.LiveCameraConnection;
+import nl.tudelft.contextproject.camera.MockedCameraConnection;
import nl.tudelft.contextproject.gui.MenuController;
import nl.tudelft.contextproject.presets.InstantPreset;
import nl.tudelft.contextproject.script.Script;
@@ -45,9 +47,11 @@ public class ContextTFP extends Application {
private Stage primaryStage;
@Override
- public void start(Stage primaryStage) throws Exception {
- this.primaryStage = primaryStage;
- this.primaryStage.setTitle("TFP Camera Control");
+ public void start(Stage pStage) throws Exception {
+ primaryStage = pStage;
+ primaryStage.setTitle("TFP Camera Control");
+ primaryStage.minWidthProperty().set(800);
+ primaryStage.minHeightProperty().set(575);
// Create the script to be used by the application.
script = new Script(new ArrayList());
@@ -60,6 +64,17 @@ public void start(Stage primaryStage) throws Exception {
Camera e = new Camera();
Camera f = new Camera();
+ LiveCameraConnection live = new LiveCameraConnection("192.168.0.13");
+ live.setUpConnection();
+ a.setConnection(live);
+
+ MockedCameraConnection mocked = new MockedCameraConnection();
+ b.setConnection(mocked);
+
+ MockedCameraConnection mocked2 = new MockedCameraConnection();
+ mocked2.setStreamLink("http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8");
+ c.setConnection(mocked2);
+
List list = new ArrayList();
list.addAll(Arrays.asList(a, b, c, d, e, f));
@@ -69,14 +84,13 @@ public void start(Stage primaryStage) throws Exception {
cam.addPreset(new InstantPreset(new CameraSettings(), 2, "awesome"));
cam.addPreset(new InstantPreset(new CameraSettings(), 3, "wuq"));
}
- //
initRootLayout();
MenuController.show();
}
/**
- * Initializes the root layout of the application.
+ * Initialises the root layout of the application.
*/
public void initRootLayout() {
try {
@@ -87,6 +101,10 @@ public void initRootLayout() {
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
+ primaryStage.setOnCloseRequest(e -> {
+ Platform.exit();
+ System.exit(0);
+ });
} catch (IOException e) {
e.printStackTrace();
}
diff --git a/src/main/java/nl/tudelft/contextproject/camera/Camera.java b/src/main/java/nl/tudelft/contextproject/camera/Camera.java
index f555b38..695d0a1 100644
--- a/src/main/java/nl/tudelft/contextproject/camera/Camera.java
+++ b/src/main/java/nl/tudelft/contextproject/camera/Camera.java
@@ -8,31 +8,34 @@
import java.util.Observable;
/**
- * Class to represent a camera.
- * Extends Observables so its settings can be observed.
+ * This class represents a camera. Every camera has its
+ * own {@link CameraSettings}. This class extends {@link Observable}
+ * so its settings can be observed.
+ *
* @since 0.2
*/
public class Camera extends Observable {
-
+
private static final HashMap CAMERAS = new HashMap();
private static int numCams = 0;
-
- private int num;
+
+ private CameraConnection connection;
private CameraSettings camSet;
private HashMap presets;
- private CameraConnection connection;
-
+
+ private int camId;
+
/**
* Creates a Camera object with initial camera settings
* set to the lower limits of the camera.
*/
public Camera() {
camSet = new CameraSettings();
- num = numCams++;
+ camId = numCams++;
presets = new HashMap();
- CAMERAS.put(num, this);
+ CAMERAS.put(camId, this);
}
-
+
/**
* Creates a Camera object with initial camera settings
* as specified in the CameraSettings object.
@@ -41,97 +44,105 @@ public Camera() {
*/
public Camera(CameraSettings init) {
camSet = init;
- num = numCams++;
+ camId = numCams++;
presets = new HashMap();
- CAMERAS.put(num, this);
+ CAMERAS.put(camId, this);
}
-
+
/**
* Returns the camera with a specific number, or null if it
- * does not yet exist.
- * @param camNum number of the camera to get
- * @return the camera with the associated number, or null if
+ * does not exist (yet).
+ *
+ * @param camNum The number of the camera to get.
+ * @return The camera with the associated number, or null if
* it does not exist.
*/
public static Camera getCamera(int camNum) {
return CAMERAS.get(camNum);
}
-
+
/**
- * Returns all cameras currently made.
- * @return a collection of all cameras currently specified.
+ * Returns all cameras that have been made.
+ * @return A collection of all cameras currently specified.
*/
public static Collection getAllCameras() {
return CAMERAS.values();
}
-
+
+ /**
+ * Clears all cameras and resets the numCams to 0.
+ */
public static void clearAllCameras() {
CAMERAS.clear();
numCams = 0;
}
-
+
/**
* Gets the camera number assigned to the camera.
* @return Camera number assigned to camera.
*/
public int getNumber() {
- return num;
+ return camId;
}
-
+
/**
- * Returns the camera settings.
- * @return Camera settings
+ * Returns the camera settings attached to the camera.
+ * @return Camera settings.
*/
public CameraSettings getSettings() {
return camSet;
}
-
+
/**
- * Sets the settings for this camera.
- * Updates the observers.
- *
+ * Sets the settings for this camera and updates the observers.
* @param settings Camera settings to set.
*/
public void setSettings(CameraSettings settings) {
- camSet = settings;
- setChanged();
- notifyObservers(settings);
+ if (hasConnection() && connection.isConnected()) {
+ camSet = settings;
+ setChanged();
+ notifyObservers(settings);
+ }
}
-
+
/**
* Returns true iff the camera has a non-null CameraConnection
* object.
- * @return true iff the camera has a non-null CameraConnection
+ *
+ * @return True iff the camera has a non-null CameraConnection.
*/
public boolean hasConnection() {
return connection != null;
}
-
+
/**
* Returns the CameraConnection object used for communicating with
* the actual camera. May be null if it has not yet been initialized.
- * @return the CameraConnection object used for communicating with
+ *
+ * @return The CameraConnection object used for communicating with
* the actual camera.
*/
public CameraConnection getConnection() {
return connection;
}
-
+
/**
* Sets the CameraConnection object used for communicating with
* the actual camera. It adds this new connection as an observer
* and if there was a previous connection, removes the previous
* connection as observer.
- * @param connect the new connection to the camera.
+ *
+ * @param connect The new connection to the camera.
*/
public void setConnection(CameraConnection connect) {
if (hasConnection()) {
this.deleteObserver(connection);
}
+
connection = connect;
this.addObserver(connect);
}
-
+
/**
* Get the total amount of cameras connected to the system.
* @return The number of cameras.
@@ -139,7 +150,7 @@ public void setConnection(CameraConnection connect) {
public static int getCameraAmount() {
return numCams;
}
-
+
/**
* Pans the camera a certain offset. Cannot pan past
* the pan limits.
@@ -148,13 +159,15 @@ public static int getCameraAmount() {
*/
public void pan(int offset) {
camSet.pan(offset);
+
if (hasConnection()) {
connection.relPan(offset);
}
+
setChanged();
notifyObservers();
}
-
+
/**
* Tilts the camera a certain offset. Cannot tilt past
* the tilt limits.
@@ -163,13 +176,15 @@ public void pan(int offset) {
*/
public void tilt(int offset) {
camSet.tilt(offset);
+
if (hasConnection()) {
connection.relTilt(offset);
}
+
setChanged();
notifyObservers();
}
-
+
/**
* Zooms the camera a certain offset. Cannot zoom past
* the zoom limits.
@@ -178,9 +193,11 @@ public void tilt(int offset) {
*/
public void zoom(int offset) {
camSet.zoom(offset);
+
if (hasConnection()) {
connection.relZoom(offset);
}
+
setChanged();
notifyObservers();
}
@@ -193,67 +210,81 @@ public void zoom(int offset) {
*/
public void focus(int offset) {
camSet.focus(offset);
+
if (hasConnection()) {
connection.relFocus(offset);
}
+
setChanged();
notifyObservers();
}
/**
* Pans and Tilts the camera to a certain pan and tilt value.
- * It cannot past the pan or tilt limit
- * @param panValue the value to pan the Camera.
- * @param tiltValue the value to tilt the Camera.
+ * It cannot go past the pan or tilt limit.
+ *
+ * @param panValue The value to pan the Camera.
+ * @param tiltValue The value to tilt the Camera.
*/
public void absPanTilt(int panValue, int tiltValue) {
camSet.setPan(panValue);
camSet.setTilt(tiltValue);
+
if (hasConnection()) {
connection.absPanTilt(panValue, tiltValue);
}
+
setChanged();
notifyObservers();
}
/**
- * Pans the camera to a certain value. Value cannot
+ * Pans the camera to a certain value. Value cannot go
* past the pan limits.
+ *
* @param value The new value to pan the Camera.
*/
public void absPan(int value) {
camSet.setPan(value);
+
if (hasConnection()) {
connection.absPan(value);
}
+
setChanged();
notifyObservers();
}
/**
- * Tilts the camera to a certain value. Value cannot
+ * Tilts the camera to a certain value. Value cannot go
* past the tilt limits.
+ *
* @param value The new value to tilt the Camera.
*/
public void absTilt(int value) {
camSet.setTilt(value);
+
if (hasConnection()) {
connection.absTilt(value);
}
+
setChanged();
notifyObservers();
}
/**
- * Zooms the camera to a certain value. Value cannot
+ * Zooms the camera to a certain value. Value cannot go
* past the zoom limits.
+ *
* @param value The new value to zoom the Camera.
*/
public void absZoom(int value) {
camSet.setZoom(value);
+
if (hasConnection()) {
connection.absZoom(value);
}
+
setChanged();
notifyObservers();
}
@@ -261,20 +292,24 @@ public void absZoom(int value) {
/**
* Focuses the camera to a certain value. Value cannot
* past the focus limits.
+ *
* @param value The new value to focus the Camera.
*/
public void absFocus(int value) {
camSet.setFocus(value);
+
if (hasConnection()) {
connection.absFocus(value);
}
+
setChanged();
notifyObservers();
}
-
+
/**
* Adds a preset to the camera, if there is not already
* a preset with the same id. Returns true if successful.
+ *
* @param p The preset to add to this camera.
* @return True if the preset was added, otherwise false.
*/
@@ -282,11 +317,13 @@ public boolean addPreset(Preset p) {
if (presets.get(p.getId()) == null) {
presets.put(p.getId(), p);
notifyObservers();
+
return true;
}
+
return false;
}
-
+
/**
* Adds a preset, overwriting if it already exists.
* @param p The preset to add.
@@ -295,7 +332,7 @@ public void overwritePreset(Preset p) {
presets.put(p.getId(), p);
notifyObservers();
}
-
+
/**
* Removes a preset from the camera.
* @param p The preset to remove.
@@ -303,17 +340,18 @@ public void overwritePreset(Preset p) {
public void removePreset(Preset p) {
presets.remove(p.getId());
}
-
+
/**
* Returns the preset with the specified id.
* Returns null if the preset doesn't exist.
+ *
* @param id The id of the preset to get.
* @return The requested preset.
*/
public Preset getPreset(int id) {
return presets.get(id);
}
-
+
/**
* Returns a hashmap with all the presets of this camera.
* @return A hashmap with all the presets of this camera.
@@ -321,7 +359,7 @@ public Preset getPreset(int id) {
public HashMap getPresets() {
return presets;
}
-
+
/**
* Returns the amount of presets currently registered to this camera.
* @return Amount of presets.
@@ -331,32 +369,33 @@ public int getPresetAmount() {
}
@Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (!(o instanceof Camera)) {
- return false;
+ public boolean equals(Object obj) {
+ if (obj instanceof Camera) {
+ Camera camera = (Camera) obj;
+
+ return camId == camera.camId
+ && Objects.equals(camSet, camera.camSet)
+ && Objects.equals(presets, camera.presets);
}
- Camera camera = (Camera) o;
- boolean result = num == camera.num
- && Objects.equals(camSet, camera.camSet)
- && Objects.equals(presets, camera.presets);
- return result;
+
+ return false;
}
@Override
public int hashCode() {
- return Objects.hash(num, camSet, presets);
+ return Objects.hash(camId, camSet, presets);
}
/**
-
* Returns the list of presets currently registered to this camera.
- * @return the list of presets registered to this camera.
+ * @return The list of presets registered to this camera.
*/
public Collection getAllPresets() {
return presets.values();
}
+ @Override
+ public String toString() {
+ return "Camera: " + camId;
+ }
}
diff --git a/src/main/java/nl/tudelft/contextproject/camera/CameraConnection.java b/src/main/java/nl/tudelft/contextproject/camera/CameraConnection.java
index bce2191..d0646cc 100644
--- a/src/main/java/nl/tudelft/contextproject/camera/CameraConnection.java
+++ b/src/main/java/nl/tudelft/contextproject/camera/CameraConnection.java
@@ -3,130 +3,143 @@
import java.util.Observer;
/**
- * Abstract class to represent a connection with a camera. A class
+ * Abstract class to represent a connection with a {@link Camera}. A class
* that extends this class should observe a Camera-object and send
* its operations to the actual camera.
*
* @since 0.4
*/
public abstract class CameraConnection implements Observer {
-
+
/**
* Sets up the connection to the camera.
- * @return true iff the connection was set up successfully.
+ * @return True iff the connection was set up successfully.
*/
public abstract boolean setUpConnection();
-
+
/**
* Returns true iff there is an active connection to the camera.
- * @return true iff the camera is connected.
+ * @return True iff the camera is connected.
*/
public abstract boolean isConnected();
-
+
/**
* Returns the link to a live feed from the camera.
- * @return the link to a live feed from the camera.
+ * @return The link to a live feed from the camera.
*/
public abstract String getStreamLink();
-
+
/**
* Returns the current camera settings of the camera as a
* CameraSettings object.
- * @return the current camera settings of the camera.
+ *
+ * @return The current camera settings of the camera.
*/
public abstract CameraSettings getCurrentCameraSettings();
-
+
/**
* Returns the current pan and tilt values of the camera in
* the form of an array.
- * @return an array with the pan and tilt values. [0] holds
+ *
+ * @return An array with the pan and tilt values. [0] holds
* the pan value, [1] holds the tilt value.
*/
public abstract int[] getCurrentPanTilt();
-
+
/**
* Returns the current zoom value of the camera.
- * @return the current zoom value of the camera.
+ * @return The current zoom value of the camera.
*/
public abstract int getCurrentZoom();
-
+
/**
* Returns the current focus value of the camera.
* In the case of a LiveCameraConnection, this method may
* return -1 when auto focus is on.
- * @return the current focus value of the camera.
+ *
+ * @return The current focus value of the camera.
*/
public abstract int getCurrentFocus();
-
+
/**
* Pans and tilts to an absolute position.
- * @param panValue the absolute pan value to pan to.
- * @param tiltValue the absolute tilt value to tilt to.
- * @return true iff the operation was performed successfully.
+ *
+ * @param panValue The absolute pan value to pan to.
+ * @param tiltValue The absolute tilt value to tilt to.
+ * @return True iff the operation was performed successfully.
*/
protected abstract boolean absPanTilt(int panValue, int tiltValue);
-
+
/**
* Pans to an absolute position.
- * @param value the absolute value to pan to.
- * @return true iff the operation was performed successfully.
+ *
+ * @param value The absolute value to pan to.
+ * @return True iff the operation was performed successfully.
*/
protected abstract boolean absPan(int value);
-
+
/**
* Tilts to an absolute position.
- * @param value the absolute value to tilt to.
- * @return true iff the operation was performed successfully.
+ *
+ * @param value The absolute value to tilt to.
+ * @return True iff the operation was performed successfully.
*/
protected abstract boolean absTilt(int value);
-
+
/**
* Sets the zoom level to an absolute position.
- * @param value the absolute value to zoom to.
- * @return true iff the operation was performed successfully.
+ *
+ * @param value The absolute value to zoom to.
+ * @return True iff the operation was performed successfully.
*/
protected abstract boolean absZoom(int value);
-
+
/**
* Sets the focus to an absolute position.
- * @param value the absolute value to focus to.
- * @return true iff the operation was performed successfully.
+ *
+ * @param value The absolute value to focus to.
+ * @return True iff the operation was performed successfully.
*/
protected abstract boolean absFocus(int value);
-
+
/**
* Pans and tilts the camera a certain offset.
- * @param panOffset offset to pan.
- * @param tiltOffset offset to tilt.
- * @return true iff the operation was performed successfully.
+ *
+ * @param panOffset Relative offset to pan.
+ * @param tiltOffset Relative offset to tilt.
+ * @return True iff the operation was performed successfully.
*/
protected abstract boolean relPanTilt(int panOffset, int tiltOffset);
-
+
/**
* Pans the camera a certain offset.
- * @param offset offset to pan.
- * @return true iff the operation was performed successfully.
+ *
+ * @param offset Relative offset to pan.
+ * @return True iff the operation was performed successfully.
*/
protected abstract boolean relPan(int offset);
-
+
/**
* Tilts the camera a certain offset.
- * @param offset offset to tilt.
- * @return true iff the operation was performed successfully.
+ *
+ * @param offset Relative offset to tilt.
+ * @return True iff the operation was performed successfully.
*/
protected abstract boolean relTilt(int offset);
-
+
/**
* Zooms the camera a certain offset.
- * @param offset offset to zoom.
- * @return true iff the operation was performed successfully.
+ *
+ * @param offset Relative offset to zoom.
+ * @return True iff the operation was performed successfully.
*/
protected abstract boolean relZoom(int offset);
-
+
/**
* Changes the focus of the camera a certain offset.
- * @param offset offset to change the focus.
- * @return true iff the operation was performed successfully.
+ *
+ * @param offset Relative offset to change the focus.
+ * @return True iff the operation was performed successfully.
*/
protected abstract boolean relFocus(int offset);
}
diff --git a/src/main/java/nl/tudelft/contextproject/camera/CameraSettings.java b/src/main/java/nl/tudelft/contextproject/camera/CameraSettings.java
index 3798279..b3f2929 100644
--- a/src/main/java/nl/tudelft/contextproject/camera/CameraSettings.java
+++ b/src/main/java/nl/tudelft/contextproject/camera/CameraSettings.java
@@ -1,20 +1,21 @@
package nl.tudelft.contextproject.camera;
/**
- * Class to represent camera settings. Can be extended with colour
+ * Class to represent camera settings. Can be extended with color
* settings etc.
+ *
* @since 0.2
*/
public class CameraSettings {
-
+
private int pan;
private int tilt;
private int zoom;
private int focus;
-
+
/**
* Constructs a camera settings object with orientation,
- * zoom level and focus level initialised to 0.
+ * zoom level and focus level initialized to 0.
*/
public CameraSettings() {
pan = 0;
@@ -22,10 +23,11 @@ public CameraSettings() {
zoom = 0;
focus = 0;
}
-
+
/**
* Constructs a camera settings object with a certain orientation,
* zoom level and focus.
+ *
* @param panPos Horizontal orientation level.
* @param tiltPos Vertical orientation level.
* @param zoomPos Zoom level.
@@ -37,7 +39,7 @@ public CameraSettings(int panPos, int tiltPos, int zoomPos, int focusPos) {
zoom = zoomPos;
focus = focusPos;
}
-
+
/**
* Gets the pan level (horizontal orientation).
* @return Pan level (horizontal orientation).
@@ -85,7 +87,7 @@ public void setFocus(int focusPos) {
public int getTilt() {
return tilt;
}
-
+
/**
* Gets the zoom level.
* @return Zoom level.
@@ -109,7 +111,7 @@ public int getFocus() {
protected void pan(int offset) {
pan += offset;
}
-
+
/**
* Tilts the camera settings a certain offset.
* @param offset The offset to tilt the camera.
@@ -117,7 +119,7 @@ protected void pan(int offset) {
protected void tilt(int offset) {
tilt += offset;
}
-
+
/**
* Zooms the camera settings a certain offset.
* @param offset The offset to zoom the camera.
@@ -138,29 +140,26 @@ protected void focus(int offset) {
public int hashCode() {
final int prime = 31;
int result = 1;
+
result = prime * result + focus;
result = prime * result + pan;
result = prime * result + tilt;
result = prime * result + zoom;
+
return result;
}
@Override
public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (!(obj instanceof CameraSettings)) {
- return false;
+ if (obj instanceof CameraSettings) {
+ CameraSettings other = (CameraSettings) obj;
+
+ return focus == other.focus
+ && pan == other.pan
+ && tilt == other.tilt
+ && zoom == other.zoom;
}
- CameraSettings other = (CameraSettings) obj;
- boolean result = focus == other.focus
- && pan == other.pan
- && tilt == other.tilt
- && zoom == other.zoom;
- return result;
+
+ return false;
}
}
diff --git a/src/main/java/nl/tudelft/contextproject/camera/LiveCameraConnection.java b/src/main/java/nl/tudelft/contextproject/camera/LiveCameraConnection.java
index a217177..0766f3d 100644
--- a/src/main/java/nl/tudelft/contextproject/camera/LiveCameraConnection.java
+++ b/src/main/java/nl/tudelft/contextproject/camera/LiveCameraConnection.java
@@ -20,77 +20,88 @@
* @since 0.4
*/
public class LiveCameraConnection extends CameraConnection {
-
+
public static final String CAMERA_MODEL = "AW-HE130";
-
+
public static final int PAN_LIMIT_LOW = 11528;
public static final int PAN_LIMIT_HIGH = 54005;
-
+
public static final int TILT_LIMIT_LOW = 7283;
public static final int TILT_LIMIT_HIGH = 36408;
-
+
public static final int ZOOM_LIMIT_LOW = 1365;
public static final int ZOOM_LIMIT_HIGH = 4095;
public static final int FOCUS_LIMIT_LOW = 1365;
public static final int FOCUS_LIMIT_HIGH = 4095;
-
+
private static final int READ_TIMEOUT = 3000;
-
- private String address;
+
+ private final String errorString = "Wrong response from camera: ";
+
private boolean connected;
private boolean autoFocus;
private CameraSettings lastKnown;
-
+ private String address;
+
/**
* Creates a LiveCameraConnection object. Assumes that the
* address given is the correctly formulated IP address of the
* camera to connect to.
+ *
* @param address IP address of the camera to connect to.
*/
public LiveCameraConnection(String address) {
this.address = address;
this.connected = false;
}
-
+
+ /**
+ * Returns the last known camera settings.
+ * @return The last known camera settings.
+ */
protected CameraSettings getLastKnownSettings() {
return lastKnown;
}
-
+
@Override
public boolean setUpConnection() {
try {
String cameraModel = sendRequest(buildCamControlURL("QID"));
+
if (cameraModel.equals("OID:" + CAMERA_MODEL)) {
String autoFocusResponse = sendRequest(buildPanTiltHeadControlURL("%23D1"));
int hasAutoFocus = Integer.parseInt(autoFocusResponse.substring(2));
autoFocus = hasAutoFocus == 1;
connected = true;
lastKnown = new CameraSettings();
+
return true;
}
+
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
-
+
@Override
public boolean isConnected() {
return connected;
}
-
+
@Override
public String getStreamLink() {
return "rtsp://" + address + "/MediaInput/h264";
}
-
+
/**
* Builds the URL for the command specified, which must be a command
* from section 3.1 Pan-tilt Head Control.
+ *
* @param command Command to be sent.
- * @return the formed URL, according to the {@link #address} and the command.
+ * @return The formed URL, according to the {@link #address} and the command.
* @throws MalformedURLException if the parameter command is null.
*/
private URL buildPanTiltHeadControlURL(String command) throws MalformedURLException {
@@ -101,12 +112,13 @@ private URL buildPanTiltHeadControlURL(String command) throws MalformedURLExcept
throw new MalformedURLException("Given command is null");
}
}
-
+
/**
* Builds the URL for the command specified, which must be a command
* from section 3.2 Camera Control.
+ *
* @param command Command to be sent.
- * @return the formed URL, according to the {@link #address} and the command.
+ * @return The formed URL, according to the {@link #address} and the command.
* @throws MalformedURLException if the parameter command is null.
*/
private URL buildCamControlURL(String command) throws MalformedURLException {
@@ -117,14 +129,15 @@ private URL buildCamControlURL(String command) throws MalformedURLException {
throw new MalformedURLException("Given command is null");
}
}
-
+
/**
* Sends the HTTP request specified in the URL as a POST request.
* It waits for a response from the server until a response is
* received or until the connection times out, which happens after
* the amount of milliseconds specified in {@link #READ_TIMEOUT}.
- * @param url the URL containing the full HTTP request
- * @return the response of the server.
+ *
+ * @param url The URL containing the full HTTP request
+ * @return The response of the server.
* @throws IOException when something goes wrong in opening the
* the connection or reading the response from the server.
* @throws java.net.ConnectException when a timeout has
@@ -132,6 +145,7 @@ private URL buildCamControlURL(String command) throws MalformedURLException {
*/
private String sendRequest(URL url) throws IOException {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+
try {
connection.setRequestMethod("GET");
connection.setConnectTimeout(READ_TIMEOUT);
@@ -140,37 +154,42 @@ private String sendRequest(URL url) throws IOException {
connected = false;
return "";
}
+
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
String response = reader.readLine();
reader.close();
+
return response != null ? response : "";
}
-
+
/**
* Returns true if the camera is on auto focus.
- * @return true if the camera is on auto focus.
+ * @return True if the camera is on auto focus.
*/
public boolean hasAutoFocus() {
if (connected) {
try {
String autoFocusRes = sendRequest(buildPanTiltHeadControlURL("%23D1"));
+
if (autoFocusRes.startsWith("d1")) {
autoFocus = Integer.parseInt(autoFocusRes.substring(2)) == 1;
} else {
- throw new IOException("Wrong response from camera: " + autoFocusRes);
+ throw new IOException(errorString + autoFocusRes);
}
} catch (IOException e) {
e.printStackTrace();
return autoFocus;
}
}
+
return autoFocus;
}
-
+
/**
* Sets the auto focus setting on the camera to on (true) or off (false).
+ *
* @param autoFocus true for ON, false for OFF
- * @return true iff the camera was set to the specified setting.
+ * @return True iff the camera was set to the specified setting.
*/
public boolean setAutoFocus(boolean autoFocus) {
if (this.autoFocus == autoFocus) {
@@ -179,11 +198,12 @@ public boolean setAutoFocus(boolean autoFocus) {
try {
int set = autoFocus ? 1 : 0;
String autoFocusRes = sendRequest(buildPanTiltHeadControlURL("%23D1" + set));
+
if (autoFocusRes.equals("d1" + set)) {
this.autoFocus = autoFocus;
return true;
} else {
- throw new IOException("Wrong response from camera: " + autoFocusRes);
+ throw new IOException(errorString + autoFocusRes);
}
} catch (IOException e) {
e.printStackTrace();
@@ -197,31 +217,36 @@ public void update(Observable o, Object arg) {
if (!(o instanceof Camera)) {
return;
}
- //Camera cam = (Camera) o;
+
if (arg instanceof CameraSettings) {
mutateSettings((CameraSettings) arg);
}
}
-
+
/**
* Finds the least amount of commands to send to the
- * camera in order to apply the specified camera settings
- * @param toSet camera settings to apply to the camera.
- * @return true iff the camera was set to the specified settings.
+ * camera in order to apply the specified camera settings.
+ *
+ * @param toSet Camera settings to apply to the camera.
+ * @return True iff the camera was set to the specified settings.
*/
private boolean mutateSettings(CameraSettings toSet) {
CameraSettings curSettings = getCurrentCameraSettings();
boolean result = true;
+
if (curSettings.getPan() != toSet.getPan()
|| curSettings.getTilt() != toSet.getTilt()) {
result = result && absPanTilt(toSet.getPan(), toSet.getTilt());
}
+
if (curSettings.getZoom() != toSet.getZoom()) {
result = result && absZoom(toSet.getZoom());
}
+
if (!hasAutoFocus() && curSettings.getFocus() != toSet.getFocus()) {
result = result && absFocus(toSet.getFocus());
}
+
return result;
}
@@ -230,46 +255,51 @@ public CameraSettings getCurrentCameraSettings() {
int[] panTilt = getCurrentPanTilt();
int zoom = getCurrentZoom();
int focus = getCurrentFocus();
+
lastKnown = new CameraSettings(panTilt[0], panTilt[1], zoom, focus);
return lastKnown;
}
-
+
@Override
public int[] getCurrentPanTilt() {
try {
String panTiltRes = sendRequest(buildPanTiltHeadControlURL("%23APC"));
+
if (panTiltRes.startsWith("aPC")) {
int pan = Integer.parseInt(panTiltRes.substring(3, 7), 16);
int tilt = Integer.parseInt(panTiltRes.substring(7, 11), 16);
lastKnown.setPan(pan);
lastKnown.setTilt(tilt);
+
return new int[]{pan, tilt};
} else {
- throw new IOException("Wrong response from camera: " + panTiltRes);
+ throw new IOException(errorString + panTiltRes);
}
} catch (IOException e) {
e.printStackTrace();
return new int[]{lastKnown.getPan(), lastKnown.getTilt()};
}
}
-
+
@Override
public int getCurrentZoom() {
try {
String zoomRes = sendRequest(buildPanTiltHeadControlURL("%23GZ"));
+
if (zoomRes.startsWith("gz")) {
int zoom = Integer.parseInt(zoomRes.substring(2, 5), 16);
lastKnown.setZoom(zoom);
+
return zoom;
} else {
- throw new IOException("Wrong response from camera: " + zoomRes);
+ throw new IOException(errorString + zoomRes);
}
} catch (IOException e) {
e.printStackTrace();
return lastKnown.getZoom();
}
}
-
+
@Override
public int getCurrentFocus() {
if (autoFocus) {
@@ -277,11 +307,12 @@ public int getCurrentFocus() {
} else {
try {
String focusRes = sendRequest(buildPanTiltHeadControlURL("%23GF"));
+
if (focusRes.startsWith("gf")) {
int focus = Integer.parseInt(focusRes.substring(2), 16);
return focus;
} else {
- throw new IOException("Wrong response from camera: " + focusRes);
+ throw new IOException(errorString + focusRes);
}
} catch (IOException e) {
e.printStackTrace();
@@ -289,25 +320,36 @@ public int getCurrentFocus() {
}
}
}
-
+
@Override
protected boolean absPanTilt(int panValue, int tiltValue) {
- panValue = (panValue < PAN_LIMIT_LOW) ? PAN_LIMIT_LOW :
- (panValue > PAN_LIMIT_HIGH) ? PAN_LIMIT_HIGH : panValue;
- tiltValue = (tiltValue < TILT_LIMIT_LOW) ? TILT_LIMIT_LOW :
- (tiltValue > TILT_LIMIT_HIGH) ? TILT_LIMIT_HIGH : tiltValue;
+ if (panValue < PAN_LIMIT_LOW) {
+ panValue = PAN_LIMIT_LOW;
+ } else if (panValue > PAN_LIMIT_HIGH) {
+ panValue = PAN_LIMIT_HIGH;
+ }
+
+ if (tiltValue < TILT_LIMIT_LOW) {
+ tiltValue = TILT_LIMIT_LOW;
+ } else if (tiltValue > TILT_LIMIT_HIGH) {
+ tiltValue = TILT_LIMIT_HIGH;
+ }
+
try {
String res = sendRequest(buildPanTiltHeadControlURL(
- "%23APS"
- + Integer.toHexString(0x10000 | panValue).substring(1).toUpperCase()
- + Integer.toHexString(0x10000 | tiltValue).substring(1).toUpperCase()
- + "1D" + "2"
+ "%23APS"
+ + Integer.toHexString(0x10000 | panValue).substring(1).toUpperCase()
+ + Integer.toHexString(0x10000 | tiltValue).substring(1).toUpperCase()
+ + "1D" + "2"
));
+
if (res.startsWith("aPS")) {
lastKnown.setPan(panValue);
lastKnown.setTilt(tiltValue);
+
return true;
}
+
return false;
} catch (IOException e) {
e.printStackTrace();
@@ -331,12 +373,14 @@ protected boolean absZoom(int value) {
(value > ZOOM_LIMIT_HIGH) ? ZOOM_LIMIT_HIGH : value;
try {
String res = sendRequest(buildPanTiltHeadControlURL("%23AXZ"
- + Integer.toHexString(0x1000 | value).substring(1).toUpperCase()
+ + Integer.toHexString(0x1000 | value).substring(1).toUpperCase()
));
+
if (res.startsWith("axz")) {
lastKnown.setZoom(value);
return true;
}
+
return false;
} catch (IOException e) {
e.printStackTrace();
@@ -348,13 +392,16 @@ protected boolean absZoom(int value) {
protected boolean absFocus(int value) {
value = (value < FOCUS_LIMIT_LOW) ? FOCUS_LIMIT_LOW :
(value > FOCUS_LIMIT_HIGH) ? FOCUS_LIMIT_HIGH : value;
+
try {
if (autoFocus) {
throw new IOException("Autofocus is on");
}
+
String res = sendRequest(buildPanTiltHeadControlURL("%23AXF"
- + Integer.toHexString(0x1000 | value).substring(1).toUpperCase()
+ + Integer.toHexString(0x1000 | value).substring(1).toUpperCase()
));
+
if (res.startsWith("axf")) {
lastKnown.setFocus(value);
return true;
@@ -362,34 +409,43 @@ protected boolean absFocus(int value) {
autoFocus = true;
throw new IOException("Autofocus is on");
}
+
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
-
+
@Override
protected boolean relPanTilt(int panOffset, int tiltOffset) {
CameraSettings curSet = getCurrentCameraSettings();
- panOffset = (curSet.getPan() + panOffset < PAN_LIMIT_LOW)
- ? curSet.getPan() - PAN_LIMIT_LOW :
- (curSet.getPan() + panOffset > PAN_LIMIT_HIGH)
- ? PAN_LIMIT_HIGH - curSet.getPan() : panOffset;
- tiltOffset = (curSet.getTilt() + tiltOffset < TILT_LIMIT_LOW)
- ? curSet.getTilt() - TILT_LIMIT_LOW :
- (curSet.getTilt() + tiltOffset > TILT_LIMIT_HIGH)
- ? TILT_LIMIT_HIGH - curSet.getTilt() : tiltOffset;
+
+ if (curSet.getPan() + panOffset < PAN_LIMIT_LOW) {
+ panOffset = curSet.getPan() - PAN_LIMIT_LOW;
+ } else if (curSet.getPan() + panOffset > PAN_LIMIT_HIGH) {
+ panOffset = PAN_LIMIT_HIGH - curSet.getPan();
+ }
+
+ if (curSet.getTilt() + tiltOffset < TILT_LIMIT_LOW) {
+ tiltOffset = curSet.getTilt() - TILT_LIMIT_LOW;
+ } else if (curSet.getTilt() + tiltOffset > TILT_LIMIT_HIGH) {
+ tiltOffset = TILT_LIMIT_HIGH - curSet.getTilt();
+ }
+
try {
String res = sendRequest(buildPanTiltHeadControlURL("%23RPC"
- + Integer.toHexString(0x10000 | 32768 + panOffset).substring(1).toUpperCase()
- + Integer.toHexString(0x10000 | 32768 + tiltOffset).substring(1).toUpperCase()
+ + Integer.toHexString(0x10000 | 32768 + panOffset).substring(1).toUpperCase()
+ + Integer.toHexString(0x10000 | 32768 + tiltOffset).substring(1).toUpperCase()
));
+
if (res.startsWith("rPC")) {
lastKnown.pan(panOffset);
lastKnown.tilt(tiltOffset);
+
return true;
}
+
return false;
} catch (IOException e) {
e.printStackTrace();
diff --git a/src/main/java/nl/tudelft/contextproject/camera/MockedCameraConnection.java b/src/main/java/nl/tudelft/contextproject/camera/MockedCameraConnection.java
index 7a1f865..944de57 100644
--- a/src/main/java/nl/tudelft/contextproject/camera/MockedCameraConnection.java
+++ b/src/main/java/nl/tudelft/contextproject/camera/MockedCameraConnection.java
@@ -3,13 +3,14 @@
import java.util.Observable;
/**
- * Class to represent a mocked camera. It mimics or mocks the behaviour of a specific camera
+ * Class to represent a mocked camera. It mimics or mocks the behavior of a specific camera
* without having a real connection to the cameras.
*
* @since 0.4
*/
public class MockedCameraConnection extends CameraConnection {
private CameraSettings camSet = new CameraSettings(30, 30, 30, 1365);
+ private String streamLink = "http://qthttp.apple.com.edgesuite.net/1010qwoeiuryfg/sl.m3u8";
@Override
public boolean setUpConnection() {
@@ -23,7 +24,15 @@ public boolean isConnected() {
@Override
public String getStreamLink() {
- return "placeholder_picture.jpg";
+ return streamLink;
+ }
+
+ /**
+ * Sets the link to the 'live stream' of this mocked camera connection
+ * @param link Link to the 'live stream' of this mocked camera connection.
+ */
+ public void setStreamLink(String link) {
+ streamLink = link;
}
@Override
@@ -113,9 +122,9 @@ public void update(Observable o, Object arg) {
if (!(o instanceof Camera)) {
return;
}
+
if (arg instanceof CameraSettings) {
camSet = (CameraSettings) arg;
}
-
}
}
diff --git a/src/main/java/nl/tudelft/contextproject/gui/AlertDialog.java b/src/main/java/nl/tudelft/contextproject/gui/AlertDialog.java
new file mode 100644
index 0000000..45f1912
--- /dev/null
+++ b/src/main/java/nl/tudelft/contextproject/gui/AlertDialog.java
@@ -0,0 +1,190 @@
+package nl.tudelft.contextproject.gui;
+
+import javafx.scene.control.Alert;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.ButtonType;
+
+import nl.tudelft.contextproject.script.Shot;
+
+import java.io.File;
+import java.util.Optional;
+
+/**
+ * Utility class that holds all generated alert dialogs. This handles
+ * the creation and showing of info, warning and error dialogs
+ * across the entire application.
+ *
+ * @since 0.6
+ */
+public final class AlertDialog {
+
+ /**
+ * Abstract classes should not have a public constructor,
+ * so defining it as private below.
+ */
+ private AlertDialog() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Shows a confirmation dialog when trying to save a {@link Script}, when
+ * the script is invalid.
+ *
+ * @param error The first shot that causes the invalid script.
+ * @return The alert.
+ */
+ public static Alert confirmInvalidScriptSaving(Shot error) {
+ Alert alert = new Alert(AlertType.CONFIRMATION);
+ alert.setTitle("Confirm saving");
+ alert.setHeaderText("Trying to save invalid script");
+ alert.setContentText("Error at shot ID: "
+ + error.getNumber()
+ + "\nYou are trying to save an invalid script. "
+ + "Are you sure you want to continue?");
+
+ return alert;
+ }
+
+ /**
+ * Shows a warning dialog when trying to load a {@link Script}, when
+ * the script is invalid.
+ *
+ * @param error The first shot that causes the invalid script.
+ * @return The alert.
+ */
+ public static Alert warningInvalidScriptLoading(Shot error) {
+ Alert alert = new Alert(AlertType.WARNING);
+ alert.setTitle("Script invalid");
+ alert.setHeaderText("Loaded an invalid script");
+ alert.setContentText("Error at shot ID: "
+ + error.getNumber()
+ + "\nThe script you loaded is invalid. You can change "
+ + "it in the edit script menu");
+
+ return alert;
+ }
+
+ /**
+ * Displays a confirm to exit dialog when the
+ * script has been saved.
+ *
+ * @param file The file that has been saved.
+ */
+ public static void confirmExitingAfterSaving(File file) {
+ Alert alert = new Alert(AlertType.CONFIRMATION);
+ alert.setTitle("Confirm exiting");
+ alert.setHeaderText("Saving script was succesful!");
+ alert.setContentText("Succesful save of script: "
+ + file.getName()
+ + " Do you want to quit to menu?");
+
+ Optional result = alert.showAndWait();
+
+ if (result.get() == ButtonType.OK) {
+ MenuController.show();
+ }
+ }
+
+ /**
+ * Shows the dialog when an invalid script is detected.
+ *
+ * @param number The camera that will have a consecutive shot.
+ * @return True if the user ignores the error, false otherwise.
+ */
+ public static boolean confirmInvalidScriptAdding(Number number) {
+ Alert alert = new Alert(AlertType.CONFIRMATION);
+ alert.setTitle("Confirm adding shot");
+ alert.setHeaderText("Invalid script!");
+ alert.setContentText("Are you sure you want to add this "
+ + "shot? It will create an invalid script since "
+ + "camera "
+ + number
+ + " will have two presets in a row!");
+
+ Optional result = alert.showAndWait();
+
+ if (result.get() == ButtonType.OK) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Displays an error dialog when saving of the script
+ * was unsuccessful.
+ *
+ * @param e The exception that was thrown.
+ * @param file The file that was supposed to be saved.
+ */
+ public static void errorSaveUnsuccesful(Exception e, File file) {
+ Alert alert = new Alert(AlertType.ERROR);
+ alert.setTitle(e.getMessage());
+ alert.setHeaderText("Saving script was unsuccesful!");
+ alert.setContentText("Error when trying to save script at location: "
+ + file.getAbsolutePath()
+ + "\n\nError: "
+ + e.getCause());
+
+ alert.showAndWait();
+ }
+
+ /**
+ * Shows a dialog when exiting a screen without saving, thus
+ * not saving currently made changes.
+ *
+ * @return True if the user wants to quit, false otherwise.
+ */
+ public static boolean confirmExiting() {
+ Alert alert = new Alert(AlertType.CONFIRMATION);
+ alert.setTitle("Confirm quitting");
+ alert.setHeaderText("Exiting will erase any unsaved changes");
+ alert.setContentText("Are you sure you want to quit? Any unsaved changes "
+ + "will not be kept.");
+
+ Optional result = alert.showAndWait();
+
+ if (result.get() == ButtonType.CANCEL) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Shows the dialog that notifies the user that the loading
+ * of a script was successful.
+ *
+ * @param file The location of the script that was loaded.
+ */
+ public static void infoSuccesfulLoading(File file) {
+ Alert alert = new Alert(AlertType.INFORMATION);
+ alert.setTitle("Info Dialog");
+ alert.setHeaderText("Loading script was succesful!");
+ alert.setContentText("Successful load of script: " + file.getName());
+
+ alert.showAndWait();
+ }
+
+ /**
+ * Displays an error dialog when saving of the script
+ * was unsuccessful.
+ *
+ * @param e The exception that was thrown.
+ * @param file The file that was supposed to be saved.
+ */
+ public static void errorLoadUnsuccesful(Exception e, File file) {
+ String c = (e.getCause() == null) ? "" : "\nCause: " + e.getCause();
+
+ Alert alert = new Alert(AlertType.ERROR);
+ alert.setTitle("Unsuccesful load!");
+ alert.setHeaderText("Loading script was unsuccesful!");
+ alert.setContentText("Error when trying to load script at location: "
+ + file.getAbsolutePath()
+ + "\n\nError: "
+ + e.getMessage()
+ + c);
+
+ alert.showAndWait();
+ }
+}
diff --git a/src/main/java/nl/tudelft/contextproject/gui/CameramanUIController.java b/src/main/java/nl/tudelft/contextproject/gui/CameramanLiveController.java
similarity index 63%
rename from src/main/java/nl/tudelft/contextproject/gui/CameramanUIController.java
rename to src/main/java/nl/tudelft/contextproject/gui/CameramanLiveController.java
index 3c58998..25ec341 100644
--- a/src/main/java/nl/tudelft/contextproject/gui/CameramanUIController.java
+++ b/src/main/java/nl/tudelft/contextproject/gui/CameramanLiveController.java
@@ -1,9 +1,11 @@
package nl.tudelft.contextproject.gui;
+import javafx.collections.FXCollections;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Button;
+import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Label;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextArea;
@@ -13,10 +15,9 @@
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
+
import nl.tudelft.contextproject.ContextTFP;
import nl.tudelft.contextproject.camera.Camera;
-import nl.tudelft.contextproject.camera.CameraSettings;
-import nl.tudelft.contextproject.presets.InstantPreset;
import nl.tudelft.contextproject.presets.MovementType;
import nl.tudelft.contextproject.presets.Preset;
import nl.tudelft.contextproject.script.Script;
@@ -24,17 +25,24 @@
import java.io.IOException;
/**
- * This class controls the live view of the camera.
+ * This class controls the screen that shows the live view of
+ * the {@link Camera}, for the cameraman. This screen allows a cameraman to see the
+ * current live view, look at the {@link Preset Presets} of the camera, and apply
+ * both new and pre-configured presets.
+ *
+ *
The view section is defined under view/CameramanLiveView.fxml
*
* @since 0.3
*/
-public class CameramanUIController {
+public class CameramanLiveController {
private static Script script;
-
+
+ @FXML private AnchorPane movementPane;
@FXML private TabPane tabs;
-
+
@FXML private Button btnBack;
+ @FXML private Button btnConfirm;
@FXML private Button swap;
@FXML private Button moveOne;
@FXML private Button moveTwo;
@@ -43,66 +51,63 @@ public class CameramanUIController {
@FXML private Button moveFive;
@FXML private Button moveSix;
@FXML private Button moveSeven;
- @FXML private Button btnConfirm;
+
+ @FXML private ChoiceBox currentCam;
@FXML private ImageView bigView;
@FXML private ImageView smallView;
-
- @FXML private TextArea descriptionField;
-
- @FXML private TextField speed;
-
- @FXML private VBox smallViewBox;
- @FXML private VBox bigViewBox;
-
+
@FXML private Label bigStatusLabel;
@FXML private Label smallStatusLabel;
@FXML private Label cameraNumberLabel;
@FXML private Label presetLabel;
@FXML private Label movement;
@FXML private Label infoLabel;
-
- private int currentView;
-
+
+ @FXML private TextArea descriptionField;
+ @FXML private TextField speed;
+
+ @FXML private VBox bigViewBox;
+ @FXML private VBox smallViewBox;
+
private Camera liveCam;
- private Camera currentCam;
+
+ private boolean live;
private int liveSpeed;
private int currentSpeed;
-
+
private MovementType liveMovement;
private MovementType currentMovement;
+ /**
+ * Initialize method used by JavaFX.
+ */
@FXML private void initialize() {
script = ContextTFP.getScript();
+ //set an initial live camera
+ liveCam = Camera.getCamera(0);
+
bigView.fitWidthProperty().bind(bigViewBox.widthProperty());
bigView.fitHeightProperty().bind(bigViewBox.heightProperty());
-
+
smallView.fitWidthProperty().bind(smallViewBox.widthProperty());
smallView.fitHeightProperty().bind(smallViewBox.heightProperty());
- currentView = 0;
-
- //Initialize dummy cameras and presets
- liveCam = new Camera();
- currentCam = new Camera();
-
- CameraSettings dummySettings = new CameraSettings();
-
- Preset presetOne = new InstantPreset(dummySettings, 1);
- Preset presetTwo = new InstantPreset(dummySettings, 2);
-
- liveCam.addPreset(presetOne);
- currentCam.addPreset(presetTwo);
+ live = true;
initializeLabels();
initializeViews();
initializeButtons();
initializeMovements();
initializeTextFields();
+ initializeCurrentCam();
+
+ movementPane.setDisable(true);
+ descriptionField.setEditable(false);
}
-
+
/**
* Initializes the labels in the gui.
*/
@@ -110,16 +115,17 @@ private void initializeLabels() {
bigStatusLabel.setText("LIVE");
bigStatusLabel.setStyle("-fx-text-fill: red;");
smallStatusLabel.setText("Current camera");
-
+
if (script.getCurrentShot() != null) {
cameraNumberLabel.setText(Integer.toString(script.getCurrentShot().getCamera().getNumber()));
presetLabel.setText(Integer.toString(script.getCurrentShot().getPreset().getId()));
descriptionField.setText(script.getCurrentShot().getDescription());
}
+
cameraNumberLabel.setText(String.valueOf(liveCam.getNumber()));
presetLabel.setText(String.valueOf(liveCam.getPreset(1).getId()));
}
-
+
/**
* Initializes the views.
*/
@@ -130,18 +136,48 @@ private void initializeViews() {
Image current = new Image("test3.jpg");
smallView.setImage(current);
}
-
+
/**
* Initialize button styling and functionality.
*/
private void initializeButtons() {
- swap.setOnAction((event) -> {
+ initSwapButton();
+
+ btnBack.setOnAction(event -> {
+ MenuController.show();
+ });
+
+ btnConfirm.setOnAction(event -> {
+ if (!speed.getText().isEmpty()) {
+ int spd = Integer.parseInt(speed.getText());
+
+ if (spd > 100) {
+ spd = 100;
+ }
+
+ if (live) {
+ liveSpeed = spd;
+ speed.setText(String.valueOf(spd));
+ } else {
+ currentSpeed = spd;
+ speed.setText(String.valueOf(spd));
+ }
+ }
+ });
+ }
+
+ /**
+ * Initializes the swap button.
+ */
+ private void initSwapButton() {
+ swap.setOnAction(event -> {
Image three = bigView.getImage();
bigView.setImage(smallView.getImage());
smallView.setImage(three);
String text = bigStatusLabel.getText();
bigStatusLabel.setText(smallStatusLabel.getText());
smallStatusLabel.setText(text);
+
if (text.equals("LIVE")) {
smallStatusLabel.setStyle("-fx-text-fill: red;");
bigStatusLabel.setStyle("");
@@ -149,74 +185,57 @@ private void initializeButtons() {
smallStatusLabel.setStyle("");
bigStatusLabel.setStyle("-fx-text-fill: red;");
}
+
swapCurrentView();
swapInfoTable();
swapSpeed();
});
-
- btnBack.setOnAction((event) -> {
- MenuController.show();
- });
-
- btnConfirm.setOnAction((event) -> {
- if (!speed.getText().isEmpty()) {
- int spd = Integer.parseInt(speed.getText());
- if (spd > 100) {
- spd = 100;
- }
- if (live()) {
- liveSpeed = spd;
- speed.setText(String.valueOf(spd));
- } else {
- currentSpeed = spd;
- speed.setText(String.valueOf(spd));
- }
- }
- });
}
-
+
/**
- * Initialize movements.
+ * Initialises movements.
*/
private void initializeMovements() {
- moveOne.setOnAction((event) -> {
+ moveOne.setOnAction(event -> {
movement.setText(moveOne.getText());
setMovement(MovementType.ZOOM_IN);
});
-
- moveTwo.setOnAction((event) -> {
+
+ moveTwo.setOnAction(event -> {
movement.setText(moveTwo.getText());
setMovement(MovementType.ZOOM_OUT);
});
-
- moveThree.setOnAction((event) -> {
+
+ moveThree.setOnAction(event -> {
movement.setText(moveThree.getText());
setMovement(MovementType.LEFT);
});
-
- moveFour.setOnAction((event) -> {
+
+ moveFour.setOnAction(event -> {
movement.setText(moveFour.getText());
setMovement(MovementType.RIGHT);
});
-
- moveFive.setOnAction((event) -> {
+
+ moveFive.setOnAction(event -> {
movement.setText(moveFive.getText());
setMovement(MovementType.UP);
});
-
- moveSix.setOnAction((event) -> {
+
+ moveSix.setOnAction(event -> {
movement.setText(moveSix.getText());
setMovement(MovementType.DOWN);
});
-
- moveSeven.setOnAction((event) -> {
+
+ moveSeven.setOnAction(event -> {
movement.setText(moveSeven.getText());
setMovement(MovementType.CUSTOM);
});
+
+
}
-
+
/**
- * Initialize the textfields.
+ * Initialises the text fields.
*/
private void initializeTextFields() {
speed.addEventFilter(KeyEvent.KEY_TYPED, new EventHandler() {
@@ -232,44 +251,72 @@ public void handle(KeyEvent event) {
}
});
}
+
+ /**
+ * Initialises the ChoiceBox of cameras to choose from.
+ */
+ private void initializeCurrentCam() {
+ currentCam.setItems(FXCollections.observableArrayList(Camera.getAllCameras()));
+ currentCam.setVisible(false);
+
+ currentCam.getSelectionModel().selectedItemProperty().addListener((obs, oldV, newV) -> {
+ changeInfoTable(newV);
+ });
+
+ //set initial current camera
+ currentCam.setValue(Camera.getCamera(1));
+ }
/**
* Swap currentView.
*/
private void swapCurrentView() {
- if (live()) {
- currentView = 1;
+ if (live) {
+ live = false;
+ currentCam.setVisible(true);
+ movementPane.setDisable(false);
} else {
- currentView = 0;
+ live = true;
+ currentCam.setVisible(false);
+ movementPane.setDisable(true);
}
}
-
+
/**
* Swap info table according to the big view.
*/
private void swapInfoTable() {
- if (live()) {
- Preset preset = liveCam.getPreset(1);
- infoLabel.setText("Information about live camera");
- cameraNumberLabel.setText(String.valueOf(liveCam.getNumber()));
- presetLabel.setText(String.valueOf(preset.getId()));
- movement.setText(MovementType.getName(liveMovement));
- descriptionField.setText(preset.getDescription());
+ if (live) {
+ setActualInfo();
} else {
- Preset preset = currentCam.getPreset(2);
- infoLabel.setText("Information about current camera");
- cameraNumberLabel.setText(String.valueOf(currentCam.getNumber()));
- presetLabel.setText(String.valueOf(preset.getId()));
- movement.setText(MovementType.getName(currentMovement));
- descriptionField.setText(preset.getDescription());
+ setCurrentInfo();
}
}
+ /**
+ * Changes the info table according to the currently selected camera.
+ *
+ * @param newCam The new camera to switch the info to.
+ */
+ private void changeInfoTable(Camera newCam) {
+ Preset preset;
+ if (newCam.getPreset(1) == null) {
+ preset = newCam.getPreset(2);
+ } else {
+ preset = newCam.getPreset(1);
+ }
+ infoLabel.setText("Information about current camera");
+ cameraNumberLabel.setText(String.valueOf(newCam.getNumber()));
+ presetLabel.setText(String.valueOf(preset.getId()));
+ movement.setText(MovementType.getName(currentMovement));
+ descriptionField.setText(preset.getDescription());
+ }
+
/**
* Swap speed according to the big view.
*/
private void swapSpeed() {
- if (live()) {
+ if (live) {
if (liveSpeed > 0) {
speed.setText(String.valueOf(liveSpeed));
} else {
@@ -283,38 +330,51 @@ private void swapSpeed() {
}
}
}
-
+
/**
- * set movement type to the big view.
- * @param mt - the movement type to set.
+ * Set movement type to the big view.
+ * @param mt The movement type to set.
*/
private void setMovement(MovementType mt) {
- if (live()) {
+ if (live) {
liveMovement = mt;
} else {
currentMovement = mt;
}
}
+
+ /**
+ * Set the table info to the actual camera info.
+ */
+ private void setActualInfo() {
+ Preset preset = liveCam.getPreset(1);
+ infoLabel.setText("Information about live camera");
+ cameraNumberLabel.setText(String.valueOf(liveCam.getNumber()));
+ presetLabel.setText(String.valueOf(preset.getId()));
+ movement.setText(MovementType.getName(liveMovement));
+ descriptionField.setText(preset.getDescription());
+ }
/**
- * See what is currently on the big view.
- * @return - whether it's the live camera on the view or the current camera.
+ * Set the table info to the current camera info.
*/
- private boolean live() {
- if (currentView == 0) {
- return true;
- } else {
- return false;
- }
+ private void setCurrentInfo() {
+ Preset preset = currentCam.getValue().getPreset(2);
+ infoLabel.setText("Information about current camera");
+ cameraNumberLabel.setText(String.valueOf(currentCam.getValue().getNumber()));
+ presetLabel.setText(String.valueOf(preset.getId()));
+ movement.setText(MovementType.getName(currentMovement));
+ descriptionField.setText(preset.getDescription());
}
/**
- * Shows this view.
+ * Calling this method shows this view in the middle of the rootLayout,
+ * forcing the current view to disappear.
*/
public static void show() {
try {
FXMLLoader loader = new FXMLLoader();
- loader.setLocation(ContextTFP.class.getResource("view/CameramanUIView.fxml"));
+ loader.setLocation(ContextTFP.class.getResource("view/CameramanLiveView.fxml"));
AnchorPane cameraLiveUI = (AnchorPane) loader.load();
ContextTFP.getRootLayout().setCenter(cameraLiveUI);
diff --git a/src/main/java/nl/tudelft/contextproject/gui/CreateScriptController.java b/src/main/java/nl/tudelft/contextproject/gui/CreateScriptController.java
index 95463f8..f25ffdf 100644
--- a/src/main/java/nl/tudelft/contextproject/gui/CreateScriptController.java
+++ b/src/main/java/nl/tudelft/contextproject/gui/CreateScriptController.java
@@ -11,7 +11,6 @@
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
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.ChoiceBox;
@@ -63,6 +62,7 @@
*/
public class CreateScriptController {
+ private static final String REDBORDER = "-fx-border-color: red;";
private static boolean fill = false;
private ObjectProperty> lastSelectedRow;
@@ -100,7 +100,7 @@ public class CreateScriptController {
@FXML private TextField editDescription;
/**
- * Initialize method used by JavaFX.
+ * Initialise method used by JavaFX.
*/
@FXML private void initialize() {
@@ -167,6 +167,315 @@ private void fillTable(List shots) {
tableEvents.getItems().addAll(shots);
}
+ /**
+ * Fills the choiceboxes for selecting a camera, both the box that
+ * adds a new camera as the box that is shown when editing a shot.
+ */
+ private void initCamera() {
+ final List cameraList = new ArrayList();
+
+ for (int i = 0; i < Camera.getCameraAmount(); ++i) {
+ cameraList.add(i + 1);
+ }
+
+ addCamera.setItems(FXCollections.observableArrayList(cameraList));
+ editCamera.setItems(FXCollections.observableArrayList(cameraList));
+ }
+
+ /**
+ * Fills the choiceboxes for selecting a preset, given the selection
+ * of a certain camera.
+ */
+ private void initPreset(String prepend) {
+ final List presetList = new ArrayList();
+ final ChoiceBox cam = (prepend.equals("add")) ? addCamera : editCamera;
+ final ChoiceBox preset = (prepend.equals("add")) ? addPreset : editPreset;
+
+ cam.getSelectionModel().selectedItemProperty().addListener((obs, oldV, newV) -> {
+ presetList.clear();
+ // None option disabled till it is implemented in the backend.
+ //TODO presetList.add("None");
+
+ if (newV != null) {
+ preset.setDisable(false);
+
+ for (int i = 0; i < Camera.
+ getCamera(cam.getSelectionModel().getSelectedIndex()).getPresetAmount(); ++i) {
+ presetList.add(Integer.toString(i + 1));
+ }
+
+ preset.setItems(FXCollections.observableArrayList(presetList));
+ } else {
+ preset.setDisable(true);
+ }
+ });
+
+ addPreset.setDisable(true);
+ }
+
+ /**
+ * Sets the factories of the table columns, aka where they should
+ * get their value from.
+ */
+ private void setFactories() {
+ columnID.setCellValueFactory(
+ new PropertyValueFactory("number"));
+
+ columnShot.setCellValueFactory(
+ new PropertyValueFactory("shotId"));
+
+ columnCamera.setCellValueFactory(cellData ->
+ new ReadOnlyObjectWrapper<>(cellData.getValue().getCamera().getNumber() + 1));
+
+ columnPreset.setCellValueFactory(cellData -> {
+ if (cellData.getValue().getPreset() == null) {
+ return new ReadOnlyObjectWrapper<>();
+ } else {
+ return new ReadOnlyObjectWrapper<>(
+ Integer.toString(cellData.getValue().getPreset().getId() + 1));
+ }
+ });
+
+ columnDescription.setCellValueFactory(
+ new PropertyValueFactory("description"));
+
+ columnAction.setCellValueFactory(cellData ->
+ new ReadOnlyObjectWrapper<>(cellData.getValue()));
+
+ columnAction.setCellFactory(cellData -> new TableCell() {
+ final Button btnRemove = new Button("Remove");
+
+ @Override
+ protected void updateItem(Shot shot, boolean empty) {
+ super.updateItem(shot, empty);
+
+ if (shot == null) {
+ setGraphic(null);
+ return;
+ }
+
+ setGraphic(btnRemove);
+
+ btnRemove.setOnAction(event -> {
+ getTableView().getItems().remove(shot);
+ });
+ }
+ });
+ }
+
+ /**
+ * Sets the onAction for the add new camera button.
+ */
+ private void setAddButton() {
+ final ObservableList data = FXCollections.observableArrayList();
+
+ tableEvents.setItems(data);
+
+ btnAdd.setOnAction(event -> {
+ if (isValidInput()) {
+ addCamera.setStyle("");
+ addPreset.setStyle("");
+ addDescription.setStyle("");
+
+ if (!validateScript(data)
+ && !AlertDialog.confirmInvalidScriptAdding(
+ addCamera.getSelectionModel().getSelectedItem())) {
+ return;
+ }
+
+ Shot newShot = createNewShot();
+ data.add(newShot);
+
+ addShot.clear();
+ addCamera.getSelectionModel().clearSelection();
+ addPreset.getSelectionModel().clearSelection();
+ addDescription.clear();
+ }
+ });
+ }
+
+ /**
+ * Checks if the new shot being added to the script
+ * is valid.
+ *
+ * @return True iff it has no errors.
+ */
+ private boolean isValidInput() {
+ boolean isValid = true;
+
+ if (addCamera.getSelectionModel().isEmpty()) {
+ addCamera.setStyle(REDBORDER);
+ isValid = false;
+ }
+
+ if (addPreset.getSelectionModel().isEmpty()) {
+ addPreset.setStyle(REDBORDER);
+ isValid = false;
+ }
+
+ if (addDescription.getText().isEmpty()) {
+ addDescription.setStyle(REDBORDER);
+ isValid = false;
+ }
+
+ return isValid;
+ }
+
+ /**
+ * Checks if a newly created shot does not create an
+ * invalid script.
+ *
+ * @param data The table data.
+ * @return True if the script is valid, false otherwise.
+ */
+ private boolean validateScript(List data) {
+ if (data.isEmpty()) {
+ return true;
+ }
+
+ Shot last = data.get(data.size() - 1);
+
+ if (last.getCamera().getNumber()
+ == addCamera.getSelectionModel().getSelectedIndex()) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Creates a new shot based on the users' input.
+ * @return The newly created shot.
+ */
+ private Shot createNewShot() {
+ maximumId++;
+
+ if (addPreset.getSelectionModel().getSelectedItem().equals("None")) {
+ final Shot newShot = new Shot(
+ maximumId,
+ addShot.getText(),
+ Camera.getCamera(addCamera.getSelectionModel().getSelectedIndex()),
+ addDescription.getText()
+ );
+
+ return newShot;
+ } else {
+ final Shot newShot = new Shot(
+ maximumId,
+ addShot.getText(),
+ Camera.getCamera(addCamera.getSelectionModel().getSelectedIndex()),
+ Camera.getCamera(addCamera.getSelectionModel().getSelectedIndex())
+ .getPreset(new Integer(addPreset.getSelectionModel().getSelectedItem()) - 1),
+ addDescription.getText()
+ );
+
+ return newShot;
+ }
+ }
+
+ /**
+ * Sets the onAction for the back button.
+ */
+ private void setBackButton() {
+ btnBack.setOnAction(event -> {
+ if (!tableEvents.getItems().isEmpty() && !AlertDialog.confirmExiting()) {
+ return;
+ }
+
+ Script backup = new Script(backupList);
+ backup.setName(ContextTFP.getScript().getName());
+
+ ContextTFP.setScript(backup);
+ MenuController.show();
+ });
+ }
+
+ /**
+ * Sets the onAction for the save buttons.
+ */
+ private void setSaveButton() {
+ if (backupList.isEmpty()) {
+ btnSave.setDisable(true);
+ }
+
+ btnSave.setOnAction(event -> {
+ setSaveAction(event, false);
+ });
+
+ btnSaveAs.setOnAction(event -> {
+ setSaveAction(event, true);
+ });
+ }
+
+ /**
+ * Handles the saving of a file.
+ */
+ private void setSaveAction(ActionEvent event, boolean showDialog) {
+ final Script script = new Script(tableEvents.getItems());
+
+ if (!showValid(script, 1)) {
+ return;
+ }
+
+ File file;
+
+ if (showDialog) {
+ FileChooser fileChooser = new FileChooser();
+ fileChooser.setTitle("Save script");
+ fileChooser.setInitialFileName("script");
+ fileChooser.getExtensionFilters().add(new ExtensionFilter("XML (*.xml)", "*.xml"));
+
+ file = fileChooser.showSaveDialog(((Node) event.getTarget()).getScene().getWindow());
+ } else {
+ file = new File(SaveScript.getSaveLocation());
+ }
+
+ if (file != null) {
+ try {
+ SaveScript.setSaveLocation(file.getAbsolutePath());
+ SaveScript.save(script);
+
+ script.setName(file.getName());
+ ContextTFP.setScript(script);
+
+ AlertDialog.confirmExitingAfterSaving(file);
+ } catch (Exception e) {
+ AlertDialog.errorSaveUnsuccesful(e, file);
+ }
+ }
+ }
+
+ /**
+ * Checks if a script is valid and gives an error message when it isn't.
+ *
+ * @param level The level of alert. Should be 1 for CONFIRMATION
+ * or 2 for WARNING. Other values are ignored.
+ * @return True if the user wants to continue and ignore the error.
+ */
+ public static boolean showValid(Script script, int level) {
+ Shot error = script.isValid();
+
+ if (error != null) {
+ Alert alert = null;
+
+ if (level == 1) {
+ alert = AlertDialog.confirmInvalidScriptSaving(error);
+ } else if (level == 2) {
+ alert = AlertDialog.warningInvalidScriptLoading(error);
+ } else {
+ return true;
+ }
+
+ Optional result = alert.showAndWait();
+
+ if (result.get() == ButtonType.CANCEL) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
/**
* Allows for editable rows in the table. This method defines the
* necessary components for row by row editing of the table.
@@ -218,24 +527,24 @@ private void allowEditing() {
*/
private void initEditButtons() {
btnEditConfirm.setOnAction(event -> {
- boolean emptyField = false;
+ boolean isValid = true;
if (editCamera.getSelectionModel().isEmpty()) {
- editCamera.setStyle("-fx-border-color: red;");
- emptyField = true;
+ editCamera.setStyle(REDBORDER);
+ isValid = false;
}
if (editPreset.getSelectionModel().isEmpty()) {
- editPreset.setStyle("-fx-border-color: red;");
- emptyField = true;
+ editPreset.setStyle(REDBORDER);
+ isValid = false;
}
if (editDescription.getText().isEmpty()) {
- editDescription.setStyle("-fx-border-color: red;");
- emptyField = true;
+ editDescription.setStyle(REDBORDER);
+ isValid = false;
}
- if (!emptyField) {
+ if (isValid) {
editCamera.setStyle("");
editPreset.setStyle("");
editDescription.setStyle("");
@@ -261,7 +570,7 @@ private void initTable() {
editShot.setText(nv.getShotId());
editCamera.getSelectionModel().select(nv.getCamera().getNumber());
if (nv.getPreset() != null) {
- editPreset.getSelectionModel().select(nv.getPreset().getId()); //+1
+ editPreset.getSelectionModel().select(nv.getPreset().getId() + 1);
} else {
editPreset.getSelectionModel().select(0);
}
@@ -299,7 +608,7 @@ private void editConfirmAction(Shot shot) {
shot.setCamera(Camera.getCamera(editCamera.getSelectionModel().getSelectedIndex()));
if (!editPreset.getSelectionModel().getSelectedItem().equals("None")) {
shot.setPreset(Camera.getCamera(editCamera.getSelectionModel().getSelectedIndex())
- .getPreset(new Integer(editPreset.getSelectionModel().getSelectedIndex()))); //-1
+ .getPreset(new Integer(editPreset.getSelectionModel().getSelectedItem()) - 1));
} else {
shot.setPreset(null);
}
@@ -429,304 +738,6 @@ private EventHandler createDragDroppedHandler(TableCell cell
};
}
- /**
- * Fills the choiceboxes for selecting a camera, both the box that
- * adds a new camera as the box that is shown when editing a shot.
- */
- private void initCamera() {
- final List cameraList = new ArrayList();
-
- for (int i = 0; i < Camera.getCameraAmount(); ++i) {
- cameraList.add(i + 1);
- }
-
- addCamera.setItems(FXCollections.observableArrayList(cameraList));
- editCamera.setItems(FXCollections.observableArrayList(cameraList));
- }
-
- /**
- * Fills the choiceboxes for selecting a preset, given the selection
- * of a certain camera.
- */
- private void initPreset(String prepend) {
- final List presetList = new ArrayList();
- final ChoiceBox cam = (prepend.equals("add")) ? addCamera : editCamera;
- final ChoiceBox preset = (prepend.equals("add")) ? addPreset : editPreset;
-
- cam.getSelectionModel().selectedItemProperty().addListener((obs, oldV, newV) -> {
- presetList.clear();
- // None option disabled till it is implemented in the backend.
- //TODO presetList.add("None");
-
- if (newV != null) {
- preset.setDisable(false);
-
- for (int i = 0; i < Camera.
- getCamera(cam.getSelectionModel().getSelectedIndex()).getPresetAmount(); ++i) {
- presetList.add(Integer.toString(i + 1));
- }
-
- preset.setItems(FXCollections.observableArrayList(presetList));
- } else {
- preset.setDisable(true);
- }
- });
-
- addPreset.setDisable(true);
- }
-
- /**
- * Sets the factories of the table columns, aka where they should
- * get their value from.
- */
- private void setFactories() {
- columnID.setCellValueFactory(
- new PropertyValueFactory("number"));
-
- columnShot.setCellValueFactory(
- new PropertyValueFactory("shotId"));
-
- columnCamera.setCellValueFactory(cellData ->
- new ReadOnlyObjectWrapper<>(cellData.getValue().getCamera().getNumber() + 1));
-
- columnPreset.setCellValueFactory(cellData -> {
- if (cellData.getValue().getPreset() == null) {
- return new ReadOnlyObjectWrapper<>();
- } else {
- return new ReadOnlyObjectWrapper<>(
- Integer.toString(cellData.getValue().getPreset().getId() + 1));
- }
- });
-
- columnDescription.setCellValueFactory(
- new PropertyValueFactory("description"));
-
- columnAction.setCellValueFactory(cellData ->
- new ReadOnlyObjectWrapper<>(cellData.getValue()));
-
- columnAction.setCellFactory(cellData -> new TableCell() {
- final Button btnRemove = new Button("Remove");
-
- @Override
- protected void updateItem(Shot shot, boolean empty) {
- super.updateItem(shot, empty);
-
- if (shot == null) {
- setGraphic(null);
- return;
- }
-
- setGraphic(btnRemove);
-
- btnRemove.setOnAction(event -> {
- getTableView().getItems().remove(shot);
- });
- }
- });
- }
-
- /**
- * Sets the onAction for the add new camera button.
- */
- private void setAddButton() {
- final ObservableList data = FXCollections.observableArrayList();
-
- tableEvents.setItems(data);
-
- btnAdd.setOnAction(event -> {
- if (isValidInput()) {
- addCamera.setStyle("");
- addPreset.setStyle("");
- addDescription.setStyle("");
-
- maximumId++;
- createNewShot(data);
-
- addShot.clear();
- addCamera.getSelectionModel().clearSelection();
- addPreset.getSelectionModel().clearSelection();
- addDescription.clear();
- }
- });
- }
-
- /**
- * Checks if the new shot being added to the script
- * is valid.
- *
- * @return True if it has no errors.
- */
- private boolean isValidInput() {
- boolean isValid = true;
-
- if (addCamera.getSelectionModel().isEmpty()) {
- addCamera.setStyle("-fx-border-color: red;");
- isValid = false;
- }
-
- if (addPreset.getSelectionModel().isEmpty()) {
- addPreset.setStyle("-fx-border-color: red;");
- isValid = false;
- }
-
- if (addDescription.getText().isEmpty()) {
- addDescription.setStyle("-fx-border-color: red;");
- isValid = false;
- }
-
- return isValid;
- }
-
- /**
- * Creates a new shot based on the users' input.
- *
- * @param data The data already in the table.
- */
- private void createNewShot(ObservableList data) {
- if (addPreset.getSelectionModel().getSelectedItem().equals("None")) {
- final Shot newShot = new Shot(
- maximumId,
- addShot.getText(),
- Camera.getCamera(addCamera.getSelectionModel().getSelectedIndex()),
- addDescription.getText()
- );
-
- data.add(newShot);
- } else {
- final Shot newShot = new Shot(
- maximumId,
- addShot.getText(),
- Camera.getCamera(addCamera.getSelectionModel().getSelectedIndex()),
- Camera.getCamera(addCamera.getSelectionModel().getSelectedIndex())
- .getPreset(new Integer(addPreset.getSelectionModel().getSelectedItem()) - 1),
- addDescription.getText()
- );
-
- data.add(newShot);
- }
- }
-
- /**
- * Sets the onAction for the back button.
- */
- private void setBackButton() {
- btnBack.setOnAction(event -> {
- if (!tableEvents.getItems().isEmpty()) {
- Alert alert = new Alert(AlertType.CONFIRMATION);
- alert.setTitle("Confirm quitting");
- alert.setHeaderText("Exiting will erase any unsaved changes");
- alert.setContentText("Are you sure you want to quit? Any unsaved changes "
- + "will not be kept.");
-
- Optional result = alert.showAndWait();
-
- if (result.get() == ButtonType.CANCEL) {
- return;
- }
- }
-
- Script backup = new Script(backupList);
- backup.setName(ContextTFP.getScript().getName());
-
- ContextTFP.setScript(backup);
- MenuController.show();
- });
- }
-
- /**
- * Sets the onAction for the save buttons.
- */
- private void setSaveButton() {
- if (backupList.isEmpty()) {
- btnSave.setDisable(true);
- }
-
- btnSave.setOnAction(event -> {
- setSavePopup(event, false);
- });
-
- btnSaveAs.setOnAction(event -> {
- setSavePopup(event, true);
- });
- }
-
- /**
- * Handles the saving of a file.
- */
- private void setSavePopup(ActionEvent event, boolean showDialog) {
- final Script script = new Script(tableEvents.getItems());
-
- if (!script.showValid(1)) {
- return;
- }
-
- File file;
-
- if (showDialog) {
- FileChooser fileChooser = new FileChooser();
- fileChooser.setTitle("Save script");
- fileChooser.setInitialFileName("script");
- fileChooser.getExtensionFilters().add(new ExtensionFilter("XML (*.xml)", "*.xml"));
-
- file = fileChooser.showSaveDialog(((Node) event.getTarget()).getScene().getWindow());
- } else {
- file = new File(SaveScript.getSaveLocation());
- }
-
- if (file != null) {
- try {
- SaveScript.setSaveLocation(file.getAbsolutePath());
- SaveScript.save(script);
-
- script.setName(file.getName());
- ContextTFP.setScript(script);
-
- showConfirmExitDialog(file);
- } catch (Exception e) {
- showErrorDialog(e, file);
- }
- }
- }
-
- /**
- * Displays a confirm to exit dialog when the
- * script has been saved.
- *
- * @param file The file that has been saved.
- */
- private void showConfirmExitDialog(File file) {
- Alert alert = new Alert(AlertType.CONFIRMATION);
- alert.setTitle("Confirm exiting");
- alert.setHeaderText("Saving script was succesful!");
- alert.setContentText("Succesful save of script: "
- + file.getName()
- + " Do you want to quit to menu?");
-
- Optional result = alert.showAndWait();
-
- if (result.get() == ButtonType.OK) {
- MenuController.show();
- }
- }
-
- /**
- * Displayes an error dialog when saving of the script
- * was unsuccesful.
- *
- * @param file The file that was supposed to be saved.
- */
- private void showErrorDialog(Exception e, File file) {
- Alert alert = new Alert(AlertType.ERROR);
- alert.setTitle(e.getMessage());
- alert.setHeaderText("Saving script was unsuccesful!");
- alert.setContentText("Error when trying to save script at location: "
- + file.getAbsolutePath()
- + "\n\nError: "
- + e.getCause());
-
- alert.showAndWait();
- }
-
/**
* Calling this method shows this view in the middle of the rootLayout,
* forcing the current view to disappear.
diff --git a/src/main/java/nl/tudelft/contextproject/gui/CameraLiveController.java b/src/main/java/nl/tudelft/contextproject/gui/DirectorLiveController.java
similarity index 79%
rename from src/main/java/nl/tudelft/contextproject/gui/CameraLiveController.java
rename to src/main/java/nl/tudelft/contextproject/gui/DirectorLiveController.java
index 5f9fa07..181ece0 100644
--- a/src/main/java/nl/tudelft/contextproject/gui/CameraLiveController.java
+++ b/src/main/java/nl/tudelft/contextproject/gui/DirectorLiveController.java
@@ -11,66 +11,80 @@
import javafx.scene.layout.VBox;
import nl.tudelft.contextproject.ContextTFP;
+import nl.tudelft.contextproject.camera.Camera;
+import nl.tudelft.contextproject.presets.Preset;
import nl.tudelft.contextproject.script.Script;
import java.io.IOException;
/**
- * This class controls the live view of the camera.
+ * This class controls the screen that shows the live view
+ * of the {@link Camera} for the director. The director can use this screen
+ * to use the application during live production to get an overview
+ * of the live camera, a preview camera and the {@link Script}, along with controls
+ * to control the cameras and the {@link Preset Presets} set to these cameras.
+ *
+ *