[#2338] Use searchable and categorizable combobox for flight data type

This commit is contained in:
SiboVG 2023-11-24 20:47:05 +01:00
parent 764ebac7b0
commit 341ab81b79
6 changed files with 569 additions and 133 deletions

View File

@ -811,6 +811,9 @@ simplotpanel.MarkerStyle.btn.VerticalMarker = Vertical line
simplotpanel.MarkerStyle.btn.Icon = Icon
simplotpanel.MarkerStyle.OnlyInTime = Only available for time domain, other domains only support icon markers
! FlightDataComboBox
FlightDataComboBox.placeholder = Enter the data type
! Component add buttons
compaddbuttons.AxialStage = Stage
compaddbuttons.Bodycompandfinsets = Body Components and Fin Sets
@ -2062,6 +2065,20 @@ FlightDataType.TYPE_LONGITUDE = Longitude
FlightDataType.TYPE_CORIOLIS_ACCELERATION = Coriolis acceleration
FlightDataType.TYPE_GRAVITY = Gravitational acceleration
! FlightDataTypeGroup
FlightDataTypeGroup.GROUP_TIME = Time
FlightDataTypeGroup.GROUP_POSITION_AND_MOTION = Position and Motion
FlightDataTypeGroup.GROUP_ORIENTATION = Orientation
FlightDataTypeGroup.GROUP_MASS_AND_INERTIA = Mass and Inertia
FlightDataTypeGroup.GROUP_STABILITY = Stability
FlightDataTypeGroup.GROUP_THRUST_AND_DRAG = Thrust and Drag
FlightDataTypeGroup.GROUP_COEFFICIENTS = Coefficients
FlightDataTypeGroup.GROUP_ATMOSPHERIC_CONDITIONS = Atmospheric Conditions
FlightDataTypeGroup.GROUP_CHARACTERISTIC_NUMBERS = Characteristic Numbers
FlightDataTypeGroup.GROUP_REFERENCE_VALUES = Reference Values
FlightDataTypeGroup.GROUP_SIMULATION_INFORMATION = Simulation Information
FlightDataTypeGroup.GROUP_CUSTOM = Custom
! PlotConfiguration
PlotConfiguration.Verticalmotion = Vertical motion vs. time
PlotConfiguration.Totalmotion = Total motion vs. time

View File

@ -38,23 +38,21 @@ public class FlightDataType implements Comparable<FlightDataType> {
//// Time
public static final FlightDataType TYPE_TIME = newType(trans.get("FlightDataType.TYPE_TIME"), "t", UnitGroup.UNITS_FLIGHT_TIME, 1);
public static final FlightDataType TYPE_TIME = newType(trans.get("FlightDataType.TYPE_TIME"), "t", UnitGroup.UNITS_FLIGHT_TIME,
FlightDataTypeGroup.TIME, 0);
//// Vertical position and motion
//// Position and motion
//// Altitude
public static final FlightDataType TYPE_ALTITUDE = newType(trans.get("FlightDataType.TYPE_ALTITUDE"), "h", UnitGroup.UNITS_DISTANCE,
FlightDataTypeGroup.POSITION_AND_MOTION, 0);
//// Vertical velocity
public static final FlightDataType TYPE_VELOCITY_Z = newType(trans.get("FlightDataType.TYPE_VELOCITY_Z"), "Vz", UnitGroup.UNITS_VELOCITY,
FlightDataTypeGroup.POSITION_AND_MOTION, 1);
//// Vertical acceleration
public static final FlightDataType TYPE_ACCELERATION_Z = newType(trans.get("FlightDataType.TYPE_ACCELERATION_Z"), "Az", UnitGroup.UNITS_ACCELERATION,
FlightDataTypeGroup.POSITION_AND_MOTION, 2);
//// Total motion
//// Total velocity
public static final FlightDataType TYPE_VELOCITY_TOTAL = newType(trans.get("FlightDataType.TYPE_VELOCITY_TOTAL"), "Vt", UnitGroup.UNITS_VELOCITY,
FlightDataTypeGroup.POSITION_AND_MOTION, 2);
//// Vertical acceleration
public static final FlightDataType TYPE_ACCELERATION_Z = newType(trans.get("FlightDataType.TYPE_ACCELERATION_Z"), "Az", UnitGroup.UNITS_ACCELERATION,
FlightDataTypeGroup.POSITION_AND_MOTION, 3);
//// Total acceleration
public static final FlightDataType TYPE_ACCELERATION_TOTAL = newType(trans.get("FlightDataType.TYPE_ACCELERATION_TOTAL"), "At", UnitGroup.UNITS_ACCELERATION,
@ -64,143 +62,179 @@ public class FlightDataType implements Comparable<FlightDataType> {
//// Lateral position and motion
//// Position East of launch
public static final FlightDataType TYPE_POSITION_X = newType(trans.get("FlightDataType.TYPE_POSITION_X"), "Px", UnitGroup.UNITS_DISTANCE,
FlightDataTypeGroup.POSITION_AND_MOTION, 5);
FlightDataTypeGroup.POSITION_AND_MOTION, 0);
//// Position North of launch
public static final FlightDataType TYPE_POSITION_Y = newType(trans.get("FlightDataType.TYPE_POSITION_Y"), "Py", UnitGroup.UNITS_DISTANCE,
FlightDataTypeGroup.POSITION_AND_MOTION, 6);
FlightDataTypeGroup.POSITION_AND_MOTION, 1);
//// Lateral distance
public static final FlightDataType TYPE_POSITION_XY = newType(trans.get("FlightDataType.TYPE_POSITION_XY"), "Pl", UnitGroup.UNITS_DISTANCE,
FlightDataTypeGroup.POSITION_AND_MOTION, 7);
FlightDataTypeGroup.POSITION_AND_MOTION, 2);
//// Lateral direction
public static final FlightDataType TYPE_POSITION_DIRECTION = newType(trans.get("FlightDataType.TYPE_POSITION_DIRECTION"), "\u03b8l", UnitGroup.UNITS_ANGLE,
FlightDataTypeGroup.POSITION_AND_MOTION, 8);
FlightDataTypeGroup.POSITION_AND_MOTION, 3);
//// Lateral velocity
public static final FlightDataType TYPE_VELOCITY_XY = newType(trans.get("FlightDataType.TYPE_VELOCITY_XY"), "Vl", UnitGroup.UNITS_VELOCITY,
FlightDataTypeGroup.POSITION_AND_MOTION, 9);
FlightDataTypeGroup.POSITION_AND_MOTION, 4);
//// Lateral acceleration
public static final FlightDataType TYPE_ACCELERATION_XY = newType(trans.get("FlightDataType.TYPE_ACCELERATION_XY"), "Al", UnitGroup.UNITS_ACCELERATION,
FlightDataTypeGroup.POSITION_AND_MOTION, 10);
FlightDataTypeGroup.POSITION_AND_MOTION, 5);
//// Latitude
public static final FlightDataType TYPE_LATITUDE = newType(trans.get("FlightDataType.TYPE_LATITUDE"), "\u03c6", UnitGroup.UNITS_ANGLE,
FlightDataTypeGroup.POSITION_AND_MOTION, 11);
FlightDataTypeGroup.POSITION_AND_MOTION, 6);
//// Longitude
public static final FlightDataType TYPE_LONGITUDE = newType(trans.get("FlightDataType.TYPE_LONGITUDE"), "\u03bb", UnitGroup.UNITS_ANGLE,
FlightDataTypeGroup.POSITION_AND_MOTION, 12);
//// Gravity
public static final FlightDataType TYPE_GRAVITY = newType(trans.get("FlightDataType.TYPE_GRAVITY"), "g", UnitGroup.UNITS_ACCELERATION, 38);
//// Angular motion
FlightDataTypeGroup.POSITION_AND_MOTION, 7);
// Orientation
//// Angle of attack
public static final FlightDataType TYPE_AOA = newType(trans.get("FlightDataType.TYPE_AOA"), "\u03b1", UnitGroup.UNITS_ANGLE, 40);
public static final FlightDataType TYPE_AOA = newType(trans.get("FlightDataType.TYPE_AOA"), "\u03b1", UnitGroup.UNITS_ANGLE,
FlightDataTypeGroup.ORIENTATION, 0);
//// Roll rate
public static final FlightDataType TYPE_ROLL_RATE = newType(trans.get("FlightDataType.TYPE_ROLL_RATE"), "d\u03a6", UnitGroup.UNITS_ROLL, 41);
public static final FlightDataType TYPE_ROLL_RATE = newType(trans.get("FlightDataType.TYPE_ROLL_RATE"), "d\u03a6", UnitGroup.UNITS_ROLL,
FlightDataTypeGroup.ORIENTATION, 1);
//// Pitch rate
public static final FlightDataType TYPE_PITCH_RATE = newType(trans.get("FlightDataType.TYPE_PITCH_RATE"), "d\u03b8", UnitGroup.UNITS_ROLL, 42);
public static final FlightDataType TYPE_PITCH_RATE = newType(trans.get("FlightDataType.TYPE_PITCH_RATE"), "d\u03b8", UnitGroup.UNITS_ROLL,
FlightDataTypeGroup.ORIENTATION, 2);
//// Yaw rate
public static final FlightDataType TYPE_YAW_RATE = newType(trans.get("FlightDataType.TYPE_YAW_RATE"), "d\u03a8", UnitGroup.UNITS_ROLL, 43);
public static final FlightDataType TYPE_YAW_RATE = newType(trans.get("FlightDataType.TYPE_YAW_RATE"), "d\u03a8", UnitGroup.UNITS_ROLL,
FlightDataTypeGroup.ORIENTATION, 3);
//// Vertical orientation (zenith)
public static final FlightDataType TYPE_ORIENTATION_THETA = newType(trans.get("FlightDataType.TYPE_ORIENTATION_THETA"), "\u0398", UnitGroup.UNITS_ANGLE,
FlightDataTypeGroup.ORIENTATION, 4);
//// Lateral orientation (azimuth)
public static final FlightDataType TYPE_ORIENTATION_PHI = newType(trans.get("FlightDataType.TYPE_ORIENTATION_PHI"), "\u03a6", UnitGroup.UNITS_ANGLE,
FlightDataTypeGroup.ORIENTATION, 5);
//// Stability information
// Mass and inertia
//// Mass
public static final FlightDataType TYPE_MASS = newType(trans.get("FlightDataType.TYPE_MASS"), "m", UnitGroup.UNITS_MASS, 50);
public static final FlightDataType TYPE_MASS = newType(trans.get("FlightDataType.TYPE_MASS"), "m", UnitGroup.UNITS_MASS,
FlightDataTypeGroup.MASS_AND_INERTIA, 0);
//// Motor mass
public static final FlightDataType TYPE_MOTOR_MASS = newType(trans.get("FlightDataType.TYPE_MOTOR_MASS"), "mp", UnitGroup.UNITS_MASS, 51);
public static final FlightDataType TYPE_MOTOR_MASS = newType(trans.get("FlightDataType.TYPE_MOTOR_MASS"), "mp", UnitGroup.UNITS_MASS,
FlightDataTypeGroup.MASS_AND_INERTIA, 1);
//// Longitudinal moment of inertia
public static final FlightDataType TYPE_LONGITUDINAL_INERTIA = newType(trans.get("FlightDataType.TYPE_LONGITUDINAL_INERTIA"), "Il", UnitGroup.UNITS_INERTIA, 52);
public static final FlightDataType TYPE_LONGITUDINAL_INERTIA = newType(trans.get("FlightDataType.TYPE_LONGITUDINAL_INERTIA"), "Il", UnitGroup.UNITS_INERTIA,
FlightDataTypeGroup.MASS_AND_INERTIA, 2);
//// Rotational moment of inertia
public static final FlightDataType TYPE_ROTATIONAL_INERTIA = newType(trans.get("FlightDataType.TYPE_ROTATIONAL_INERTIA"), "Ir", UnitGroup.UNITS_INERTIA, 53);
public static final FlightDataType TYPE_ROTATIONAL_INERTIA = newType(trans.get("FlightDataType.TYPE_ROTATIONAL_INERTIA"), "Ir", UnitGroup.UNITS_INERTIA,
FlightDataTypeGroup.MASS_AND_INERTIA, 3);
//// Gravity
public static final FlightDataType TYPE_GRAVITY = newType(trans.get("FlightDataType.TYPE_GRAVITY"), "g", UnitGroup.UNITS_ACCELERATION,
FlightDataTypeGroup.MASS_AND_INERTIA, 4);
// Stability
//// CP location
public static final FlightDataType TYPE_CP_LOCATION = newType(trans.get("FlightDataType.TYPE_CP_LOCATION"), "Cp", UnitGroup.UNITS_LENGTH, 54);
public static final FlightDataType TYPE_CP_LOCATION = newType(trans.get("FlightDataType.TYPE_CP_LOCATION"), "Cp", UnitGroup.UNITS_LENGTH,
FlightDataTypeGroup.STABILITY, 0);
//// CG location
public static final FlightDataType TYPE_CG_LOCATION = newType(trans.get("FlightDataType.TYPE_CG_LOCATION"), "Cg", UnitGroup.UNITS_LENGTH, 55);
public static final FlightDataType TYPE_CG_LOCATION = newType(trans.get("FlightDataType.TYPE_CG_LOCATION"), "Cg", UnitGroup.UNITS_LENGTH,
FlightDataTypeGroup.STABILITY, 1);
//// Stability margin calibers
public static final FlightDataType TYPE_STABILITY = newType(trans.get("FlightDataType.TYPE_STABILITY"), "S", UnitGroup.UNITS_COEFFICIENT, 56);
public static final FlightDataType TYPE_STABILITY = newType(trans.get("FlightDataType.TYPE_STABILITY"), "S", UnitGroup.UNITS_COEFFICIENT,
FlightDataTypeGroup.STABILITY, 2);
//// Characteristic numbers
// Characteristic numbers
//// Mach number
public static final FlightDataType TYPE_MACH_NUMBER = newType(trans.get("FlightDataType.TYPE_MACH_NUMBER"), "M", UnitGroup.UNITS_COEFFICIENT, 60);
public static final FlightDataType TYPE_MACH_NUMBER = newType(trans.get("FlightDataType.TYPE_MACH_NUMBER"), "M", UnitGroup.UNITS_COEFFICIENT,
FlightDataTypeGroup.CHARACTERISTIC_NUMBERS, 0);
//// Reynolds number
public static final FlightDataType TYPE_REYNOLDS_NUMBER = newType(trans.get("FlightDataType.TYPE_REYNOLDS_NUMBER"), "R", UnitGroup.UNITS_COEFFICIENT, 61);
public static final FlightDataType TYPE_REYNOLDS_NUMBER = newType(trans.get("FlightDataType.TYPE_REYNOLDS_NUMBER"), "R", UnitGroup.UNITS_COEFFICIENT,
FlightDataTypeGroup.CHARACTERISTIC_NUMBERS, 1);
//// Thrust and drag
// Thrust and drag
//// Thrust
public static final FlightDataType TYPE_THRUST_FORCE = newType(trans.get("FlightDataType.TYPE_THRUST_FORCE"), "Ft", UnitGroup.UNITS_FORCE, 70);
public static final FlightDataType TYPE_THRUST_FORCE = newType(trans.get("FlightDataType.TYPE_THRUST_FORCE"), "Ft", UnitGroup.UNITS_FORCE,
FlightDataTypeGroup.THRUST_AND_DRAG, 0);
//// Thrust-to-weight ratio
public static final FlightDataType TYPE_THRUST_WEIGHT_RATIO = newType(trans.get("FlightDataType.TYPE_THRUST_WEIGHT_RATIO"), "Twr", UnitGroup.UNITS_COEFFICIENT, 71);
public static final FlightDataType TYPE_THRUST_WEIGHT_RATIO = newType(trans.get("FlightDataType.TYPE_THRUST_WEIGHT_RATIO"), "Twr", UnitGroup.UNITS_COEFFICIENT,
FlightDataTypeGroup.THRUST_AND_DRAG, 1);
//// Drag force
public static final FlightDataType TYPE_DRAG_FORCE = newType(trans.get("FlightDataType.TYPE_DRAG_FORCE"), "Fd", UnitGroup.UNITS_FORCE, 72);
public static final FlightDataType TYPE_DRAG_FORCE = newType(trans.get("FlightDataType.TYPE_DRAG_FORCE"), "Fd", UnitGroup.UNITS_FORCE,
FlightDataTypeGroup.THRUST_AND_DRAG, 2);
//// Drag coefficient
public static final FlightDataType TYPE_DRAG_COEFF = newType(trans.get("FlightDataType.TYPE_DRAG_COEFF"), "Cd", UnitGroup.UNITS_COEFFICIENT, 73);
//// Axial drag coefficient
public static final FlightDataType TYPE_AXIAL_DRAG_COEFF = newType(trans.get("FlightDataType.TYPE_AXIAL_DRAG_COEFF"), "Cda", UnitGroup.UNITS_COEFFICIENT, 74);
//// Component drag coefficients
public static final FlightDataType TYPE_DRAG_COEFF = newType(trans.get("FlightDataType.TYPE_DRAG_COEFF"), "Cd", UnitGroup.UNITS_COEFFICIENT,
FlightDataTypeGroup.THRUST_AND_DRAG, 3);
//// Friction drag coefficient
public static final FlightDataType TYPE_FRICTION_DRAG_COEFF = newType(trans.get("FlightDataType.TYPE_FRICTION_DRAG_COEFF"), "Cdf", UnitGroup.UNITS_COEFFICIENT, 80);
public static final FlightDataType TYPE_FRICTION_DRAG_COEFF = newType(trans.get("FlightDataType.TYPE_FRICTION_DRAG_COEFF"), "Cdf", UnitGroup.UNITS_COEFFICIENT,
FlightDataTypeGroup.THRUST_AND_DRAG, 4);
//// Pressure drag coefficient
public static final FlightDataType TYPE_PRESSURE_DRAG_COEFF = newType(trans.get("FlightDataType.TYPE_PRESSURE_DRAG_COEFF"), "Cdp", UnitGroup.UNITS_COEFFICIENT, 81);
public static final FlightDataType TYPE_PRESSURE_DRAG_COEFF = newType(trans.get("FlightDataType.TYPE_PRESSURE_DRAG_COEFF"), "Cdp", UnitGroup.UNITS_COEFFICIENT,
FlightDataTypeGroup.THRUST_AND_DRAG, 5);
//// Base drag coefficient
public static final FlightDataType TYPE_BASE_DRAG_COEFF = newType(trans.get("FlightDataType.TYPE_BASE_DRAG_COEFF"), "Cdb", UnitGroup.UNITS_COEFFICIENT, 82);
public static final FlightDataType TYPE_BASE_DRAG_COEFF = newType(trans.get("FlightDataType.TYPE_BASE_DRAG_COEFF"), "Cdb", UnitGroup.UNITS_COEFFICIENT,
FlightDataTypeGroup.THRUST_AND_DRAG, 6);
//// Axial drag coefficient
public static final FlightDataType TYPE_AXIAL_DRAG_COEFF = newType(trans.get("FlightDataType.TYPE_AXIAL_DRAG_COEFF"), "Cda", UnitGroup.UNITS_COEFFICIENT,
FlightDataTypeGroup.THRUST_AND_DRAG, 7);
//// Other coefficients
// Coefficients
//// Normal force coefficient
public static final FlightDataType TYPE_NORMAL_FORCE_COEFF = newType(trans.get("FlightDataType.TYPE_NORMAL_FORCE_COEFF"), "Cn", UnitGroup.UNITS_COEFFICIENT, 90);
public static final FlightDataType TYPE_NORMAL_FORCE_COEFF = newType(trans.get("FlightDataType.TYPE_NORMAL_FORCE_COEFF"), "Cn", UnitGroup.UNITS_COEFFICIENT,
FlightDataTypeGroup.COEFFICIENTS, 0);
//// Pitch moment coefficient
public static final FlightDataType TYPE_PITCH_MOMENT_COEFF = newType(trans.get("FlightDataType.TYPE_PITCH_MOMENT_COEFF"), "C\u03b8", UnitGroup.UNITS_COEFFICIENT, 91);
public static final FlightDataType TYPE_PITCH_MOMENT_COEFF = newType(trans.get("FlightDataType.TYPE_PITCH_MOMENT_COEFF"), "C\u03b8", UnitGroup.UNITS_COEFFICIENT,
FlightDataTypeGroup.COEFFICIENTS, 1);
//// Yaw moment coefficient
public static final FlightDataType TYPE_YAW_MOMENT_COEFF = newType(trans.get("FlightDataType.TYPE_YAW_MOMENT_COEFF"), "C\u03c4\u03a8", UnitGroup.UNITS_COEFFICIENT, 92);
public static final FlightDataType TYPE_YAW_MOMENT_COEFF = newType(trans.get("FlightDataType.TYPE_YAW_MOMENT_COEFF"), "C\u03c4\u03a8", UnitGroup.UNITS_COEFFICIENT,
FlightDataTypeGroup.COEFFICIENTS, 2);
//// Side force coefficient
public static final FlightDataType TYPE_SIDE_FORCE_COEFF = newType(trans.get("FlightDataType.TYPE_SIDE_FORCE_COEFF"), "C\u03c4s", UnitGroup.UNITS_COEFFICIENT, 93);
public static final FlightDataType TYPE_SIDE_FORCE_COEFF = newType(trans.get("FlightDataType.TYPE_SIDE_FORCE_COEFF"), "C\u03c4s", UnitGroup.UNITS_COEFFICIENT,
FlightDataTypeGroup.COEFFICIENTS, 3);
//// Roll moment coefficient
public static final FlightDataType TYPE_ROLL_MOMENT_COEFF = newType(trans.get("FlightDataType.TYPE_ROLL_MOMENT_COEFF"), "C\u03c4\u03a6", UnitGroup.UNITS_COEFFICIENT, 94);
public static final FlightDataType TYPE_ROLL_MOMENT_COEFF = newType(trans.get("FlightDataType.TYPE_ROLL_MOMENT_COEFF"), "C\u03c4\u03a6", UnitGroup.UNITS_COEFFICIENT,
FlightDataTypeGroup.COEFFICIENTS, 4);
//// Roll forcing coefficient
public static final FlightDataType TYPE_ROLL_FORCING_COEFF = newType(trans.get("FlightDataType.TYPE_ROLL_FORCING_COEFF"), "Cf\u03a6", UnitGroup.UNITS_COEFFICIENT, 95);
public static final FlightDataType TYPE_ROLL_FORCING_COEFF = newType(trans.get("FlightDataType.TYPE_ROLL_FORCING_COEFF"), "Cf\u03a6", UnitGroup.UNITS_COEFFICIENT,
FlightDataTypeGroup.COEFFICIENTS, 5);
//// Roll damping coefficient
public static final FlightDataType TYPE_ROLL_DAMPING_COEFF = newType(trans.get("FlightDataType.TYPE_ROLL_DAMPING_COEFF"), "C\u03b6\u03a6", UnitGroup.UNITS_COEFFICIENT, 96);
public static final FlightDataType TYPE_ROLL_DAMPING_COEFF = newType(trans.get("FlightDataType.TYPE_ROLL_DAMPING_COEFF"), "C\u03b6\u03a6", UnitGroup.UNITS_COEFFICIENT,
FlightDataTypeGroup.COEFFICIENTS, 6);
//// Pitch damping coefficient
public static final FlightDataType TYPE_PITCH_DAMPING_MOMENT_COEFF = newType(trans.get("FlightDataType.TYPE_PITCH_DAMPING_MOMENT_COEFF"), "C\u03b6\u03b8", UnitGroup.UNITS_COEFFICIENT, 97);
public static final FlightDataType TYPE_PITCH_DAMPING_MOMENT_COEFF = newType(trans.get("FlightDataType.TYPE_PITCH_DAMPING_MOMENT_COEFF"), "C\u03b6\u03b8", UnitGroup.UNITS_COEFFICIENT,
FlightDataTypeGroup.COEFFICIENTS, 7);
//// Yaw damping coefficient
public static final FlightDataType TYPE_YAW_DAMPING_MOMENT_COEFF = newType(trans.get("FlightDataType.TYPE_YAW_DAMPING_MOMENT_COEFF"), "C\u03b6\u03a8", UnitGroup.UNITS_COEFFICIENT, 98);
public static final FlightDataType TYPE_YAW_DAMPING_MOMENT_COEFF = newType(trans.get("FlightDataType.TYPE_YAW_DAMPING_MOMENT_COEFF"), "C\u03b6\u03a8", UnitGroup.UNITS_COEFFICIENT,
FlightDataTypeGroup.COEFFICIENTS, 8);
//// Coriolis acceleration
public static final FlightDataType TYPE_CORIOLIS_ACCELERATION = newType(trans.get("FlightDataType.TYPE_CORIOLIS_ACCELERATION"), "Ac", UnitGroup.UNITS_ACCELERATION, 99);
//// Reference length + area
// Reference values
//// Reference length
public static final FlightDataType TYPE_REFERENCE_LENGTH = newType(trans.get("FlightDataType.TYPE_REFERENCE_LENGTH"), "Lr", UnitGroup.UNITS_LENGTH, 100);
public static final FlightDataType TYPE_REFERENCE_LENGTH = newType(trans.get("FlightDataType.TYPE_REFERENCE_LENGTH"), "Lr", UnitGroup.UNITS_LENGTH,
FlightDataTypeGroup.REFERENCE_VALUES, 0);
//// Reference area
public static final FlightDataType TYPE_REFERENCE_AREA = newType(trans.get("FlightDataType.TYPE_REFERENCE_AREA"), "Ar", UnitGroup.UNITS_AREA, 101);
public static final FlightDataType TYPE_REFERENCE_AREA = newType(trans.get("FlightDataType.TYPE_REFERENCE_AREA"), "Ar", UnitGroup.UNITS_AREA,
FlightDataTypeGroup.REFERENCE_VALUES, 1);
//// Orientation
//// Vertical orientation (zenith)
public static final FlightDataType TYPE_ORIENTATION_THETA = newType(trans.get("FlightDataType.TYPE_ORIENTATION_THETA"), "\u0398", UnitGroup.UNITS_ANGLE, 106);
//// Lateral orientation (azimuth)
public static final FlightDataType TYPE_ORIENTATION_PHI = newType(trans.get("FlightDataType.TYPE_ORIENTATION_PHI"), "\u03a6", UnitGroup.UNITS_ANGLE, 107);
//// Atmospheric conditions
// Atmospheric conditions
//// Wind velocity
public static final FlightDataType TYPE_WIND_VELOCITY = newType(trans.get("FlightDataType.TYPE_WIND_VELOCITY"), "Vw", UnitGroup.UNITS_VELOCITY, 110);
public static final FlightDataType TYPE_WIND_VELOCITY = newType(trans.get("FlightDataType.TYPE_WIND_VELOCITY"), "Vw", UnitGroup.UNITS_VELOCITY,
FlightDataTypeGroup.ATMOSPHERIC_CONDITIONS, 0);
//// Air temperature
public static final FlightDataType TYPE_AIR_TEMPERATURE = newType(trans.get("FlightDataType.TYPE_AIR_TEMPERATURE"), "T", UnitGroup.UNITS_TEMPERATURE, 111);
public static final FlightDataType TYPE_AIR_TEMPERATURE = newType(trans.get("FlightDataType.TYPE_AIR_TEMPERATURE"), "T", UnitGroup.UNITS_TEMPERATURE,
FlightDataTypeGroup.ATMOSPHERIC_CONDITIONS, 1);
//// Air pressure
public static final FlightDataType TYPE_AIR_PRESSURE = newType(trans.get("FlightDataType.TYPE_AIR_PRESSURE"), "P", UnitGroup.UNITS_PRESSURE, 112);
public static final FlightDataType TYPE_AIR_PRESSURE = newType(trans.get("FlightDataType.TYPE_AIR_PRESSURE"), "P", UnitGroup.UNITS_PRESSURE,
FlightDataTypeGroup.ATMOSPHERIC_CONDITIONS, 2);
//// Speed of sound
public static final FlightDataType TYPE_SPEED_OF_SOUND = newType(trans.get("FlightDataType.TYPE_SPEED_OF_SOUND"), "Vs", UnitGroup.UNITS_VELOCITY, 113);
public static final FlightDataType TYPE_SPEED_OF_SOUND = newType(trans.get("FlightDataType.TYPE_SPEED_OF_SOUND"), "Vs", UnitGroup.UNITS_VELOCITY,
FlightDataTypeGroup.ATMOSPHERIC_CONDITIONS, 3);
//// Simulation information
// Simulation information
//// Simulation time step
public static final FlightDataType TYPE_TIME_STEP = newType(trans.get("FlightDataType.TYPE_TIME_STEP"), "dt", UnitGroup.UNITS_TIME_STEP, 200);
public static final FlightDataType TYPE_TIME_STEP = newType(trans.get("FlightDataType.TYPE_TIME_STEP"), "dt", UnitGroup.UNITS_TIME_STEP,
FlightDataTypeGroup.SIMULATION_INFORMATION, 0);
//// Computation time
public static final FlightDataType TYPE_COMPUTATION_TIME = newType(trans.get("FlightDataType.TYPE_COMPUTATION_TIME"), "tc", UnitGroup.UNITS_SHORT_TIME, 201);
public static final FlightDataType TYPE_COMPUTATION_TIME = newType(trans.get("FlightDataType.TYPE_COMPUTATION_TIME"), "tc", UnitGroup.UNITS_SHORT_TIME,
FlightDataTypeGroup.SIMULATION_INFORMATION, 1);
// An array of all the built in types
public static final FlightDataType[] ALL_TYPES = {

View File

@ -6,14 +6,34 @@ import net.sf.openrocket.startup.Application;
public class FlightDataTypeGroup {
private static final Translator trans = Application.getTranslator();
public static final FlightDataTypeGroup POSITION_AND_MOTION = new FlightDataTypeGroup("Position and motion", 0);
public static final FlightDataTypeGroup TIME = new FlightDataTypeGroup(trans.get("FlightDataTypeGroup.GROUP_TIME"), 0);
public static final FlightDataTypeGroup POSITION_AND_MOTION = new FlightDataTypeGroup(trans.get("FlightDataTypeGroup.GROUP_POSITION_AND_MOTION"), 10);
public static final FlightDataTypeGroup ORIENTATION = new FlightDataTypeGroup(trans.get("FlightDataTypeGroup.GROUP_ORIENTATION"), 20);
public static final FlightDataTypeGroup MASS_AND_INERTIA = new FlightDataTypeGroup(trans.get("FlightDataTypeGroup.GROUP_MASS_AND_INERTIA"), 30);
public static final FlightDataTypeGroup STABILITY = new FlightDataTypeGroup(trans.get("FlightDataTypeGroup.GROUP_STABILITY"), 40);
public static final FlightDataTypeGroup THRUST_AND_DRAG = new FlightDataTypeGroup(trans.get("FlightDataTypeGroup.GROUP_THRUST_AND_DRAG"), 50);
public static final FlightDataTypeGroup COEFFICIENTS = new FlightDataTypeGroup(trans.get("FlightDataTypeGroup.GROUP_COEFFICIENTS"), 60);
public static final FlightDataTypeGroup ATMOSPHERIC_CONDITIONS = new FlightDataTypeGroup(trans.get("FlightDataTypeGroup.GROUP_ATMOSPHERIC_CONDITIONS"), 70);
public static final FlightDataTypeGroup CHARACTERISTIC_NUMBERS = new FlightDataTypeGroup(trans.get("FlightDataTypeGroup.GROUP_CHARACTERISTIC_NUMBERS"), 80);
public static final FlightDataTypeGroup REFERENCE_VALUES = new FlightDataTypeGroup(trans.get("FlightDataTypeGroup.GROUP_REFERENCE_VALUES"), 90);
public static final FlightDataTypeGroup SIMULATION_INFORMATION = new FlightDataTypeGroup(trans.get("FlightDataTypeGroup.GROUP_SIMULATION_INFORMATION"), 100);
public static final FlightDataTypeGroup CUSTOM = new FlightDataTypeGroup("Custom", 100);
public static final FlightDataTypeGroup CUSTOM = new FlightDataTypeGroup(trans.get("FlightDataTypeGroup.GROUP_CUSTOM"), 200);
// An array of all the built-in groups
public static final FlightDataTypeGroup[] ALL_GROUPS = {
POSITION_AND_MOTION,
CUSTOM
TIME,
POSITION_AND_MOTION,
ORIENTATION,
MASS_AND_INERTIA,
STABILITY,
THRUST_AND_DRAG,
COEFFICIENTS,
ATMOSPHERIC_CONDITIONS,
CHARACTERISTIC_NUMBERS,
REFERENCE_VALUES,
SIMULATION_INFORMATION,
CUSTOM
};
private final String name;

View File

@ -1,14 +1,33 @@
package net.sf.openrocket.gui.simulation;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.gui.util.UITheme;
import net.sf.openrocket.gui.widgets.PlaceholderTextField;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.simulation.FlightDataType;
import net.sf.openrocket.simulation.FlightDataTypeGroup;
import net.sf.openrocket.startup.Application;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.plaf.basic.BasicArrowButton;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
@ -16,49 +35,268 @@ import java.util.ArrayList;
import java.util.Hashtable;
public class FlightDataComboBox extends JComboBox<FlightDataType> {
private final JPopupMenu mainMenu;
private final Hashtable<FlightDataTypeGroup, FlightDataType[]> subItems = new Hashtable<>();
private static final Translator trans = Application.getTranslator();
public FlightDataComboBox(FlightDataType[] types) {
private final JPopupMenu categoryPopup;
private final JPopupMenu searchPopup;
private final PlaceholderTextField searchFieldCategory;
private final PlaceholderTextField searchFieldSearch;
private final JList<FlightDataType> filteredList;
private final FlightDataType[] allTypes;
private final Hashtable<FlightDataTypeGroup, FlightDataType[]> typeGroupMap;
private int highlightedListIdx = -1;
private static Color textSelectionBackground;
static {
initColors();
}
public FlightDataComboBox(FlightDataTypeGroup[] allGroups, FlightDataType[] types) {
super(types);
setEditable(false);
for (FlightDataTypeGroup group : FlightDataTypeGroup.ALL_GROUPS) {
ArrayList<FlightDataType> listForGroup = new ArrayList<>();
for (FlightDataType type : types) {
if (type.getGroup().equals(group)) {
listForGroup.add(type);
}
}
subItems.put(group, listForGroup.toArray(new FlightDataType[0]));
}
this.allTypes = types;
mainMenu = createMainMenu();
initColors();
// Create the map of flight data group and corresponding flight data types
typeGroupMap = createFlightDataGroupMap(allGroups, types);
// Create the search field widget
searchFieldCategory = new PlaceholderTextField();
searchFieldCategory.setPlaceholder(trans.get("FlightDataComboBox.placeholder"));
searchFieldSearch = new PlaceholderTextField();
// Create the filtered list
filteredList = createFilteredList();
// Create the different popups
categoryPopup = createCategoryPopup();
searchPopup = createSearchPopup();
searchPopup.setPreferredSize(categoryPopup.getPreferredSize());
// Add key listener for the search fields
searchFieldCategory.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
overrideActionKeys(e);
}
public void keyTyped(KeyEvent e) {
EventQueue.invokeLater(() -> {
String text = searchFieldCategory.getText();
highlightedListIdx = 0; // Start with the first item selected
searchFieldSearch.setText(text);
if (!text.isEmpty() && !searchPopup.isVisible()) {
hideCategoryPopup();
showSearchPopup();
filter(text);
}
});
}
});
searchFieldSearch.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
overrideActionKeys(e);
}
@Override
public void keyTyped(KeyEvent e) {
EventQueue.invokeLater(() -> {
String text = searchFieldSearch.getText();
highlightedListIdx = 0; // Start with the first item selected
searchFieldCategory.setText(text);
if (text.isEmpty() && !categoryPopup.isVisible()) {
hideSearchPopup();
showCategoryPopup();
}
filter(text);
});
}
});
// Override the mouse listeners to use our custom popup
for (MouseListener mouseListener : getMouseListeners()) {
removeMouseListener(mouseListener);
}
addMouseListener(new MouseAdapter() {
addMouseListeners();
}
private static void initColors() {
updateColors();
UITheme.Theme.addUIThemeChangeListener(FlightDataComboBox::updateColors);
}
private static void updateColors() {
textSelectionBackground = GUIUtil.getUITheme().getTextSelectionBackgroundColor();
}
/**
* Create a map of flight data group and corresponding flight data types.
* @param groups the groups
* @param types the types
* @return the map linking the types to their groups
*/
private Hashtable<FlightDataTypeGroup, FlightDataType[]> createFlightDataGroupMap(FlightDataTypeGroup[] groups, FlightDataType[] types) {
Hashtable<FlightDataTypeGroup, FlightDataType[]> map = new Hashtable<>();
for (FlightDataTypeGroup group : groups) {
ArrayList<FlightDataType> listForGroup = new ArrayList<>();
for (FlightDataType type : types) {
if (type.getGroup().equals(group)) {
listForGroup.add(type);
}
}
map.put(group, listForGroup.toArray(new FlightDataType[0]));
}
return map;
}
private JPopupMenu createCategoryPopup() {
final JPopupMenu menu = new JPopupMenu();
// Add the search field at the top
menu.add(searchFieldCategory);
menu.addSeparator(); // Separator between search field and menu items
// Fill the menu with the groups
for (FlightDataTypeGroup group : typeGroupMap.keySet()) {
JMenu groupList = new JMenu(group.getName());
FlightDataType[] typesForGroup = typeGroupMap.get(group);
if (typesForGroup != null) {
for (FlightDataType type : typesForGroup) {
JMenuItem typeItem = new JMenuItem(type.getName());
typeItem.addActionListener(e -> {
setSelectedItem(type);
});
groupList.add(typeItem);
}
}
menu.add(groupList);
}
return menu;
}
private JPopupMenu createSearchPopup() {
final JPopupMenu menu = new JPopupMenu();
menu.setLayout(new BorderLayout());
// Add the search field at the top
menu.add(searchFieldSearch, BorderLayout.NORTH);
menu.addSeparator();
menu.add(new JScrollPane(filteredList));
return menu;
}
private JList<FlightDataType> createFilteredList() {
JList<FlightDataType> list = new JList<>();
list.setCellRenderer(new DefaultListCellRenderer() {
@Override
public void mouseClicked(MouseEvent e) {
showCustomPopup();
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
FlightDataType type = (FlightDataType) value;
String typeName = type.toString();
if (typeName.toLowerCase().contains(searchFieldSearch.getText().toLowerCase())) {
// Use HTML to underline matching text
typeName = typeName.replaceAll("(?i)(" + searchFieldSearch.getText() + ")", "<u>$1</u>");
label.setText("<html>" + typeName + "</html>");
}
// Set the hover color
if (highlightedListIdx == index || isSelected) {
label.setBackground(textSelectionBackground);
label.setOpaque(true);
} else {
label.setOpaque(false);
}
return label;
}
});
Component arrowButton = getArrowButton();
if (arrowButton != null) {
for (MouseListener mouseListener : arrowButton.getMouseListeners()) {
arrowButton.removeMouseListener(mouseListener);
}
arrowButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
showCustomPopup();
list.addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
Point p = new Point(e.getX(),e.getY());
int index = list.locationToIndex(p);
if (index != highlightedListIdx) {
highlightedListIdx = index;
list.repaint();
}
});
}
});
list.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
// Check if the event is in the final phase of change
if (!e.getValueIsAdjusting()) {
selectComboBoxItemFromFilteredList();
}
}
});
return list;
}
private void selectComboBoxItemFromFilteredList() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
FlightDataType selectedType = filteredList.getSelectedValue();
if (selectedType != null) {
FlightDataComboBox.this.setSelectedItem(selectedType);
// Hide the popups after selection
hideCategoryPopup();
hideSearchPopup();
}
}
});
}
private void showCategoryPopup() {
categoryPopup.show(this, 0, getHeight());
searchFieldSearch.setText("");
searchFieldCategory.setText("");
}
private void hideCategoryPopup() {
categoryPopup.setVisible(false);
}
private void showSearchPopup() {
searchPopup.show(this, 0, getHeight());
}
private void hideSearchPopup() {
searchPopup.setVisible(false);
}
private void filter(String text) {
filteredList.removeAll();
String searchText = text.toLowerCase();
DefaultListModel<FlightDataType> filteredModel = new DefaultListModel<>();
for (FlightDataType item : this.allTypes) {
if (item.toString().toLowerCase().contains(searchText)) {
filteredModel.addElement(item);
}
}
filteredList.setModel(filteredModel);
filteredList.revalidate();
filteredList.repaint();
}
private Component getArrowButton() {
@ -76,30 +314,101 @@ public class FlightDataComboBox extends JComboBox<FlightDataType> {
// Our custom popup will be shown by the MouseListener
}
private JPopupMenu createMainMenu() {
JPopupMenu menu = new JPopupMenu();
for (FlightDataTypeGroup group : FlightDataTypeGroup.ALL_GROUPS) {
JMenu groupMenu = new JMenu(group.getName());
FlightDataType[] typesForGroup = subItems.get(group);
if (typesForGroup != null) {
for (FlightDataType type : typesForGroup) {
JMenuItem typeItem = new JMenuItem(type.getName());
typeItem.addActionListener(e -> {
setSelectedItem(type);
});
groupMenu.add(typeItem);
}
}
menu.add(groupMenu);
}
return menu;
@Override
public boolean isPopupVisible() {
return categoryPopup.isVisible() || searchPopup.isVisible();
}
private void showCustomPopup() {
mainMenu.show(this, 0, getHeight());
/**
* Override the default action keys (escape, enter, arrow keys) to do our own actions.
* @param e the key event
*/
private void overrideActionKeys(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
hideCategoryPopup();
hideSearchPopup();
} else if (e.getKeyCode() == KeyEvent.VK_ENTER) {
selectHighlightedItemInFilteredList();
} else if (e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyCode() == KeyEvent.VK_RIGHT) {
highlightNextItemInFilteredList();
} else if (e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_LEFT) {
highlightPreviousItemInFilteredList();
}
}
/**
* Select the highlighted item in the filtered list and hide the popups.
*/
private void selectHighlightedItemInFilteredList() {
if (highlightedListIdx >= filteredList.getModel().getSize() || highlightedListIdx < 0 || !searchPopup.isVisible()) {
return;
}
filteredList.setSelectedIndex(highlightedListIdx);
selectComboBoxItemFromFilteredList();
}
/**
* Highlight the next item in the filtered list.
*/
private void highlightNextItemInFilteredList() {
if (highlightedListIdx + 1 >= filteredList.getModel().getSize() || !searchPopup.isVisible()) {
return;
}
highlightedListIdx++;
filteredList.ensureIndexIsVisible(highlightedListIdx);
filteredList.repaint();
}
/**
* Highlight the previous item in the filtered list.
*/
private void highlightPreviousItemInFilteredList() {
if (highlightedListIdx <= 0 || !searchPopup.isVisible()) {
return;
}
highlightedListIdx--;
filteredList.ensureIndexIsVisible(highlightedListIdx);
filteredList.repaint();
}
/**
* Add mouse listener to widgets of the combobox to open our custom popup menu.
*/
private void addMouseListeners() {
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (!isPopupVisible()) {
showCategoryPopup();
}
}
});
}
});
Component arrowButton = getArrowButton();
if (arrowButton != null) {
for (MouseListener mouseListener : arrowButton.getMouseListeners()) {
arrowButton.removeMouseListener(mouseListener);
}
arrowButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (!isPopupVisible()) {
showCategoryPopup();
}
}
});
}
});
}
}
}

View File

@ -37,6 +37,7 @@ import net.sf.openrocket.gui.util.UITheme;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.simulation.FlightDataBranch;
import net.sf.openrocket.simulation.FlightDataType;
import net.sf.openrocket.simulation.FlightDataTypeGroup;
import net.sf.openrocket.simulation.FlightEvent;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.startup.Preferences;
@ -497,7 +498,7 @@ public class SimulationPlotPanel extends JPanel {
this.index = plotIndex;
typeSelector = new FlightDataComboBox(types);
typeSelector = new FlightDataComboBox(FlightDataTypeGroup.ALL_GROUPS, types);
typeSelector.setSelectedItem(type);
typeSelector.addItemListener(new ItemListener() {
@Override

View File

@ -0,0 +1,55 @@
package net.sf.openrocket.gui.widgets;
import javax.swing.JTextField;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
/**
* A text field that can display a placeholder when empty.
*
* @author Sibo Van Gool <sibo.vangool@hotmail.com>
*/
public class PlaceholderTextField extends JTextField {
private String placeholder;
public PlaceholderTextField() { }
public PlaceholderTextField(final int pColumns) {
super(pColumns);
}
public PlaceholderTextField(final String pText) {
super(pText);
}
public PlaceholderTextField(final String pText, final int pColumns) {
super(pText, pColumns);
}
public String getPlaceholder() {
return placeholder;
}
@Override
protected void paintComponent(Graphics pG) {
super.paintComponent(pG);
if (placeholder == null || placeholder.isEmpty() || !getText().isEmpty()) {
return;
}
final Graphics2D g = (Graphics2D) pG;
g.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(getDisabledTextColor());
g.drawString(placeholder, getInsets().left, pG.getFontMetrics()
.getMaxAscent() + getInsets().top);
}
public void setPlaceholder(final String s) {
placeholder = s;
}
}