From 27a43f42a7708295c047246d7aac63309a923e16 Mon Sep 17 00:00:00 2001 From: Tom Joannem Date: Thu, 25 Sep 2025 11:15:38 +0200 Subject: [PATCH 1/3] Fix pending, autoSize not working --- .../widgets/SlideButtonRepresentation.java | 68 +++++++++++++++---- 1 file changed, 55 insertions(+), 13 deletions(-) diff --git a/app/display/representation-javafx/src/main/java/org/csstudio/display/builder/representation/javafx/widgets/SlideButtonRepresentation.java b/app/display/representation-javafx/src/main/java/org/csstudio/display/builder/representation/javafx/widgets/SlideButtonRepresentation.java index 03d92d4bc7..1270182b44 100644 --- a/app/display/representation-javafx/src/main/java/org/csstudio/display/builder/representation/javafx/widgets/SlideButtonRepresentation.java +++ b/app/display/representation-javafx/src/main/java/org/csstudio/display/builder/representation/javafx/widgets/SlideButtonRepresentation.java @@ -8,7 +8,6 @@ */ package org.csstudio.display.builder.representation.javafx.widgets; - import static org.csstudio.display.builder.representation.ToolkitRepresentation.logger; import java.util.concurrent.atomic.AtomicBoolean; @@ -23,7 +22,6 @@ import org.csstudio.display.builder.model.widgets.SlideButtonWidget; import org.csstudio.display.builder.representation.javafx.JFXUtil; import org.epics.vtype.VType; -import org.phoebus.ui.javafx.Styles; import javafx.application.Platform; import javafx.geometry.Pos; @@ -34,7 +32,6 @@ import javafx.scene.layout.Priority; import javafx.scene.paint.Color; - /** * JavaFX representation of the SlideButton model. * @@ -64,24 +61,27 @@ public class SlideButtonRepresentation extends RegionBaseRepresentation Date: Wed, 23 Sep 2026 13:24:05 +0200 Subject: [PATCH 2/3] add stretched mode to slide button --- .../display/builder/model/Messages.java | 1 + .../properties/CommonWidgetProperties.java | 7 + .../model/widgets/SlideButtonWidget.java | 10 ++ .../display/builder/model/messages.properties | 1 + .../builder/model/messages_fr.properties | 1 + .../widgets/SlideButtonRepresentation.java | 170 ++++++++++-------- 6 files changed, 113 insertions(+), 77 deletions(-) diff --git a/app/display/model/src/main/java/org/csstudio/display/builder/model/Messages.java b/app/display/model/src/main/java/org/csstudio/display/builder/model/Messages.java index 1f56ddea77..002370323a 100644 --- a/app/display/model/src/main/java/org/csstudio/display/builder/model/Messages.java +++ b/app/display/model/src/main/java/org/csstudio/display/builder/model/Messages.java @@ -217,6 +217,7 @@ public class Messages WidgetProperties_Editable, WidgetProperties_EmptyColor, WidgetProperties_Enabled, + WidgetProperties_Stretched, WidgetProperties_ExtremaVisible, WidgetProperties_FallbackSymbol, WidgetProperties_File, diff --git a/app/display/model/src/main/java/org/csstudio/display/builder/model/properties/CommonWidgetProperties.java b/app/display/model/src/main/java/org/csstudio/display/builder/model/properties/CommonWidgetProperties.java index 236702a380..0f0b57f22f 100644 --- a/app/display/model/src/main/java/org/csstudio/display/builder/model/properties/CommonWidgetProperties.java +++ b/app/display/model/src/main/java/org/csstudio/display/builder/model/properties/CommonWidgetProperties.java @@ -718,6 +718,13 @@ public WidgetProperty> createProperty(final Widget widget, public static final WidgetPropertyDescriptor propEnabled = newBooleanPropertyDescriptor(WidgetPropertyCategory.BEHAVIOR, "enabled", Messages.WidgetProperties_Enabled); + /** + * 'stretched' property + */ + public static final WidgetPropertyDescriptor propStretched = + newBooleanPropertyDescriptor(WidgetPropertyCategory.BEHAVIOR, "stretched", Messages.WidgetProperties_Stretched); + + /** * 'interactive' property: Does widget react to mouse etc. at runtime? */ diff --git a/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/SlideButtonWidget.java b/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/SlideButtonWidget.java index 95e5878fb0..a80963aed5 100644 --- a/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/SlideButtonWidget.java +++ b/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/SlideButtonWidget.java @@ -14,6 +14,7 @@ import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propConfirmDialogOptions; import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propConfirmMessage; import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propEnabled; +import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propStretched; import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propFont; import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propForegroundColor; import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propOffColor; @@ -74,6 +75,7 @@ public Widget createWidget ( ) { private volatile WidgetProperty confirm_dialog; private volatile WidgetProperty confirm_message; private volatile WidgetProperty enabled; + private volatile WidgetProperty stretched; private volatile WidgetProperty font; private volatile WidgetProperty foreground; private volatile WidgetProperty label; @@ -121,6 +123,13 @@ public WidgetProperty propEnabled ( ) { return enabled; } + /** + * @return 'stretched' property. + */ + public WidgetProperty propStretched ( ) { + return stretched; + } + /** * @return 'font' property. */ @@ -176,6 +185,7 @@ protected void defineProperties ( final List> properties ) { properties.add(foreground = propForegroundColor.createProperty(this, WidgetColorService.getColor(NamedWidgetColors.TEXT))); properties.add(auto_size = propAutoSize.createProperty(this, false)); properties.add(enabled = propEnabled.createProperty(this, true)); + properties.add(stretched = propStretched.createProperty(this, false)); properties.add(confirm_dialog = propConfirmDialogOptions.createProperty(this, ConfirmDialog.NONE)); properties.add(confirm_message = propConfirmMessage.createProperty(this, "Are your sure you want to do this?")); properties.add(password = propPassword.createProperty(this, "")); diff --git a/app/display/model/src/main/resources/org/csstudio/display/builder/model/messages.properties b/app/display/model/src/main/resources/org/csstudio/display/builder/model/messages.properties index 278fcc4753..15171841da 100644 --- a/app/display/model/src/main/resources/org/csstudio/display/builder/model/messages.properties +++ b/app/display/model/src/main/resources/org/csstudio/display/builder/model/messages.properties @@ -202,6 +202,7 @@ WidgetProperties_DiscreteSeconds=Discrete Seconds WidgetProperties_Editable=Editable WidgetProperties_EmptyColor=Empty Color WidgetProperties_Enabled=Enabled +WidgetProperties_Stretched=Stretched WidgetProperties_ExtremaVisible=Extrema Visible WidgetProperties_DragDisabled=Drag Disabled WidgetProperties_FallbackSymbol=Fallback Symbol diff --git a/app/display/model/src/main/resources/org/csstudio/display/builder/model/messages_fr.properties b/app/display/model/src/main/resources/org/csstudio/display/builder/model/messages_fr.properties index a5764e7ef7..6a640ac8e5 100644 --- a/app/display/model/src/main/resources/org/csstudio/display/builder/model/messages_fr.properties +++ b/app/display/model/src/main/resources/org/csstudio/display/builder/model/messages_fr.properties @@ -202,6 +202,7 @@ WidgetProperties_DiscreteSeconds=Secondes discrètes WidgetProperties_Editable=Modifiable WidgetProperties_EmptyColor=Couleur vide WidgetProperties_Enabled=Activé +WidgetProperties_Stretched=Etiré WidgetProperties_ExtremaVisible=Extrêmes visibles WidgetProperties_DragDisabled=Glisser-déposer désactivé WidgetProperties_FallbackSymbol=Symbole de secours diff --git a/app/display/representation-javafx/src/main/java/org/csstudio/display/builder/representation/javafx/widgets/SlideButtonRepresentation.java b/app/display/representation-javafx/src/main/java/org/csstudio/display/builder/representation/javafx/widgets/SlideButtonRepresentation.java index 1270182b44..9d57b371e0 100644 --- a/app/display/representation-javafx/src/main/java/org/csstudio/display/builder/representation/javafx/widgets/SlideButtonRepresentation.java +++ b/app/display/representation-javafx/src/main/java/org/csstudio/display/builder/representation/javafx/widgets/SlideButtonRepresentation.java @@ -8,6 +8,7 @@ */ package org.csstudio.display.builder.representation.javafx.widgets; + import static org.csstudio.display.builder.representation.ToolkitRepresentation.logger; import java.util.concurrent.atomic.AtomicBoolean; @@ -30,8 +31,10 @@ import javafx.scene.input.MouseEvent; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; +import javafx.scene.layout.StackPane; import javafx.scene.paint.Color; + /** * JavaFX representation of the SlideButton model. * @@ -53,6 +56,9 @@ public class SlideButtonRepresentation extends RegionBaseRepresentation bitChangedListener = this::bitChanged; private final WidgetPropertyListener labelChangedListener = this::labelChanged; private final WidgetPropertyListener valueChangedListener = this::valueChanged; + private final UntypedWidgetPropertyListener stretchedChangedListener = this::stretchedChanged; + + private final AtomicBoolean updating = new AtomicBoolean(); protected volatile int bit = 0; protected volatile boolean enabled = true; @@ -61,33 +67,32 @@ public class SlideButtonRepresentation extends RegionBaseRepresentation + { + // To avoid setting a new value when context menu is requested, + // slide only if primary button was pressed. + if (event.getButton().equals(MouseButton.PRIMARY)) { + handleSlide(); + } + event.consume(); + }); + } - button = new ToggleSwitch(); button.setMinSize(37, 20); button.setPrefSize(37, 20); button.setGraphicTextGap(0); button.setMnemonicParsing(false); - if (! toolkit.isEditMode() ) - button.addEventFilter(MouseEvent.MOUSE_RELEASED, event -> - { - // To avoid setting a new value when context menu is requested, - // slide only if primary button was pressed. - if(event.getButton().equals(MouseButton.PRIMARY)) { - handleSlide(); - } - event.consume(); - }); - // Label - label = new Label(labelContent); - label.setMaxWidth(Double.MAX_VALUE); + if (label == null) + label = new Label(labelContent); + label.setMnemonicParsing(false); - - // Empty label - emptyLabel = new Label(); - - HBox.setHgrow(label, Priority.ALWAYS); - HBox hbox = new HBox(6,emptyLabel, button, label); - hbox.setAlignment(Pos.CENTER); - hbox.setCenterShape(true); - button.setCenterShape(true); - - /* - // Border - float space = 6f; - BorderWidths width = new BorderWidths(space, space, space, space, true, true, true, true); - Insets insets = new Insets((int)space, (int)space, (int)space, (int)space); - CornerRadii cornerRadii = new CornerRadii(space); - Paint paint = Paint.valueOf("Blue"); - BorderStroke stroke = new BorderStroke(paint, BorderStrokeStyle.SOLID, cornerRadii, width, insets); - Border border = new Border(stroke); - hbox.setBorder(border); - */ - - return hbox; + label.setMaxWidth(Double.MAX_VALUE); + + + if (jfx_node != null) { + hbox = jfx_node; + hbox.getChildren().clear(); + } else { + hbox = new HBox(6); + } + if (model_widget.propStretched().getValue()) { + if (buttonContainer == null) { + buttonContainer = new StackPane(button); + buttonContainer.setAlignment(Pos.CENTER); + } + + double height = hbox.getHeight(); + if (height > 20) { + double scale = height / 20.0; + button.setScaleX(scale); + button.setScaleY(scale); + + buttonContainer.setPrefWidth(37 * scale); + buttonContainer.setMinWidth(37 * scale); + buttonContainer.setMaxWidth(37 * scale); + } + + hbox.getChildren().addAll(buttonContainer, label); + hbox.setAlignment(Pos.CENTER_LEFT); + } else { + buttonContainer = null; + + button.setScaleX(1); + button.setScaleY(1); + + hbox.getChildren().addAll(button, label); + hbox.setAlignment(Pos.CENTER_RIGHT); + + HBox.setHgrow(label, Priority.ALWAYS); + } + + return hbox; } - @Override + + @Override protected boolean isFilteringEditModeClicks() { return true; @@ -211,6 +222,7 @@ protected void registerListeners ( ) { styleChanged(null, null, null); + model_widget.propStretched().addUntypedPropertyListener(stretchedChangedListener); model_widget.propEnabled().addUntypedPropertyListener(styleChangedListener); model_widget.propFont().addUntypedPropertyListener(styleChangedListener); model_widget.propForegroundColor().addUntypedPropertyListener(styleChangedListener); @@ -230,6 +242,7 @@ protected void registerListeners ( ) { @Override protected void unregisterListeners() { + model_widget.propStretched().removePropertyListener(stretchedChangedListener); model_widget.propAutoSize().removePropertyListener(sizeChangedListener); model_widget.propHeight().removePropertyListener(sizeChangedListener); model_widget.propWidth().removePropertyListener(sizeChangedListener); @@ -246,11 +259,14 @@ protected void unregisterListeners() } private void bitChanged ( final WidgetProperty property, final Integer old_value, final Integer new_value ) { - bit = ( new_value != null ? new_value : model_widget.propBit().getValue() ); - stateChanged(bit, value); + } + private void stretchedChanged(final WidgetProperty property, final Object old_value, final Object new_value) { + dirty_size.mark(); + dirty_style.mark(); + toolkit.scheduleUpdate(this); } private void confirm ( ) { @@ -277,7 +293,7 @@ private void confirm ( ) { final String message = model_widget.propConfirmMessage().getValue(); final String password = model_widget.propPassword().getValue(); - if ( password.length() > 0 ) { + if (!password.isEmpty()) { if ( toolkit.showPasswordDialog(model_widget, message, password) == null ) { return; } @@ -342,4 +358,4 @@ private void valueChanged ( final WidgetProperty property, final VType ol stateChanged(bit, value); } -} +} \ No newline at end of file From d60f10024a15a8e79259ca13e2a7bd08e630ad29 Mon Sep 17 00:00:00 2001 From: lcaouen Date: Wed, 23 Sep 2026 16:16:47 +0200 Subject: [PATCH 3/3] pre-commit corrections --- .../javafx/widgets/SlideButtonRepresentation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/display/representation-javafx/src/main/java/org/csstudio/display/builder/representation/javafx/widgets/SlideButtonRepresentation.java b/app/display/representation-javafx/src/main/java/org/csstudio/display/builder/representation/javafx/widgets/SlideButtonRepresentation.java index 9d57b371e0..c99e760cfd 100644 --- a/app/display/representation-javafx/src/main/java/org/csstudio/display/builder/representation/javafx/widgets/SlideButtonRepresentation.java +++ b/app/display/representation-javafx/src/main/java/org/csstudio/display/builder/representation/javafx/widgets/SlideButtonRepresentation.java @@ -358,4 +358,4 @@ private void valueChanged ( final WidgetProperty property, final VType ol stateChanged(bit, value); } -} \ No newline at end of file +}