Skip to content

Commit ecbe7ea

Browse files
committed
Support -resource xyz?target=window@800x600+100+300
In addition to plain "target=window" we now support "target=window@.." with a geometry specification similar to the X11 `-geometry` paramter. Format is {width}x{height}+{x}+{y} or {width}x{height} or +{x}+{y}
1 parent 4d615e4 commit ecbe7ea

File tree

5 files changed

+97
-10
lines changed

5 files changed

+97
-10
lines changed

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2017 Oak Ridge National Laboratory.
2+
* Copyright (c) 2017-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
@@ -38,6 +38,7 @@
3838
import org.phoebus.ui.docking.DockItemWithInput;
3939
import org.phoebus.ui.docking.DockPane;
4040
import org.phoebus.ui.docking.DockStage;
41+
import org.phoebus.ui.docking.Geometry;
4142
import org.phoebus.ui.javafx.ToolbarHelper;
4243

4344
import javafx.application.Platform;
@@ -115,11 +116,14 @@ public static DisplayRuntimeInstance ofDisplayModel(final DisplayModel model)
115116
DockPane dock_pane = null;
116117
if (prefTarget != null)
117118
{
118-
if (prefTarget.equals("window"))
119+
if (prefTarget.startsWith("window"))
119120
{
120121
// Open new Stage in which this app will be opened, its DockPane is a new active one
121122
final Stage new_stage = new Stage();
122-
DockStage.configureStage(new_stage);
123+
if (prefTarget.startsWith("window@"))
124+
DockStage.configureStage(new_stage, new Geometry(prefTarget.substring(7)));
125+
else
126+
DockStage.configureStage(new_stage);
123127
new_stage.show();
124128
}
125129
else

core/launcher/src/main/java/org/phoebus/product/Launcher.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ private static void help()
235235
System.out.println("-resource 'pv://?sim://sine&app=probe' - Opens the 'sim://sine' PV with 'probe'.");
236236
System.out.println("-resource 'pv://?Fred&sim://sine&app=pv_table' - Opens two PVs PV with 'pv_table'.");
237237
System.out.println("-resource '...&target=window' - Opens resource in separate window.");
238+
System.out.println("-resource '...&target=window@800x600+200+150' - Opens resource in separate window sized 800 by 600 at x=200, y=150.");
238239
System.out.println("-resource '...&target=name_of_pane' - Opens resource in named pane.");
239240
}
240241
}

core/ui/src/main/java/org/phoebus/ui/application/PhoebusApplication.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -970,7 +970,7 @@ private void openResource(final URI resource, final boolean prompt) {
970970
if (end < 0)
971971
end = query.length();
972972
final String target = query.substring(i + 7, end);
973-
if (!target.equals("window")) {
973+
if (!target.startsWith("window")) {
974974
// Should the new panel open in a specific, named pane?
975975
final DockPane existing = DockStage.getDockPaneByName(target);
976976
if (existing != null)

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

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2017-2020 Oak Ridge National Laboratory.
2+
* Copyright (c) 2017-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
@@ -19,10 +19,6 @@
1919
import java.util.UUID;
2020
import java.util.logging.Level;
2121

22-
import javafx.scene.control.SplitPane;
23-
import javafx.scene.input.KeyCode;
24-
import javafx.scene.input.KeyCodeCombination;
25-
import javafx.scene.input.KeyCombination;
2622
import org.phoebus.framework.jobs.JobManager;
2723
import org.phoebus.framework.workbench.Locations;
2824
import org.phoebus.ui.application.Messages;
@@ -34,6 +30,7 @@
3430
import javafx.scene.Node;
3531
import javafx.scene.Parent;
3632
import javafx.scene.Scene;
33+
import javafx.scene.control.SplitPane;
3734
import javafx.scene.image.Image;
3835
import javafx.scene.layout.BorderPane;
3936
import javafx.stage.Stage;
@@ -116,6 +113,22 @@ static String createID(final String what)
116113
* @return {@link DockPane} that was added to the {@link Stage}
117114
*/
118115
public static DockPane configureStage(final Stage stage, final DockItem... tabs)
116+
{
117+
return configureStage(stage, new Geometry(null), tabs);
118+
}
119+
120+
/** Helper to configure a Stage for docking
121+
*
122+
* <p>Adds a Scene with a BorderPane layout and a DockPane in the center
123+
*
124+
* @param stage Stage, should be empty
125+
* @param geometry_spec A geometry specification "{width}x{height}+{x}+{y}", see {@link Geometry}
126+
* @param tabs Zero or more initial {@link DockItem}s
127+
* @throws Exception on error
128+
*
129+
* @return {@link DockPane} that was added to the {@link Stage}
130+
*/
131+
public static DockPane configureStage(final Stage stage, final Geometry geometry, final DockItem... tabs)
119132
{
120133
stage.getProperties().put(KEY_ID, createID("DockStage"));
121134

@@ -141,9 +154,19 @@ else if(layout.getChildren().get(0) instanceof SplitPane){
141154
}
142155
});
143156

144-
final Scene scene = new Scene(layout, 1600, 900);
157+
final Scene scene = new Scene(layout, geometry.width, geometry.height);
145158
stage.setScene(scene);
146159
stage.setTitle(Messages.FixedTitle);
160+
// Set position
161+
stage.setX(geometry.x);
162+
stage.setY(geometry.y);
163+
164+
// Force window to be visible
165+
stage.show();
166+
stage.toFront();
167+
stage.setAlwaysOnTop(true);
168+
stage.setAlwaysOnTop(false);
169+
147170
Styles.setSceneStyle(scene);
148171
try
149172
{
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2022 Oak Ridge National Laboratory.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
*******************************************************************************/
8+
package org.phoebus.ui.docking;
9+
10+
import java.util.regex.Matcher;
11+
import java.util.regex.Pattern;
12+
13+
/** Geometry info
14+
*
15+
* Uses a geometry specification <code>{width}x{height}+{x}+{y}</code>,
16+
* in a format similar to X11 <code>-geometry ..</code> argument.
17+
*
18+
* For example <code>600x400+100+50</code> describes a window
19+
* sized 600 by 400 located at X=100, Y=50.
20+
*
21+
* It is also allowed to provide only <code>{width}x{height}</code>
22+
* or <code>+{x}+{y}</code>
23+
*/
24+
public class Geometry
25+
{
26+
// 09 x 09 + 09 + 09, group for each number, with both size and offset being optional
27+
private static final Pattern SIZE_AND_OFFSET = Pattern.compile("(([0-9]+)x([0-9]+))?(\\+([0-9]+)\\+([0-9]+))?");
28+
29+
public int width = 1600;
30+
public int height = 900;
31+
public int x = 50;
32+
public int y = 50;
33+
34+
/** @param spec geometry specification <code>{width}x{height}+{x}+{y}</code> */
35+
public Geometry(final String spec)
36+
{
37+
if (spec != null)
38+
{
39+
final Matcher matcher = SIZE_AND_OFFSET.matcher(spec);
40+
if (matcher.matches())
41+
{
42+
if (matcher.group(2) != null)
43+
width = Integer.parseInt(matcher.group(2));
44+
if (matcher.group(3) != null)
45+
height = Integer.parseInt(matcher.group(3));
46+
if (matcher.group(5) != null)
47+
x = Integer.parseInt(matcher.group(5));
48+
if (matcher.group(6) != null)
49+
y = Integer.parseInt(matcher.group(6));
50+
}
51+
}
52+
}
53+
54+
@Override
55+
public String toString()
56+
{
57+
return width + "x" + height + "+" + x + "+" + y;
58+
}
59+
}

0 commit comments

Comments
 (0)