diff --git a/ugs-core/src/resources/MessagesBundle_en_US.properties b/ugs-core/src/resources/MessagesBundle_en_US.properties
index b2bc3d75bd..501187bb03 100644
--- a/ugs-core/src/resources/MessagesBundle_en_US.properties
+++ b/ugs-core/src/resources/MessagesBundle_en_US.properties
@@ -354,8 +354,10 @@ platform.visualizer.color.rapid = Rapid Movement Color (G0)
platform.visualizer.color.arc = Arc Movement Color (G2/G3)
platform.visualizer.color.plunge = Plunge/Raise Movement Color
platform.visualizer.color.completed = Color of lines which have been completed
-platform.visualizer.grid = Show coordinates and plane
-platform.visualizer.grid.desc = Show coordinates and plane
+platform.visualizer.grid = Toggles grid
+platform.visualizer.grid.desc = Toggles the grid
+platform.visualizer.plane = Toggle plane
+platform.visualizer.plane.desc = Toggles the plane
platform.visualizer.color.xy-grid = Color (and opacity) of XY grid lines.
platform.visualizer.color.xy-plane = Color (and opacity) of XY plane.
platform.visualizer.color.x-axis = Color (and opacity) of X-Axis line.
@@ -661,7 +663,7 @@ mainWindow.status.jog = Jog
mainWindow.status.offline = Off-line
platform.window.diagnostics = UGS Diagnostics
platform.window.diagnostics.tooltip = Internal UGS diagnostics information.
-platform.visualizer.popup.showFeatures = Show features
+platform.visualizer.popup.showFeatures = Features
platform.visualizer.popup.viewPresets = View presets
platform.visualizer.popup.presets.reset = Reset view
platform.visualizer.popup.presets.top = Top
diff --git a/ugs-platform/ProbeModule/src/main/java/com/willwinder/ugs/platform/probe/renderable/AbstractProbePreview.java b/ugs-platform/ProbeModule/src/main/java/com/willwinder/ugs/platform/probe/renderable/AbstractProbePreview.java
index 0cb32c082f..26afe116dd 100644
--- a/ugs-platform/ProbeModule/src/main/java/com/willwinder/ugs/platform/probe/renderable/AbstractProbePreview.java
+++ b/ugs-platform/ProbeModule/src/main/java/com/willwinder/ugs/platform/probe/renderable/AbstractProbePreview.java
@@ -18,6 +18,7 @@ This file is part of Universal Gcode Sender (UGS).
*/
package com.willwinder.ugs.platform.probe.renderable;
+import static com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions.VISUALIZER_OPTION_PROBE_PREVIEW;
import com.willwinder.ugs.nbm.visualizer.shared.Renderable;
import com.willwinder.ugs.platform.probe.ProbeParameters;
import com.willwinder.ugs.platform.probe.ProbeService;
@@ -28,8 +29,8 @@ public abstract class AbstractProbePreview extends Renderable {
private final ProbeService probeService;
- public AbstractProbePreview(int priority, String title) {
- super(priority, title);
+ protected AbstractProbePreview(int priority, String title) {
+ super(priority, title, VISUALIZER_OPTION_PROBE_PREVIEW);
probeService = Lookup.getDefault().lookup(ProbeService.class);
}
diff --git a/ugs-platform/ProbeModule/src/main/java/com/willwinder/ugs/platform/probe/renderable/CornerProbePathPreview.java b/ugs-platform/ProbeModule/src/main/java/com/willwinder/ugs/platform/probe/renderable/CornerProbePathPreview.java
index e466d07bb8..3abea23855 100644
--- a/ugs-platform/ProbeModule/src/main/java/com/willwinder/ugs/platform/probe/renderable/CornerProbePathPreview.java
+++ b/ugs-platform/ProbeModule/src/main/java/com/willwinder/ugs/platform/probe/renderable/CornerProbePathPreview.java
@@ -21,16 +21,13 @@ This file is part of Universal Gcode Sender (UGS).
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.util.gl2.GLUT;
-import com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions;
import com.willwinder.ugs.platform.probe.ProbeParameters;
import com.willwinder.ugs.platform.probe.renderable.ProbeRenderableHelpers.Side;
-import com.willwinder.universalgcodesender.model.Position;
-
-import static com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions.VISUALIZER_OPTION_PROBE_PREVIEW;
import static com.willwinder.ugs.platform.probe.renderable.ProbeRenderableHelpers.Side.NEGATIVE;
import static com.willwinder.ugs.platform.probe.renderable.ProbeRenderableHelpers.Side.POSITIVE;
import static com.willwinder.ugs.platform.probe.renderable.ProbeRenderableHelpers.drawArrow;
import static com.willwinder.ugs.platform.probe.renderable.ProbeRenderableHelpers.drawTouchPlate;
+import com.willwinder.universalgcodesender.model.Position;
/**
*
@@ -79,10 +76,6 @@ public boolean center() {
public void init(GLAutoDrawable drawable) {
}
- @Override
- public void reloadPreferences(VisualizerOptions vo) {
- }
-
private boolean invalidSettings() {
return this.spacing.x == 0
&& this.spacing.y == 0
@@ -202,14 +195,4 @@ public void draw(GLAutoDrawable drawable, boolean idle, Position machineCoord, P
drawXYZ(gl, X, Y);
}
}
-
- @Override
- public boolean isEnabled() {
- return VisualizerOptions.getBooleanOption(VISUALIZER_OPTION_PROBE_PREVIEW, true);
- }
-
- @Override
- public void setEnabled(boolean enabled) {
- VisualizerOptions.setBooleanOption(VISUALIZER_OPTION_PROBE_PREVIEW, enabled);
- }
}
diff --git a/ugs-platform/ProbeModule/src/main/java/com/willwinder/ugs/platform/probe/renderable/HoleCenterPathPreview.java b/ugs-platform/ProbeModule/src/main/java/com/willwinder/ugs/platform/probe/renderable/HoleCenterPathPreview.java
index 8c1bd6539f..6ea8671706 100644
--- a/ugs-platform/ProbeModule/src/main/java/com/willwinder/ugs/platform/probe/renderable/HoleCenterPathPreview.java
+++ b/ugs-platform/ProbeModule/src/main/java/com/willwinder/ugs/platform/probe/renderable/HoleCenterPathPreview.java
@@ -21,8 +21,6 @@ This file is part of Universal Gcode Sender (UGS).
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.util.gl2.GLUT;
-import com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions;
-import static com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions.VISUALIZER_OPTION_PROBE_PREVIEW;
import com.willwinder.ugs.platform.probe.ProbeParameters;
import com.willwinder.ugs.platform.probe.ProbeSettings;
import com.willwinder.ugs.platform.probe.renderable.ProbeRenderableHelpers.Triangle;
@@ -228,16 +226,6 @@ public void updateSettings() {
updateSpacing(ProbeSettings.getHcDiameter() * scaleFactor);
}
- @Override
- public boolean isEnabled() {
- return VisualizerOptions.getBooleanOption(VISUALIZER_OPTION_PROBE_PREVIEW, true);
- }
-
- @Override
- public void setEnabled(boolean enabled) {
- VisualizerOptions.setBooleanOption(VISUALIZER_OPTION_PROBE_PREVIEW, enabled);
- }
-
public void updateSpacing(double hcDiameter) {
this.hcDiameter = hcDiameter;
}
@@ -256,10 +244,6 @@ public boolean center() {
public void init(GLAutoDrawable drawable) {
}
- @Override
- public void reloadPreferences(VisualizerOptions vo) {
- }
-
private boolean invalidSettings() {
return this.hcDiameter <= 0;
}
diff --git a/ugs-platform/ProbeModule/src/main/java/com/willwinder/ugs/platform/probe/renderable/ZProbePathPreview.java b/ugs-platform/ProbeModule/src/main/java/com/willwinder/ugs/platform/probe/renderable/ZProbePathPreview.java
index d6ddec0f18..3b2410b6a7 100644
--- a/ugs-platform/ProbeModule/src/main/java/com/willwinder/ugs/platform/probe/renderable/ZProbePathPreview.java
+++ b/ugs-platform/ProbeModule/src/main/java/com/willwinder/ugs/platform/probe/renderable/ZProbePathPreview.java
@@ -21,8 +21,6 @@ This file is part of Universal Gcode Sender (UGS).
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.util.gl2.GLUT;
-import com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions;
-import static com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions.VISUALIZER_OPTION_PROBE_PREVIEW;
import com.willwinder.ugs.platform.probe.ProbeParameters;
import com.willwinder.ugs.platform.probe.ProbeSettings;
import com.willwinder.universalgcodesender.i18n.Localization;
@@ -76,10 +74,6 @@ public boolean center() {
public void init(GLAutoDrawable drawable) {
}
- @Override
- public void reloadPreferences(VisualizerOptions vo) {
- }
-
@Override
public void draw(GLAutoDrawable drawable, boolean idle, Position machineCoord, Position workCoord, Position objectMin, Position objectMax, double scaleFactor, Position mouseWorldCoordinates, Position rotation) {
if (this.probeDepth == null || this.probeOffset == null) return;
@@ -110,14 +104,4 @@ public void draw(GLAutoDrawable drawable, boolean idle, Position machineCoord, P
gl.glTranslated(0, 0, zAbs - 1);
glut.glutSolidCone(.2, 1, slices, stacks);
}
-
- @Override
- public boolean isEnabled() {
- return VisualizerOptions.getBooleanOption(VISUALIZER_OPTION_PROBE_PREVIEW, true);
- }
-
- @Override
- public void setEnabled(boolean enabled) {
- VisualizerOptions.setBooleanOption(VISUALIZER_OPTION_PROBE_PREVIEW, enabled);
- }
}
diff --git a/ugs-platform/ugs-platform-gcode-editor/src/main/java/com/willwinder/ugs/nbp/editor/actions/InsertPositionAction.java b/ugs-platform/ugs-platform-gcode-editor/src/main/java/com/willwinder/ugs/nbp/editor/actions/InsertPositionAction.java
index b19163108d..370f2d6090 100644
--- a/ugs-platform/ugs-platform-gcode-editor/src/main/java/com/willwinder/ugs/nbp/editor/actions/InsertPositionAction.java
+++ b/ugs-platform/ugs-platform-gcode-editor/src/main/java/com/willwinder/ugs/nbp/editor/actions/InsertPositionAction.java
@@ -36,8 +36,8 @@
@ActionReferences({
@ActionReference(
path = LocalizingService.MENU_EDIT,
- position = 1900,
- separatorAfter = 2000),
+ position = 1901,
+ separatorAfter = 1999),
})
public class InsertPositionAction extends AbstractAction implements UGSEventListener {
public static final String NAME = LocalizingService.InsertPositionTitle;
diff --git a/ugs-platform/ugs-platform-gcode-editor/src/main/java/com/willwinder/ugs/nbp/editor/renderer/EditorPosition.java b/ugs-platform/ugs-platform-gcode-editor/src/main/java/com/willwinder/ugs/nbp/editor/renderer/EditorPosition.java
index 86e14dbb0a..23d11b1383 100644
--- a/ugs-platform/ugs-platform-gcode-editor/src/main/java/com/willwinder/ugs/nbp/editor/renderer/EditorPosition.java
+++ b/ugs-platform/ugs-platform-gcode-editor/src/main/java/com/willwinder/ugs/nbp/editor/renderer/EditorPosition.java
@@ -1,5 +1,5 @@
/*
- Copyright 2016-2021 Will Winder
+ Copyright 2016-2024 Will Winder
This file is part of Universal Gcode Sender (UGS).
@@ -23,14 +23,13 @@ This file is part of Universal Gcode Sender (UGS).
import com.jogamp.opengl.glu.GLU;
import com.jogamp.opengl.glu.GLUquadric;
import com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions;
+import static com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions.VISUALIZER_OPTION_EDITOR_POSITION;
import com.willwinder.ugs.nbm.visualizer.renderables.GcodeModel;
import com.willwinder.ugs.nbm.visualizer.shared.Renderable;
import com.willwinder.universalgcodesender.model.Position;
import java.awt.Color;
-import static com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions.VISUALIZER_OPTION_EDITOR_POSITION;
-
/**
* Displays a pointer on the given line number
*
@@ -43,7 +42,7 @@ public class EditorPosition extends Renderable {
private Position position;
public EditorPosition(GcodeModel model, String title) {
- super(10, title);
+ super(10, title, VISUALIZER_OPTION_EDITOR_POSITION);
this.model = model;
}
@@ -62,10 +61,6 @@ public void init(GLAutoDrawable drawable) {
GQ = GLU.gluNewQuadric();
}
- @Override
- public void reloadPreferences(VisualizerOptions vo) {
- }
-
@Override
public void draw(GLAutoDrawable drawable, boolean idle, Position machineCoord, Position workCoord, Position focusMin, Position focusMax, double scaleFactor, Position mouseCoordinates, Position rotation) {
if (position == null || GQ == null) {
@@ -97,14 +92,4 @@ public void setLineNumber(int lineNumber) {
.findFirst()
.ifPresent(lineSegment -> position = lineSegment.getEnd());
}
-
- @Override
- public boolean isEnabled() {
- return VisualizerOptions.getBooleanOption(VISUALIZER_OPTION_EDITOR_POSITION, true);
- }
-
- @Override
- public void setEnabled(boolean enabled) {
- VisualizerOptions.setBooleanOption(VISUALIZER_OPTION_EDITOR_POSITION, enabled);
- }
}
diff --git a/ugs-platform/ugs-platform-gcode-editor/src/main/java/com/willwinder/ugs/nbp/editor/renderer/Highlight.java b/ugs-platform/ugs-platform-gcode-editor/src/main/java/com/willwinder/ugs/nbp/editor/renderer/Highlight.java
index 9cbfffa7eb..aa1fb9a4b6 100644
--- a/ugs-platform/ugs-platform-gcode-editor/src/main/java/com/willwinder/ugs/nbp/editor/renderer/Highlight.java
+++ b/ugs-platform/ugs-platform-gcode-editor/src/main/java/com/willwinder/ugs/nbp/editor/renderer/Highlight.java
@@ -1,5 +1,5 @@
/*
- Copyright 2016-2022 Will Winder
+ Copyright 2016-2024 Will Winder
This file is part of Universal Gcode Sender (UGS).
@@ -22,8 +22,11 @@ This file is part of Universal Gcode Sender (UGS).
import com.jogamp.opengl.GL2ES3;
import com.jogamp.opengl.GLAutoDrawable;
import com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions;
+import static com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions.VISUALIZER_OPTION_HIGHLIGHT;
+import static com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions.VISUALIZER_OPTION_HIGHLIGHT_COLOR;
import com.willwinder.ugs.nbm.visualizer.renderables.GcodeModel;
import com.willwinder.ugs.nbm.visualizer.shared.Renderable;
+import static com.willwinder.universalgcodesender.gcode.GcodePreprocessorUtils.getAngle;
import com.willwinder.universalgcodesender.gcode.util.Plane;
import com.willwinder.universalgcodesender.gcode.util.PlaneFormatter;
import com.willwinder.universalgcodesender.model.CNCPoint;
@@ -33,13 +36,8 @@ This file is part of Universal Gcode Sender (UGS).
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.stream.Collectors;
import java.util.stream.Stream;
-import static com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions.VISUALIZER_OPTION_HIGHLIGHT;
-import static com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions.VISUALIZER_OPTION_HIGHLIGHT_COLOR;
-import static com.willwinder.universalgcodesender.gcode.GcodePreprocessorUtils.getAngle;
-
/**
* Highlights the selected lines in the editor. It will attempt to buffer the lines with quads to make them more visible
* because GL's line width is platform dependant and is also deprecated.
@@ -60,13 +58,14 @@ public class Highlight extends Renderable {
private int endLine = 0;
public Highlight(GcodeModel model, String title) {
- super(9, title);
+ super(9, title, VISUALIZER_OPTION_HIGHLIGHT);
this.model = model;
reloadPreferences(new VisualizerOptions());
}
@Override
public final void reloadPreferences(VisualizerOptions vo) {
+ super.reloadPreferences(vo);
highlightColor = vo.getOptionForKey(VISUALIZER_OPTION_HIGHLIGHT_COLOR).value;
}
@@ -138,18 +137,8 @@ private void generateBufferedLines() {
CNCPoint dPoint = new Position(lineSegment.getStart()).add(xyOffset).add(zOffset);
return Stream.of(aPoint, bPoint, cPoint, dPoint);
})
- .collect(Collectors.toList());
+ .toList();
points.addAll(newPoints);
}
-
- @Override
- public void setEnabled(boolean enabled) {
- VisualizerOptions.setBooleanOption(VISUALIZER_OPTION_HIGHLIGHT, enabled);
- }
-
- @Override
- public boolean isEnabled() {
- return VisualizerOptions.getBooleanOption(VISUALIZER_OPTION_HIGHLIGHT, true);
- }
}
diff --git a/ugs-platform/ugs-platform-surfacescanner/src/main/java/com/willwinder/ugs/platform/surfacescanner/renderable/AutoLevelPreview.java b/ugs-platform/ugs-platform-surfacescanner/src/main/java/com/willwinder/ugs/platform/surfacescanner/renderable/AutoLevelPreview.java
index 3fa432c1cd..b09b48b340 100644
--- a/ugs-platform/ugs-platform-surfacescanner/src/main/java/com/willwinder/ugs/platform/surfacescanner/renderable/AutoLevelPreview.java
+++ b/ugs-platform/ugs-platform-surfacescanner/src/main/java/com/willwinder/ugs/platform/surfacescanner/renderable/AutoLevelPreview.java
@@ -1,5 +1,5 @@
/*
- Copyright 2017 Will Winder
+ Copyright 2017-2024 Will Winder
This file is part of Universal Gcode Sender (UGS).
@@ -24,6 +24,7 @@ This file is part of Universal Gcode Sender (UGS).
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.util.gl2.GLUT;
import com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions;
+import static com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions.VISUALIZER_OPTION_AUTOLEVEL_PREVIEW;
import com.willwinder.ugs.nbm.visualizer.shared.Renderable;
import com.willwinder.universalgcodesender.model.CNCPoint;
import com.willwinder.universalgcodesender.model.Position;
@@ -31,11 +32,8 @@ This file is part of Universal Gcode Sender (UGS).
import com.willwinder.universalgcodesender.model.UnitUtils.Units;
import java.util.Arrays;
-import java.util.Deque;
import java.util.stream.DoubleStream;
-import static com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions.VISUALIZER_OPTION_AUTOLEVEL_PREVIEW;
-
/**
* @author wwinder
*/
@@ -53,7 +51,7 @@ public class AutoLevelPreview extends Renderable {
private float[] low = {255, 0, 0}; // red
public AutoLevelPreview(String title) {
- super(10, title);
+ super(10, title, VISUALIZER_OPTION_AUTOLEVEL_PREVIEW);
glut = new GLUT();
@@ -76,6 +74,7 @@ public void init(GLAutoDrawable drawable) {
@Override
public final void reloadPreferences(VisualizerOptions vo) {
+ super.reloadPreferences(vo);
high = VisualizerOptions.colorToFloatArray(vo.getOptionForKey(VisualizerOptions.VISUALIZER_OPTION_HIGH).value);
low = VisualizerOptions.colorToFloatArray(vo.getOptionForKey(VisualizerOptions.VISUALIZER_OPTION_LOW).value);
}
@@ -239,11 +238,6 @@ private DoubleStream getGridZStream() {
.filter(z -> !Double.isNaN(z));
}
- @Override
- public boolean isEnabled() {
- return VisualizerOptions.getBooleanOption(VISUALIZER_OPTION_AUTOLEVEL_PREVIEW, true);
- }
-
@Override
public void setEnabled(boolean enabled) {
if (VisualizerOptions.getBooleanOption(VISUALIZER_OPTION_AUTOLEVEL_PREVIEW, true) != enabled) {
diff --git a/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/RendererInputHandler.java b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/RendererInputHandler.java
index 7e309abccc..aee1d98acd 100644
--- a/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/RendererInputHandler.java
+++ b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/RendererInputHandler.java
@@ -34,7 +34,6 @@ This file is part of Universal Gcode Sender (UGS).
import com.willwinder.universalgcodesender.model.events.CommandEventType;
import com.willwinder.universalgcodesender.model.events.ControllerStatusEvent;
import com.willwinder.universalgcodesender.model.events.FileStateEvent;
-import com.willwinder.universalgcodesender.model.events.SettingChangedEvent;
import com.willwinder.universalgcodesender.utils.Settings;
import com.willwinder.universalgcodesender.utils.Settings.FileStats;
import org.apache.commons.lang3.SystemUtils;
@@ -86,7 +85,6 @@ public RendererInputHandler(GcodeRenderer gr, AnimatorBase a, BackendAPI backend
gcodeModel = new GcodeModel(Localization.getString("platform.visualizer.renderable.gcode-model"), backend);
sizeDisplay = new SizeDisplay(Localization.getString("platform.visualizer.renderable.gcode-model-size"));
selection = new Selection(Localization.getString("platform.visualizer.renderable.selection"));
- sizeDisplay.setUnits(settings.getPreferredUnits());
gr.registerRenderable(gcodeModel);
gr.registerRenderable(sizeDisplay);
@@ -160,8 +158,6 @@ public void UGSEvent(UGSEvent cse) {
}
animator.resume();
- } else if (cse instanceof SettingChangedEvent) {
- sizeDisplay.setUnits(settings.getPreferredUnits());
} else if (cse instanceof ControllerStatusEvent controllerStatusEvent) {
gcodeRenderer.setMachineCoordinate(controllerStatusEvent.getStatus().getMachineCoord());
gcodeRenderer.setWorkCoordinate(controllerStatusEvent.getStatus().getWorkCoord());
diff --git a/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/VisualizerToolBar.java b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/VisualizerToolBar.java
index d622c4f60b..ca6f56a910 100644
--- a/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/VisualizerToolBar.java
+++ b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/VisualizerToolBar.java
@@ -1,5 +1,5 @@
/*
- Copyright 2022 Will Winder
+ Copyright 2022-2024 Will Winder
This file is part of Universal Gcode Sender (UGS).
@@ -22,11 +22,29 @@ This file is part of Universal Gcode Sender (UGS).
import com.willwinder.ugs.nbm.visualizer.actions.CameraXPreset;
import com.willwinder.ugs.nbm.visualizer.actions.CameraYPreset;
import com.willwinder.ugs.nbm.visualizer.actions.CameraZPreset;
+import com.willwinder.ugs.nbm.visualizer.actions.ToggleBoundaryFeatureAction;
+import com.willwinder.ugs.nbm.visualizer.actions.ToggleGridFeatureAction;
+import com.willwinder.ugs.nbm.visualizer.actions.ToggleModelFeatureAction;
+import com.willwinder.ugs.nbm.visualizer.actions.ToggleMouseFeatureAction;
+import com.willwinder.ugs.nbm.visualizer.actions.ToggleOrientationFeatureAction;
+import com.willwinder.ugs.nbm.visualizer.actions.TogglePlaneFeatureAction;
+import com.willwinder.ugs.nbm.visualizer.actions.ToggleSelectFeatureAction;
+import com.willwinder.ugs.nbm.visualizer.actions.ToggleSizeFeatureAction;
+import com.willwinder.ugs.nbm.visualizer.actions.ToggleToolFeatureAction;
import com.willwinder.ugs.nbp.core.actions.OutlineAction;
import com.willwinder.ugs.nbp.core.actions.ToggleUnitAction;
import com.willwinder.ugs.nbp.core.ui.ToolBar;
+import org.openide.awt.DropDownButtonFactory;
+import org.openide.util.ImageUtilities;
-import javax.swing.*;
+import javax.swing.Action;
+import javax.swing.Box;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.JToggleButton;
+import java.awt.event.ActionListener;
/**
* A toolbar for visualizer actions
@@ -34,28 +52,76 @@ This file is part of Universal Gcode Sender (UGS).
* @author Joacim Breiler
*/
public class VisualizerToolBar extends ToolBar {
+ private JButton cameraPresetButton = null;
+
public VisualizerToolBar() {
setFloatable(false);
initComponents();
}
private void initComponents() {
- createAndAddButton(new CameraResetPreset());
- createAndAddButton(new CameraXPreset());
- createAndAddButton(new CameraYPreset());
- createAndAddButton(new CameraZPreset());
+ add(createCameraPresetDropDownButton());
+ addSeparator();
+ createAndAddToggleButton(new TogglePlaneFeatureAction());
+ createAndAddToggleButton(new ToggleGridFeatureAction());
+ createAndAddToggleButton(new ToggleSizeFeatureAction());
+ createAndAddToggleButton(new ToggleToolFeatureAction());
+ createAndAddToggleButton(new ToggleBoundaryFeatureAction());
+ createAndAddToggleButton(new ToggleSelectFeatureAction());
+ createAndAddToggleButton(new ToggleOrientationFeatureAction());
+ createAndAddToggleButton(new ToggleModelFeatureAction());
+ createAndAddToggleButton(new ToggleMouseFeatureAction());
addSeparator();
createAndAddButton(new OutlineAction());
add(Box.createGlue());
createAndAddButton(new ToggleUnitAction());
}
+ private void createAndAddToggleButton(Action action) {
+ JToggleButton resetPresetButton = new JToggleButton(action);
+ resetPresetButton.setText("");
+ resetPresetButton.setToolTipText((String) action.getValue(Action.SHORT_DESCRIPTION));
+ this.add(resetPresetButton);
+ }
+
private void createAndAddButton(Action action) {
JButton resetPresetButton = new JButton(action);
resetPresetButton.setText("");
resetPresetButton.setToolTipText((String) action.getValue(Action.SHORT_DESCRIPTION));
- resetPresetButton.setContentAreaFilled(false);
- resetPresetButton.setBorderPainted(false);
this.add(resetPresetButton);
}
+
+
+ private JButton createCameraPresetDropDownButton() {
+ // An action listener that listens to the popup menu items and changes the current action
+ ActionListener toolMenuListener = e -> {
+ if (cameraPresetButton == null) {
+ return;
+ }
+
+ JMenuItem source = (JMenuItem) e.getSource();
+ cameraPresetButton.setIcon((Icon) source.getAction().getValue(Action.LARGE_ICON_KEY));
+ cameraPresetButton.setSelected(false);
+ cameraPresetButton.setAction(source.getAction());
+ };
+
+ CameraResetPreset cameraResetPreset = new CameraResetPreset();
+ JPopupMenu popupMenu = new JPopupMenu();
+ addDropDownAction(popupMenu, cameraResetPreset, toolMenuListener);
+ addDropDownAction(popupMenu, new CameraXPreset(), toolMenuListener);
+ addDropDownAction(popupMenu, new CameraYPreset(), toolMenuListener);
+ addDropDownAction(popupMenu, new CameraZPreset(), toolMenuListener);
+ cameraPresetButton = DropDownButtonFactory.createDropDownButton(ImageUtilities.loadImageIcon(CameraResetPreset.LARGE_ICON_PATH, false), popupMenu);
+ cameraPresetButton.setAction(cameraResetPreset);
+ return cameraPresetButton;
+ }
+
+ private void addDropDownAction(JPopupMenu popupMenu, Action action, ActionListener actionListener) {
+ JMenuItem menuItem = new JMenuItem(action);
+ if (actionListener != null) {
+ menuItem.addActionListener(actionListener);
+ }
+ popupMenu.add(menuItem);
+ }
+
}
diff --git a/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/MoveCameraAction.java b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/MoveCameraAction.java
index 72211eee4b..9981d63e90 100644
--- a/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/MoveCameraAction.java
+++ b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/MoveCameraAction.java
@@ -1,5 +1,5 @@
/*
- Copyright 2017-2018 Will Winder
+ Copyright 2017-2024 Will Winder
This file is part of Universal Gcode Sender (UGS).
@@ -31,7 +31,7 @@ This file is part of Universal Gcode Sender (UGS).
*/
public class MoveCameraAction extends AbstractAction {
- public static final Position CAMERA_POSITION = new Position(0, 0, 1.5);
+ public static final Position CAMERA_POSITION = new Position(0, 0, 3);
public static final Position ROTATION_TOP = new Position(0, 0, 0);
public static final Position ROTATION_LEFT = new Position(90, -90, 0);
public static final Position ROTATION_FRONT = new Position(0, -90, 0);
diff --git a/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleBoundaryFeatureAction.java b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleBoundaryFeatureAction.java
new file mode 100644
index 0000000000..ac4ba56e3c
--- /dev/null
+++ b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleBoundaryFeatureAction.java
@@ -0,0 +1,58 @@
+/*
+ Copyright 2024 Will Winder
+
+ This file is part of Universal Gcode Sender (UGS).
+
+ UGS is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ UGS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with UGS. If not, see .
+ */
+package com.willwinder.ugs.nbm.visualizer.actions;
+
+import com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions;
+import com.willwinder.ugs.nbp.lib.services.LocalizingService;
+import com.willwinder.universalgcodesender.model.BackendAPI;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionReferences;
+import org.openide.awt.ActionRegistration;
+import org.openide.awt.ActionState;
+import org.openide.util.ImageUtilities;
+
+@ActionID(
+ category = LocalizingService.CATEGORY_VISUALIZER,
+ id = ToggleBoundaryFeatureAction.ID
+)
+@ActionRegistration(
+ iconBase = ToggleBoundaryFeatureAction.SMALL_ICON_PATH,
+ displayName = "Toggle boundary",
+ checkedOn = @ActionState(type = BackendAPI.class, useActionInstance = true)
+)
+@ActionReferences({
+ @ActionReference(
+ path = LocalizingService.MENU_VISUALIZER,
+ position = 1090)
+})
+public class ToggleBoundaryFeatureAction extends ToggleFeatureAction {
+ public static final String ID = "com.willwinder.ugs.nbm.visualizer.actions.ToggleBoundaryFeatureAction";
+ public static final String SMALL_ICON_PATH = "icons/boundary.svg";
+ public static final String LARGE_ICON_PATH = "icons/boundary24.svg";
+
+ public ToggleBoundaryFeatureAction() {
+ super(VisualizerOptions.VISUALIZER_OPTION_BOUNDRY, VisualizerOptions.VISUALIZER_OPTION_BOUNDRY_DESC);
+
+ putValue("iconBase", SMALL_ICON_PATH);
+ putValue(SMALL_ICON, ImageUtilities.loadImageIcon(SMALL_ICON_PATH, false));
+ putValue(SMALL_ICON, ImageUtilities.loadImageIcon(SMALL_ICON_PATH, false));
+ putValue(LARGE_ICON_KEY, ImageUtilities.loadImageIcon(LARGE_ICON_PATH, false));
+ }
+}
diff --git a/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleFeatureAction.java b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleFeatureAction.java
new file mode 100644
index 0000000000..b01bb6d11b
--- /dev/null
+++ b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleFeatureAction.java
@@ -0,0 +1,73 @@
+/*
+ Copyright 2024 Will Winder
+
+ This file is part of Universal Gcode Sender (UGS).
+
+ UGS is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ UGS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with UGS. If not, see .
+ */
+package com.willwinder.ugs.nbm.visualizer.actions;
+
+import com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions;
+import com.willwinder.universalgcodesender.i18n.Localization;
+import org.openide.awt.Actions;
+import org.openide.util.ImageUtilities;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import java.awt.event.ActionEvent;
+
+/**
+ * A action base class for toggling a feature in the visualizer
+ *
+ * @author Joacim Breiler
+ */
+public class ToggleFeatureAction extends AbstractAction {
+ public static final String SMALL_ICON_PATH = "icons/grid.svg";
+ public static final String LARGE_ICON_PATH = "icons/grid24.svg";
+
+ private final String toggleKey;
+
+ protected ToggleFeatureAction(String toggleKey, String descriptionKey) {
+ this.toggleKey = toggleKey;
+
+ String title = Localization.getString(toggleKey);
+ putValue(NAME, title);
+ putValue("menuText", title);
+ putValue(SHORT_DESCRIPTION, Localization.getString(descriptionKey));
+
+ putValue("iconBase", SMALL_ICON_PATH);
+ putValue(SMALL_ICON, ImageUtilities.loadImageIcon(SMALL_ICON_PATH, false));
+ putValue(SMALL_ICON, ImageUtilities.loadImageIcon(SMALL_ICON_PATH, false));
+ putValue(LARGE_ICON_KEY, ImageUtilities.loadImageIcon(LARGE_ICON_PATH, false));
+
+ updateState();
+ VisualizerOptions.addListener(this::updateState);
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ boolean newValue = !VisualizerOptions.getBooleanOption(toggleKey, true);
+ VisualizerOptions.setBooleanOption(toggleKey, newValue);
+
+ updateState();
+ }
+
+ private void updateState() {
+ boolean value = VisualizerOptions.getBooleanOption(toggleKey, true);
+ putValue(Action.SELECTED_KEY, value);
+ putValue(Actions.ACTION_VALUE_TOGGLE, value);
+ setEnabled(true);
+ VisualizerOptions.setBooleanOption(toggleKey, value);
+ }
+}
diff --git a/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleGridFeatureAction.java b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleGridFeatureAction.java
new file mode 100644
index 0000000000..0d480bbf6a
--- /dev/null
+++ b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleGridFeatureAction.java
@@ -0,0 +1,58 @@
+/*
+ Copyright 2024 Will Winder
+
+ This file is part of Universal Gcode Sender (UGS).
+
+ UGS is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ UGS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with UGS. If not, see .
+ */
+package com.willwinder.ugs.nbm.visualizer.actions;
+
+import com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions;
+import com.willwinder.ugs.nbp.lib.services.LocalizingService;
+import com.willwinder.universalgcodesender.model.BackendAPI;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionReferences;
+import org.openide.awt.ActionRegistration;
+import org.openide.awt.ActionState;
+import org.openide.util.ImageUtilities;
+
+@ActionID(
+ category = LocalizingService.CATEGORY_VISUALIZER,
+ id = ToggleGridFeatureAction.ID
+)
+@ActionRegistration(
+ iconBase = ToggleGridFeatureAction.SMALL_ICON_PATH,
+ displayName = "Toggle grid",
+ checkedOn = @ActionState(type = BackendAPI.class, useActionInstance = true)
+)
+@ActionReferences({
+ @ActionReference(
+ path = LocalizingService.MENU_VISUALIZER,
+ position = 1075)
+})
+public class ToggleGridFeatureAction extends ToggleFeatureAction {
+ public static final String SMALL_ICON_PATH = "icons/grid.svg";
+ public static final String LARGE_ICON_PATH = "icons/grid24.svg";
+ public static final String ID = "com.willwinder.ugs.nbm.visualizer.actions.ToggleGridFeatureAction";
+
+
+ public ToggleGridFeatureAction() {
+ super(VisualizerOptions.VISUALIZER_OPTION_GRID, VisualizerOptions.VISUALIZER_OPTION_GRID_DESC);
+ putValue("iconBase", SMALL_ICON_PATH);
+ putValue(SMALL_ICON, ImageUtilities.loadImageIcon(SMALL_ICON_PATH, false));
+ putValue(SMALL_ICON, ImageUtilities.loadImageIcon(SMALL_ICON_PATH, false));
+ putValue(LARGE_ICON_KEY, ImageUtilities.loadImageIcon(LARGE_ICON_PATH, false));
+ }
+}
diff --git a/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleModelFeatureAction.java b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleModelFeatureAction.java
new file mode 100644
index 0000000000..f22cf9f199
--- /dev/null
+++ b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleModelFeatureAction.java
@@ -0,0 +1,58 @@
+/*
+ Copyright 2024 Will Winder
+
+ This file is part of Universal Gcode Sender (UGS).
+
+ UGS is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ UGS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with UGS. If not, see .
+ */
+package com.willwinder.ugs.nbm.visualizer.actions;
+
+import com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions;
+import com.willwinder.ugs.nbp.lib.services.LocalizingService;
+import com.willwinder.universalgcodesender.model.BackendAPI;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionReferences;
+import org.openide.awt.ActionRegistration;
+import org.openide.awt.ActionState;
+import org.openide.util.ImageUtilities;
+
+@ActionID(
+ category = LocalizingService.CATEGORY_VISUALIZER,
+ id = ToggleModelFeatureAction.ID
+)
+@ActionRegistration(
+ iconBase = ToggleModelFeatureAction.SMALL_ICON_PATH,
+ displayName = "Toggle tool path",
+ checkedOn = @ActionState(type = BackendAPI.class, useActionInstance = true)
+)
+@ActionReferences({
+ @ActionReference(
+ path = LocalizingService.MENU_VISUALIZER,
+ position = 1110)
+})
+public class ToggleModelFeatureAction extends ToggleFeatureAction {
+ public static final String SMALL_ICON_PATH = "icons/model.svg";
+ public static final String LARGE_ICON_PATH = "icons/model24.svg";
+ public static final String ID = "com.willwinder.ugs.nbm.visualizer.actions.ToggleModelFeatureAction";
+
+ public ToggleModelFeatureAction() {
+ super(VisualizerOptions.VISUALIZER_OPTION_MODEL, VisualizerOptions.VISUALIZER_OPTION_MODEL_DESC);
+
+ putValue("iconBase", SMALL_ICON_PATH);
+ putValue(SMALL_ICON, ImageUtilities.loadImageIcon(SMALL_ICON_PATH, false));
+ putValue(SMALL_ICON, ImageUtilities.loadImageIcon(SMALL_ICON_PATH, false));
+ putValue(LARGE_ICON_KEY, ImageUtilities.loadImageIcon(LARGE_ICON_PATH, false));
+ }
+}
diff --git a/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleMouseFeatureAction.java b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleMouseFeatureAction.java
new file mode 100644
index 0000000000..313a27e0a1
--- /dev/null
+++ b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleMouseFeatureAction.java
@@ -0,0 +1,58 @@
+/*
+ Copyright 2024 Will Winder
+
+ This file is part of Universal Gcode Sender (UGS).
+
+ UGS is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ UGS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with UGS. If not, see .
+ */
+package com.willwinder.ugs.nbm.visualizer.actions;
+
+import com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions;
+import com.willwinder.ugs.nbp.lib.services.LocalizingService;
+import com.willwinder.universalgcodesender.model.BackendAPI;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionReferences;
+import org.openide.awt.ActionRegistration;
+import org.openide.awt.ActionState;
+import org.openide.util.ImageUtilities;
+
+@ActionID(
+ category = LocalizingService.CATEGORY_VISUALIZER,
+ id = ToggleMouseFeatureAction.ID
+)
+@ActionRegistration(
+ iconBase = ToggleMouseFeatureAction.SMALL_ICON_PATH,
+ displayName = "Toggle mouse",
+ checkedOn = @ActionState(type = BackendAPI.class, useActionInstance = true)
+)
+@ActionReferences({
+ @ActionReference(
+ path = LocalizingService.MENU_VISUALIZER,
+ position = 1120)
+})
+public class ToggleMouseFeatureAction extends ToggleFeatureAction {
+ public static final String SMALL_ICON_PATH = "icons/mouse.svg";
+ public static final String LARGE_ICON_PATH = "icons/mouse24.svg";
+ public static final String ID = "com.willwinder.ugs.nbm.visualizer.actions.ToggleMouseFeatureAction";
+
+ public ToggleMouseFeatureAction() {
+ super(VisualizerOptions.VISUALIZER_OPTION_MOUSE_OVER, VisualizerOptions.VISUALIZER_OPTION_MOUSE_OVER_DESC);
+
+ putValue("iconBase", SMALL_ICON_PATH);
+ putValue(SMALL_ICON, ImageUtilities.loadImageIcon(SMALL_ICON_PATH, false));
+ putValue(SMALL_ICON, ImageUtilities.loadImageIcon(SMALL_ICON_PATH, false));
+ putValue(LARGE_ICON_KEY, ImageUtilities.loadImageIcon(LARGE_ICON_PATH, false));
+ }
+}
diff --git a/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleOrientationFeatureAction.java b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleOrientationFeatureAction.java
new file mode 100644
index 0000000000..19937a5aeb
--- /dev/null
+++ b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleOrientationFeatureAction.java
@@ -0,0 +1,58 @@
+/*
+ Copyright 2024 Will Winder
+
+ This file is part of Universal Gcode Sender (UGS).
+
+ UGS is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ UGS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with UGS. If not, see .
+ */
+package com.willwinder.ugs.nbm.visualizer.actions;
+
+import com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions;
+import com.willwinder.ugs.nbp.lib.services.LocalizingService;
+import com.willwinder.universalgcodesender.model.BackendAPI;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionReferences;
+import org.openide.awt.ActionRegistration;
+import org.openide.awt.ActionState;
+import org.openide.util.ImageUtilities;
+
+@ActionID(
+ category = LocalizingService.CATEGORY_VISUALIZER,
+ id = ToggleOrientationFeatureAction.ID
+)
+@ActionRegistration(
+ iconBase = ToggleOrientationFeatureAction.SMALL_ICON_PATH,
+ displayName = "Toggle orientation cube",
+ checkedOn = @ActionState(type = BackendAPI.class, useActionInstance = true)
+)
+@ActionReferences({
+ @ActionReference(
+ path = LocalizingService.MENU_VISUALIZER,
+ position = 1100)
+})
+public class ToggleOrientationFeatureAction extends ToggleFeatureAction {
+ public static final String ID = "com.willwinder.ugs.nbm.visualizer.actions.ToggleOrientationFeatureAction";
+ public static final String SMALL_ICON_PATH = "icons/cube.svg";
+ public static final String LARGE_ICON_PATH = "icons/cube24.svg";
+
+ public ToggleOrientationFeatureAction() {
+ super(VisualizerOptions.VISUALIZER_OPTION_ORIENTATION_CUBE, VisualizerOptions.VISUALIZER_OPTION_ORIENTATION_CUBE_DESC);
+
+ putValue("iconBase", SMALL_ICON_PATH);
+ putValue(SMALL_ICON, ImageUtilities.loadImageIcon(SMALL_ICON_PATH, false));
+ putValue(SMALL_ICON, ImageUtilities.loadImageIcon(SMALL_ICON_PATH, false));
+ putValue(LARGE_ICON_KEY, ImageUtilities.loadImageIcon(LARGE_ICON_PATH, false));
+ }
+}
diff --git a/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/TogglePlaneFeatureAction.java b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/TogglePlaneFeatureAction.java
new file mode 100644
index 0000000000..b016cd3de2
--- /dev/null
+++ b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/TogglePlaneFeatureAction.java
@@ -0,0 +1,57 @@
+/*
+ Copyright 2024 Will Winder
+
+ This file is part of Universal Gcode Sender (UGS).
+
+ UGS is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ UGS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with UGS. If not, see .
+ */
+package com.willwinder.ugs.nbm.visualizer.actions;
+
+import com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions;
+import com.willwinder.ugs.nbp.lib.services.LocalizingService;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionReferences;
+import org.openide.awt.ActionRegistration;
+import org.openide.util.ImageUtilities;
+
+@ActionID(
+ category = LocalizingService.CATEGORY_VISUALIZER,
+ id = TogglePlaneFeatureAction.ID
+)
+@ActionRegistration(
+ iconBase = TogglePlaneFeatureAction.SMALL_ICON_PATH,
+ displayName = "Toggle plane",
+ lazy = false
+)
+@ActionReferences({
+ @ActionReference(
+ separatorBefore = 1069,
+ path = LocalizingService.MENU_VISUALIZER,
+ position = 1070)
+})
+public class TogglePlaneFeatureAction extends ToggleFeatureAction {
+ public static final String SMALL_ICON_PATH = "icons/plane.svg";
+ public static final String LARGE_ICON_PATH = "icons/plane24.svg";
+ public static final String ID = "com.willwinder.ugs.nbm.visualizer.actions.TogglePlaneFeatureAction";
+
+ public TogglePlaneFeatureAction() {
+ super(VisualizerOptions.VISUALIZER_OPTION_PLANE, VisualizerOptions.VISUALIZER_OPTION_PLANE_DESC);
+
+ putValue("iconBase", SMALL_ICON_PATH);
+ putValue(SMALL_ICON, ImageUtilities.loadImageIcon(SMALL_ICON_PATH, false));
+ putValue(SMALL_ICON, ImageUtilities.loadImageIcon(SMALL_ICON_PATH, false));
+ putValue(LARGE_ICON_KEY, ImageUtilities.loadImageIcon(LARGE_ICON_PATH, false));
+ }
+}
diff --git a/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleSelectFeatureAction.java b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleSelectFeatureAction.java
new file mode 100644
index 0000000000..2ad1f4398a
--- /dev/null
+++ b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleSelectFeatureAction.java
@@ -0,0 +1,59 @@
+/*
+ Copyright 2024 Will Winder
+
+ This file is part of Universal Gcode Sender (UGS).
+
+ UGS is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ UGS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with UGS. If not, see .
+ */
+package com.willwinder.ugs.nbm.visualizer.actions;
+
+import com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions;
+import com.willwinder.ugs.nbp.lib.services.LocalizingService;
+import com.willwinder.universalgcodesender.model.BackendAPI;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionReferences;
+import org.openide.awt.ActionRegistration;
+import org.openide.awt.ActionState;
+import org.openide.util.ImageUtilities;
+
+
+@ActionID(
+ category = LocalizingService.CATEGORY_VISUALIZER,
+ id = ToggleSelectFeatureAction.ID
+)
+@ActionRegistration(
+ iconBase = ToggleSelectFeatureAction.SMALL_ICON_PATH,
+ displayName = "Toggle selected lines",
+ checkedOn = @ActionState(type = BackendAPI.class, useActionInstance = true)
+)
+@ActionReferences({
+ @ActionReference(
+ path = LocalizingService.MENU_VISUALIZER,
+ position = 1095)
+})
+public class ToggleSelectFeatureAction extends ToggleFeatureAction {
+ public static final String ID = "com.willwinder.ugs.nbm.visualizer.actions.ToggleSelectFeatureAction";
+ public static final String SMALL_ICON_PATH = "icons/select.svg";
+ public static final String LARGE_ICON_PATH = "icons/select24.svg";
+
+ public ToggleSelectFeatureAction() {
+ super(VisualizerOptions.VISUALIZER_OPTION_SELECTION, VisualizerOptions.VISUALIZER_OPTION_SELECTION_DESC);
+
+ putValue("iconBase", SMALL_ICON_PATH);
+ putValue(SMALL_ICON, ImageUtilities.loadImageIcon(SMALL_ICON_PATH, false));
+ putValue(SMALL_ICON, ImageUtilities.loadImageIcon(SMALL_ICON_PATH, false));
+ putValue(LARGE_ICON_KEY, ImageUtilities.loadImageIcon(LARGE_ICON_PATH, false));
+ }
+}
diff --git a/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleSizeFeatureAction.java b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleSizeFeatureAction.java
new file mode 100644
index 0000000000..cf97180f76
--- /dev/null
+++ b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleSizeFeatureAction.java
@@ -0,0 +1,58 @@
+/*
+ Copyright 2024 Will Winder
+
+ This file is part of Universal Gcode Sender (UGS).
+
+ UGS is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ UGS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with UGS. If not, see .
+ */
+package com.willwinder.ugs.nbm.visualizer.actions;
+
+import com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions;
+import com.willwinder.ugs.nbp.lib.services.LocalizingService;
+import com.willwinder.universalgcodesender.model.BackendAPI;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionReferences;
+import org.openide.awt.ActionRegistration;
+import org.openide.awt.ActionState;
+import org.openide.util.ImageUtilities;
+
+@ActionID(
+ category = LocalizingService.CATEGORY_VISUALIZER,
+ id = ToggleSizeFeatureAction.ID
+)
+@ActionRegistration(
+ iconBase = ToggleSizeFeatureAction.SMALL_ICON_PATH,
+ displayName = "Toggle size",
+ checkedOn = @ActionState(type = BackendAPI.class, useActionInstance = true)
+)
+@ActionReferences({
+ @ActionReference(
+ path = LocalizingService.MENU_VISUALIZER,
+ position = 1080)
+})
+public class ToggleSizeFeatureAction extends ToggleFeatureAction {
+ public static final String ID = "com.willwinder.ugs.nbm.visualizer.actions.ToggleSizeFeatureAction";
+ public static final String SMALL_ICON_PATH = "icons/size.svg";
+ public static final String LARGE_ICON_PATH = "icons/size24.svg";
+
+ public ToggleSizeFeatureAction() {
+ super(VisualizerOptions.VISUALIZER_OPTION_SIZE_DISPLAY, VisualizerOptions.VISUALIZER_OPTION_SIZE_DISPLAY_DESC);
+
+ putValue("iconBase", SMALL_ICON_PATH);
+ putValue(SMALL_ICON, ImageUtilities.loadImageIcon(SMALL_ICON_PATH, false));
+ putValue(SMALL_ICON, ImageUtilities.loadImageIcon(SMALL_ICON_PATH, false));
+ putValue(LARGE_ICON_KEY, ImageUtilities.loadImageIcon(LARGE_ICON_PATH, false));
+ }
+}
diff --git a/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleToolFeatureAction.java b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleToolFeatureAction.java
new file mode 100644
index 0000000000..cc5d7ba812
--- /dev/null
+++ b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/actions/ToggleToolFeatureAction.java
@@ -0,0 +1,58 @@
+/*
+ Copyright 2024 Will Winder
+
+ This file is part of Universal Gcode Sender (UGS).
+
+ UGS is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ UGS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with UGS. If not, see .
+ */
+package com.willwinder.ugs.nbm.visualizer.actions;
+
+import com.willwinder.ugs.nbm.visualizer.options.VisualizerOptions;
+import com.willwinder.ugs.nbp.lib.services.LocalizingService;
+import com.willwinder.universalgcodesender.model.BackendAPI;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionReferences;
+import org.openide.awt.ActionRegistration;
+import org.openide.awt.ActionState;
+import org.openide.util.ImageUtilities;
+
+@ActionID(
+ category = LocalizingService.CATEGORY_VISUALIZER,
+ id = ToggleToolFeatureAction.ID
+)
+@ActionRegistration(
+ iconBase = ToggleToolFeatureAction.SMALL_ICON_PATH,
+ displayName = "Toggle tool",
+ checkedOn = @ActionState(type = BackendAPI.class, useActionInstance = true)
+)
+@ActionReferences({
+ @ActionReference(
+ path = LocalizingService.MENU_VISUALIZER,
+ position = 1085)
+})
+public class ToggleToolFeatureAction extends ToggleFeatureAction {
+ public static final String ID = "com.willwinder.ugs.nbm.visualizer.actions.ToggleToolFeatureAction";
+ public static final String SMALL_ICON_PATH = "icons/tool.svg";
+ public static final String LARGE_ICON_PATH = "icons/tool24.svg";
+
+ public ToggleToolFeatureAction() {
+ super(VisualizerOptions.VISUALIZER_OPTION_TOOL, VisualizerOptions.VISUALIZER_OPTION_TOOL_DESC);
+
+ putValue("iconBase", SMALL_ICON_PATH);
+ putValue(SMALL_ICON, ImageUtilities.loadImageIcon(SMALL_ICON_PATH, false));
+ putValue(SMALL_ICON, ImageUtilities.loadImageIcon(SMALL_ICON_PATH, false));
+ putValue(LARGE_ICON_KEY, ImageUtilities.loadImageIcon(LARGE_ICON_PATH, false));
+ }
+}
diff --git a/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/options/VisualizerOptions.java b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/options/VisualizerOptions.java
index 8ac0a31212..3ece686cf8 100644
--- a/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/options/VisualizerOptions.java
+++ b/ugs-platform/ugs-platform-visualizer/src/main/java/com/willwinder/ugs/nbm/visualizer/options/VisualizerOptions.java
@@ -1,5 +1,5 @@
/*
- Copyright 2016-2022 Will Winder
+ Copyright 2016-2024 Will Winder
This file is part of Universal Gcode Sender (UGS).
@@ -65,11 +65,14 @@ public class VisualizerOptions extends ArrayList