1 package jspecview.js2d; 2 3 import java.io.BufferedInputStream; 4 import java.net.URL; 5 import java.util.Map; 6 7 import javax.swing.JOptionPane; 8 9 import org.jmol.api.GenericFileInterface; 10 import org.jmol.api.GenericImageDialog; 11 import org.jmol.api.GenericMenuInterface; 12 import org.jmol.api.GenericMouseInterface; 13 import org.jmol.api.GenericPlatform; 14 import org.jmol.api.JmolInChI; 15 import org.jmol.api.PlatformViewer; 16 17 import org.jmol.util.Font; 18 19 import javajs.util.P3; 20 import javajs.util.AjaxURLStreamHandlerFactory; 21 import javajs.util.Rdr; 22 import javajs.util.SB; 23 24 import jspecview.api.JSVPanel; 25 import jspecview.app.GenericMouse; 26 27 28 29 /** 30 * JavaScript 2D canvas version requires Ajax-based URL stream processing. 31 * 32 * Jmol "display" --> HTML5 "canvas" 33 * Jmol "image" --> HTML5 "canvas" (because we need width and height) 34 * Jmol "graphics" --> HTML5 "context(2d)" (one for display, one off-screen for fonts) 35 * Jmol "font" --> JmolFont 36 * Jmol "fontMetrics" --> HTML5 "context(2d)" 37 * (Not fully implemented) 38 * 39 * @author Bob Hanson 40 * 41 */ 42 public class JsPlatform implements GenericPlatform { 43 Object canvas; 44 PlatformViewer viewer; 45 Object context; 46 47 @Override setViewer(PlatformViewer viewer, Object canvas)48 public void setViewer(PlatformViewer viewer, Object canvas) { 49 Object context = ""; 50 this.viewer = viewer; 51 this.canvas = canvas; 52 /** 53 * @j2sNative 54 * 55 * if (canvas != null) { 56 * context = canvas.getContext("2d"); 57 * canvas.imgdata = context.getImageData(0, 0, canvas.width, canvas.height); 58 * canvas.buf8 = canvas.imgdata.data; 59 * } 60 */ 61 {} 62 if (context != "") 63 this.context = context; 64 // 65 try { 66 URL.setURLStreamHandlerFactory(new AjaxURLStreamHandlerFactory()); 67 } catch (Throwable e) { 68 // that's fine -- already created 69 } 70 } 71 72 @Override isSingleThreaded()73 public boolean isSingleThreaded() { 74 return true; 75 } 76 77 @Override getJsObjectInfo(Object[] jsObject, String method, Object[] args)78 public Object getJsObjectInfo(Object[] jsObject, String method, Object[] args) { 79 /** 80 * we must use Object[] here to hide [HTMLUnknownElement] and [Attribute] from Java2Script 81 * @j2sNative 82 * 83 * return (method == null ? null : method == "localName" ? jsObject[0]["nodeName"] : args == null ? jsObject[0][method] : jsObject[0][method](args[0])); 84 * 85 * 86 */ 87 { 88 return null; 89 } 90 } 91 92 @Override isHeadless()93 public boolean isHeadless() { 94 return false; 95 } 96 97 @Override getMouseManager(double privateKey, Object jsvp)98 public GenericMouseInterface getMouseManager(double privateKey, Object jsvp) { 99 return new GenericMouse((JSVPanel) jsvp); 100 } 101 102 // /// Display 103 104 @Override convertPointFromScreen(Object canvas, P3 ptTemp)105 public void convertPointFromScreen(Object canvas, P3 ptTemp) { 106 // from JmolMultiTouchClientAdapter.fixXY 107 Display.convertPointFromScreen(canvas, ptTemp); 108 } 109 110 @Override getFullScreenDimensions(Object canvas, int[] widthHeight)111 public void getFullScreenDimensions(Object canvas, int[] widthHeight) { 112 Display.getFullScreenDimensions(canvas, widthHeight); 113 } 114 115 @Override getMenuPopup(String menuStructure, char type)116 public GenericMenuInterface getMenuPopup(String menuStructure, 117 char type) { 118 return null; 119 } 120 121 @Override hasFocus(Object canvas)122 public boolean hasFocus(Object canvas) { 123 return Display.hasFocus(canvas); 124 } 125 126 @Override prompt(String label, String data, String[] list, boolean asButtons)127 public String prompt(String label, String data, String[] list, 128 boolean asButtons) { 129 return Display.prompt(label, data, list, asButtons); 130 } 131 132 /** 133 * legacy apps will use this 134 * 135 * @param context 136 * @param size 137 */ 138 @Override renderScreenImage(Object context, Object size)139 public void renderScreenImage(Object context, Object size) { 140 Display.renderScreenImage(viewer, context, size); 141 } 142 143 @Override drawImage(Object context, Object canvas, int x, int y, int width, int height, boolean isDTI)144 public void drawImage(Object context, Object canvas, int x, int y, int width, 145 int height, boolean isDTI) { 146 147 // from Viewer.render1 148 Image.drawImage(context, canvas, x, y, width, height); 149 } 150 151 @Override requestFocusInWindow(Object canvas)152 public void requestFocusInWindow(Object canvas) { 153 Display.requestFocusInWindow(canvas); 154 } 155 156 @Override repaint(Object canvas)157 public void repaint(Object canvas) { 158 Display.repaint(canvas); 159 } 160 161 @Override setTransparentCursor(Object canvas)162 public void setTransparentCursor(Object canvas) { 163 Display.setTransparentCursor(canvas); 164 } 165 166 @Override setCursor(int c, Object canvas)167 public void setCursor(int c, Object canvas) { 168 Display.setCursor(c, canvas); 169 } 170 171 // //// Image 172 173 @Override allocateRgbImage(int windowWidth, int windowHeight, int[] pBuffer, int windowSize, boolean backgroundTransparent, boolean isImageWrite)174 public Object allocateRgbImage(int windowWidth, int windowHeight, 175 int[] pBuffer, int windowSize, boolean backgroundTransparent, boolean isImageWrite) { 176 return Image.allocateRgbImage(windowWidth, windowHeight, pBuffer, 177 windowSize, backgroundTransparent, (isImageWrite ? null : canvas)); 178 } 179 180 @Override notifyEndOfRendering()181 public void notifyEndOfRendering() { 182 } 183 184 /** 185 * could be byte[] (from ZIP file) or String (local file name) or URL 186 * @param data 187 * @return image object 188 * 189 */ 190 @Override createImage(Object data)191 public Object createImage(Object data) { 192 // N/A in JS 193 return null; 194 } 195 196 @Override disposeGraphics(Object gOffscreen)197 public void disposeGraphics(Object gOffscreen) { 198 // N/A 199 } 200 201 @Override grabPixels(Object canvas, int width, int height, int[] pixels, int startRow, int nRows)202 public int[] grabPixels(Object canvas, int width, int height, 203 int[] pixels, int startRow, int nRows) { 204 // from PNG and JPG image creators, also g3d.ImageRenderer.plotImage via drawImageToBuffer 205 206 /** 207 * 208 * (might be just an object with buf32 defined -- WRITE IMAGE) 209 * 210 * @j2sNative 211 * 212 * if (canvas.image && (width != canvas.width || height != canvas.height)) 213 * Jmol._setCanvasImage(canvas, width, height); 214 * if (canvas.buf32) return canvas.buf32; 215 */ 216 {} 217 int[] buf = Image.grabPixels(Image.getGraphics(canvas), width, height); 218 /** 219 * @j2sNative 220 * 221 * canvas.buf32 = buf; 222 * 223 */ 224 {} 225 return buf; 226 } 227 228 @Override drawImageToBuffer(Object gOffscreen, Object imageOffscreen, Object canvas, int width, int height, int bgcolor)229 public int[] drawImageToBuffer(Object gOffscreen, Object imageOffscreen, 230 Object canvas, int width, int height, int bgcolor) { 231 return grabPixels(canvas, width, height, null, 0, 0); 232 } 233 234 @Override getTextPixels(String text, Font font3d, Object context, Object image, int width, int height, int ascent)235 public int[] getTextPixels(String text, Font font3d, Object context, 236 Object image, int width, int height, int ascent) { 237 return Image.getTextPixels(text, font3d, context, width, height, ascent); 238 } 239 240 @Override flushImage(Object imagePixelBuffer)241 public void flushImage(Object imagePixelBuffer) { 242 // N/A 243 } 244 245 @Override getGraphics(Object canvas)246 public Object getGraphics(Object canvas) { 247 return (canvas == null ? context : (context = Image.getGraphics(this.canvas = canvas))); 248 } 249 250 @Override getImageHeight(Object canvas)251 public int getImageHeight(Object canvas) { 252 return (canvas == null ? -1 : Image.getHeight(canvas)); 253 } 254 255 @Override getImageWidth(Object canvas)256 public int getImageWidth(Object canvas) { 257 return (canvas == null ? -1 : Image.getWidth(canvas)); 258 } 259 260 @Override getStaticGraphics(Object image, boolean backgroundTransparent)261 public Object getStaticGraphics(Object image, boolean backgroundTransparent) { 262 return Image.getStaticGraphics(image, backgroundTransparent); 263 } 264 265 @Override newBufferedImage(Object image, int w, int h)266 public Object newBufferedImage(Object image, int w, int h) { 267 /** 268 * @j2sNative 269 * 270 * if (self.Jmol && Jmol._getHiddenCanvas) 271 * return Jmol._getHiddenCanvas(this.vwr.html5Applet, "stereoImage", w, h); 272 */ 273 {} 274 return null; 275 } 276 277 @Override newOffScreenImage(int w, int h)278 public Object newOffScreenImage(int w, int h) { 279 /** 280 * @j2sNative 281 * 282 * if (self.Jmol && Jmol._getHiddenCanvas) 283 * return Jmol._getHiddenCanvas(this.vwr.html5Applet, "textImage", w, h); 284 */ 285 {} 286 return null; 287 } 288 289 @Override waitForDisplay(Object echoNameAndPath, Object zipBytes)290 public boolean waitForDisplay(Object echoNameAndPath, Object zipBytes) 291 throws InterruptedException { 292 // not implmented in JSpecView 293 return false; 294 } 295 296 // /// FONT 297 298 @Override fontStringWidth(Font font, String text)299 public int fontStringWidth(Font font, String text) { 300 return JsFont.stringWidth(font, text); 301 } 302 303 @Override getFontAscent(Object context)304 public int getFontAscent(Object context) { 305 return JsFont.getAscent(context); 306 } 307 308 @Override getFontDescent(Object context)309 public int getFontDescent(Object context) { 310 return JsFont.getDescent(context); 311 } 312 313 @Override getFontMetrics(Font font, Object context)314 public Object getFontMetrics(Font font, Object context) { 315 return JsFont.getFontMetrics(font, context); 316 } 317 318 @Override newFont(String fontFace, boolean isBold, boolean isItalic, float fontSize)319 public Object newFont(String fontFace, boolean isBold, boolean isItalic, 320 float fontSize) { 321 return JsFont.newFont(fontFace, isBold, isItalic, fontSize, "px"); 322 } 323 324 @Override getDateFormat(String isoType)325 public String getDateFormat(String isoType) { 326 /** 327 * 328 * Mon Jan 07 2013 19:54:39 GMT-0600 (Central Standard Time) 329 * or YYYYMMDDHHmmssOHH'mm' 330 * 331 * @j2sNative 332 * 333 * if (isoType == null) { 334 * } else if (isoType.indexOf("8824") >= 0) { 335 * var d = new Date(); 336 * var x = d.toString().split(" "); 337 * var MM = "0" + d.getMonth(); MM = MM.substring(MM.length - 2); 338 * var dd = "0" + d.getDate(); dd = dd.substring(dd.length - 2); 339 * return x[3] + MM + dd + x[4].replace(/\:/g,"") + x[5].substring(3,6) + "'" + x[5].substring(6,8) + "'" 340 * } else if (isoType.indexOf("8601") >= 0){ 341 * var d = new Date(); 342 * var x = d.toString().split(" "); 343 * var MM = "0" + d.getMonth(); MM = MM.substring(MM.length - 2); 344 * var dd = "0" + d.getDate(); dd = dd.substring(dd.length - 2); 345 * return x[3] + MM + dd + x[4].replace(/\:/g,"") + x[5].substring(3,6) + "'" + x[5].substring(6,8) + "'" 346 * } 347 * return ("" + (new Date())).split(" (")[0]; 348 */ 349 { 350 return null; 351 } 352 } 353 354 @Override newFile(String name)355 public GenericFileInterface newFile(String name) { 356 return new JsFile(name); 357 } 358 359 @Override getBufferedFileInputStream(String name)360 public Object getBufferedFileInputStream(String name) { 361 // n/a for any applet 362 return null; 363 } 364 365 @Override getURLContents(URL url, byte[] outputBytes, String post, boolean asString)366 public Object getURLContents(URL url, byte[] outputBytes, String post, 367 boolean asString) { 368 Object ret = JsFile.getURLContents(url, outputBytes, post); 369 // check for error 370 try { 371 return (!asString ? ret : ret instanceof String ? ret : ret instanceof SB ? ((SB) ret) 372 .toString() : ret instanceof byte[] ? new String((byte[]) ret) 373 : new String((byte[]) Rdr.getStreamAsBytes((BufferedInputStream) ret, 374 null))); 375 } catch (Exception e) { 376 return "" + e; 377 } 378 } 379 380 @Override getLocalUrl(String fileName)381 public String getLocalUrl(String fileName) { 382 // not used in JSpecView 383 return null; 384 } 385 386 @Override getImageDialog(String title, Map<String, GenericImageDialog> imageMap)387 public GenericImageDialog getImageDialog(String title, 388 Map<String, GenericImageDialog> imageMap) { 389 // TODO Auto-generated method stub 390 return null; 391 } 392 393 @Override forceAsyncLoad(String filename)394 public boolean forceAsyncLoad(String filename) { 395 // TODO Auto-generated method stub 396 return false; 397 } 398 399 @Override getInChI()400 public JmolInChI getInChI() { 401 // TODO 402 return null; 403 } 404 405 @Override confirm(String msg, String msgNo)406 public int confirm(String msg, String msgNo) { 407 boolean ok = /** @j2sNative confirm(msg) || */false; 408 if (ok) 409 return JOptionPane.OK_OPTION; 410 if (msgNo != null) 411 ok = /** @j2sNative confirm(msgNo) || */false; 412 return (ok ? JOptionPane.NO_OPTION : JOptionPane.CANCEL_OPTION); 413 } 414 415 416 } 417