1 /* $RCSfile$ 2 * $Author: hansonr $ 3 * $Date: 2012-09-11 19:29:26 -0500 (Tue, 11 Sep 2012) $ 4 * $Revision: 17556 $ 5 * 6 * Copyright (C) 2004-2005 The Jmol Development Team 7 * 8 * Contact: jmol-developers@lists.sf.net 9 * 10 * This library is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU Lesser General Public 12 * License as published by the Free Software Foundation; either 13 * version 2.1 of the License, or (at your option) any later version. 14 * 15 * This library is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * Lesser General Public License for more details. 19 * 20 * You should have received a copy of the GNU Lesser General Public 21 * License along with this library; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 23 */ 24 25 package org.jmol.appletjs; 26 27 import java.net.URL; 28 import java.util.Hashtable; 29 import java.util.Map; 30 31 import javajs.api.JSInterface; 32 import javajs.util.PT; 33 34 import org.jmol.api.js.JmolToJSmolInterface; 35 import org.jmol.util.GenericApplet; 36 import org.jmol.util.Logger; 37 import org.jmol.util.Parser; 38 39 /** 40 * Java2Script rendition of Jmol using HTML5-only or WebGL-based graphics 41 * 42 * @author Bob Hanson hansonr@stolaf.edu, Takanori Nakane, with the assistance 43 * of Jhou Renjian 44 * 45 */ 46 47 public class Jmol extends GenericApplet implements JSInterface { 48 49 private Map<String, Object> htParams; 50 51 /** 52 * cannot ignore super because it involves preparing fields 53 * @param vwrOptions 54 * 55 */ Jmol(Map<String, Object> vwrOptions)56 public Jmol(Map<String, Object> vwrOptions) { 57 htParams = new Hashtable<String, Object>(); 58 if (vwrOptions == null) 59 vwrOptions = new Hashtable<String, Object>(); 60 this.vwrOptions = vwrOptions; 61 for (Map.Entry<String, Object> entry : vwrOptions.entrySet()) 62 htParams.put(entry.getKey().toLowerCase(), entry.getValue()); 63 documentBase = "" + vwrOptions.get("documentBase"); 64 codeBase = "" + vwrOptions.get("codePath"); 65 isJS = true; 66 init(this); 67 } 68 69 @Override setStereoGraphics(boolean isStereo)70 public Object setStereoGraphics(boolean isStereo) { 71 /** 72 * @j2sNative 73 * 74 * if (isStereo) 75 * return vwr.apiPlatform.context; 76 * 77 */ 78 { 79 } 80 return null; 81 } 82 83 @Override initOptions()84 protected void initOptions() { 85 vwrOptions.remove("debug"); 86 vwrOptions.put("fullName", fullName); 87 haveDocumentAccess = "true".equalsIgnoreCase("" 88 + getValue("allowjavascript", "true")); 89 mayScript = true; 90 } 91 92 @Override getJmolParameter(String paramName)93 protected String getJmolParameter(String paramName) { 94 Object o = htParams.get(paramName.toLowerCase()); 95 return (o == null ? null : "" + o); 96 } 97 98 @Override doSendJsTextStatus(String message)99 protected void doSendJsTextStatus(String message) { 100 System.out.println(message); 101 // not implemented 102 } 103 104 @Override doSendJsTextareaStatus(String message)105 protected void doSendJsTextareaStatus(String message) { 106 System.out.println(message); 107 // not implemented 108 } 109 110 @Override doFunctionXY(String functionName, int nX, int nY)111 protected float[][] doFunctionXY(String functionName, int nX, int nY) { 112 /*three options: 113 * 114 * nX > 0 and nY > 0 return one at a time, with (slow) individual function calls 115 * nX < 0 and nY > 0 return a string that can be parsed to give the list of values 116 * nX < 0 and nY < 0 fill the supplied float[-nX][-nY] array directly in JavaScript 117 * 118 */ 119 120 //System.out.println("functionXY" + nX + " " + nY + " " + functionName); 121 float[][] fxy = new float[Math.abs(nX)][Math.abs(nY)]; 122 if (!mayScript || !haveDocumentAccess || nX == 0 || nY == 0) 123 return fxy; 124 try { 125 if (nX > 0 && nY > 0) { // fill with individual function calls (slow) 126 for (int i = 0; i < nX; i++) 127 for (int j = 0; j < nY; j++) { 128 /** 129 * @j2sNative 130 * 131 * fxy[i][j] = window.eval(functionName)(this.htmlName, i, j); 132 */ 133 { 134 } 135 } 136 } else if (nY > 0) { // fill with parsed values from a string (pretty fast) 137 String data; 138 /** 139 * @j2sNative 140 * 141 * data = window.eval(functionName)(this.htmlName, nX, nY); 142 * 143 */ 144 { 145 data = ""; 146 } 147 nX = Math.abs(nX); 148 float[] fdata = new float[nX * nY]; 149 Parser.parseStringInfestedFloatArray(data, null, fdata); 150 for (int i = 0, ipt = 0; i < nX; i++) { 151 for (int j = 0; j < nY; j++, ipt++) { 152 fxy[i][j] = fdata[ipt]; 153 } 154 } 155 } else { // fill float[][] directly using JavaScript 156 /** 157 * @j2sNative 158 * 159 * data = window.eval(functionName)(this.htmlName, nX, nY, fxy); 160 * 161 */ 162 { 163 System.out.println(functionName); 164 } 165 } 166 } catch (Exception e) { 167 Logger.error("Exception " + e + " with nX, nY: " + nX + " " + nY); 168 } 169 // for (int i = 0; i < nX; i++) 170 // for (int j = 0; j < nY; j++) 171 //System.out.println("i j fxy " + i + " " + j + " " + fxy[i][j]); 172 return fxy; 173 } 174 175 @Override doFunctionXYZ(String functionName, int nX, int nY, int nZ)176 protected float[][][] doFunctionXYZ(String functionName, int nX, int nY, 177 int nZ) { 178 float[][][] fxyz = new float[Math.abs(nX)][Math.abs(nY)][Math.abs(nZ)]; 179 if (!mayScript || !haveDocumentAccess || nX == 0 || nY == 0 || nZ == 0) 180 return fxyz; 181 try { 182 /** 183 * @j2sNative 184 * 185 * window.eval(functionName)(this.htmlName, nX, nY, nZ, fxyz); 186 * 187 */ 188 { 189 } 190 } catch (Exception e) { 191 Logger.error("Exception " + e + " for " + functionName 192 + " with nX, nY, nZ: " + nX + " " + nY + " " + nZ); 193 } 194 // for (int i = 0; i < nX; i++) 195 // for (int j = 0; j < nY; j++) 196 // for (int k = 0; k < nZ; k++) 197 //System.out.println("i j k fxyz " + i + " " + j + " " + k + " " + fxyz[i][j][k]); 198 return fxyz; 199 } 200 201 @Override doShowDocument(URL url)202 protected void doShowDocument(URL url) { 203 String[] surl = PT.split(url.toString(), "?POST?"); 204 if (surl.length == 1) { 205 /** 206 * @j2sNative 207 * 208 * window.open(surl[0]); 209 * 210 */ 211 {} 212 return; 213 } 214 215 String f = "<form id=f method=POST action='" + surl[0] + "'>"; 216 f += "<input type='hidden' name='name' value='nmr-1h-prediction' id='name'>"; 217 f += "<input type='submit' value='working...'>"; 218 String[] fields = surl[1].split("&"); 219 for (int i = 0; i < fields.length; i++) { 220 String field = fields[i]; 221 int pt = field.indexOf("="); 222 String name = field.substring(0, pt); 223 String value = field.substring(pt); 224 if (value.indexOf("\n") >= 0) { 225 f +="<textarea style='display:none' name=" + name + ">" + value +"</textarea>"; 226 } else { 227 f +="<input type=hidden name=" + name + " value=\""+ value +"\">"; 228 } 229 } 230 f += "</form>"; 231 /** 232 * @j2sNative 233 * var w=window.open("");w.document.write(f);w.document.getElementById("f").submit(); 234 * 235 */ 236 { 237 System.out.println(f + url); 238 } 239 } 240 241 @Override doSendCallback(String callback, Object[] data, String strInfo)242 protected String doSendCallback(String callback, Object[] data, String strInfo) { 243 if (callback == null || callback.length() == 0) { 244 } else if (callback.equals("alert")) { 245 /** 246 * @j2sNative alert(strInfo); return ""; 247 */ 248 { 249 System.out.println(strInfo); 250 } 251 } else { 252 String[] tokens = PT.split(callback, "."); 253 /** 254 * @j2sNative 255 * 256 * try{ 257 * var o = window[tokens[0]]; 258 * for (var i = 1; i < tokens.length; i++) 259 * o = o[tokens[i]]; 260 * for (var i = 0; i < data.length; i++) 261 * data[i] && data[i].booleanValue && (data[i] = data[i].booleanValue()); 262 * return o.apply(null,data) 263 * } catch (e) { System.out.println(callback + " failed " + e); } 264 */ 265 { 266 System.out.println(tokens + " " + data); 267 } 268 } 269 return ""; 270 } 271 272 /** 273 * return RAW JAVASCRIPT OBJECT, NOT A STRING 274 */ 275 @Override doEval(String strEval)276 protected String doEval(String strEval) { 277 try { 278 /** 279 * 280 * @j2sNative 281 * 282 * return window.eval(strEval); 283 */ 284 { 285 } 286 } catch (Exception e) { 287 Logger.error("# error evaluating " + strEval + ":" + e.toString()); 288 } 289 return ""; 290 } 291 292 @Override doShowStatus(String message)293 protected void doShowStatus(String message) { 294 try { 295 System.out.println(message); 296 } catch (Exception e) { 297 //ignore if page is closing 298 } 299 } 300 301 /** 302 * This method is only called by JmolGLmol applet._refresh(); 303 * 304 * @return enough data to update a WebGL view 305 * 306 */ getGLmolView()307 public Object getGLmolView() { 308 return viewer.getGLmolView(); 309 } 310 311 /** 312 * possibly called from JSmolApplet.js upon start up 313 * 314 * @param fileName 315 * @return error or null 316 */ 317 openFile(String fileName)318 public String openFile(String fileName) { 319 return viewer.openFile(fileName); 320 } 321 322 // JSInterface -- methods called from JSmol JavaScript library 323 324 @Override cacheFileByName(String fileName, boolean isAdd)325 public int cacheFileByName(String fileName, boolean isAdd) { 326 return viewer.cacheFileByName(fileName, isAdd); 327 } 328 329 @Override cachePut(String key, Object data)330 public void cachePut(String key, Object data) { 331 viewer.cachePut(key, data); 332 } 333 334 @Override getFullName()335 public String getFullName() { 336 return fullName; 337 } 338 339 @Override processMouseEvent(int id, int x, int y, int modifiers, long time)340 public boolean processMouseEvent(int id, int x, int y, int modifiers, 341 long time) { 342 return viewer.processMouseEvent(id, x, y, modifiers, time); 343 } 344 345 @Override setDisplay(Object canvas)346 public void setDisplay(Object canvas) { 347 viewer.setDisplay(canvas); 348 } 349 350 @Override setStatusDragDropped(int mode, int x, int y, String fileName)351 public boolean setStatusDragDropped(int mode, int x, int y, String fileName) { 352 return viewer.setStatusDragDropped(mode, x, y, fileName); 353 } 354 355 @Override startHoverWatcher(boolean enable)356 public void startHoverWatcher(boolean enable) { 357 viewer.startHoverWatcher(enable); 358 } 359 360 @Override update()361 public void update() { 362 viewer.updateJS(); 363 } 364 365 @Override openFileAsyncSpecial(String fileName, int flags)366 public void openFileAsyncSpecial(String fileName, int flags) { 367 viewer.openFileAsyncSpecial(fileName, flags); 368 } 369 370 @Override processTwoPointGesture(float[][][] touches)371 public void processTwoPointGesture(float[][][] touches) { 372 viewer.processTwoPointGesture(touches); 373 } 374 375 @Override setScreenDimension(int width, int height)376 public void setScreenDimension(int width, int height) { 377 viewer.setScreenDimension(width, height); 378 } 379 380 @Override resizeInnerPanel(String data)381 public int[] resizeInnerPanel(String data) { 382 float[] dims = new float[2]; 383 Parser.parseStringInfestedFloatArray(data, null, dims); 384 resizeDisplay((int) dims[0], (int) dims[1]); 385 return new int[] { (int) dims[0], (int) dims[1] }; 386 } 387 resizeDisplay(int width, int height)388 void resizeDisplay(int width, int height) { 389 JmolToJSmolInterface jmol = org.jmol.awtjs2d.Platform.Jmol(); 390 jmol.resizeApplet(viewer.html5Applet, new int[] {width, height}); 391 } 392 393 } 394