--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/lcdui_qt/src/javax/microedition/lcdui/LayoutObject.java Mon May 03 12:27:20 2010 +0300
@@ -0,0 +1,436 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package javax.microedition.lcdui;
+
+import java.util.Enumeration;
+
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Structure which represents Control stored in Form Row.
+ */
+final class LayoutObject {
+
+ /**
+ * Control which is represented by this LayoutObject.
+ */
+ private Control control;
+
+ /**
+ * If control is Composite (for example if Item has label), then
+ * commandControl will contain composite's child that will receive events.
+ * Otherwise commandControl will be same as control.
+ */
+ private Control commandControl;
+ private Item owningItem;
+ private boolean commandsActivated;
+
+ private int x;
+ private int y;
+ private int width;
+ private int height;
+
+ private EswtItemCommandListener eswtItemCommandListener =
+ new EswtItemCommandListener();
+
+ // index of the row current LayoutObject belongs to
+ private int layoutRowIdx;
+
+ /**
+ * Constructor.
+ *
+ * @param owningItem - Item which this LayoutObject corresponds to
+ * @param control - Control for that LayoutObject
+ */
+ LayoutObject(Item owningItem, Control control) {
+ this.owningItem = owningItem;
+ setControl(control);
+ }
+
+ /**
+ * Set the Control for that LayoutObject.
+ *
+ * @param newControl Control to set
+ */
+ private void setControl(final Control newControl) {
+ ESWTUIThreadRunner.syncExec(new Runnable() {
+ public void run() {
+ control = newControl;
+ eswtUpdateSize();
+ Control temp = eswtGetCommandControl(control);
+ commandControl = (temp != null ? temp : control);
+
+ Enumeration e = owningItem.getCommands().elements();
+ Command cmd = null;
+ while (e.hasMoreElements()) {
+ cmd = (Command) e.nextElement();
+ eswtAddCommand(cmd);
+ }
+ }
+ });
+ }
+
+ /**
+ * Gets Control which should be used with commands.<br>
+ * This might be LayoutObject's control or one of its children in case of
+ * Button. Button should be handled separately here because of MSK.
+ *
+ * @param ctrl Control of this LayoutObject.
+ * @return Control.
+ */
+ Control eswtGetCommandControl(Control ctrl) {
+ Control ret = null;
+ if (ctrl != null) {
+ if (ctrl instanceof Button) {
+ ret = ctrl;
+ }
+ else if (ctrl instanceof Composite) {
+ Control[] children = ((Composite) ctrl).getChildren();
+ for (int i = 0; i < children.length; i++) {
+ Control result = eswtGetCommandControl(children[i]);
+ if (result != null) {
+ ret = result;
+ break;
+ }
+ }
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * Dispose LayoutObject.
+ */
+ void dispose() {
+ ESWTUIThreadRunner.syncExec(new Runnable() {
+ public void run() {
+ control.dispose();
+ control = null;
+ commandControl = null;
+ }
+ });
+ }
+
+ /**
+ * Returns the Item's vertical layout.
+ */
+ int getVerticalLayout() {
+ return Item.getVerticalLayout(owningItem.getLayout());
+ }
+
+ /**
+ * Get Control of the layoutObject.
+ *
+ * @return control
+ */
+ Control getControl() {
+ return control;
+ }
+
+ /**
+ * Get Item to which the LayoutObjecy belongs.
+ *
+ * @return owning Item
+ */
+ Item getOwningItem() {
+ return owningItem;
+ }
+
+ /**
+ * Set location of the LayoutObject and the control.
+ *
+ * @param xCoord x coordinate
+ * @param yCoord y coordinate
+ */
+ void eswtSetLocation(int xCoord, int yCoord) {
+ x = xCoord;
+ y = yCoord;
+ control.setLocation(xCoord, yCoord);
+ }
+
+ /**
+ * Update LayoutObject width and height.
+ */
+ void eswtUpdateSize() {
+ Rectangle bounds = control.getBounds();
+ width = bounds.width;
+ height = bounds.height;
+ }
+
+ /**
+ * Get x Coordinate of LayoutObject,
+ *
+ * @return xCoordinate of LayoutObject.
+ */
+ int getX() {
+ return x;
+ }
+
+ /**
+ * Get y Coordinate of LayoutObject,
+ *
+ * @return yCoordinate of LayoutObject.
+ */
+ int getY() {
+ return y;
+ }
+
+ /**
+ * Get width of LayoutObject.
+ *
+ * @return width of a control
+ */
+ int getWidth() {
+ return width;
+ }
+
+ /**
+ * Get width of LayoutObject.
+ *
+ * @return width of a control
+ */
+ int getHeight() {
+ return height;
+ }
+
+ /**
+ * Sets the row index of the Row where this LayoutObject is placed.
+ *
+ * @param row Row index.
+ */
+ void setRowIdx(int row) {
+ layoutRowIdx = row;
+ }
+
+ /**
+ * Returns row index where this LayoutObject is placed.
+ *
+ * @return Index of the row.
+ */
+ int getRowIdx() {
+ return layoutRowIdx;
+ }
+
+ boolean contains(int xCoord, int yCoord) {
+ return (y <= yCoord && yCoord <= y + height
+ && x <= xCoord && xCoord <= x + width);
+ }
+
+ /**
+ * Returns if this LayoutObject is below the other.
+ */
+ boolean isBelow(LayoutObject other) {
+ if (other != null) {
+ return (this.getRowIdx() > other.getRowIdx());
+ }
+ return true;
+ }
+
+ /**
+ * Returns if this LayoutObject is above the other.
+ */
+ boolean isAbove(LayoutObject other) {
+ if (other != null) {
+ return (this.getRowIdx() < other.getRowIdx());
+ }
+ return true;
+ }
+
+ /**
+ * Returns the horizontal middle of the LayoutObject.
+ *
+ * @return x horizontal coordinate of the middle of LayoutObject.
+ */
+ private int getXMiddle() {
+ return (x + width / 2);
+ }
+
+ /**
+ * Returns the vertical middle of the LayoutObject.
+ *
+ * @return y vertical coordinate of the middle of LayoutObject.
+ */
+ private int getYMiddle() {
+ return (y + height / 2);
+ }
+
+ /**
+ * Returns the horizontal distance between the middle of the LayoutObjects.
+ * The method is used to find next focusable item.
+ *
+ * @param other another LayoutObject
+ * @return positive distance between the middles
+ */
+ int distanceTo(LayoutObject other) {
+ if (other != null) {
+ int xd = Math.abs(getXMiddle() - other.getXMiddle());
+ int yd = Math.abs(getYMiddle() - other.getYMiddle());
+ return (int) Math.sqrt(xd * xd + yd * yd);
+ }
+ else {
+ return Integer.MAX_VALUE - 1;
+ }
+ }
+
+ /**
+ * Activates commands associated with owning item.
+ */
+ void eswtAddSelectionListenerForCommands() {
+ // Logger.method(this, "eswtAddSelectionListenerForCommands");
+ commandsActivated = true;
+
+ // Add new control to commands in owning item:
+ Enumeration e = owningItem.getCommands().elements();
+ Command cmd = null;
+ while (e.hasMoreElements()) {
+ cmd = (Command) e.nextElement();
+ cmd.eswtAddCommandSelectionListener(commandControl,
+ eswtItemCommandListener);
+ }
+ // Add SelectionListener to Button control.
+ // Listener is activated when command mapped to MSK is clicked.
+ if (commandControl instanceof Button && !commandControl.isDisposed()) {
+ ((Button) commandControl)
+ .addSelectionListener(eswtItemCommandListener);
+ }
+ }
+
+ /**
+ * DeActivates commands associated with owning item.
+ */
+ void eswtRemoveSelectionListenerForCommands() {
+ // Logger.method(this, "eswtRemoveSelectionListenerForCommands");
+ commandsActivated = false;
+
+ // Add new control to commands in owning item:
+ Enumeration e = owningItem.getCommands().elements();
+ Command cmd = null;
+ while (e.hasMoreElements()) {
+ cmd = (Command) e.nextElement();
+ cmd.eswtRemoveCommandSelectionListener(commandControl,
+ eswtItemCommandListener);
+ }
+ // Remove SelectionListener from Button control.
+ // Listener is activated when command mapped to MSK is clicked.
+ if (commandControl instanceof Button && !commandControl.isDisposed()) {
+ ((Button) commandControl)
+ .removeSelectionListener(eswtItemCommandListener);
+ }
+ }
+
+ /**
+ * Adds command to the owning item.
+ *
+ * @param command The command to be added.
+ */
+ void addCommand(final Command command) {
+ ESWTUIThreadRunner.syncExec(new Runnable() {
+ public void run() {
+ eswtAddCommand(command);
+ }
+ });
+ }
+
+ /**
+ * eSWT callback to add a Command.
+ */
+ void eswtAddCommand(Command command) {
+ //Logger.method(this, "eswtAddCommand", command);
+ if (command != null && commandControl != null) {
+ command.eswtAddESWTCommand(commandControl,
+ (command == owningItem.getDefaultCommand()));
+ if (commandsActivated) {
+ command.eswtAddCommandSelectionListener(commandControl,
+ eswtItemCommandListener);
+ }
+ }
+ }
+
+ /**
+ * Removes command from the owning item.
+ *
+ * @param command The command to be removed.
+ */
+ void removeCommand(final Command command) {
+ ESWTUIThreadRunner.syncExec(new Runnable() {
+ public void run() {
+ eswtRemoveCommand(command);
+ }
+ });
+ }
+
+ /**
+ * eSWT callback to remove a Command.
+ */
+ private void eswtRemoveCommand(Command command) {
+ //Logger.method(this, "eswtRemoveCommand", command);
+ if (command != null && commandControl != null) {
+ if (commandsActivated) {
+ command.eswtRemoveCommandSelectionListener(commandControl,
+ eswtItemCommandListener);
+ }
+ command.eswtRemoveESWTCommand(commandControl);
+ }
+ }
+
+ /**
+ * Inner class which receives SelectionEvents from eSWT and convert and
+ * forwards those events to LCDUI Item's ItemCommandListener.
+ */
+ class EswtItemCommandListener implements SelectionListener {
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+
+ /**
+ * Executed by eSWT when event occurs. This method will then call
+ * Item's ItemCommandListener if event source matches with the
+ * Commands added to the Item.
+ */
+ public void widgetSelected(SelectionEvent event) {
+ // Go through all Commands added to owning item:
+ Enumeration e = owningItem.getCommands().elements();
+ Command cmd = null;
+ while (e.hasMoreElements()) {
+ cmd = (Command) e.nextElement();
+ // get eSWT Command of this Control from Command and compare
+ // it to the widget which launched the event:
+ if (cmd.getESWTCommand(commandControl) == event.widget) {
+ owningItem.callCommandAction(cmd);
+ break;
+ }
+
+ // Handle MSK:
+ Command mskCmd = owningItem.getMSKCommand();
+ if (mskCmd != null && cmd == mskCmd) {
+ if (commandControl == event.widget) {
+ owningItem.callCommandAction(cmd);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ public String toString() {
+ return owningItem + " [line:" + layoutRowIdx + "]";
+ }
+
+}