Skip to content

Commit 8022e22

Browse files
committed
Resolve merge conflict
2 parents 994b652 + f7e4990 commit 8022e22

File tree

15 files changed

+258
-141
lines changed

15 files changed

+258
-141
lines changed

app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/plots/ImageWidget.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2015-2018 Oak Ridge National Laboratory.
2+
* Copyright (c) 2015-2022 Oak Ridge National Laboratory.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -13,6 +13,7 @@
1313
import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propFile;
1414
import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propForegroundColor;
1515
import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propInteractive;
16+
import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propLimitsFromPV;
1617
import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propMaximum;
1718
import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propMinimum;
1819
import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.runtimePropConfigure;
@@ -409,6 +410,7 @@ public boolean configureFromXML(final ModelReader model_reader, final Widget wid
409410
private volatile WidgetProperty<ColorMap> data_colormap;
410411
private volatile ColorBarProperty color_bar;
411412
private volatile AxisWidgetProperty x_axis, y_axis;
413+
private volatile WidgetProperty<Boolean> limits_from_pv;
412414
private volatile WidgetProperty<Integer> data_width, data_height;
413415
private volatile WidgetProperty<InterpolationType> data_interpolation;
414416
private volatile WidgetProperty<VImageType> data_color_mode;
@@ -440,6 +442,7 @@ protected void defineProperties(final List<WidgetProperty<?>> properties)
440442
properties.add(color_bar = new ColorBarProperty(this));
441443
properties.add(x_axis = new XAxisWidgetProperty(this));
442444
properties.add(y_axis = new YAxisWidgetProperty(this));
445+
properties.add(limits_from_pv = propLimitsFromPV.createProperty(this, false)); // 'true' would be preferred but breaks existing displays
443446
properties.add(data_width = propDataWidth.createProperty(this, 100));
444447
properties.add(data_height = propDataHeight.createProperty(this, 100));
445448
properties.add(data_interpolation = propInterpolationType.createProperty(this, InterpolationType.AUTOMATIC));
@@ -531,6 +534,12 @@ public AxisWidgetProperty propYAxis()
531534
return y_axis;
532535
}
533536

537+
/** @return 'limits_from_pv' property */
538+
public WidgetProperty<Boolean> propLimitsFromPV()
539+
{
540+
return limits_from_pv;
541+
}
542+
534543
/** @return 'data_width' property */
535544
public WidgetProperty<Integer> propDataWidth()
536545
{

app/display/model/src/main/resources/examples/plots_image.bob

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<display version="2.0.0">
33
<name>Image Widget</name>
4-
<width>1100</width>
5-
<height>1200</height>
4+
<width>1090</width>
5+
<height>1430</height>
66
<widget type="label" version="2.0.0">
77
<name>Label</name>
88
<class>TITLE</class>
@@ -274,33 +274,38 @@ the value range.</text>
274274
</rois>
275275
</widget>
276276
<widget type="label" version="2.0.0">
277-
<name>Label_8</name>
278-
<text>For PVAccess, a PV that serves an NTNDArray will provide
279-
both the image data and the width &amp; height information.
280-
(This is currently limited to byte[] data.
281-
For NTNDArray with short, int, etc., you need to read
282-
pva://that_pv/value to get just the data array,
283-
and configure the data width and height).
284-
285-
For PVAccess or Channel Access, the data can be a waveform
286-
that contains the pixels values starting with the top-left pixel,
287-
followed by the pixels of the top row, then the second row
288-
and so on.
277+
<class>SECTION</class>
278+
<text>PV, Data</text>
279+
<x>201</x>
280+
<y>891</y>
281+
<width>171</width>
282+
<font use_class="true">
283+
<font name="Default Bold" family="Liberation Sans" style="BOLD" size="14.0">
284+
</font>
285+
</font>
286+
<foreground_color use_class="true">
287+
<color name="Text" red="0" green="0" blue="0">
288+
</color>
289+
</foreground_color>
290+
<transparent use_class="true">true</transparent>
291+
</widget>
292+
<widget type="label" version="2.0.0">
293+
<text>The pixel data is an array that starts with the top-left pixel, followed by the pixels of the top row, then the second row and so on.
294+
295+
For PVAccess, a PV that serves an NTNDArray will provide not only the pixel data but also the width, height, signed/unsigned information and color mode.
289296

290-
The image data width and height need to be configured for
291-
waveform PVs.
292-
For NTNDArray PVs, the image size is provided by the PV.</text>
297+
For Channel Access, the waveform PV only provides pixels. The data width, height, signedness and color mode need to be configured via properties of the image widget.
298+
</text>
293299
<x>201</x>
294300
<y>921</y>
295301
<width>421</width>
296-
<height>279</height>
302+
<height>209</height>
297303
</widget>
298304
<widget type="label" version="2.0.0">
299-
<name>Label_9</name>
300305
<class>SECTION</class>
301-
<text>PV, Data</text>
306+
<text>Axes</text>
302307
<x>201</x>
303-
<y>891</y>
308+
<y>1130</y>
304309
<width>171</width>
305310
<font use_class="true">
306311
<font name="Default Bold" family="Liberation Sans" style="BOLD" size="14.0">
@@ -312,6 +317,19 @@ For NTNDArray PVs, the image size is provided by the PV.</text>
312317
</foreground_color>
313318
<transparent use_class="true">true</transparent>
314319
</widget>
320+
<widget type="label" version="2.0.0">
321+
<text>When the "Limits from PV" property of the widget is set, the X axis will range from 0 to the width of the image in pixels and the Y axis from 0 to the height. The origin will be placed in the top-left corner.
322+
323+
When "Limits from PV" is not set, the range of the X and Y axes can be configured independently from the image size. This allows for example a calibration of pixel positions in millimeters.
324+
The axis direction can be inverted by swapping the axis minimum and maximum limit.
325+
326+
To set an axis limit relative to the image pixel size, one can use rules or scripts that take inputs from formula PVs '=imageWidth(`pva://...Image`)' or '=imageHeight(`pva://...Image`)' and then write for example the 'x_axis.maximum' or 'y_axis.minimum' property of the widget.
327+
</text>
328+
<x>200</x>
329+
<y>1150</y>
330+
<width>422</width>
331+
<height>280</height>
332+
</widget>
315333
<widget type="label" version="2.0.0">
316334
<name>Label_10</name>
317335
<text>Region of Interest</text>

app/display/representation-javafx/src/main/java/org/csstudio/display/builder/representation/javafx/JFXUtil.java

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -94,41 +94,32 @@ public static StringBuilder appendWebRGB(final StringBuilder buf, final WidgetCo
9494

9595
/** Convert model color into CSS style string for shading tabs, buttons, etc
9696
* @param color {@link WidgetColor}
97-
* @return style string of the form "-fx-color: ... -fx-outer-border: ... -fx-inner-border: ... -fx-background: ..."
97+
* @return style string of the form "-fx-base: ..;"
9898
*/
9999
public static String shadedStyle(final WidgetColor color)
100100
{
101101
return shadedStyleCache.computeIfAbsent(color, col ->
102102
{
103103
// How to best set colors?
104-
// Content Pane can be set in API, but Tab has no usable 'set color' API.
104+
// Content Pane can be set in API, but Button and Tab have no usable 'set color' API.
105105
// TabPane has setBackground(), but in "floating" style that would be
106106
// the background behind the tabs, which is usually transparent.
107-
// modena.css of JDK8 reveals a structure of sub-items which are shaded with gradients based
108-
// on -fx-color for the inactive tabs,
109-
// -fx-outer-border and -fx-inner-border for the, well, border,
110-
// and -fx-background for the selected tab,
111-
// so re-define those.
107+
//
108+
// Adjusting the style can break when the underlying style sheet changes,
109+
// but since at least JDK8 that has been modena.css with little changes until JFX 18,
110+
// which can be found in javafx-controls-18-linux.jar as
111+
// com/sun/javafx/scene/control/skin/modena/modena.css
112+
//
113+
// Buttons use nested -fx-background-color entries
114+
// -fx-shadow-highlight-color, -fx-outer-border, -fx-inner-border, -fx-body-color
115+
// with associated ..-insets and ..-radius which are all based on -fx-base,
116+
// so redefine that to adjust the overall color.
117+
// The .button.armed state uses
118+
// -fx-pressed-base: derive(-fx-base,-6%);
119+
// which we change into a more obvious variant.
112120
final String bg = webRGB(col);
113-
return "-fx-color: derive(" + bg + ", 50%);" +
114-
"-fx-outer-border: derive(" + bg + ", -23%);" +
115-
"-fx-inner-border: linear-gradient(to bottom," +
116-
"ladder(" + bg + "," +
117-
" derive(" + bg + ",30%) 0%," +
118-
" derive(" + bg + ",20%) 40%," +
119-
" derive(" + bg + ",25%) 60%," +
120-
" derive(" + bg + ",55%) 80%," +
121-
" derive(" + bg + ",55%) 90%," +
122-
" derive(" + bg + ",75%) 100%" +
123-
")," +
124-
"ladder(" + bg + "," +
125-
" derive(" + bg + ",20%) 0%," +
126-
" derive(" + bg + ",10%) 20%," +
127-
" derive(" + bg + ",5%) 40%," +
128-
" derive(" + bg + ",-2%) 60%," +
129-
" derive(" + bg + ",-5%) 100%" +
130-
"));" +
131-
"-fx-background: " + bg + ";";
121+
return "-fx-base: " + bg + "; " +
122+
"-fx-pressed-base: derive(-fx-base,-25%);";
132123
});
133124
}
134125

@@ -217,7 +208,7 @@ public static Pos computePos(final HorizontalAlignment horiz, final VerticalAlig
217208
}
218209

219210
/**returns double[] array for given line style scaled by line_width
220-
*
211+
*
221212
* @param style - actual line style
222213
* @param line_width - actual line width
223214
* @return double[] with segment lengths

app/display/representation-javafx/src/main/java/org/csstudio/display/builder/representation/javafx/widgets/ActionButtonRepresentation.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2015-2020 Oak Ridge National Laboratory.
2+
* Copyright (c) 2015-2022 Oak Ridge National Laboratory.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -323,7 +323,7 @@ private void handleActions(final List<ActionInfo> actions)
323323
/** @param action Action that the user invoked */
324324
private void handleAction(ActionInfo action)
325325
{
326-
// Keyboard presses are not supressed so check if the widget is enabled
326+
// Keyboard presses are not suppressed so check if the widget is enabled
327327
if (! enabled)
328328
return;
329329

app/display/representation-javafx/src/main/java/org/csstudio/display/builder/representation/javafx/widgets/plots/ImageRepresentation.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2015-2020 Oak Ridge National Laboratory.
2+
* Copyright (c) 2015-2022 Oak Ridge National Laboratory.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -424,13 +424,19 @@ private void contentChanged(final WidgetProperty<?> property, final Object old_v
424424
{
425425
final VType value = model_widget.runtimePropValue().getValue();
426426
if (value instanceof VNumberArray)
427-
image_plot.setValue(model_widget.propDataWidth().getValue(),
428-
model_widget.propDataHeight().getValue(),
427+
{
428+
// Can't get size from PV, use data_width, .._height
429+
final int width = model_widget.propDataWidth().getValue();
430+
final int height = model_widget.propDataHeight().getValue();
431+
if (model_widget.propLimitsFromPV().getValue())
432+
image_plot.setAxisRange(0.0, width, height, 0.0);
433+
image_plot.setValue(width, height,
429434
((VNumberArray) value).getData(),
430435
model_widget.propDataUnsigned().getValue(),
431436
model_widget.propDataColorMode().getValue());
437+
}
432438
else if (value instanceof VImage)
433-
{
439+
{ // Use VImage metadata
434440
final VImage image = (VImage) value;
435441
boolean isUnsigned;
436442
switch (image.getDataType())
@@ -444,7 +450,12 @@ else if (value instanceof VImage)
444450
default:
445451
isUnsigned = false;
446452
}
447-
image_plot.setValue(image.getWidth(), image.getHeight(), image.getData(),
453+
454+
final int width = image.getWidth();
455+
final int height = image.getHeight();
456+
if (model_widget.propLimitsFromPV().getValue())
457+
image_plot.setAxisRange(0.0, width, height, 0.0);
458+
image_plot.setValue(width, height, image.getData(),
448459
isUnsigned, image.getVImageType());
449460
}
450461
else if (value != null)

0 commit comments

Comments
 (0)