=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/AbstractGuiDriver.java' --- src/com/goldencode/p2j/ui/client/gui/driver/AbstractGuiDriver.java 2015-08-28 13:58:40 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/AbstractGuiDriver.java 2015-09-01 12:37:18 +0000 @@ -24,6 +24,7 @@ ** 007 GES 20150817 Removed isOnTop() since it is unnecessary. Added an abstract method for ** window restacking. Editable and Movable actions are moved at the driver level. ** deriveFont() now is driver specific - it scales the font depending on the DPI. +** Implemented setIcon(). */ package com.goldencode.p2j.ui.client.gui.driver; @@ -1004,6 +1005,28 @@ } /** + * Sets the image to the window to be displayed as the window icon representation + * for the system task bar, the title window panel or the system tray icons panel. + * + * @param icon + * The wrapped icon. + * @param width + * the icon width. + * @param height + * the icon height. + */ + @Override + public void setIcon(ImageWrapper icon, int width, int height) + { + PaintStructure ps = new PaintStructure(PaintPrimitives.SET_ICON); + ps.img = icon; + ps.width = width; + ps.height = height; + + ews.offer(ps); + } + + /** * Set current font used on draw operations. * * @param font === modified file 'src/com/goldencode/p2j/ui/client/gui/driver/GuiDriver.java' --- src/com/goldencode/p2j/ui/client/gui/driver/GuiDriver.java 2015-08-26 22:14:27 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/GuiDriver.java 2015-09-01 12:46:23 +0000 @@ -54,7 +54,7 @@ ** 030 GES 20150730 Removed translatedOrigin() since it isn't actually used.translate() was ** converted to translatePush()/translatePop() to make it clear that they need ** to have matched pairs. -** 031 GES 20150817 Removed isOnTop() since it is unnecessary. +** 031 GES 20150817 Removed isOnTop() since it is unnecessary, added setIcon(). */ package com.goldencode.p2j.ui.client.gui.driver; @@ -957,4 +957,17 @@ * Register all the mouse-aware widgets (in all Windows) with the driver. */ public void registerMouseWidgets(); + + /** + * Sets the image to the window to be displayed as the window icon representation + * for the system task bar, the title window panel or the system tray icons panel. + * + * @param icon + * The wrapped icon. + * @param width + * the icon width. + * @param height + * the icon height. + */ + public void setIcon(ImageWrapper icon, int width, int height); } === modified file 'src/com/goldencode/p2j/ui/client/gui/driver/PaintPrimitives.java' --- src/com/goldencode/p2j/ui/client/gui/driver/PaintPrimitives.java 2015-08-26 22:14:27 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/PaintPrimitives.java 2015-09-01 12:38:06 +0000 @@ -20,7 +20,7 @@ ** 009 CA 20150408 Added SET_TITLE. ** 010 GES 20150422 Moved this class to a more generic location (not specific to Swing). ** 011 HC 20150612 Implemented support for paragraph layout. -** 012 GES 20150720 Added a warning about future modifications. +** 012 GES 20150720 Added a warning about future modifications, added SET_ICON. */ package com.goldencode.p2j.ui.client.gui.driver; @@ -69,5 +69,6 @@ CLEAR_HIGHLIGHT, START_BATCH, END_BATCH, - SET_TITLE; + SET_TITLE, + SET_ICON; } === modified file 'src/com/goldencode/p2j/ui/client/gui/driver/swing/SwingEmulatedWindow.java' --- src/com/goldencode/p2j/ui/client/gui/driver/swing/SwingEmulatedWindow.java 2015-08-31 20:45:55 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/swing/SwingEmulatedWindow.java 2015-09-01 12:42:06 +0000 @@ -59,6 +59,7 @@ ** 030 GES 20150817 Removed isOnTop() since it is unnecessary. The saveFocusListeners(), ** restoreFocusListeners() and moveToTop() are only needed for Swing usage and ** are now just local helper methods. Added custom Swing mouse handler. +** Implemented SET_ICON drawing primitive. */ package com.goldencode.p2j.ui.client.gui.driver.swing; @@ -831,6 +832,10 @@ { ((JDialog) window).setTitle(ps.title); } + break; + case SET_ICON: + window.setIconImage(ps.img.getImage()); + break; default: break; } === modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebEmulatedWindow.java' --- src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebEmulatedWindow.java 2015-08-31 20:45:55 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebEmulatedWindow.java 2015-09-01 12:45:11 +0000 @@ -19,7 +19,8 @@ ** restoreFocusListeners() and moveToTop() are only needed for Swing usage and ** have been removed from this class, added line strokes. ** Added captureMouseEvents to enable mouse support. -** Improvements for mouse support: added dedicated mouse handler. +** Improvements for mouse support: added dedicated mouse handler. Implemented +** SET_ICON drawing primitive. */ package com.goldencode.p2j.ui.client.gui.driver.web; @@ -313,25 +314,15 @@ websock.drawRoundRect(ps.x, ps.y, ps.width, ps.height, ps.arcDiameter); break; case DRAW_IMAGE: - ImageWrapper wrappedImage = drawHelper.processImage(ps); - VirtualScreen virtualScreen = webdriver.getVirtualScreen(); - int imageHash = wrappedImage.getImage().hashCode(); - ImageEncoding encoding; - byte[] encodedImage; - if (webdriver.addImageUsage(imageHash, windowId)) - { - encoding = ImageEncoding.RAW; - virtualScreen.drawImage(wrappedImage, ps.x, ps.y); - encodedImage = new RawEncoder().packToBinaries(virtualScreen, ps.x, ps.y, - wrappedImage.getWidth(), wrappedImage.getHeight()); - } - else - { - encoding = ImageEncoding.HASH; - encodedImage = null; - } - websock.drawImage(ps.x, ps.y, wrappedImage.getWidth(), wrappedImage.getHeight(), - encoding, imageHash, encodedImage); + { + ImageWrapper wrappedImage = drawHelper.processImage(ps); + Object[] imageEncodedPacket = encodeImage(ps.x, ps.y, wrappedImage); + int imageHash = (Integer) imageEncodedPacket[0]; + ImageEncoding encoding = (ImageEncoding) imageEncodedPacket[1]; + byte[] encodedImage = (byte[]) imageEncodedPacket[2]; + websock.drawImage(ps.x, ps.y, wrappedImage.getWidth(), wrappedImage.getHeight(), + encoding, imageHash, encodedImage); + } break; case FILL_RECT: websock.fillRect(ps.x, ps.y, ps.width, ps.height); @@ -409,12 +400,60 @@ websock.setWindowTitle(title); } break; + case SET_ICON: + { + ImageWrapper wrappedImage = ps.img; + Object[] imageEncodedPacket = encodeImage(0, 0, wrappedImage); + int imageHash = (Integer) imageEncodedPacket[0]; + ImageEncoding encoding = (ImageEncoding) imageEncodedPacket[1]; + byte[] encodedImage = (byte[]) imageEncodedPacket[2]; + websock.setIconImage(ps.width, ps.height, encoding, imageHash, encodedImage); + } + break; default: break; } } /** + * Encodes the image if it isn't already loaded and returns the 3-elements array that holds + * the image hash in its first element, the image encoding in its second element + * and the encoded image or null in its third element depending on its loaded state. + * + * @param x + * The x-coordinate of the target image position. + * @param y + * The y-coordinate of the target image position. + * @param wrappedImage + * The wrapped image. + * + * @return The 3-elements array that holds the image hash in its first element, + * the image encoding in its second element and the bytes array of the encoded image + * or null in its third element. + */ + private final Object[] encodeImage(int x, int y, ImageWrapper wrappedImage) + { + VirtualScreen virtualScreen = webdriver.getVirtualScreen(); + int imageHash = wrappedImage.getImage().hashCode(); + ImageEncoding encoding; + byte[] encodedImage; + if (webdriver.addImageUsage(imageHash, windowId)) + { + encoding = ImageEncoding.RAW; + virtualScreen.drawImage(wrappedImage, x, y); + encodedImage = new RawEncoder().packToBinaries(virtualScreen, x, y, + wrappedImage.getWidth(), wrappedImage.getHeight()); + } + else + { + encoding = ImageEncoding.HASH; + encodedImage = null; + } + + return new Object[] {imageHash, encoding, encodedImage}; + } + + /** * Render the given paint operation. Any graphics context or other resources needed must * have already been setup/stored by the caller. */ === modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebSocket.java' --- src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebSocket.java 2015-08-31 20:45:55 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebSocket.java 2015-09-01 12:39:14 +0000 @@ -19,6 +19,7 @@ ** specification, reuse the entry. ** Improvements for mouse support; added window activated. ** deriveFont() now is driver specific - it scales the font depending on the DPI. +** Added setIconImage(). */ package com.goldencode.p2j.ui.client.gui.driver.web; @@ -679,6 +680,43 @@ } /** + * Sets the window icon. If an image encoding is HASH, then the binary image isn't sent to + * the client. + * + * @param width + * The width of the image. + * @param height + * The height of the image. + * @param encoding + * The encoding id. + * @param imageHash + * The image hash code, its own id. + * @param encodedImage + * The encoded image represented by bytes. + */ + public void setIconImage(int width, int height, ImageEncoding encoding, int imageHash, byte[] encodedImage) + { + int msgLen = 14; + if (encoding == ImageEncoding.RAW) + { + msgLen += encodedImage.length; + } + + byte[] setIconMsg = new byte[msgLen]; + setIconMsg[0] = (byte) (PaintPrimitives.SET_ICON.ordinal()); + writeMessageInt32(setIconMsg, 1, width); + writeMessageInt32(setIconMsg, 5, height); + setIconMsg[9] = (byte) encoding.getValue(); + writeMessageInt32(setIconMsg, 10, imageHash); + if (encoding == ImageEncoding.RAW) + { + System.arraycopy(encodedImage, 0, setIconMsg, 14, encodedImage.length); + } + + addDrawingOp(setIconMsg); + } + + /** * Send all pending drawing operations to the javascript side and clear the list of pending * operations. * === modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.screen.js' --- src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.screen.js 2015-08-31 20:45:55 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.screen.js 2015-09-01 12:40:54 +0000 @@ -16,7 +16,7 @@ ** 003 GES 20150720 Total rewrite to implement a first pass at GUI support, ** added a drawing image operation. ** 004 GES 20150818 Added more GUI support including fonts, cursors, z-order, mouse events. -* Fixed many problems with the initial implementation. +* Fixed many problems with the initial implementation. Implemented SET_ICON. */ "use strict"; @@ -86,6 +86,7 @@ START_BATCH : 27, END_BATCH : 28, SET_TITLE : 29, + SET_ICON : 30, }; // reverse map the types to their property names @@ -228,6 +229,21 @@ this.trans = 0; this.clips = 0; + + /** + * Defines the window icon id. + */ + this.iconId = -1; + + /** + * Defines the window icon's width. + */ + this.iconWidth = 0; + + /** + * Defines the window icon's height. + */ + this.iconHeight = 0; }; /** @@ -1132,6 +1148,24 @@ this.title = title; // TODO: force taskbar to repaint break; + case ops.SET_ICON: + var iconWidth = p2j.socket.readInt32BinaryMessage(message, idx + 1); + var iconHeight = p2j.socket.readInt32BinaryMessage(message, idx + 5); + var encoding = message[idx + 9]; + var key = p2j.socket.readInt32BinaryMessage(message, idx + 10); + var pixelsInBytes = iconWidth * iconHeight * 4; + var imgData; + var imgDataOffset; + if(!loadedImages.has(key)) + { + imgData = message; + imgDataOffset = idx + 14; + loadedImages.set(key, message.subarray(imgDataOffset, imgDataOffset + pixelsInBytes)); + this.iconId = key; + this.iconWidth = iconWidth; + this.iconHeight = iconHeight; + } + break; default: if (typeof type !== "undefined") {