Merge pull request #220 from enderw88/better-tree-icons
Added component tree icons for the new mass types.
@ -1401,6 +1401,13 @@ ComponentIcons.Streamer = Streamer
|
||||
ComponentIcons.Shockcord = Shock cord
|
||||
ComponentIcons.Masscomponent = Mass component
|
||||
ComponentIcons.disabled = (disabled)
|
||||
ComponentIcons.Altimeter = Altimeter
|
||||
ComponentIcons.Flightcomputer = Flight computer
|
||||
ComponentIcons.Battery = Battery
|
||||
ComponentIcons.Tracker = Tracker
|
||||
ComponentIcons.Recoveryhardware = Recovery hardware
|
||||
ComponentIcons.Payload = Payload
|
||||
ComponentIcons.Deploymentcharge = Deployment charge
|
||||
|
||||
! StageAction
|
||||
StageAction.Stage = Stage
|
||||
|
BIN
core/resources/pix/componenticons/altimeter-small.png
Normal file
After Width: | Height: | Size: 799 B |
BIN
core/resources/pix/componenticons/battery-small.png
Normal file
After Width: | Height: | Size: 842 B |
BIN
core/resources/pix/componenticons/deployment-charge-small.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
core/resources/pix/componenticons/flight-comp-small.png
Normal file
After Width: | Height: | Size: 871 B |
BIN
core/resources/pix/componenticons/payload-small.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
core/resources/pix/componenticons/recovery-hardware-small.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
core/resources/pix/componenticons/tracker-small.png
Normal file
After Width: | Height: | Size: 851 B |
@ -19,6 +19,7 @@ import net.sf.openrocket.rocketcomponent.FreeformFinSet;
|
||||
import net.sf.openrocket.rocketcomponent.InnerTube;
|
||||
import net.sf.openrocket.rocketcomponent.LaunchLug;
|
||||
import net.sf.openrocket.rocketcomponent.MassComponent;
|
||||
import net.sf.openrocket.rocketcomponent.MassComponent.MassComponentType;
|
||||
import net.sf.openrocket.rocketcomponent.NoseCone;
|
||||
import net.sf.openrocket.rocketcomponent.Parachute;
|
||||
import net.sf.openrocket.rocketcomponent.ShockCord;
|
||||
@ -28,145 +29,194 @@ import net.sf.openrocket.rocketcomponent.TrapezoidFinSet;
|
||||
import net.sf.openrocket.rocketcomponent.TubeCoupler;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
|
||||
|
||||
public class ComponentIcons {
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
|
||||
private static final String ICON_DIRECTORY = "pix/componenticons/";
|
||||
private static final String SMALL_SUFFIX = "-small.png";
|
||||
private static final String LARGE_SUFFIX = "-large.png";
|
||||
|
||||
private static final HashMap<Class<?>, ImageIcon> SMALL_ICONS =
|
||||
new HashMap<Class<?>, ImageIcon>();
|
||||
private static final HashMap<Class<?>, ImageIcon> LARGE_ICONS =
|
||||
new HashMap<Class<?>, ImageIcon>();
|
||||
private static final HashMap<Class<?>, ImageIcon> DISABLED_ICONS =
|
||||
new HashMap<Class<?>, ImageIcon>();
|
||||
|
||||
|
||||
private static final HashMap<Class<?>, ImageIcon> SMALL_ICONS = new HashMap<Class<?>, ImageIcon>();
|
||||
private static final HashMap<Class<?>, ImageIcon> LARGE_ICONS = new HashMap<Class<?>, ImageIcon>();
|
||||
private static final HashMap<Class<?>, ImageIcon> DISABLED_ICONS = new HashMap<Class<?>, ImageIcon>();
|
||||
private static final HashMap<MassComponentType, ImageIcon> MASS_COMPONENT_SMALL_ICONS = new HashMap<MassComponentType, ImageIcon>();
|
||||
static {
|
||||
//// Nose cone
|
||||
// // Nose cone
|
||||
load("nosecone", trans.get("ComponentIcons.Nosecone"), NoseCone.class);
|
||||
//// Body tube
|
||||
// // Body tube
|
||||
load("bodytube", trans.get("ComponentIcons.Bodytube"), BodyTube.class);
|
||||
//// Transition
|
||||
load("transition", trans.get("ComponentIcons.Transition"), Transition.class);
|
||||
//// Trapezoidal fin set
|
||||
load("trapezoidfin", trans.get("ComponentIcons.Trapezoidalfinset"), TrapezoidFinSet.class);
|
||||
//// Elliptical fin set
|
||||
load("ellipticalfin", trans.get("ComponentIcons.Ellipticalfinset"), EllipticalFinSet.class);
|
||||
//// Freeform fin set
|
||||
load("freeformfin", trans.get("ComponentIcons.Freeformfinset"), FreeformFinSet.class);
|
||||
//// Launch lug
|
||||
load("launchlug", trans.get("ComponentIcons.Launchlug"), LaunchLug.class);
|
||||
//// Inner tube
|
||||
load("innertube", trans.get("ComponentIcons.Innertube"), InnerTube.class);
|
||||
//// Tube coupler
|
||||
load("tubecoupler", trans.get("ComponentIcons.Tubecoupler"), TubeCoupler.class);
|
||||
//// Centering ring
|
||||
load("centeringring", trans.get("ComponentIcons.Centeringring"), CenteringRing.class);
|
||||
//// Bulk head
|
||||
// // Transition
|
||||
load("transition", trans.get("ComponentIcons.Transition"),
|
||||
Transition.class);
|
||||
// // Trapezoidal fin set
|
||||
load("trapezoidfin", trans.get("ComponentIcons.Trapezoidalfinset"),
|
||||
TrapezoidFinSet.class);
|
||||
// // Elliptical fin set
|
||||
load("ellipticalfin", trans.get("ComponentIcons.Ellipticalfinset"),
|
||||
EllipticalFinSet.class);
|
||||
// // Freeform fin set
|
||||
load("freeformfin", trans.get("ComponentIcons.Freeformfinset"),
|
||||
FreeformFinSet.class);
|
||||
// // Launch lug
|
||||
load("launchlug", trans.get("ComponentIcons.Launchlug"),
|
||||
LaunchLug.class);
|
||||
// // Inner tube
|
||||
load("innertube", trans.get("ComponentIcons.Innertube"),
|
||||
InnerTube.class);
|
||||
// // Tube coupler
|
||||
load("tubecoupler", trans.get("ComponentIcons.Tubecoupler"),
|
||||
TubeCoupler.class);
|
||||
// // Centering ring
|
||||
load("centeringring", trans.get("ComponentIcons.Centeringring"),
|
||||
CenteringRing.class);
|
||||
// // Bulk head
|
||||
load("bulkhead", trans.get("ComponentIcons.Bulkhead"), Bulkhead.class);
|
||||
//// Engine block
|
||||
load("engineblock", trans.get("ComponentIcons.Engineblock"), EngineBlock.class);
|
||||
//// Parachute
|
||||
load("parachute", trans.get("ComponentIcons.Parachute"), Parachute.class);
|
||||
//// Streamer
|
||||
// // Engine block
|
||||
load("engineblock", trans.get("ComponentIcons.Engineblock"),
|
||||
EngineBlock.class);
|
||||
// // Parachute
|
||||
load("parachute", trans.get("ComponentIcons.Parachute"),
|
||||
Parachute.class);
|
||||
// // Streamer
|
||||
load("streamer", trans.get("ComponentIcons.Streamer"), Streamer.class);
|
||||
//// Shock cord
|
||||
load("shockcord", trans.get("ComponentIcons.Shockcord"), ShockCord.class);
|
||||
//// Mass component
|
||||
load("mass", trans.get("ComponentIcons.Masscomponent"), MassComponent.class);
|
||||
// // Shock cord
|
||||
load("shockcord", trans.get("ComponentIcons.Shockcord"),
|
||||
ShockCord.class);
|
||||
load("mass", trans.get("ComponentIcons.Masscomponent"),
|
||||
MassComponent.class);
|
||||
// // Mass components
|
||||
loadMassTypeIcon("mass", trans.get("ComponentIcons.Masscomponent"),
|
||||
MassComponentType.MASSCOMPONENT);
|
||||
loadMassTypeIcon("altimeter", trans.get("ComponentIcons.Altimeter"),
|
||||
MassComponentType.ALTIMETER);
|
||||
loadMassTypeIcon("battery", trans.get("ComponentIcons.Battery"),
|
||||
MassComponentType.BATTERY);
|
||||
loadMassTypeIcon("deployment-charge",
|
||||
trans.get("ComponentIcons.Deploymentcharge"),
|
||||
MassComponentType.DEPLOYMENTCHARGE);
|
||||
loadMassTypeIcon("payload", trans.get("ComponentIcons.Payload"),
|
||||
MassComponentType.PAYLOAD);
|
||||
loadMassTypeIcon("flight-comp",
|
||||
trans.get("ComponentIcons.Flightcomputer"),
|
||||
MassComponentType.FLIGHTCOMPUTER);
|
||||
loadMassTypeIcon("recovery-hardware",
|
||||
trans.get("ComponentIcons.Recoveryhardware"),
|
||||
MassComponentType.RECOVERYHARDWARE);
|
||||
loadMassTypeIcon("tracker", trans.get("ComponentIcons.Tracker"),
|
||||
MassComponentType.TRACKER);
|
||||
}
|
||||
|
||||
private static void load(String filename, String name, Class<?> componentClass) {
|
||||
ImageIcon icon = loadSmall(ICON_DIRECTORY + filename + SMALL_SUFFIX, name);
|
||||
|
||||
private static void load(String filename, String name,
|
||||
Class<?> componentClass) {
|
||||
ImageIcon icon = loadSmall(ICON_DIRECTORY + filename + SMALL_SUFFIX,
|
||||
name);
|
||||
SMALL_ICONS.put(componentClass, icon);
|
||||
|
||||
ImageIcon[] icons = loadLarge(ICON_DIRECTORY + filename + LARGE_SUFFIX, name);
|
||||
|
||||
ImageIcon[] icons = loadLarge(ICON_DIRECTORY + filename + LARGE_SUFFIX,
|
||||
name);
|
||||
LARGE_ICONS.put(componentClass, icons[0]);
|
||||
DISABLED_ICONS.put(componentClass, icons[1]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void loadMassTypeIcon(String filename, String name,
|
||||
MassComponentType t) {
|
||||
ImageIcon icon = loadSmall(ICON_DIRECTORY + filename + SMALL_SUFFIX,
|
||||
name);
|
||||
MASS_COMPONENT_SMALL_ICONS.put(t, icon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the small icon for a component type.
|
||||
*
|
||||
* @param c the component class.
|
||||
* @return the icon, or <code>null</code> if none available.
|
||||
* @param c
|
||||
* the component class.
|
||||
* @return the icon, or <code>null</code> if none available.
|
||||
*/
|
||||
public static Icon getSmallIcon(Class<?> c) {
|
||||
if (c.isAssignableFrom(MassComponent.class)) {
|
||||
}
|
||||
return SMALL_ICONS.get(c);
|
||||
}
|
||||
|
||||
|
||||
public static Icon getSmallMassTypeIcon(MassComponentType t) {
|
||||
return MASS_COMPONENT_SMALL_ICONS.get(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the large icon for a component type.
|
||||
*
|
||||
* @param c the component class.
|
||||
* @return the icon, or <code>null</code> if none available.
|
||||
* @param c
|
||||
* the component class.
|
||||
* @return the icon, or <code>null</code> if none available.
|
||||
*/
|
||||
public static Icon getLargeIcon(Class<?> c) {
|
||||
return LARGE_ICONS.get(c);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the large disabled icon for a component type.
|
||||
*
|
||||
* @param c the component class.
|
||||
* @return the icon, or <code>null</code> if none available.
|
||||
* @param c
|
||||
* the component class.
|
||||
* @return the icon, or <code>null</code> if none available.
|
||||
*/
|
||||
public static Icon getLargeDisabledIcon(Class<?> c) {
|
||||
return DISABLED_ICONS.get(c);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private static ImageIcon loadSmall(String file, String desc) {
|
||||
URL url = ClassLoader.getSystemResource(file);
|
||||
if (url == null) {
|
||||
Application.getExceptionHandler().handleErrorCondition("ERROR: Couldn't find file: " + file);
|
||||
Application.getExceptionHandler().handleErrorCondition(
|
||||
"ERROR: Couldn't find file: " + file);
|
||||
return null;
|
||||
}
|
||||
return new ImageIcon(url, desc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static ImageIcon[] loadLarge(String file, String desc) {
|
||||
ImageIcon[] icons = new ImageIcon[2];
|
||||
|
||||
|
||||
URL url = ClassLoader.getSystemResource(file);
|
||||
if (url != null) {
|
||||
BufferedImage bi, bi2;
|
||||
try {
|
||||
bi = ImageIO.read(url);
|
||||
bi2 = ImageIO.read(url); // How the fsck can one duplicate a BufferedImage???
|
||||
bi2 = ImageIO.read(url); // How the fsck can one duplicate a
|
||||
// BufferedImage???
|
||||
} catch (IOException e) {
|
||||
Application.getExceptionHandler().handleErrorCondition("ERROR: Couldn't read file: " + file, e);
|
||||
Application.getExceptionHandler().handleErrorCondition(
|
||||
"ERROR: Couldn't read file: " + file, e);
|
||||
return new ImageIcon[] { null, null };
|
||||
}
|
||||
|
||||
|
||||
icons[0] = new ImageIcon(bi, desc);
|
||||
|
||||
|
||||
// Create disabled icon
|
||||
boolean useAlphaFade = false; // don't use fade to alpha yet
|
||||
if (useAlphaFade) { // Fade using alpha
|
||||
|
||||
/* TODO This code to do fade using alpha had been dead code inside a "if (false) {" block.
|
||||
* Eclipse would give a build warning about dead code, so this code has been commented out
|
||||
* but left here for future use; am assuming it was dead code because it wasn't working correctly
|
||||
* but that it will be useful in the future.
|
||||
boolean useAlphaFade = false; // don't use fade to alpha yet
|
||||
if (useAlphaFade) { // Fade using alpha
|
||||
|
||||
/*
|
||||
* TODO This code to do fade using alpha had been dead code
|
||||
* inside a "if (false) {" block. Eclipse would give a build
|
||||
* warning about dead code, so this code has been commented out
|
||||
* but left here for future use; am assuming it was dead code
|
||||
* because it wasn't working correctly but that it will be
|
||||
* useful in the future.
|
||||
*/
|
||||
// int rgb[] = bi2.getRGB(0, 0, bi2.getWidth(), bi2.getHeight(), null, 0, bi2.getWidth());
|
||||
// int rgb[] = bi2.getRGB(0, 0, bi2.getWidth(), bi2.getHeight(),
|
||||
// null, 0, bi2.getWidth());
|
||||
// for (int i = 0; i < rgb.length; i++) {
|
||||
// final int alpha = (rgb[i] >> 24) & 0xFF;
|
||||
// rgb[i] = (rgb[i] & 0xFFFFFF) | (alpha / 3) << 24;
|
||||
//
|
||||
// //rgb[i] = (rgb[i]&0xFFFFFF) | ((rgb[i]>>1)&0x3F000000);
|
||||
// final int alpha = (rgb[i] >> 24) & 0xFF;
|
||||
// rgb[i] = (rgb[i] & 0xFFFFFF) | (alpha / 3) << 24;
|
||||
//
|
||||
// //rgb[i] = (rgb[i]&0xFFFFFF) | ((rgb[i]>>1)&0x3F000000);
|
||||
// }
|
||||
// bi2.setRGB(0, 0, bi2.getWidth(), bi2.getHeight(), rgb, 0, bi2.getWidth());
|
||||
|
||||
// bi2.setRGB(0, 0, bi2.getWidth(), bi2.getHeight(), rgb, 0,
|
||||
// bi2.getWidth());
|
||||
|
||||
} else { // Raster alpha
|
||||
|
||||
|
||||
for (int x = 0; x < bi.getWidth(); x++) {
|
||||
for (int y = 0; y < bi.getHeight(); y++) {
|
||||
if ((x + y) % 2 == 0) {
|
||||
@ -174,15 +224,17 @@ public class ComponentIcons {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//// (disabled)
|
||||
icons[1] = new ImageIcon(bi2, desc + " " + trans.get("ComponentIcons.disabled"));
|
||||
|
||||
|
||||
// // (disabled)
|
||||
icons[1] = new ImageIcon(bi2, desc + " "
|
||||
+ trans.get("ComponentIcons.disabled"));
|
||||
|
||||
return icons;
|
||||
} else {
|
||||
Application.getExceptionHandler().handleErrorCondition("ERROR: Couldn't find file: " + file);
|
||||
Application.getExceptionHandler().handleErrorCondition(
|
||||
"ERROR: Couldn't find file: " + file);
|
||||
return new ImageIcon[] { null, null };
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
package net.sf.openrocket.gui.main.componenttree;
|
||||
|
||||
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.FlowLayout;
|
||||
|
||||
@ -14,88 +12,95 @@ import javax.swing.tree.DefaultTreeCellRenderer;
|
||||
import net.sf.openrocket.gui.main.ComponentIcons;
|
||||
import net.sf.openrocket.gui.util.Icons;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.rocketcomponent.MassComponent;
|
||||
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.TextUtil;
|
||||
|
||||
public class ComponentTreeRenderer extends DefaultTreeCellRenderer {
|
||||
|
||||
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
@Override
|
||||
public Component getTreeCellRendererComponent(
|
||||
JTree tree,
|
||||
Object value,
|
||||
boolean sel,
|
||||
boolean expanded,
|
||||
boolean leaf,
|
||||
int row,
|
||||
public Component getTreeCellRendererComponent(JTree tree, Object value,
|
||||
boolean sel, boolean expanded, boolean leaf, int row,
|
||||
boolean hasFocus1) {
|
||||
|
||||
Component comp = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus1);
|
||||
|
||||
|
||||
Component comp = super.getTreeCellRendererComponent(tree, value, sel,
|
||||
expanded, leaf, row, hasFocus1);
|
||||
|
||||
// Set icon
|
||||
setIcon(ComponentIcons.getSmallIcon(value.getClass()));
|
||||
|
||||
|
||||
RocketComponent c = (RocketComponent) value;
|
||||
|
||||
if ( c.isMassOverridden() || c.isCGOverridden()) {
|
||||
if (c.getClass().isAssignableFrom(MassComponent.class)) {
|
||||
MassComponentType t = ((MassComponent) c).getMassComponentType();
|
||||
setIcon(ComponentIcons.getSmallMassTypeIcon(t));
|
||||
} else {
|
||||
setIcon(ComponentIcons.getSmallIcon(value.getClass()));
|
||||
}
|
||||
if (c.isMassOverridden() || c.isCGOverridden()) {
|
||||
JPanel p = new JPanel();
|
||||
p.setLayout( new FlowLayout( FlowLayout.LEFT, 1,1) );
|
||||
p.setBackground( UIManager.getColor("Tree.textBackground"));
|
||||
p.setForeground( UIManager.getColor("Tree.textForeground"));
|
||||
p.add(comp/*, BorderLayout.WEST*/);
|
||||
if ( c.isMassOverridden() ) {
|
||||
p.add( new JLabel( Icons.MASS_OVERRIDE ) );
|
||||
p.setLayout(new FlowLayout(FlowLayout.LEFT, 1, 1));
|
||||
p.setBackground(UIManager.getColor("Tree.textBackground"));
|
||||
p.setForeground(UIManager.getColor("Tree.textForeground"));
|
||||
p.add(comp/* , BorderLayout.WEST */);
|
||||
if (c.isMassOverridden()) {
|
||||
p.add(new JLabel(Icons.MASS_OVERRIDE));
|
||||
}
|
||||
if ( c.isCGOverridden() ) {
|
||||
p.add( new JLabel(Icons.CG_OVERRIDE) );
|
||||
if (c.isCGOverridden()) {
|
||||
p.add(new JLabel(Icons.CG_OVERRIDE));
|
||||
}
|
||||
p.setToolTipText(getToolTip(c));
|
||||
comp = p;
|
||||
}
|
||||
|
||||
|
||||
// Set tooltip
|
||||
this.setToolTipText(getToolTip(c));
|
||||
|
||||
|
||||
return comp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static String getToolTip(RocketComponent c) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("<html>");
|
||||
|
||||
|
||||
sb.append("<b>").append(c.getName()).append("</b>");
|
||||
if (c.isMassive() || c.isMassOverridden() ) {
|
||||
sb.append(" (").append(UnitGroup.UNITS_MASS.toStringUnit(c.getMass()));
|
||||
if(c.getChildCount()>0){
|
||||
sb.append(" of ").append(UnitGroup.UNITS_MASS.toStringUnit(c.getSectionMass())).append( " total");
|
||||
if (c.isMassive() || c.isMassOverridden()) {
|
||||
sb.append(" (").append(
|
||||
UnitGroup.UNITS_MASS.toStringUnit(c.getMass()));
|
||||
if (c.getChildCount() > 0) {
|
||||
sb.append(" of ")
|
||||
.append(UnitGroup.UNITS_MASS.toStringUnit(c
|
||||
.getSectionMass())).append(" total");
|
||||
}
|
||||
sb.append(")");
|
||||
} else {
|
||||
if((c.getChildCount()>0) && (c.getSectionMass()>0)){
|
||||
sb.append(" (").append(UnitGroup.UNITS_MASS.toStringUnit(c.getSectionMass())).append( " total)");
|
||||
if ((c.getChildCount() > 0) && (c.getSectionMass() > 0)) {
|
||||
sb.append(" (")
|
||||
.append(UnitGroup.UNITS_MASS.toStringUnit(c
|
||||
.getSectionMass())).append(" total)");
|
||||
}
|
||||
}
|
||||
|
||||
if ( c.isMassOverridden() ) {
|
||||
|
||||
if (c.isMassOverridden()) {
|
||||
sb.append(" ").append(trans.get("ComponentTree.ttip.massoverride"));
|
||||
}
|
||||
|
||||
if ( c.isCGOverridden() ) {
|
||||
|
||||
if (c.isCGOverridden()) {
|
||||
sb.append(" ").append(trans.get("ComponentTree.ttip.cgoverride"));
|
||||
}
|
||||
|
||||
|
||||
String comment = c.getComment().trim();
|
||||
if (comment.length() > 0) {
|
||||
comment = TextUtil.escapeXML(comment);
|
||||
comment = comment.replace("\n", "<br>");
|
||||
sb.append("<br>").append(comment);
|
||||
}
|
||||
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|