You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by tv...@apache.org on 2009/03/26 00:12:17 UTC
svn commit: r758461 [19/47] - in /incubator/pivot/branches: ./ 1.1/
1.1/charts-test/ 1.1/charts-test/src/ 1.1/charts-test/src/pivot/
1.1/charts-test/src/pivot/charts/ 1.1/charts-test/src/pivot/charts/test/
1.1/charts/ 1.1/charts/lib/ 1.1/charts/src/ 1....
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ComponentMouseListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ComponentMouseListener.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ComponentMouseListener.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ComponentMouseListener.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * 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 pivot.wtk;
+
+/**
+ * Component mouse listener interface. Component mouse events are "bubbling"
+ * and are fired as the event propagates up the component hierarchy.
+ *
+ * @author gbrown
+ */
+public interface ComponentMouseListener {
+ /**
+ * Called when the mouse is moved over a component.
+ *
+ * @param component
+ * @param x
+ * @param y
+ *
+ * @return
+ * <tt>true</tt> to consume the event; <tt>false</tt> to allow it to
+ * propagate.
+ */
+ public boolean mouseMove(Component component, int x, int y);
+
+ /**
+ * Called when the mouse enters a component.
+ *
+ * @param component
+ */
+ public void mouseOver(Component component);
+
+ /**
+ * Called when the mouse exits a component.
+ *
+ * @param component
+ */
+ public void mouseOut(Component component);
+}
+
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ComponentMouseWheelListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ComponentMouseWheelListener.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ComponentMouseWheelListener.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ComponentMouseWheelListener.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * 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 pivot.wtk;
+
+/**
+ * Component mouse wheel listener interface.
+ *
+ * @author gbrown
+ */
+public interface ComponentMouseWheelListener {
+ /**
+ * Called when the mouse wheel is scrolled over a component.
+ *
+ * @param component
+ * @param scrollType
+ * @param scrollAmount
+ * @param wheelRotation
+ * @param x
+ * @param y
+ *
+ * @return
+ * <tt>true</tt> to consume the event; <tt>false</tt> to allow it to
+ * propagate.
+ */
+ public boolean mouseWheel(Component component, Mouse.ScrollType scrollType,
+ int scrollAmount, int wheelRotation, int x, int y);
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ComponentStateListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ComponentStateListener.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ComponentStateListener.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ComponentStateListener.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * 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 pivot.wtk;
+
+/**
+ * Component state listener interface.
+ *
+ * @author gbrown
+ * @author tvolkert
+ */
+public interface ComponentStateListener {
+ /**
+ * Called when a component's enabled state has changed.
+ *
+ * @param component
+ */
+ public void enabledChanged(Component component);
+
+ /**
+ * Called when a component's focused state has changed.
+ *
+ * @param component
+ * @param temporary
+ */
+ public void focusedChanged(Component component, boolean temporary);
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ConstrainedVisual.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ConstrainedVisual.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ConstrainedVisual.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ConstrainedVisual.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,41 @@
+package pivot.wtk;
+
+/**
+ * Interface representing a visual that is used in layout.
+ *
+ * @author gbrown
+ */
+public interface ConstrainedVisual extends Visual {
+ /**
+ * Sets the visual's render size.
+ *
+ * @param width
+ * @param height
+ */
+ public void setSize(int width, int height);
+
+ /**
+ * Returns the visual's preferred width given the provided height
+ * constraint.
+ *
+ * @param height
+ * The height by which to constrain the preferred width, or <tt>-1</tt>
+ * for no constraint.
+ */
+ public int getPreferredWidth(int height);
+
+ /**
+ * Returns the visual's preferred height given the provided width
+ * constraint.
+ *
+ * @param width
+ * The width by which to constrain the preferred height, or <tt>-1</tt>
+ * for no constraint.
+ */
+ public int getPreferredHeight(int width);
+
+ /**
+ * Returns the visual's unconstrained preferred size.
+ */
+ public Dimensions getPreferredSize();
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Container.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Container.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Container.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Container.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,780 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * 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 pivot.wtk;
+
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.util.Iterator;
+
+import pivot.beans.BeanDictionary;
+import pivot.collections.ArrayList;
+import pivot.collections.Dictionary;
+import pivot.collections.Map;
+import pivot.collections.Sequence;
+import pivot.util.ImmutableIterator;
+import pivot.util.ListenerList;
+import pivot.wtk.effects.Decorator;
+
+/**
+ * Abstract base class for containers.
+ * <p>
+ * NOTES:
+ * <ul>
+ * <li>Child components that have special meaning to a container should be
+ * installed via a dedicated method (for example,
+ * {@link pivot.wtk.Window#setContent(Component)}); additional components may
+ * be added by the skin when installed. Other components may still be added but
+ * may not be rendered properly by the installed skin.</li>
+ * <li>Callers should not rely on component position within container to mean
+ * anything other than paint order.</li>
+ * </ul>
+ *
+ * @author gbrown
+ */
+public abstract class Container extends Component
+ implements Sequence<Component>, Iterable<Component> {
+ private static class ContainerListenerList extends ListenerList<ContainerListener>
+ implements ContainerListener {
+ public void componentInserted(Container container, int index) {
+ for (ContainerListener listener : this) {
+ listener.componentInserted(container, index);
+ }
+ }
+
+ public void componentsRemoved(Container container, int index, Sequence<Component> components) {
+ for (ContainerListener listener : this) {
+ listener.componentsRemoved(container, index, components);
+ }
+ }
+
+ public void contextKeyChanged(Container container, String previousContextKey) {
+ for (ContainerListener listener : this) {
+ listener.contextKeyChanged(container, previousContextKey);
+ }
+ }
+
+ public void focusTraversalPolicyChanged(Container container,
+ FocusTraversalPolicy previousFocusTraversalPolicy) {
+ for (ContainerListener listener : this) {
+ listener.focusTraversalPolicyChanged(container, previousFocusTraversalPolicy);
+ }
+ }
+ }
+
+ private static class ContainerMouseListenerList extends ListenerList<ContainerMouseListener>
+ implements ContainerMouseListener {
+ public boolean mouseMove(Container container, int x, int y) {
+ boolean consumed = false;
+
+ for (ContainerMouseListener listener : this) {
+ consumed |= listener.mouseMove(container, x, y);
+ }
+
+ return consumed;
+ }
+
+ public boolean mouseDown(Container container, Mouse.Button button, int x, int y) {
+ boolean consumed = false;
+
+ for (ContainerMouseListener listener : this) {
+ consumed |= listener.mouseDown(container, button, x, y);
+ }
+
+ return consumed;
+ }
+
+ public boolean mouseUp(Container container, Mouse.Button button, int x, int y) {
+ boolean consumed = false;
+
+ for (ContainerMouseListener listener : this) {
+ consumed |= listener.mouseUp(container, button, x, y);
+ }
+
+ return consumed;
+ }
+
+ public boolean mouseWheel(Container container, Mouse.ScrollType scrollType,
+ int scrollAmount, int wheelRotation, int x, int y) {
+ boolean consumed = false;
+
+ for (ContainerMouseListener listener : this) {
+ consumed |= listener.mouseWheel(container, scrollType, scrollAmount, wheelRotation, x, y);
+ }
+
+ return consumed;
+ }
+ }
+
+ // TODO A linked list may be more efficient than an array list; it would
+ // certainly optimize moveToTop() and moveToBottom() in Window, since
+ // an array list will need to perform a lot of copying as owned windows
+ // are removed from the list and appended to the end
+ private ArrayList<Component> components = new ArrayList<Component>();
+
+ private boolean valid = true;
+
+ private FocusTraversalPolicy focusTraversalPolicy = null;
+ private String contextKey = null;
+
+ private Component mouseOverComponent = null;
+
+ private Component mouseDownComponent = null;
+ private long mouseDownTime = 0;
+ private int mouseClickCount = 0;
+ private boolean mouseClickConsumed = false;
+
+ private ContainerListenerList containerListeners = new ContainerListenerList();
+ private ContainerMouseListenerList containerMouseListeners = new ContainerMouseListenerList();
+
+ public final int add(Component component) {
+ int i = getLength();
+ insert(component, i);
+
+ return i;
+ }
+
+ public void insert(Component component, int index) {
+ if (component == null) {
+ throw new IllegalArgumentException("component is null.");
+ }
+
+ if (component == this) {
+ throw new IllegalArgumentException("Cannot add a container to itself.");
+ }
+
+ if (component.getParent() != null) {
+ throw new IllegalArgumentException("Component already has a parent.");
+ }
+
+ component.setParent(Container.this);
+ components.insert(component, index);
+
+ // Repaint the area occupied by the new component
+ repaint(component.getDecoratedBounds());
+
+ invalidate();
+
+ containerListeners.componentInserted(Container.this, index);
+ }
+
+ public Component update(int index, Component component) {
+ throw new UnsupportedOperationException();
+ }
+
+ public final int remove(Component component) {
+ int index = indexOf(component);
+ if (index != -1) {
+ remove(index, 1);
+ }
+
+ return index;
+ }
+
+ public Sequence<Component> remove(int index, int count) {
+ Sequence<Component> removed = components.remove(index, count);
+
+ // Set the removed components' parent to null and repaint the area
+ // formerly occupied by the components
+ for (int i = 0, n = removed.getLength(); i < n; i++) {
+ Component component = removed.get(i);
+ if (component == mouseOverComponent) {
+ if (mouseOverComponent.isMouseOver()) {
+ mouseOverComponent.mouseOut();
+ }
+
+ mouseOverComponent = null;
+ Mouse.setCursor(this);
+ }
+
+ repaint(component.getDecoratedBounds());
+ component.setParent(null);
+ }
+
+ if (removed.getLength() > 0) {
+ invalidate();
+ containerListeners.componentsRemoved(Container.this, index, removed);
+ }
+
+ return removed;
+ }
+
+ public final Sequence<Component> removeAll() {
+ return remove(0, getLength());
+ }
+
+ /**
+ * Moves a component within the component sequence. This method does not
+ * fire any events; it is the caller's responsibility to ensure that
+ * appropriate events are fired (see
+ * {@link WindowListener#windowMoved(Window, int, int)} as an example).
+ *
+ * @param from
+ * @param to
+ */
+ protected void move(int from, int to) {
+ if (from != to) {
+ Sequence<Component> removed = components.remove(from, 1);
+ Component component = removed.get(0);
+ components.insert(component, to);
+
+ // Repaint the area occupied by the component
+ repaint(component.getDecoratedBounds());
+ }
+ }
+
+ public Component get(int index) {
+ return components.get(index);
+ }
+
+ public int indexOf(Component component) {
+ return components.indexOf(component);
+ }
+
+ public int getLength() {
+ return components.getLength();
+ }
+
+ public Iterator<Component> iterator() {
+ return new ImmutableIterator<Component>(components.iterator());
+ }
+
+ @Override
+ protected void setParent(Container parent) {
+ // If this container is being removed from the component hierarchy
+ // and contains the focused component, clear the focus
+ if (parent == null
+ && isAncestor(getFocusedComponent())) {
+ clearFocus(true);
+ }
+
+ super.setParent(parent);
+ }
+
+ public Component getComponentAt(int x, int y) {
+ Component component = null;
+
+ int i = components.getLength() - 1;
+ while (i >= 0) {
+ component = components.get(i);
+ if (component.isVisible()) {
+ Bounds bounds = component.getBounds();
+ if (bounds.contains(x, y)) {
+ break;
+ }
+ }
+
+ i--;
+ }
+
+ if (i < 0) {
+ component = null;
+ }
+
+ return component;
+ }
+
+ public Component getDescendantAt(int x, int y) {
+ Component component = getComponentAt(x, y);
+
+ if (component instanceof Container) {
+ Container container = (Container)component;
+ component = container.getDescendantAt(x - component.getX(),
+ y - component.getY());
+ }
+
+ if (component == null) {
+ component = this;
+ }
+
+ return component;
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ if (!visible
+ && containsFocus()) {
+ clearFocus(true);
+ }
+
+ super.setVisible(visible);
+ }
+
+ @Override
+ public boolean isValid() {
+ return valid;
+ }
+
+ @Override
+ public void invalidate() {
+ valid = false;
+ super.invalidate();
+ }
+
+ @Override
+ public void validate() {
+ super.validate();
+
+ if (!valid) {
+ try {
+ for (int i = 0, n = components.getLength(); i < n; i++) {
+ Component component = components.get(i);
+ component.validate();
+ }
+ } finally {
+ valid = true;
+ }
+ }
+ }
+
+ @Override
+ public void paint(Graphics2D graphics) {
+ // Give the base method a copy of the graphics context; otherwise,
+ // container skins can change the graphics state before it is passed
+ // to subcomponents
+ Graphics2D containerGraphics = (Graphics2D)graphics.create();
+ super.paint(containerGraphics);
+ containerGraphics.dispose();
+
+ // Determine the paint bounds
+ Bounds paintBounds = new Bounds(0, 0, getWidth(), getHeight());
+ Rectangle clipBounds = graphics.getClipBounds();
+ if (clipBounds != null) {
+ paintBounds.intersect(new Bounds(clipBounds));
+ }
+
+ for (Component component : this) {
+ // Calculate the decorated bounds
+ Bounds decoratedBounds = component.getDecoratedBounds();
+
+ // Only paint components that are visible and intersect the
+ // current clip rectangle
+ if (component.isVisible()
+ && decoratedBounds.intersects(paintBounds)) {
+ Bounds componentBounds = component.getBounds();
+
+ // Create a copy of the current graphics context and
+ // translate to the component's coordinate system
+ Graphics2D decoratedGraphics = (Graphics2D)graphics.create();
+ decoratedGraphics.translate(componentBounds.x, componentBounds.y);
+
+ // Prepare the decorators
+ DecoratorSequence decorators = component.getDecorators();
+ int n = decorators.getLength();
+ for (int i = n - 1; i >= 0; i--) {
+ Decorator decorator = decorators.get(i);
+ decoratedGraphics = decorator.prepare(component, decoratedGraphics);
+ }
+
+ // Paint the component
+ Graphics2D componentGraphics = (Graphics2D)decoratedGraphics.create();
+ componentGraphics.clipRect(0, 0, componentBounds.width, componentBounds.height);
+ component.paint(componentGraphics);
+ componentGraphics.dispose();
+
+ // Update the decorators
+ for (int i = 0; i < n; i++) {
+ Decorator decorator = decorators.get(i);
+ decorator.update();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void setEnabled(boolean enabled) {
+ if (isEnabled() != enabled) {
+ super.setEnabled(enabled);
+
+ if (isEnabled() == enabled) {
+ if (!enabled
+ && containsFocus()) {
+ clearFocus(true);
+ }
+ }
+ }
+ }
+
+ /**
+ * Unsupported for containers. Only leaf components can have tooltips.
+ */
+ public void setTooltip(String tooltip) {
+ throw new UnsupportedOperationException("A container cannot have a toolip.");
+ }
+
+ /**
+ * Tests if this container is an ancestor of a given component.
+ *
+ * @param component
+ * The component to test.
+ *
+ * @return
+ * <tt>true</tt> if this container is an ancestor of <tt>component</tt>;
+ * <tt>false</tt>, otherwise.
+ */
+ public boolean isAncestor(Component component) {
+ boolean ancestor = false;
+
+ Component parent = component;
+ while (parent != null) {
+ if (parent == this) {
+ ancestor = true;
+ break;
+ }
+
+ parent = parent.getParent();
+ }
+
+ return ancestor;
+ }
+
+ /**
+ * @return
+ * <tt>false</tt>; containers are not focusable.
+ */
+ @Override
+ public final boolean isFocusable() {
+ return false;
+ }
+
+ @Override
+ /**
+ * Requests that focus be set to the first focusable component in this
+ * container.
+ */
+ public void requestFocus() {
+ if (getLength() > 0) {
+ get(0).requestFocus();
+ }
+ }
+
+ /**
+ * Returns this container's focus traversal policy.
+ */
+ public FocusTraversalPolicy getFocusTraversalPolicy() {
+ return this.focusTraversalPolicy;
+ }
+
+ /**
+ * Sets this container's focus traversal policy.
+ *
+ * @param focusTraversalPolicy
+ * The focus traversal policy to use with this container.
+ */
+ public void setFocusTraversalPolicy(FocusTraversalPolicy focusTraversalPolicy) {
+ FocusTraversalPolicy previousFocusTraversalPolicy = this.focusTraversalPolicy;
+
+ if (previousFocusTraversalPolicy != focusTraversalPolicy) {
+ this.focusTraversalPolicy = focusTraversalPolicy;
+ containerListeners.focusTraversalPolicyChanged(this, previousFocusTraversalPolicy);
+ }
+ }
+
+ /**
+ * Tests whether this container is an ancestor of the currently focused
+ * component.
+ *
+ * @return
+ * <tt>true</tt> if a component is focused and this container is an
+ * ancestor of the component; <tt>false</tt>, otherwise.
+ */
+ public boolean containsFocus() {
+ Component focusedComponent = getFocusedComponent();
+ return (focusedComponent != null && isAncestor(focusedComponent));
+ }
+
+ /**
+ * Returns the container's context key.
+ *
+ * @return
+ * The context key, or <tt>null</tt> if no context key is set.
+ */
+ public String getContextKey() {
+ return contextKey;
+ }
+
+ /**
+ * Sets the component's context key.
+ *
+ * @param contextKey
+ * The context key, or <tt>null</tt> to clear the context.
+ */
+ public void setContextKey(String contextKey) {
+ String previousContextKey = this.contextKey;
+
+ if ((previousContextKey != null
+ && contextKey != null
+ && !previousContextKey.equals(contextKey))
+ || previousContextKey != contextKey) {
+ this.contextKey = contextKey;
+ containerListeners.contextKeyChanged(this, previousContextKey);
+ }
+ }
+
+ /**
+ * Propagates binding to subcomponents. If this container has a binding
+ * set, propagates the bound value as a nested context.
+ *
+ * @param context
+ */
+ @SuppressWarnings("unchecked")
+ public void load(Dictionary<String, ?> context) {
+ if (contextKey != null
+ && context.containsKey(contextKey)) {
+ Object value = context.get(contextKey);
+ if (value instanceof Dictionary<?, ?>) {
+ context = (Map<String, Object>)value;
+ } else {
+ context = new BeanDictionary(value);
+ }
+ }
+
+ for (Component component : components) {
+ component.load(context);
+ }
+ }
+
+ /**
+ * Propagates binding to subcomponents by converting the given context
+ * to a bean dictionary.
+ *
+ * @param context
+ */
+ public void load(Object context) {
+ load(new BeanDictionary(context));
+ }
+
+ /**
+ * Propagates binding to subcomponents. If this container has a binding
+ * set, propagates the bound value as a nested context.
+ *
+ * @param context
+ */
+ @SuppressWarnings("unchecked")
+ public void store(Dictionary<String, ?> context) {
+ if (contextKey != null) {
+ // Bound value is expected to be a sub-context
+ Object value = context.get(contextKey);
+ if (value instanceof Dictionary<?, ?>) {
+ context = (Map<String, Object>)value;
+ } else {
+ context = new BeanDictionary(value);
+ }
+ }
+
+ for (Component component : components) {
+ component.store(context);
+ }
+ }
+
+ /**
+ * Propagates binding to subcomponents by converting the given context
+ * to a bean dictionary.
+ *
+ * @param context
+ */
+ public void store(Object context) {
+ store(new BeanDictionary(context));
+ }
+
+ @Override
+ protected boolean mouseMove(int x, int y) {
+ boolean consumed = false;
+
+ if (isEnabled()) {
+ // Notify container listeners
+ consumed = containerMouseListeners.mouseMove(this, x, y);
+
+ if (!consumed) {
+ // Clear the mouse over component if its mouse-over state has
+ // changed (e.g. if its enabled or visible properties have
+ // changed)
+ if (mouseOverComponent != null
+ && !mouseOverComponent.isMouseOver()) {
+ mouseOverComponent = null;
+ }
+
+ // Synthesize mouse over/out events
+ Component component = getComponentAt(x, y);
+
+ if (mouseOverComponent != component) {
+ if (mouseOverComponent != null) {
+ mouseOverComponent.mouseOut();
+ }
+
+ mouseOverComponent = component;
+
+ if (mouseOverComponent == null) {
+ Mouse.setCursor(this);
+ } else {
+ mouseOverComponent.mouseOver();
+ Mouse.setCursor(mouseOverComponent);
+ }
+ }
+
+ // Propagate event to subcomponents
+ if (component != null) {
+ consumed = component.mouseMove(x - component.getX(),
+ y - component.getY());
+ }
+
+ // Notify the base class
+ if (!consumed) {
+ consumed = super.mouseMove(x, y);
+ }
+ }
+ }
+
+ return consumed;
+ }
+
+ @Override
+ protected void mouseOut() {
+ // Ensure that mouse out is called on descendant components
+ if (mouseOverComponent != null
+ && mouseOverComponent.isMouseOver()) {
+ mouseOverComponent.mouseOut();
+ }
+
+ mouseOverComponent = null;
+
+ super.mouseOut();
+ }
+
+ @Override
+ protected boolean mouseDown(Mouse.Button button, int x, int y) {
+ boolean consumed = false;
+
+ if (isEnabled()) {
+ // Notify container listeners
+ consumed = containerMouseListeners.mouseDown(this, button, x, y);
+
+ if (!consumed) {
+ // Synthesize mouse click event
+ Component component = getComponentAt(x, y);
+
+ long currentTime = System.currentTimeMillis();
+ int multiClickInterval = Platform.getMultiClickInterval();
+ if (mouseDownComponent == component
+ && currentTime - mouseDownTime < multiClickInterval) {
+ mouseClickCount++;
+ } else {
+ mouseDownTime = System.currentTimeMillis();
+ mouseClickCount = 1;
+ }
+
+ mouseDownComponent = component;
+
+ // Propagate event to subcomponents
+ if (component != null) {
+ consumed = component.mouseDown(button, x - component.getX(),
+ y - component.getY());
+ }
+
+ // Notify the base class
+ if (!consumed) {
+ consumed = super.mouseDown(button, x, y);
+ }
+ }
+ }
+
+ return consumed;
+ }
+
+ @Override
+ protected boolean mouseUp(Mouse.Button button, int x, int y) {
+ boolean consumed = false;
+
+ if (isEnabled()) {
+ // Notify container listeners
+ consumed = containerMouseListeners.mouseUp(this, button, x, y);
+
+ if (!consumed) {
+ // Propagate event to subcomponents
+ Component component = getComponentAt(x, y);
+
+ if (component != null) {
+ consumed = component.mouseUp(button, x - component.getX(),
+ y - component.getY());
+ }
+
+ // Notify the base class
+ if (!consumed) {
+ consumed = super.mouseUp(button, x, y);
+ }
+
+ // Synthesize mouse click event
+ if (component != null
+ && component == mouseDownComponent
+ && mouseDownComponent.isEnabled()
+ && mouseDownComponent.isVisible()) {
+ mouseClickConsumed = component.mouseClick(button, x - component.getX(),
+ y - component.getY(), mouseClickCount);
+ }
+ }
+ }
+
+ return consumed;
+ }
+
+ @Override
+ protected boolean mouseClick(Mouse.Button button, int x, int y, int count) {
+ if (isEnabled()) {
+ if (!mouseClickConsumed) {
+ // Allow the event to propagate
+ mouseClickConsumed = super.mouseClick(button, x, y, count);
+ }
+ }
+
+ return mouseClickConsumed;
+ }
+
+ @Override
+ protected boolean mouseWheel(Mouse.ScrollType scrollType, int scrollAmount,
+ int wheelRotation, int x, int y) {
+ boolean consumed = false;
+
+ if (isEnabled()) {
+ // Notify container listeners
+ consumed = containerMouseListeners.mouseWheel(this, scrollType, scrollAmount,
+ wheelRotation, x, y);
+
+ if (!consumed) {
+ // Propagate event to subcomponents
+ Component component = getComponentAt(x, y);
+
+ if (component != null) {
+ consumed = component.mouseWheel(scrollType, scrollAmount, wheelRotation,
+ x - component.getX(), y - component.getY());
+ }
+
+ // Notify the base class
+ if (!consumed) {
+ consumed = super.mouseWheel(scrollType, scrollAmount, wheelRotation, x, y);
+ }
+ }
+ }
+
+ return consumed;
+ }
+
+ public ListenerList<ContainerListener> getContainerListeners() {
+ return containerListeners;
+ }
+
+ public ListenerList<ContainerMouseListener> getContainerMouseListeners() {
+ return containerMouseListeners;
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ContainerListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ContainerListener.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ContainerListener.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ContainerListener.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * 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 pivot.wtk;
+
+import pivot.collections.Sequence;
+
+/**
+ * Container listener interface.
+ *
+ * @author gbrown
+ */
+public interface ContainerListener {
+ /**
+ * Called when a component has been inserted into a container's component
+ * sequence.
+ *
+ * @param container
+ * @param index
+ */
+ public void componentInserted(Container container, int index);
+
+ /**
+ * Called when components have been removed from a container's component
+ * sequence.
+ *
+ * @param container
+ * @param index
+ * @param removed
+ */
+ public void componentsRemoved(Container container, int index, Sequence<Component> removed);
+
+ /**
+ * Called when a container's context key has changed.
+ *
+ * @param container
+ * @param previousContextKey
+ */
+ public void contextKeyChanged(Container container, String previousContextKey);
+
+ /**
+ * Called when a container's focus traversal policy has changed.
+ *
+ * @param container
+ * @param previousFocusTraversalPolicy
+ */
+ public void focusTraversalPolicyChanged(Container container,
+ FocusTraversalPolicy previousFocusTraversalPolicy);
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ContainerMouseListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ContainerMouseListener.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ContainerMouseListener.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ContainerMouseListener.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * 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 pivot.wtk;
+
+/**
+ * Container mouse listener interface. Container mouse events are "tunneling"
+ * events that are fired as the event propagates down the component hierarchy.
+ *
+ * @author gbrown
+ */
+public interface ContainerMouseListener {
+ /**
+ * Called when the mouse is moved over a container.
+ *
+ * @param container
+ * @param x
+ * @param y
+ *
+ * @return
+ * <tt>true</tt> to consume the event; <tt>false</tt> to allow it to
+ * propagate.
+ */
+ public boolean mouseMove(Container container, int x, int y);
+
+ /**
+ * Called when the mouse is pressed over a container.
+ *
+ * @param container
+ * @param button
+ * @param x
+ * @param y
+ *
+ * @return
+ * <tt>true</tt> to consume the event; <tt>false</tt> to allow it to
+ * propagate.
+ */
+ public boolean mouseDown(Container container, Mouse.Button button, int x, int y);
+
+ /**
+ * Called when the mouse is released over a container.
+ *
+ * @param container
+ * @param button
+ * @param x
+ * @param y
+ *
+ * @return
+ * <tt>true</tt> to consume the event; <tt>false</tt> to allow it to
+ * propagate.
+ */
+ public boolean mouseUp(Container container, Mouse.Button button, int x, int y);
+
+ /**
+ * Called when the mouse wheel is scrolled over a container.
+ *
+ * @param container
+ * @param scrollType
+ * @param scrollAmount
+ * @param wheelRotation
+ * @param x
+ * @param y
+ *
+ * @return
+ * <tt>true</tt> to consume the event; <tt>false</tt> to allow it to
+ * propagate.
+ */
+ public boolean mouseWheel(Container container, Mouse.ScrollType scrollType,
+ int scrollAmount, int wheelRotation, int x, int y);
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/CornerRadii.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/CornerRadii.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/CornerRadii.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/CornerRadii.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * 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 pivot.wtk;
+
+import pivot.collections.Dictionary;
+
+/**
+ * Class representing the corner radii of a rectangular object.
+ *
+ * @author gbrown
+ */
+public class CornerRadii {
+ public int topLeft = 0;
+ public int topRight = 0;
+ public int bottomLeft = 0;
+ public int bottomRight = 0;
+
+ public static final String TOP_LEFT_KEY = "topLeft";
+ public static final String TOP_RIGHT_KEY = "topRight";
+ public static final String BOTTOM_LEFT_KEY = "bottomLeft";
+ public static final String BOTTOM_RIGHT_KEY = "bottomRight";
+
+ public CornerRadii() {
+ }
+
+ public CornerRadii(int radius) {
+ this(radius, radius, radius, radius);
+ }
+
+ public CornerRadii(Dictionary<String, ?> cornerRadii) {
+ if (cornerRadii == null) {
+ throw new IllegalArgumentException("cornerRadii is null.");
+ }
+
+ if (cornerRadii.containsKey(TOP_LEFT_KEY)) {
+ topLeft = (Integer)cornerRadii.get(TOP_LEFT_KEY);
+ }
+
+ if (cornerRadii.containsKey(TOP_RIGHT_KEY)) {
+ topRight = (Integer)cornerRadii.get(TOP_RIGHT_KEY);
+ }
+
+ if (cornerRadii.containsKey(BOTTOM_LEFT_KEY)) {
+ bottomLeft = (Integer)cornerRadii.get(BOTTOM_LEFT_KEY);
+ }
+
+ if (cornerRadii.containsKey(BOTTOM_RIGHT_KEY)) {
+ bottomRight = (Integer)cornerRadii.get(BOTTOM_RIGHT_KEY);
+ }
+ }
+
+ public CornerRadii(CornerRadii cornerRadii) {
+ if (cornerRadii == null) {
+ throw new IllegalArgumentException("cornerRadii is null.");
+ }
+
+ this.topLeft = cornerRadii.topLeft;
+ this.topRight = cornerRadii.topRight;
+ this.bottomLeft = cornerRadii.bottomLeft;
+ this.bottomRight = cornerRadii.bottomRight;
+ }
+
+ public CornerRadii(int topLeft, int topRight, int bottomLeft, int bottomRight) {
+ this.topLeft = topLeft;
+ this.topRight = topRight;
+ this.bottomLeft = bottomLeft;
+ this.bottomRight = bottomRight;
+ }
+
+ public boolean equals(Object object) {
+ boolean equals = false;
+
+ if (object instanceof CornerRadii) {
+ CornerRadii cornerRadii = (CornerRadii)object;
+ equals = (topLeft == cornerRadii.topLeft
+ && topRight == cornerRadii.topRight
+ && bottomLeft == cornerRadii.bottomLeft
+ && bottomRight == cornerRadii.bottomRight);
+ }
+
+ return equals;
+ }
+
+ public String toString() {
+ return getClass().getName() + " [" + topLeft + ", " + topRight
+ + bottomLeft + ", " + bottomRight + "]";
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Cursor.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Cursor.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Cursor.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Cursor.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * 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 pivot.wtk;
+
+/**
+ * Enumeration defining the supported mouse cursor types.
+ *
+ * @author gbrown
+ */
+public enum Cursor {
+ DEFAULT,
+ HAND,
+ TEXT,
+ WAIT,
+ CROSSHAIR,
+ MOVE,
+ RESIZE_NORTH,
+ RESIZE_SOUTH,
+ RESIZE_EAST,
+ RESIZE_WEST,
+ RESIZE_NORTH_EAST,
+ RESIZE_NORTH_WEST,
+ RESIZE_SOUTH_EAST,
+ RESIZE_SOUTH_WEST;
+
+ public static Cursor decode(String value) {
+ if (value == null) {
+ throw new IllegalArgumentException("value is null.");
+ }
+
+ Cursor cursor = null;
+
+ if (value.equalsIgnoreCase("default")) {
+ cursor = Cursor.DEFAULT;
+ } else if (value.equalsIgnoreCase("hand")) {
+ cursor = Cursor.HAND;
+ } else if (value.equalsIgnoreCase("text")) {
+ cursor = Cursor.TEXT;
+ } else if (value.equalsIgnoreCase("wait")) {
+ cursor = Cursor.WAIT;
+ } else if (value.equalsIgnoreCase("crosshair")) {
+ cursor = Cursor.CROSSHAIR;
+ } else if (value.equalsIgnoreCase("move")) {
+ cursor = Cursor.MOVE;
+ } else if (value.equalsIgnoreCase("resizeNorth")) {
+ cursor = Cursor.RESIZE_NORTH;
+ } else if (value.equalsIgnoreCase("resizeSouth")) {
+ cursor = Cursor.RESIZE_SOUTH;
+ } else if (value.equalsIgnoreCase("resizeEast")) {
+ cursor = Cursor.RESIZE_EAST;
+ } else if (value.equalsIgnoreCase("resizeWest")) {
+ cursor = Cursor.RESIZE_WEST;
+ } else if (value.equalsIgnoreCase("resizeNorthEast")) {
+ cursor = Cursor.RESIZE_NORTH_EAST;
+ } else if (value.equalsIgnoreCase("resizeNorthWest")) {
+ cursor = Cursor.RESIZE_NORTH_WEST;
+ } else if (value.equalsIgnoreCase("resizeSouthEast")) {
+ cursor = Cursor.RESIZE_SOUTH_EAST;
+ } else if (value.equalsIgnoreCase("resizeSouthWest")) {
+ cursor = Cursor.RESIZE_SOUTH_WEST;
+ } else {
+ throw new IllegalArgumentException("\"" + value
+ + "\" is not a valid cursor.");
+ }
+
+ return cursor;
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DesktopApplicationContext.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DesktopApplicationContext.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DesktopApplicationContext.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DesktopApplicationContext.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * 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 pivot.wtk;
+
+import java.awt.AWTEvent;
+import java.awt.Graphics;
+import java.awt.event.WindowEvent;
+
+import pivot.collections.HashMap;
+import pivot.collections.immutable.ImmutableMap;
+import pivot.wtk.media.Image;
+import pivot.wtk.media.Picture;
+
+/**
+ * Application context used to execute applications in a native frame
+ * window.
+ *
+ * @author gbrown
+ */
+@SuppressWarnings("deprecation")
+public final class DesktopApplicationContext extends ApplicationContext {
+ private static class HostFrame extends java.awt.Frame {
+ private static final long serialVersionUID = 0;
+
+ private HostFrame() {
+ enableEvents(AWTEvent.WINDOW_EVENT_MASK
+ | AWTEvent.WINDOW_STATE_EVENT_MASK);
+
+ // Add the display host
+ add(applicationContext.getDisplayHost());
+
+ // Disable focus traversal keys
+ setFocusTraversalKeysEnabled(false);
+
+ // Clear the background
+ setBackground(null);
+ }
+
+ @Override
+ public void update(Graphics graphics) {
+ paint(graphics);
+ }
+
+ @Override
+ public void processWindowEvent(WindowEvent event) {
+ super.processWindowEvent(event);
+
+ switch(event.getID()) {
+ case WindowEvent.WINDOW_OPENED: {
+ applicationContext.getDisplayHost().requestFocus();
+
+ createTimer();
+
+ try {
+ application.startup(applicationContext.getDisplay(),
+ new ImmutableMap<String, String>(properties));
+ } catch(Exception exception) {
+ exception.printStackTrace();
+ String message = exception.getMessage();
+ if (message == null) {
+ message = exception.getClass().getName();
+ }
+
+ Alert.alert(MessageType.ERROR, message, applicationContext.getDisplay());
+ }
+
+ break;
+ }
+
+ case WindowEvent.WINDOW_CLOSING: {
+ boolean shutdown = true;
+
+ try {
+ shutdown = application.shutdown(true);
+ } catch(Exception exception) {
+ exception.printStackTrace();
+ Alert.alert(MessageType.ERROR, exception.getMessage(),
+ applicationContext.getDisplay());
+ }
+
+ if (shutdown) {
+ destroyTimer();
+
+ java.awt.Window window = event.getWindow();
+ window.setVisible(false);
+ window.dispose();
+ }
+
+ break;
+ }
+
+ case WindowEvent.WINDOW_CLOSED: {
+ exit();
+ break;
+ }
+ }
+ }
+
+ @Override
+ protected void processWindowStateEvent(WindowEvent event) {
+ super.processWindowStateEvent(event);
+
+ switch(event.getID()) {
+ case WindowEvent.WINDOW_ICONIFIED: {
+ try {
+ application.suspend();
+ } catch(Exception exception) {
+ exception.printStackTrace();
+ Alert.alert(MessageType.ERROR, exception.getMessage(),
+ applicationContext.getDisplay());
+ }
+
+ break;
+ }
+
+ case WindowEvent.WINDOW_DEICONIFIED: {
+ try {
+ application.resume();
+ } catch(Exception exception) {
+ exception.printStackTrace();
+ Alert.alert(MessageType.ERROR, exception.getMessage(),
+ applicationContext.getDisplay());
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
+ private static DesktopApplicationContext applicationContext = null;
+ private static HashMap<String, String> properties = null;
+ private static Application application = null;
+
+ private static int x = 0;
+ private static int y = 0;
+ private static int width = 800;
+ private static int height = 600;
+ private static boolean center = false;
+ private static boolean resizable = true;
+
+ private static final String DEFAULT_HOST_FRAME_TITLE = "Pivot"; // TODO i18n
+
+ private static final String X_ARGUMENT = "x";
+ private static final String Y_ARGUMENT = "y";
+ private static final String WIDTH_ARGUMENT = "width";
+ private static final String HEIGHT_ARGUMENT = "height";
+ private static final String CENTER_ARGUMENT = "center";
+ private static final String RESIZABLE_ARGUMENT = "resizable";
+
+ /**
+ * Terminates the application context.
+ */
+ public static void exit() {
+ System.exit(0);
+ }
+
+ public static void main(String[] args) throws Exception {
+ // Get the application class name and startup properties
+ String applicationClassName = null;
+ properties = new HashMap<String, String>();
+
+ for (int i = 0, n = args.length; i < n; i++) {
+ String arg = args[i];
+
+ if (i == 0) {
+ applicationClassName = arg;
+ } else {
+ String[] property = arg.split(":");
+
+ if (property.length == 2) {
+ String key = property[0];
+ String value = property[1];
+
+ if (key.equals(X_ARGUMENT)) {
+ x = Integer.parseInt(value);
+ } else if (key.equals(Y_ARGUMENT)) {
+ y = Integer.parseInt(value);
+ } else if (key.equals(WIDTH_ARGUMENT)) {
+ width = Integer.parseInt(value);
+ } else if (key.equals(HEIGHT_ARGUMENT)) {
+ height = Integer.parseInt(value);
+ } else if (key.equals(CENTER_ARGUMENT)) {
+ center = Boolean.parseBoolean(value);
+ } else if (key.equals(RESIZABLE_ARGUMENT)) {
+ resizable = Boolean.parseBoolean(value);
+ } else {
+ properties.put(key, value);
+ }
+ } else {
+ System.err.println(arg + " is not a valid startup property.");
+ }
+ }
+ }
+
+ // Create the application context
+ applicationContext = new DesktopApplicationContext();
+
+ // Load the application
+ if (applicationClassName == null) {
+ System.err.println("Application class name is required.");
+ } else {
+ Class<?> applicationClass = Class.forName(applicationClassName);
+ application = (Application)applicationClass.newInstance();
+ }
+
+ // Create the host frame
+ final HostFrame hostFrame = new HostFrame();
+ hostFrame.setTitle(DEFAULT_HOST_FRAME_TITLE);
+
+ hostFrame.setSize(width, height);
+ hostFrame.setResizable(resizable);
+
+ if (center) {
+ java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
+ hostFrame.setLocation((screenSize.width - width) / 2, (screenSize.height - height) / 2);
+ } else {
+ hostFrame.setLocation(x, y);
+ }
+
+ // Open the window and focus the display host
+ hostFrame.setVisible(true);
+
+ Window.getWindowClassListeners().add(new WindowClassListener() {
+ public void activeWindowChanged(Window previousActiveWindow) {
+ ApplicationContext.queueCallback(new Runnable() {
+ public void run() {
+ Window activeWindow = Window.getActiveWindow();
+
+ if (activeWindow == null) {
+ hostFrame.setTitle(DEFAULT_HOST_FRAME_TITLE);
+ } else {
+ Window rootOwner = activeWindow.getRootOwner();
+ hostFrame.setTitle(rootOwner.getTitle());
+
+ Image rootIcon = rootOwner.getIcon();
+ if (rootIcon instanceof Picture) {
+ Picture rootPicture = (Picture)rootIcon;
+ hostFrame.setIconImage(rootPicture.getBufferedImage());
+ }
+ }
+ }
+ });
+ }
+ });
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Dialog.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Dialog.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Dialog.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Dialog.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * 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 pivot.wtk;
+
+import pivot.util.ListenerList;
+import pivot.util.Vote;
+
+/**
+ * Window class whose primary purpose is to facilitate interaction between
+ * an application and a user.
+ *
+ * @author gbrown
+ */
+public class Dialog extends Frame {
+ private static class DialogStateListenerList extends ListenerList<DialogStateListener>
+ implements DialogStateListener {
+ public Vote previewDialogClose(Dialog dialog, boolean result) {
+ Vote vote = Vote.APPROVE;
+
+ for (DialogStateListener listener : this) {
+ vote = vote.tally(listener.previewDialogClose(dialog, result));
+ }
+
+ return vote;
+ }
+
+ public void dialogCloseVetoed(Dialog dialog, Vote reason) {
+ for (DialogStateListener listener : this) {
+ listener.dialogCloseVetoed(dialog, reason);
+ }
+ }
+
+ public void dialogClosed(Dialog dialog) {
+ for (DialogStateListener listener : this) {
+ listener.dialogClosed(dialog);
+ }
+ }
+ }
+
+ private class RepositionCallback implements Runnable {
+ private static final float GOLDEN_SECTION = 0.382f;
+
+ public void run() {
+ Window owner = getOwner();
+
+ if (owner == null) {
+ throw new IllegalStateException("Dialog has no owner.");
+ }
+
+ int deltaWidth = owner.getWidth() - getWidth();
+ int deltaHeight = owner.getHeight() - getHeight();
+
+ int x = Math.max(0, Math.round(owner.getX() + 0.5f * deltaWidth));
+ int y = Math.max(0, Math.round(owner.getY() + GOLDEN_SECTION * deltaHeight));
+
+ setLocation(x, y);
+ }
+ }
+
+ private boolean modal = false;
+ private DialogCloseListener dialogCloseListener = null;
+ private Window disabledOwner = null;
+ private boolean result = false;
+
+ private DialogStateListenerList dialogStateListeners = new DialogStateListenerList();
+
+ public Dialog() {
+ this(null, null);
+ }
+
+ public Dialog(String title) {
+ this(title, null);
+ }
+
+ public Dialog(Component content) {
+ this(null, content);
+ }
+
+ public Dialog(String title, Component content) {
+ super(title, content);
+ installSkin(Dialog.class);
+ }
+
+ /**
+ * Opens the dialog.
+ *
+ * @param display
+ */
+ public final void open(Display display) {
+ open(display, null);
+ }
+
+ /**
+ * Opens the dialog.
+ *
+ * @param display
+ * @param dialogCloseListener
+ */
+ public void open(Display display, DialogCloseListener dialogCloseListener) {
+ super.open(display);
+
+ if (isOpen()) {
+ this.dialogCloseListener = dialogCloseListener;
+ this.modal = false;
+ }
+ }
+
+ /**
+ * Opens the dialog as modal over its owner.
+ *
+ * @param owner
+ */
+ public final void open(Window owner) {
+ open(owner, true, null);
+ }
+
+ /**
+ * Opens the dialog.
+ *
+ * @param owner
+ * @param modal
+ */
+ public final void open(Window owner, boolean modal) {
+ open(owner, modal, null);
+ }
+
+ /**
+ * Opens the dialog as modal over its owner.
+ *
+ * @param owner
+ * The dialog's owner.
+ *
+ * @param dialogCloseListener
+ * Optional dialog close listener to be called when the dialog is closed.
+ */
+ public final void open(Window owner, DialogCloseListener dialogCloseListener) {
+ open(owner, true, dialogCloseListener);
+ }
+
+ /**
+ * Opens the dialog.
+ *
+ * @param owner
+ * The dialog's owner.
+ *
+ * @param modal
+ * If <tt>true</tt>, the dialog is opened as modal, disabling its owner
+ * tree.
+ *
+ * @param dialogCloseListener
+ * Optional dialog close listener to be called when the dialog is closed.
+ */
+ public void open(Window owner, boolean modal, DialogCloseListener dialogCloseListener) {
+ super.open(owner);
+
+ if (isOpen()) {
+ this.dialogCloseListener = dialogCloseListener;
+ this.modal = modal;
+
+ if (modal) {
+ if (!owner.isEnabled()) {
+ throw new IllegalStateException("Owner is already disabled.");
+ }
+
+ // Walk owner tree to find the nearest enabled owning ancestor
+ // and disable it
+ Window disabledOwner = null;
+
+ while (owner != null
+ && owner.isEnabled()) {
+ disabledOwner = owner;
+ owner = owner.getOwner();
+ }
+
+ // Disable the ancestor and maintain a reference to it so we can
+ // enable it when this dialog is closed
+ if (disabledOwner != null) {
+ disabledOwner.setEnabled(false);
+ }
+
+ this.disabledOwner = disabledOwner;
+
+ // Disabling the owner tree also disabled this dialog; re-enable it
+ // and make it the active window
+ setEnabled(true);
+ setActiveWindow(this);
+
+ // Align the dialog with its owner
+ ApplicationContext.queueCallback(new RepositionCallback());
+ }
+ }
+ }
+
+ @Override
+ public final void close() {
+ close(false);
+ }
+
+ public void close(boolean result) {
+ if (!isClosed()) {
+ Vote vote = dialogStateListeners.previewDialogClose(this, result);
+
+ if (vote == Vote.APPROVE) {
+ super.close();
+
+ if (isClosed()) {
+ this.result = result;
+
+ // Enable the ancestor that was disabled when this dialog
+ // was opened
+ if (disabledOwner != null) {
+ disabledOwner.setEnabled(true);
+
+ // Move the owner to the front
+ if (modal) {
+ disabledOwner.moveToFront();
+ }
+ }
+
+ modal = false;
+ disabledOwner = null;
+
+ // Notify listeners
+ if (dialogCloseListener != null) {
+ dialogCloseListener.dialogClosed(this);
+ dialogCloseListener = null;
+ }
+
+ dialogStateListeners.dialogClosed(this);
+ }
+ } else {
+ dialogStateListeners.dialogCloseVetoed(this, vote);
+ }
+ }
+ }
+
+ public boolean isModal() {
+ return modal;
+ }
+
+ public DialogCloseListener getDialogCloseListener() {
+ return dialogCloseListener;
+ }
+
+ public Window getDisabledOwner() {
+ return disabledOwner;
+ }
+
+ public boolean getResult() {
+ return result;
+ }
+
+ public ListenerList<DialogStateListener> getDialogStateListeners() {
+ return dialogStateListeners;
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DialogCloseListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DialogCloseListener.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DialogCloseListener.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DialogCloseListener.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * 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 pivot.wtk;
+
+/**
+ * Dialog close listener interface.
+ *
+ * @author gbrown
+ */
+public interface DialogCloseListener {
+ /**
+ * Called when a dialog has closed.
+ *
+ * @param dialog
+ */
+ public void dialogClosed(Dialog dialog);
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DialogStateListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DialogStateListener.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DialogStateListener.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DialogStateListener.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * 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 pivot.wtk;
+
+import pivot.util.Vote;
+
+/**
+ * Dialog state listener interface.
+ *
+ * @author tvolkert
+ * @author gbrown
+ */
+public interface DialogStateListener extends DialogCloseListener {
+ /**
+ * Called to preview a dialog close event.
+ *
+ * @param dialog
+ * @param result
+ */
+ public Vote previewDialogClose(Dialog dialog, boolean result);
+
+ /**
+ * Called when a dialog close event has been vetoed.
+ *
+ * @param dialog
+ * @param reason
+ */
+ public void dialogCloseVetoed(Dialog dialog, Vote reason);
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Dimensions.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Dimensions.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Dimensions.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Dimensions.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * 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 pivot.wtk;
+
+import pivot.collections.Dictionary;
+
+/**
+ * Class representing the dimensions of an object.
+ *
+ * @author gbrown
+ */
+public class Dimensions {
+ public int width = 0;
+ public int height = 0;
+
+ public static final String WIDTH_KEY = "width";
+ public static final String HEIGHT_KEY = "height";
+
+ public Dimensions() {
+ }
+
+ public Dimensions(Dictionary<String, ?> dimensions) {
+ if (dimensions == null) {
+ throw new IllegalArgumentException("dimensions is null.");
+ }
+
+ if (dimensions.containsKey(WIDTH_KEY)) {
+ width = (Integer)dimensions.get(WIDTH_KEY);
+ }
+
+ if (dimensions.containsKey(HEIGHT_KEY)) {
+ height = (Integer)dimensions.get(HEIGHT_KEY);
+ }
+ }
+
+ public Dimensions(int width, int height) {
+ this.width = width;
+ this.height = height;
+ }
+
+ public Dimensions(Dimensions dimensions) {
+ if (dimensions == null) {
+ throw new IllegalArgumentException("dimensions is null.");
+ }
+
+ this.width = dimensions.width;
+ this.height = dimensions.height;
+ }
+
+ public boolean equals(Object object) {
+ boolean equals = false;
+
+ if (object instanceof Dimensions) {
+ Dimensions dimensions = (Dimensions)object;
+ equals = (width == dimensions.width
+ && height == dimensions.height);
+ }
+
+ return equals;
+ }
+
+ public String toString() {
+ return getClass().getName() + " [" + width + "x" + height + "]";
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Direction.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Direction.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Direction.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Direction.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * 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 pivot.wtk;
+
+/**
+ * Enumeration representing a two-dimensional direction.
+ *
+ * @author gbrown
+ */
+public enum Direction {
+ FORWARD,
+ BACKWARD;
+
+ public static Direction decode(String value) {
+ return valueOf(value.toUpperCase());
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Display.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Display.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Display.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Display.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * 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 pivot.wtk;
+
+import java.awt.Graphics2D;
+import pivot.wtk.skin.DisplaySkin;
+
+/**
+ * Container that serves as the root of a component hierarchy.
+ *
+ * @author gbrown
+ */
+public final class Display extends Container {
+ private class ValidateCallback implements Runnable {
+ public void run() {
+ validate();
+ if (!paintPending) {
+ validateCallback = null;
+ }
+ }
+ }
+
+ private ApplicationContext.DisplayHost displayHost;
+ private ValidateCallback validateCallback = null;
+ private boolean paintPending = false;
+
+ protected Display(ApplicationContext.DisplayHost displayHost) {
+ this.displayHost = displayHost;
+ super.setSkin(new DisplaySkin());
+ }
+
+ public ApplicationContext.DisplayHost getDisplayHost() {
+ return displayHost;
+ }
+
+ public Point getMouseLocation() {
+ return displayHost.getMouseLocation();
+ }
+
+ @Override
+ protected void setSkin(Skin skin) {
+ throw new UnsupportedOperationException("Can't replace Display skin.");
+ }
+
+ @Override
+ protected void setParent(Container parent) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setLocation(int x, int y) {
+ throw new UnsupportedOperationException("Can't change the location of the display.");
+ }
+
+ @Override
+ public void invalidate() {
+ if (validateCallback == null) {
+ validateCallback = new ValidateCallback();
+ ApplicationContext.queueCallback(validateCallback);
+ }
+
+ super.invalidate();
+ }
+
+ @Override
+ public void repaint(int x, int y, int width, int height, boolean immediate) {
+ if (immediate) {
+ Graphics2D graphics = (Graphics2D)displayHost.getGraphics();
+ graphics.clipRect(x, y, width, height);
+ paint(graphics);
+ graphics.dispose();
+ } else {
+ displayHost.repaint(x, y, width, height);
+ paintPending = true;
+ }
+ }
+
+ @Override
+ public void paint(Graphics2D graphics) {
+ super.paint(graphics);
+ paintPending = false;
+
+ if (validateCallback != null) {
+ ApplicationContext.queueCallback(validateCallback);
+ }
+ }
+
+ @Override
+ public void insert(Component component, int index) {
+ if (!(component instanceof Window)) {
+ throw new IllegalArgumentException("component must be an instance "
+ + "of " + Window.class);
+ }
+
+ super.insert(component, index);
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DragSource.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DragSource.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DragSource.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DragSource.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * 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 pivot.wtk;
+
+/**
+ * Interface representing a drag source.
+ *
+ * @author gbrown
+ */
+public interface DragSource {
+ /**
+ * Called by the framework to initiate a drag operation.
+ *
+ * @param component
+ * @param x
+ * @param y
+ *
+ * @return
+ * <tt>true</tt> to accept the drag; <tt>false</tt> to reject it.
+ */
+ public boolean beginDrag(Component component, int x, int y);
+
+ /**
+ * Called by the framework to terminate a drag operation.
+ *
+ * @param component
+ * @param dropAction
+ */
+ public void endDrag(Component component, DropAction dropAction);
+
+ /**
+ * Returns the drag source's native flag.
+ *
+ * @return
+ * If <tt>true</tt>, the drag will be executed via the native OS. Otherwise,
+ * it will be executed locally.
+ */
+ public boolean isNative();
+
+ /**
+ * Returns the drag content.
+ */
+ public LocalManifest getContent();
+
+ /**
+ * Returns a visual representing the drag content.
+ *
+ * @return
+ * The drag visual, or <tt>null</tt> for no visual.
+ */
+ public Visual getRepresentation();
+
+ /**
+ * Returns the offset of the mouse pointer within the drag visual. Not
+ * required unless a representation is specified.
+ *
+ * @return
+ * The mouse offset within the drag visual, or <tt>null</tt> if no visual
+ * is specified.
+ */
+ public Point getOffset();
+
+ /**
+ * Returns the drop actions supported by this drag source.
+ *
+ * @return
+ * A bitfield of the supported drop actions.
+ */
+ public int getSupportedDropActions();
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DropAction.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DropAction.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DropAction.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DropAction.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * 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 pivot.wtk;
+
+/**
+ * Enumeration defining supported drop actions.
+ *
+ * @author gbrown
+ */
+public enum DropAction {
+ COPY,
+ MOVE,
+ LINK;
+
+ public int getMask() {
+ return 1 << ordinal();
+ }
+
+ public boolean isSelected(int dropActions) {
+ return ((dropActions & getMask()) > 0);
+ }
+
+ public static DropAction decode(String value) {
+ return valueOf(value.toUpperCase());
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DropTarget.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DropTarget.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DropTarget.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/DropTarget.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * 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 pivot.wtk;
+
+/**
+ * Interface representing a drop target.
+ *
+ * @author gbrown
+ */
+public interface DropTarget {
+ /**
+ * Called when the mouse first enters a drop target during a drag
+ * operation.
+ *
+ * @param component
+ * @param dragContent
+ * @param supportedDropActions
+ * @param userDropAction
+ *
+ * @return
+ * The drop action that would result if the user dropped the item at this
+ * location, or <tt>null</tt> if the target cannot accept the drop.
+ */
+ public DropAction dragEnter(Component component, Manifest dragContent,
+ int supportedDropActions, DropAction userDropAction);
+
+ /**
+ * Called when the mouse leaves a drop target during a drag operation.
+ *
+ * @param component
+ */
+ public void dragExit(Component component);
+
+ /**
+ * Called when the mouse is moved while positioned over a drop target
+ * during a drag operation.
+ *
+ * @param component
+ * @param dragContent
+ * @param supportedDropActions
+ * @param x
+ * @param y
+ * @param userDropAction
+ *
+ * @return
+ * The drop action that would result if the user dropped the item at this
+ * location, or <tt>null</tt> if the target cannot accept the drop.
+ */
+ public DropAction dragMove(Component component, Manifest dragContent,
+ int supportedDropActions, int x, int y, DropAction userDropAction);
+
+ /**
+ * Called when the user drop action changes while the mouse is positioned
+ * over a drop target during a drag operation.
+ *
+ * @param component
+ * @param dragContent
+ * @param supportedDropActions
+ * @param x
+ * @param y
+ * @param userDropAction
+ *
+ * @return
+ * The drop action that would result if the user dropped the item at this
+ * location, or <tt>null</tt> if the target cannot accept the drop.
+ */
+ public DropAction userDropActionChange(Component component, Manifest dragContent,
+ int supportedDropActions, int x, int y, DropAction userDropAction);
+
+ /**
+ * Called to drop the drag content.
+ *
+ * @param component
+ * @param dragContent
+ * @param supportedDropActions
+ * @param x
+ * @param y
+ * @param userDropAction
+ *
+ * @return
+ * The drop action used to perform the drop, or <tt>null</tt> if the target
+ * rejected the drop.
+ */
+ public DropAction drop(Component component, Manifest dragContent,
+ int supportedDropActions, int x, int y, DropAction userDropAction);
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Editor.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Editor.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Editor.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Editor.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2009 VMware, Inc.
+ *
+ * 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 pivot.wtk;
+
+/**
+ * Base interface for content editors.
+ *
+ * @author gbrown
+ */
+public interface Editor {
+ public boolean isEditing();
+ public void save();
+ public void cancel();
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Expander.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Expander.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Expander.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Expander.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * 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 pivot.wtk;
+
+import pivot.collections.Sequence;
+import pivot.util.ListenerList;
+import pivot.util.Vote;
+
+/**
+ * Navigation container that allows a user to expand and collapse a content
+ * component.
+ *
+ * @author tvolkert
+ */
+public class Expander extends Container {
+ private static class ExpanderListenerList extends ListenerList<ExpanderListener>
+ implements ExpanderListener {
+ public void titleChanged(Expander expander, String previousTitle) {
+ for (ExpanderListener listener : this) {
+ listener.titleChanged(expander, previousTitle);
+ }
+ }
+
+ public Vote previewExpandedChange(Expander expander) {
+ Vote vote = Vote.APPROVE;
+
+ for (ExpanderListener listener : this) {
+ vote = vote.tally(listener.previewExpandedChange(expander));
+ }
+
+ return vote;
+ }
+
+ public void expandedChangeVetoed(Expander expander, Vote reason) {
+ for (ExpanderListener listener : this) {
+ listener.expandedChangeVetoed(expander, reason);
+ }
+ }
+
+ public void expandedChanged(Expander expander) {
+ for (ExpanderListener listener : this) {
+ listener.expandedChanged(expander);
+ }
+ }
+
+ public void contentChanged(Expander expander, Component previousContent) {
+ for (ExpanderListener listener : this) {
+ listener.contentChanged(expander, previousContent);
+ }
+ }
+ }
+
+ private String title = null;
+ private boolean expanded = true;
+ private Component content = null;
+
+ private ExpanderListenerList expanderListeners = new ExpanderListenerList();
+
+ public Expander() {
+ installSkin(Expander.class);
+ }
+
+ /**
+ * Returns the expander's title.
+ *
+ * @return
+ * The pane's title, or <tt>null</tt> if no title is set.
+ */
+ public String getTitle() {
+ return title;
+ }
+
+ /**
+ * Sets the expander's title.
+ *
+ * @param title
+ * The new title, or <tt>null</tt> for no title.
+ */
+ public void setTitle(String title) {
+ String previousTitle = this.title;
+
+ if (previousTitle == null ^ title == null) {
+ this.title = title;
+ expanderListeners.titleChanged(this, previousTitle);
+ }
+ }
+
+ public boolean isExpanded() {
+ return expanded;
+ }
+
+ public void setExpanded(boolean expanded) {
+ if (expanded != this.expanded) {
+ Vote vote = expanderListeners.previewExpandedChange(this);
+
+ if (vote == Vote.APPROVE) {
+ this.expanded = expanded;
+ expanderListeners.expandedChanged(this);
+ } else {
+ expanderListeners.expandedChangeVetoed(this, vote);
+ }
+ }
+ }
+
+ public Component getContent() {
+ return content;
+ }
+
+ public void setContent(Component content) {
+ Component previousContent = this.content;
+
+ if (content != previousContent) {
+ this.content = null;
+
+ // Remove any previous content component
+ if (previousContent != null) {
+ remove(previousContent);
+ }
+
+ // Add the component
+ if (content != null) {
+ add(content);
+ }
+
+ this.content = content;
+
+ expanderListeners.contentChanged(this, previousContent);
+ }
+ }
+
+ @Override
+ public Sequence<Component> remove(int index, int count) {
+ for (int i = index, n = index + count; i < n; i++) {
+ Component component = get(i);
+ if (component == content) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ // Call the base method to remove the components
+ return super.remove(index, count);
+ }
+
+ public ListenerList<ExpanderListener> getExpanderListeners() {
+ return expanderListeners;
+ }
+}