Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
import org.csstudio.display.builder.representation.javafx.ScriptsDialog;
import org.phoebus.framework.preferences.PhoebusPreferenceService;
import org.phoebus.ui.dialog.DialogHelper;
import org.phoebus.ui.dialog.MultiLineInputDialog;
import org.phoebus.ui.dialog.CodeDialog;
import org.phoebus.ui.javafx.EditCell;
import org.phoebus.ui.javafx.LineNumberTableCellFactory;
import org.phoebus.ui.javafx.TableHelper;
Expand Down Expand Up @@ -769,7 +769,7 @@ private Node createRulesTable ()
if (sel >= 0)
{
final String content = rule_items.get(sel).getRuleInfo().getTextPy(attached_widget);
final MultiLineInputDialog dialog = new MultiLineInputDialog(btn_show_script, content);
final CodeDialog dialog = new CodeDialog(btn_show_script, content);
DialogHelper.positionDialog(dialog, btn_show_script, -200, -300);
dialog.setTextHeight(600);
dialog.show();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,7 @@
.widget_pane_focused{
-fx-border-color: #00A0D8;
}

.code-dialog {
-fx-font-family: monospace !important;
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@
import java.util.function.Consumer;
import java.util.logging.Level;

import org.csstudio.display.builder.model.DisplayModel;
import org.csstudio.display.builder.model.UntypedWidgetPropertyListener;
import org.csstudio.display.builder.model.Widget;
import org.csstudio.display.builder.model.WidgetPropertyListener;
import org.csstudio.display.builder.model.*;
import org.csstudio.display.builder.model.properties.PredefinedColorMaps;
import org.csstudio.display.builder.model.properties.WidgetColor;
import org.csstudio.display.builder.representation.ToolkitRepresentation;
Expand Down Expand Up @@ -92,14 +89,23 @@
* |
* scroll_body (Group)
* |
* widget_parent (Pane)
* widget_pane (Pane)
* |
* widget_parent (Group)
*
* </pre>
*
* <p>widget_parent:
* This is where the widgets of the model get represented.
* <p>widget_pane:
* This contains the group with the child widgets.
* Its scaling factors are used to zoom.
* Also used to set the overall background color.
*
* <p>widget_parent:
* This is where the widgets of the model get represented.
* We need this to be a Group, as a Pane handle the prefSize properly when it contains
* transformed widgets (like a rotated Label). Groups set their prefSize according
* to the _transformed_ dimensions of its children.
*
* <p>scroll_body:
* Needed for scroll pane to use visual bounds, i.e. be aware of zoom.
* Otherwise scroll bars would enable/disable based on layout bounds,
Expand Down Expand Up @@ -152,8 +158,9 @@ public class JFXRepresentation extends ToolkitRepresentation<Parent, Node>
/** Update background color, grid */
private final UntypedWidgetPropertyListener background_listener = ( p, o, n ) -> execute(this::updateBackground);

private Group widget_parent;
private Line horiz_bound, vert_bound;
private Pane widget_parent;
private Pane widget_pane;
private Group scroll_body;
private ScrollPane model_root;

Expand Down Expand Up @@ -191,8 +198,9 @@ final public ScrollPane createModelRoot()
if (model_root != null)
throw new IllegalStateException("Already created model root");

widget_parent = new Pane();
scroll_body = new Group(widget_parent);
widget_parent = new Group();
widget_pane = new Pane(widget_parent);
scroll_body = new Group(widget_pane);

if (isEditMode())
{
Expand Down Expand Up @@ -281,7 +289,7 @@ final public ScrollPane createModelRoot()
}
});
else
widget_parent.addEventHandler(ScrollEvent.ANY, evt ->
widget_pane.addEventHandler(ScrollEvent.ANY, evt ->
{
if (evt.isShortcutDown())
{
Expand Down Expand Up @@ -319,7 +327,8 @@ private void doWheelZoom(final double delta, final double x, final double y)
// setText() only, otherwise it gets into an endless update due to getValue/setValue implementation in Editor. In Runtime was OK.
// Drawback: return to a previous "combo driven" zoom level from any wheel level not possible directly (no value change in combo)
setZoom(new_zoom);
zoom_listener.accept(Integer.toString((int)(new_zoom * 100)) + " %");
if (zoom_listener != null)
zoom_listener.accept(Integer.toString((int)(new_zoom * 100)) + " %");

repositionScroller(scroll_body, model_root, realFactor, scrollOffset, new Point2D(x, y));
}
Expand Down Expand Up @@ -448,7 +457,7 @@ private double setZoom(double zoom)
if (zoom <= 0.0)
{ // Determine zoom to fit outline of display into available space
final Bounds available = model_root.getLayoutBounds();
final Bounds outline = widget_parent.getLayoutBounds();
final Bounds outline = widget_pane.getLayoutBounds();

// 'outline' will wrap the actual widgets when the display
// is larger than the available viewport.
Expand Down Expand Up @@ -483,6 +492,7 @@ else if (zoom == ZOOM_HEIGHT)
}

widget_parent.getTransforms().setAll(new Scale(zoom, zoom));
widget_pane.getTransforms().setAll(new Scale(zoom, zoom));
// Appears similar to using this API:
// widget_parent.setScaleX(zoom);
// widget_parent.setScaleY(zoom);
Expand All @@ -502,7 +512,7 @@ else if (zoom == ZOOM_HEIGHT)
/** @return Zoom factor, 1.0 for 1:1 */
public double getZoom()
{
final List<Transform> transforms = widget_parent.getTransforms();
final List<Transform> transforms = widget_pane.getTransforms();
if (transforms.isEmpty() ||
transforms.size() > 1 ||
! (transforms.get(0) instanceof Scale))
Expand Down Expand Up @@ -568,16 +578,16 @@ private void handleViewportChanges()
: model_height;

// Does not consider zooming.
// If the widget_parent is zoomed 'out', e.g. 50%,
// the widget_parent will only be half as large
// If the widget_pane is zoomed 'out', e.g. 50%,
// the widget_pane will only be half as large
// as we specify here in pixels
// -> Ignore. If user zooms out a lot, there'll be an
// area a gray area at the right and bottom of the display.
// But user tends to zoom out to see the complete set of widgets,
// so there is very little gray area.
// widget_parent.setMinWidth(show_x / zoom);
// widget_parent.setMinHeight(show_y / zoom);
widget_parent.setMinSize(show_x, show_y);
widget_pane.setMinSize(show_x, show_y);
}

/** Update lines that indicate model's size in edit mode */
Expand All @@ -586,7 +596,7 @@ private void updateModelSizeIndicators()
int width = model.propWidth().getValue();
int height = model.propHeight().getValue();

final ObservableList<Transform> transforms = widget_parent.getTransforms();
final ObservableList<Transform> transforms = widget_pane.getTransforms();
if (transforms.size() > 0 && transforms.get(0) instanceof Scale)
{
final Scale scale = (Scale) transforms.get(0);
Expand Down Expand Up @@ -883,7 +893,7 @@ private void updateBackground()
final WritableImage wimage = new WritableImage(gridStepX, gridStepY);
SwingFXUtils.toFXImage(image, wimage);
final ImagePattern pattern = new ImagePattern(wimage, 0, 0, gridStepX, gridStepY, false);
widget_parent.setBackground(new Background(new BackgroundFill(pattern, CornerRadii.EMPTY, Insets.EMPTY)));
widget_pane.setBackground(new Background(new BackgroundFill(pattern, CornerRadii.EMPTY, Insets.EMPTY)));
}

// Future for controlling the audio player
Expand Down Expand Up @@ -1065,6 +1075,7 @@ public void shutdown()
logger.log(Level.WARNING, "Display representation still contains items on shutdown: " + widget_parent.getChildren());

widget_parent = null;
widget_pane = null;
model_root = null;
scroll_body = null;
zoom_listener = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
import org.phoebus.framework.preferences.PhoebusPreferenceService;
import org.phoebus.framework.util.ResourceParser;
import org.phoebus.ui.application.ApplicationLauncherService;
import org.phoebus.ui.dialog.CodeDialog;
import org.phoebus.ui.dialog.DialogHelper;
import org.phoebus.ui.dialog.MultiLineInputDialog;
import org.phoebus.ui.javafx.EditCell;
import org.phoebus.ui.javafx.LineNumberTableCellFactory;
import org.phoebus.ui.javafx.TableHelper;
Expand Down Expand Up @@ -617,7 +617,7 @@ private void add(final String file, final String text)
{
Platform.runLater(() ->
{
final MultiLineInputDialog dlg = new MultiLineInputDialog(scripts_table, selected_script_item.text);
final CodeDialog dlg = new CodeDialog(scripts_table, selected_script_item.text);
dlg.showAndWait().ifPresent(result -> selected_script_item.text = result);
});
}
Expand Down Expand Up @@ -751,7 +751,7 @@ private void editOrSelect()
}
else
{
final MultiLineInputDialog dlg = new MultiLineInputDialog(scripts_table, selected_script_item.text);
final CodeDialog dlg = new CodeDialog(scripts_table, selected_script_item.text);
dlg.showAndWait().ifPresent(result -> selected_script_item.text = result);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

import javafx.geometry.Insets;
import javafx.scene.Parent;
import javafx.scene.Group;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.layout.Background;
Expand Down Expand Up @@ -89,12 +90,16 @@ public class EmbeddedDisplayRepresentation extends RegionBaseRepresentation<Pane
private volatile double zoom_factor_y = 1.0;


/** Inner pane that holds child widgets
/** Inner pane & group that holds child widgets
* We need the group, since the Pane does NOT account for child widget transforms
* when computing prefWidth / prefHeight, making embedded displays larger than
* they actually are, when containing a tall (interpreted as wide) rotated child widget.
*
* <p>Set to null when representation is disposed,
* which is used as indicator to pending display updates.
*/
private volatile Pane inner;
private volatile Group inner_parent;
private volatile Background inner_background = Background.EMPTY;

/** Zoom for 'inner' pane */
Expand All @@ -103,7 +108,7 @@ public class EmbeddedDisplayRepresentation extends RegionBaseRepresentation<Pane
/** Optional scroll pane between 'jfx_node' Pane and 'inner'.
*
* To allow scrolling, the scene graph is
* jfx_node -> scroll -> inner.
* jfx_node -> scroll -> inner -> inner_parent.
*
* If no scrolling is desired, the scrollbars can be hidden via
* scroll.setHbarPolicy(ScrollBarPolicy.NEVER),
Expand All @@ -113,7 +118,7 @@ public class EmbeddedDisplayRepresentation extends RegionBaseRepresentation<Pane
*
* The easiest way to remove the scroll bars and any of its impact on
* event handling is to simply remove the scrollpane from the scene graph:
* jfx_node-> inner.
* jfx_node-> inner -> inner_parent.
*/
private ScrollPane scroll;

Expand All @@ -137,12 +142,20 @@ protected boolean isFilteringEditModeClicks()
@Override
public Pane createJFXNode() throws Exception
{
// rotated child widgets break the prefWidth / prefHeight of a Pane as its own prefWidth / prefHeight uses
// the non-transformed dimensions of its children. So the child widget parent must be a Group instead
// See https://forums.oracle.com/ords/apexds/post/java-fx-strange-behaviour-when-trying-to-write-a-label-vert-3164
// This is easily reproducible, by creating an embedded display with sufficient width and height,
// and placing a very tall rotated label inside of it. The resulting embedded display will get a horizontal
// scrollbar, as the pane containing it would be wider than it is shown to be.
inner_parent = new Group();

// inner.setScaleX() and setScaleY() zoom from the center
// and not the top-left edge, requiring adjustments to
// inner.setTranslateX() and ..Y() to compensate.
// Using a separate Scale transformation does not have that problem.
// See http://stackoverflow.com/questions/10707880/javafx-scale-and-translate-operation-results-in-anomaly
inner = new Pane();
inner = new Pane(inner_parent);
inner.getTransforms().add(zoom = new Scale());

scroll = new NonCachingScrollPane(inner);
Expand All @@ -165,7 +178,7 @@ public Pane createJFXNode() throws Exception
@Override
protected Parent getChildParent(final Parent parent)
{
return inner;
return inner_parent;
}

@Override
Expand Down Expand Up @@ -343,7 +356,7 @@ private void representContent(final DisplayModel content_model)
zoom.setX(zoom_factor_x);
zoom.setY(zoom_factor_y);

toolkit.representModel(inner, content_model);
toolkit.representModel(inner_parent, content_model);
backgroundChanged(null, null, null);
}
catch (final Exception ex)
Expand Down Expand Up @@ -426,7 +439,7 @@ public void updateChanges()
else
{ // Don't use a scroll pane
scroll.setContent(null);
jfx_node.getChildren().setAll(inner);
jfx_node.getChildren().setAll(inner_parent);

// During runtime or if the resize property is set to Crop we clip inner
// but allow 'overdrawing' in edit mode so the out-of-region widgets are visible to the user
Expand All @@ -450,7 +463,7 @@ else if (inner.getHeight() != 0.0 && inner.getWidth() != 0.0)
rect.setManaged(false);
rect.resizeRelocate(0, scaled_height, inner.getWidth(), inner.getHeight() - scaled_height);
rect.setBackground(EDIT_OVERDRAWN_BACKGROUND);
inner.getChildren().addAll(rect);
inner_parent.getChildren().addAll(rect);
}

// Check if wider than allowed
Expand All @@ -460,7 +473,7 @@ else if (inner.getHeight() != 0.0 && inner.getWidth() != 0.0)
rect.setManaged(false);
rect.resizeRelocate(scaled_width, 0, inner.getWidth() - scaled_width, inner.getHeight());
rect.setBackground(EDIT_OVERDRAWN_BACKGROUND);
inner.getChildren().addAll(rect);
inner_parent.getChildren().addAll(rect);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import java.util.Optional;
import java.util.logging.Level;

import javafx.scene.input.*;
import org.csstudio.display.builder.model.ChildrenProperty;
import org.csstudio.display.builder.model.DirtyFlag;
import org.csstudio.display.builder.model.DisplayModel;
Expand All @@ -31,10 +32,8 @@
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
import org.phoebus.core.types.ProcessVariable;
import org.phoebus.ui.dnd.DataFormats;

/** Base class for all JavaFX widget representations
* @param <JFX> JFX Widget
Expand Down Expand Up @@ -184,7 +183,8 @@ protected void configurePVNameDrag()
// this prevents selecting content within a text field
// via a mouse drag.
// Ctrl-drag is thus required to start dragging a PV name.
if (! event.isControlDown())
final Optional<WidgetProperty<Boolean>> writable = model_widget.checkProperty(CommonWidgetProperties.runtimePropPVWritable);
if (writable.isPresent() && !event.isControlDown())
return;

final String pv = pv_name.get().getValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,12 @@ public static DisplayRuntimeInstance ofDisplayModel(final DisplayModel model)
dock_pane.addTab(dock_item);

representation.getModelParent().getProperties().put(MODEL_PARENT_DISPLAY_RUNTIME, this);
representation.getModelParent().setOnContextMenuRequested(event ->

// since the model parent is now a Group, which takes on the bounds of its children,
// we need to add the context menu interaction to the Root, and not the parent
// I guess to be completely compliant to the 'old version', we'd need to get the
// widget_pane, but this seems more appropriate and generic
representation.getModelRoot().setOnContextMenuRequested(event ->
{
final DisplayModel model = active_model;
if (model != null)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/logbook/ui/src/main/resources/icons/logentry-add-16@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public class Messages
RestoreSelection_TT,
Saved,
Saved_Value_TimeStamp,
SearchPV,
Selected,
Snapshot,
Snapshot_TT,
Expand Down
Loading