From c40dee7ab059087c07ffc5894c865aef238b1df9 Mon Sep 17 00:00:00 2001 From: GiWoong Kim Date: Mon, 22 Dec 2014 20:47:56 +0900 Subject: [PATCH] skin: added rotary widget Change-Id: I2049347fadc2e2665ca56aacde3de1a28d0346cb Signed-off-by: GiWoong Kim (cherry picked from commit a829b24beeba889efcd2033d7fe450826544bcb0) --- .../src/org/tizen/emulator/skin/EmulatorSkin.java | 11 +- .../skin/layout/ProfileRotarySkinComposer.java | 96 +++++++++++ .../skin/layout/ProfileSpecificSkinComposer.java | 2 +- .../src/org/tizen/emulator/skin/layout/Rotary.java | 179 +++++++++++++++++++++ 4 files changed, 286 insertions(+), 2 deletions(-) create mode 100644 tizen/src/skin/client/src/org/tizen/emulator/skin/layout/ProfileRotarySkinComposer.java create mode 100644 tizen/src/skin/client/src/org/tizen/emulator/skin/layout/Rotary.java diff --git a/tizen/src/skin/client/src/org/tizen/emulator/skin/EmulatorSkin.java b/tizen/src/skin/client/src/org/tizen/emulator/skin/EmulatorSkin.java index a339ae0..348eaaf 100644 --- a/tizen/src/skin/client/src/org/tizen/emulator/skin/EmulatorSkin.java +++ b/tizen/src/skin/client/src/org/tizen/emulator/skin/EmulatorSkin.java @@ -97,6 +97,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; @@ -105,6 +106,7 @@ import org.tizen.emulator.skin.menu.KeyWindowKeeper; import org.tizen.emulator.skin.menu.PopupMenu; import org.tizen.emulator.skin.screenshot.ScreenShotDialog; import org.tizen.emulator.skin.util.SkinUtil; +import org.tizen.emulator.skin.util.StringUtil; import org.tizen.emulator.skin.util.SwtUtil; /** @@ -284,7 +286,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 index 0000000..9f120c8 --- /dev/null +++ b/tizen/src/skin/client/src/org/tizen/emulator/skin/layout/ProfileRotarySkinComposer.java @@ -0,0 +1,96 @@ +/** + * Profile Rotary Skin Layout + * + * Copyright (C) 2011 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * GiWoong Kim + * SangHo Park + * + * 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 = displayCanvas.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); + } + } + }); + } +} diff --git a/tizen/src/skin/client/src/org/tizen/emulator/skin/layout/ProfileSpecificSkinComposer.java b/tizen/src/skin/client/src/org/tizen/emulator/skin/layout/ProfileSpecificSkinComposer.java index 0b69aed..9f8b78f 100644 --- a/tizen/src/skin/client/src/org/tizen/emulator/skin/layout/ProfileSpecificSkinComposer.java +++ b/tizen/src/skin/client/src/org/tizen/emulator/skin/layout/ProfileSpecificSkinComposer.java @@ -88,7 +88,7 @@ public class ProfileSpecificSkinComposer implements ISkinComposer { private MouseMoveListener shellMouseMoveListener; private MouseListener shellMouseListener; - private ProfileSkinImageRegistry imageRegistry; + protected ProfileSkinImageRegistry imageRegistry; private HWKey currentPressedHWKey; private HWKey currentHoveredHWKey; 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 index 0000000..38f4d89 --- /dev/null +++ b/tizen/src/skin/client/src/org/tizen/emulator/skin/layout/Rotary.java @@ -0,0 +1,179 @@ +/** + * Rotary + * + * Copyright (C) 2011 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * GiWoong Kim + * SangHo Park + * + * 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 -- 2.7.4