]>
git.argeo.org Git - gpl/argeo-suite.git/blob - swt/org.argeo.app.geo.swt/src/org/argeo/app/geo/swt/SwtJSMapPart.java
1 package org
.argeo
.app
.geo
.swt
;
3 import java
.util
.Locale
;
4 import java
.util
.concurrent
.CompletableFuture
;
5 import java
.util
.concurrent
.CompletionStage
;
6 import java
.util
.function
.Consumer
;
7 import java
.util
.function
.Function
;
9 import org
.argeo
.api
.cms
.CmsLog
;
10 import org
.argeo
.app
.geo
.ux
.JsImplementation
;
11 import org
.argeo
.app
.geo
.ux
.MapPart
;
12 import org
.eclipse
.swt
.SWT
;
13 import org
.eclipse
.swt
.browser
.Browser
;
14 import org
.eclipse
.swt
.browser
.BrowserFunction
;
15 import org
.eclipse
.swt
.browser
.ProgressEvent
;
16 import org
.eclipse
.swt
.browser
.ProgressListener
;
17 import org
.eclipse
.swt
.layout
.GridData
;
18 import org
.eclipse
.swt
.widgets
.Composite
;
19 import org
.eclipse
.swt
.widgets
.Control
;
22 * An SWT implementation of {@link MapPart} based on JavaScript execute in a
23 * {@link Browser} control.
25 public class SwtJSMapPart
implements MapPart
{
26 static final long serialVersionUID
= 2713128477504858552L;
28 private final static CmsLog log
= CmsLog
.getLog(SwtJSMapPart
.class);
30 private final static String GLOBAL_THIS_
= "globalThis.";
32 private final Browser browser
;
34 private final CompletableFuture
<Boolean
> pageLoaded
= new CompletableFuture
<>();
36 private String jsImplementation
= JsImplementation
.OPENLAYERS_MAP_PART
.getJsClass();
37 private final String mapName
;// = "argeoMap";
39 public SwtJSMapPart(String mapName
, Composite parent
, int style
) {
40 this.mapName
= mapName
;
41 browser
= new Browser(parent
, 0);
42 browser
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
44 browser
.setUrl("/pkg/org.argeo.app.geo.js/index.html");
45 browser
.addProgressListener(new ProgressListener() {
46 static final long serialVersionUID
= 1L;
49 public void completed(ProgressEvent event
) {
52 browser
.execute(getJsMapVar() + " = new " + jsImplementation
+ "('" + mapName
+ "');");
54 pageLoaded
.complete(true);
55 } catch (Exception e
) {
56 log
.error("Cannot create map in browser", e
);
57 pageLoaded
.complete(false);
62 public void changed(ProgressEvent event
) {
67 public Control
getControl() {
76 public void addPoint(double lng
, double lat
, String style
) {
77 callMapMethod("addPoint(%f, %f, %s)", lng
, lat
, style
== null ?
"'default'" : style
);
81 public void addUrlLayer(String url
, GeoFormat format
, String style
) {
82 callMapMethod("addUrlLayer('%s', '%s', %s)", url
, format
.name(), style
);
86 public void setZoom(int zoom
) {
87 callMapMethod("setZoom(%d)", zoom
);
91 public void setCenter(double lng
, double lat
) {
92 callMapMethod("setCenter(%f, %f)", lng
, lat
);
95 protected CompletionStage
<Object
> callMapMethod(String methodCall
, Object
... args
) {
96 return callMethod(getJsMapVar(), methodCall
, args
);
99 protected CompletionStage
<Object
> callMethod(String jsObject
, String methodCall
, Object
... args
) {
100 return evaluate(jsObject
+ '.' + methodCall
, args
);
103 private String
getJsMapVar() {
104 return GLOBAL_THIS_
+ mapName
;
108 * Execute this JavaScript on the client side after making sure that the page
109 * has been loaded and the map object has been created.
111 * @param js the JavaScript code, possibly formatted according to
112 * {@link String#format}, with {@link Locale#ROOT} as locale (for
113 * stability of decimal separator, as expected by JavaScript.
114 * @param args the optional arguments of
115 * {@link String#format(String, Object...)}
117 protected CompletionStage
<Object
> evaluate(String js
, Object
... args
) {
118 CompletableFuture
<Object
> res
= pageLoaded
.thenApply((ready
) -> {
120 throw new IllegalStateException("Map " + mapName
+ " is not initialised.");
121 Object result
= browser
.evaluate(String
.format(Locale
.ROOT
, js
, args
));
124 return res
.minimalCompletionStage();
127 protected void loadExtension(String url
) {
129 // var script = document.createElement("script");
130 // script.src = '%s';
131 // document.head.appendChild(script);
133 // browser.evaluate(String.format(Locale.ROOT, js, url));
134 browser
.evaluate(String
.format(Locale
.ROOT
, "import('%s')", url
));
137 /** To be overridden with calls to {@link #loadExtension(String)}. */
138 protected void loadExtensions() {
145 public void onFeatureSelected(Consumer
<FeatureSelectedEvent
> toDo
) {
146 addCallback("FeatureSelected", (arr
) -> {
147 toDo
.accept(new FeatureSelectedEvent((String
) arr
[0]));
152 public void onFeatureSingleClick(Consumer
<FeatureSingleClickEvent
> toDo
) {
153 addCallback("FeatureSingleClick", (arr
) -> {
154 toDo
.accept(new FeatureSingleClickEvent((String
) arr
[0]));
159 public void onFeaturePopup(Function
<FeaturePopupEvent
, String
> toDo
) {
160 addCallback("FeaturePopup", (arr
) -> {
161 return toDo
.apply(new FeaturePopupEvent((String
) arr
[0]));
165 protected void addCallback(String suffix
, Function
<Object
[], Object
> toDo
) {
166 pageLoaded
.thenAccept((ready
) -> {
167 // browser functions must be directly on window (RAP specific)
168 new BrowserFunction(browser
, mapName
+ "__on" + suffix
) {
171 public Object
function(Object
[] arguments
) {
172 Object result
= toDo
.apply(arguments
);
177 browser
.execute(getJsMapVar() + ".callbacks['on" + suffix
+ "']=window." + mapName
+ "__on" + suffix
+ ";");
178 callMethod(mapName
, "enable" + suffix
+ "()");