From ea86da6b74517556f849ad77cacd6ae5182cb122 Mon Sep 17 00:00:00 2001
From: Simon Dietz
Date: Fri, 13 Dec 2024 19:14:16 +0100
Subject: [PATCH 01/15] Refactor BevelVerticesModifier for Improved Clarity and
Workflow Separation
- Split the beveling workflow into clear, modular methods for better
readability.
- Added `modifyWorkflow()` to encapsulate the entire beveling process
sequence.
- Improved edge point creation with dedicated logic in
`generateEdgePointsForFaces`.
- Introduced `clear()` to reset all related data structures before
processing.
- Updated traversal logic to ensure edge processing is more structured
and efficient.
- Removed redundant utility methods in favor of streamlined logic with
clearer names.
- Enhanced error handling with checks (e.g., null checks for meshes).
- Improved the use of helper methods (`toReverseArray`) for geometry
transformations.
---
.../mesh/modifier/BevelVerticesModifier.java | 323 +++++++++++++-----
1 file changed, 238 insertions(+), 85 deletions(-)
diff --git a/src/main/java/mesh/modifier/BevelVerticesModifier.java b/src/main/java/mesh/modifier/BevelVerticesModifier.java
index fb871512..c1729b72 100644
--- a/src/main/java/mesh/modifier/BevelVerticesModifier.java
+++ b/src/main/java/mesh/modifier/BevelVerticesModifier.java
@@ -3,7 +3,7 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
-import java.util.Vector;
+import java.util.Map;
import math.Vector3f;
import mesh.Edge3D;
@@ -11,159 +11,312 @@
import mesh.Mesh3D;
import mesh.util.TraverseHelper;
+/**
+ * This class modifies a 3D mesh by beveling its vertices.
+ *
+ *
+ * The beveling process creates new vertices along the edges of the mesh and
+ * generates new faces to connect these vertices, resulting in a chamfered
+ * effect.
+ *
+ *
+ *
+ * This implementation supports basic vertex beveling with a customizable bevel
+ * amount.
+ *
+ */
public class BevelVerticesModifier implements IMeshModifier {
+ /**
+ * The default bevel amount used if no custom amount is specified during
+ * instantiation. This determines the default intensity of the bevel effect
+ * applied to the mesh edges.
+ */
+ private static final float DEFAULT_AMOUNT = 0.1f;
+
+ /**
+ * The amount of bevel to apply to the vertices and edges of the mesh. This
+ * value defines how much the edges are chamfered.
+ */
private float amount;
+ /**
+ * The 3D mesh to be modified by this class.
+ */
private Mesh3D mesh;
+ /**
+ * A list of new vertices generated during the beveling process.
+ */
private List verticesToAdd;
+ /**
+ * A list of new faces to be added to the mesh to form the bevel effect.
+ */
private List facesToAdd;
- private HashMap edgeToEdgePointIndex;
-
+ /**
+ * A map connecting edges to their corresponding new beveled vertex indices.
+ * This is used to efficiently track which new vertices are associated with
+ * specific edges, ensuring the mesh geometry is modified correctly.
+ */
+ private Map edgeToEdgePointIndex;
+
+ /**
+ * A map that tracks unique vertices (edge points) to their corresponding
+ * index. This ensures that vertices are reused rather than duplicated during
+ * the beveling process, maintaining the mesh's geometric integrity and
+ * avoiding unnecessary computations.
+ */
+ private Map vertexIndexMap;
+
+ /**
+ * Default constructor with a predefined bevel amount of 0.1.
+ */
public BevelVerticesModifier() {
- this(0.1f);
+ this(DEFAULT_AMOUNT);
}
+ /**
+ * Constructs a new BevelVerticesModifier with a custom bevel amount.
+ *
+ * @param amount The amount to bevel. Must be positive.
+ * @throws IllegalArgumentException if the bevel amount is less than or equal
+ * to zero.
+ */
public BevelVerticesModifier(float amount) {
+ if (amount <= 0) {
+ throw new IllegalArgumentException("Bevel amount must be positive.");
+ }
this.amount = amount;
- verticesToAdd = new ArrayList();
- facesToAdd = new ArrayList();
- edgeToEdgePointIndex = new HashMap();
+ this.verticesToAdd = new ArrayList<>();
+ this.facesToAdd = new ArrayList<>();
+ this.edgeToEdgePointIndex = new HashMap<>();
+ this.vertexIndexMap = new HashMap<>();
}
+ /**
+ * Modifies the given mesh by applying the beveling workflow.
+ *
+ * @param mesh The 3D mesh to be modified.
+ * @return The modified mesh after applying the bevel.
+ * @throws IllegalArgumentException if the mesh is null.
+ */
@Override
public Mesh3D modify(Mesh3D mesh) {
+ if (mesh == null) {
+ throw new IllegalArgumentException("Mesh cannot be null.");
+ }
+ modifyWorkflow(mesh);
+ return mesh;
+ }
+
+ /**
+ * Runs the entire beveling workflow, including edge point generation, face
+ * creation, clearing old geometry, and adding new geometry.
+ *
+ * @param mesh The 3D mesh to modify during the workflow.
+ */
+ private void modifyWorkflow(Mesh3D mesh) {
clear();
setMesh(mesh);
- createEdgePoints();
- createFacesForVerticesAroundOldVertex();
- removeOldFaces();
- removeOldVertices();
- addNewVertices();
- addNewFaces();
- return mesh;
+ generateEdgePointsForFaces();
+ createFacesAroundVertices();
+ removeOldFacesAndVertices();
+ addNewVerticesAndFaces();
}
- private void createEdgePointsOf(Face3D face) {
- Vector indices = new Vector();
+ /**
+ * Generates edge points for all faces in the mesh.
+ */
+ private void generateEdgePointsForFaces() {
+ for (Face3D face : mesh.faces) {
+ generateEdgePointsForFace(face);
+ }
+ }
+ /**
+ * Generates edge points for a single face and maps them for further
+ * processing.
+ *
+ * @param face The face to process edge points for.
+ */
+ private void generateEdgePointsForFace(Face3D face) {
+ int[] indices = new int[face.indices.length * 2];
for (int i = 0; i < face.indices.length; i++) {
+ int index = i * 2;
Vector3f from = getVertexForIndexAt(face, i);
Vector3f to = getVertexForIndexAt(face, i + 1);
- Vector3f edgePointFrom = calculateEdgePoint(from, to);
- Vector3f edgePointTo = calculateEdgePoint(to, from);
-
- addEdgePoint(edgePointFrom);
- addEdgePoint(edgePointTo);
+ indices[index] = addEdgePoint(calculateEdgePoint(to, from));
+ indices[index + 1] = addEdgePoint(calculateEdgePoint(from, to));
- int edgePointFromIndex = indexOf(edgePointFrom);
- int edgePointToIndex = indexOf(edgePointTo);
-
- indices.add(edgePointToIndex);
- indices.add(edgePointFromIndex);
-
- Edge3D edge = new Edge3D(getIndexAt(face, i), getIndexAt(face, i + 1));
- edgeToEdgePointIndex.put(edge, edgePointToIndex);
+ mapEdgeToEdgePointIndex(face, i, indices[index]);
}
-
- addFace(toArray(indices));
+ addFace(indices);
}
- private Vector3f calculateEdgePoint(Vector3f from, Vector3f to) {
- return from.subtract(to).mult(amount).add(to);
+ /**
+ * Maps edge points to their corresponding indices for quick lookup.
+ *
+ * @param face The face associated with the edge.
+ * @param i The index of the edge in the face.
+ * @param index The computed index for the edge.
+ */
+ private void mapEdgeToEdgePointIndex(Face3D face, int i, int index) {
+ Edge3D edge = new Edge3D(getIndexAt(face, i), getIndexAt(face, i + 1));
+ edgeToEdgePointIndex.put(edge, index);
}
- private void createFacesForVerticesAroundOldVertex() {
+ /**
+ * Creates new faces by connecting edge points around vertices in the mesh.
+ */
+ private void createFacesAroundVertices() {
TraverseHelper helper = new TraverseHelper(mesh);
for (int i = 0; i < mesh.getVertexCount(); i++) {
- Edge3D outgoingEdge = helper.getOutgoing(i);
- Edge3D edge = outgoingEdge;
- Vector indices = new Vector();
- do {
- int index = edgeToEdgePointIndex.get(edge);
- indices.add(index);
- edge = helper.getPairNext(edge.fromIndex, edge.toIndex);
- } while (!outgoingEdge.equals(edge));
- facesToAdd.add(new Face3D(toReverseArray(indices)));
+ List indices = collectEdgePointsAroundVertex(helper, i);
+ if (!indices.isEmpty()) {
+ facesToAdd.add(new Face3D(toReverseArray(indices)));
+ }
}
}
- private int[] toArray(Vector values) {
- int[] a = new int[values.size()];
- for (int j = 0; j < a.length; j++) {
- a[j] = values.get(j);
- }
- return a;
+ /**
+ * Collects edge points surrounding a specific vertex using traversal logic.
+ *
+ * @param helper The traversal helper instance.
+ * @param vertexIndex The index of the vertex to process.
+ * @return A list of edge indices surrounding the vertex.
+ */
+ private List collectEdgePointsAroundVertex(TraverseHelper helper,
+ int vertexIndex) {
+ Edge3D outgoingEdge = helper.getOutgoing(vertexIndex);
+ Edge3D edge = outgoingEdge;
+ List indices = new ArrayList<>();
+
+ do {
+ int index = edgeToEdgePointIndex.get(edge);
+ indices.add(index);
+ edge = helper.getPairNext(edge.fromIndex, edge.toIndex);
+ } while (!outgoingEdge.equals(edge));
+
+ return indices;
}
- private int[] toReverseArray(Vector values) {
- int[] a = new int[values.size()];
- for (int j = 0; j < a.length; j++) {
- int index = a.length - j - 1;
- a[index] = values.get(j);
+ /**
+ * Adds a new edge point to the list or retrieves the index if it already
+ * exists.
+ *
+ * @param edgePoint The edge point to add.
+ * @return The index of the edge point.
+ */
+ private int addEdgePoint(Vector3f edgePoint) {
+ if (!vertexIndexMap.containsKey(edgePoint)) {
+ vertexIndexMap.put(edgePoint, verticesToAdd.size());
+ verticesToAdd.add(edgePoint);
}
- return a;
- }
-
- private void clear() {
- verticesToAdd.clear();
- facesToAdd.clear();
- edgeToEdgePointIndex.clear();
+ return vertexIndexMap.get(edgePoint);
}
- private void removeOldVertices() {
- mesh.vertices.clear();
- }
-
- private void removeOldFaces() {
+ /**
+ * Clears out old faces and vertices from the mesh.
+ */
+ private void removeOldFacesAndVertices() {
mesh.faces.clear();
+ mesh.vertices.clear();
}
- private void addNewVertices() {
+ /**
+ * Adds newly computed vertices and faces to the mesh.
+ */
+ private void addNewVerticesAndFaces() {
mesh.vertices.addAll(verticesToAdd);
- }
-
- private void addNewFaces() {
mesh.faces.addAll(facesToAdd);
}
- private void createEdgePoints() {
- for (Face3D face : mesh.faces)
- createEdgePointsOf(face);
- }
-
+ /**
+ * Adds a new face to the list of faces to be added to the mesh.
+ *
+ * @param indices The indices defining the new face.
+ */
private void addFace(int[] indices) {
facesToAdd.add(new Face3D(indices));
}
+ /**
+ * Calculates a new edge point based on a linear interpolation with the given
+ * bevel amount.
+ *
+ * @param from The starting vertex.
+ * @param to The ending vertex.
+ * @return The calculated edge point.
+ */
+ private Vector3f calculateEdgePoint(Vector3f from, Vector3f to) {
+ return from.subtract(to).mult(amount).add(to);
+ }
+
+ /**
+ * Retrieves the index of the vertex at the specified position in the face's
+ * indices list, with support for circular indexing by wrapping around when
+ * necessary.
+ *
+ * @param face The face from which to retrieve the index. Must not be null.
+ * @param i The position of the index to retrieve within the face's
+ * indices.
+ * @return The vertex index at the specified position, with wrapping support.
+ */
private int getIndexAt(Face3D face, int i) {
return face.indices[i % face.indices.length];
}
+ /**
+ * Retrieves the actual 3D vertex (as a Vector3f) associated with the
+ * specified index in the face's indices list. This maps the index to the
+ * corresponding vertex in the provided mesh.
+ *
+ * @param face The face whose index to map to a vertex. Must not be null.
+ * @param i The index position within the face's indices.
+ * @return The 3D vertex (Vector3f) corresponding to the index.
+ */
private Vector3f getVertexForIndexAt(Face3D face, int i) {
int index = getIndexAt(face, i);
return mesh.getVertexAt(index);
}
- private void addEdgePoint(Vector3f edgePoint) {
- if (!contains(edgePoint))
- verticesToAdd.add(edgePoint);
- }
-
- private boolean contains(Vector3f v) {
- return verticesToAdd.contains(v);
+ /**
+ * Reverses the order of integers in the provided list and converts it to an
+ * array. This is used to reverse traversal or ordering logic in certain
+ * geometric calculations.
+ *
+ * @param values The list of integer indices to reverse.
+ * @return A new integer array with the order of elements reversed compared to
+ * the input list.
+ */
+ private int[] toReverseArray(List values) {
+ int[] a = new int[values.size()];
+ for (int j = 0; j < a.length; j++) {
+ a[j] = values.get(values.size() - 1 - j);
+ }
+ return a;
}
- private int indexOf(Vector3f v) {
- return verticesToAdd.indexOf(v);
+ /**
+ * Clears the old data structures related to the beveling process.
+ */
+ private void clear() {
+ verticesToAdd.clear();
+ facesToAdd.clear();
+ edgeToEdgePointIndex.clear();
+ vertexIndexMap.clear();
}
+ /**
+ * Sets the mesh to be modified during the workflow.
+ *
+ * @param mesh The mesh to work on.
+ */
private void setMesh(Mesh3D mesh) {
this.mesh = mesh;
}
-}
+}
\ No newline at end of file
From 5b8cf0d4d28ab3ebdf7c7f9633cf5d69a5bba5e5 Mon Sep 17 00:00:00 2001
From: Simon Dietz
Date: Sat, 14 Dec 2024 07:45:39 +0100
Subject: [PATCH 02/15] Format changes.
---
.../workspace/command/AbstractKeyCommand.java | 56 +++++++++----------
.../command/AbstractWorkspaceKeyCommand.java | 20 +++----
.../java/workspace/command/KeyCommand.java | 10 ++--
.../java/workspace/command/KeyCommandMap.java | 34 +++++------
.../command/ResetPanningCommand.java | 20 +++----
.../command/ShadeSmoothFlatCommand.java | 23 ++++----
.../command/ShowHideEdgesCommand.java | 18 +++---
.../command/ShowHideFaceNormalsCommand.java | 18 +++---
.../command/ShowHideGridCommand.java | 18 +++---
.../command/ShowHideSideBarCommand.java | 18 +++---
.../command/ShowHideVertexNormalsCommand.java | 19 +++----
.../command/ShowHideXAxisCommand.java | 18 +++---
.../command/ShowHideYAxisCommand.java | 18 +++---
.../command/ShowHideZAxisCommand.java | 18 +++---
.../workspace/command/WireframeCommand.java | 18 +++---
.../ui/border/{IBorder.java => Border.java} | 0
16 files changed, 162 insertions(+), 164 deletions(-)
rename src/main/java/workspace/ui/border/{IBorder.java => Border.java} (100%)
diff --git a/src/main/java/workspace/command/AbstractKeyCommand.java b/src/main/java/workspace/command/AbstractKeyCommand.java
index 6c31d7ef..f422604a 100644
--- a/src/main/java/workspace/command/AbstractKeyCommand.java
+++ b/src/main/java/workspace/command/AbstractKeyCommand.java
@@ -2,43 +2,43 @@
public abstract class AbstractKeyCommand implements KeyCommand {
- private char key;
+ private char key;
- private boolean enabled;
+ private boolean enabled;
- private String name;
+ private String name;
- public AbstractKeyCommand() {
- setEnabled(true);
- }
+ public AbstractKeyCommand() {
+ setEnabled(true);
+ }
- @Override
- public abstract void execute();
+ @Override
+ public abstract void execute();
- @Override
- public String getName() {
- return name;
- }
+ @Override
+ public String getName() {
+ return name;
+ }
- public void setName(String name) {
- this.name = name;
- }
+ public void setName(String name) {
+ this.name = name;
+ }
- @Override
- public char getKey() {
- return key;
- }
+ @Override
+ public char getKey() {
+ return key;
+ }
- public void setKey(char key) {
- this.key = key;
- }
+ public void setKey(char key) {
+ this.key = key;
+ }
- public boolean isEnabled() {
- return enabled;
- }
+ public boolean isEnabled() {
+ return enabled;
+ }
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- }
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
}
diff --git a/src/main/java/workspace/command/AbstractWorkspaceKeyCommand.java b/src/main/java/workspace/command/AbstractWorkspaceKeyCommand.java
index 596f373a..af57c3b1 100644
--- a/src/main/java/workspace/command/AbstractWorkspaceKeyCommand.java
+++ b/src/main/java/workspace/command/AbstractWorkspaceKeyCommand.java
@@ -4,18 +4,18 @@
public abstract class AbstractWorkspaceKeyCommand extends AbstractKeyCommand {
- private WorkspaceModel model;
+ private WorkspaceModel model;
- public AbstractWorkspaceKeyCommand(WorkspaceModel model) {
- this.model = model;
- }
+ public AbstractWorkspaceKeyCommand(WorkspaceModel model) {
+ this.model = model;
+ }
- public WorkspaceModel getModel() {
- return model;
- }
+ public WorkspaceModel getModel() {
+ return model;
+ }
- public void setModel(WorkspaceModel model) {
- this.model = model;
- }
+ public void setModel(WorkspaceModel model) {
+ this.model = model;
+ }
}
diff --git a/src/main/java/workspace/command/KeyCommand.java b/src/main/java/workspace/command/KeyCommand.java
index 533fef12..9ee728d4 100644
--- a/src/main/java/workspace/command/KeyCommand.java
+++ b/src/main/java/workspace/command/KeyCommand.java
@@ -2,14 +2,14 @@
public interface KeyCommand {
- void execute();
+ void execute();
- String getName();
+ String getName();
- char getKey();
+ char getKey();
- void setEnabled(boolean enabled);
+ void setEnabled(boolean enabled);
- boolean isEnabled();
+ boolean isEnabled();
}
diff --git a/src/main/java/workspace/command/KeyCommandMap.java b/src/main/java/workspace/command/KeyCommandMap.java
index 3d1e289e..2f72edaf 100644
--- a/src/main/java/workspace/command/KeyCommandMap.java
+++ b/src/main/java/workspace/command/KeyCommandMap.java
@@ -4,28 +4,28 @@
public class KeyCommandMap {
- private HashMap commands;
+ private HashMap commands;
- public KeyCommandMap() {
- this.commands = new HashMap();
- }
+ public KeyCommandMap() {
+ this.commands = new HashMap();
+ }
- public void register(KeyCommand command) {
- commands.put(command.getKey(), command);
- }
+ public void register(KeyCommand command) {
+ commands.put(command.getKey(), command);
+ }
- public void execute(char key) {
- if (!commands.containsKey(key))
- return;
+ public void execute(char key) {
+ if (!commands.containsKey(key))
+ return;
- KeyCommand command = commands.get(key);
+ KeyCommand command = commands.get(key);
- if (command.isEnabled())
- command.execute();
- }
+ if (command.isEnabled())
+ command.execute();
+ }
- public KeyCommand getCommand(char key) {
- return commands.get(key);
- }
+ public KeyCommand getCommand(char key) {
+ return commands.get(key);
+ }
}
diff --git a/src/main/java/workspace/command/ResetPanningCommand.java b/src/main/java/workspace/command/ResetPanningCommand.java
index c418d07c..936ab57a 100644
--- a/src/main/java/workspace/command/ResetPanningCommand.java
+++ b/src/main/java/workspace/command/ResetPanningCommand.java
@@ -4,16 +4,16 @@
public class ResetPanningCommand extends AbstractWorkspaceKeyCommand {
- public ResetPanningCommand(WorkspaceModel model) {
- super(model);
- setName("Reset Panning");
- setKey('c');
- }
+ public ResetPanningCommand(WorkspaceModel model) {
+ super(model);
+ setName("Reset Panning");
+ setKey('c');
+ }
- @Override
- public void execute() {
- getModel().setPanningX(0);
- getModel().setPanningY(0);
- }
+ @Override
+ public void execute() {
+ getModel().setPanningX(0);
+ getModel().setPanningY(0);
+ }
}
diff --git a/src/main/java/workspace/command/ShadeSmoothFlatCommand.java b/src/main/java/workspace/command/ShadeSmoothFlatCommand.java
index 5b68218b..47e0cba8 100644
--- a/src/main/java/workspace/command/ShadeSmoothFlatCommand.java
+++ b/src/main/java/workspace/command/ShadeSmoothFlatCommand.java
@@ -5,18 +5,17 @@
public class ShadeSmoothFlatCommand extends AbstractWorkspaceKeyCommand {
- public ShadeSmoothFlatCommand(WorkspaceModel model) {
- super(model);
- setName("Shade Smooth");
- setKey('s');
- }
+ public ShadeSmoothFlatCommand(WorkspaceModel model) {
+ super(model);
+ setName("Shade Smooth");
+ setKey('s');
+ }
- @Override
- public void execute() {
- getModel().setShading(
- getModel().getShading() == Shading.SMOOTH ? Shading.FLAT
- : Shading.SMOOTH
- );
- }
+ @Override
+ public void execute() {
+ getModel()
+ .setShading(getModel().getShading() == Shading.SMOOTH ? Shading.FLAT
+ : Shading.SMOOTH);
+ }
}
diff --git a/src/main/java/workspace/command/ShowHideEdgesCommand.java b/src/main/java/workspace/command/ShowHideEdgesCommand.java
index b4834682..bdbaf0dd 100644
--- a/src/main/java/workspace/command/ShowHideEdgesCommand.java
+++ b/src/main/java/workspace/command/ShowHideEdgesCommand.java
@@ -4,15 +4,15 @@
public class ShowHideEdgesCommand extends AbstractWorkspaceKeyCommand {
- public ShowHideEdgesCommand(WorkspaceModel model) {
- super(model);
- setName("Edges");
- setKey('e');
- }
+ public ShowHideEdgesCommand(WorkspaceModel model) {
+ super(model);
+ setName("Edges");
+ setKey('e');
+ }
- @Override
- public void execute() {
- getModel().setEdgesVisible(!getModel().isEdgesVisible());
- }
+ @Override
+ public void execute() {
+ getModel().setEdgesVisible(!getModel().isEdgesVisible());
+ }
}
diff --git a/src/main/java/workspace/command/ShowHideFaceNormalsCommand.java b/src/main/java/workspace/command/ShowHideFaceNormalsCommand.java
index ddb92efb..dc334b83 100644
--- a/src/main/java/workspace/command/ShowHideFaceNormalsCommand.java
+++ b/src/main/java/workspace/command/ShowHideFaceNormalsCommand.java
@@ -4,15 +4,15 @@
public class ShowHideFaceNormalsCommand extends AbstractWorkspaceKeyCommand {
- public ShowHideFaceNormalsCommand(WorkspaceModel model) {
- super(model);
- setName("Face Normals");
- setKey('n');
- }
+ public ShowHideFaceNormalsCommand(WorkspaceModel model) {
+ super(model);
+ setName("Face Normals");
+ setKey('n');
+ }
- @Override
- public void execute() {
- getModel().setFaceNormalsVisible(!getModel().isFaceNormalsVisible());
- }
+ @Override
+ public void execute() {
+ getModel().setFaceNormalsVisible(!getModel().isFaceNormalsVisible());
+ }
}
diff --git a/src/main/java/workspace/command/ShowHideGridCommand.java b/src/main/java/workspace/command/ShowHideGridCommand.java
index 9c3e2307..d8f88b7a 100644
--- a/src/main/java/workspace/command/ShowHideGridCommand.java
+++ b/src/main/java/workspace/command/ShowHideGridCommand.java
@@ -4,15 +4,15 @@
public class ShowHideGridCommand extends AbstractWorkspaceKeyCommand {
- public ShowHideGridCommand(WorkspaceModel model) {
- super(model);
- setName("Grid");
- setKey('g');
- }
+ public ShowHideGridCommand(WorkspaceModel model) {
+ super(model);
+ setName("Grid");
+ setKey('g');
+ }
- @Override
- public void execute() {
- getModel().setGridVisible(!getModel().isGridVisible());
- }
+ @Override
+ public void execute() {
+ getModel().setGridVisible(!getModel().isGridVisible());
+ }
}
diff --git a/src/main/java/workspace/command/ShowHideSideBarCommand.java b/src/main/java/workspace/command/ShowHideSideBarCommand.java
index b81a1095..6fa28593 100644
--- a/src/main/java/workspace/command/ShowHideSideBarCommand.java
+++ b/src/main/java/workspace/command/ShowHideSideBarCommand.java
@@ -4,15 +4,15 @@
public class ShowHideSideBarCommand extends AbstractWorkspaceKeyCommand {
- public ShowHideSideBarCommand(WorkspaceModel model) {
- super(model);
- setName("Sidebar");
- setKey('y');
- }
+ public ShowHideSideBarCommand(WorkspaceModel model) {
+ super(model);
+ setName("Sidebar");
+ setKey('y');
+ }
- @Override
- public void execute() {
- getModel().setUiVisible(!getModel().isUiVisible());
- }
+ @Override
+ public void execute() {
+ getModel().setUiVisible(!getModel().isUiVisible());
+ }
}
diff --git a/src/main/java/workspace/command/ShowHideVertexNormalsCommand.java b/src/main/java/workspace/command/ShowHideVertexNormalsCommand.java
index 72243046..4c7d5fb2 100644
--- a/src/main/java/workspace/command/ShowHideVertexNormalsCommand.java
+++ b/src/main/java/workspace/command/ShowHideVertexNormalsCommand.java
@@ -4,16 +4,15 @@
public class ShowHideVertexNormalsCommand extends AbstractWorkspaceKeyCommand {
- public ShowHideVertexNormalsCommand(WorkspaceModel model) {
- super(model);
- setName("Vertex Normals");
- setKey('v');
- }
+ public ShowHideVertexNormalsCommand(WorkspaceModel model) {
+ super(model);
+ setName("Vertex Normals");
+ setKey('v');
+ }
- @Override
- public void execute() {
- getModel()
- .setVertexNormalsVisible(!getModel().isVertexNormalsVisible());
- }
+ @Override
+ public void execute() {
+ getModel().setVertexNormalsVisible(!getModel().isVertexNormalsVisible());
+ }
}
diff --git a/src/main/java/workspace/command/ShowHideXAxisCommand.java b/src/main/java/workspace/command/ShowHideXAxisCommand.java
index a5855fe9..43a06732 100644
--- a/src/main/java/workspace/command/ShowHideXAxisCommand.java
+++ b/src/main/java/workspace/command/ShowHideXAxisCommand.java
@@ -4,15 +4,15 @@
public class ShowHideXAxisCommand extends AbstractWorkspaceKeyCommand {
- public ShowHideXAxisCommand(WorkspaceModel model) {
- super(model);
- setName("X-Axis");
- setKey('1');
- }
+ public ShowHideXAxisCommand(WorkspaceModel model) {
+ super(model);
+ setName("X-Axis");
+ setKey('1');
+ }
- @Override
- public void execute() {
- getModel().setxAxisVisible(!getModel().isxAxisVisible());
- }
+ @Override
+ public void execute() {
+ getModel().setxAxisVisible(!getModel().isxAxisVisible());
+ }
}
diff --git a/src/main/java/workspace/command/ShowHideYAxisCommand.java b/src/main/java/workspace/command/ShowHideYAxisCommand.java
index e74d3b39..78df6d31 100644
--- a/src/main/java/workspace/command/ShowHideYAxisCommand.java
+++ b/src/main/java/workspace/command/ShowHideYAxisCommand.java
@@ -4,15 +4,15 @@
public class ShowHideYAxisCommand extends AbstractWorkspaceKeyCommand {
- public ShowHideYAxisCommand(WorkspaceModel model) {
- super(model);
- setName("Y-Axis");
- setKey('2');
- }
+ public ShowHideYAxisCommand(WorkspaceModel model) {
+ super(model);
+ setName("Y-Axis");
+ setKey('2');
+ }
- @Override
- public void execute() {
- getModel().setyAxisVisible(!getModel().isyAxisVisible());
- }
+ @Override
+ public void execute() {
+ getModel().setyAxisVisible(!getModel().isyAxisVisible());
+ }
}
diff --git a/src/main/java/workspace/command/ShowHideZAxisCommand.java b/src/main/java/workspace/command/ShowHideZAxisCommand.java
index 9e450c54..62c1b97b 100644
--- a/src/main/java/workspace/command/ShowHideZAxisCommand.java
+++ b/src/main/java/workspace/command/ShowHideZAxisCommand.java
@@ -4,15 +4,15 @@
public class ShowHideZAxisCommand extends AbstractWorkspaceKeyCommand {
- public ShowHideZAxisCommand(WorkspaceModel model) {
- super(model);
- setName("Z-Axis");
- setKey('3');
- }
+ public ShowHideZAxisCommand(WorkspaceModel model) {
+ super(model);
+ setName("Z-Axis");
+ setKey('3');
+ }
- @Override
- public void execute() {
- getModel().setzAxisVisible(!getModel().iszAxisVisible());
- }
+ @Override
+ public void execute() {
+ getModel().setzAxisVisible(!getModel().iszAxisVisible());
+ }
}
diff --git a/src/main/java/workspace/command/WireframeCommand.java b/src/main/java/workspace/command/WireframeCommand.java
index 92b38d95..d2442ff4 100644
--- a/src/main/java/workspace/command/WireframeCommand.java
+++ b/src/main/java/workspace/command/WireframeCommand.java
@@ -4,15 +4,15 @@
public class WireframeCommand extends AbstractWorkspaceKeyCommand {
- public WireframeCommand(WorkspaceModel model) {
- super(model);
- setName("Wireframe");
- setKey('z');
- }
+ public WireframeCommand(WorkspaceModel model) {
+ super(model);
+ setName("Wireframe");
+ setKey('z');
+ }
- @Override
- public void execute() {
- getModel().setWireframe(!getModel().isWireframe());
- }
+ @Override
+ public void execute() {
+ getModel().setWireframe(!getModel().isWireframe());
+ }
}
diff --git a/src/main/java/workspace/ui/border/IBorder.java b/src/main/java/workspace/ui/border/Border.java
similarity index 100%
rename from src/main/java/workspace/ui/border/IBorder.java
rename to src/main/java/workspace/ui/border/Border.java
From 9775ed1e3fb78e638a6591ae045fbd623978e54a Mon Sep 17 00:00:00 2001
From: Simon Dietz
Date: Sat, 14 Dec 2024 07:55:01 +0100
Subject: [PATCH 03/15] Format changes.
---
.../java/workspace/WorkspaceSideBarUi.java | 576 +++++++++---------
1 file changed, 286 insertions(+), 290 deletions(-)
diff --git a/src/main/java/workspace/WorkspaceSideBarUi.java b/src/main/java/workspace/WorkspaceSideBarUi.java
index acf581a1..66435b60 100644
--- a/src/main/java/workspace/WorkspaceSideBarUi.java
+++ b/src/main/java/workspace/WorkspaceSideBarUi.java
@@ -11,295 +11,291 @@
public class WorkspaceSideBarUi extends UiComponent implements ModelListener {
- private int xOffset = 10;
-
- private int yOffset = 65;
-
- private UiCheckBox gridCheckBox;
-
- private UiCheckBox faceNormalsCheckBox;
-
- private UiCheckBox vertexNormalsCheckBox;
-
- private UiCheckBox wireFrameCheckBox;
-
- private UiCheckBox xAxisCheckBox;
-
- private UiCheckBox yAxisCheckBox;
-
- private UiCheckBox zAxisCheckBox;
-
- private UiCheckBox edgeCheckBox;
-
- private UiCheckBox smoothShadingCheckBox;
-
- private UiCheckBox loopCheckBox;
-
- private UiLabel label;
-
- private WorkspaceModel model;
-
- public WorkspaceSideBarUi(WorkspaceModel model) {
- this.model = model;
- this.model.addListener(this);
- createUI();
- }
-
- @Override
- public void onModelChanged() {
- gridCheckBox.setSelected(model.isGridVisible());
- faceNormalsCheckBox.setSelected(model.isFaceNormalsVisible());
- vertexNormalsCheckBox.setSelected(model.isVertexNormalsVisible());
- wireFrameCheckBox.setSelected(model.isWireframe());
- xAxisCheckBox.setSelected(model.isxAxisVisible());
- yAxisCheckBox.setSelected(model.isyAxisVisible());
- zAxisCheckBox.setSelected(model.iszAxisVisible());
- edgeCheckBox.setSelected(model.isEdgesVisible());
- smoothShadingCheckBox.setSelected(model.getShading() == Shading.SMOOTH);
- loopCheckBox.setSelected(model.isLoop());
- }
-
- private void createUI() {
- UiPanel panel = new UiPanel();
- panel.setWidth(200);
- panel.setHeight(500);
- panel.setBackground(new Color(77, 77, 77, 0));
- panel.add(getUiLabel());
- panel.add(getGridCheckBox());
- panel.add(getFaceNormalsCheckBox());
- panel.add(getVertexNormalsCheckBox());
- panel.add(getWireFrameCheckBox());
- panel.add(getXAxisCheckBox());
- panel.add(getYAxisCheckBox());
- panel.add(getZAxisCheckBox());
- panel.add(getEdgeCheckBox());
- panel.add(getSmoothShadingCheckBox());
- panel.add(getLoopCheckBox());
- add(panel);
- }
-
- protected UiLabel getUiLabel() {
- if (label != null)
- return label;
-
- label = new UiLabel();
- label.setX(xOffset);
- label.setY(yOffset);
- label.setTitle("Controls:");
- label.setBackground(new Color(0, 0, 0, 0));
- label.setForeground(UiValues.UI_ELEMENT_FOREGROUND);
- return label;
- }
-
- protected UiCheckBox getGridCheckBox() {
- if (gridCheckBox != null)
- return gridCheckBox;
-
- gridCheckBox = new UiCheckBox("Grid (G)");
- gridCheckBox.setX(xOffset);
- gridCheckBox.setY(yOffset + 20);
- gridCheckBox.setSelected(model.isGridVisible());
- gridCheckBox.setForeground(UiValues.UI_ELEMENT_FOREGROUND);
- gridCheckBox.setActionListener(new IActionListener() {
-
- @Override
- public void onActionPerformed() {
- model.setGridVisible(gridCheckBox.isSelected());
- }
- });
-
- return gridCheckBox;
- }
-
- protected UiCheckBox getFaceNormalsCheckBox() {
- if (faceNormalsCheckBox != null)
- return faceNormalsCheckBox;
-
- faceNormalsCheckBox = new UiCheckBox("Face Normals (N)");
- faceNormalsCheckBox.setX(xOffset);
- faceNormalsCheckBox.setY(yOffset + 40);
- faceNormalsCheckBox.setSelected(model.isFaceNormalsVisible());
- faceNormalsCheckBox.setForeground(UiValues.UI_ELEMENT_FOREGROUND);
- faceNormalsCheckBox.setActionListener(new IActionListener() {
-
- @Override
- public void onActionPerformed() {
- model.setFaceNormalsVisible(faceNormalsCheckBox.isSelected());
- }
- });
-
- return faceNormalsCheckBox;
- }
-
- protected UiCheckBox getVertexNormalsCheckBox() {
- if (vertexNormalsCheckBox != null)
- return vertexNormalsCheckBox;
-
- vertexNormalsCheckBox = new UiCheckBox("Vertex Normals (V)");
- vertexNormalsCheckBox.setX(xOffset);
- vertexNormalsCheckBox.setY(yOffset + 60);
- vertexNormalsCheckBox.setSelected(model.isVertexNormalsVisible());
- vertexNormalsCheckBox.setForeground(UiValues.UI_ELEMENT_FOREGROUND);
- vertexNormalsCheckBox.setActionListener(new IActionListener() {
-
- @Override
- public void onActionPerformed() {
- model.setVertexNormalsVisible(
- vertexNormalsCheckBox.isSelected()
- );
- }
- });
-
- return vertexNormalsCheckBox;
- }
-
- protected UiCheckBox getWireFrameCheckBox() {
- if (wireFrameCheckBox != null)
- return wireFrameCheckBox;
-
- wireFrameCheckBox = new UiCheckBox("Wireframe (Z)");
- wireFrameCheckBox.setX(xOffset);
- wireFrameCheckBox.setY(yOffset + 80);
- wireFrameCheckBox.setSelected(model.isWireframe());
- wireFrameCheckBox.setForeground(UiValues.UI_ELEMENT_FOREGROUND);
- wireFrameCheckBox.setActionListener(new IActionListener() {
-
- @Override
- public void onActionPerformed() {
- model.setWireframe(wireFrameCheckBox.isSelected());
- }
- });
-
- return wireFrameCheckBox;
- }
-
- protected UiCheckBox getXAxisCheckBox() {
- if (xAxisCheckBox != null)
- return xAxisCheckBox;
-
- xAxisCheckBox = new UiCheckBox("X-Axis (1)");
- xAxisCheckBox.setX(xOffset);
- xAxisCheckBox.setY(yOffset + 100);
- xAxisCheckBox.setSelected(model.isxAxisVisible());
- xAxisCheckBox.setForeground(UiValues.UI_ELEMENT_FOREGROUND);
- xAxisCheckBox.setActionListener(new IActionListener() {
-
- @Override
- public void onActionPerformed() {
- model.setxAxisVisible(xAxisCheckBox.isSelected());
- }
- });
-
- return xAxisCheckBox;
- }
-
- protected UiCheckBox getYAxisCheckBox() {
- if (yAxisCheckBox != null)
- return yAxisCheckBox;
-
- yAxisCheckBox = new UiCheckBox("Y-Axis (2)");
- yAxisCheckBox.setX(xOffset);
- yAxisCheckBox.setY(yOffset + 120);
- yAxisCheckBox.setSelected(model.isyAxisVisible());
- yAxisCheckBox.setForeground(UiValues.UI_ELEMENT_FOREGROUND);
- yAxisCheckBox.setActionListener(new IActionListener() {
-
- @Override
- public void onActionPerformed() {
- model.setyAxisVisible(yAxisCheckBox.isSelected());
- }
- });
-
- return yAxisCheckBox;
- }
-
- protected UiCheckBox getZAxisCheckBox() {
- if (zAxisCheckBox != null)
- return zAxisCheckBox;
-
- zAxisCheckBox = new UiCheckBox("Z-Axis (3)");
- zAxisCheckBox.setX(xOffset);
- zAxisCheckBox.setY(yOffset + 140);
- zAxisCheckBox.setSelected(model.iszAxisVisible());
- zAxisCheckBox.setForeground(UiValues.UI_ELEMENT_FOREGROUND);
- zAxisCheckBox.setActionListener(new IActionListener() {
-
- @Override
- public void onActionPerformed() {
- model.setzAxisVisible(zAxisCheckBox.isSelected());
- }
- });
-
- return zAxisCheckBox;
- }
-
- protected UiCheckBox getEdgeCheckBox() {
- if (edgeCheckBox != null)
- return edgeCheckBox;
-
- edgeCheckBox = new UiCheckBox("Edges (E)");
- edgeCheckBox.setX(xOffset);
- edgeCheckBox.setY(yOffset + 160);
- edgeCheckBox.setSelected(model.isEdgesVisible());
- edgeCheckBox.setForeground(UiValues.UI_ELEMENT_FOREGROUND);
- edgeCheckBox.setActionListener(new IActionListener() {
-
- @Override
- public void onActionPerformed() {
- model.setEdgesVisible(edgeCheckBox.isSelected());
- }
- });
-
- return edgeCheckBox;
- }
-
- protected UiCheckBox getSmoothShadingCheckBox() {
- if (smoothShadingCheckBox != null)
- return smoothShadingCheckBox;
-
- smoothShadingCheckBox = new UiCheckBox("Shade Smooth (S)");
- smoothShadingCheckBox.setX(xOffset);
- smoothShadingCheckBox.setY(yOffset + 180);
- smoothShadingCheckBox.setSelected(model.getShading() == Shading.SMOOTH);
- smoothShadingCheckBox.setForeground(UiValues.UI_ELEMENT_FOREGROUND);
- smoothShadingCheckBox.setActionListener(new IActionListener() {
-
- @Override
- public void onActionPerformed() {
- model.setShading(
- smoothShadingCheckBox.isSelected() ? Shading.SMOOTH
- : Shading.FLAT
- );
- }
- });
-
- return smoothShadingCheckBox;
-
- }
-
- protected UiCheckBox getLoopCheckBox() {
- if (loopCheckBox != null)
- return loopCheckBox;
-
- loopCheckBox = new UiCheckBox("Loop");
- loopCheckBox.setX(xOffset);
- loopCheckBox.setY(yOffset + 200);
- loopCheckBox.setSelected(model.isLoop());
- loopCheckBox.setForeground(UiValues.UI_ELEMENT_FOREGROUND);
- loopCheckBox.setActionListener(new IActionListener() {
-
- @Override
- public void onActionPerformed() {
- model.setLoop(loopCheckBox.isSelected());
- }
- });
-
- return loopCheckBox;
- }
-
- @Override
- public boolean contains(int x, int y) {
- return true;
- }
+ private int xOffset = 10;
+
+ private int yOffset = 65;
+
+ private UiCheckBox gridCheckBox;
+
+ private UiCheckBox faceNormalsCheckBox;
+
+ private UiCheckBox vertexNormalsCheckBox;
+
+ private UiCheckBox wireFrameCheckBox;
+
+ private UiCheckBox xAxisCheckBox;
+
+ private UiCheckBox yAxisCheckBox;
+
+ private UiCheckBox zAxisCheckBox;
+
+ private UiCheckBox edgeCheckBox;
+
+ private UiCheckBox smoothShadingCheckBox;
+
+ private UiCheckBox loopCheckBox;
+
+ private UiLabel label;
+
+ private WorkspaceModel model;
+
+ public WorkspaceSideBarUi(WorkspaceModel model) {
+ this.model = model;
+ this.model.addListener(this);
+ createUI();
+ }
+
+ @Override
+ public void onModelChanged() {
+ gridCheckBox.setSelected(model.isGridVisible());
+ faceNormalsCheckBox.setSelected(model.isFaceNormalsVisible());
+ vertexNormalsCheckBox.setSelected(model.isVertexNormalsVisible());
+ wireFrameCheckBox.setSelected(model.isWireframe());
+ xAxisCheckBox.setSelected(model.isxAxisVisible());
+ yAxisCheckBox.setSelected(model.isyAxisVisible());
+ zAxisCheckBox.setSelected(model.iszAxisVisible());
+ edgeCheckBox.setSelected(model.isEdgesVisible());
+ smoothShadingCheckBox.setSelected(model.getShading() == Shading.SMOOTH);
+ loopCheckBox.setSelected(model.isLoop());
+ }
+
+ private void createUI() {
+ UiPanel panel = new UiPanel();
+ panel.setWidth(200);
+ panel.setHeight(500);
+ panel.setBackground(new Color(77, 77, 77, 0));
+ panel.add(getUiLabel());
+ panel.add(getGridCheckBox());
+ panel.add(getFaceNormalsCheckBox());
+ panel.add(getVertexNormalsCheckBox());
+ panel.add(getWireFrameCheckBox());
+ panel.add(getXAxisCheckBox());
+ panel.add(getYAxisCheckBox());
+ panel.add(getZAxisCheckBox());
+ panel.add(getEdgeCheckBox());
+ panel.add(getSmoothShadingCheckBox());
+ panel.add(getLoopCheckBox());
+ add(panel);
+ }
+
+ protected UiLabel getUiLabel() {
+ if (label != null)
+ return label;
+
+ label = new UiLabel();
+ label.setX(xOffset);
+ label.setY(yOffset);
+ label.setTitle("Controls:");
+ label.setBackground(new Color(0, 0, 0, 0));
+ label.setForeground(UiValues.UI_ELEMENT_FOREGROUND);
+ return label;
+ }
+
+ protected UiCheckBox getGridCheckBox() {
+ if (gridCheckBox != null)
+ return gridCheckBox;
+
+ gridCheckBox = new UiCheckBox("Grid (G)");
+ gridCheckBox.setX(xOffset);
+ gridCheckBox.setY(yOffset + 20);
+ gridCheckBox.setSelected(model.isGridVisible());
+ gridCheckBox.setForeground(UiValues.UI_ELEMENT_FOREGROUND);
+ gridCheckBox.setActionListener(new IActionListener() {
+
+ @Override
+ public void onActionPerformed() {
+ model.setGridVisible(gridCheckBox.isSelected());
+ }
+ });
+
+ return gridCheckBox;
+ }
+
+ protected UiCheckBox getFaceNormalsCheckBox() {
+ if (faceNormalsCheckBox != null)
+ return faceNormalsCheckBox;
+
+ faceNormalsCheckBox = new UiCheckBox("Face Normals (N)");
+ faceNormalsCheckBox.setX(xOffset);
+ faceNormalsCheckBox.setY(yOffset + 40);
+ faceNormalsCheckBox.setSelected(model.isFaceNormalsVisible());
+ faceNormalsCheckBox.setForeground(UiValues.UI_ELEMENT_FOREGROUND);
+ faceNormalsCheckBox.setActionListener(new IActionListener() {
+
+ @Override
+ public void onActionPerformed() {
+ model.setFaceNormalsVisible(faceNormalsCheckBox.isSelected());
+ }
+ });
+
+ return faceNormalsCheckBox;
+ }
+
+ protected UiCheckBox getVertexNormalsCheckBox() {
+ if (vertexNormalsCheckBox != null)
+ return vertexNormalsCheckBox;
+
+ vertexNormalsCheckBox = new UiCheckBox("Vertex Normals (V)");
+ vertexNormalsCheckBox.setX(xOffset);
+ vertexNormalsCheckBox.setY(yOffset + 60);
+ vertexNormalsCheckBox.setSelected(model.isVertexNormalsVisible());
+ vertexNormalsCheckBox.setForeground(UiValues.UI_ELEMENT_FOREGROUND);
+ vertexNormalsCheckBox.setActionListener(new IActionListener() {
+
+ @Override
+ public void onActionPerformed() {
+ model.setVertexNormalsVisible(vertexNormalsCheckBox.isSelected());
+ }
+ });
+
+ return vertexNormalsCheckBox;
+ }
+
+ protected UiCheckBox getWireFrameCheckBox() {
+ if (wireFrameCheckBox != null)
+ return wireFrameCheckBox;
+
+ wireFrameCheckBox = new UiCheckBox("Wireframe (Z)");
+ wireFrameCheckBox.setX(xOffset);
+ wireFrameCheckBox.setY(yOffset + 80);
+ wireFrameCheckBox.setSelected(model.isWireframe());
+ wireFrameCheckBox.setForeground(UiValues.UI_ELEMENT_FOREGROUND);
+ wireFrameCheckBox.setActionListener(new IActionListener() {
+
+ @Override
+ public void onActionPerformed() {
+ model.setWireframe(wireFrameCheckBox.isSelected());
+ }
+ });
+
+ return wireFrameCheckBox;
+ }
+
+ protected UiCheckBox getXAxisCheckBox() {
+ if (xAxisCheckBox != null)
+ return xAxisCheckBox;
+
+ xAxisCheckBox = new UiCheckBox("X-Axis (1)");
+ xAxisCheckBox.setX(xOffset);
+ xAxisCheckBox.setY(yOffset + 100);
+ xAxisCheckBox.setSelected(model.isxAxisVisible());
+ xAxisCheckBox.setForeground(UiValues.UI_ELEMENT_FOREGROUND);
+ xAxisCheckBox.setActionListener(new IActionListener() {
+
+ @Override
+ public void onActionPerformed() {
+ model.setxAxisVisible(xAxisCheckBox.isSelected());
+ }
+ });
+
+ return xAxisCheckBox;
+ }
+
+ protected UiCheckBox getYAxisCheckBox() {
+ if (yAxisCheckBox != null)
+ return yAxisCheckBox;
+
+ yAxisCheckBox = new UiCheckBox("Y-Axis (2)");
+ yAxisCheckBox.setX(xOffset);
+ yAxisCheckBox.setY(yOffset + 120);
+ yAxisCheckBox.setSelected(model.isyAxisVisible());
+ yAxisCheckBox.setForeground(UiValues.UI_ELEMENT_FOREGROUND);
+ yAxisCheckBox.setActionListener(new IActionListener() {
+
+ @Override
+ public void onActionPerformed() {
+ model.setyAxisVisible(yAxisCheckBox.isSelected());
+ }
+ });
+
+ return yAxisCheckBox;
+ }
+
+ protected UiCheckBox getZAxisCheckBox() {
+ if (zAxisCheckBox != null)
+ return zAxisCheckBox;
+
+ zAxisCheckBox = new UiCheckBox("Z-Axis (3)");
+ zAxisCheckBox.setX(xOffset);
+ zAxisCheckBox.setY(yOffset + 140);
+ zAxisCheckBox.setSelected(model.iszAxisVisible());
+ zAxisCheckBox.setForeground(UiValues.UI_ELEMENT_FOREGROUND);
+ zAxisCheckBox.setActionListener(new IActionListener() {
+
+ @Override
+ public void onActionPerformed() {
+ model.setzAxisVisible(zAxisCheckBox.isSelected());
+ }
+ });
+
+ return zAxisCheckBox;
+ }
+
+ protected UiCheckBox getEdgeCheckBox() {
+ if (edgeCheckBox != null)
+ return edgeCheckBox;
+
+ edgeCheckBox = new UiCheckBox("Edges (E)");
+ edgeCheckBox.setX(xOffset);
+ edgeCheckBox.setY(yOffset + 160);
+ edgeCheckBox.setSelected(model.isEdgesVisible());
+ edgeCheckBox.setForeground(UiValues.UI_ELEMENT_FOREGROUND);
+ edgeCheckBox.setActionListener(new IActionListener() {
+
+ @Override
+ public void onActionPerformed() {
+ model.setEdgesVisible(edgeCheckBox.isSelected());
+ }
+ });
+
+ return edgeCheckBox;
+ }
+
+ protected UiCheckBox getSmoothShadingCheckBox() {
+ if (smoothShadingCheckBox != null)
+ return smoothShadingCheckBox;
+
+ smoothShadingCheckBox = new UiCheckBox("Shade Smooth (S)");
+ smoothShadingCheckBox.setX(xOffset);
+ smoothShadingCheckBox.setY(yOffset + 180);
+ smoothShadingCheckBox.setSelected(model.getShading() == Shading.SMOOTH);
+ smoothShadingCheckBox.setForeground(UiValues.UI_ELEMENT_FOREGROUND);
+ smoothShadingCheckBox.setActionListener(new IActionListener() {
+
+ @Override
+ public void onActionPerformed() {
+ model.setShading(
+ smoothShadingCheckBox.isSelected() ? Shading.SMOOTH : Shading.FLAT);
+ }
+ });
+
+ return smoothShadingCheckBox;
+
+ }
+
+ protected UiCheckBox getLoopCheckBox() {
+ if (loopCheckBox != null)
+ return loopCheckBox;
+
+ loopCheckBox = new UiCheckBox("Loop");
+ loopCheckBox.setX(xOffset);
+ loopCheckBox.setY(yOffset + 200);
+ loopCheckBox.setSelected(model.isLoop());
+ loopCheckBox.setForeground(UiValues.UI_ELEMENT_FOREGROUND);
+ loopCheckBox.setActionListener(new IActionListener() {
+
+ @Override
+ public void onActionPerformed() {
+ model.setLoop(loopCheckBox.isSelected());
+ }
+ });
+
+ return loopCheckBox;
+ }
+
+ @Override
+ public boolean contains(int x, int y) {
+ return true;
+ }
}
From b9db88953714dd0476738ad22480ae39675df5de Mon Sep 17 00:00:00 2001
From: Simon Dietz
Date: Sat, 14 Dec 2024 09:24:21 +0100
Subject: [PATCH 04/15] Refactor ViewGizmo for improved modularity and
deprecation compliance Introduced default values for size and height to
simplify initialization. Replaced deprecated mesh operations with
TranslateModifier and RotateModifier for cone transformations.
Modularized rendering logic by introducing renderMesh to reduce redundancy
and improve readability. Centralized cone creation logic in createCone
for better code reuse and consistency. Enhanced method and variable
naming for clarity.
---
src/main/java/workspace/ui/ViewGizmo.java | 201 ++++++++++++----------
1 file changed, 108 insertions(+), 93 deletions(-)
diff --git a/src/main/java/workspace/ui/ViewGizmo.java b/src/main/java/workspace/ui/ViewGizmo.java
index a32d9215..9c9960f4 100644
--- a/src/main/java/workspace/ui/ViewGizmo.java
+++ b/src/main/java/workspace/ui/ViewGizmo.java
@@ -5,104 +5,119 @@
import mesh.creator.primitives.ConeCreator;
import mesh.creator.primitives.CubeCreator;
import mesh.modifier.RotateXModifier;
+import mesh.modifier.RotateZModifier;
import mesh.modifier.ScaleModifier;
+import mesh.modifier.TranslateModifier;
import workspace.laf.UiConstants;
import workspace.laf.UiValues;
public class ViewGizmo extends UiComponent {
- private float height = 2;
-
- private float size = 10;
-
- private float rotationX;
-
- private float rotationY;
-
- private float rotationZ;
-
- private Mesh3D cube;
-
- private Mesh3D coneX;
-
- private Mesh3D coneY;
-
- private Mesh3D coneZ;
-
- public ViewGizmo() {
- createMeshes();
- }
-
- public void draw(Graphics g) {
- g.pushMatrix();
- g.translate(x, y);
- g.rotateX(rotationX);
- g.rotateY(rotationY);
- g.rotateZ(rotationZ);
- g.setColor(UiValues.getColor(UiConstants.KEY_GIZMO_CENTER_COLOR));
- g.fillFaces(cube);
- g.setColor(UiValues.getColor(UiConstants.KEY_GIZMO_AXIS_X_COLOR));
- g.fillFaces(coneX);
- g.setColor(UiValues.getColor(UiConstants.KEY_GIZMO_AXIS_Y_COLOR));
- g.fillFaces(coneY);
- g.setColor(UiValues.getColor(UiConstants.KEY_GIZMO_AXIS_Z_COLOR));
- g.fillFaces(coneZ);
- g.popMatrix();
- }
-
- private void createMeshes() {
- createCube();
- createConeX();
- createConeY();
- createConeZ();
- }
-
- private void createConeX() {
- coneX = new ConeCreator().create();
- coneX.apply(new ScaleModifier(size));
- coneX.rotateZ(-Mathf.HALF_PI);
- coneX.translateX(height * size);
- }
-
- private void createConeY() {
- coneY = new ConeCreator().create();
- coneY.apply(new ScaleModifier(size));
- coneY.translateY(height * size);
- }
-
- private void createConeZ() {
- coneZ = new ConeCreator().create();
- coneZ.apply(new ScaleModifier(size));
- coneZ.apply(new RotateXModifier(Mathf.HALF_PI));
- coneZ.translateZ(height * size);
- }
-
- private void createCube() {
- cube = new CubeCreator(size).create();
- }
-
- public float getRotationX() {
- return rotationX;
- }
-
- public void setRotationX(float rotationX) {
- this.rotationX = rotationX;
- }
-
- public float getRotationY() {
- return rotationY;
- }
-
- public void setRotationY(float rotationY) {
- this.rotationY = rotationY;
- }
-
- public float getRotationZ() {
- return rotationZ;
- }
-
- public void setRotationZ(float rotationZ) {
- this.rotationZ = rotationZ;
- }
+ private static final float DEFAULT_HEIGHT = 2;
+
+ private static final float DEFAULT_SIZE = 10;
+
+ private float height;
+
+ private float size;
+
+ private float rotationX;
+
+ private float rotationY;
+
+ private float rotationZ;
+
+ private Mesh3D cube;
+
+ private Mesh3D coneX;
+
+ private Mesh3D coneY;
+
+ private Mesh3D coneZ;
+
+ public ViewGizmo() {
+ this.height = DEFAULT_HEIGHT;
+ this.size = DEFAULT_SIZE;
+ createMeshes();
+ }
+
+ @Override
+ public void render(Graphics g) {
+ g.pushMatrix();
+ g.translate(x, y);
+ g.rotateX(rotationX);
+ g.rotateY(rotationY);
+ g.rotateZ(rotationZ);
+
+ renderMesh(g, cube, UiConstants.KEY_GIZMO_CENTER_COLOR);
+ renderMesh(g, coneX, UiConstants.KEY_GIZMO_AXIS_X_COLOR);
+ renderMesh(g, coneY, UiConstants.KEY_GIZMO_AXIS_Y_COLOR);
+ renderMesh(g, coneZ, UiConstants.KEY_GIZMO_AXIS_Z_COLOR);
+
+ g.popMatrix();
+ }
+
+ private void renderMesh(Graphics g, Mesh3D mesh, String colorKey) {
+ g.setColor(UiValues.getColor(colorKey));
+ g.fillFaces(mesh);
+ }
+
+ private void createMeshes() {
+ createCube();
+ createConeX();
+ createConeY();
+ createConeZ();
+ }
+
+ private void createConeX() {
+ coneX = createCone();
+ coneX.apply(new RotateZModifier(-Mathf.HALF_PI));
+ coneX.apply(new TranslateModifier(height * size, 0, 0));
+ }
+
+ private void createConeY() {
+ coneY = createCone();
+ coneY.apply(new TranslateModifier(0, height * size, 0));
+ }
+
+ private void createConeZ() {
+ coneZ = createCone();
+ coneZ.apply(new RotateXModifier(Mathf.HALF_PI));
+ coneZ.apply(new TranslateModifier(0, 0, height * size));
+ }
+
+ private Mesh3D createCone() {
+ Mesh3D cone = new ConeCreator().create();
+ cone.apply(new ScaleModifier(size));
+ return cone;
+ }
+
+ private void createCube() {
+ cube = new CubeCreator(size).create();
+ }
+
+ public float getRotationX() {
+ return rotationX;
+ }
+
+ public void setRotationX(float rotationX) {
+ this.rotationX = rotationX;
+ }
+
+ public float getRotationY() {
+ return rotationY;
+ }
+
+ public void setRotationY(float rotationY) {
+ this.rotationY = rotationY;
+ }
+
+ public float getRotationZ() {
+ return rotationZ;
+ }
+
+ public void setRotationZ(float rotationZ) {
+ this.rotationZ = rotationZ;
+ }
}
From ad44ab83ca592ebc557cad6cefebb0663e3e12b6 Mon Sep 17 00:00:00 2001
From: Simon Dietz
Date: Sat, 14 Dec 2024 09:28:19 +0100
Subject: [PATCH 05/15] Rename ViewGizmo to ViewportCompass
- Updated class name from `ViewGizmo` to `ViewportCompass` to better
reflect its purpose as a non-interactive orientation indicator for the
viewport.
- Adjusted references and comments to align with the new name.
---
.../java/workspace/ui/{ViewGizmo.java => ViewportCompass.java} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename src/main/java/workspace/ui/{ViewGizmo.java => ViewportCompass.java} (100%)
diff --git a/src/main/java/workspace/ui/ViewGizmo.java b/src/main/java/workspace/ui/ViewportCompass.java
similarity index 100%
rename from src/main/java/workspace/ui/ViewGizmo.java
rename to src/main/java/workspace/ui/ViewportCompass.java
From fcfb5c85208676fccdd8875570ee3e7455c13ea8 Mon Sep 17 00:00:00 2001
From: Simon Dietz
Date: Sat, 14 Dec 2024 09:45:26 +0100
Subject: [PATCH 06/15] =?UTF-8?q?Refactor:=20Consolidate=20rotation=20logi?=
=?UTF-8?q?c=20with=20Vector3f=20-=20Switched=20to=20`Vector3f`=20for=20cl?=
=?UTF-8?q?eaner=20rotation=20handling.=20-=20Centralized=20rotation=20upd?=
=?UTF-8?q?ates=20using=20`setRotation(Vector3f)`=20with=20clamping=20logi?=
=?UTF-8?q?c=20to=20ensure=20safe=20ranges=20(-=CF=80,=20=CF=80).=20-=20Re?=
=?UTF-8?q?moved=20individual=20axis=20setter=20methods=20for=20simplicity?=
=?UTF-8?q?=20and=20better=20maintainability.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../java/workspace/ui/ViewportCompass.java | 44 +++++--------------
1 file changed, 12 insertions(+), 32 deletions(-)
diff --git a/src/main/java/workspace/ui/ViewportCompass.java b/src/main/java/workspace/ui/ViewportCompass.java
index 9c9960f4..f3fc676c 100644
--- a/src/main/java/workspace/ui/ViewportCompass.java
+++ b/src/main/java/workspace/ui/ViewportCompass.java
@@ -1,6 +1,7 @@
package workspace.ui;
import math.Mathf;
+import math.Vector3f;
import mesh.Mesh3D;
import mesh.creator.primitives.ConeCreator;
import mesh.creator.primitives.CubeCreator;
@@ -11,7 +12,7 @@
import workspace.laf.UiConstants;
import workspace.laf.UiValues;
-public class ViewGizmo extends UiComponent {
+public class ViewportCompass extends UiComponent {
private static final float DEFAULT_HEIGHT = 2;
@@ -21,11 +22,7 @@ public class ViewGizmo extends UiComponent {
private float size;
- private float rotationX;
-
- private float rotationY;
-
- private float rotationZ;
+ private Vector3f rotation;
private Mesh3D cube;
@@ -35,9 +32,10 @@ public class ViewGizmo extends UiComponent {
private Mesh3D coneZ;
- public ViewGizmo() {
+ public ViewportCompass() {
this.height = DEFAULT_HEIGHT;
this.size = DEFAULT_SIZE;
+ this.rotation = new Vector3f();
createMeshes();
}
@@ -45,9 +43,9 @@ public ViewGizmo() {
public void render(Graphics g) {
g.pushMatrix();
g.translate(x, y);
- g.rotateX(rotationX);
- g.rotateY(rotationY);
- g.rotateZ(rotationZ);
+ g.rotateX(rotation.x);
+ g.rotateY(rotation.y);
+ g.rotateZ(rotation.z);
renderMesh(g, cube, UiConstants.KEY_GIZMO_CENTER_COLOR);
renderMesh(g, coneX, UiConstants.KEY_GIZMO_AXIS_X_COLOR);
@@ -96,28 +94,10 @@ private void createCube() {
cube = new CubeCreator(size).create();
}
- public float getRotationX() {
- return rotationX;
- }
-
- public void setRotationX(float rotationX) {
- this.rotationX = rotationX;
- }
-
- public float getRotationY() {
- return rotationY;
- }
-
- public void setRotationY(float rotationY) {
- this.rotationY = rotationY;
- }
-
- public float getRotationZ() {
- return rotationZ;
- }
-
- public void setRotationZ(float rotationZ) {
- this.rotationZ = rotationZ;
+ public void setRotation(Vector3f rotation) {
+ this.rotation.setX(Mathf.clamp(rotation.x, -Mathf.PI, Mathf.PI));
+ this.rotation.setY(Mathf.clamp(rotation.y, -Mathf.PI, Mathf.PI));
+ this.rotation.setZ(Mathf.clamp(rotation.z, -Mathf.PI, Mathf.PI));
}
}
From 76844628451288abbf1ffe4772511c9a6c82b3f1 Mon Sep 17 00:00:00 2001
From: Simon Dietz
Date: Sat, 14 Dec 2024 09:49:45 +0100
Subject: [PATCH 07/15] Add JavaDoc comments to ViewportCompass class and its
methods
- Documented the purpose of the `ViewportCompass` class.
- Added JavaDoc for all methods to explain their purpose, parameters,
and logic.
- Improved maintainability and developer clarity by providing context
for each helper method and transformations.
---
.../java/workspace/ui/ViewportCompass.java | 60 ++++++++++++++++++-
1 file changed, 57 insertions(+), 3 deletions(-)
diff --git a/src/main/java/workspace/ui/ViewportCompass.java b/src/main/java/workspace/ui/ViewportCompass.java
index f3fc676c..445c4624 100644
--- a/src/main/java/workspace/ui/ViewportCompass.java
+++ b/src/main/java/workspace/ui/ViewportCompass.java
@@ -12,16 +12,22 @@
import workspace.laf.UiConstants;
import workspace.laf.UiValues;
+/**
+ * Represents a simple viewport compass in the upper-right corner of the mesh
+ * viewer UI. The compass visualizes the current rotation/orientation of the
+ * viewport in 3D space. This component is non-interactive and purely for
+ * visualization purposes.
+ */
public class ViewportCompass extends UiComponent {
private static final float DEFAULT_HEIGHT = 2;
private static final float DEFAULT_SIZE = 10;
- private float height;
-
private float size;
+ private float height;
+
private Vector3f rotation;
private Mesh3D cube;
@@ -32,13 +38,24 @@ public class ViewportCompass extends UiComponent {
private Mesh3D coneZ;
+ /**
+ * Default constructor initializes the compass with default height, size, and
+ * creates all required meshes for rendering the compass.
+ */
public ViewportCompass() {
- this.height = DEFAULT_HEIGHT;
this.size = DEFAULT_SIZE;
+ this.height = DEFAULT_HEIGHT;
this.rotation = new Vector3f();
createMeshes();
}
+ /**
+ * Renders the viewport compass in the UI's graphics context. This method sets
+ * the translation, applies rotations, and renders the gizmo axes and center
+ * mesh.
+ *
+ * @param g The graphics context for rendering.
+ */
@Override
public void render(Graphics g) {
g.pushMatrix();
@@ -55,11 +72,21 @@ public void render(Graphics g) {
g.popMatrix();
}
+ /**
+ * Helper method to render a given mesh with its associated color key.
+ *
+ * @param g The graphics context for rendering.
+ * @param mesh The mesh to render.
+ * @param colorKey The key identifying the color to use from UiValues.
+ */
private void renderMesh(Graphics g, Mesh3D mesh, String colorKey) {
g.setColor(UiValues.getColor(colorKey));
g.fillFaces(mesh);
}
+ /**
+ * Creates and initializes all necessary meshes for the compass visualization.
+ */
private void createMeshes() {
createCube();
createConeX();
@@ -67,33 +94,60 @@ private void createMeshes() {
createConeZ();
}
+ /**
+ * Creates the X-axis cone and applies necessary transformations to position
+ * and rotate it.
+ */
private void createConeX() {
coneX = createCone();
coneX.apply(new RotateZModifier(-Mathf.HALF_PI));
coneX.apply(new TranslateModifier(height * size, 0, 0));
}
+ /**
+ * Creates the Y-axis cone and applies necessary transformations to position
+ * it in the Y direction.
+ */
private void createConeY() {
coneY = createCone();
coneY.apply(new TranslateModifier(0, height * size, 0));
}
+ /**
+ * Creates the Z-axis cone and applies transformations to rotate and position
+ * it in the Z direction.
+ */
private void createConeZ() {
coneZ = createCone();
coneZ.apply(new RotateXModifier(Mathf.HALF_PI));
coneZ.apply(new TranslateModifier(0, 0, height * size));
}
+ /**
+ * Creates a cone mesh, scales it appropriately, and prepares it for
+ * rendering.
+ *
+ * @return The scaled and ready-to-render cone mesh.
+ */
private Mesh3D createCone() {
Mesh3D cone = new ConeCreator().create();
cone.apply(new ScaleModifier(size));
return cone;
}
+ /**
+ * Creates the central cube for visualization.
+ */
private void createCube() {
cube = new CubeCreator(size).create();
}
+ /**
+ * Sets the viewport's rotation, clamping each rotation axis value to ensure
+ * valid ranges.
+ *
+ * @param rotation The desired rotation vector.
+ */
public void setRotation(Vector3f rotation) {
this.rotation.setX(Mathf.clamp(rotation.x, -Mathf.PI, Mathf.PI));
this.rotation.setY(Mathf.clamp(rotation.y, -Mathf.PI, Mathf.PI));
From e0f2ca3c1d437e4aee445faed67536f1abd403bc Mon Sep 17 00:00:00 2001
From: Simon Dietz
Date: Sat, 14 Dec 2024 10:00:34 +0100
Subject: [PATCH 08/15] Fix: Removed clamping. Did not behave as expected.
---
src/main/java/workspace/ui/ViewportCompass.java | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/src/main/java/workspace/ui/ViewportCompass.java b/src/main/java/workspace/ui/ViewportCompass.java
index 445c4624..b143ea99 100644
--- a/src/main/java/workspace/ui/ViewportCompass.java
+++ b/src/main/java/workspace/ui/ViewportCompass.java
@@ -143,15 +143,14 @@ private void createCube() {
}
/**
- * Sets the viewport's rotation, clamping each rotation axis value to ensure
- * valid ranges.
+ * Sets the viewport's rotation.
*
* @param rotation The desired rotation vector.
*/
public void setRotation(Vector3f rotation) {
- this.rotation.setX(Mathf.clamp(rotation.x, -Mathf.PI, Mathf.PI));
- this.rotation.setY(Mathf.clamp(rotation.y, -Mathf.PI, Mathf.PI));
- this.rotation.setZ(Mathf.clamp(rotation.z, -Mathf.PI, Mathf.PI));
+ this.rotation.setX(rotation.x);
+ this.rotation.setY(rotation.y);
+ this.rotation.setZ(rotation.z);
}
}
From 842d012879b434e7ea8177be9a2fa69e381161a9 Mon Sep 17 00:00:00 2001
From: Simon Dietz
Date: Sat, 14 Dec 2024 12:41:03 +0100
Subject: [PATCH 09/15] Refactor: Transition UI Framework to Abstract, Flexible
Design
- Restructured package hierarchy to better organize framework
components.
- Decoupled core UI logic from Processing-specific implementations,
paving the way for broader flexibility and rendering backends.
- Began transforming library from a prototype to a robust, extensible UI
framework.
- Introduced abstract base classes and interfaces for key components.
- Updated existing components to align with the new architecture.
- Enhanced modularity by improving separation of concerns:
- Moved rendering logic to dedicated `Renderer` classes.
- Improved code clarity and maintainability with better encapsulation
and naming conventions.
- Added comprehensive JavaDocs to foundational classes for improved
readability and usability.
This commit marks the foundational shift from a prototype to a polished
framework capable of supporting future scalability and flexibility.
Follow-up commits will address integration, performance tuning, and
additional feature development.
---
src/main/java/workspace/Editor.java | 292 +++---
src/main/java/workspace/FirstPersonView.java | 197 ++--
src/main/java/workspace/GraphicsPImpl.java | 326 +++---
src/main/java/workspace/ModelListener.java | 2 +-
src/main/java/workspace/SceneObject.java | 62 +-
src/main/java/workspace/Workspace.java | 967 +++++++++---------
src/main/java/workspace/WorkspaceModel.java | 592 +++++------
.../java/workspace/WorkspaceSideBarUi.java | 10 +-
src/main/java/workspace/laf/LookAndFeel.java | 67 +-
src/main/java/workspace/laf/UiConstants.java | 26 +-
src/main/java/workspace/laf/UiValues.java | 42 +-
src/main/java/workspace/ui/Color.java | 114 +--
src/main/java/workspace/ui/Graphics.java | 54 +-
src/main/java/workspace/ui/Slider.java | 145 +--
src/main/java/workspace/ui/UiComponent.java | 446 ++++----
src/main/java/workspace/ui/UiSimpleList.java | 80 +-
src/main/java/workspace/ui/border/Border.java | 32 +-
.../workspace/ui/border/CompoundBorder.java | 96 ++
.../workspace/ui/border/CornerGapBorder.java | 172 ++++
.../java/workspace/ui/border/EmptyBorder.java | 53 +
src/main/java/workspace/ui/border/Insets.java | 418 ++++----
.../java/workspace/ui/border/LineBorder.java | 167 ++-
.../workspace/ui/{ => elements}/UiButton.java | 0
.../ui/{ => elements}/UiCheckBox.java | 0
.../ui/{ => elements}/UiEditorMenu.java | 0
.../java/workspace/ui/elements/UiElement.java | 170 +++
.../workspace/ui/{ => elements}/UiLabel.java | 0
.../workspace/ui/{ => elements}/UiPanel.java | 0
.../ui/{ => elements}/ViewportCompass.java | 0
.../ui/{ => event}/IActionListener.java | 0
.../ui/{ => event}/ISliderCallBack.java | 0
.../workspace/ui/{ => event}/MouseEvent.java | 0
src/main/java/workspace/ui/layout/Layout.java | 37 +-
.../workspace/ui/renderer/ButtonRenderer.java | 44 +
.../ui/renderer/CheckBoxRenderer.java | 45 +
.../ui/renderer/EditorMenuRenderer.java | 46 +
.../workspace/ui/renderer/LabelRenderer.java | 44 +
.../workspace/ui/renderer/PanelRenderer.java | 45 +
.../java/workspace/ui/renderer/Renderer.java | 42 +
39 files changed, 2882 insertions(+), 1951 deletions(-)
create mode 100644 src/main/java/workspace/ui/border/CompoundBorder.java
create mode 100644 src/main/java/workspace/ui/border/CornerGapBorder.java
create mode 100644 src/main/java/workspace/ui/border/EmptyBorder.java
rename src/main/java/workspace/ui/{ => elements}/UiButton.java (100%)
rename src/main/java/workspace/ui/{ => elements}/UiCheckBox.java (100%)
rename src/main/java/workspace/ui/{ => elements}/UiEditorMenu.java (100%)
create mode 100644 src/main/java/workspace/ui/elements/UiElement.java
rename src/main/java/workspace/ui/{ => elements}/UiLabel.java (100%)
rename src/main/java/workspace/ui/{ => elements}/UiPanel.java (100%)
rename src/main/java/workspace/ui/{ => elements}/ViewportCompass.java (100%)
rename src/main/java/workspace/ui/{ => event}/IActionListener.java (100%)
rename src/main/java/workspace/ui/{ => event}/ISliderCallBack.java (100%)
rename src/main/java/workspace/ui/{ => event}/MouseEvent.java (100%)
create mode 100644 src/main/java/workspace/ui/renderer/ButtonRenderer.java
create mode 100644 src/main/java/workspace/ui/renderer/CheckBoxRenderer.java
create mode 100644 src/main/java/workspace/ui/renderer/EditorMenuRenderer.java
create mode 100644 src/main/java/workspace/ui/renderer/LabelRenderer.java
create mode 100644 src/main/java/workspace/ui/renderer/PanelRenderer.java
create mode 100644 src/main/java/workspace/ui/renderer/Renderer.java
diff --git a/src/main/java/workspace/Editor.java b/src/main/java/workspace/Editor.java
index 1fc060eb..0c24edaf 100644
--- a/src/main/java/workspace/Editor.java
+++ b/src/main/java/workspace/Editor.java
@@ -18,150 +18,158 @@
import workspace.command.WireframeCommand;
import workspace.laf.LookAndFeel;
import workspace.ui.UiComponent;
-import workspace.ui.UiEditorMenu;
-import workspace.ui.ViewGizmo;
+import workspace.ui.elements.UiEditorMenu;
+import workspace.ui.elements.ViewportCompass;
public class Editor implements ModelListener {
- protected List sceneObjects;
-
- protected UiComponent rootUi;
-
- protected KeyCommandMap commands;
-
- protected WorkspaceModel model;
-
- protected ViewGizmo gizmo;
-
- protected WorkspaceSideBarUi sideBar;
-
- protected UiEditorMenu menu;
-
- public Editor() {
- setup();
- }
-
- private void setup() {
- setupLookAndFeel();
- initializeModel();
- initializeSceneObjects();
- initializeRootUi();
- createUi();
- initializeCommandMap();
- registerKeyCommands();
- }
-
- @Override
- public void onModelChanged() {
- rootUi.setVisible(model.isUiVisible());
- }
-
- private void initializeSceneObjects() {
- sceneObjects = new ArrayList();
- }
-
- private void createUi() {
- rootUi.add(getSideBar());
- rootUi.add(getGizmo());
- rootUi.add(getMenu());
- }
-
- private WorkspaceSideBarUi getSideBar() {
- if (sideBar == null) {
- sideBar = new WorkspaceSideBarUi(model);
- }
- return sideBar;
- }
-
- private ViewGizmo getGizmo() {
- if (gizmo == null) {
- gizmo = new ViewGizmo();
- }
- return gizmo;
- }
-
- private UiEditorMenu getMenu() {
- if (menu == null) {
- menu = new UiEditorMenu();
- }
- return menu;
- }
-
- private void initializeRootUi() {
- rootUi = new UiComponent();
- }
-
- private void setupLookAndFeel() {
- LookAndFeel.setup();
- }
-
- private void initializeCommandMap() {
- commands = new KeyCommandMap();
- }
-
- private void initializeModel() {
- model = new WorkspaceModel();
- }
-
- private void registerKeyCommands() {
- commands.register(new ShowHideGridCommand(model));
- commands.register(new ShowHideXAxisCommand(model));
- commands.register(new ShowHideYAxisCommand(model));
- commands.register(new ShowHideZAxisCommand(model));
- commands.register(new ShowHideSideBarCommand(model));
- commands.register(new ShowHideFaceNormalsCommand(model));
- commands.register(new ResetPanningCommand(model));
- commands.register(new ShowHideVertexNormalsCommand(model));
- commands.register(new ShowHideEdgesCommand(model));
- commands.register(new WireframeCommand(model));
- commands.register(new ShadeSmoothFlatCommand(model));
- }
-
- private void resizeRootUi(int x, int y, int width, int height) {
- rootUi.setX(x);
- rootUi.setY(y);
- rootUi.setWidth(width);
- rootUi.setHeight(height);
- }
-
- public void resize(int x, int y, int width, int height) {
- resizeRootUi(x, y, width, height);
- updateGizmo(width, height);
- }
-
- public void handleMouseClicked(int x, int y) {
- rootUi.onMouseClicked(x, y);
- }
-
- public void handleMouseDragged(int x, int y) {
- rootUi.onMouseDragged(x, y);
- }
-
- public void handleMouseWheel(float amount) {
- float scale = model.getScale();
- scale -= amount * scale * 0.2f;
- model.setScale(scale);
- }
-
- private void updateGizmo(int width, int height) {
- gizmo.setX(width - 80);
- gizmo.setY(130);
- }
-
- public void add(UiComponent component) {
- rootUi.add(component);
- }
-
- public void addSceneObject(SceneObject sceneObject) {
- sceneObjects.add(sceneObject);
- }
-
- public void addAll(Collection sceneObjects) {
- this.sceneObjects.addAll(sceneObjects);
- }
-
- public void clearSceneObjects() {
- sceneObjects.clear();
- }
+ protected List sceneObjects;
+
+ protected UiComponent rootUi;
+
+ protected KeyCommandMap commands;
+
+ protected WorkspaceModel model;
+
+ protected ViewportCompass gizmo;
+
+ protected WorkspaceSideBarUi sideBar;
+
+ protected UiEditorMenu menu;
+
+ public Editor() {
+ setup();
+ }
+
+ private void setup() {
+ setupLookAndFeel();
+ initializeModel();
+ initializeSceneObjects();
+ initializeRootUi();
+ createUi();
+ initializeCommandMap();
+ registerKeyCommands();
+ }
+
+ @Override
+ public void onModelChanged() {
+ rootUi.setVisible(model.isUiVisible());
+ }
+
+ private void initializeSceneObjects() {
+ sceneObjects = new ArrayList();
+ }
+
+ private void createUi() {
+ rootUi.add(getSideBar());
+ rootUi.add(getGizmo());
+ rootUi.add(getMenu());
+ }
+
+ private WorkspaceSideBarUi getSideBar() {
+ if (sideBar == null) {
+ sideBar = new WorkspaceSideBarUi(model);
+ }
+ return sideBar;
+ }
+
+ private ViewportCompass getGizmo() {
+ if (gizmo == null) {
+ gizmo = new ViewportCompass();
+ }
+ return gizmo;
+ }
+
+ private UiEditorMenu getMenu() {
+ if (menu == null) {
+ menu = new UiEditorMenu();
+ }
+ return menu;
+ }
+
+ private void initializeRootUi() {
+ rootUi = new UiComponent();
+ }
+
+ private void setupLookAndFeel() {
+ LookAndFeel.setup();
+ }
+
+ private void initializeCommandMap() {
+ commands = new KeyCommandMap();
+ }
+
+ private void initializeModel() {
+ model = new WorkspaceModel();
+ }
+
+ private void registerKeyCommands() {
+ commands.register(new ShowHideGridCommand(model));
+ commands.register(new ShowHideXAxisCommand(model));
+ commands.register(new ShowHideYAxisCommand(model));
+ commands.register(new ShowHideZAxisCommand(model));
+ commands.register(new ShowHideSideBarCommand(model));
+ commands.register(new ShowHideFaceNormalsCommand(model));
+ commands.register(new ResetPanningCommand(model));
+ commands.register(new ShowHideVertexNormalsCommand(model));
+ commands.register(new ShowHideEdgesCommand(model));
+ commands.register(new WireframeCommand(model));
+ commands.register(new ShadeSmoothFlatCommand(model));
+ }
+
+ private void resizeRootUi(int x, int y, int width, int height) {
+ rootUi.setX(x);
+ rootUi.setY(y);
+ rootUi.setWidth(width);
+ rootUi.setHeight(height);
+ }
+
+ public void resize(int x, int y, int width, int height) {
+ resizeRootUi(x, y, width, height);
+ updateGizmo(width, height);
+ }
+
+ public void handleMouseClicked(int x, int y) {
+ rootUi.onMouseClicked(x, y);
+ }
+
+ public void handleMousePressed(int x, int y) {
+ rootUi.onMousePressed(x, y);
+ }
+
+ public void handleMouseDragged(int x, int y) {
+ rootUi.onMouseDragged(x, y);
+ }
+
+ public void handleMouseReleased(int x, int y) {
+ rootUi.onMouseReleased(x, y);
+ }
+
+ public void handleMouseWheel(float amount) {
+ float scale = model.getScale();
+ scale -= amount * scale * 0.2f;
+ model.setScale(scale);
+ }
+
+ private void updateGizmo(int width, int height) {
+ gizmo.setX(width - 80);
+ gizmo.setY(130);
+ }
+
+ public void add(UiComponent component) {
+ rootUi.add(component);
+ }
+
+ public void addSceneObject(SceneObject sceneObject) {
+ sceneObjects.add(sceneObject);
+ }
+
+ public void addAll(Collection sceneObjects) {
+ this.sceneObjects.addAll(sceneObjects);
+ }
+
+ public void clearSceneObjects() {
+ sceneObjects.clear();
+ }
}
diff --git a/src/main/java/workspace/FirstPersonView.java b/src/main/java/workspace/FirstPersonView.java
index 6a94deab..d6b71a7e 100644
--- a/src/main/java/workspace/FirstPersonView.java
+++ b/src/main/java/workspace/FirstPersonView.java
@@ -10,148 +10,145 @@
public class FirstPersonView {
- private boolean enabled;
+ private boolean enabled;
- private boolean left;
+ private boolean left;
- private boolean right;
+ private boolean right;
- private boolean forward;
+ private boolean forward;
- private boolean back;
+ private boolean back;
- private boolean up;
+ private boolean up;
- private boolean down;
+ private boolean down;
- private float pitch = Mathf.PI;
+ private float pitch = Mathf.PI;
- private float yaw = 0;
+ private float yaw = 0;
- private Vector3f eye = new Vector3f(-1000, 0, 1000);
+ private Vector3f eye = new Vector3f(-1000, 0, 1000);
- private float speed = 10;
+ private float speed = 10;
- private PApplet context;
+ private PApplet context;
- public FirstPersonView(PApplet context) {
- this.context = context;
- context.registerMethod("pre", this);
- context.registerMethod("keyEvent", this);
- }
+ public FirstPersonView(PApplet context) {
+ this.context = context;
+ context.registerMethod("pre", this);
+ context.registerMethod("keyEvent", this);
+ }
- public void pre() {
- if (!enabled)
- return;
- yaw = Mathf.map(context.mouseX, 0, context.width, Mathf.PI, -Mathf.PI);
- pitch = Mathf
- .map(context.mouseY, 0, context.height, -Mathf.PI, Mathf.PI);
+ public void pre() {
+ if (!enabled)
+ return;
+ yaw = Mathf.map(context.mouseX, 0, context.width, Mathf.PI, -Mathf.PI);
+ pitch = Mathf.map(context.mouseY, 0, context.height, -Mathf.PI, Mathf.PI);
// if (pitch > 89)
// pitch = 89;
// if (pitch < -89)
// pitch = -89;
- Vector3f front = new Vector3f();
- float x = Mathf.cos(Mathf.toRadians(yaw))
- * Mathf.cos(Mathf.toRadians(pitch));
- float y = Mathf.sin(Mathf.toRadians(pitch));
- float z = Mathf.cos(Mathf.toRadians(yaw))
- * Mathf.cos(Mathf.toRadians(pitch));
- front.set(x, y, z);
+ Vector3f front = new Vector3f();
+ float x = Mathf.cos(Mathf.toRadians(yaw))
+ * Mathf.cos(Mathf.toRadians(pitch));
+ float y = Mathf.sin(Mathf.toRadians(pitch));
+ float z = Mathf.cos(Mathf.toRadians(yaw))
+ * Mathf.cos(Mathf.toRadians(pitch));
+ front.set(x, y, z);
- Vector3f velocity = new Vector3f();
+ Vector3f velocity = new Vector3f();
- if (left) {
- velocity.addLocal(-1, 0, 0);
- }
+ if (left) {
+ velocity.addLocal(-1, 0, 0);
+ }
- if (right) {
- velocity.addLocal(1, 0, 0);
- }
+ if (right) {
+ velocity.addLocal(1, 0, 0);
+ }
- if (back) {
- velocity.addLocal(0, 0, 1);
- }
+ if (back) {
+ velocity.addLocal(0, 0, 1);
+ }
- if (forward) {
- velocity.addLocal(0, 0, -1);
- }
+ if (forward) {
+ velocity.addLocal(0, 0, -1);
+ }
- velocity.multLocal(getRotationMatrix(yaw));
+ velocity.multLocal(getRotationMatrix(yaw));
- eye.addLocal(velocity.mult(speed));
- eye.setY(-300);
- }
+ eye.addLocal(velocity.mult(speed));
+ eye.setY(-300);
+ }
- public void apply() {
- Matrix4f m = Matrix4f.fpsViewRH(eye, pitch, yaw).transpose();
- PMatrix matrix = context.getMatrix();
- matrix.set(m.getValues());
- context.setMatrix(matrix);
- }
+ public void apply() {
+ Matrix4f m = Matrix4f.fpsViewRH(eye, pitch, yaw).transpose();
+ PMatrix matrix = context.getMatrix();
+ matrix.set(m.getValues());
+ context.setMatrix(matrix);
+ }
- public void keyEvent(KeyEvent key) {
- if (key.getAction() == KeyEvent.PRESS)
- onKeyPressed(key.getKey());
- if (key.getAction() == KeyEvent.RELEASE)
- onKeyReleased(key.getKey());
- }
+ public void keyEvent(KeyEvent key) {
+ if (key.getAction() == KeyEvent.PRESS)
+ onKeyPressed(key.getKey());
+ if (key.getAction() == KeyEvent.RELEASE)
+ onKeyReleased(key.getKey());
+ }
- public void onKeyPressed(char key) {
- if (key == 'w' || key == 'W')
- forward = true;
+ public void onKeyPressed(char key) {
+ if (key == 'w' || key == 'W')
+ forward = true;
- if (key == 's' || key == 'S')
- back = true;
+ if (key == 's' || key == 'S')
+ back = true;
- if (key == 'a' || key == 'A')
- left = true;
+ if (key == 'a' || key == 'A')
+ left = true;
- if (key == 'd' || key == 'D')
- right = true;
+ if (key == 'd' || key == 'D')
+ right = true;
- if (key == ' ')
- up = true;
+ if (key == ' ')
+ up = true;
- if (key == 'c' || key == 'C')
- down = true;
- }
+ if (key == 'c' || key == 'C')
+ down = true;
+ }
- public void onKeyReleased(char key) {
- if (key == 'w' || key == 'W')
- forward = false;
+ public void onKeyReleased(char key) {
+ if (key == 'w' || key == 'W')
+ forward = false;
- if (key == 's' || key == 'S')
- back = false;
+ if (key == 's' || key == 'S')
+ back = false;
- if (key == 'a' || key == 'A')
- left = false;
+ if (key == 'a' || key == 'A')
+ left = false;
- if (key == 'd' || key == 'D')
- right = false;
+ if (key == 'd' || key == 'D')
+ right = false;
- if (key == ' ')
- up = false;
+ if (key == ' ')
+ up = false;
- if (key == 'c' || key == 'C')
- down = false;
- }
+ if (key == 'c' || key == 'C')
+ down = false;
+ }
- public Matrix3f getRotationMatrix(float angle) {
- Matrix3f m = new Matrix3f(
- Mathf.cos(angle), 0, Mathf.sin(angle), 0, 1, 0,
- -Mathf.sin(angle), 0, Mathf.cos(angle)
- );
- return m;
- }
+ public Matrix3f getRotationMatrix(float angle) {
+ Matrix3f m = new Matrix3f(Mathf.cos(angle), 0, Mathf.sin(angle), 0, 1, 0,
+ -Mathf.sin(angle), 0, Mathf.cos(angle));
+ return m;
+ }
- public boolean isEnabled() {
- return enabled;
- }
+ public boolean isEnabled() {
+ return enabled;
+ }
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- }
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
}
diff --git a/src/main/java/workspace/GraphicsPImpl.java b/src/main/java/workspace/GraphicsPImpl.java
index a79199ac..4d871a78 100644
--- a/src/main/java/workspace/GraphicsPImpl.java
+++ b/src/main/java/workspace/GraphicsPImpl.java
@@ -9,150 +9,186 @@
public class GraphicsPImpl implements Graphics {
- private Color color;
- private PGraphics g;
- private Mesh3DRenderer renderer;
-
- public GraphicsPImpl(PApplet p) {
- this.g = p.g;
- renderer = new Mesh3DRenderer(p);
- }
-
- @Override
- public void fillFaces(Mesh3D mesh) {
- g.noStroke();
- fill();
- renderer.drawFaces(mesh);
- }
-
- @Override
- public int getWidth() {
- return g.width;
- }
-
- @Override
- public int getHeight() {
- return g.height;
- }
-
- private void stroke() {
- g.stroke(
- color.getRed(), color.getGreen(), color.getBlue(),
- color.getAlpha()
- );
- }
-
- private void fill() {
- g.fill(
- color.getRed(), color.getGreen(), color.getBlue(),
- color.getAlpha()
- );
- }
-
- @Override
- public void pushMatrix() {
- g.pushMatrix();
- }
-
- @Override
- public void popMatrix() {
- g.popMatrix();
- }
-
- @Override
- public void translate(float x, float y) {
- g.translate(x, y);
- }
-
- @Override
- public void strokeWeight(float weight) {
- g.strokeWeight(weight);
- }
-
- @Override
- public void setColor(Color color) {
- this.color = color;
- }
-
- @Override
- public void setColor(int red, int green, int blue) {
- color = new Color(red, green, blue);
- }
-
- @Override
- public void drawRect(float x, float y, float width, float height) {
- g.pushStyle();
- g.noFill();
- stroke();
- g.rectMode(PApplet.CORNER);
- g.rect(x, y, width, height);
- g.popStyle();
- }
-
- @Override
- public void fillRect(float x, float y, float width, float height) {
- g.pushStyle();
- g.noStroke();
- fill();
- g.rectMode(PApplet.CORNER);
- g.rect(x, y, width, height);
- g.popStyle();
- }
-
- @Override
- public void textSize(float size) {
- g.textSize(size);
- }
-
- @Override
- public float getTextSize() {
- return g.textSize;
- }
-
- @Override
- public float textWidth(String text) {
- return g.textWidth(text);
- }
-
- @Override
- public float textAscent() {
- return g.textAscent();
- }
-
- @Override
- public float textDescent() {
- return g.textDescent();
- }
-
- @Override
- public void text(String text, float x, float y) {
- fill();
- g.text(text, x, y);
- }
-
- @Override
- public void enableDepthTest() {
- g.hint(PApplet.ENABLE_DEPTH_TEST);
- }
-
- @Override
- public void disableDepthTest() {
- g.hint(PApplet.DISABLE_DEPTH_TEST);
- }
-
- @Override
- public void rotateX(float angle) {
- g.rotateX(angle);
- }
-
- @Override
- public void rotateY(float angle) {
- g.rotateY(angle);
- }
-
- @Override
- public void rotateZ(float angle) {
- g.rotate(angle);
- }
+ private Color color;
+
+ private PGraphics g;
+
+ private Mesh3DRenderer renderer;
+
+ public GraphicsPImpl(PApplet p) {
+ this.g = p.g;
+ renderer = new Mesh3DRenderer(p);
+ }
+
+ @Override
+ public void fillFaces(Mesh3D mesh) {
+ g.noStroke();
+ fill();
+ renderer.drawFaces(mesh);
+ }
+
+ @Override
+ public int getWidth() {
+ return g.width;
+ }
+
+ @Override
+ public int getHeight() {
+ return g.height;
+ }
+
+ private void stroke() {
+ g.stroke(color.getRed(), color.getGreen(), color.getBlue(),
+ color.getAlpha());
+ }
+
+ private void fill() {
+ g.fill(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
+ }
+
+ @Override
+ public void pushMatrix() {
+ g.pushMatrix();
+ }
+
+ @Override
+ public void popMatrix() {
+ g.popMatrix();
+ }
+
+ @Override
+ public void translate(float x, float y) {
+ g.translate(x, y);
+ }
+
+ @Override
+ public void strokeWeight(float weight) {
+ g.strokeWeight(weight);
+ }
+
+ @Override
+ public void setColor(Color color) {
+ this.color = color;
+ }
+
+ @Override
+ public void setColor(int red, int green, int blue) {
+ color = new Color(red, green, blue);
+ }
+
+ @Override
+ public void setColor(math.Color color) {
+ setColor(color.getRedInt(), color.getGreenInt(), color.getBlueInt());
+ }
+
+ @Override
+ public void drawRect(float x, float y, float width, float height) {
+ g.pushStyle();
+ g.noFill();
+ stroke();
+ g.rectMode(PApplet.CORNER);
+ g.rect(x, y, width, height);
+ g.popStyle();
+ }
+
+ @Override
+ public void drawLine(float x1, float y1, float x2, float y2) {
+ g.pushStyle();
+ g.noFill();
+ stroke();
+ g.line(x1, y1, x2, y2);
+ g.popStyle();
+ }
+
+ @Override
+ public void fillRect(float x, float y, float width, float height) {
+ g.pushStyle();
+ g.noStroke();
+ fill();
+ g.rectMode(PApplet.CORNER);
+ g.rect(x, y, width, height);
+ g.popStyle();
+ }
+
+ @Override
+ public void drawOval(float x, float y, float width, float height) {
+ g.pushStyle();
+ g.noFill();
+ stroke();
+ g.ellipseMode(PApplet.CORNER);
+ g.ellipse(x, y, height, width);
+ g.popStyle();
+ }
+
+ @Override
+ public void fillOval(float x, float y, float width, float height) {
+ g.pushStyle();
+ g.noStroke();
+ fill();
+ g.ellipseMode(PApplet.CORNER);
+ g.ellipse(x, y, height, width);
+ g.popStyle();
+ }
+
+ @Override
+ public void textSize(float size) {
+ g.textSize(size);
+ }
+
+ @Override
+ public float getTextSize() {
+ return g.textSize;
+ }
+
+ @Override
+ public float textWidth(String text) {
+ return g.textWidth(text);
+ }
+
+ @Override
+ public float textAscent() {
+ return g.textAscent();
+ }
+
+ @Override
+ public float textDescent() {
+ return g.textDescent();
+ }
+
+ @Override
+ public void text(String text, float x, float y) {
+ fill();
+ g.text(text, x, y);
+ }
+
+ @Override
+ public void enableDepthTest() {
+ g.hint(PApplet.ENABLE_DEPTH_TEST);
+ }
+
+ @Override
+ public void disableDepthTest() {
+ g.hint(PApplet.DISABLE_DEPTH_TEST);
+ }
+
+ @Override
+ public void rotate(float angle) {
+ g.rotate(angle);
+ }
+
+ @Override
+ public void rotateX(float angle) {
+ g.rotateX(angle);
+ }
+
+ @Override
+ public void rotateY(float angle) {
+ g.rotateY(angle);
+ }
+
+ @Override
+ public void rotateZ(float angle) {
+ g.rotate(angle);
+ }
}
diff --git a/src/main/java/workspace/ModelListener.java b/src/main/java/workspace/ModelListener.java
index 74dd7c5d..c4255196 100644
--- a/src/main/java/workspace/ModelListener.java
+++ b/src/main/java/workspace/ModelListener.java
@@ -2,6 +2,6 @@
public interface ModelListener {
- void onModelChanged();
+ void onModelChanged();
}
diff --git a/src/main/java/workspace/SceneObject.java b/src/main/java/workspace/SceneObject.java
index 67cc9d64..ee3775a3 100644
--- a/src/main/java/workspace/SceneObject.java
+++ b/src/main/java/workspace/SceneObject.java
@@ -5,47 +5,47 @@
public class SceneObject {
- private String name;
+ private String name;
- private Color fillColor;
+ private Color fillColor;
- private Mesh3D mesh;
+ private Mesh3D mesh;
- public SceneObject(Mesh3D mesh) {
- this.mesh = mesh;
- fillColor = Color.WHITE;
- }
+ public SceneObject(Mesh3D mesh) {
+ this.mesh = mesh;
+ fillColor = Color.WHITE;
+ }
- public SceneObject() {
- this(null);
- }
+ public SceneObject() {
+ this(null);
+ }
- public Mesh3D getMesh() {
- return mesh;
- }
+ public Mesh3D getMesh() {
+ return mesh;
+ }
- public void setMesh(Mesh3D mesh) {
- this.mesh = mesh;
- }
+ public void setMesh(Mesh3D mesh) {
+ this.mesh = mesh;
+ }
- public Color getFillColor() {
- return fillColor;
- }
+ public Color getFillColor() {
+ return fillColor;
+ }
- public void setFillColor(Color fillColor) {
- this.fillColor = fillColor;
- }
+ public void setFillColor(Color fillColor) {
+ this.fillColor = fillColor;
+ }
- public void setFillColor(int r, int g, int b) {
- fillColor = new Color(r, g, b);
- }
+ public void setFillColor(int r, int g, int b) {
+ fillColor = new Color(r, g, b);
+ }
- public String getName() {
- return name;
- }
+ public String getName() {
+ return name;
+ }
- public void setName(String name) {
- this.name = name;
- }
+ public void setName(String name) {
+ this.name = name;
+ }
}
diff --git a/src/main/java/workspace/Workspace.java b/src/main/java/workspace/Workspace.java
index 41b49c70..075f248d 100644
--- a/src/main/java/workspace/Workspace.java
+++ b/src/main/java/workspace/Workspace.java
@@ -1,5 +1,6 @@
package workspace;
+import math.Vector3f;
import mesh.Mesh3D;
import mesh.util.VertexNormals;
import processing.core.PApplet;
@@ -14,505 +15,509 @@
public class Workspace extends Editor implements ModelListener {
- int vertices;
-
- int faces;
-
- private PApplet p;
-
- private Mesh3DRenderer renderer;
-
- private FirstPersonView firstPersonView;
-
- private ObjectSelectionRender selectionRender;
-
- private SceneObject selectedObject;
-
- private boolean select;
-
- private GraphicsPImpl gImpl;
-
- public Workspace(PApplet p) {
- this.p = p;
- registerMethods();
- firstPersonView = new FirstPersonView(p);
- renderer = new Mesh3DRenderer(p);
- selectionRender = new ObjectSelectionRender(p);
- refreshLoopPreference();
- model.addListener(this);
- gImpl = new GraphicsPImpl(p);
- }
-
- private void registerMethods() {
- p.registerMethod("pre", this);
- p.registerMethod("draw", this);
- p.registerMethod("post", this);
- p.registerMethod("mouseEvent", this);
- p.registerMethod("keyEvent", this);
- }
-
- @Override
- public void onModelChanged() {
- super.onModelChanged();
- refreshLoopPreference();
- gizmo.setRotationX(model.getRotationX());
- gizmo.setRotationY(model.getRotationY());
- gizmo.setRotationZ(model.getRotationZ());
- if (!isLoop())
- p.redraw();
- }
-
- protected void refreshLoopPreference() {
- if (!isLoop()) {
- p.noLoop();
- } else {
- p.loop();
- }
- }
-
- public void applyTransformations() {
- if (firstPersonView.isEnabled()) {
- firstPersonView.apply();
- p.scale(getScale());
- } else {
- p.translate(p.width / 2, p.height / 2);
- p.translate(getPanningX(), getPanningY());
- p.scale(getScale());
- p.rotateX(getRotationX());
- p.rotateY(getRotationY());
- p.rotateZ(getRotationZ());
- }
- }
-
- public void applyCamera() {
- firstPersonView.apply();
- }
-
- public void drawGrid(int rows, int cols, float size) {
- if (!isGridVisible())
- return;
-
- p.stroke(UiValues.getColor(UiConstants.KEY_GRID_COLOR).getRGBA());
- p.noFill();
-
- p.pushMatrix();
- p.rotateX(PApplet.radians(-90));
- p.translate(-cols / 2, -rows / 2);
-
- for (int i = 0; i < rows; i++) {
- for (int j = 0; j < cols; j++) {
- p.rect(j * size, i * size, size, size);
- }
- }
-
- p.popMatrix();
- }
-
- protected void drawAxis(float size) {
- p.pushStyle();
- p.pushMatrix();
-
- p.noFill();
- p.strokeWeight(1.5f / getScale());
-
- if (isxAxisVisible()) {
- p.stroke(UiValues.getColor(UiConstants.KEY_AXIS_X_COLOR).getRGBA());
- p.line(size, 0, 0, 0, 0, 0);
- p.line(-size, 0, 0, 0, 0, 0);
- }
-
- if (isyAxisVisible()) {
- p.stroke(UiValues.getColor(UiConstants.KEY_AXIS_Y_COLOR).getRGBA());
- p.line(0, size, 0, 0, 0, 0);
- p.line(0, -size, 0, 0, 0, 0);
- }
-
- if (iszAxisVisible()) {
- p.stroke(UiValues.getColor(UiConstants.KEY_AXIS_Z_COLOR).getRGBA());
- p.line(0, 0, size, 0, 0, 0);
- p.line(0, 0, -size, 0, 0, 0);
- }
-
- p.popStyle();
- p.popMatrix();
- }
-
- public void pre() {
- resize(0, 0, p.width, p.height);
- vertices = 0;
- faces = 0;
- p.background(getBackground().getRGBA());
- p.lights();
- applyTransformations();
- p.strokeWeight(1 / getScale());
- drawGrid(32, 32, 1);
- drawAxis(2000);
- }
-
- protected void disableDepthTestFor2dDrawing() {
- p.hint(PApplet.DISABLE_DEPTH_TEST);
- }
-
- protected void enableDepthTestFor3dDrawing() {
- p.hint(PApplet.ENABLE_DEPTH_TEST);
- }
-
- protected void drawUI() {
- disableDepthTestFor2dDrawing();
- p.camera();
- p.noLights();
- rootUi.draw(gImpl);
- enableDepthTestFor3dDrawing();
- }
-
- public void draw() {
- drawSelection();
- drawSceneObjects();
-
- if (selectedObject != null) {
- p.fill(255);
- renderer.drawFaces(selectedObject.getMesh());
- }
-
- drawUI();
-
- menu.setText(getInformationString());
-
- // Debug code
+ int vertices;
+
+ int faces;
+
+ private PApplet p;
+
+ private Mesh3DRenderer renderer;
+
+ private FirstPersonView firstPersonView;
+
+ private ObjectSelectionRender selectionRender;
+
+ private SceneObject selectedObject;
+
+ private boolean select;
+
+ private GraphicsPImpl gImpl;
+
+ public Workspace(PApplet p) {
+ this.p = p;
+ registerMethods();
+ firstPersonView = new FirstPersonView(p);
+ renderer = new Mesh3DRenderer(p);
+ selectionRender = new ObjectSelectionRender(p);
+ refreshLoopPreference();
+ model.addListener(this);
+ gImpl = new GraphicsPImpl(p);
+ }
+
+ private void registerMethods() {
+ p.registerMethod("pre", this);
+ p.registerMethod("draw", this);
+ p.registerMethod("post", this);
+ p.registerMethod("mouseEvent", this);
+ p.registerMethod("keyEvent", this);
+ }
+
+ @Override
+ public void onModelChanged() {
+ super.onModelChanged();
+ refreshLoopPreference();
+ gizmo.setRotation(new Vector3f(model.getRotationX(), model.getRotationY(),
+ model.getRotationZ()));
+ if (!isLoop())
+ p.redraw();
+ }
+
+ protected void refreshLoopPreference() {
+ if (!isLoop()) {
+ p.noLoop();
+ } else {
+ p.loop();
+ }
+ }
+
+ public void applyTransformations() {
+ if (firstPersonView.isEnabled()) {
+ firstPersonView.apply();
+ p.scale(getScale());
+ } else {
+ p.translate(p.width / 2, p.height / 2);
+ p.translate(getPanningX(), getPanningY());
+ p.scale(getScale());
+ p.rotateX(getRotationX());
+ p.rotateY(getRotationY());
+ p.rotateZ(getRotationZ());
+ }
+ }
+
+ public void applyCamera() {
+ firstPersonView.apply();
+ }
+
+ public void drawGrid(int rows, int cols, float size) {
+ if (!isGridVisible())
+ return;
+
+ p.stroke(UiValues.getColor(UiConstants.KEY_GRID_COLOR).getRGBA());
+ p.noFill();
+
+ p.pushMatrix();
+ p.rotateX(PApplet.radians(-90));
+ p.translate(-cols / 2, -rows / 2);
+
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < cols; j++) {
+ p.rect(j * size, i * size, size, size);
+ }
+ }
+
+ p.popMatrix();
+ }
+
+ protected void drawAxis(float size) {
+ p.pushStyle();
+ p.pushMatrix();
+
+ p.noFill();
+ p.strokeWeight(1.5f / getScale());
+
+ if (isxAxisVisible()) {
+ p.stroke(UiValues.getColor(UiConstants.KEY_AXIS_X_COLOR).getRGBA());
+ p.line(size, 0, 0, 0, 0, 0);
+ p.line(-size, 0, 0, 0, 0, 0);
+ }
+
+ if (isyAxisVisible()) {
+ p.stroke(UiValues.getColor(UiConstants.KEY_AXIS_Y_COLOR).getRGBA());
+ p.line(0, size, 0, 0, 0, 0);
+ p.line(0, -size, 0, 0, 0, 0);
+ }
+
+ if (iszAxisVisible()) {
+ p.stroke(UiValues.getColor(UiConstants.KEY_AXIS_Z_COLOR).getRGBA());
+ p.line(0, 0, size, 0, 0, 0);
+ p.line(0, 0, -size, 0, 0, 0);
+ }
+
+ p.popStyle();
+ p.popMatrix();
+ }
+
+ public void pre() {
+ resize(0, 0, p.width, p.height);
+ vertices = 0;
+ faces = 0;
+ p.background(getBackground().getRGBA());
+ p.lights();
+ applyTransformations();
+ p.strokeWeight(1 / getScale());
+ drawGrid(32, 32, 1);
+ drawAxis(2000);
+ }
+
+ protected void disableDepthTestFor2dDrawing() {
+ p.hint(PApplet.DISABLE_DEPTH_TEST);
+ }
+
+ protected void enableDepthTestFor3dDrawing() {
+ p.hint(PApplet.ENABLE_DEPTH_TEST);
+ }
+
+ protected void drawUI() {
+ disableDepthTestFor2dDrawing();
+ p.camera();
+ p.noLights();
+ rootUi.render(gImpl);
+ enableDepthTestFor3dDrawing();
+ }
+
+ public void draw() {
+ drawSelection();
+ drawSceneObjects();
+
+ if (selectedObject != null) {
+ p.fill(255);
+ renderer.drawFaces(selectedObject.getMesh());
+ }
+
+ drawUI();
+
+ menu.setText(getInformationString());
+
+ // Debug code
// p.pushMatrix();
// p.camera();
// p.hint(PApplet.DISABLE_DEPTH_TEST);
// selectionRender.drawColorBuffer();
// p.hint(PApplet.ENABLE_DEPTH_TEST);
// p.popMatrix();
- }
-
- private void drawSelection() {
- selectionRender.draw(sceneObjects);
- }
-
- public void drawSceneObjects() {
- for (SceneObject sceneObject : sceneObjects) {
- draw(sceneObject.getMesh(), sceneObject.getFillColor());
- }
- }
-
- public void draw(Mesh3D mesh, Color color) {
- p.pushStyle();
- vertices = mesh.vertices.size();
- faces = mesh.faces.size();
-
- if (!isWireframe()) {
- p.noStroke();
- p.fill(
- color.getRed(), color.getGreen(), color.getBlue(),
- color.getAlpha()
- );
- renderer.drawFaces(mesh, mesh.faces, getShading());
- p.stroke(0);
- } else {
- p.stroke(
- UiValues.getColor(UiConstants.KEY_EDITOR_WIREFRAME_COLOR)
- .getRGBA()
- );
- renderer.drawEdges(mesh);
- }
-
- if (isEdgesVisible())
- renderer.drawEdges(mesh);
-
- if (isFaceNormalsVisible()) {
- p.stroke(255);
- renderer.drawFaceNormals(mesh);
- }
-
- if (isVertexNormalsVisible()) {
- p.stroke(35, 97, 221);
- VertexNormals normals = new VertexNormals(mesh);
- renderer.drawVertexNormals(mesh, normals.getVertexNormals());
- }
- p.popStyle();
- }
-
- public void drawVertices(Mesh3D mesh) {
- p.pushStyle();
- p.stroke(255);
- p.fill(255);
- p.strokeWeight(0.08f);
- renderer.drawVertices(mesh);
- p.popStyle();
- }
-
- public void draw(Mesh3D mesh) {
- draw(mesh, new Color(220, 220, 220));
- }
-
- public void post() {
+ }
+
+ private void drawSelection() {
+ selectionRender.draw(sceneObjects);
+ }
+
+ public void drawSceneObjects() {
+ for (SceneObject sceneObject : sceneObjects) {
+ draw(sceneObject.getMesh(), sceneObject.getFillColor());
+ }
+ }
+
+ public void draw(Mesh3D mesh, Color color) {
+ p.pushStyle();
+ vertices = mesh.vertices.size();
+ faces = mesh.faces.size();
+
+ if (!isWireframe()) {
+ if (isEdgesVisible()) {
+ p.stroke(0);
+ } else {
+ p.noStroke();
+ }
+ p.fill(color.getRed(), color.getGreen(), color.getBlue(),
+ color.getAlpha());
+ renderer.drawFaces(mesh, mesh.faces, getShading());
+ } else {
+ p.stroke(
+ UiValues.getColor(UiConstants.KEY_EDITOR_WIREFRAME_COLOR).getRGBA());
+ renderer.drawEdges(mesh);
+ }
+
+// if (isEdgesVisible()) {
+// p.noFill();
+// renderer.drawEdges(mesh);
+// }
+
+ if (isFaceNormalsVisible()) {
+ p.stroke(255);
+ renderer.drawFaceNormals(mesh);
+ }
+
+ if (isVertexNormalsVisible()) {
+ p.stroke(35, 97, 221);
+ VertexNormals normals = new VertexNormals(mesh);
+ renderer.drawVertexNormals(mesh, normals.getVertexNormals());
+ }
+ p.popStyle();
+ }
+
+ public void drawVertices(Mesh3D mesh) {
+ p.pushStyle();
+ p.stroke(255);
+ p.fill(255);
+ p.strokeWeight(0.08f);
+ renderer.drawVertices(mesh);
+ p.popStyle();
+ }
+
+ public void draw(Mesh3D mesh) {
+ draw(mesh, new Color(220, 220, 220));
+ }
+
+ public void post() {
// p.saveFrame("output/workspace/workspace_demo####.png");
- }
-
- protected void onMouseDragged() {
- if (p.mouseButton != 3)
- return;
- float rx = getRotationX()
- + (p.pmouseY - p.mouseY) * PApplet.TWO_PI / 1000;
- float ry = getRotationY()
- - (p.pmouseX - p.mouseX) * PApplet.TWO_PI / 1000;
- setRotation(rx, ry, 0);
- }
-
- protected void onShiftMouseDragged() {
- if (p.mouseButton != 3)
- return;
- float panningX = getPanningX() - ((p.pmouseX - p.mouseX) * 2);
- float panningY = getPanningY() - ((p.pmouseY - p.mouseY) * 2);
- setPanningX(panningX);
- setPanningY(panningY);
- }
-
- private void handleSelection(int x, int y) {
- SceneObject sceneObject = null;
- String sceneObjectName = selectionRender.getObject(x, y);
-
- if (sceneObjectName != null) {
- for (SceneObject o : sceneObjects) {
- if (o.getName().equals(sceneObjectName)) {
- sceneObject = o;
- break;
- }
- }
- }
- selectedObject = sceneObject;
- }
-
- /**
- *
- * @param e
- */
- public void mouseEvent(MouseEvent e) {
- int action = e.getAction();
-
- switch (action) {
- case MouseEvent.CLICK:
- select = true;
- handleMouseClicked(e.getX(), e.getY());
- break;
- case MouseEvent.DRAG:
- handleMouseDragged(e.getX(), e.getY());
- if (e.isShiftDown()) {
- onShiftMouseDragged();
- break;
- }
- onMouseDragged();
- break;
- case MouseEvent.WHEEL:
- handleMouseWheel(e.getCount());
- break;
- }
- // Model?
- if (!isLoop())
- p.redraw();
- }
-
- public void keyEvent(KeyEvent e) {
- if (!isUseKeyBindings())
- return;
-
- if (e.getAction() != KeyEvent.TYPE)
- return;
-
- switch (e.getKey()) {
- case '4':
- if (!firstPersonView.isEnabled()) {
- setLoop(true);
- } else {
- p.redraw();
- }
- firstPersonView.setEnabled(!firstPersonView.isEnabled());
- commands.getCommand('s').setEnabled(!firstPersonView.isEnabled());
- break;
- default:
- commands.execute(e.getKey());
- break;
- }
- }
-
- protected String getInformationString() {
- StringBuffer buffer = new StringBuffer();
- buffer.append("Verts:");
- buffer.append(vertices);
- buffer.append(" | Faces:");
- buffer.append(faces);
- buffer.append(" | FPS:");
- buffer.append(p.frameRate);
- buffer.append(" | FrameCount:");
- buffer.append(p.frameCount);
- return buffer.toString();
- }
-
- public Mesh3DRenderer getRenderer() {
- return renderer;
- }
-
- public SceneObject getSceneObject(int mouseX, int mouseY) {
- String objectName = selectionRender.getObject(mouseX, mouseY);
-
- if (objectName == null)
- return null;
- for (SceneObject sceneObject : sceneObjects) {
- if (sceneObject.getName().equals(objectName)) {
- return sceneObject;
- }
- }
- return null;
- }
-
- public float getPanningX() {
- return model.getPanningX();
- }
-
- public void setPanningX(float panningX) {
- model.setPanningX(panningX);
- }
-
- public float getPanningY() {
- return model.getPanningY();
- }
-
- public void setPanningY(float panningY) {
- model.setPanningY(panningY);
- }
-
- public float getRotationX() {
- return model.getRotationX();
- }
-
- public float getRotationY() {
- return model.getRotationY();
- }
-
- public float getRotationZ() {
- return model.getRotationZ();
- }
-
- public void setRotation(float rx, float ry, float rz) {
- model.setRotation(rx, ry, rz);
- }
-
- public float getScale() {
- return model.getScale();
- }
-
- public void setScale(float scale) {
- model.setScale(scale);
- }
-
- public WorkspaceModel getModel() {
- return model;
- }
-
- public boolean isxAxisVisible() {
- return model.isxAxisVisible();
- }
-
- public void setxAxisVisible(boolean xAxisVisible) {
- model.setxAxisVisible(xAxisVisible);
- }
-
- public boolean isyAxisVisible() {
- return model.isyAxisVisible();
- }
-
- public void setyAxisVisible(boolean yAxisVisible) {
- model.setyAxisVisible(yAxisVisible);
- }
-
- public boolean iszAxisVisible() {
- return model.iszAxisVisible();
- }
-
- public void setzAxisVisible(boolean zAxisVisible) {
- model.setzAxisVisible(zAxisVisible);
- }
-
- public boolean isGridVisible() {
- return model.isGridVisible();
- }
-
- public void setGridVisible(boolean gridVisible) {
- model.setGridVisible(gridVisible);
- }
-
- public boolean isFaceNormalsVisible() {
- return model.isFaceNormalsVisible();
- }
-
- public void setFaceNormalsVisible(boolean faceNormalsVisible) {
- model.setFaceNormalsVisible(faceNormalsVisible);
- }
-
- public boolean isVertexNormalsVisible() {
- return model.isVertexNormalsVisible();
- }
-
- public void setVertexNormalsVisible(boolean vertexNormalsVisible) {
- model.setVertexNormalsVisible(vertexNormalsVisible);
- }
-
- public boolean isEdgesVisible() {
- return model.isEdgesVisible();
- }
-
- public void setEdgesVisible(boolean edgesVisible) {
- model.setEdgesVisible(edgesVisible);
- }
+ }
+
+ protected void onMouseDragged() {
+ if (p.mouseButton != 3)
+ return;
+ float rx = getRotationX() + (p.pmouseY - p.mouseY) * PApplet.TWO_PI / 1000;
+ float ry = getRotationY() - (p.pmouseX - p.mouseX) * PApplet.TWO_PI / 1000;
+ setRotation(rx, ry, 0);
+ }
+
+ protected void onShiftMouseDragged() {
+ if (p.mouseButton != 3)
+ return;
+ float panningX = getPanningX() - ((p.pmouseX - p.mouseX) * 2);
+ float panningY = getPanningY() - ((p.pmouseY - p.mouseY) * 2);
+ setPanningX(panningX);
+ setPanningY(panningY);
+ }
+
+ private void handleSelection(int x, int y) {
+ SceneObject sceneObject = null;
+ String sceneObjectName = selectionRender.getObject(x, y);
+
+ if (sceneObjectName != null) {
+ for (SceneObject o : sceneObjects) {
+ if (o.getName().equals(sceneObjectName)) {
+ sceneObject = o;
+ break;
+ }
+ }
+ }
+ selectedObject = sceneObject;
+ }
+
+ /**
+ *
+ * @param e
+ */
+ public void mouseEvent(MouseEvent e) {
+ int action = e.getAction();
+
+ switch (action) {
+ case MouseEvent.CLICK:
+ select = true;
+ handleMouseClicked(e.getX(), e.getY());
+ break;
+ case MouseEvent.DRAG:
+ handleMouseDragged(e.getX(), e.getY());
+ if (e.isShiftDown()) {
+ onShiftMouseDragged();
+ break;
+ }
+ onMouseDragged();
+ break;
+ case MouseEvent.WHEEL:
+ handleMouseWheel(e.getCount());
+ break;
+ case MouseEvent.RELEASE:
+ handleMouseReleased(e.getX(), e.getY());
+ break;
+ case MouseEvent.PRESS:
+ handleMousePressed(e.getX(), e.getY());
+ break;
+ }
+ // Model?
+ if (!isLoop())
+ p.redraw();
+ }
+
+ public void keyEvent(KeyEvent e) {
+ if (!isUseKeyBindings())
+ return;
+
+ if (e.getAction() != KeyEvent.TYPE)
+ return;
+
+ switch (e.getKey()) {
+ case '4':
+ if (!firstPersonView.isEnabled()) {
+ setLoop(true);
+ } else {
+ p.redraw();
+ }
+ firstPersonView.setEnabled(!firstPersonView.isEnabled());
+ commands.getCommand('s').setEnabled(!firstPersonView.isEnabled());
+ break;
+ default:
+ commands.execute(e.getKey());
+ break;
+ }
+ }
+
+ protected String getInformationString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("Verts:");
+ buffer.append(vertices);
+ buffer.append(" | Faces:");
+ buffer.append(faces);
+ buffer.append(" | FPS:");
+ buffer.append(p.frameRate);
+ buffer.append(" | FrameCount:");
+ buffer.append(p.frameCount);
+ return buffer.toString();
+ }
+
+ public Mesh3DRenderer getRenderer() {
+ return renderer;
+ }
+
+ public SceneObject getSceneObject(int mouseX, int mouseY) {
+ String objectName = selectionRender.getObject(mouseX, mouseY);
+
+ if (objectName == null)
+ return null;
+ for (SceneObject sceneObject : sceneObjects) {
+ if (sceneObject.getName().equals(objectName)) {
+ return sceneObject;
+ }
+ }
+ return null;
+ }
+
+ public float getPanningX() {
+ return model.getPanningX();
+ }
+
+ public void setPanningX(float panningX) {
+ model.setPanningX(panningX);
+ }
+
+ public float getPanningY() {
+ return model.getPanningY();
+ }
+
+ public void setPanningY(float panningY) {
+ model.setPanningY(panningY);
+ }
+
+ public float getRotationX() {
+ return model.getRotationX();
+ }
+
+ public float getRotationY() {
+ return model.getRotationY();
+ }
+
+ public float getRotationZ() {
+ return model.getRotationZ();
+ }
+
+ public void setRotation(float rx, float ry, float rz) {
+ model.setRotation(rx, ry, rz);
+ }
+
+ public float getScale() {
+ return model.getScale();
+ }
+
+ public void setScale(float scale) {
+ model.setScale(scale);
+ }
+
+ public WorkspaceModel getModel() {
+ return model;
+ }
+
+ public boolean isxAxisVisible() {
+ return model.isxAxisVisible();
+ }
+
+ public void setxAxisVisible(boolean xAxisVisible) {
+ model.setxAxisVisible(xAxisVisible);
+ }
+
+ public boolean isyAxisVisible() {
+ return model.isyAxisVisible();
+ }
+
+ public void setyAxisVisible(boolean yAxisVisible) {
+ model.setyAxisVisible(yAxisVisible);
+ }
+
+ public boolean iszAxisVisible() {
+ return model.iszAxisVisible();
+ }
+
+ public void setzAxisVisible(boolean zAxisVisible) {
+ model.setzAxisVisible(zAxisVisible);
+ }
+
+ public boolean isGridVisible() {
+ return model.isGridVisible();
+ }
+
+ public void setGridVisible(boolean gridVisible) {
+ model.setGridVisible(gridVisible);
+ }
+
+ public boolean isFaceNormalsVisible() {
+ return model.isFaceNormalsVisible();
+ }
+
+ public void setFaceNormalsVisible(boolean faceNormalsVisible) {
+ model.setFaceNormalsVisible(faceNormalsVisible);
+ }
+
+ public boolean isVertexNormalsVisible() {
+ return model.isVertexNormalsVisible();
+ }
+
+ public void setVertexNormalsVisible(boolean vertexNormalsVisible) {
+ model.setVertexNormalsVisible(vertexNormalsVisible);
+ }
+
+ public boolean isEdgesVisible() {
+ return model.isEdgesVisible();
+ }
+
+ public void setEdgesVisible(boolean edgesVisible) {
+ model.setEdgesVisible(edgesVisible);
+ }
- public boolean isUiVisible() {
- return model.isUiVisible();
- }
+ public boolean isUiVisible() {
+ return model.isUiVisible();
+ }
- public void setUiVisible(boolean uiVisible) {
- model.setUiVisible(uiVisible);
- }
+ public void setUiVisible(boolean uiVisible) {
+ model.setUiVisible(uiVisible);
+ }
- public boolean isWireframe() {
- return model.isWireframe();
- }
+ public boolean isWireframe() {
+ return model.isWireframe();
+ }
- public void setWireframe(boolean wireframe) {
- model.setWireframe(wireframe);
- }
+ public void setWireframe(boolean wireframe) {
+ model.setWireframe(wireframe);
+ }
- public boolean isLoop() {
- return model.isLoop();
- }
+ public boolean isLoop() {
+ return model.isLoop();
+ }
- public void setLoop(boolean loop) {
- model.setLoop(loop);
- }
+ public void setLoop(boolean loop) {
+ model.setLoop(loop);
+ }
- public boolean isUseKeyBindings() {
- return model.isUseKeyBindings();
- }
+ public boolean isUseKeyBindings() {
+ return model.isUseKeyBindings();
+ }
- public void setUseKeyBindings(boolean useKeyBindings) {
- model.setUseKeyBindings(useKeyBindings);
- }
+ public void setUseKeyBindings(boolean useKeyBindings) {
+ model.setUseKeyBindings(useKeyBindings);
+ }
- public Color getBackground() {
- return model.getBackground();
- }
+ public Color getBackground() {
+ return model.getBackground();
+ }
- public void setBackground(Color background) {
- model.setBackground(background);
- }
+ public void setBackground(Color background) {
+ model.setBackground(background);
+ }
- public Shading getShading() {
- return model.getShading();
- }
+ public Shading getShading() {
+ return model.getShading();
+ }
- public void setShading(Shading shading) {
- model.setShading(shading);
- }
+ public void setShading(Shading shading) {
+ model.setShading(shading);
+ }
}
diff --git a/src/main/java/workspace/WorkspaceModel.java b/src/main/java/workspace/WorkspaceModel.java
index c4d9387d..58acd851 100644
--- a/src/main/java/workspace/WorkspaceModel.java
+++ b/src/main/java/workspace/WorkspaceModel.java
@@ -11,323 +11,323 @@
public class WorkspaceModel {
- private float panningX;
+ private float panningX;
- private float panningY;
+ private float panningY;
- private float rotationX;
+ private float rotationX;
- private float rotationY;
+ private float rotationY;
- private float rotationZ;
+ private float rotationZ;
- private float scale;
+ private float scale;
- private float minScale;
+ private float minScale;
- private float maxScale;
+ private float maxScale;
- private boolean xAxisVisible;
+ private boolean xAxisVisible;
- private boolean yAxisVisible;
+ private boolean yAxisVisible;
- private boolean zAxisVisible;
+ private boolean zAxisVisible;
- private boolean gridVisible;
+ private boolean gridVisible;
- private boolean faceNormalsVisible;
+ private boolean faceNormalsVisible;
- private boolean vertexNormalsVisible;
+ private boolean vertexNormalsVisible;
- private boolean edgesVisible;
+ private boolean edgesVisible;
- private boolean uiVisible;
+ private boolean uiVisible;
- private boolean wireframe;
+ private boolean wireframe;
- private boolean loop;
+ private boolean loop;
- private boolean useKeyBindings;
+ private boolean useKeyBindings;
- private Shading shading;
+ private Shading shading;
- private Color background;
+ private Color background;
- private List listeners;
+ private List listeners;
- public WorkspaceModel() {
- scale = 100;
- minScale = 1;
- maxScale = 1000;
- rotationX = Mathf.toRadians(-30);
- rotationY = Mathf.toRadians(30);
- xAxisVisible = false;
- yAxisVisible = false;
- zAxisVisible = false;
- gridVisible = false;
- faceNormalsVisible = false;
- vertexNormalsVisible = false;
- edgesVisible = true;
- uiVisible = true;
- wireframe = false;
- loop = false;
- useKeyBindings = true;
- shading = Shading.FLAT;
- background = UiValues.getColor(UiConstants.KEY_EDITOR_BACKGROUND_COLOR);
- listeners = new ArrayList();
- }
-
- public float getPanningX() {
- return panningX;
- }
-
- public void setPanningX(float panningX) {
- if (this.panningX == panningX)
- return;
- this.panningX = panningX;
- fireChangeEvent();
- }
-
- public float getPanningY() {
- return panningY;
- }
-
- public void setPanningY(float panningY) {
- if (this.panningY == panningY)
- return;
- this.panningY = panningY;
- fireChangeEvent();
- }
-
- public float getRotationX() {
- return rotationX;
- }
-
- public void setRotationX(float rotationX) {
- if (this.rotationX == rotationX)
- return;
- this.rotationX = rotationX;
- fireChangeEvent();
- }
-
- public float getRotationY() {
- return rotationY;
- }
-
- public void setRotationY(float rotationY) {
- if (this.rotationY == rotationY)
- return;
- this.rotationY = rotationY;
- fireChangeEvent();
- }
-
- public float getRotationZ() {
- return rotationZ;
- }
-
- public void setRotationZ(float rotationZ) {
- if (this.rotationZ == rotationZ)
- return;
- this.rotationZ = rotationZ;
- fireChangeEvent();
- }
-
- public void setRotation(float rx, float ry, float rz) {
- if (rotationX == rx && rotationY == ry && rotationZ == rz)
- return;
- rotationX = rx;
- rotationY = ry;
- rotationZ = rz;
- fireChangeEvent();
- }
-
- public float getScale() {
- return scale;
- }
-
- public void setScale(float scale) {
- scale = Mathf.clamp(scale, getMinScale(), getMaxScale());
- if (this.scale == scale)
- return;
- this.scale = scale;
- fireChangeEvent();
- }
-
- public float getMinScale() {
- return minScale;
- }
-
- public void setMinScale(float minScale) {
- if (this.minScale == minScale)
- return;
- this.minScale = minScale;
- fireChangeEvent();
- }
-
- public float getMaxScale() {
- return maxScale;
- }
-
- public void setMaxScale(float maxScale) {
- if (this.maxScale == maxScale)
- return;
- this.maxScale = maxScale;
- fireChangeEvent();
- }
-
- public boolean isxAxisVisible() {
- return xAxisVisible;
- }
-
- public void setxAxisVisible(boolean xAxisVisible) {
- if (this.xAxisVisible == xAxisVisible)
- return;
- this.xAxisVisible = xAxisVisible;
- fireChangeEvent();
- }
-
- public boolean isyAxisVisible() {
- return yAxisVisible;
- }
-
- public void setyAxisVisible(boolean yAxisVisible) {
- if (this.yAxisVisible == yAxisVisible)
- return;
- this.yAxisVisible = yAxisVisible;
- fireChangeEvent();
- }
-
- public boolean iszAxisVisible() {
- return zAxisVisible;
- }
-
- public void setzAxisVisible(boolean zAxisVisible) {
- if (this.zAxisVisible == zAxisVisible)
- return;
- this.zAxisVisible = zAxisVisible;
- fireChangeEvent();
- }
-
- public boolean isGridVisible() {
- return gridVisible;
- }
-
- public void setGridVisible(boolean gridVisible) {
- if (this.gridVisible == gridVisible)
- return;
- this.gridVisible = gridVisible;
- fireChangeEvent();
- }
-
- public boolean isFaceNormalsVisible() {
- return faceNormalsVisible;
- }
-
- public void setFaceNormalsVisible(boolean faceNormalsVisible) {
- if (this.faceNormalsVisible == faceNormalsVisible)
- return;
- this.faceNormalsVisible = faceNormalsVisible;
- fireChangeEvent();
- }
-
- public boolean isVertexNormalsVisible() {
- return vertexNormalsVisible;
- }
-
- public void setVertexNormalsVisible(boolean vertexNormalsVisible) {
- if (this.vertexNormalsVisible == vertexNormalsVisible)
- return;
- this.vertexNormalsVisible = vertexNormalsVisible;
- fireChangeEvent();
- }
-
- public boolean isEdgesVisible() {
- return edgesVisible;
- }
-
- public void setEdgesVisible(boolean edgesVisible) {
- if (this.edgesVisible == edgesVisible)
- return;
- this.edgesVisible = edgesVisible;
- fireChangeEvent();
- }
-
- public boolean isUiVisible() {
- return uiVisible;
- }
-
- public void setUiVisible(boolean uiVisible) {
- if (this.uiVisible == uiVisible)
- return;
- this.uiVisible = uiVisible;
- fireChangeEvent();
- }
-
- public boolean isWireframe() {
- return wireframe;
- }
-
- public void setWireframe(boolean wireframe) {
- if (this.wireframe == wireframe)
- return;
- this.wireframe = wireframe;
- fireChangeEvent();
- }
-
- public boolean isLoop() {
- return loop;
- }
-
- public void setLoop(boolean loop) {
- if (this.loop == loop)
- return;
- this.loop = loop;
- fireChangeEvent();
- }
-
- public Shading getShading() {
- return shading;
- }
-
- public void setShading(Shading shading) {
- if (this.shading == shading)
- return;
- this.shading = shading;
- fireChangeEvent();
- }
-
- public Color getBackground() {
- return background;
- }
-
- public void setBackground(Color background) {
- if (this.background.equals(background))
- return;
- this.background = background;
- fireChangeEvent();
- }
-
- public boolean isUseKeyBindings() {
- return useKeyBindings;
- }
-
- public void setUseKeyBindings(boolean useKeyBindings) {
- if (this.useKeyBindings == useKeyBindings)
- return;
- this.useKeyBindings = useKeyBindings;
- fireChangeEvent();
- }
-
- public void fireChangeEvent() {
- for (ModelListener l : listeners) {
- l.onModelChanged();
- }
- }
-
- public void addListener(ModelListener listener) {
- if (listener == null)
- return;
- listeners.add(listener);
- }
+ public WorkspaceModel() {
+ scale = 100;
+ minScale = 1;
+ maxScale = 1000;
+ rotationX = Mathf.toRadians(-30);
+ rotationY = Mathf.toRadians(30);
+ xAxisVisible = false;
+ yAxisVisible = false;
+ zAxisVisible = false;
+ gridVisible = false;
+ faceNormalsVisible = false;
+ vertexNormalsVisible = false;
+ edgesVisible = true;
+ uiVisible = true;
+ wireframe = false;
+ loop = false;
+ useKeyBindings = true;
+ shading = Shading.FLAT;
+ background = UiValues.getColor(UiConstants.KEY_EDITOR_BACKGROUND_COLOR);
+ listeners = new ArrayList();
+ }
+
+ public float getPanningX() {
+ return panningX;
+ }
+
+ public void setPanningX(float panningX) {
+ if (this.panningX == panningX)
+ return;
+ this.panningX = panningX;
+ fireChangeEvent();
+ }
+
+ public float getPanningY() {
+ return panningY;
+ }
+
+ public void setPanningY(float panningY) {
+ if (this.panningY == panningY)
+ return;
+ this.panningY = panningY;
+ fireChangeEvent();
+ }
+
+ public float getRotationX() {
+ return rotationX;
+ }
+
+ public void setRotationX(float rotationX) {
+ if (this.rotationX == rotationX)
+ return;
+ this.rotationX = rotationX;
+ fireChangeEvent();
+ }
+
+ public float getRotationY() {
+ return rotationY;
+ }
+
+ public void setRotationY(float rotationY) {
+ if (this.rotationY == rotationY)
+ return;
+ this.rotationY = rotationY;
+ fireChangeEvent();
+ }
+
+ public float getRotationZ() {
+ return rotationZ;
+ }
+
+ public void setRotationZ(float rotationZ) {
+ if (this.rotationZ == rotationZ)
+ return;
+ this.rotationZ = rotationZ;
+ fireChangeEvent();
+ }
+
+ public void setRotation(float rx, float ry, float rz) {
+ if (rotationX == rx && rotationY == ry && rotationZ == rz)
+ return;
+ rotationX = rx;
+ rotationY = ry;
+ rotationZ = rz;
+ fireChangeEvent();
+ }
+
+ public float getScale() {
+ return scale;
+ }
+
+ public void setScale(float scale) {
+ scale = Mathf.clamp(scale, getMinScale(), getMaxScale());
+ if (this.scale == scale)
+ return;
+ this.scale = scale;
+ fireChangeEvent();
+ }
+
+ public float getMinScale() {
+ return minScale;
+ }
+
+ public void setMinScale(float minScale) {
+ if (this.minScale == minScale)
+ return;
+ this.minScale = minScale;
+ fireChangeEvent();
+ }
+
+ public float getMaxScale() {
+ return maxScale;
+ }
+
+ public void setMaxScale(float maxScale) {
+ if (this.maxScale == maxScale)
+ return;
+ this.maxScale = maxScale;
+ fireChangeEvent();
+ }
+
+ public boolean isxAxisVisible() {
+ return xAxisVisible;
+ }
+
+ public void setxAxisVisible(boolean xAxisVisible) {
+ if (this.xAxisVisible == xAxisVisible)
+ return;
+ this.xAxisVisible = xAxisVisible;
+ fireChangeEvent();
+ }
+
+ public boolean isyAxisVisible() {
+ return yAxisVisible;
+ }
+
+ public void setyAxisVisible(boolean yAxisVisible) {
+ if (this.yAxisVisible == yAxisVisible)
+ return;
+ this.yAxisVisible = yAxisVisible;
+ fireChangeEvent();
+ }
+
+ public boolean iszAxisVisible() {
+ return zAxisVisible;
+ }
+
+ public void setzAxisVisible(boolean zAxisVisible) {
+ if (this.zAxisVisible == zAxisVisible)
+ return;
+ this.zAxisVisible = zAxisVisible;
+ fireChangeEvent();
+ }
+
+ public boolean isGridVisible() {
+ return gridVisible;
+ }
+
+ public void setGridVisible(boolean gridVisible) {
+ if (this.gridVisible == gridVisible)
+ return;
+ this.gridVisible = gridVisible;
+ fireChangeEvent();
+ }
+
+ public boolean isFaceNormalsVisible() {
+ return faceNormalsVisible;
+ }
+
+ public void setFaceNormalsVisible(boolean faceNormalsVisible) {
+ if (this.faceNormalsVisible == faceNormalsVisible)
+ return;
+ this.faceNormalsVisible = faceNormalsVisible;
+ fireChangeEvent();
+ }
+
+ public boolean isVertexNormalsVisible() {
+ return vertexNormalsVisible;
+ }
+
+ public void setVertexNormalsVisible(boolean vertexNormalsVisible) {
+ if (this.vertexNormalsVisible == vertexNormalsVisible)
+ return;
+ this.vertexNormalsVisible = vertexNormalsVisible;
+ fireChangeEvent();
+ }
+
+ public boolean isEdgesVisible() {
+ return edgesVisible;
+ }
+
+ public void setEdgesVisible(boolean edgesVisible) {
+ if (this.edgesVisible == edgesVisible)
+ return;
+ this.edgesVisible = edgesVisible;
+ fireChangeEvent();
+ }
+
+ public boolean isUiVisible() {
+ return uiVisible;
+ }
+
+ public void setUiVisible(boolean uiVisible) {
+ if (this.uiVisible == uiVisible)
+ return;
+ this.uiVisible = uiVisible;
+ fireChangeEvent();
+ }
+
+ public boolean isWireframe() {
+ return wireframe;
+ }
+
+ public void setWireframe(boolean wireframe) {
+ if (this.wireframe == wireframe)
+ return;
+ this.wireframe = wireframe;
+ fireChangeEvent();
+ }
+
+ public boolean isLoop() {
+ return loop;
+ }
+
+ public void setLoop(boolean loop) {
+ if (this.loop == loop)
+ return;
+ this.loop = loop;
+ fireChangeEvent();
+ }
+
+ public Shading getShading() {
+ return shading;
+ }
+
+ public void setShading(Shading shading) {
+ if (this.shading == shading)
+ return;
+ this.shading = shading;
+ fireChangeEvent();
+ }
+
+ public Color getBackground() {
+ return background;
+ }
+
+ public void setBackground(Color background) {
+ if (this.background.equals(background))
+ return;
+ this.background = background;
+ fireChangeEvent();
+ }
+
+ public boolean isUseKeyBindings() {
+ return useKeyBindings;
+ }
+
+ public void setUseKeyBindings(boolean useKeyBindings) {
+ if (this.useKeyBindings == useKeyBindings)
+ return;
+ this.useKeyBindings = useKeyBindings;
+ fireChangeEvent();
+ }
+
+ public void fireChangeEvent() {
+ for (ModelListener l : listeners) {
+ l.onModelChanged();
+ }
+ }
+
+ public void addListener(ModelListener listener) {
+ if (listener == null)
+ return;
+ listeners.add(listener);
+ }
}
diff --git a/src/main/java/workspace/WorkspaceSideBarUi.java b/src/main/java/workspace/WorkspaceSideBarUi.java
index 66435b60..0679e4be 100644
--- a/src/main/java/workspace/WorkspaceSideBarUi.java
+++ b/src/main/java/workspace/WorkspaceSideBarUi.java
@@ -3,11 +3,11 @@
import workspace.laf.UiValues;
import workspace.render.Shading;
import workspace.ui.Color;
-import workspace.ui.IActionListener;
-import workspace.ui.UiCheckBox;
import workspace.ui.UiComponent;
-import workspace.ui.UiLabel;
-import workspace.ui.UiPanel;
+import workspace.ui.elements.UiCheckBox;
+import workspace.ui.elements.UiLabel;
+import workspace.ui.elements.UiPanel;
+import workspace.ui.event.IActionListener;
public class WorkspaceSideBarUi extends UiComponent implements ModelListener {
@@ -82,7 +82,7 @@ protected UiLabel getUiLabel() {
if (label != null)
return label;
- label = new UiLabel();
+ label = new UiLabel("");
label.setX(xOffset);
label.setY(yOffset);
label.setTitle("Controls:");
diff --git a/src/main/java/workspace/laf/LookAndFeel.java b/src/main/java/workspace/laf/LookAndFeel.java
index cc131e6f..6688e8e2 100644
--- a/src/main/java/workspace/laf/LookAndFeel.java
+++ b/src/main/java/workspace/laf/LookAndFeel.java
@@ -4,48 +4,35 @@
public class LookAndFeel {
- public static void setup() {
- setupGizmo();
- setupAxis();
- setupMenu();
- UiValues.put(
- UiConstants.KEY_EDITOR_BACKGROUND_COLOR, new Color(60, 60, 60)
- );
- UiValues.put(UiConstants.KEY_GRID_COLOR, new Color(74, 74, 74));
- UiValues.put(
- UiConstants.KEY_EDITOR_WIREFRAME_COLOR, new Color(241, 152, 45)
- );
- }
+ public static void setup() {
+ setupGizmo();
+ setupAxis();
+ setupMenu();
+ UiValues.put(UiConstants.KEY_EDITOR_BACKGROUND_COLOR,
+ new Color(60, 60, 60));
+ UiValues.put(UiConstants.KEY_GRID_COLOR, new Color(74, 74, 74));
+ UiValues.put(UiConstants.KEY_EDITOR_WIREFRAME_COLOR,
+ new Color(241, 152, 45));
+ }
- private static void setupAxis() {
- UiValues.put(UiConstants.KEY_AXIS_X_COLOR, new Color(157, 67, 80));
- UiValues.put(UiConstants.KEY_AXIS_Y_COLOR, new Color(109, 148, 46));
- UiValues.put(UiConstants.KEY_AXIS_Z_COLOR, new Color(63, 112, 162));
- }
+ private static void setupAxis() {
+ UiValues.put(UiConstants.KEY_AXIS_X_COLOR, new Color(157, 67, 80));
+ UiValues.put(UiConstants.KEY_AXIS_Y_COLOR, new Color(109, 148, 46));
+ UiValues.put(UiConstants.KEY_AXIS_Z_COLOR, new Color(63, 112, 162));
+ }
- private static void setupGizmo() {
- UiValues.put(
- UiConstants.KEY_GIZMO_AXIS_X_COLOR, new Color(221, 56, 79)
- );
- UiValues.put(
- UiConstants.KEY_GIZMO_AXIS_Y_COLOR, new Color(120, 181, 22)
- );
- UiValues.put(
- UiConstants.KEY_GIZMO_AXIS_Z_COLOR, new Color(44, 142, 252)
- );
- UiValues.put(
- UiConstants.KEY_GIZMO_CENTER_COLOR, new Color(200, 200, 200)
- );
- }
+ private static void setupGizmo() {
+ UiValues.put(UiConstants.KEY_GIZMO_AXIS_X_COLOR, new Color(221, 56, 79));
+ UiValues.put(UiConstants.KEY_GIZMO_AXIS_Y_COLOR, new Color(120, 181, 22));
+ UiValues.put(UiConstants.KEY_GIZMO_AXIS_Z_COLOR, new Color(44, 142, 252));
+ UiValues.put(UiConstants.KEY_GIZMO_CENTER_COLOR, new Color(200, 200, 200));
+ }
- private static void setupMenu() {
- UiValues.put(
- UiConstants.KEY_MENU_FOREGROUND_COLOR, new Color(151, 151, 151)
- );
- UiValues.put(
- UiConstants.KEY_MENU_BACKGROUND_COLOR, new Color(35, 35, 35)
- );
- UiValues.put(UiConstants.KEY_MENU_TEXT_SIZE, 12);
- }
+ private static void setupMenu() {
+ UiValues.put(UiConstants.KEY_MENU_FOREGROUND_COLOR,
+ new Color(151, 151, 151));
+ UiValues.put(UiConstants.KEY_MENU_BACKGROUND_COLOR, new Color(35, 35, 35));
+ UiValues.put(UiConstants.KEY_MENU_TEXT_SIZE, 12);
+ }
}
diff --git a/src/main/java/workspace/laf/UiConstants.java b/src/main/java/workspace/laf/UiConstants.java
index 85449492..df9c3059 100644
--- a/src/main/java/workspace/laf/UiConstants.java
+++ b/src/main/java/workspace/laf/UiConstants.java
@@ -2,30 +2,30 @@
public class UiConstants {
- public static final String KEY_AXIS_X_COLOR = "Axis.x.color";
+ public static final String KEY_AXIS_X_COLOR = "Axis.x.color";
- public static final String KEY_AXIS_Y_COLOR = "Axis.y.color";
+ public static final String KEY_AXIS_Y_COLOR = "Axis.y.color";
- public static final String KEY_AXIS_Z_COLOR = "Axis.z.color";
+ public static final String KEY_AXIS_Z_COLOR = "Axis.z.color";
- public static final String KEY_GRID_COLOR = "Grid.color";
+ public static final String KEY_GRID_COLOR = "Grid.color";
- public static final String KEY_EDITOR_BACKGROUND_COLOR = "Editor.background.color";
+ public static final String KEY_EDITOR_BACKGROUND_COLOR = "Editor.background.color";
- public static final String KEY_EDITOR_WIREFRAME_COLOR = "Editor.wireframe.color";
+ public static final String KEY_EDITOR_WIREFRAME_COLOR = "Editor.wireframe.color";
- public static final String KEY_GIZMO_AXIS_X_COLOR = "Gizmo.x.color";
+ public static final String KEY_GIZMO_AXIS_X_COLOR = "Gizmo.x.color";
- public static final String KEY_GIZMO_AXIS_Y_COLOR = "Gizmo.y.color";
+ public static final String KEY_GIZMO_AXIS_Y_COLOR = "Gizmo.y.color";
- public static final String KEY_GIZMO_AXIS_Z_COLOR = "Gizmo.z.color";
+ public static final String KEY_GIZMO_AXIS_Z_COLOR = "Gizmo.z.color";
- public static final String KEY_GIZMO_CENTER_COLOR = "Gizmo.center.color";
+ public static final String KEY_GIZMO_CENTER_COLOR = "Gizmo.center.color";
- public static final String KEY_MENU_FOREGROUND_COLOR = "Menu.foreground.color";
+ public static final String KEY_MENU_FOREGROUND_COLOR = "Menu.foreground.color";
- public static final String KEY_MENU_BACKGROUND_COLOR = "Menu.background.color";
+ public static final String KEY_MENU_BACKGROUND_COLOR = "Menu.background.color";
- public static final String KEY_MENU_TEXT_SIZE = "Menu.text.size";
+ public static final String KEY_MENU_TEXT_SIZE = "Menu.text.size";
}
diff --git a/src/main/java/workspace/laf/UiValues.java b/src/main/java/workspace/laf/UiValues.java
index 44b9a5c7..52c92a72 100644
--- a/src/main/java/workspace/laf/UiValues.java
+++ b/src/main/java/workspace/laf/UiValues.java
@@ -7,38 +7,38 @@
public class UiValues {
- public static final Color UI_ELEMENT_FOREGROUND = new Color(250, 250, 250);
+ public static final Color UI_ELEMENT_FOREGROUND = new Color(250, 250, 250);
- public static final Color BASE_BLUE = new Color(82, 120, 180);
+ public static final Color BASE_BLUE = new Color(82, 120, 180);
- public static final Color BASE_ORANGE = new Color(199, 135, 83);
+ public static final Color BASE_ORANGE = new Color(199, 135, 83);
- public static final Color SLIDER_BACKGROUND_COLOR = new Color(35, 35, 35);
+ public static final Color SLIDER_BACKGROUND_COLOR = new Color(35, 35, 35);
- public static final Color SLIDER_LIGHT = new Color(89, 89, 89);
+ public static final Color SLIDER_LIGHT = new Color(89, 89, 89);
// public static final float TEXT_SIZE = 12;
- private static HashMap mappings;
+ private static HashMap mappings;
- static {
- mappings = new HashMap();
- }
+ static {
+ mappings = new HashMap();
+ }
- public static void put(String key, Object value) {
- mappings.put(key, value);
- }
+ public static void put(String key, Object value) {
+ mappings.put(key, value);
+ }
- public static Color getColor(String key) {
- return (Color) mappings.get(key);
- }
+ public static Color getColor(String key) {
+ return (Color) mappings.get(key);
+ }
- public static Font getFont(String key) {
- return (Font) mappings.get(key);
- }
+ public static Font getFont(String key) {
+ return (Font) mappings.get(key);
+ }
- public static int getInt(String key) {
- return (int) mappings.get(key);
- }
+ public static int getInt(String key) {
+ return (int) mappings.get(key);
+ }
}
diff --git a/src/main/java/workspace/ui/Color.java b/src/main/java/workspace/ui/Color.java
index 1b3cceb6..27df6f3a 100644
--- a/src/main/java/workspace/ui/Color.java
+++ b/src/main/java/workspace/ui/Color.java
@@ -2,89 +2,89 @@
public class Color {
- public static final Color BLACK = new Color(0, 0, 0, 255);
+ public static final Color BLACK = new Color(0, 0, 0, 255);
- public static final Color WHITE = new Color(255, 255, 255, 255);
+ public static final Color WHITE = new Color(255, 255, 255, 255);
- public static final Color RED = new Color(255, 0, 0, 255);
+ public static final Color RED = new Color(255, 0, 0, 255);
- public static final Color GREEN = new Color(0, 255, 0, 255);
+ public static final Color GREEN = new Color(0, 255, 0, 255);
- public static final Color BLUE = new Color(0, 0, 255, 255);
+ public static final Color BLUE = new Color(0, 0, 255, 255);
- public static final Color YELLOW = new Color(255, 255, 0, 255);
+ public static final Color YELLOW = new Color(255, 255, 0, 255);
- public static final Color MAGENTA = new Color(255, 0, 255, 255);
+ public static final Color MAGENTA = new Color(255, 0, 255, 255);
- public static final Color ORANGE = new Color(255, 200, 0, 255);
+ public static final Color ORANGE = new Color(255, 200, 0, 255);
- public static final Color CYAN = new Color(0, 255, 255, 255);
+ public static final Color CYAN = new Color(0, 255, 255, 255);
- public static final Color GRAY = new Color(128, 128, 128, 255);
+ public static final Color GRAY = new Color(128, 128, 128, 255);
- public static final Color DARK_GRAY = new Color(64, 64, 64, 255);
+ public static final Color DARK_GRAY = new Color(64, 64, 64, 255);
- public static final Color LIGHT_GRAY = new Color(192, 192, 192, 255);
+ public static final Color LIGHT_GRAY = new Color(192, 192, 192, 255);
- public static final Color PINK = new Color(255, 175, 175, 255);
+ public static final Color PINK = new Color(255, 175, 175, 255);
- private int red;
+ private int red;
- private int green;
+ private int green;
- private int blue;
+ private int blue;
- private int alpha;
+ private int alpha;
- public Color(int red, int green, int blue) {
- this.red = red;
- this.green = green;
- this.blue = blue;
- this.alpha = 255;
- }
+ public Color(int red, int green, int blue) {
+ this.red = red;
+ this.green = green;
+ this.blue = blue;
+ this.alpha = 255;
+ }
- public Color(int red, int green, int blue, int alpha) {
- this.red = red;
- this.green = green;
- this.blue = blue;
- this.alpha = alpha;
- }
+ public Color(int red, int green, int blue, int alpha) {
+ this.red = red;
+ this.green = green;
+ this.blue = blue;
+ this.alpha = alpha;
+ }
- public int getRGBA() {
- return ((alpha & 0xFF) << 24) | ((red & 0xFF) << 16)
- | ((green & 0xFF) << 8) | ((blue & 0xFF) << 0);
- }
+ public int getRGBA() {
+ return ((alpha & 0xFF) << 24) | ((red & 0xFF) << 16) | ((green & 0xFF) << 8)
+ | ((blue & 0xFF) << 0);
+ }
- public int getRed() {
- return red;
- }
+ public int getRed() {
+ return red;
+ }
- public void setRed(int red) {
- this.red = red;
- }
+ public void setRed(int red) {
+ this.red = red;
+ }
- public int getGreen() {
- return green;
- }
+ public int getGreen() {
+ return green;
+ }
- public void setGreen(int green) {
- this.green = green;
- }
+ public void setGreen(int green) {
+ this.green = green;
+ }
- public int getBlue() {
- return blue;
- }
+ public int getBlue() {
+ return blue;
+ }
- public void setBlue(int blue) {
- this.blue = blue;
- }
+ public void setBlue(int blue) {
+ this.blue = blue;
+ }
- public int getAlpha() {
- return alpha;
- }
+ public int getAlpha() {
+ return alpha;
+ }
- public void setAlpha(int alpha) {
- this.alpha = alpha;
- }
+ public void setAlpha(int alpha) {
+ this.alpha = alpha;
+ }
}
diff --git a/src/main/java/workspace/ui/Graphics.java b/src/main/java/workspace/ui/Graphics.java
index a18ab463..1d7d95dc 100644
--- a/src/main/java/workspace/ui/Graphics.java
+++ b/src/main/java/workspace/ui/Graphics.java
@@ -4,48 +4,58 @@
public interface Graphics {
- int getWidth();
+ int getWidth();
- int getHeight();
+ int getHeight();
- void pushMatrix();
+ void pushMatrix();
- void popMatrix();
+ void popMatrix();
- void translate(float x, float y);
+ void translate(float x, float y);
- void strokeWeight(float weight);
+ void strokeWeight(float weight);
- void setColor(Color color);
+ void setColor(Color color);
- void setColor(int red, int green, int blue);
+ void setColor(math.Color color);
- void drawRect(float x, float y, float width, float height);
+ void setColor(int red, int green, int blue);
- void fillRect(float x, float y, float width, float height);
+ void drawRect(float x, float y, float width, float height);
- void fillFaces(Mesh3D mesh);
+ void fillRect(float x, float y, float width, float height);
- void textSize(float size);
+ void drawOval(float x, float y, float width, float height);
- float getTextSize();
+ void fillOval(float x, float y, float width, float height);
- float textWidth(String text);
+ void drawLine(float x1, float y1, float x2, float y2);
- float textAscent();
+ void fillFaces(Mesh3D mesh);
- float textDescent();
+ void textSize(float size);
- void text(String text, float x, float y);
+ float getTextSize();
- void enableDepthTest();
+ float textWidth(String text);
- void disableDepthTest();
+ float textAscent();
- void rotateX(float angle);
+ float textDescent();
- void rotateY(float angle);
+ void text(String text, float x, float y);
- void rotateZ(float angle);
+ void enableDepthTest();
+
+ void disableDepthTest();
+
+ void rotate(float angle);
+
+ void rotateX(float angle);
+
+ void rotateY(float angle);
+
+ void rotateZ(float angle);
}
diff --git a/src/main/java/workspace/ui/Slider.java b/src/main/java/workspace/ui/Slider.java
index 3a14574c..5a6f17f1 100644
--- a/src/main/java/workspace/ui/Slider.java
+++ b/src/main/java/workspace/ui/Slider.java
@@ -3,88 +3,115 @@
import math.Mathf;
import workspace.laf.UiValues;
import workspace.ui.border.Insets;
+import workspace.ui.event.ISliderCallBack;
public class Slider extends UiComponent {
- private float value;
+ private float value;
- private float minValue = 0;
+ private float minValue = 0;
- private float maxValue = 3;
+ private float maxValue = 3;
- private float posX;
+ private float posX;
- private ISliderCallBack sliderCallBack;
+ private ISliderCallBack sliderCallBack;
- private String text = "Slider";
+ private String text = "Slider";
- @Override
- public void onDraw(Graphics g) {
- Insets insets = getInsets();
+ @Override
+ public void renderSelf(Graphics g) {
+ Insets insets = getInsets();
- g.setColor(getBackground());
- g.fillRect(
- insets.left, insets.right, width - insets.getWidth(),
- height - insets.getHeight()
- );
+ g.setColor(getBackground());
+ g.fillRect(insets.getLeft(), insets.getRight(),
+ width - insets.getHorizontalInsets(),
+ height - insets.getVerticalInsets());
- g.setColor(getForeground());
- g.fillRect(getWidth() + posX, 0, 5, getHeight());
+ g.setColor(getForeground());
+ g.fillRect(getWidth() + posX, 0, 5, getHeight());
- g.setColor(UiValues.SLIDER_LIGHT);
- g.fillRect(0, 0, getWidth() + posX, getHeight());
+ g.setColor(UiValues.SLIDER_LIGHT);
+ g.fillRect(0, 0, getWidth() + posX, getHeight());
- g.setColor(foreground);
- g.text(" " + value, 4, g.getTextSize() + g.textDescent());
- g.text(text, getWidth() + 10, g.getTextSize() + g.textDescent());
- }
+ g.setColor(foreground);
+ g.text(" " + value, 4, g.getTextSize() + g.textDescent());
+ g.text(text, getWidth() + 10, g.getTextSize() + g.textDescent());
+ }
- public void onMouseDragged(int x, int y) {
- posX = x - getWidth() - getX();
- updateValue();
- if (sliderCallBack != null)
- sliderCallBack.valueChanged(value);
- }
+ public void onMouseDragged(int x, int y) {
+ posX = x - getWidth() - getX();
+ clampPosX(); // Ensure posX stays within bounds
+ updateValue();
+ if (sliderCallBack != null)
+ sliderCallBack.valueChanged(value);
+ }
- @Override
- public void onMouseClicked(int x, int y) {
+ @Override
+ public void onMouseClicked(int x, int y) {
+ // Optionally, jump posX to the clicked position
+ }
- }
+ private void updateValue() {
+ // Map posX to the slider's value range
+// value = Mathf.map(posX, 0, getWidth(), minValue, maxValue);
+// value = Mathf.clamp(value, minValue, maxValue); // Ensure value stays in range
+ value = maxValue + Mathf.map(posX, 0, getWidth(), minValue, maxValue);
+ }
- private void updateValue() {
- value = maxValue + Mathf.map(posX, 0, getWidth(), minValue, maxValue);
- }
+ private void updatePosX() {
+// posX = Mathf.map(value, minValue, maxValue, x, x + width);
- public String getText() {
- return text;
- }
+ // Map value back to posX
+// posX = Mathf.map(value, minValue, maxValue, x, x + getWidth());
+// clampPosX(); // Ensure posX stays within bounds
+ }
- public void setText(String text) {
- this.text = text;
- }
+ private void clampPosX() {
+// // Ensure posX doesn't exceed slider's drawable area
+// posX = Mathf.clamp(posX, 0, getWidth());
+ }
- public ISliderCallBack getSliderCallBack() {
- return sliderCallBack;
- }
+ public float getValue() {
+ return value;
+ }
- public void setSliderCallBack(ISliderCallBack sliderCallBack) {
- this.sliderCallBack = sliderCallBack;
- }
+ public void setValue(float value) {
+// this.value = Mathf.clamp(value, minValue, maxValue); // Clamp the value
+ updatePosX(); // Update posX to reflect the new value
+ }
- public float getMinValue() {
- return minValue;
- }
+ public String getText() {
+ return text;
+ }
- public void setMinValue(float minValue) {
- this.minValue = minValue;
- }
+ public void setText(String text) {
+ this.text = text;
+ }
- public float getMaxValue() {
- return maxValue;
- }
+ public ISliderCallBack getSliderCallBack() {
+ return sliderCallBack;
+ }
- public void setMaxValue(float maxValue) {
- this.maxValue = maxValue;
- }
+ public void setSliderCallBack(ISliderCallBack sliderCallBack) {
+ this.sliderCallBack = sliderCallBack;
+ }
-}
+ public float getMinValue() {
+ return minValue;
+ }
+
+ public void setMinValue(float minValue) {
+ this.minValue = minValue;
+ updatePosX(); // Update posX to reflect any change in range
+ }
+
+ public float getMaxValue() {
+ return maxValue;
+ }
+
+ public void setMaxValue(float maxValue) {
+ this.maxValue = maxValue;
+ updatePosX(); // Update posX to reflect any change in range
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/workspace/ui/UiComponent.java b/src/main/java/workspace/ui/UiComponent.java
index a835d935..39c72eca 100644
--- a/src/main/java/workspace/ui/UiComponent.java
+++ b/src/main/java/workspace/ui/UiComponent.java
@@ -3,207 +3,255 @@
import java.util.ArrayList;
import java.util.List;
-import workspace.ui.border.IBorder;
+import workspace.ui.border.Border;
import workspace.ui.border.Insets;
+import workspace.ui.elements.UiElement;
import workspace.ui.layout.Layout;
+import workspace.ui.renderer.Renderer;
+
+public class UiComponent implements UiElement {
+
+ protected int x;
+
+ protected int y;
+
+ protected int width;
+
+ protected int height;
+
+ protected boolean visible;
+
+ protected Color foreground;
+
+ protected Color background;
+
+ protected Border border;
+
+ protected List components;
+
+ protected Layout layout;
+
+ private Renderer renderer;
+
+ public UiComponent() {
+ this(0, 0, 0, 0, true, Color.BLACK, Color.GRAY);
+ }
+
+ public UiComponent(int x, int y, int width, int height, boolean visible,
+ Color foreground, Color background) {
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+ this.visible = visible;
+ this.foreground = foreground;
+ this.background = background;
+ this.components = new ArrayList();
+ }
+
+ @Override
+ public void setRenderer(Renderer renderer) {
+ this.renderer = renderer;
+ }
+
+ @Override
+ public Renderer getRenderer() {
+ return renderer;
+ }
+
+ @Override
+ public Insets getInsets() {
+ if (border == null)
+ return new Insets();
+ return border.getInsets();
+ }
+
+
+ @Override
+ public void setBorder(Border border) {
+ this.border = border;
+ }
+
+ @Override
+ public void render(Graphics g) {
+ if (!visible)
+ return;
+ g.pushMatrix();
+ g.translate(x, y);
+ renderSelf(g);
+ renderBorder(g);
+ g.translate(getInsets().getLeft(), getInsets().getTop());
+ renderChildren(g);
+ g.popMatrix();
+ }
+
+ /**
+ * Renders the border of the UI element if a border is defined.
+ *
+ * This method checks if the {@code border} is not null before calling the
+ * {@code renderBorder} method on the provided graphics context. It uses the
+ * element's current width and height to define the area of the border.
+ *
+ *
+ * @param g the graphics context to draw on.
+ */
+ protected void renderBorder(Graphics g) {
+ if (border == null)
+ return;
+ border.renderBorder(g, 0, 0, getWidth(), getHeight());
+ }
+
+ protected void renderChildren(Graphics g) {
+ for (UiComponent component : components) {
+ component.render(g);
+ }
+ }
+
+ @Override
+ public void setLayout(Layout layout) {
+ this.layout = layout;
+ }
+
+ @Override
+ public boolean contains(int x, int y) {
+ return x >= this.x && y >= this.y && x <= (this.x + getWidth())
+ && y <= (this.y + getHeight());
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ this.visible = visible;
+ }
+
+ @Override
+ public boolean isVisible() {
+ return visible;
+ }
+
+ public void renderSelf(Graphics g) {
+ if (renderer == null)
+ return;
+ renderer.render(g, this);
+ }
+
+ protected void layout() {
+ if (layout == null)
+ return;
+ layout.layout(this);
+ }
+
+ public void onMouseClicked(int x, int y) {
+ if (!isVisible())
+ return;
+ for (UiComponent component : components) {
+ if (component.contains(x - this.x, y - this.y)) {
+ component.onMouseClicked(x, y);
+ }
+ }
+ }
+
+ public void onMouseDragged(int x, int y) {
+ if (!isVisible())
+ return;
+ for (UiComponent component : components) {
+ if (component.contains(x - this.x, y - this.y)) {
+ component.onMouseDragged(x, y);
+ }
+ }
+ }
+
+ public void onMouseReleased(int x, int y) {
+ if (!isVisible())
+ return;
+ for (UiComponent component : components) {
+ if (component.contains(x - this.x, y - this.y)) {
+ component.onMouseReleased(x, y);
+ }
+ }
+ }
+
+ public void onMousePressed(int x, int y) {
+ if (!isVisible())
+ return;
+ for (UiComponent component : components) {
+ if (component.contains(x - this.x, y - this.y)) {
+ component.onMousePressed(x, y);
+ }
+ }
+ }
+
+ // USED
+ public void add(UiComponent component) {
+ if (component == null)
+ return;
+ components.add(component);
+ layout();
+ }
+//
+// public void remove(UiComponent component) {
+// if (component == null)
+// return;
+// components.remove(component);
+// layout();
+// }
+//
+// public int getComponentCount() {
+// return components.size();
+// }
+//
+// public UiComponent getComponentAt(int index) {
+// return components.get(index);
+// }
+
+ public int getX() {
+ return x;
+ }
+
+ public void setX(int x) {
+ this.x = x;
+ }
+
+ public int getY() {
+ return y;
+ }
+
+ public void setY(int y) {
+ this.y = y;
+ }
+
+ @Override
+ public int getWidth() {
+ return width;
+ }
+
+ public void setWidth(int width) {
+ this.width = width;
+ }
+
+ @Override
+ public int getHeight() {
+ return height;
+ }
+
+ public void setHeight(int height) {
+ this.height = height;
+ }
+
+ public Color getForeground() {
+ return foreground;
+ }
+
+ public void setForeground(Color foreground) {
+ this.foreground = foreground;
+ }
+
+ public Color getBackground() {
+ return background;
+ }
+
+ public void setBackground(Color background) {
+ this.background = background;
+ }
-public class UiComponent {
-
- protected int x;
-
- protected int y;
-
- protected int width;
-
- protected int height;
-
- protected boolean visible;
-
- protected Color foreground;
-
- protected Color background;
-
- protected IBorder border;
-
- protected List components;
-
- protected Layout layout;
-
- public UiComponent() {
- this(0, 0, 0, 0, true, Color.BLACK, Color.GRAY);
- }
-
- public UiComponent(int x, int y, int width, int height, boolean visible,
- Color foreground, Color background) {
- this.x = x;
- this.y = y;
- this.width = width;
- this.height = height;
- this.visible = visible;
- this.foreground = foreground;
- this.background = background;
- this.components = new ArrayList();
- }
-
- public void draw(Graphics g) {
- if (!visible)
- return;
- g.pushMatrix();
- g.translate(x, y);
- onDraw(g);
- drawBorder(g);
- g.translate(getInsets().left, getInsets().top);
- drawChildren(g);
- g.popMatrix();
- }
-
- public void onDraw(Graphics g) {
-
- }
-
- protected void layout() {
- if (layout == null)
- return;
- layout.layout(this);
- }
-
- protected void drawBorder(Graphics g) {
- IBorder border = getBorder();
- if (border == null)
- return;
- border.drawBorder(g, 0, 0, getWidth(), getHeight());
- }
-
- protected void drawChildren(Graphics g) {
- for (UiComponent component : components) {
- component.draw(g);
- }
- }
-
- public boolean contains(int x, int y) {
- return x >= this.x && y >= this.y && x <= (this.x + getWidth())
- && y <= (this.y + getHeight());
- }
-
- public void onMouseClicked(int x, int y) {
- if (!isVisible())
- return;
- for (UiComponent component : components) {
- if (component.contains(x - this.x, y - this.y)) {
- component.onMouseClicked(x, y);
- }
- }
- }
-
- public void onMouseDragged(int x, int y) {
- if (!isVisible())
- return;
- for (UiComponent component : components) {
- if (component.contains(x - this.x, y - this.y)) {
- component.onMouseDragged(x, y);
- }
- }
- }
-
- public void add(UiComponent component) {
- if (component == null)
- return;
- components.add(component);
- layout();
- }
-
- public void remove(UiComponent component) {
- if (component == null)
- return;
- components.remove(component);
- layout();
- }
-
- public int getComponentCount() {
- return components.size();
- }
-
- public UiComponent getComponentAt(int index) {
- return components.get(index);
- }
-
- public Layout getLayout() {
- return layout;
- }
-
- public void setLayout(Layout layout) {
- this.layout = layout;
- }
-
- public int getX() {
- return x;
- }
-
- public void setX(int x) {
- this.x = x;
- }
-
- public int getY() {
- return y;
- }
-
- public void setY(int y) {
- this.y = y;
- }
-
- public int getWidth() {
- return width;
- }
-
- public void setWidth(int width) {
- this.width = width;
- }
-
- public int getHeight() {
- return height;
- }
-
- public void setHeight(int height) {
- this.height = height;
- }
-
- public boolean isVisible() {
- return visible;
- }
-
- public void setVisible(boolean visible) {
- this.visible = visible;
- }
-
- public Color getForeground() {
- return foreground;
- }
-
- public void setForeground(Color foreground) {
- this.foreground = foreground;
- }
-
- public Color getBackground() {
- return background;
- }
-
- public void setBackground(Color background) {
- this.background = background;
- }
-
- public Insets getInsets() {
- IBorder border = getBorder();
- if (border == null)
- return new Insets();
- return border.getInsets();
- }
-
- public IBorder getBorder() {
- return border;
- }
-
- public void setBorder(IBorder border) {
- this.border = border;
- }
}
diff --git a/src/main/java/workspace/ui/UiSimpleList.java b/src/main/java/workspace/ui/UiSimpleList.java
index a9d8c461..869fc01f 100644
--- a/src/main/java/workspace/ui/UiSimpleList.java
+++ b/src/main/java/workspace/ui/UiSimpleList.java
@@ -5,46 +5,44 @@
public class UiSimpleList extends UiComponent {
- private List
+ */
public interface IActionListener {
- void onActionPerformed();
+ /**
+ * Called when an action is performed.
+ *
+ * This method is invoked in response to a user interaction with a UI
+ * component, such as clicking a button or selecting a menu item.
+ * Implementations should define the behavior to execute when the action
+ * occurs.
+ *
+ */
+ void onActionPerformed();
-}
+}
\ No newline at end of file
diff --git a/src/main/java/workspace/ui/event/ISliderCallBack.java b/src/main/java/workspace/ui/event/ISliderCallBack.java
index d7d18d47..3c417fa8 100644
--- a/src/main/java/workspace/ui/event/ISliderCallBack.java
+++ b/src/main/java/workspace/ui/event/ISliderCallBack.java
@@ -1,7 +1,7 @@
-package workspace.ui;
+package workspace.ui.event;
public interface ISliderCallBack {
- void valueChanged(float value);
+ void valueChanged(float value);
}
diff --git a/src/main/java/workspace/ui/event/MouseEvent.java b/src/main/java/workspace/ui/event/MouseEvent.java
index bacbc120..086e781a 100644
--- a/src/main/java/workspace/ui/event/MouseEvent.java
+++ b/src/main/java/workspace/ui/event/MouseEvent.java
@@ -1,37 +1,87 @@
-package workspace.ui;
+package workspace.ui.event;
+/**
+ * Represents a mouse event, containing information about the current and
+ * previous mouse positions.
+ *
+ * This class is used to encapsulate the state of the mouse during an event,
+ * such as mouse movement or mouse clicks. It provides details about the mouse's
+ * current coordinates as well as its previous position.
+ *
+ *
+ *
+ * Example usage:
+ *
+ * MouseEvent event = new MouseEvent(100, 200, 90, 180);
+ * int currentX = event.getMouseX();
+ * int previousX = event.getPreviousMouseX();
+ *
+ */
public class MouseEvent {
- private int mouseX;
+ /** The current X-coordinate of the mouse. */
+ private final int mouseX;
- private int mouseY;
+ /** The current Y-coordinate of the mouse. */
+ private final int mouseY;
- private int previousMouseX;
+ /** The previous X-coordinate of the mouse. */
+ private final int previousMouseX;
- private int previousMouseY;
+ /** The previous Y-coordinate of the mouse. */
+ private final int previousMouseY;
- public MouseEvent(int mouseX, int mouseY, int previousMouseX,
- int previousMouseY) {
- this.mouseX = mouseX;
- this.mouseY = mouseY;
- this.previousMouseX = previousMouseX;
- this.previousMouseY = previousMouseY;
- }
+ /**
+ * Constructs a new {@code MouseEvent} with the specified current and previous
+ * mouse coordinates.
+ *
+ * @param mouseX The current X-coordinate of the mouse.
+ * @param mouseY The current Y-coordinate of the mouse.
+ * @param previousMouseX The previous X-coordinate of the mouse.
+ * @param previousMouseY The previous Y-coordinate of the mouse.
+ */
+ public MouseEvent(int mouseX, int mouseY, int previousMouseX,
+ int previousMouseY) {
+ this.mouseX = mouseX;
+ this.mouseY = mouseY;
+ this.previousMouseX = previousMouseX;
+ this.previousMouseY = previousMouseY;
+ }
- public int getMouseX() {
- return mouseX;
- }
+ /**
+ * Gets the current X-coordinate of the mouse.
+ *
+ * @return The current X-coordinate.
+ */
+ public int getMouseX() {
+ return mouseX;
+ }
- public int getMouseY() {
- return mouseY;
- }
+ /**
+ * Gets the current Y-coordinate of the mouse.
+ *
+ * @return The current Y-coordinate.
+ */
+ public int getMouseY() {
+ return mouseY;
+ }
- public int getPreviousMouseX() {
- return previousMouseX;
- }
+ /**
+ * Gets the previous X-coordinate of the mouse.
+ *
+ * @return The previous X-coordinate.
+ */
+ public int getPreviousMouseX() {
+ return previousMouseX;
+ }
- public int getPreviousMouseY() {
- return previousMouseY;
- }
+ /**
+ * Gets the previous Y-coordinate of the mouse.
+ *
+ * @return The previous Y-coordinate.
+ */
+ public int getPreviousMouseY() {
+ return previousMouseY;
+ }
-}
+}
\ No newline at end of file
From afd4c72211e5cc847045baeb697eafcfbd11ed78 Mon Sep 17 00:00:00 2001
From: Simon Dietz
Date: Sat, 14 Dec 2024 13:23:39 +0100
Subject: [PATCH 11/15] feat: add comprehensive lighting system to scene
package
- Introduced `Light` interface to define common properties and behavior
for all light types.
- Added `LightRenderer` interface to decouple rendering logic for
different light types.
- Implemented `DirectionalLight` for uniform parallel lighting,
typically used for simulating sunlight.
- Implemented `PointLight` for omnidirectional light sources.
- Implemented `Spotlight` for directional lighting with limited cone
angles.
- Added `LightType` enum to categorize and identify light types.
This commit establishes a flexible and extensible lighting system,
enabling dynamic light management and rendering in the scene graph.
---
.../java/scene/light/DirectionalLight.java | 200 +++++++++++++
src/main/java/scene/light/Light.java | 49 ++++
src/main/java/scene/light/LightRenderer.java | 66 +++++
src/main/java/scene/light/LightType.java | 21 ++
src/main/java/scene/light/PointLight.java | 210 ++++++++++++++
src/main/java/scene/light/SpotLight.java | 268 ++++++++++++++++++
6 files changed, 814 insertions(+)
create mode 100644 src/main/java/scene/light/DirectionalLight.java
create mode 100644 src/main/java/scene/light/Light.java
create mode 100644 src/main/java/scene/light/LightRenderer.java
create mode 100644 src/main/java/scene/light/LightType.java
create mode 100644 src/main/java/scene/light/PointLight.java
create mode 100644 src/main/java/scene/light/SpotLight.java
diff --git a/src/main/java/scene/light/DirectionalLight.java b/src/main/java/scene/light/DirectionalLight.java
new file mode 100644
index 00000000..29ed5bf6
--- /dev/null
+++ b/src/main/java/scene/light/DirectionalLight.java
@@ -0,0 +1,200 @@
+package scene.light;
+
+import math.Color;
+import math.Vector3f;
+
+/**
+ * Represents a directional light source in a 3D scene.
+ *
+ *
+ * A directional light simulates light emitted from a distant source, such as
+ * the sun or moon. Unlike point lights or spotlights, directional lights have
+ * no specific position, and their light rays travel in a uniform direction
+ * throughout the scene. This makes them ideal for creating consistent lighting
+ * over large areas.
+ *
+ *
+ *
+ * Key characteristics of a directional light:
+ * - The light's direction is defined by a normalized vector.
+ * - It emits light uniformly in the specified direction, without attenuation
+ * (intensity does not decrease with distance).
+ * - It is commonly used to simulate natural light sources like sunlight during
+ * the day or moonlight at night.
+ *
+ *
+ * This class provides methods to configure the light's direction, color, and
+ * intensity, as well as integration with rendering systems via the
+ * {@link LightRenderer}.
+ */
+public class DirectionalLight implements Light {
+
+ /**
+ * The color of the light emitted by the directional light source.
+ */
+ private Color color;
+
+ /**
+ * The direction of the light source.
+ */
+ private Vector3f direction;
+
+ /**
+ * The intensity of the light emitted by the directional light source.
+ */
+ private float intensity;
+
+ /**
+ * Creates a new DirectionalLight instance with default settings.
+ *
+ *
+ * This constructor initializes the light with the following defaults: -
+ * Color: White light. RGB(255, 255, 255) - Direction: A downward-facing
+ * vector (0, 1, 0), simulating overhead light. - Intensity: 1.0 (full
+ * strength).
+ *
+ */
+ public DirectionalLight() {
+ this(Color.WHITE, new Vector3f(0, 1, 0), 1.0f);
+ }
+
+ /**
+ * Creates a new DirectionalLight instance.
+ *
+ * @param color The color of the light emitted by the directional light
+ * source. Represents the RGB values of the light's color.
+ * This parameter cannot be null.
+ * @param direction The direction of the light source. This vector determines
+ * the direction in which the light rays travel. The provided
+ * vector is automatically normalized during construction,
+ * ensuring the direction's magnitude is always 1. This
+ * parameter cannot be null.
+ * @param intensity The intensity of the light emitted by the directional
+ * light source. This value must be non-negative.
+ *
+ * @throws IllegalArgumentException if the direction or color is null, or if
+ * the intensity is negative.
+ */
+ public DirectionalLight(Color color, Vector3f direction, float intensity) {
+ setColor(color);
+ setDirection(direction);
+ setIntensity(intensity);
+ }
+
+ /**
+ * Gets the direction of the light source.
+ *
+ * @return The direction of the light source.
+ * @see #setDirection(Vector3f)
+ */
+ public Vector3f getDirection() {
+ return direction;
+ }
+
+ /**
+ * Sets the direction of the directional light source.
+ *
+ * The provided vector is normalized to ensure the light's direction always
+ * has a magnitude of 1, which maintains consistent light behavior. This
+ * method validates that the input is not null to avoid runtime errors.
+ *
+ * @param direction The new direction vector for the light source. This vector
+ * defines the direction in which the light rays travel.
+ *
+ * @throws IllegalArgumentException if the provided direction vector is null.
+ */
+ public void setDirection(Vector3f direction) {
+ if (direction == null)
+ throw new IllegalArgumentException("Direction cannot be null.");
+ this.direction = direction.normalize();
+ }
+
+ /**
+ * Gets the color of the light emitted by the directional light source.
+ *
+ * @return The color of the light.
+ * @see #setColor(Color)
+ */
+ @Override
+ public Color getColor() {
+ return color;
+ }
+
+ /**
+ * Sets the color of the directional light source.
+ *
+ * This method updates the light's emitted color. It validates that the
+ * provided color is not null to ensure the light's color is always valid.
+ *
+ * @param color The new color of the light to set. Represents the RGB values
+ * of the light's color.
+ *
+ * @throws IllegalArgumentException if the provided color is null.
+ */
+ public void setColor(Color color) {
+ if (color == null)
+ throw new IllegalArgumentException("Color cannot be null.");
+ this.color = color;
+ }
+
+ /**
+ * Gets the intensity of the light emitted by the directional light source.
+ *
+ * @return The intensity of the light.
+ * @see #setIntensity(float)
+ */
+ public float getIntensity() {
+ return intensity;
+ }
+
+ /**
+ * Sets the intensity of the light emitted by the directional light source.
+ *
+ * The intensity value determines how bright the light appears in the scene.
+ * This method ensures that the value is non-negative, as negative intensity
+ * does not make logical sense in this context.
+ *
+ * @param intensity The new intensity value to set for the light source. Must
+ * be non-negative to represent valid light brightness.
+ *
+ * @throws IllegalArgumentException if the provided intensity is negative.
+ */
+ public void setIntensity(float intensity) {
+ if (intensity < 0)
+ throw new IllegalArgumentException("Intensity must be non-negative.");
+ this.intensity = intensity;
+ }
+
+ /**
+ * Gets the type of the light source.
+ *
+ * @return The type of the light source, which is `LightType.DIRECTIONAL`.
+ */
+ @Override
+ public LightType getType() {
+ return LightType.DIRECTIONAL;
+ }
+
+ /**
+ * Renders the directional light source using the provided renderer.
+ *
+ * @param renderer The renderer to use for rendering the light source.
+ */
+ @Override
+ public void render(LightRenderer renderer) {
+ renderer.render(this);
+ }
+
+ /**
+ * Provides a string representation of this directional light instance for
+ * debugging.
+ *
+ * @return String describing the current state of the directional light.
+ */
+ @Override
+ public String toString() {
+ return "DirectionalLight [color=" + color + ", direction=" + direction
+ + ", intensity=" + intensity + "]";
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/scene/light/Light.java b/src/main/java/scene/light/Light.java
new file mode 100644
index 00000000..002ffddd
--- /dev/null
+++ b/src/main/java/scene/light/Light.java
@@ -0,0 +1,49 @@
+package scene.light;
+
+import math.Color;
+
+/**
+ * Interface for defining light sources within a 3D scene.
+ *
+ *
+ * This interface serves as a contract for all light types (e.g., PointLight,
+ * DirectionalLight, SpotLight) by defining essential behaviors and properties
+ * that any light source should possess. It provides mechanisms to query a
+ * light's type, retrieve its color, and delegate rendering logic to a given
+ * renderer.
+ *
+ */
+public interface Light {
+
+ /**
+ * Gets the color of the light emitted by the light source.
+ *
+ * @return The {@link Color} object representing the light's color. The color
+ * should define the RGB components that determine the light's hue and
+ * saturation.
+ */
+ Color getColor();
+
+ /**
+ * Gets the type of the light source.
+ *
+ * @return The {@link LightType} that identifies the specific type of light
+ * (e.g., POINT, DIRECTIONAL, or SPOT) this instance represents.
+ */
+ LightType getType();
+
+ /**
+ * Gets the light source using the provided renderer to draw the light's
+ * effects.
+ *
+ * This method allows the implementation to delegate rendering logic to the
+ * given {@link LightRenderer}. The rendering logic could involve adding
+ * effects like shadows, light rays, or other visual representations specific
+ * to the light's type.
+ *
+ * @param renderer The {@link LightRenderer} implementation responsible for
+ * rendering this light's effects in the scene.
+ */
+ void render(LightRenderer renderer);
+
+}
\ No newline at end of file
diff --git a/src/main/java/scene/light/LightRenderer.java b/src/main/java/scene/light/LightRenderer.java
new file mode 100644
index 00000000..3490d213
--- /dev/null
+++ b/src/main/java/scene/light/LightRenderer.java
@@ -0,0 +1,66 @@
+package scene.light;
+
+/**
+ * Interface for rendering various light sources in a 3D scene.
+ *
+ * This interface establishes a contract for rendering different types of light
+ * sources in a 3D environment. It provides specific rendering methods for each
+ * type of light, such as {@link PointLight}, {@link DirectionalLight}, and
+ * {@link SpotLight}. Implementations of this interface handle the actual
+ * rendering logic for these light types within a 3D graphics or game engine.
+ *
+ * This method is a catch-all for rendering any light source that implements
+ * the {@link Light} interface. Specific rendering logic for the light type
+ * may be determined by the implementation.
+ *
+ *
+ * @param light The light source to render. Must not be null.
+ */
+ void render(Light light);
+
+ /**
+ * Renders a spotlight.
+ *
+ * This method is responsible for rendering a spotlight with specific
+ * directionality, cone angles, and attenuation effects. Spotlights are used
+ * to simulate focused beams of light, such as those from flashlights, lamps,
+ * or theater lighting.
+ *
+ *
+ * @param light The spotlight to render. Must not be null.
+ */
+ void render(SpotLight light);
+
+ /**
+ * Renders a point light source.
+ *
+ * This method handles the rendering of a point light, which emits light
+ * uniformly in all directions from a single point in 3D space. Point lights
+ * are commonly used to simulate small localized light sources such as light
+ * bulbs or torches.
+ *
+ *
+ * @param light The point light source to render. Must not be null.
+ */
+ void render(PointLight light);
+
+ /**
+ * Renders a directional light source.
+ *
+ * This method handles rendering for a directional light, which simulates
+ * light coming from a distant, uniform direction (e.g., sunlight or
+ * moonlight). Directional lights are ideal for simulating natural light
+ * sources that do not have an attenuation effect based on distance.
+ *
+ *
+ * @param light The directional light source to render. Must not be null.
+ */
+ void render(DirectionalLight light);
+
+}
\ No newline at end of file
diff --git a/src/main/java/scene/light/LightType.java b/src/main/java/scene/light/LightType.java
new file mode 100644
index 00000000..051300a9
--- /dev/null
+++ b/src/main/java/scene/light/LightType.java
@@ -0,0 +1,21 @@
+package scene.light;
+
+/**
+ * Enum representing different types of lights.
+ *
+ * This enum defines the three primary types of lights commonly used in 3D
+ * graphics:
+ *
+ *
+ * - POINT: A point light emits light uniformly in all directions.
+ * - DIRECTIONAL: A directional light emits light in parallel rays from
+ * a specific direction.
+ * - SPOT: A spotlight emits light in a cone shape, with a specific
+ * direction and angle.
+ *
+ */
+public enum LightType {
+
+ POINT, DIRECTIONAL, SPOT
+
+}
diff --git a/src/main/java/scene/light/PointLight.java b/src/main/java/scene/light/PointLight.java
new file mode 100644
index 00000000..f37a81df
--- /dev/null
+++ b/src/main/java/scene/light/PointLight.java
@@ -0,0 +1,210 @@
+package scene.light;
+
+import math.Color;
+import math.Vector3f;
+
+/**
+ * Represents a point light source in a 3D scene.
+ *
+ *
+ * A point light simulates a light-emitting point in space, radiating light
+ * uniformly in all directions. It is characterized by its position, color,
+ * intensity, and range. This class is ideal for simulating localized light
+ * sources such as lightbulbs, torches, or other small light emitters in a 3D
+ * environment.
+ *
+ *
+ *
+ * Key Characteristics of a point light:
+ * Position: A 3D vector representing the spatial location of the light in
+ * the scene.
+ * Color: The color of light the point light emits. Represented by an instance
+ * of {@link math.Color}.
+ * Intensity: A non-negative float value that defines how bright the light
+ * appears.
+ * Range: The maximum distance at which the light's effect is visible, beyond
+ * which the light has no influence.
+ *
+ *
+ * Usage: This class provides methods to dynamically configure light properties,
+ * such as changing the light's intensity, range, or color at runtime.
+ * Integration with rendering systems can be accomplished via the
+ * {@link LightRenderer}.
+ */
+public class PointLight implements Light {
+
+ /**
+ * The color of the light emitted by the point light source.
+ */
+ private Color color;
+
+ /**
+ * The 3D position of the point light source within the scene.
+ */
+ private Vector3f position;
+
+ /**
+ * The intensity of the light emitted by the point light source.
+ */
+ private float intensity;
+
+ /**
+ * The maximum distance at which the light's effect can influence objects.
+ */
+ private float range;
+
+ /**
+ * Creates a new PointLight instance with default settings.
+ *
+ * This constructor initializes the point light with the following default
+ * values: - Color: White (RGB(255, 255, 255)). - Position: (0, 0, 0). -
+ * Intensity: 1.0. - Range: 10.0.
+ *
+ */
+ public PointLight() {
+ this(Color.WHITE, new Vector3f(0, 0, 0), 1.0f, 10.0f);
+ }
+
+ /**
+ * Creates a new PointLight instance with specified parameters.
+ *
+ * @param color The color of the light. Must not be null.
+ * @param position The 3D position of the light source in the scene. Must not
+ * be null.
+ * @param intensity The intensity of the light. Must be a non-negative value.
+ * @param range The maximum distance of the light's effect. Must be
+ * non-negative.
+ *
+ * @throws IllegalArgumentException if any argument is invalid (e.g., null
+ * values or negative numbers).
+ */
+ public PointLight(Color color, Vector3f position, float intensity,
+ float range) {
+ setColor(color);
+ setPosition(position);
+ setIntensity(intensity);
+ setRange(range);
+ }
+
+ /**
+ * Gets the maximum range at which the light's effect is felt.
+ *
+ * @return The range of the light's effect in world units.
+ */
+ public float getRange() {
+ return range;
+ }
+
+ /**
+ * Sets the maximum range of the light's influence in the scene.
+ *
+ * @param range The new range value. Must be non-negative.
+ * @throws IllegalArgumentException if the provided range is less than 0.
+ */
+ public void setRange(float range) {
+ if (range < 0) {
+ throw new IllegalArgumentException("Range must be non-negative.");
+ }
+ this.range = range;
+ }
+
+ /**
+ * Gets the current intensity of the light.
+ *
+ * @return The intensity value, a non-negative float.
+ */
+ public float getIntensity() {
+ return intensity;
+ }
+
+ /**
+ * Sets the intensity of the light source.
+ *
+ * @param intensity The new intensity value to apply. Must be non-negative.
+ * @throws IllegalArgumentException if intensity is less than 0.
+ */
+ public void setIntensity(float intensity) {
+ if (intensity < 0) {
+ throw new IllegalArgumentException("Intensity must be non-negative.");
+ }
+ this.intensity = intensity;
+ }
+
+ /**
+ * Gets the color of the light emitted by the point light source.
+ *
+ * @return The current {@link math.Color} of the point light.
+ */
+ @Override
+ public Color getColor() {
+ return color;
+ }
+
+ /**
+ * Sets the color of the light source.
+ *
+ * @param color The new color value for the light source. Must not be null.
+ * @throws IllegalArgumentException if color is null.
+ */
+ public void setColor(Color color) {
+ if (color == null) {
+ throw new IllegalArgumentException("Color cannot be null.");
+ }
+ this.color = color;
+ }
+
+ /**
+ * Gets the 3D position of the light source.
+ *
+ * @return The current position of the light as a {@link math.Vector3f}.
+ */
+ public Vector3f getPosition() {
+ return position;
+ }
+
+ /**
+ * Sets the 3D position of the light source within the 3D scene.
+ *
+ * @param position The new position value to set. Must not be null.
+ * @throws IllegalArgumentException if position is null.
+ */
+ public void setPosition(Vector3f position) {
+ if (position == null) {
+ throw new IllegalArgumentException("Position cannot be null.");
+ }
+ this.position = position;
+ }
+
+ /**
+ * Gets the type of light.
+ *
+ * @return The type of the light, represented as `LightType.POINT`.
+ */
+ @Override
+ public LightType getType() {
+ return LightType.POINT;
+ }
+
+ /**
+ * Renders this point light source using the provided renderer.
+ *
+ * @param renderer The renderer responsible for rendering the light in the 3D
+ * scene.
+ */
+ @Override
+ public void render(LightRenderer renderer) {
+ renderer.render(this);
+ }
+
+ /**
+ * Generates a string representation of this {@link PointLight}.
+ *
+ * @return A string describing the current state of this point light.
+ */
+ @Override
+ public String toString() {
+ return "PointLight [color=" + color + ", position=" + position
+ + ", intensity=" + intensity + ", range=" + range + "]";
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/scene/light/SpotLight.java b/src/main/java/scene/light/SpotLight.java
new file mode 100644
index 00000000..c6d17e16
--- /dev/null
+++ b/src/main/java/scene/light/SpotLight.java
@@ -0,0 +1,268 @@
+package scene.light;
+
+import math.Color;
+import math.Vector3f;
+
+/**
+ * Represents a spotlight in a 3D scene.
+ *
+ * A spotlight emits light in a cone shape, with a defined position, direction,
+ * cone angle, and concentration (center bias). This class models the essential
+ * properties of a spotlight, allowing users to specify its behavior and
+ * appearance in a 3D environment.
+ *
+ *
+ * Key properties include:
+ * - Position: The 3D coordinates where the spotlight is located.
+ * - Direction: The orientation direction the spotlight points towards.
+ * - Color: The color of the emitted light.
+ * - Angle: The cone angle, defining the spread of the light in radians.
+ * - Concentration: The exponent controlling how focused the spotlight
+ * is on its center.
+ *
+ *
+ * This class supports both a default spotlight configuration and customizable
+ * initialization via its constructors. Input values are validated to ensure
+ * realistic and meaningful spotlight behavior.
+ */
+public class SpotLight implements Light {
+
+ /**
+ * 45° in radians, the default cone angle for a standard spotlight.
+ */
+ private static final float DEFAULT_ANGLE = (float) Math.PI / 4;
+
+ /**
+ * Default center bias value for the spotlight's cone.
+ */
+ private static final float DEFAULT_CONCENTRATION = 10.0f;
+
+ /**
+ * The default position of the spotlight, located at the origin.
+ */
+ private static final Vector3f DEFAULT_POSITION = new Vector3f(0, 0, 0);
+
+ /**
+ * The default direction for the spotlight, pointing along the negative
+ * Z-axis.
+ */
+ private static final Vector3f DEFAULT_DIRECTION = new Vector3f(0, 0, -1);
+
+ /**
+ * The default color of the spotlight's emitted light (white light).
+ */
+ private static final Color DEFAULT_COLOR = Color.WHITE;
+
+ /** The angle of the spotlight's cone in radians. */
+ private float angle;
+
+ /** Determines the spotlight's intensity concentration toward its center. */
+ private float concentration;
+
+ /** The position of the spotlight in 3D space. */
+ private Vector3f position;
+
+ /** The direction vector indicating the spotlight's orientation. */
+ private Vector3f direction;
+
+ /** The color of the emitted spotlight's light. */
+ private Color color;
+
+ /**
+ * Default constructor initializes the spotlight with pre-defined defaults.
+ *
+ *
+ * The defaults include:
+ * - Position at (0,0,0).
+ * - Direction pointing along the negative Z-axis.
+ * - White color.
+ * - A cone angle of 45° (π/4 radians).
+ * - A concentration value of 10.0 (focused light)
+ *
+ */
+ public SpotLight() {
+ this(DEFAULT_POSITION, DEFAULT_DIRECTION, DEFAULT_COLOR,
+ DEFAULT_CONCENTRATION, DEFAULT_ANGLE);
+ }
+
+ /**
+ * Constructs a new SpotLight instance with the specified properties.
+ *
+ *
+ * Initializes the spotlight with the provided position, direction, color,
+ * concentration, and cone angle values. Each input is validated to ensure it
+ * adheres to acceptable ranges or requirements.
+ *
+ *
+ * @param position The 3D position of the spotlight. Must not be null.
+ * @param direction The direction the spotlight points towards. Must not
+ * be null.
+ * @param color The emitted light's color. Must not be null.
+ * @param concentration The center bias (intensity focus) of the spotlight
+ * cone. Must be non-negative.
+ * @param angle The cone angle in radians. Must be greater than 0 and
+ * less than or equal to π radians.
+ * @throws IllegalArgumentException if any of the following conditions are
+ * met: - `position` is null. - `direction`
+ * is null. - `color` is null. -
+ * `concentration` is negative. - `angle` is
+ * less than or equal to 0, or greater than π
+ * radians.
+ */
+ public SpotLight(Vector3f position, Vector3f direction, Color color,
+ float concentration, float angle) {
+ setPosition(position);
+ setDirection(direction);
+ setColor(color);
+ setConcentration(concentration);
+ setAngle(angle);
+ }
+
+ /**
+ * Gets the angle of the spotlight cone.
+ *
+ * @return The cone's angle in radians.
+ */
+ public float getAngle() {
+ return angle;
+ }
+
+ /**
+ * Sets the cone angle, ensuring it is within valid physical limits.
+ *
+ * @param angle The new angle of the spotlight cone.
+ * @throws IllegalArgumentException if the value is less than or equal to 0 or
+ * exceeds π radians.
+ */
+ public void setAngle(float angle) {
+ if (angle <= 0 || angle > Math.PI) {
+ throw new IllegalArgumentException(
+ "Angle must be between 0 and PI radians.");
+ }
+ this.angle = angle;
+ }
+
+ /**
+ * Gets the concentration (center bias) of the spotlight's cone.
+ *
+ * @return The concentration value of the spotlight.
+ */
+ public float getConcentration() {
+ return concentration;
+ }
+
+ /**
+ * Sets the concentration value for the spotlight cone's focus.
+ *
+ * @param concentration The new concentration value.
+ * @throws IllegalArgumentException if the value is negative.
+ */
+ public void setConcentration(float concentration) {
+ if (concentration < 0) {
+ throw new IllegalArgumentException("Concentration must be non-negative.");
+ }
+ this.concentration = concentration;
+ }
+
+ /**
+ * Retrieves the direction vector of the spotlight.
+ *
+ * @return The current direction vector.
+ */
+ public Vector3f getDirection() {
+ return direction;
+ }
+
+ /**
+ * Sets the direction vector of the spotlight.
+ *
+ * @param direction The new direction vector.
+ * @throws IllegalArgumentException if the provided vector is null.
+ */
+ public void setDirection(Vector3f direction) {
+ if (direction == null) {
+ throw new IllegalArgumentException("Direction cannot be null.");
+ }
+ this.direction = direction;
+ }
+
+ /**
+ * Retrieves the position of the spotlight.
+ *
+ * @return The position vector.
+ */
+ public Vector3f getPosition() {
+ return position;
+ }
+
+ /**
+ * Sets the position of the spotlight in 3D space.
+ *
+ * @param position The new position vector.
+ * @throws IllegalArgumentException if the provided vector is null.
+ */
+ public void setPosition(Vector3f position) {
+ if (position == null) {
+ throw new IllegalArgumentException("Position cannot be null.");
+ }
+ this.position = position;
+ }
+
+ /**
+ * Retrieves the color of the spotlight's light.
+ *
+ * @return The spotlight's color.
+ */
+ @Override
+ public Color getColor() {
+ return color;
+ }
+
+ /**
+ * Sets the color of the spotlight's emitted light.
+ *
+ * @param color The new color value.
+ * @throws IllegalArgumentException if the provided color is null.
+ */
+ public void setColor(Color color) {
+ if (color == null) {
+ throw new IllegalArgumentException("Color cannot be null.");
+ }
+ this.color = color;
+ }
+
+ /**
+ * Determines the type of light, specifically `LightType.SPOT`.
+ *
+ * @return The type of light.
+ */
+ @Override
+ public LightType getType() {
+ return LightType.SPOT;
+ }
+
+ /**
+ * Renders the spotlight using the provided rendering system.
+ *
+ * Delegates rendering logic to the specified {@link LightRenderer}.
+ *
+ * @param renderer The renderer responsible for spotlight rendering.
+ */
+ @Override
+ public void render(LightRenderer renderer) {
+ renderer.render(this);
+ }
+
+ /**
+ * Provides a string representation of this spotlight instance for debugging.
+ *
+ * @return String describing the current state of the spotlight.
+ */
+ @Override
+ public String toString() {
+ return "SpotLight [angle=" + angle + ", concentration=" + concentration
+ + ", position=" + position + ", direction=" + direction + ", color="
+ + color + "]";
+ }
+
+}
\ No newline at end of file
From ff70217260aae5bbea5abca626f56cba64c4911d Mon Sep 17 00:00:00 2001
From: Simon Dietz
Date: Sat, 14 Dec 2024 14:23:49 +0100
Subject: [PATCH 12/15] Refactoring. Changes Slider name and implemented
renderer.
---
src/main/java/workspace/ui/Slider.java | 117 -----------------
src/main/java/workspace/ui/UiSlider.java | 120 ++++++++++++++++++
.../workspace/ui/renderer/SliderRenderer.java | 47 +++++++
3 files changed, 167 insertions(+), 117 deletions(-)
delete mode 100644 src/main/java/workspace/ui/Slider.java
create mode 100644 src/main/java/workspace/ui/UiSlider.java
create mode 100644 src/main/java/workspace/ui/renderer/SliderRenderer.java
diff --git a/src/main/java/workspace/ui/Slider.java b/src/main/java/workspace/ui/Slider.java
deleted file mode 100644
index 5a6f17f1..00000000
--- a/src/main/java/workspace/ui/Slider.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package workspace.ui;
-
-import math.Mathf;
-import workspace.laf.UiValues;
-import workspace.ui.border.Insets;
-import workspace.ui.event.ISliderCallBack;
-
-public class Slider extends UiComponent {
-
- private float value;
-
- private float minValue = 0;
-
- private float maxValue = 3;
-
- private float posX;
-
- private ISliderCallBack sliderCallBack;
-
- private String text = "Slider";
-
- @Override
- public void renderSelf(Graphics g) {
- Insets insets = getInsets();
-
- g.setColor(getBackground());
- g.fillRect(insets.getLeft(), insets.getRight(),
- width - insets.getHorizontalInsets(),
- height - insets.getVerticalInsets());
-
- g.setColor(getForeground());
- g.fillRect(getWidth() + posX, 0, 5, getHeight());
-
- g.setColor(UiValues.SLIDER_LIGHT);
- g.fillRect(0, 0, getWidth() + posX, getHeight());
-
- g.setColor(foreground);
- g.text(" " + value, 4, g.getTextSize() + g.textDescent());
- g.text(text, getWidth() + 10, g.getTextSize() + g.textDescent());
- }
-
- public void onMouseDragged(int x, int y) {
- posX = x - getWidth() - getX();
- clampPosX(); // Ensure posX stays within bounds
- updateValue();
- if (sliderCallBack != null)
- sliderCallBack.valueChanged(value);
- }
-
- @Override
- public void onMouseClicked(int x, int y) {
- // Optionally, jump posX to the clicked position
- }
-
- private void updateValue() {
- // Map posX to the slider's value range
-// value = Mathf.map(posX, 0, getWidth(), minValue, maxValue);
-// value = Mathf.clamp(value, minValue, maxValue); // Ensure value stays in range
- value = maxValue + Mathf.map(posX, 0, getWidth(), minValue, maxValue);
- }
-
- private void updatePosX() {
-// posX = Mathf.map(value, minValue, maxValue, x, x + width);
-
- // Map value back to posX
-// posX = Mathf.map(value, minValue, maxValue, x, x + getWidth());
-// clampPosX(); // Ensure posX stays within bounds
- }
-
- private void clampPosX() {
-// // Ensure posX doesn't exceed slider's drawable area
-// posX = Mathf.clamp(posX, 0, getWidth());
- }
-
- public float getValue() {
- return value;
- }
-
- public void setValue(float value) {
-// this.value = Mathf.clamp(value, minValue, maxValue); // Clamp the value
- updatePosX(); // Update posX to reflect the new value
- }
-
- public String getText() {
- return text;
- }
-
- public void setText(String text) {
- this.text = text;
- }
-
- public ISliderCallBack getSliderCallBack() {
- return sliderCallBack;
- }
-
- public void setSliderCallBack(ISliderCallBack sliderCallBack) {
- this.sliderCallBack = sliderCallBack;
- }
-
- public float getMinValue() {
- return minValue;
- }
-
- public void setMinValue(float minValue) {
- this.minValue = minValue;
- updatePosX(); // Update posX to reflect any change in range
- }
-
- public float getMaxValue() {
- return maxValue;
- }
-
- public void setMaxValue(float maxValue) {
- this.maxValue = maxValue;
- updatePosX(); // Update posX to reflect any change in range
- }
-}
\ No newline at end of file
diff --git a/src/main/java/workspace/ui/UiSlider.java b/src/main/java/workspace/ui/UiSlider.java
new file mode 100644
index 00000000..14209ee2
--- /dev/null
+++ b/src/main/java/workspace/ui/UiSlider.java
@@ -0,0 +1,120 @@
+package workspace.ui;
+
+import math.Mathf;
+import workspace.ui.border.Insets;
+import workspace.ui.event.ISliderCallBack;
+import workspace.ui.renderer.SliderRenderer;
+
+/**
+ * A customizable UI slider component for selecting a value within a defined
+ * range. Supports dragging and value change callbacks.
+ */
+public class UiSlider extends UiComponent {
+
+ private float value;
+
+ private float minValue = 0;
+
+ private float maxValue = 1;
+
+ private float handlePosition;
+
+ private String text = "Slider";
+
+ private ISliderCallBack callback;
+
+ public UiSlider() {
+ setRenderer(new SliderRenderer());
+ }
+
+ @Override
+ public void onMouseDragged(int mouseX, int mouseY) {
+ super.onMouseDragged(mouseX, mouseY);
+ updateHandlePosition(mouseX);
+ updateValue();
+ if (callback != null) {
+ callback.valueChanged(value);
+ }
+ }
+
+ @Override
+ public void onMouseClicked(int mouseX, int mouseY) {
+ super.onMouseClicked(mouseX, mouseY);
+ updateHandlePosition(mouseX);
+ updateValue();
+ if (callback != null) {
+ callback.valueChanged(value);
+ }
+ }
+
+ private void updateHandlePosition(int mouseX) {
+ Insets insets = getInsets();
+ int trackStart = getX() + insets.getLeft(); // Account for global x position
+ int trackWidth = getWidth() - insets.getHorizontalInsets();
+
+ // Adjust handlePosition relative to the track's start position
+ handlePosition = Mathf.clamp(mouseX - trackStart, 0, trackWidth);
+ }
+
+ private void updateValue() {
+ Insets insets = getInsets();
+ int trackWidth = getWidth() - insets.getHorizontalInsets();
+
+ value = Mathf.map(handlePosition, 0, trackWidth, minValue, maxValue);
+ }
+
+ public float getValue() {
+ return value;
+ }
+
+ public void setValue(float value) {
+ this.value = Mathf.clamp(value, minValue, maxValue);
+ updateHandlePositionFromValue();
+ }
+
+ private void updateHandlePositionFromValue() {
+ Insets insets = getInsets();
+ int trackWidth = getWidth() - insets.getHorizontalInsets();
+
+// handlePosition = Mathf.map(value, minValue, maxValue, 0, trackWidth);
+ }
+
+ public float getMinValue() {
+ return minValue;
+ }
+
+ public void setMinValue(float minValue) {
+ this.minValue = minValue;
+ updateHandlePositionFromValue();
+ }
+
+ public float getMaxValue() {
+ return maxValue;
+ }
+
+ public void setMaxValue(float maxValue) {
+ this.maxValue = maxValue;
+ updateHandlePositionFromValue();
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+
+ public ISliderCallBack getSliderCallback() {
+ return callback;
+ }
+
+ public void setSliderCallBack(ISliderCallBack callback) {
+ this.callback = callback;
+ }
+
+ public float getHandlePosition() {
+ return handlePosition;
+ }
+
+}
diff --git a/src/main/java/workspace/ui/renderer/SliderRenderer.java b/src/main/java/workspace/ui/renderer/SliderRenderer.java
new file mode 100644
index 00000000..b753a04f
--- /dev/null
+++ b/src/main/java/workspace/ui/renderer/SliderRenderer.java
@@ -0,0 +1,47 @@
+package workspace.ui.renderer;
+
+import workspace.ui.Graphics;
+import workspace.ui.UiSlider;
+import workspace.ui.border.Insets;
+import workspace.ui.elements.UiElement;
+
+/**
+ * Renderer for the slider component.
+ */
+public class SliderRenderer implements Renderer {
+
+ @Override
+ public void render(Graphics g, UiElement element) {
+ UiSlider slider = (UiSlider) element;
+ Insets insets = slider.getInsets();
+
+ int trackStartX = insets.getLeft();
+ int trackStartY = insets.getTop();
+ int trackWidth = slider.getWidth() - insets.getHorizontalInsets();
+ int trackHeight = slider.getHeight() - insets.getVerticalInsets();
+
+ // Draw track
+ g.setColor(slider.getBackground());
+ g.fillRect(trackStartX, trackStartY, trackWidth, trackHeight);
+
+ // Draw filled portion
+// g.setColor(slider.getForeground());
+ g.setColor(60, 60, 60);
+ g.fillRect(trackStartX, trackStartY, (int) slider.getHandlePosition(),
+ trackHeight);
+
+ // Draw handle
+ g.setColor(slider.getForeground());
+ int handleWidth = 5;
+ int handleX = (int) (trackStartX + slider.getHandlePosition()
+ - handleWidth / 2);
+ g.fillRect(handleX, trackStartY, handleWidth, trackHeight);
+
+ // Draw label and value
+ g.setColor(slider.getForeground());
+ g.text(slider.getText() + ":" + slider.getValue(),
+ insets.getLeft() + slider.getWidth() + 10,
+ g.getTextSize() + g.textDescent());
+ }
+
+}
\ No newline at end of file
From 0f940c0318371669eaf844eb5c2184196b409d52 Mon Sep 17 00:00:00 2001
From: Simon Dietz
Date: Sat, 14 Dec 2024 14:24:33 +0100
Subject: [PATCH 13/15] Moved to the according package.
---
src/main/java/workspace/ui/{ => elements}/UiSlider.java | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename src/main/java/workspace/ui/{ => elements}/UiSlider.java (100%)
diff --git a/src/main/java/workspace/ui/UiSlider.java b/src/main/java/workspace/ui/elements/UiSlider.java
similarity index 100%
rename from src/main/java/workspace/ui/UiSlider.java
rename to src/main/java/workspace/ui/elements/UiSlider.java
From f23738192756cc1fe8e371793946cbacbf79a179 Mon Sep 17 00:00:00 2001
From: Simon Dietz
Date: Sat, 14 Dec 2024 14:24:57 +0100
Subject: [PATCH 14/15] Moved to the according package.
---
src/main/java/workspace/ui/elements/UiSlider.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/main/java/workspace/ui/elements/UiSlider.java b/src/main/java/workspace/ui/elements/UiSlider.java
index 14209ee2..b6f92b3e 100644
--- a/src/main/java/workspace/ui/elements/UiSlider.java
+++ b/src/main/java/workspace/ui/elements/UiSlider.java
@@ -1,6 +1,7 @@
-package workspace.ui;
+package workspace.ui.elements;
import math.Mathf;
+import workspace.ui.UiComponent;
import workspace.ui.border.Insets;
import workspace.ui.event.ISliderCallBack;
import workspace.ui.renderer.SliderRenderer;
From 0b571428983fed83cac1e8b6bac7408223d7b55f Mon Sep 17 00:00:00 2001
From: Simon Dietz
Date: Sat, 14 Dec 2024 14:25:16 +0100
Subject: [PATCH 15/15] Moved to the according package.
---
src/main/java/workspace/ui/renderer/SliderRenderer.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/workspace/ui/renderer/SliderRenderer.java b/src/main/java/workspace/ui/renderer/SliderRenderer.java
index b753a04f..91d37070 100644
--- a/src/main/java/workspace/ui/renderer/SliderRenderer.java
+++ b/src/main/java/workspace/ui/renderer/SliderRenderer.java
@@ -1,9 +1,9 @@
package workspace.ui.renderer;
import workspace.ui.Graphics;
-import workspace.ui.UiSlider;
import workspace.ui.border.Insets;
import workspace.ui.elements.UiElement;
+import workspace.ui.elements.UiSlider;
/**
* Renderer for the slider component.