diff --git a/core/src/main/java/info/openrocket/core/rocketcomponent/RocketComponent.java b/core/src/main/java/info/openrocket/core/rocketcomponent/RocketComponent.java index b4e44cac7..09b72676c 100644 --- a/core/src/main/java/info/openrocket/core/rocketcomponent/RocketComponent.java +++ b/core/src/main/java/info/openrocket/core/rocketcomponent/RocketComponent.java @@ -146,6 +146,12 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab // If true, component change events will not be fired private boolean bypassComponentChangeEvent = false; + + /** + * Controls the visibility of the component. If false, the component will not be rendered. + * Visibility does not affect component simulation. + */ + private boolean isVisible = true; /** @@ -2706,7 +2712,25 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab } return false; } - + + /** + * Returns true if this component is visible. + * @return True if this component is visible. + * @apiNote The component is rendered if true is returned. + */ + public boolean isVisible() { + return isVisible; + } + + /** + * Sets the component's visibility to the specified value. + * @param value Visibility value + * @apiNote The component is rendered if the specified value is set to true. + */ + public void setVisible(boolean value) { + this.isVisible = value; + fireComponentChangeEvent(ComponentChangeEvent.GRAPHIC_CHANGE); + } /////////// Iterators ////////// diff --git a/core/src/main/resources/l10n/messages.properties b/core/src/main/resources/l10n/messages.properties index f4b354c78..679525eac 100644 --- a/core/src/main/resources/l10n/messages.properties +++ b/core/src/main/resources/l10n/messages.properties @@ -50,6 +50,16 @@ RocketActions.MoveDownAct.ttip.Movedown = Move this component downwards. RocketActions.ExportOBJAct.ExportOBJ = Export as OBJ (.obj) RocketActions.ExportOBJAct.ttip.ExportOBJ = Export the selected components as a Wavefront OBJ 3D file. +RocketActions.Visibility = Visibility +RocketActions.VisibilityAct.ShowAll = Show all +RocketActions.VisibilityAct.ttip.ShowAll = Show all components. +RocketActions.VisibilityAct.HideAll = Hide all +RocketActions.VisibilityAct.ttip.HideAll = Hide all components. +RocketActions.VisibilityAct.ShowSelected = Show selected +RocketActions.VisibilityAct.ttip.ShowSelected = Show selected components. +RocketActions.VisibilityAct.HideSelected = Hide selected +RocketActions.VisibilityAct.ttip.HideSelected = Hide selected components. + ! RocketPanel RocketPanel.FigTypeAct.SideView = Side view RocketPanel.FigTypeAct.TopView = Top view diff --git a/swing/src/main/java/info/openrocket/swing/gui/figure3d/RocketRenderer.java b/swing/src/main/java/info/openrocket/swing/gui/figure3d/RocketRenderer.java index 8d24294ac..17524e7a6 100644 --- a/swing/src/main/java/info/openrocket/swing/gui/figure3d/RocketRenderer.java +++ b/swing/src/main/java/info/openrocket/swing/gui/figure3d/RocketRenderer.java @@ -214,7 +214,10 @@ public abstract class RocketRenderer { if( null == motor ){ throw new NullPointerException(" null motor from configuration.getActiveMotors... this is a bug."); } - + + if (!((RocketComponent) mount).isVisible()) { + continue; + } double length = motor.getLength(); Coordinate[] position = ((RocketComponent) mount).toAbsolute(new Coordinate(((RocketComponent) mount) diff --git a/swing/src/main/java/info/openrocket/swing/gui/figure3d/geometry/ComponentRenderer.java b/swing/src/main/java/info/openrocket/swing/gui/figure3d/geometry/ComponentRenderer.java index 6b51773d4..b04a76396 100644 --- a/swing/src/main/java/info/openrocket/swing/gui/figure3d/geometry/ComponentRenderer.java +++ b/swing/src/main/java/info/openrocket/swing/gui/figure3d/geometry/ComponentRenderer.java @@ -95,6 +95,9 @@ public class ComponentRenderer { if (glu == null) throw new IllegalStateException(this + " Not Initialized"); + if (!c.isVisible()) { + return; + } glu.gluQuadricNormals(q, GLU.GLU_SMOOTH); if (c instanceof BodyTube) { diff --git a/swing/src/main/java/info/openrocket/swing/gui/main/BasicFrame.java b/swing/src/main/java/info/openrocket/swing/gui/main/BasicFrame.java index 686277cee..fa6306cae 100644 --- a/swing/src/main/java/info/openrocket/swing/gui/main/BasicFrame.java +++ b/swing/src/main/java/info/openrocket/swing/gui/main/BasicFrame.java @@ -52,8 +52,6 @@ import net.miginfocom.swing.MigLayout; import info.openrocket.core.file.wavefrontobj.export.OBJExportOptions; import info.openrocket.core.file.wavefrontobj.export.OBJExporterFactory; -import info.openrocket.core.file.wavefrontobj.CoordTransform; -import info.openrocket.core.file.wavefrontobj.DefaultCoordTransform; import info.openrocket.core.logging.ErrorSet; import info.openrocket.core.logging.WarningSet; import info.openrocket.core.appearance.DecalImage; @@ -257,6 +255,7 @@ public class BasicFrame extends JFrame { popupMenu.addSeparator(); popupMenu.add(actions.getScaleAction()); + popupMenu.add(actions.getToggleVisibilityAction()); popupMenu.addSeparator(); popupMenu.add(actions.getExportOBJAction()); @@ -608,6 +607,15 @@ public class BasicFrame extends JFrame { item = new JMenuItem(actions.getScaleAction()); editMenu.add(item); + //// Visibility + JMenu visibilitySubMenu = new JMenu(trans.get("RocketActions.Visibility")); + editMenu.add(visibilitySubMenu); + item = new JMenuItem(actions.getToggleVisibilityAction()); + visibilitySubMenu.add(item); + item = new JMenuItem(actions.getShowAllComponentsAction()); + visibilitySubMenu.add(item); + + editMenu.addSeparator(); //// Preferences item = new JMenuItem(trans.get("main.menu.edit.preferences")); diff --git a/swing/src/main/java/info/openrocket/swing/gui/main/RocketActions.java b/swing/src/main/java/info/openrocket/swing/gui/main/RocketActions.java index 3e17f4e31..418b5ff3e 100644 --- a/swing/src/main/java/info/openrocket/swing/gui/main/RocketActions.java +++ b/swing/src/main/java/info/openrocket/swing/gui/main/RocketActions.java @@ -5,11 +5,7 @@ import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.io.Serial; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.LinkedList; -import java.util.List; +import java.util.*; import javax.swing.AbstractAction; import javax.swing.Action; @@ -18,8 +14,11 @@ import javax.swing.JOptionPane; import javax.swing.KeyStroke; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; + +import info.openrocket.core.rocketcomponent.*; import info.openrocket.swing.gui.configdialog.ComponentConfigDialog; import info.openrocket.swing.gui.dialogs.ScaleDialog; +import info.openrocket.swing.gui.util.GUIUtil; import info.openrocket.swing.gui.util.Icons; import org.slf4j.Logger; @@ -31,12 +30,6 @@ import info.openrocket.core.document.OpenRocketDocument; import info.openrocket.core.document.Simulation; import info.openrocket.core.l10n.Translator; import info.openrocket.core.logging.Markers; -import info.openrocket.core.rocketcomponent.ComponentChangeEvent; -import info.openrocket.core.rocketcomponent.ComponentChangeListener; -import info.openrocket.core.rocketcomponent.ParallelStage; -import info.openrocket.core.rocketcomponent.Rocket; -import info.openrocket.core.rocketcomponent.RocketComponent; -import info.openrocket.core.rocketcomponent.AxialStage; import info.openrocket.core.startup.Application; import info.openrocket.core.util.ORColor; import info.openrocket.core.util.Pair; @@ -81,6 +74,8 @@ public class RocketActions { private final RocketAction moveUpAction; private final RocketAction moveDownAction; private final RocketAction exportOBJAction; + private final RocketAction toggleVisibilityAction; + private final RocketAction showAllComponentsAction; private static final Translator trans = Application.getTranslator(); private static final Logger log = LoggerFactory.getLogger(RocketActions.class); @@ -106,6 +101,8 @@ public class RocketActions { this.moveUpAction = new MoveUpAction(); this.moveDownAction = new MoveDownAction(); this.exportOBJAction = new ExportOBJAction(); + this.toggleVisibilityAction = new ToggleVisibilityAction(); + this.showAllComponentsAction = new ShowAllComponentsAction(); OpenRocketClipboard.addClipboardListener(new ClipboardListener() { @Override @@ -154,6 +151,8 @@ public class RocketActions { moveUpAction.clipboardChanged(); moveDownAction.clipboardChanged(); exportOBJAction.clipboardChanged(); + toggleVisibilityAction.clipboardChanged(); + showAllComponentsAction.clipboardChanged(); } @@ -207,6 +206,14 @@ public class RocketActions { return exportOBJAction; } + public Action getToggleVisibilityAction() { + return toggleVisibilityAction; + } + + public Action getShowAllComponentsAction() { + return showAllComponentsAction; + } + /** * Tie an action to a JButton, without using the icon or text of the action for the button. * @@ -482,7 +489,26 @@ public class RocketActions { return result; } - + /** + * Returns all descendants of the specified component. + * + * @param component Component to query + * @return All descendants + * @apiNote Returns an empty set if the component does not have children. + */ + private Set getDescendants(RocketComponent component) { + Objects.requireNonNull(component); + + var result = new LinkedHashSet(); + var queue = new ArrayDeque<>(component.getChildren()); + + while (!queue.isEmpty()) { + var node = queue.pop(); + result.add(node); + node.getChildren().stream().filter(c -> !result.contains(c)).forEach(queue::add); + } + return result; + } /////// Action classes @@ -1257,4 +1283,121 @@ public class RocketActions { } } + /** + * Action to toggle the visibility of the selected components. + * @see RocketComponent#isVisible() + */ + private class ToggleVisibilityAction extends RocketAction { + public ToggleVisibilityAction() { + super.putValue(NAME, trans.get("RocketActions.VisibilityAct.HideSelected")); + super.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.VisibilityAct.ttip.HideSelected")); + super.putValue(SMALL_ICON, GUIUtil.getUITheme().getVisibilityHiddenIcon()); + clipboardChanged(); + } + + @Override + public void clipboardChanged() { + var components = new ArrayList<>(selectionModel.getSelectedComponents()); + super.setEnabled(!components.isEmpty()); + + if (components.isEmpty()) { + return; + } + + if (isRocketSelected(components)) { + super.putValue(NAME, rocket.isVisible() ? + trans.get("RocketActions.VisibilityAct.HideAll") : + trans.get("RocketActions.VisibilityAct.ShowAll")); + super.putValue(SHORT_DESCRIPTION, rocket.isVisible() ? + trans.get("RocketActions.VisibilityAct.ttip.HideAll") : + trans.get("RocketActions.VisibilityAct.ttip.ShowAll")); + super.putValue(SMALL_ICON, rocket.isVisible() ? + GUIUtil.getUITheme().getVisibilityHiddenIcon() : + GUIUtil.getUITheme().getVisibilityShowingIcon()); + } else { + var visibility = components.stream().anyMatch(RocketComponent::isVisible); + super.putValue(NAME, visibility ? + trans.get("RocketActions.VisibilityAct.HideSelected") : + trans.get("RocketActions.VisibilityAct.ShowSelected")); + super.putValue(SHORT_DESCRIPTION, visibility ? + trans.get("RocketActions.VisibilityAct.ttip.HideSelected") : + trans.get("RocketActions.VisibilityAct.ttip.ShowSelected")); + super.putValue(SMALL_ICON, visibility ? + GUIUtil.getUITheme().getVisibilityHiddenIcon() : + GUIUtil.getUITheme().getVisibilityShowingIcon()); + } + } + + @Override + public void actionPerformed(ActionEvent e) { + var components = new ArrayList<>(selectionModel.getSelectedComponents()); + + if (components.isEmpty()) { + return; + } + + // Toggle the visibility of the rocket and its descendants + if (isRocketSelected(components)) { + var rocketVisibility = !rocket.isVisible(); + rocket.setVisible(rocketVisibility); + getDescendants(rocket).forEach(descendant -> descendant.setVisible(rocketVisibility)); + return; + } + var visibility = components.stream().noneMatch(RocketComponent::isVisible); + + // Toggle the visibility of all non-stage and non-rocket components + components.stream().filter(c -> !(c instanceof AxialStage || c instanceof Rocket)).forEach(component -> { + component.setVisible(visibility); + + // Update the visibility of this component's stage + var stage = component.getStage(); + stage.setVisible(getDescendants(stage).stream().anyMatch(RocketComponent::isVisible)); + + // Update the visibility of the rocket + rocket.setVisible(getDescendants(rocket).stream().anyMatch(RocketComponent::isVisible)); + }); + + // Toggle the visibility of all stage components and their descendants + components.stream().filter(AxialStage.class::isInstance).forEach(stage -> { + stage.setVisible(visibility); + getDescendants(stage).forEach(descendant -> descendant.setVisible(visibility)); + }); + } + + /** + * Returns true if the rocket or all descendant are in the specified list. + * + * @param components Components to query + * @return True if all components are selected + */ + private boolean isRocketSelected(List components) { + var rocketSelected = components.stream().anyMatch(Rocket.class::isInstance); + var allComponentsSelected = getDescendants(rocket).size() == components.size(); + return rocketSelected || allComponentsSelected; + } + } + + /** + * Action to show all hidden components. + * @see RocketComponent#isVisible() + */ + private class ShowAllComponentsAction extends RocketAction { + public ShowAllComponentsAction() { + super.putValue(NAME, trans.get("RocketActions.VisibilityAct.ShowAll")); + super.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.VisibilityAct.ttip.ShowAll")); + super.putValue(SMALL_ICON, GUIUtil.getUITheme().getVisibilityShowingIcon()); + clipboardChanged(); + } + + @Override + public void clipboardChanged() { + super.setEnabled(getDescendants(rocket).stream().anyMatch(c -> !c.isVisible())); + } + + @Override + public void actionPerformed(ActionEvent e) { + rocket.setVisible(true); + getDescendants(rocket).forEach(descendant -> descendant.setVisible(true)); + } + } } diff --git a/swing/src/main/java/info/openrocket/swing/gui/main/componenttree/ComponentTreeRenderer.java b/swing/src/main/java/info/openrocket/swing/gui/main/componenttree/ComponentTreeRenderer.java index 0d4ea5ba6..5deaacca2 100644 --- a/swing/src/main/java/info/openrocket/swing/gui/main/componenttree/ComponentTreeRenderer.java +++ b/swing/src/main/java/info/openrocket/swing/gui/main/componenttree/ComponentTreeRenderer.java @@ -3,23 +3,16 @@ package info.openrocket.swing.gui.main.componenttree; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; -import java.awt.FlowLayout; -import java.awt.Font; import java.awt.Graphics; import java.util.LinkedList; import java.util.List; -import javax.swing.BorderFactory; -import javax.swing.BoxLayout; import javax.swing.Icon; -import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTree; -import javax.swing.SwingConstants; import javax.swing.UIManager; -import javax.swing.border.Border; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.TreePath; @@ -35,6 +28,7 @@ import info.openrocket.core.startup.Application; import info.openrocket.core.unit.UnitGroup; import info.openrocket.core.util.ArrayList; import info.openrocket.core.util.TextUtil; +import info.openrocket.swing.gui.util.Icons; @SuppressWarnings("serial") public class ComponentTreeRenderer extends DefaultTreeCellRenderer { @@ -45,6 +39,7 @@ public class ComponentTreeRenderer extends DefaultTreeCellRenderer { private static Color textSelectionForegroundColor; private static Color componentTreeBackgroundColor; private static Color componentTreeForegroundColor; + private static Color visibilityHiddenForegroundColor; private static Icon massOverrideSubcomponentIcon; private static Icon massOverrideIcon; private static Icon CGOverrideSubcomponentIcon; @@ -92,6 +87,11 @@ public class ComponentTreeRenderer extends DefaultTreeCellRenderer { RocketComponent c = (RocketComponent) value; applyToolTipText(components, c, panel); + // Set the cell text color if component is hidden + if (!c.isVisible() && !sel) { + label.setForeground(visibilityHiddenForegroundColor); + } + // Set the tree icon final Icon treeIcon; if (c.getClass().isAssignableFrom(MassComponent.class)) { @@ -103,10 +103,11 @@ public class ComponentTreeRenderer extends DefaultTreeCellRenderer { panel.add(new JLabel(treeIcon), BorderLayout.WEST); - // Add mass/CG/CD overridden icons + // Add mass/CG/CD overridden and component hidden icons if (c.isMassOverridden() || c.getMassOverriddenBy() != null || c.isCGOverridden() || c.getCGOverriddenBy() != null || - c.isCDOverridden() || c.getCDOverriddenBy() != null) { + c.isCDOverridden() || c.getCDOverriddenBy() != null || + !c.isVisible()) { List icons = new LinkedList<>(); if (c.getMassOverriddenBy() != null) { icons.add(massOverrideSubcomponentIcon); @@ -123,6 +124,9 @@ public class ComponentTreeRenderer extends DefaultTreeCellRenderer { } else if (c.isCDOverridden()) { icons.add(CDOverrideIcon); } + if (!c.isVisible()) { + icons.add(Icons.COMPONENT_HIDDEN); + } Icon combinedIcon = combineIcons(3, icons.toArray(new Icon[0])); JLabel overrideIconsLabel = new JLabel(combinedIcon); @@ -144,6 +148,7 @@ public class ComponentTreeRenderer extends DefaultTreeCellRenderer { CGOverrideIcon = GUIUtil.getUITheme().getCGOverrideIcon(); CDOverrideSubcomponentIcon = GUIUtil.getUITheme().getCDOverrideSubcomponentIcon(); CDOverrideIcon = GUIUtil.getUITheme().getCDOverrideIcon(); + visibilityHiddenForegroundColor = GUIUtil.getUITheme().getVisibilityHiddenForegroundColor(); } private void applyToolTipText(List components, RocketComponent c, JComponent comp) { diff --git a/swing/src/main/java/info/openrocket/swing/gui/scalefigure/RocketFigure.java b/swing/src/main/java/info/openrocket/swing/gui/scalefigure/RocketFigure.java index fdcfb9dfa..cf58cbc97 100644 --- a/swing/src/main/java/info/openrocket/swing/gui/scalefigure/RocketFigure.java +++ b/swing/src/main/java/info/openrocket/swing/gui/scalefigure/RocketFigure.java @@ -265,6 +265,10 @@ public class RocketFigure extends AbstractScaleFigure { while (!figureShapesCopy.isEmpty()) { RocketComponentShapes rcs = figureShapesCopy.poll(); RocketComponent c = rcs.getComponent(); + + if (!c.isVisible()) { + continue; + } boolean selected = false; // Check if component is in the selection @@ -322,6 +326,10 @@ public class RocketFigure extends AbstractScaleFigure { double motorRadius = motor.getDiameter() / 2; RocketComponent mountComponent = ((RocketComponent) mount); + if (!mountComponent.isVisible()) { + continue; + } + // .getLocation() will return all the parent instances of this owning component, AND all of it's own instances as well. // so, just draw a motor once for each Coordinate returned... Coordinate[] mountLocations = mount.getLocations(); diff --git a/swing/src/main/java/info/openrocket/swing/gui/theme/UITheme.java b/swing/src/main/java/info/openrocket/swing/gui/theme/UITheme.java index 46f523dbf..5be4f6a45 100644 --- a/swing/src/main/java/info/openrocket/swing/gui/theme/UITheme.java +++ b/swing/src/main/java/info/openrocket/swing/gui/theme/UITheme.java @@ -85,6 +85,7 @@ public class UITheme { Color getComponentTreeBackgroundColor(); Color getComponentTreeForegroundColor(); + Color getVisibilityHiddenForegroundColor(); Color getFinPointGridMajorLineColor(); Color getFinPointGridMinorLineColor(); @@ -99,6 +100,9 @@ public class UITheme { Icon getCDOverrideIcon(); Icon getCDOverrideSubcomponentIcon(); + Icon getVisibilityHiddenIcon(); + Icon getVisibilityShowingIcon(); + Border getBorder(); Border getMarginBorder(); Border getUnitSelectorBorder(); @@ -369,6 +373,11 @@ public class UITheme { return UIManager.getColor("Tree.textForeground"); } + @Override + public Color getVisibilityHiddenForegroundColor() { + return UIManager.getColor("Tree.textForeground.hidden.light"); + } + @Override public Color getFinPointGridMajorLineColor() { return new Color( 0, 0, 255, 80); @@ -424,6 +433,16 @@ public class UITheme { return Icons.CD_OVERRIDE_SUBCOMPONENT_LIGHT; } + @Override + public Icon getVisibilityHiddenIcon() { + return Icons.COMPONENT_HIDDEN_LIGHT; + } + + @Override + public Icon getVisibilityShowingIcon() { + return Icons.COMPONENT_SHOWING_LIGHT; + } + @Override public Border getBorder() { return new FlatBorder(); @@ -755,6 +774,11 @@ public class UITheme { return getTextColor(); } + @Override + public Color getVisibilityHiddenForegroundColor() { + return UIManager.getColor("Tree.textForeground.hidden.dark"); + } + @Override public Color getFinPointGridMajorLineColor() { return new Color(135, 135, 199, 197); @@ -810,6 +834,16 @@ public class UITheme { return Icons.CD_OVERRIDE_SUBCOMPONENT_DARK; } + @Override + public Icon getVisibilityHiddenIcon() { + return Icons.COMPONENT_HIDDEN_DARK; + } + + @Override + public Icon getVisibilityShowingIcon() { + return Icons.COMPONENT_SHOWING_DARK; + } + @Override public Border getBorder() { return new FlatBorder(); @@ -1141,6 +1175,11 @@ public class UITheme { return getTextColor(); } + @Override + public Color getVisibilityHiddenForegroundColor() { + return UIManager.getColor("Tree.textForeground.hidden.dark"); + } + @Override public Color getFinPointGridMajorLineColor() { return new Color(164, 164, 224, 197); @@ -1196,6 +1235,16 @@ public class UITheme { return Icons.CD_OVERRIDE_SUBCOMPONENT_DARK; } + @Override + public Icon getVisibilityHiddenIcon() { + return Icons.COMPONENT_HIDDEN_DARK; + } + + @Override + public Icon getVisibilityShowingIcon() { + return Icons.COMPONENT_SHOWING_DARK; + } + @Override public Border getBorder() { return new FlatBorder(); @@ -1546,6 +1595,11 @@ public class UITheme { return getCurrentTheme().getComponentTreeForegroundColor(); } + @Override + public Color getVisibilityHiddenForegroundColor() { + return getCurrentTheme().getVisibilityHiddenForegroundColor(); + } + @Override public Color getFinPointGridMajorLineColor() { return getCurrentTheme().getFinPointGridMajorLineColor(); @@ -1601,6 +1655,16 @@ public class UITheme { return getCurrentTheme().getCDOverrideSubcomponentIcon(); } + @Override + public Icon getVisibilityHiddenIcon() { + return getCurrentTheme().getVisibilityHiddenIcon(); + } + + @Override + public Icon getVisibilityShowingIcon() { + return getCurrentTheme().getVisibilityHiddenIcon(); + } + @Override public Border getBorder() { return getCurrentTheme().getBorder(); diff --git a/swing/src/main/java/info/openrocket/swing/gui/util/Icons.java b/swing/src/main/java/info/openrocket/swing/gui/util/Icons.java index cf3c6fd75..8711c980b 100644 --- a/swing/src/main/java/info/openrocket/swing/gui/util/Icons.java +++ b/swing/src/main/java/info/openrocket/swing/gui/util/Icons.java @@ -117,6 +117,12 @@ public class Icons { public static final Icon CD_OVERRIDE_SUBCOMPONENT_LIGHT = loadImageIcon("pix/icons/cd-override-subcomponent_light.png", "CD Override Subcomponent"); public static final Icon CD_OVERRIDE_SUBCOMPONENT_DARK = loadImageIcon("pix/icons/cd-override-subcomponent_dark.png", "CD Override Subcomponent"); + public static final Icon COMPONENT_HIDDEN = loadImageIcon("pix/icons/component-hidden.png", "Component Hidden"); + public static final Icon COMPONENT_HIDDEN_DARK = loadImageIcon("pix/icons/component-hidden_dark.png", "Component Hidden"); + public static final Icon COMPONENT_HIDDEN_LIGHT = loadImageIcon("pix/icons/component-hidden_light.png", "Component Hidden"); + public static final Icon COMPONENT_SHOWING_DARK = loadImageIcon("pix/icons/component-showing_dark.png", "Component Showing"); + public static final Icon COMPONENT_SHOWING_LIGHT = loadImageIcon("pix/icons/component-showing_light.png", "Component Showing"); + // MANUFACTURERS ICONS public static final Icon RASAERO = loadImageIcon("pix/icons/RASAero_16.png", "RASAero Icon"); public static final Icon ROCKSIM = loadImageIcon("pix/icons/Rocksim_16.png", "Rocksim Icon"); diff --git a/swing/src/main/resources/pix/icons/component-hidden.png b/swing/src/main/resources/pix/icons/component-hidden.png new file mode 100644 index 000000000..a9df29fa6 Binary files /dev/null and b/swing/src/main/resources/pix/icons/component-hidden.png differ diff --git a/swing/src/main/resources/pix/icons/component-hidden_dark.png b/swing/src/main/resources/pix/icons/component-hidden_dark.png new file mode 100644 index 000000000..b7258cff0 Binary files /dev/null and b/swing/src/main/resources/pix/icons/component-hidden_dark.png differ diff --git a/swing/src/main/resources/pix/icons/component-hidden_light.png b/swing/src/main/resources/pix/icons/component-hidden_light.png new file mode 100644 index 000000000..d58b28ae9 Binary files /dev/null and b/swing/src/main/resources/pix/icons/component-hidden_light.png differ diff --git a/swing/src/main/resources/pix/icons/component-showing_dark.png b/swing/src/main/resources/pix/icons/component-showing_dark.png new file mode 100644 index 000000000..7992c961d Binary files /dev/null and b/swing/src/main/resources/pix/icons/component-showing_dark.png differ diff --git a/swing/src/main/resources/pix/icons/component-showing_light.png b/swing/src/main/resources/pix/icons/component-showing_light.png new file mode 100644 index 000000000..f92166a2e Binary files /dev/null and b/swing/src/main/resources/pix/icons/component-showing_light.png differ diff --git a/swing/src/main/resources/themes/FlatLaf.properties b/swing/src/main/resources/themes/FlatLaf.properties index a9f98b247..0187ded38 100644 --- a/swing/src/main/resources/themes/FlatLaf.properties +++ b/swing/src/main/resources/themes/FlatLaf.properties @@ -9,6 +9,8 @@ Tree.paintLines = true Tree.showCellFocusIndicator = true Tree.wideSelection = true Tree.paintSelection = true +Tree.textForeground.hidden.dark = darken($Tree.textForeground, 25%) +Tree.textForeground.hidden.light = lighten($Tree.textForeground, 25%) # Margin as top,left,bottom,right Tree.rendererMargins = 2, 0, 3, 0