Merge pull request #1412 from SiboVG/issue-1411
[#1411] Show combined mass of multi-selection hover in component
This commit is contained in:
commit
213a9b9063
@ -1640,6 +1640,24 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iteratively checks whether the list of components contains the parent or super-parent (parent of parent of parent of...)
|
||||
* of component.
|
||||
* @param components list of components that may contain the parent
|
||||
* @param component component to check the parent for
|
||||
* @return true if the list contains the parent, false if not
|
||||
*/
|
||||
public static boolean listContainsParent(List<RocketComponent> components, RocketComponent component) {
|
||||
RocketComponent c = component;
|
||||
while (c.getParent() != null) {
|
||||
if (components.contains(c.getParent())) {
|
||||
return true;
|
||||
}
|
||||
c = c.getParent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the root component of the component tree.
|
||||
|
@ -278,24 +278,6 @@ public class RocketActions {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iteratively checks whether the list of components contains the parent or super-parent (parent of parent of parent of...)
|
||||
* of component.
|
||||
* @param components list of components that may contain the parent
|
||||
* @param component component to check the parent for
|
||||
* @return true if the list contains the parent, false if not
|
||||
*/
|
||||
public static boolean listContainsParent(List<RocketComponent> components, RocketComponent component) {
|
||||
RocketComponent c = component;
|
||||
while (c.getParent() != null) {
|
||||
if (components.contains(c.getParent())) {
|
||||
return true;
|
||||
}
|
||||
c = c.getParent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the children of a parent are not selected, add them to the selection. Do this recursively for the children
|
||||
* of the children as well.
|
||||
@ -340,7 +322,7 @@ public class RocketActions {
|
||||
// If there is a component in the selection, but its parent (or the parent of the parent) is still
|
||||
// not selected, add it to the selection
|
||||
RocketComponent temp = component;
|
||||
if (listContainsParent(selections, temp) && !selections.contains(temp.getParent())) {
|
||||
if (RocketComponent.listContainsParent(selections, temp) && !selections.contains(temp.getParent())) {
|
||||
while (!selections.contains(temp.getParent())) {
|
||||
selections.add(temp.getParent());
|
||||
temp = temp.getParent();
|
||||
@ -1038,7 +1020,7 @@ public class RocketActions {
|
||||
|
||||
for (RocketComponent component : components) {
|
||||
// Only move top components, don't move its children
|
||||
if (!listContainsParent(components, component)) {
|
||||
if (!RocketComponent.listContainsParent(components, component)) {
|
||||
moveUp(component);
|
||||
}
|
||||
}
|
||||
@ -1075,7 +1057,7 @@ public class RocketActions {
|
||||
return false;
|
||||
|
||||
for (RocketComponent component : components) {
|
||||
if (!listContainsParent(components, component) && !canMove(component))
|
||||
if (!RocketComponent.listContainsParent(components, component) && !canMove(component))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -1113,7 +1095,7 @@ public class RocketActions {
|
||||
|
||||
for (RocketComponent component : components) {
|
||||
// Only move top components, don't move its children
|
||||
if (!listContainsParent(components, component)) {
|
||||
if (!RocketComponent.listContainsParent(components, component)) {
|
||||
moveDown(component);
|
||||
}
|
||||
}
|
||||
@ -1150,7 +1132,7 @@ public class RocketActions {
|
||||
return false;
|
||||
|
||||
for (RocketComponent component : components) {
|
||||
if (!listContainsParent(components, component) && !canMove(component))
|
||||
if (!RocketComponent.listContainsParent(components, component) && !canMove(component))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -2,12 +2,14 @@ package net.sf.openrocket.gui.main.componenttree;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.FlowLayout;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.tree.DefaultTreeCellRenderer;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import net.sf.openrocket.gui.main.ComponentIcons;
|
||||
import net.sf.openrocket.gui.util.Icons;
|
||||
@ -17,6 +19,7 @@ import net.sf.openrocket.rocketcomponent.MassComponent.MassComponentType;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
import net.sf.openrocket.util.ArrayList;
|
||||
import net.sf.openrocket.util.TextUtil;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@ -31,11 +34,15 @@ public class ComponentTreeRenderer extends DefaultTreeCellRenderer {
|
||||
|
||||
Component comp = super.getTreeCellRendererComponent(tree, value, sel,
|
||||
expanded, leaf, row, hasFocus1);
|
||||
if (tree == null) return comp;
|
||||
TreePath[] paths = tree.getSelectionPaths();
|
||||
List<RocketComponent> components = null;
|
||||
if (paths != null && paths.length > 0) {
|
||||
components = new ArrayList<>(ComponentTreeModel.componentsFromPaths(paths));
|
||||
}
|
||||
|
||||
// Set icon
|
||||
|
||||
RocketComponent c = (RocketComponent) value;
|
||||
|
||||
if (c.getClass().isAssignableFrom(MassComponent.class)) {
|
||||
MassComponentType t = ((MassComponent) c).getMassComponentType();
|
||||
setIcon(ComponentIcons.getSmallMassTypeIcon(t));
|
||||
@ -54,17 +61,26 @@ public class ComponentTreeRenderer extends DefaultTreeCellRenderer {
|
||||
if (c.isCGOverridden()) {
|
||||
p.add(new JLabel(Icons.CG_OVERRIDE));
|
||||
}
|
||||
p.setToolTipText(getToolTip(c));
|
||||
|
||||
if (components != null && components.size() > 1 && components.contains(c)) {
|
||||
p.setToolTipText(getToolTipMultipleComponents(components));
|
||||
} else {
|
||||
p.setToolTipText(getToolTipSingleComponent(c));
|
||||
}
|
||||
|
||||
comp = p;
|
||||
}
|
||||
|
||||
// Set tooltip
|
||||
this.setToolTipText(getToolTip(c));
|
||||
if (components != null && components.size() > 1 && components.contains(c)) {
|
||||
this.setToolTipText(getToolTipMultipleComponents(components));
|
||||
} else {
|
||||
this.setToolTipText(getToolTipSingleComponent(c));
|
||||
}
|
||||
|
||||
return comp;
|
||||
}
|
||||
|
||||
private static String getToolTip(RocketComponent c) {
|
||||
private static String getToolTipSingleComponent(RocketComponent c) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("<html>");
|
||||
|
||||
@ -104,4 +120,55 @@ public class ComponentTreeRenderer extends DefaultTreeCellRenderer {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String getToolTipMultipleComponents(List<RocketComponent> components) {
|
||||
if (components == null || components.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("<html>");
|
||||
|
||||
sb.append("<b>Components</b>");
|
||||
double totalMass = 0;
|
||||
double totalSectionMass = 0;
|
||||
boolean containsSectionMass = false;
|
||||
for (RocketComponent c : components) {
|
||||
if (c.isMassive() || c.isMassOverridden()) {
|
||||
totalMass += c.getMass();
|
||||
// Don't add this component's mass to the section mass if its parent is in the list, otherwise you add up duplicate mass
|
||||
if (!RocketComponent.listContainsParent(components, c)) {
|
||||
if (c.getChildCount() > 0 && c.getSectionMass() > 0) {
|
||||
totalSectionMass += c.getSectionMass();
|
||||
containsSectionMass = true;
|
||||
} else {
|
||||
totalSectionMass += c.getMass();
|
||||
}
|
||||
}
|
||||
} else if ((c.getChildCount() > 0) && (c.getSectionMass() > 0)) {
|
||||
totalMass = c.getSectionMass();
|
||||
containsSectionMass = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sb.append(" (").append(UnitGroup.UNITS_MASS.toStringUnit(totalMass));
|
||||
if (containsSectionMass) {
|
||||
sb.append(" of ").append(UnitGroup.UNITS_MASS.toStringUnit(totalSectionMass)).append(" total)");
|
||||
} else {
|
||||
sb.append(")");
|
||||
}
|
||||
|
||||
// Set the component names as description
|
||||
sb.append("<br>");
|
||||
for (int i = 0; i < components.size(); i++) {
|
||||
if (i < components.size() - 1) {
|
||||
sb.append(components.get(i).getName()).append(", ");
|
||||
} else {
|
||||
sb.append(components.get(i).getName());
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ import javax.swing.TransferHandler;
|
||||
import javax.swing.tree.TreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import net.sf.openrocket.gui.main.RocketActions;
|
||||
import net.sf.openrocket.util.ArrayList;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -73,7 +72,7 @@ public class ComponentTreeTransferHandler extends TransferHandler {
|
||||
|
||||
// When the parent of a child is in the selection, don't include the child in components
|
||||
for (RocketComponent component : new ArrayList<>(components)) {
|
||||
if (RocketActions.listContainsParent(components, component)) {
|
||||
if (RocketComponent.listContainsParent(components, component)) {
|
||||
components.remove(component);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user