skin: added rotary widget
authorGiWoong Kim <giwoong.kim@samsung.com>
Mon, 22 Dec 2014 11:47:56 +0000 (20:47 +0900)
committerGiWoong Kim <giwoong.kim@samsung.com>
Mon, 29 Dec 2014 05:46:54 +0000 (14:46 +0900)
Change-Id: I2049347fadc2e2665ca56aacde3de1a28d0346cb
Signed-off-by: GiWoong Kim <giwoong.kim@samsung.com>
tizen/src/skin/client/src/org/tizen/emulator/skin/EmulatorSkin.java
tizen/src/skin/client/src/org/tizen/emulator/skin/layout/ProfileRotarySkinComposer.java [new file with mode: 0644]
tizen/src/skin/client/src/org/tizen/emulator/skin/layout/ProfileSpecificSkinComposer.java
tizen/src/skin/client/src/org/tizen/emulator/skin/layout/Rotary.java [new file with mode: 0644]
tizen/src/skin/client/src/org/tizen/emulator/skin/util/SkinUtil.java

index c9e49e5be6a10a80aaf9ad381091565c7ba14963..691a808f44d4c2f232325a17bc0ec29bb1197b31 100755 (executable)
@@ -100,6 +100,7 @@ import org.tizen.emulator.skin.info.EmulatorSkinState;
 import org.tizen.emulator.skin.info.SkinInformation;
 import org.tizen.emulator.skin.layout.GeneralPurposeSkinComposer;
 import org.tizen.emulator.skin.layout.ISkinComposer;
+import org.tizen.emulator.skin.layout.ProfileRotarySkinComposer;
 import org.tizen.emulator.skin.layout.ProfileSpecificSkinComposer;
 import org.tizen.emulator.skin.layout.rotation.Rotation;
 import org.tizen.emulator.skin.layout.rotation.SkinRotations;
@@ -109,6 +110,7 @@ import org.tizen.emulator.skin.menu.PopupMenu;
 import org.tizen.emulator.skin.screenshot.ScreenShotDialog;
 import org.tizen.emulator.skin.util.IOUtil;
 import org.tizen.emulator.skin.util.SkinUtil;
+import org.tizen.emulator.skin.util.StringUtil;
 import org.tizen.emulator.skin.util.SwtUtil;
 
 /**
@@ -272,7 +274,14 @@ public class EmulatorSkin {
 
                /* build a skin layout */
                if (skinInfo.isGeneralPurposeSkin() == false) {
-                       skinComposer = new ProfileSpecificSkinComposer(config, this);
+                       if (StringUtil.nvl(config.getDbiContents().getLayer())
+                                       .compareToIgnoreCase("rotary") == 0) {
+                               logger.info("profile rotary skin");
+
+                               skinComposer = new ProfileRotarySkinComposer(config, this);
+                       } else {
+                               skinComposer = new ProfileSpecificSkinComposer(config, this);
+                       }
                } else { /* general purpose skin */
                        skinComposer = new GeneralPurposeSkinComposer(config, this);
                }
diff --git a/tizen/src/skin/client/src/org/tizen/emulator/skin/layout/ProfileRotarySkinComposer.java b/tizen/src/skin/client/src/org/tizen/emulator/skin/layout/ProfileRotarySkinComposer.java
new file mode 100644 (file)
index 0000000..630f82b
--- /dev/null
@@ -0,0 +1,96 @@
+/**
+ * Profile Rotary Skin Layout
+ *
+ * Copyright (C) 2011 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * SangHo Park <sangho1206.park@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+package org.tizen.emulator.skin.layout;
+
+import java.util.logging.Logger;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.graphics.Region;
+import org.tizen.emulator.skin.EmulatorSkin;
+import org.tizen.emulator.skin.config.EmulatorConfig;
+import org.tizen.emulator.skin.log.SkinLogger;
+import org.tizen.emulator.skin.util.SkinUtil;
+
+public class ProfileRotarySkinComposer extends ProfileSpecificSkinComposer {
+       private Logger logger = SkinLogger.getSkinLogger(
+                       ProfileRotarySkinComposer.class).getLogger();
+
+       protected Rotary rotary;
+
+       public ProfileRotarySkinComposer(
+                       EmulatorConfig config, EmulatorSkin skin) {
+               super(config, skin);
+
+               rotary = new Rotary(shell, SWT.DOUBLE_BUFFERED, imageRegistry);
+       }
+
+       @Override
+       public void arrangeSkin(int scale, short rotationId) {
+               super.arrangeSkin(scale, rotationId);
+
+               rotary.arrange(scale, rotationId);
+
+               shell.getDisplay().syncExec(new Runnable() {
+                       @Override
+                       public void run() {
+                               logger.info("arrange a rotary");
+
+                               Image rotaryImage = rotary.getImage();
+                               if (rotaryImage != null) {
+                                       final int rotaryW = rotaryImage.getImageData().width;
+                                       final int rotaryH = rotaryImage.getImageData().height;
+
+                                       /* calculate rotary bounds */
+                                       Rectangle displayBounds = currentState.getDisplayBounds();
+                                       final int offsetX = (rotaryW - displayBounds.width) / 2;
+                                       final int offsetY = (rotaryH - displayBounds.height) / 2;
+                                       rotary.setBounds(
+                                                       displayBounds.x - offsetX, displayBounds.y - offsetY,
+                                                       rotaryW, rotaryH);
+
+                                       /* make rotary region */
+                                       Region rotaryRegion = SkinUtil.getTrimmedRegion(rotaryImage);
+                                       Region displayRegion = lcdCanvas.getRegion();
+                                       displayRegion.translate(offsetX, offsetY);
+                                       rotaryRegion.subtract(displayRegion);
+                                       displayRegion.translate(-offsetX, -offsetY);
+
+                                       rotary.setRegion(rotaryRegion);
+                               } else {
+                                       logger.warning("undefined rotary");
+
+                                       rotary.setBounds(0, 0, 0, 0);
+                                       rotary.setRegion(null);
+                               }
+                       }
+               });
+       }
+}
index 226e5b75054043e9351b9d623b7f34fea0b1d9a3..2266bf3f4d944ae6f51fda2a506031c9da68591f 100644 (file)
@@ -75,19 +75,19 @@ public class ProfileSpecificSkinComposer implements ISkinComposer {
        private Logger logger = SkinLogger.getSkinLogger(
                        ProfileSpecificSkinComposer.class).getLogger();
 
-       private EmulatorConfig config;
-       private EmulatorSkin skin;
-       private Shell shell;
-       private Canvas lcdCanvas;
-       private EmulatorSkinState currentState;
-       private SocketCommunicator communicator;
+       protected EmulatorConfig config;
+       protected EmulatorSkin skin;
+       protected Shell shell;
+       protected Canvas lcdCanvas;
+       protected EmulatorSkinState currentState;
+       protected SocketCommunicator communicator;
 
        private PaintListener shellPaintListener;
        private MouseTrackListener shellMouseTrackListener;
        private MouseMoveListener shellMouseMoveListener;
        private MouseListener shellMouseListener;
 
-       private ProfileSkinImageRegistry imageRegistry;
+       protected ProfileSkinImageRegistry imageRegistry;
        private HWKey currentPressedHWKey;
        private HWKey currentHoveredHWKey;
 
@@ -109,6 +109,7 @@ public class ProfileSpecificSkinComposer implements ISkinComposer {
        @Override
        public Canvas compose(int style) {
                lcdCanvas = new Canvas(shell, style);
+               lcdCanvas.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK));
 
                int x = config.getValidWindowX();
                int y = config.getValidWindowY();
diff --git a/tizen/src/skin/client/src/org/tizen/emulator/skin/layout/Rotary.java b/tizen/src/skin/client/src/org/tizen/emulator/skin/layout/Rotary.java
new file mode 100644 (file)
index 0000000..38f4d89
--- /dev/null
@@ -0,0 +1,179 @@
+/**
+ * Rotary
+ *
+ * Copyright (C) 2011 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * SangHo Park <sangho1206.park@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+package org.tizen.emulator.skin.layout;
+
+import java.util.logging.Logger;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Transform;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Shell;
+import org.tizen.emulator.skin.image.ProfileSkinImageRegistry;
+import org.tizen.emulator.skin.image.ProfileSkinImageRegistry.SkinImageType;
+import org.tizen.emulator.skin.log.SkinLogger;
+import org.tizen.emulator.skin.util.SkinUtil;
+
+public class Rotary extends Canvas {
+       private Logger logger = SkinLogger.getSkinLogger(Rotary.class).getLogger();
+
+       private Shell parent;
+       private ProfileSkinImageRegistry imageRegistry;
+       private Image image;
+       private int degrees; /* absolute */
+       private int angleDelta;
+       private Point grabPosition;
+
+       /**
+        *  Constructor
+        */
+       Rotary(final Shell parent, int style, ProfileSkinImageRegistry imageRegistry) {
+               super(parent, style);
+
+               this.parent = parent;
+               this.imageRegistry = imageRegistry;
+               this.image = null;
+               this.degrees = 0;
+               this.angleDelta = 0;
+               this.grabPosition = new Point(-1, -1);
+
+               addListeners();
+
+               setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_BLACK));
+       }
+
+       public Image getImage() {
+               return image;
+       }
+
+       public int getDegrees() {
+               return degrees;
+       }
+
+       public void arrange(final int scale, final short rotationId) {
+               logger.info("scale : " + scale + ", rotate : " + rotationId);
+
+               parent.getDisplay().syncExec(new Runnable() {
+                       @Override
+                       public void run() {
+                               if (image != null) {
+                                       image.dispose();
+                                       image = null;
+                               }
+
+                               Image imageRotary = imageRegistry.getSkinImage(
+                                               rotationId, SkinImageType.DISPLAY_ROTARY_IMAGE);
+                               if (imageRotary != null) {
+                                       image = SkinUtil.createScaledImage(
+                                                       parent.getDisplay(), imageRotary, rotationId, scale);
+                               }
+
+                               redraw();
+                       }
+               });
+       }
+
+       private void addListeners() {
+               /* rendering */
+               this.addPaintListener(new PaintListener() {
+                       @Override
+                       public void paintControl(PaintEvent e) {
+                               if (image != null) {
+                                       final int imageHalfW = getImage().getImageData().width / 2;
+                                       final int imageHalfH = getImage().getImageData().height / 2;
+
+                                       Transform transform = new Transform(parent.getDisplay());
+                                       transform.translate(imageHalfW, imageHalfH);
+                                       transform.rotate(degrees);
+                                       e.gc.setTransform(transform);
+
+                                       e.gc.drawImage(getImage(), -imageHalfW, -imageHalfH);
+
+                                       transform.dispose();
+                               }
+                       }
+               });
+
+               /* controlling */
+               this.addMouseMoveListener(new MouseMoveListener() {
+                       @Override
+                       public void mouseMove(MouseEvent e) {
+                               if (grabPosition.x >= 0 && grabPosition.y >= 0 &&
+                                               e.button == 0/* left button */) {
+                                       final int angle = SkinUtil.getAngleFromVector(Rotary.this, e.x, e.y);
+                                       int delta = angle - angleDelta;
+                                       degrees += delta;
+
+                                       if (delta != 0) {
+                                               if (delta < -180) { /* 359 -> 0 */
+                                                       delta += 360;
+                                               } else if (delta > 180) { /* 0 -> 359 */
+                                                       delta -= 360;
+                                               }
+
+                                               // TODO: send to qemu
+                                               logger.info("rotary : " + delta);
+
+                                               redraw();
+                                       }
+
+                                       angleDelta = angle;
+                               }
+                       }
+               });
+
+               this.addMouseListener(new MouseListener() {
+                       public void mouseDown(MouseEvent e) {
+                               if (1 == e.button) { /* left button */
+                                       grabPosition.x = e.x;
+                                       grabPosition.y = e.y;
+                                       angleDelta = SkinUtil.getAngleFromVector(Rotary.this, e.x, e.y);
+                               }
+                       }
+
+                       public void mouseUp(MouseEvent e) {
+                               if (e.button == 1) { /* left button */
+                                       grabPosition.x = -1;
+                                       grabPosition.y = -1;
+                                       angleDelta = 0;
+                               }
+                       }
+
+                       public void mouseDoubleClick(MouseEvent e) {
+                               /* do nothing */
+                       }
+               });
+       }
+}
\ No newline at end of file
index 8cce8a619e085503116eda00cf2511f12f952778..4868210c215e17d586e047d9390aaa13b5a389e0 100644 (file)
@@ -47,6 +47,7 @@ import org.eclipse.swt.graphics.ImageData;
 import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.graphics.Region;
+import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.MessageBox;
 import org.eclipse.swt.widgets.Shell;
@@ -1071,4 +1072,9 @@ public class SkinUtil {
                logger.info("32bit architecture : " + System.getProperty("os.arch"));
                return setTopMost32(shell, isOnTop); /* 32bit */
        }
+
+       public static int getAngleFromVector(Control con, int x, int y) {
+               return (int)Math.toDegrees(
+                               Math.atan2(y - (con.getSize().y / 2), x - (con.getSize().x / 2)));
+       }
 }