diff options
Diffstat (limited to 'src/plugins/emulator/src/com/motorola/studio/android/emulator/ui/controls/maindisplay/MainDisplayComposite.java')
-rw-r--r-- | src/plugins/emulator/src/com/motorola/studio/android/emulator/ui/controls/maindisplay/MainDisplayComposite.java | 470 |
1 files changed, 470 insertions, 0 deletions
diff --git a/src/plugins/emulator/src/com/motorola/studio/android/emulator/ui/controls/maindisplay/MainDisplayComposite.java b/src/plugins/emulator/src/com/motorola/studio/android/emulator/ui/controls/maindisplay/MainDisplayComposite.java new file mode 100644 index 0000000..c5a4561 --- /dev/null +++ b/src/plugins/emulator/src/com/motorola/studio/android/emulator/ui/controls/maindisplay/MainDisplayComposite.java @@ -0,0 +1,470 @@ +/* +* Copyright (C) 2012 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package com.motorola.studio.android.emulator.ui.controls.maindisplay; + +import static com.motorola.studio.android.common.log.StudioLogger.info; + +import java.util.Properties; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.sequoyah.vnc.vncviewer.graphics.IRemoteDisplay; +import org.eclipse.sequoyah.vnc.vncviewer.graphics.swt.SWTRemoteDisplay; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ControlAdapter; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.MouseWheelListener; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; + +import com.motorola.studio.android.adt.DDMSFacade; +import com.motorola.studio.android.emulator.core.model.IAndroidEmulatorInstance; +import com.motorola.studio.android.emulator.core.model.IInputLogic; +import com.motorola.studio.android.emulator.logic.AndroidLogicUtils; +import com.motorola.studio.android.emulator.skin.android.AndroidSkinTranslator; +import com.motorola.studio.android.emulator.ui.controls.IAndroidComposite; +import com.motorola.studio.android.emulator.ui.controls.UIHelper; +import com.motorola.studio.android.emulator.ui.handlers.IHandlerConstants; +import com.motorola.studio.android.nativeos.NativeUIUtils; + +/** + * This class is the composite that holds the main display and it is shown by + * the Emulator Main Display View. + */ +public class MainDisplayComposite extends Composite implements IAndroidComposite +{ + + /** + * The zoom factor whose default value is 1.0 (100%) + */ + private double zoomFactor = 1.0; + + private double fitZoomfactor; + + // Minimum value to be used as zoom factor. This is necessary to avoid + // divisions to zero + private static final double MINIMUM_ZOOM_FACTOR = 0.0001; + + private static final double ZOOM_FIT = 0.0; + + /** + * The flag indicating that Ctrl key is pressed + */ + private boolean ctrlPressed = false; + + /** + * SWT key pressed/released events listener. + */ + private KeyListener keyListener; + + private MouseListener mouseListener; + + private MouseMoveListener mouseMoveListener; + + private IInputLogic androidInput; + + private boolean isMouseLeftButtonPressed; + + private boolean isFitToWindow; + + private IAndroidEmulatorInstance androidInstance; + + private Properties keyMap; + + /** + * Constructor + * + * @param parent + * composite + * @param style + * style + * @param baseWidth + * the default main display width + * @param baseHeight + * the default main display height + */ + public MainDisplayComposite(Composite parent, int style, int baseWidth, int baseHeight, + IAndroidEmulatorInstance instance) + { + super(parent, style); + + androidInput = instance.getInputLogic(); + + androidInstance = instance; + + isMouseLeftButtonPressed = false; + + keyMap = AndroidSkinTranslator.getQwertyKeyMap(); + + addListener(); + + if (!Platform.getOS().equals(Platform.OS_MACOSX)) + { + hideEmulatorWindow(); + } + + } + + private void hideEmulatorWindow() + { + int port = + AndroidLogicUtils.getEmulatorPort(DDMSFacade.getSerialNumberByName(androidInstance + .getName())); + long windowHandle = NativeUIUtils.getWindowHandle(androidInstance.getName(), port); + androidInstance.setWindowHandle(windowHandle); + + NativeUIUtils.hideWindow(windowHandle); + } + + /* + * (non-Javadoc) + * @see org.eclipse.swt.widgets.Widget#dispose() + */ + @Override + public void dispose() + { + if (androidInput != null) + { + androidInput.dispose(); + } + + keyListener = null; + mouseListener = null; + mouseMoveListener = null; + + if (!Platform.getOS().equals(Platform.OS_MACOSX)) + { + long hnd = androidInstance.getWindowHandle(); + if (hnd > 0) + { + NativeUIUtils.showWindow(hnd); + NativeUIUtils.restoreWindow(hnd); + } + + //Force update on redrawing + androidInstance.setWindowHandle(0); + } + + super.dispose(); + } + + /** + * Updates the composite size when zoom is changed. + * + * @param zoom + * the zoom factor + */ + public void setZoomFactor(double zoomFactor) + { + info("Update detached view composite size"); + if (zoomFactor == ZOOM_FIT) + { + isFitToWindow = true; + } + else + { + isFitToWindow = false; + } + this.zoomFactor = zoomFactor; + } + + /** + * Gets the zoom factor. + * + * @return zoom the zoom factor. + */ + public double getZoomFactor() + { + return zoomFactor; + } + + /** + * Applies the zoom factor to the components of the composite, updating the + * composite size to hold totally the main display. + */ + public void applyZoomFactor() + { + + SWTRemoteDisplay mainDisplay = UIHelper.getRemoteDisplayAssociatedToControl(this); + IRemoteDisplay.Rotation rotation = mainDisplay.getRotation(); + + int baseHeight; + int baseWidth; + + switch (rotation) + { + case ROTATION_90DEG_COUNTERCLOCKWISE: + baseHeight = mainDisplay.getScreenWidth(); + baseWidth = mainDisplay.getScreenHeight(); + break; + default: + baseHeight = mainDisplay.getScreenHeight(); + baseWidth = mainDisplay.getScreenWidth(); + + } + + int width; + int height; + if (isFitToWindow) + { + Rectangle clientArea = getParent().getClientArea(); + if ((clientArea.width == 0) || (clientArea.height == 0)) + { + // zoom factor cannot be zero, otherwise an + // IllegalArgumentException + // is raised in some SWT methods + fitZoomfactor = MINIMUM_ZOOM_FACTOR; + } + else + { + double widthRatio = (double) (clientArea.width) / baseWidth; + double heightRatio = (double) (clientArea.height) / baseHeight; + fitZoomfactor = Math.min(widthRatio, heightRatio); + } + width = new Double(baseWidth * fitZoomfactor).intValue(); + height = new Double(baseHeight * fitZoomfactor).intValue(); + + if (mainDisplay != null) + { + mainDisplay.setZoomFactor(fitZoomfactor); + } + } + else + { + width = new Double(baseWidth * zoomFactor).intValue(); + height = new Double(baseHeight * zoomFactor).intValue(); + + if (mainDisplay != null) + { + mainDisplay.setZoomFactor(zoomFactor); + } + } + + setSize(width, height); + } + + /** + * Adds listener for SWT events. + */ + private void addListener() + { + // add listener to handle keyboard key pressing + keyListener = new KeyListener() + { + + public void keyPressed(KeyEvent arg0) + { + + int keyCode = arg0.keyCode; + + if (keyCode == SWT.CTRL) + { + ctrlPressed = true; + } + else + { + // send message to emulator + androidInput.sendKey(arg0.character, keyCode, keyMap); + } + + } + + public void keyReleased(KeyEvent arg0) + { + int keyCode = arg0.keyCode; + + if (keyCode == SWT.CTRL) + { + ctrlPressed = false; + } + } + + }; + + // listener to change the zoom factor using Ctrl + Mouse Wheel + addMouseWheelListener(new MouseWheelListener() + { + + public void mouseScrolled(MouseEvent event) + { + if (ctrlPressed) + { + + if ((event.count > 0) && (zoomFactor < IHandlerConstants.MAXIMUM_ZOOM)) + { + // increase zoom factor + setZoomFactor(zoomFactor + IHandlerConstants.STEP_ZOOM); + applyZoomFactor(); + } + + else if ((event.count < 0) && (zoomFactor > IHandlerConstants.MINIMUM_ZOOM)) + { + // decrease zoom factor + setZoomFactor(zoomFactor - IHandlerConstants.STEP_ZOOM); + applyZoomFactor(); + } + } + } + }); + + mouseListener = new MouseAdapter() + { + /** + * @see org.eclipse.swt.events.MouseListener#mouseUp(MouseEvent) + */ + @Override + public void mouseUp(MouseEvent e) + { + handleMouseUp(e); + } + + /** + * @see org.eclipse.swt.events.MouseListener#mouseDown(MouseEvent) + */ + @Override + public void mouseDown(MouseEvent e) + { + setFocus(); + handleMouseDown(e); + } + }; + + mouseMoveListener = new MouseMoveListener() + { + /** + * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(MouseEvent) + */ + public void mouseMove(MouseEvent e) + { + handleMouseMove(e); + } + }; + + getParent().addControlListener(new ControlAdapter() + { + /* + * (non-Javadoc) + * @see org.eclipse.swt.events.ControlAdapter#controlResized(org.eclipse.swt.events.ControlEvent) + */ + @Override + public void controlResized(ControlEvent event) + { + if (isFitToWindow) + { + applyZoomFactor(); + } + } + }); + + } + + /* + * (non-Javadoc) + * @see com.motorola.studio.android.emulator.ui.controls.IAndroidComposite#applyLayout(java.lang.String) + */ + public void applyLayout(String layoutName) + { + //do nothing + } + + /** + * Gets the listener that handles SWT key pressing and releasing events. + * + * @return the KeyListener object + */ + public KeyListener getKeyListener() + { + return keyListener; + } + + /** + * Gets the listener that handles SWT mouse clicking events. + * + * @return the MouseListener object + */ + public MouseListener getMouseListener() + { + return mouseListener; + } + + /** + * Gets the listener that handles SWT mouse moving events. + * + * @return the MouseMoveListener object + */ + public MouseMoveListener getMouseMoveListener() + { + return mouseMoveListener; + } + + /** + * Handles the mouse up event on the skin composite + * + * @param e + * The mouse up event + */ + private void handleMouseUp(MouseEvent e) + { + if (e.button == 1) + { + isMouseLeftButtonPressed = false; + UIHelper.ajustCoordinates(e, this); + androidInput.sendMouseUp(e.x, e.y); + } + } + + /** + * Handles the mouse down event on the skin composite + * + * @param e + * The mouse down event + */ + private void handleMouseDown(MouseEvent e) + { + if (e.button == 1) + { + UIHelper.ajustCoordinates(e, this); + androidInput.sendMouseDown(e.x, e.y); + isMouseLeftButtonPressed = true; + } + + } + + /** + * Handles the mouse move event on the skin composite + * + * @param e + * The mouse move event + */ + private void handleMouseMove(MouseEvent e) + { + if (isMouseLeftButtonPressed) + { + UIHelper.ajustCoordinates(e, this); + androidInput.sendMouseMove(e.x, e.y); + } + } + + public boolean isFitToWindowSelected() + { + return isFitToWindow; + } +} |