Skip to content

Commit 4077073

Browse files
authored
Merge pull request #2387 from ControlSystemStudio/CSSTUDIO-1121
fix: DisplayRuntime window doesn't use width set by display properties
2 parents 8fd7bc7 + 4552396 commit 4077073

File tree

3 files changed

+83
-9
lines changed

3 files changed

+83
-9
lines changed

app/display/runtime/src/main/java/org/csstudio/display/builder/runtime/app/DisplayRuntimeInstance.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
import static org.csstudio.display.builder.runtime.WidgetRuntime.logger;
1111

12+
13+
import java.awt.geom.Rectangle2D;
1214
import java.io.ByteArrayOutputStream;
1315
import java.io.PrintStream;
1416
import java.util.Objects;
@@ -506,4 +508,23 @@ public void onClosed()
506508

507509
navigation.dispose();
508510
}
511+
512+
@Override
513+
public Optional<Rectangle2D> getPositionAndSizeHint() {
514+
return Optional.ofNullable(active_model).flatMap(displayModel -> {
515+
Integer width = displayModel.propWidth().getValue();
516+
Integer height = displayModel.propHeight().getValue();
517+
if(width != null && width > 0 && height != null && height > 0) {
518+
return Optional.of(new Rectangle2D.Double(
519+
displayModel.propX().getValue(),
520+
displayModel.propY().getValue(),
521+
width,
522+
height
523+
));
524+
} else {
525+
return Optional.empty();
526+
}
527+
});
528+
}
529+
509530
}

core/framework/src/main/java/org/phoebus/framework/spi/AppInstance.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.phoebus.framework.spi;
22

3+
import java.awt.geom.Rectangle2D;
4+
import java.util.Optional;
35
import org.phoebus.framework.persistence.Memento;
46

57
public interface AppInstance {
@@ -38,4 +40,15 @@ public default void restore(Memento memento) {
3840
public default void save(Memento memento) {
3941
// Default does nothing
4042
}
43+
44+
/**
45+
* Get possible window size and position for the application instance, if defined
46+
* (for example, Display Runtime may want the window to be the size defined in the display)
47+
*
48+
* (Note: Use Rectangle2D to avoid loading AWT toolkit; we only need a data container)
49+
*
50+
* @return Empty optional if no dimension is specified by the application instance.
51+
*/
52+
public default Optional<Rectangle2D> getPositionAndSizeHint() { return Optional.empty(); }
53+
4154
}

core/ui/src/main/java/org/phoebus/ui/docking/DockItem.java

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -447,19 +447,46 @@ private void handleDragDone(final DragEvent event)
447447
// but event.getX(), getSceneX(), getScreenX() are all 0.0.
448448
// --> Using MouseInfo, which is actually AWT code
449449
final Stage other = item.detach();
450-
final PointerInfo pi = MouseInfo.getPointerInfo();
451-
if (pi != null)
452-
{
453-
final Point loc = pi.getLocation();
454-
other.setX(loc.getX());
455-
other.setY(loc.getY());
456-
}
450+
451+
// Try to use the x/y location of the stage using the dimension hint if it
452+
// has been specified; Otherwise, use the pointer location
453+
AppInstance application = this.getApplication();
454+
application.getPositionAndSizeHint().ifPresentOrElse(dimension -> {
455+
// If the x and y position are default values (zero) then
456+
// use the cursor position
457+
if (isDefaultPosition(dimension.getX()) && isDefaultPosition(dimension.getY())) {
458+
setLocationToMousePointer(other);
459+
}
460+
// Otherwise use the position hint
461+
else {
462+
other.setX(dimension.getX());
463+
other.setY(dimension.getY());
464+
}
465+
}, () -> {
466+
setLocationToMousePointer(other);
467+
});
468+
457469
}
458470
event.consume();
459471
}
460472

473+
private void setLocationToMousePointer(Stage stage) {
474+
final PointerInfo pi = MouseInfo.getPointerInfo();
475+
if (pi != null)
476+
{
477+
final Point loc = pi.getLocation();
478+
stage.setX(loc.getX());
479+
stage.setY(loc.getY());
480+
}
481+
}
482+
483+
private boolean isDefaultPosition(double pos) {
484+
return pos > -1.0 && pos < 1.0;
485+
}
486+
461487
private Stage detach()
462488
{
489+
463490
// For size of new stage, approximate the
464491
// current size of the item, i.e. the size
465492
// of its DockPane, adding some extra space
@@ -479,8 +506,21 @@ private Stage detach()
479506
other.setTitle(UUID.randomUUID().toString());
480507

481508
DockStage.configureStage(other, this);
482-
other.setWidth(old_parent.getWidth() + extra_width);
483-
other.setHeight(old_parent.getHeight() + extra_height);
509+
510+
// Set the dimensions of the stage using the dimension hint from the
511+
// application (e.g. the width and height of the Display widget if
512+
// it's the display application). Otherwise, use the parent window dimensions.
513+
AppInstance application = this.getApplication();
514+
application.getPositionAndSizeHint().ifPresentOrElse(dimension -> {
515+
// use the dimension hints suggested by the application
516+
// such as possibly Display widget dimensions
517+
other.setWidth(dimension.getWidth() + extra_width);
518+
other.setHeight(dimension.getHeight() + extra_height);
519+
}, () -> {
520+
// use the parent window dimensions if no dimension hints
521+
other.setWidth(old_parent.getWidth() + extra_width);
522+
other.setHeight(old_parent.getHeight() + extra_height);
523+
});
484524

485525
// Assert that styles used in old scene are still available
486526
for (String css : old_scene.getStylesheets())

0 commit comments

Comments
 (0)