Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@
WidgetCategory_Plots,
WidgetCategory_Structure,
WidgetProperties_Actions,
WidgetProperties_AlarmLimitsFromPV,

Check warning on line 172 in app/display/model/src/main/java/org/csstudio/display/builder/model/Messages.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this field "WidgetProperties_AlarmLimitsFromPV" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.

See more on https://sonarcloud.io/project/issues?id=ControlSystemStudio_phoebus&issues=AZ1HEPL0BfEcQZ3_IDPt&open=AZ1HEPL0BfEcQZ3_IDPt&pullRequest=3760

Check warning on line 172 in app/display/model/src/main/java/org/csstudio/display/builder/model/Messages.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make WidgetProperties_AlarmLimitsFromPV a static final constant or non-public and provide accessors if needed.

See more on https://sonarcloud.io/project/issues?id=ControlSystemStudio_phoebus&issues=AZ1HEPL0BfEcQZ3_IDPh&open=AZ1HEPL0BfEcQZ3_IDPh&pullRequest=3760

Check warning on line 172 in app/display/model/src/main/java/org/csstudio/display/builder/model/Messages.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make this "public static WidgetProperties_AlarmLimitsFromPV" field final

See more on https://sonarcloud.io/project/issues?id=ControlSystemStudio_phoebus&issues=AZ1HEPL0BfEcQZ3_IDPn&open=AZ1HEPL0BfEcQZ3_IDPn&pullRequest=3760
WidgetProperties_AngleSize,
WidgetProperties_AngleStart,
WidgetProperties_ArrayIndex,
Expand Down Expand Up @@ -262,6 +263,7 @@
WidgetProperties_Locale,
WidgetProperties_LogScale,
WidgetProperties_Macros,
WidgetProperties_MajorAlarmColor,

Check warning on line 266 in app/display/model/src/main/java/org/csstudio/display/builder/model/Messages.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make WidgetProperties_MajorAlarmColor a static final constant or non-public and provide accessors if needed.

See more on https://sonarcloud.io/project/issues?id=ControlSystemStudio_phoebus&issues=AZ1HEPL0BfEcQZ3_IDPi&open=AZ1HEPL0BfEcQZ3_IDPi&pullRequest=3760
WidgetProperties_MajorTickSpace,
WidgetProperties_MajorTickStepHint,
WidgetProperties_MajorTickVisible,
Expand All @@ -271,6 +273,7 @@
WidgetProperties_MinMaxTolerance,
WidgetProperties_MinorTickSpace,
WidgetProperties_MinorTickVisible,
WidgetProperties_MinorAlarmColor,

Check warning on line 276 in app/display/model/src/main/java/org/csstudio/display/builder/model/Messages.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this field "WidgetProperties_MinorAlarmColor" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.

See more on https://sonarcloud.io/project/issues?id=ControlSystemStudio_phoebus&issues=AZ1HEPL0BfEcQZ3_IDPv&open=AZ1HEPL0BfEcQZ3_IDPv&pullRequest=3760

Check warning on line 276 in app/display/model/src/main/java/org/csstudio/display/builder/model/Messages.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make this "public static WidgetProperties_MinorAlarmColor" field final

See more on https://sonarcloud.io/project/issues?id=ControlSystemStudio_phoebus&issues=AZ1HEPL0BfEcQZ3_IDPp&open=AZ1HEPL0BfEcQZ3_IDPp&pullRequest=3760
WidgetProperties_MinuteColor,
WidgetProperties_MinuteTickMarkColor,
WidgetProperties_MinuteTickMarkVisible,
Expand Down Expand Up @@ -305,6 +308,7 @@
WidgetProperties_ScaleFactor,
WidgetProperties_ScaleFormat,
WidgetProperties_ScaleDirection,
WidgetProperties_OppositeScaleVisible,
WidgetProperties_ScaleVisible,
WidgetProperties_SecondColor,
WidgetProperties_SecondVisible,
Expand All @@ -316,10 +320,12 @@
WidgetProperties_ShowHiHi,
WidgetProperties_ShowIndex,
WidgetProperties_ShowLED,
WidgetProperties_ShowAlarmLimits,
WidgetProperties_ShowLimits,
WidgetProperties_ShowLow,
WidgetProperties_ShowLoLo,
WidgetProperties_ShowMinorTicks,
WidgetProperties_PerpendicularTickLabels,
WidgetProperties_ShowOK,
WidgetProperties_ShowScale,
WidgetProperties_ShowUnits,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
/*******************************************************************************
* Copyright (c) 2015-2025 Oak Ridge National Laboratory.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.csstudio.display.builder.model.widgets;

import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.newBooleanPropertyDescriptor;
import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.newColorPropertyDescriptor;
import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.newDoublePropertyDescriptor;
import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.newIntegerPropertyDescriptor;
import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propLimitsFromPV;
import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propMaximum;
import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propMinimum;

import java.util.List;

import org.csstudio.display.builder.model.Messages;
import org.csstudio.display.builder.model.Widget;
import org.csstudio.display.builder.model.WidgetProperty;
import org.csstudio.display.builder.model.WidgetPropertyCategory;
import org.csstudio.display.builder.model.WidgetPropertyDescriptor;
import org.phoebus.ui.color.NamedWidgetColors;
import org.phoebus.ui.color.WidgetColorService;
import org.csstudio.display.builder.model.properties.EnumWidgetProperty;
import org.phoebus.ui.color.WidgetColor;
import org.phoebus.ui.vtype.ScaleFormat;

/** Base class for PV widgets that display a numeric value on a scale
* (Tank, Thermometer, ProgressBar and similar).
*
* <p>Consolidates properties that were historically duplicated across
* individual scaled widgets: display range, limits-from-PV toggle,
* alarm-level thresholds and their colours. This follows the pattern
* established by CS-Studio BOY's {@code LinearMeterWidget} which exposed
* LOLO/LO/HI/HIHI levels with both PV-sourced and manual modes.
*
* <p>Provides:
* <ul>
* <li>{@code limits_from_pv} &mdash; whether the PV display range
* overrides the manual {@code minimum}/{@code maximum}. This is
* the existing upstream property, unchanged.</li>
* <li>{@code alarm_limits_from_pv} &mdash; whether PV alarm metadata
* overrides the manual LOLO/LO/HI/HIHI levels. New property;
* old Phoebus silently ignores the XML element.</li>
* <li>Manual {@code minimum} / {@code maximum} range.</li>
* <li>A {@code show_limits} toggle for alarm-limit visual markers.</li>
* <li>Manual LOLO / LO / HI / HIHI thresholds (NaN = inactive).</li>
* <li>Configurable minor/major alarm colours defaulting to the named
* {@code ALARM_MINOR} / {@code ALARM_MAJOR} palette entries.</li>
* </ul>
*
* <p>Backward compatibility note: every new property uses a type that
* stock Phoebus already knows (boolean, double, color). Old versions
* will silently skip the unknown XML elements; saving in old Phoebus
* will simply drop them. No ordinal-based enums are used, specifically
* to avoid the round-trip failure that {@code BooleanWidgetProperty}
* causes when it encounters an ordinal &ge; 2.
*
* @author Kay Kasemir
* @author Heredie Delvalle &mdash; CLS, alarm limits, scale refactoring
*/
@SuppressWarnings("nls")
public abstract class ScaledPVWidget extends PVWidget
{
// ---- Property descriptors -------------------------------------------

/** 'format' — scale label number format (ScaleFormat subset) */
public static final WidgetPropertyDescriptor<ScaleFormat> propScaleFormat =
new WidgetPropertyDescriptor<>(
WidgetPropertyCategory.DISPLAY, "format", Messages.WidgetProperties_Format)
{
@Override
public EnumWidgetProperty<ScaleFormat> createProperty(final Widget widget,
final ScaleFormat default_value)

Check warning on line 77 in app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/ScaledPVWidget.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.

See more on https://sonarcloud.io/project/issues?id=ControlSystemStudio_phoebus&issues=AZ1HEPKxBfEcQZ3_IDPO&open=AZ1HEPKxBfEcQZ3_IDPO&pullRequest=3760
{
return new EnumWidgetProperty<>(this, widget, default_value);
}
};

/** 'precision' — number of decimal places (0..15) */
public static final WidgetPropertyDescriptor<Integer> propScalePrecision =
newIntegerPropertyDescriptor(WidgetPropertyCategory.DISPLAY, "precision",
Messages.WidgetProperties_Precision, 0, 15);

/** 'alarm_limits_from_pv' — use PV alarm metadata for LOLO/LO/HI/HIHI? */
public static final WidgetPropertyDescriptor<Boolean> propAlarmLimitsFromPV =
newBooleanPropertyDescriptor(WidgetPropertyCategory.BEHAVIOR, "alarm_limits_from_pv",
Messages.WidgetProperties_AlarmLimitsFromPV);

/** 'show_alarm_limits' — draw LOLO/LO/HI/HIHI alarm limit markers on the scale */
public static final WidgetPropertyDescriptor<Boolean> propShowAlarmLimits =
newBooleanPropertyDescriptor(WidgetPropertyCategory.DISPLAY, "show_alarm_limits",
Messages.WidgetProperties_ShowAlarmLimits);

/** 'level_lolo' — LOLO (major alarm) lower threshold; {@code NaN} = inactive */
public static final WidgetPropertyDescriptor<Double> propLevelLoLo =
newDoublePropertyDescriptor(WidgetPropertyCategory.BEHAVIOR, "level_lolo",
Messages.WidgetProperties_LevelLoLo);

/** 'level_low' — LO (minor warning) lower threshold; {@code NaN} = inactive */
public static final WidgetPropertyDescriptor<Double> propLevelLow =
newDoublePropertyDescriptor(WidgetPropertyCategory.BEHAVIOR, "level_low",
Messages.WidgetProperties_LevelLow);

/** 'level_high' — HI (minor warning) upper threshold; {@code NaN} = inactive */
public static final WidgetPropertyDescriptor<Double> propLevelHigh =
newDoublePropertyDescriptor(WidgetPropertyCategory.BEHAVIOR, "level_high",
Messages.WidgetProperties_LevelHigh);

/** 'level_hihi' — HIHI (major alarm) upper threshold; {@code NaN} = inactive */
public static final WidgetPropertyDescriptor<Double> propLevelHiHi =
newDoublePropertyDescriptor(WidgetPropertyCategory.BEHAVIOR, "level_hihi",
Messages.WidgetProperties_LevelHiHi);

/** 'minor_alarm_color' — color for LO / HI lines; defaults to named MINOR alarm color */
public static final WidgetPropertyDescriptor<WidgetColor> propMinorAlarmColor =
newColorPropertyDescriptor(WidgetPropertyCategory.DISPLAY, "minor_alarm_color",
Messages.WidgetProperties_MinorAlarmColor);

/** 'major_alarm_color' — color for LOLO / HIHI lines; defaults to named MAJOR alarm color */
public static final WidgetPropertyDescriptor<WidgetColor> propMajorAlarmColor =
newColorPropertyDescriptor(WidgetPropertyCategory.DISPLAY, "major_alarm_color",
Messages.WidgetProperties_MajorAlarmColor);

// ---- Instance fields ------------------------------------------------

private volatile WidgetProperty<ScaleFormat> format;
private volatile WidgetProperty<Integer> precision;
private volatile WidgetProperty<Boolean> limits_from_pv;
private volatile WidgetProperty<Boolean> alarm_limits_from_pv;
private volatile WidgetProperty<Double> minimum;
private volatile WidgetProperty<Double> maximum;
private volatile WidgetProperty<Boolean> show_alarm_limits;

Check warning on line 136 in app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/ScaledPVWidget.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this field "show_alarm_limits" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.

See more on https://sonarcloud.io/project/issues?id=ControlSystemStudio_phoebus&issues=AZ1HEPKxBfEcQZ3_IDPS&open=AZ1HEPKxBfEcQZ3_IDPS&pullRequest=3760
private volatile WidgetProperty<Double> level_lolo;

Check warning on line 137 in app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/ScaledPVWidget.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this field "level_lolo" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.

See more on https://sonarcloud.io/project/issues?id=ControlSystemStudio_phoebus&issues=AZ1HEPKxBfEcQZ3_IDPT&open=AZ1HEPKxBfEcQZ3_IDPT&pullRequest=3760
private volatile WidgetProperty<Double> level_low;

Check warning on line 138 in app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/ScaledPVWidget.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this field "level_low" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.

See more on https://sonarcloud.io/project/issues?id=ControlSystemStudio_phoebus&issues=AZ1HEPKxBfEcQZ3_IDPU&open=AZ1HEPKxBfEcQZ3_IDPU&pullRequest=3760
private volatile WidgetProperty<Double> level_high;
private volatile WidgetProperty<Double> level_hihi;
private volatile WidgetProperty<WidgetColor> minor_alarm_color;
private volatile WidgetProperty<WidgetColor> major_alarm_color;

protected ScaledPVWidget(final String type, final int default_width, final int default_height)
{
super(type, default_width, default_height);
}

/** Reorder properties so that alarm-related items sit together.
* {@code border_alarm_sensitive} (from PVWidget) is moved down to
* appear next to {@code alarm_limits_from_pv}.
*/
@Override
protected void defineProperties(final List<WidgetProperty<?>> properties)
{
super.defineProperties(properties);

// Move border_alarm_sensitive (added by PVWidget) down so it sits
// next to the alarm-related limit properties.
final WidgetProperty<?> alarm_border_prop = propBorderAlarmSensitive();
properties.remove(alarm_border_prop);

properties.add(format = propScaleFormat.createProperty(this, ScaleFormat.DEFAULT));
properties.add(precision = propScalePrecision.createProperty(this, 2));
properties.add(limits_from_pv = propLimitsFromPV.createProperty(this, true));
properties.add(minimum = propMinimum.createProperty(this, 0.0));

Check warning on line 166 in app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/ScaledPVWidget.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Extract the assignment out of this expression.

See more on https://sonarcloud.io/project/issues?id=ControlSystemStudio_phoebus&issues=AZ1HEPKxBfEcQZ3_IDPE&open=AZ1HEPKxBfEcQZ3_IDPE&pullRequest=3760
properties.add(maximum = propMaximum.createProperty(this, 100.0));
properties.add(alarm_border_prop);
properties.add(alarm_limits_from_pv = propAlarmLimitsFromPV.createProperty(this, true));
properties.add(show_alarm_limits = propShowAlarmLimits.createProperty(this, false));

Check warning on line 170 in app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/ScaledPVWidget.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Extract the assignment out of this expression.

See more on https://sonarcloud.io/project/issues?id=ControlSystemStudio_phoebus&issues=AZ1HEPKxBfEcQZ3_IDPH&open=AZ1HEPKxBfEcQZ3_IDPH&pullRequest=3760
properties.add(level_lolo = propLevelLoLo.createProperty(this, Double.NaN));

Check warning on line 171 in app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/ScaledPVWidget.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Extract the assignment out of this expression.

See more on https://sonarcloud.io/project/issues?id=ControlSystemStudio_phoebus&issues=AZ1HEPKxBfEcQZ3_IDPI&open=AZ1HEPKxBfEcQZ3_IDPI&pullRequest=3760
properties.add(level_low = propLevelLow.createProperty(this, Double.NaN));
properties.add(level_high = propLevelHigh.createProperty(this, Double.NaN));
properties.add(level_hihi = propLevelHiHi.createProperty(this, Double.NaN));
properties.add(minor_alarm_color = propMinorAlarmColor.createProperty(this,
WidgetColorService.getColor(NamedWidgetColors.ALARM_MINOR)));
properties.add(major_alarm_color = propMajorAlarmColor.createProperty(this,

Check warning on line 177 in app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/ScaledPVWidget.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Extract the assignment out of this expression.

See more on https://sonarcloud.io/project/issues?id=ControlSystemStudio_phoebus&issues=AZ1HEPKxBfEcQZ3_IDPN&open=AZ1HEPKxBfEcQZ3_IDPN&pullRequest=3760
WidgetColorService.getColor(NamedWidgetColors.ALARM_MAJOR)));
}

/** @return 'format' property (scale label format) */
public WidgetProperty<ScaleFormat> propFormat() { return format; }

/** @return 'precision' property */
public WidgetProperty<Integer> propPrecision() { return precision; }

/** @return 'limits_from_pv' property (min/max display range) */
public WidgetProperty<Boolean> propLimitsFromPV() { return limits_from_pv; }

/** @return 'alarm_limits_from_pv' property (LOLO/LO/HI/HIHI alarm levels) */
public WidgetProperty<Boolean> propAlarmLimitsFromPV() { return alarm_limits_from_pv; }

Check failure on line 191 in app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/ScaledPVWidget.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename method "propAlarmLimitsFromPV" to prevent any misunderstanding/clash with field "propAlarmLimitsFromPV".

See more on https://sonarcloud.io/project/issues?id=ControlSystemStudio_phoebus&issues=AZ1HEPKxBfEcQZ3_IDPZ&open=AZ1HEPKxBfEcQZ3_IDPZ&pullRequest=3760

/** @return 'minimum' property */
public WidgetProperty<Double> propMinimum() { return minimum; }

/** @return 'maximum' property */
public WidgetProperty<Double> propMaximum() { return maximum; }

/** @return 'show_alarm_limits' property */
public WidgetProperty<Boolean> propShowAlarmLimits() { return show_alarm_limits; }

/** @return 'level_lolo' property */
public WidgetProperty<Double> propLevelLoLo() { return level_lolo; }

/** @return 'level_lo' property */
public WidgetProperty<Double> propLevelLow() { return level_low; }

/** @return 'level_hi' property */
public WidgetProperty<Double> propLevelHigh() { return level_high; }

/** @return 'level_hihi' property */
public WidgetProperty<Double> propLevelHiHi() { return level_hihi; }

Check failure on line 212 in app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/ScaledPVWidget.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename method "propLevelHiHi" to prevent any misunderstanding/clash with field "propLevelHiHi".

See more on https://sonarcloud.io/project/issues?id=ControlSystemStudio_phoebus&issues=AZ1HEPKxBfEcQZ3_IDPe&open=AZ1HEPKxBfEcQZ3_IDPe&pullRequest=3760

/** @return 'minor_alarm_color' property */
public WidgetProperty<WidgetColor> propMinorAlarmColor() { return minor_alarm_color; }

/** @return 'major_alarm_color' property */
public WidgetProperty<WidgetColor> propMajorAlarmColor() { return major_alarm_color; }
}
Loading
Loading