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 [27/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/Window.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Window.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Window.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Window.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,975 @@
+/*
+ * 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.net.URL;
+
+import pivot.collections.ArrayList;
+import pivot.collections.ArrayStack;
+import pivot.collections.Dictionary;
+import pivot.collections.HashMap;
+import pivot.collections.Sequence;
+import pivot.util.ListenerList;
+import pivot.util.Vote;
+import pivot.wtk.media.Image;
+
+/**
+ * Top-level container representing the entry point into a user interface.
+ * Windows are direct descendants of the display.
+ *
+ * @author gbrown
+ */
+public class Window extends Container {
+ /**
+ * Action dictionary implementation.
+ *
+ * @author gbrown
+ */
+ public final class ActionDictionary
+ implements Dictionary<Keyboard.KeyStroke, Action> {
+ private ActionDictionary() {
+ }
+
+ public Action get(Keyboard.KeyStroke key) {
+ return actions.get(key);
+ }
+
+ public Action put(Keyboard.KeyStroke key, Action value) {
+ return actions.put(key, value);
+
+ // TODO Fire WindowActionListener#actionAdded()/actionUpdated()
+ }
+
+ public Action remove(Keyboard.KeyStroke key) {
+ return actions.remove(key);
+
+ // TODO Fire WindowActionListener#actionRemoved()
+ }
+
+ public boolean containsKey(Keyboard.KeyStroke key) {
+ return actions.containsKey(key);
+ }
+
+ public boolean isEmpty() {
+ return actions.isEmpty();
+ }
+ }
+
+ /**
+ * Window listener list.
+ *
+ * @author gbrown
+ */
+ private static class WindowListenerList extends ListenerList<WindowListener>
+ implements WindowListener {
+ public void titleChanged(Window window, String previousTitle) {
+ for (WindowListener listener : this) {
+ listener.titleChanged(window, previousTitle);
+ }
+ }
+
+ public void iconChanged(Window window, Image previousIcon) {
+ for (WindowListener listener : this) {
+ listener.iconChanged(window, previousIcon);
+ }
+ }
+
+ public void contentChanged(Window window, Component previousContent) {
+ for (WindowListener listener : this) {
+ listener.contentChanged(window, previousContent);
+ }
+ }
+
+ public void windowMoved(Window window, int from, int to) {
+ for (WindowListener listener : this) {
+ listener.windowMoved(window, from, to);
+ }
+ }
+
+ public void ownerChanged(Window window, Window previousOwner) {
+ for (WindowListener listener : this) {
+ listener.ownerChanged(window, previousOwner);
+ }
+ }
+
+ public void activeChanged(Window window) {
+ for (WindowListener listener : this) {
+ listener.activeChanged(window);
+ }
+ }
+
+ public void maximizedChanged(Window window) {
+ for (WindowListener listener : this) {
+ listener.maximizedChanged(window);
+ }
+ }
+ }
+
+ /**
+ * Window state listener list.
+ *
+ * @author gbrown
+ */
+ private static class WindowStateListenerList extends ListenerList<WindowStateListener>
+ implements WindowStateListener {
+ public Vote previewWindowOpen(Window window, Display display) {
+ Vote vote = Vote.APPROVE;
+
+ for (WindowStateListener listener : this) {
+ vote = vote.tally(listener.previewWindowOpen(window, display));
+ }
+
+ return vote;
+ }
+
+ public void windowOpenVetoed(Window window, Vote reason) {
+ for (WindowStateListener listener : this) {
+ listener.windowOpenVetoed(window, reason);
+ }
+ }
+
+ public void windowOpened(Window window) {
+ for (WindowStateListener listener : this) {
+ listener.windowOpened(window);
+ }
+ }
+
+ public Vote previewWindowClose(Window window) {
+ Vote vote = Vote.APPROVE;
+
+ for (WindowStateListener listener : this) {
+ vote = vote.tally(listener.previewWindowClose(window));
+ }
+
+ return vote;
+ }
+
+ public void windowCloseVetoed(Window window, Vote reason) {
+ for (WindowStateListener listener : this) {
+ listener.windowCloseVetoed(window, reason);
+ }
+ }
+
+ public void windowClosed(Window window, Display display) {
+ for (WindowStateListener listener : this) {
+ listener.windowClosed(window, display);
+ }
+ }
+ }
+
+ /**
+ * Window class listener list.
+ *
+ * @author tvolkert
+ */
+ private static class WindowClassListenerList
+ extends ListenerList<WindowClassListener>
+ implements WindowClassListener {
+ public void activeWindowChanged(Window previousActiveWindow) {
+ for (WindowClassListener listener : this) {
+ listener.activeWindowChanged(previousActiveWindow);
+ }
+ }
+ }
+
+ private boolean auxilliary;
+
+ private Window owner = null;
+ private ArrayList<Window> ownedWindows = new ArrayList<Window>();
+
+ private HashMap<Keyboard.KeyStroke, Action> actions = new HashMap<Keyboard.KeyStroke, Action>();
+ private ActionDictionary actionDictionary = new ActionDictionary();
+
+ private String title = null;
+ private Image icon = null;
+ private Component content = null;
+ private Component activeDescendant = null;
+
+ private boolean opening = false;
+ private boolean closing = false;
+
+ private boolean maximized = false;
+
+ private WindowListenerList windowListeners = new WindowListenerList();
+ private WindowStateListenerList windowStateListeners = new WindowStateListenerList();
+ private static WindowClassListenerList windowClassListeners = new WindowClassListenerList();
+
+ private static Window activeWindow = null;
+
+ public Window() {
+ this(null, false);
+ }
+
+ public Window(boolean auxilliary) {
+ this(null, auxilliary);
+ }
+
+ public Window(Component content) {
+ this(content, false);
+ }
+
+ public Window(Component content, boolean auxilliary) {
+ this.auxilliary = auxilliary;
+
+ setContent(content);
+ installSkin(Window.class);
+ }
+
+ @Override
+ protected void setParent(Container parent) {
+ if (parent != null
+ && (!(parent instanceof Display))) {
+ throw new IllegalArgumentException("Window parent must be null or display.");
+ }
+
+ if (parent == null
+ && isActive()) {
+ setActiveWindow(null);
+ }
+
+ super.setParent(parent);
+ }
+
+ @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);
+ }
+
+ /**
+ * Sets the displayable state of this window and all of its owned
+ * descendant windows.
+ *
+ * @param displayable
+ * If <tt>true</tt>, the window and its owned descendants are displayable;
+ * otherwise, they are not displayable.
+ */
+ @Override
+ public void setDisplayable(boolean displayable) {
+ super.setDisplayable(displayable);
+
+ if (!displayable) {
+ if (isActive()) {
+ setActiveWindow(null);
+ }
+ }
+
+ // Show/hide owned windows
+ for (Window ownedWindow : ownedWindows) {
+ ownedWindow.setDisplayable(displayable);
+ }
+ }
+
+ /**
+ * Sets the enabled state of this window and all of its owned
+ * descendant windows.
+ *
+ * @param enabled
+ * If <tt>true</tt>, the window and its owned descendants are enabled;
+ * otherwise, they are not enabled.
+ */
+ @Override
+ public void setEnabled(boolean enabled) {
+ if (isEnabled() != enabled) {
+ super.setEnabled(enabled);
+
+ if (isEnabled() == enabled) {
+ if (!enabled
+ && isActive()) {
+ setActiveWindow(null);
+ }
+
+ // Enable/disable owned windows
+ for (Window ownedWindow : ownedWindows) {
+ ownedWindow.setEnabled(enabled);
+ }
+ }
+ }
+ }
+
+ public Window getOwner() {
+ return owner;
+ }
+
+ public void setOwner(Window owner) {
+ if (owner != null
+ && owner.isAuxilliary()
+ && !isAuxilliary()) {
+ throw new IllegalArgumentException("Primary windows must have a"
+ + " primary owner.");
+ }
+
+ Window previousOwner = this.owner;
+
+ if (previousOwner != owner) {
+ if (previousOwner != null) {
+ previousOwner.ownedWindows.remove(this);
+ }
+
+ if (owner != null) {
+ owner.ownedWindows.add(this);
+ setDisplayable(owner.isDisplayable());
+ setEnabled(owner.isEnabled());
+ }
+
+ this.owner = owner;
+
+ windowListeners.ownerChanged(this, previousOwner);
+ }
+ }
+
+ public Window getRootOwner() {
+ return (owner == null) ? this : owner.getRootOwner();
+ }
+
+ public Window getOwnedWindow(int index) {
+ return ownedWindows.get(index);
+ }
+
+ public int getOwnedWindowCount() {
+ return ownedWindows.getLength();
+ }
+
+ /**
+ * Tests whether this window is an owning ancestor of a given window. A
+ * window is not considered an owner of itself.
+ *
+ * @param window
+ *
+ * @return
+ * <tt>true</tt> if this window is an owning ancestor of the given window;
+ * <tt>false</tt>, otherwise.
+ */
+ public boolean isOwner(Window window) {
+ if (window == null) {
+ throw new IllegalArgumentException("window is null.");
+ }
+
+ Window owner = window.getOwner();
+
+ while (owner != null
+ && owner != this) {
+ owner = owner.getOwner();
+ }
+
+ return (owner == this);
+ }
+
+ /**
+ * Returns this window's open state.
+ *
+ * @return
+ * <tt>true</tt> if the window is open; <tt>false</tt>, otherwise.
+ */
+ public boolean isOpen() {
+ return (getParent() != null);
+ }
+
+ /**
+ * Returns this window's opening state.
+ *
+ * @return
+ * <tt>true</tt> if the window is open; <tt>false</tt>, otherwise.
+ */
+ public boolean isOpening() {
+ return opening;
+ }
+
+ /**
+ * Opens the window. Opening a window adds it to the display's component
+ * sequence. If the window is activatable, it will become the active
+ * window.
+ *
+ * @param display
+ * The display on which the window will be opened.
+ */
+ public void open(Display display) {
+ if (display == null) {
+ throw new IllegalArgumentException("display is null.");
+ }
+
+ if (isOpen()
+ && getDisplay() != display) {
+ throw new IllegalStateException("Window is already open on a different display.");
+ }
+
+ if (owner != null
+ && !owner.isOpen()) {
+ throw new IllegalArgumentException("Owner is not open.");
+ }
+
+ if (owner != null
+ && owner.getDisplay() != display) {
+ throw new IllegalArgumentException("Owner is opened on a different display.");
+ }
+
+ if (!isOpen()
+ && !opening) {
+ Vote vote = windowStateListeners.previewWindowOpen(this, display);
+
+ if (vote == Vote.APPROVE) {
+ opening = true;
+
+ // Add this as child of display
+ display.add(this);
+
+ // Notify listeners
+ windowStateListeners.windowOpened(this);
+
+ // Move this window to the front (which, unless this window is
+ // disabled or incapable of becoming active, will activate the
+ // window)
+ moveToFront();
+
+ opening = false;
+ } else {
+ windowStateListeners.windowOpenVetoed(this, vote);
+ }
+ }
+ }
+
+ /**
+ * Opens the window.
+ *
+ * @param owner
+ * The window's owner.
+ */
+ public void open(Window owner) {
+ if (owner == null) {
+ throw new IllegalArgumentException("owner is null.");
+ }
+
+ if (isOpen()
+ && getOwner() != owner) {
+ throw new IllegalStateException("Window is already open with a different owner.");
+ }
+
+ setOwner(owner);
+ open(owner.getDisplay());
+ }
+
+ /**
+ * Returns this window's closed state.
+ *
+ * @return
+ * <tt>true</tt> if the window is closed; <tt>false</tt>, otherwise.
+ */
+ public boolean isClosed() {
+ return !isOpen();
+ }
+
+ /**
+ * Returns this window's closing state.
+ *
+ * @return
+ * <tt>true</tt> if the window is closing; <tt>false</tt>, otherwise.
+ */
+ public boolean isClosing() {
+ return closing;
+ }
+
+ /**
+ * Closes the window. Closing a window closes all owned windows and
+ * removes the window from the display's component sequence. If the window
+ * was the active window, the active window will be cleared. If the window
+ * was the focus host, the focused component will be cleared.
+ */
+ public void close() {
+ if (!isClosed()
+ && !closing) {
+ Vote vote = windowStateListeners.previewWindowClose(this);
+
+ if (vote.isApproved()) {
+ closing = true;
+
+ if (isActive()) {
+ setActiveWindow(null);
+ }
+
+ // Close all owned windows (create a copy of the owned window
+ // list so owned windows can remove themselves from the list
+ // without interrupting the iteration)
+ for (Window ownedWindow : new ArrayList<Window>(this.ownedWindows)) {
+ ownedWindow.close();
+ }
+
+ // Detach from display
+ Display display = getDisplay();
+ display.remove(this);
+
+ // Notify listeners
+ windowStateListeners.windowClosed(this, display);
+
+ closing = false;
+ } else {
+ windowStateListeners.windowCloseVetoed(this, vote);
+ }
+ }
+ }
+
+ /**
+ * Returns the window's title.
+ *
+ * @return
+ * The pane's title, or <tt>null</tt> if no title is set.
+ */
+ public String getTitle() {
+ return title;
+ }
+
+ /**
+ * Sets the window'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;
+ windowListeners.titleChanged(this, previousTitle);
+ }
+ }
+
+ /**
+ * Returns the window's icon.
+ *
+ * @return
+ * The window's icon, or <tt>null</tt> if the window has no icon.
+ */
+ public Image getIcon() {
+ return icon;
+ }
+
+ /**
+ * Sets the window's icon.
+ *
+ * @param icon
+ * The window's icon, or <tt>null</tt> for no icon.
+ */
+ public void setIcon(Image icon) {
+ Image previousIcon = this.icon;
+
+ if (previousIcon != icon) {
+ this.icon = icon;
+ windowListeners.iconChanged(this, previousIcon);
+ }
+ }
+
+ /**
+ * Sets the window's icon by URL.
+ *
+ * @param icon
+ * The location of the icon to set.
+ */
+ public void setIcon(URL icon) {
+ if (icon == null) {
+ throw new IllegalArgumentException("icon is null.");
+ }
+
+ setIcon(Image.load(icon));
+ }
+
+ /**
+ * Sets the window's icon by resource name.
+ *
+ * @param icon
+ * The resource name of the icon to set.
+ */
+ public void setIcon(String icon) {
+ if (icon == null) {
+ throw new IllegalArgumentException("icon is null.");
+ }
+
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ setIcon(classLoader.getResource(icon));
+ }
+
+ 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) {
+ insert(content, 0);
+ }
+
+ this.content = content;
+
+ windowListeners.contentChanged(this, previousContent);
+ }
+ }
+
+ /**
+ * Returns the window's auxilliary flag. Auxilliary windows must have an
+ * owner, can't become active, and can only own other auxilliary windows.
+ *
+ * @return
+ * <tt>true</tt> if this is an auxilliary window; <tt>false</tt>, otherwise.
+ */
+ public boolean isAuxilliary() {
+ return auxilliary;
+ }
+
+ /**
+ * Returns the window's active state.
+ *
+ * @return
+ * <tt>true</tt> if the window is active; <tt>false</tt>; otherwise.
+ */
+ public boolean isActive() {
+ return activeWindow == this;
+ }
+
+ /**
+ * Called to notify a window that its active state has changed.
+ *
+ * @param active
+ */
+ protected void setActive(boolean active) {
+ if (active) {
+ // If this window is still an ancestor of the active descendant
+ // and the active descendant can be focused, restore focus to it;
+ // otherwise, clear the active descendant
+ if (activeDescendant != null) {
+ if (isAncestor(activeDescendant)
+ && !activeDescendant.isBlocked()
+ && activeDescendant.isShowing()) {
+ activeDescendant.requestFocus(true);
+ } else {
+ activeDescendant = null;
+ }
+ }
+ } else {
+ // Temporarily clear the focus
+ clearFocus(true);
+ }
+
+ windowListeners.activeChanged(this);
+ }
+
+ /**
+ * Returns the currently active window.
+ *
+ * @return
+ * The window that is currently active, or <tt>null</tt> if no window
+ * is active.
+ */
+ public static Window getActiveWindow() {
+ return activeWindow;
+ }
+
+ /**
+ * Sets the active window. The window must be activatable, open, and
+ * enabled. If the window is not currently visible, it will be made
+ * visible.
+ *
+ * @param activeWindow
+ * The window to activate, or <tt>null</tt> to clear the active window.
+ */
+ public static void setActiveWindow(Window activeWindow) {
+ Window previousActiveWindow = Window.activeWindow;
+
+ if (previousActiveWindow != activeWindow) {
+ if (activeWindow != null) {
+ if (activeWindow.isAuxilliary()) {
+ throw new IllegalArgumentException("activeWindow is auxilliary.");
+ }
+
+ if (!activeWindow.isOpen()) {
+ throw new IllegalArgumentException("activeWindow is not open.");
+ }
+
+ if (!activeWindow.isEnabled()) {
+ throw new IllegalArgumentException("activeWindow is not enabled.");
+ }
+ }
+
+ // Set the active window
+ Window.activeWindow = activeWindow;
+
+ // Notify the windows of the state change
+ if (previousActiveWindow != null) {
+ previousActiveWindow.setActive(false);
+ }
+
+ // Activate the window
+ if (activeWindow != null) {
+ activeWindow.setActive(true);
+ }
+
+ windowClassListeners.activeWindowChanged(previousActiveWindow);
+ }
+ }
+
+ /**
+ * Returns the window descendant that currently has the focus.
+ */
+ public Component getActiveDescendant() {
+ return activeDescendant;
+ }
+
+ /**
+ * Sets the window's active descendant, the descendant that currently
+ * has the focus.
+ *
+ * @param activeDescendant
+ */
+ protected void setActiveDescendant(Component activeDescendant) {
+ this.activeDescendant = activeDescendant;
+ }
+
+ /**
+ * Returns the global action map for this window.
+ */
+ public ActionDictionary getActions() {
+ return actionDictionary;
+ }
+
+ /**
+ * Moves the window to the top of the window stack. The window is removed
+ * from its current position in the display's component sequence and
+ * appended to the end. It is also moved to the top of its owner's owned
+ * window list so it becomes top-most of all windows owned by its owner.
+ * <p>
+ * All windows owned by this window are subsequently moved to the front,
+ * ensuring that this window's owned windows remain on top of it.
+ * <p>
+ * Finally, the window is made active and focus is restored to the most
+ * recently focused decendant component.
+ */
+ public void moveToFront() {
+ if (!isOpen()) {
+ throw new IllegalStateException("Window is not open.");
+ }
+
+ // If this window is not currently top-most, move it to the top
+ Display display = getDisplay();
+
+ Window window = this;
+ ArrayStack<Integer> ownedWindowIndexes = new ArrayStack<Integer>();
+ ownedWindowIndexes.push(0);
+
+ while (ownedWindowIndexes.getLength() > 0) {
+ // Get the next owned window index for this window
+ int j = ownedWindowIndexes.peek();
+
+ if (j == 0) {
+ // Move the window within the window stack
+ int i = display.indexOf(window);
+
+ if (i < display.getLength() - 1) {
+ int k = display.getLength() - 1;
+ display.move(i, k);
+ window.windowListeners.windowMoved(window, i, k);
+ }
+ }
+
+ if (j < window.ownedWindows.getLength()) {
+ // There is another owned window to traverse; move down
+ // the tree
+ ownedWindowIndexes.poke(j + 1);
+ window = window.ownedWindows.get(j);
+
+ // If the window is not open, ignore it
+ if (window.isOpen()) {
+ ownedWindowIndexes.push(0);
+ } else {
+ window = window.owner;
+ }
+ } else {
+ // Activate the window
+ if (window.isEnabled()
+ && !window.isAuxilliary()) {
+ setActiveWindow(window);
+ }
+
+ // This was the last owned window for the current window; move
+ // up the tree
+ ownedWindowIndexes.pop();
+ window = window.owner;
+ }
+ }
+
+ // Move this window to the top of its owner's owned window list,
+ // so it becomes top-most of all windows owned by this window's
+ // owner
+ if (owner != null) {
+ int j = owner.ownedWindows.indexOf(this);
+
+ if (j < owner.ownedWindows.getLength() - 1) {
+ owner.ownedWindows.remove(j, 1);
+ owner.ownedWindows.add(this);
+ }
+ }
+ }
+
+ /**
+ * Moves the window to the bottom of the window stack. If the window is
+ * active, the active window will be cleared. If the window is the focus
+ * host, the focus will be cleared.
+ */
+ public void moveToBack() {
+ if (!isOpen()) {
+ throw new IllegalStateException("Window is not open.");
+ }
+
+ if (isActive()) {
+ setActiveWindow(null);
+ }
+
+ Display display = getDisplay();
+
+ // Ensure that the window and all of its owning ancestors are moved
+ // to the back
+ Window window = this;
+ while (window != null) {
+ // If this window is not currently bottom-most, move it to the
+ // bottom
+ int i = display.indexOf(window);
+
+ if (i > 0) {
+ display.move(i, 0);
+ window.windowListeners.windowMoved(window, i, 0);
+ }
+
+ window = window.getOwner();
+ }
+
+ // Move this window to the bottom of its owner's owned window list
+ if (owner != null) {
+ int j = owner.ownedWindows.indexOf(this);
+
+ if (j > 0) {
+ owner.ownedWindows.remove(j, 1);
+ owner.ownedWindows.insert(this, 0);
+ }
+ }
+ }
+
+ public boolean isMaximized() {
+ return maximized;
+ }
+
+ public void setMaximized(boolean maximized) {
+ if (maximized != this.maximized) {
+ this.maximized = maximized;
+
+ invalidate();
+
+ windowListeners.maximizedChanged(this);
+ }
+ }
+
+ public void align(Bounds bounds,
+ HorizontalAlignment horizontalAlignment,
+ VerticalAlignment verticalAlignment) {
+ align(bounds, horizontalAlignment, 0, verticalAlignment, 0);
+ }
+
+ public void align(Bounds bounds,
+ HorizontalAlignment horizontalAlignment, int horizontalOffset,
+ VerticalAlignment verticalAlignment, int verticalOffset) {
+
+ int x = 0;
+ int y = 0;
+
+ Dimensions size = getSize();
+
+ if (horizontalAlignment == HorizontalAlignment.LEFT) {
+ x = bounds.x - size.width;
+ }
+ else if (horizontalAlignment == HorizontalAlignment.RIGHT) {
+ x = bounds.x + bounds.width - size.width;
+ }
+ else if (horizontalAlignment == HorizontalAlignment.CENTER) {
+ x = bounds.x + (int)Math.round((double)(bounds.width - size.width) / 2);
+ }
+ else {
+ throw new IllegalArgumentException("Unsupported horizontal alignment.");
+ }
+
+ x += horizontalOffset;
+
+ if (verticalAlignment == VerticalAlignment.TOP) {
+ y = bounds.y - size.height;
+ }
+ else if (verticalAlignment == VerticalAlignment.BOTTOM) {
+ y = bounds.y + bounds.height;
+ }
+ else if (verticalAlignment == VerticalAlignment.CENTER) {
+ y = bounds.y + (int)Math.round((double)(bounds.height - size.height) / 2);
+ }
+ else {
+ throw new IllegalArgumentException("Unsupported vertical alignment.");
+ }
+
+ y += verticalOffset;
+
+ setLocation(x, y);
+ }
+
+ @Override
+ protected boolean mouseDown(Mouse.Button button, int x, int y) {
+ // NOTE This is done here rather than in WindowSkin because the
+ // user input methods are not called on the skin when the component
+ // is disabled
+
+ if (isEnabled()) {
+ // Bring this window to the front
+ moveToFront();
+ } else {
+ ApplicationContext.beep();
+
+ // Bring the window's owner tree to the front
+ Window rootOwner = getRootOwner();
+ rootOwner.moveToFront();
+ }
+
+ return super.mouseDown(button, x, y);
+ }
+
+ public ListenerList<WindowListener> getWindowListeners() {
+ return windowListeners;
+ }
+
+ public ListenerList<WindowStateListener> getWindowStateListeners() {
+ return windowStateListeners;
+ }
+
+ public static ListenerList<WindowClassListener> getWindowClassListeners() {
+ return windowClassListeners;
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/WindowClassListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/WindowClassListener.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/WindowClassListener.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/WindowClassListener.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;
+
+/**
+ * Window class listener interface.
+ *
+ * @author tvolkert
+ */
+public interface WindowClassListener {
+ /**
+ * Called when the active window has changed.
+ *
+ * @param previousActiveWindow
+ */
+ public void activeWindowChanged(Window previousActiveWindow);
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/WindowListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/WindowListener.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/WindowListener.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/WindowListener.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,80 @@
+/*
+ * 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.wtk.media.Image;
+
+/**
+ * Window listener interface.
+ *
+ * @author gbrown
+ */
+public interface WindowListener {
+ /**
+ * Called when a window's title has changed.
+ *
+ * @param window
+ * @param previousTitle
+ */
+ public void titleChanged(Window window, String previousTitle);
+
+ /**
+ * Called when a window's icon has changed.
+ *
+ * @param window
+ * @param previousIcon
+ */
+ public void iconChanged(Window window, Image previousIcon);
+
+ /**
+ * Called when a window's content component has changed.
+ *
+ * @param window
+ * @param previousContent
+ */
+ public void contentChanged(Window window, Component previousContent);
+
+ /**
+ * Called when a window's owner has changed.
+ *
+ * @param window
+ * @param previousOwner
+ */
+ public void ownerChanged(Window window, Window previousOwner);
+
+ /**
+ * Called when a window's active state has changed.
+ *
+ * @param window
+ */
+ public void activeChanged(Window window);
+
+ /**
+ * Called when a window's maximized state has changed.
+ *
+ * @param window
+ */
+ public void maximizedChanged(Window window);
+
+ /**
+ * Called when a window's position has changed.
+ *
+ * @param window
+ * @param from
+ * @param to
+ */
+ public void windowMoved(Window window, int from, int to);
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/WindowStateListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/WindowStateListener.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/WindowStateListener.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/WindowStateListener.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,72 @@
+/*
+ * 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;
+
+/**
+ * Window state listener interface.
+ *
+ * @author gbrown
+ * @author tvolkert
+ */
+public interface WindowStateListener {
+ /**
+ * Called to preview a window open event.
+ *
+ * @param window
+ * @param display
+ */
+ public Vote previewWindowOpen(Window window, Display display);
+
+ /**
+ * Called when a window open event has been vetoed.
+ *
+ * @param window
+ * @param reason
+ */
+ public void windowOpenVetoed(Window window, Vote reason);
+
+ /**
+ * Called when a window has opened.
+ *
+ * @param window
+ */
+ public void windowOpened(Window window);
+
+ /**
+ * Called to preview a window close event.
+ *
+ * @param window
+ */
+ public Vote previewWindowClose(Window window);
+
+ /**
+ * Called when a window close event has been vetoed.
+ *
+ * @param window
+ * @param reason
+ */
+ public void windowCloseVetoed(Window window, Vote reason);
+
+ /**
+ * Called when a window has closed.
+ *
+ * @param window
+ * @param display
+ */
+ public void windowClosed(Window window, Display display);
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ButtonData.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ButtonData.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ButtonData.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ButtonData.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,80 @@
+/*
+ * 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.content;
+
+import java.net.URL;
+
+import pivot.wtk.ApplicationContext;
+import pivot.wtk.media.Image;
+
+/**
+ * Default button data implementation.
+ *
+ * @author gbrown
+ */
+public class ButtonData {
+ private Image icon;
+ private String text;
+
+ public ButtonData() {
+ this(null, null);
+ }
+
+ public ButtonData(Image icon) {
+ this(icon, null);
+ }
+
+ public ButtonData(String text) {
+ this(null, text);
+ }
+
+ public ButtonData(Image icon, String text) {
+ this.icon = icon;
+ this.text = text;
+ }
+
+ public Image getIcon() {
+ return icon;
+ }
+
+ public void setIcon(Image icon) {
+ this.icon = icon;
+ }
+
+ public void setIcon(URL iconURL) {
+ Image icon = (Image)ApplicationContext.getResourceCache().get(iconURL);
+
+ if (icon == null) {
+ icon = Image.load(iconURL);
+ ApplicationContext.getResourceCache().put(iconURL, icon);
+ }
+
+ setIcon(icon);
+ }
+
+ public void setIcon(String iconName) {
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ setIcon(classLoader.getResource(iconName));
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ButtonDataRenderer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ButtonDataRenderer.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ButtonDataRenderer.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ButtonDataRenderer.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,108 @@
+/*
+ * 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.content;
+
+import java.awt.Color;
+import java.awt.Font;
+
+import pivot.wtk.Button;
+import pivot.wtk.Component;
+import pivot.wtk.FlowPane;
+import pivot.wtk.HorizontalAlignment;
+import pivot.wtk.VerticalAlignment;
+import pivot.wtk.ImageView;
+import pivot.wtk.Label;
+import pivot.wtk.media.Image;
+
+/**
+ * Default button data renderer.
+ *
+ * @author gbrown
+ */
+public class ButtonDataRenderer extends FlowPane implements Button.DataRenderer {
+ protected ImageView imageView = new ImageView();
+ protected Label label = new Label();
+
+ public ButtonDataRenderer() {
+ getStyles().put("horizontalAlignment", HorizontalAlignment.CENTER);
+ getStyles().put("verticalAlignment", VerticalAlignment.CENTER);
+
+ add(imageView);
+ add(label);
+
+ imageView.getStyles().put("backgroundColor", null);
+ }
+
+ @Override
+ public void setSize(int width, int height) {
+ super.setSize(width, height);
+
+ // Since this component doesn't have a parent, it won't be validated
+ // via layout; ensure that it is valid here
+ validate();
+ }
+
+ public void render(Object data, Button button, boolean highlighted) {
+ Image icon = null;
+ String text = null;
+
+ if (data instanceof ButtonData) {
+ ButtonData buttonData = (ButtonData)data;
+ icon = buttonData.getIcon();
+ text = buttonData.getText();
+ } else if (data instanceof Image) {
+ icon = (Image)data;
+ } else {
+ if (data != null) {
+ text = data.toString();
+ }
+ }
+
+ // Show/hide the image view
+ if (icon == null) {
+ imageView.setDisplayable(false);
+ } else {
+ imageView.setDisplayable(true);
+ imageView.setImage(icon);
+
+ imageView.getStyles().put("opacity", button.isEnabled() ? 1.0f : 0.5f);
+ }
+
+ // Show/hide the label
+ if (text == null) {
+ label.setDisplayable(false);
+ } else {
+ label.setDisplayable(true);
+ label.setText(text);
+
+ // Update the label styles
+ Component.StyleDictionary labelStyles = label.getStyles();
+
+ Object labelFont = button.getStyles().get("font");
+ if (labelFont instanceof Font) {
+ labelStyles.put("font", labelFont);
+ }
+
+ Object color = button.isEnabled() ?
+ button.getStyles().get("color") :
+ button.getStyles().get("disabledColor");
+
+ if (color instanceof Color) {
+ labelStyles.put("color", color);
+ }
+ }
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/CalendarButtonDataRenderer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/CalendarButtonDataRenderer.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/CalendarButtonDataRenderer.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/CalendarButtonDataRenderer.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,57 @@
+/*
+ * 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.content;
+
+import java.text.DateFormat;
+import java.util.Locale;
+
+import pivot.util.CalendarDate;
+import pivot.wtk.Button;
+import pivot.wtk.CalendarButton;
+import pivot.wtk.HorizontalAlignment;
+
+/**
+ * Default calendar button data renderer.
+ * <p>
+ * TODO Add showIcon property to this class so the size of the button doesn't
+ * change when changing selection between items with and without icons.
+ *
+ * @author gbrown
+ */
+public class CalendarButtonDataRenderer extends ButtonDataRenderer {
+ public CalendarButtonDataRenderer() {
+ getStyles().put("horizontalAlignment", HorizontalAlignment.LEFT);
+ }
+
+ @Override
+ public void render(Object data, Button button, boolean highlight) {
+ CalendarButton calendarButton = (CalendarButton)button;
+ Locale locale = calendarButton.getLocale();
+
+ if (data == null) {
+ data = "";
+ } else {
+ if (data instanceof CalendarDate) {
+ CalendarDate date = (CalendarDate)data;
+
+ DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, locale);
+ data = dateFormat.format(date.toCalendar().getTime());
+ }
+ }
+
+ super.render(data, button, highlight);
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/CalendarDateSpinnerData.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/CalendarDateSpinnerData.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/CalendarDateSpinnerData.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/CalendarDateSpinnerData.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,241 @@
+/*
+ * 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.content;
+
+import java.util.Calendar;
+import java.util.Comparator;
+import java.util.GregorianCalendar;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.TimeZone;
+
+import pivot.collections.List;
+import pivot.collections.ListListener;
+import pivot.collections.Sequence;
+import pivot.util.CalendarDate;
+import pivot.util.ListenerList;
+
+/**
+ * Spinner data model that presents a bounded list of calendar dates.
+ * <p>
+ * This is a lightweight class that spoofs the actual list data by using an
+ * internal calendar instance from which <tt>CalendarDate</tt> instances are
+ * created on demand.
+ *
+ * @author tvolkert
+ */
+public class CalendarDateSpinnerData implements List<CalendarDate> {
+ /**
+ * Iterator that simply wraps calls to the list. Since the internal list
+ * data is spoofed, each accessor runs in constant time, so there's no
+ * performance hit in making the iterator delegate its implementation to
+ * the list.
+ *
+ * @author tvolkert
+ */
+ private class DataIterator implements Iterator<CalendarDate> {
+ private int index = 0;
+
+ public boolean hasNext() {
+ return (index < length);
+ }
+
+ public CalendarDate next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ return get(index++);
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ private GregorianCalendar calendar;
+ private int calendarIndex;
+
+ // Calculated during construction
+ private transient int length;
+
+ private ListListenerList<CalendarDate> listListeners =
+ new ListListenerList<CalendarDate>();
+
+ /**
+ * Creates a new <tt>CalendarDateSpinnerData</tt> bounded from
+ * <tt>1900-01-01</tt> to <tt>2099-12-31</tt>.
+ */
+ public CalendarDateSpinnerData() {
+ this(new CalendarDate(1900, 0, 0), new CalendarDate(2099, 11, 30));
+ }
+
+ /**
+ * Creates a new <tt>CalendarDateSpinnerData</tt> bounded by the specified
+ * calendar dates (inclusive).
+ *
+ * @param lowerBound
+ * The earliest date to include in this spinner data.
+ *
+ * @param upperBound
+ * The latest date to include in this spinner data.
+ */
+ public CalendarDateSpinnerData(CalendarDate lowerBound, CalendarDate upperBound) {
+ if (lowerBound == null) {
+ throw new IllegalArgumentException("lowerBound is null.");
+ }
+
+ if (upperBound == null) {
+ throw new IllegalArgumentException("upperBound is null.");
+ }
+
+ if (lowerBound.compareTo(upperBound) >= 0) {
+ throw new IllegalArgumentException("lowerBound must be before upperBound.");
+ }
+
+ calendar = new GregorianCalendar(lowerBound.getYear(), lowerBound.getMonth(),
+ lowerBound.getDay() + 1);
+ calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
+ calendarIndex = 0;
+
+ // Calculate our length and cache it, since it is guaranteed to
+ // remain fixed
+ GregorianCalendar upperBoundCalendar = new GregorianCalendar(upperBound.getYear(),
+ upperBound.getMonth(), upperBound.getDay() + 1);
+ upperBoundCalendar.setTimeZone(TimeZone.getTimeZone("GMT"));
+ long lowerBoundMilliseconds = calendar.getTimeInMillis();
+ long upperBoundMilliseconds = upperBoundCalendar.getTimeInMillis();
+ long indexDiff = (upperBoundMilliseconds - lowerBoundMilliseconds) /
+ (1000 * 60 * 60 * 24);
+ length = (int)indexDiff + 1;
+ }
+
+ /**
+ * Throws <tt>UnsupportedOperationException</tt>.
+ */
+ public int add(CalendarDate item) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Throws <tt>UnsupportedOperationException</tt>.
+ */
+ public void insert(CalendarDate item, int index) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Throws <tt>UnsupportedOperationException</tt>.
+ */
+ public CalendarDate update(int index, CalendarDate item) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Throws <tt>UnsupportedOperationException</tt>.
+ */
+ public int remove(CalendarDate item) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Throws <tt>UnsupportedOperationException</tt>.
+ */
+ public Sequence<CalendarDate> remove(int index, int count) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Gets the calendar date at the specified index.
+ *
+ * @param index
+ * The index of the calendar date to retrieve.
+ */
+ public CalendarDate get(int index) {
+ if (index < 0 || index >= length) {
+ throw new IndexOutOfBoundsException("Index out of bounds: " + index);
+ }
+
+ // Move the calendar's fields to match the specified index
+ calendar.add(Calendar.DAY_OF_YEAR, index - calendarIndex);
+ calendarIndex = index;
+
+ // Calculate the desired fields
+ int year = calendar.get(Calendar.YEAR);
+ int month = calendar.get(Calendar.MONTH);
+ int day = calendar.get(Calendar.DAY_OF_MONTH) - 1;
+
+ return new CalendarDate(year, month, day);
+ }
+
+ public int indexOf(CalendarDate item) {
+ long currentMilliseconds = calendar.getTimeInMillis();
+
+ int year = item.getYear();
+ int month = item.getMonth();
+ int day = item.getDay() + 1;
+
+ GregorianCalendar tmpCalendar = new GregorianCalendar(year, month, day);
+ tmpCalendar.setTimeZone(TimeZone.getTimeZone("GMT"));
+ long itemMilliseconds = tmpCalendar.getTimeInMillis();
+
+ long indexDiff = (itemMilliseconds - currentMilliseconds) / (1000 * 60 * 60 * 24);
+ int index = calendarIndex + (int)indexDiff;
+
+ return (index < 0 || index >= length) ? -1 : index;
+ }
+
+ /**
+ * Throws <tt>UnsupportedOperationException</tt>.
+ */
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Gets the number of entries in this list.
+ *
+ * @return
+ * The number of calendar dates in this list.
+ */
+ public int getLength() {
+ return length;
+ }
+
+ /**
+ * Gets the comparator for this list, which is guaranteed to always be
+ * <tt>null</tt>. This class does not support comparators since there's no
+ * real data to sort (it's all spoofed).
+ */
+ public Comparator<CalendarDate> getComparator() {
+ return null;
+ }
+
+ /**
+ * Throws <tt>UnsupportedOperationException</tt>.
+ */
+ public void setComparator(Comparator<CalendarDate> comparator) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Iterator<CalendarDate> iterator() {
+ return new DataIterator();
+ }
+
+ public ListenerList<ListListener<CalendarDate>> getListListeners() {
+ return listListeners;
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ColorItem.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ColorItem.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ColorItem.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ColorItem.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,76 @@
+/*
+ * 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.content;
+
+import java.awt.Color;
+
+/**
+ * List item representing a color.
+ *
+ * @author gbrown
+ */
+public class ColorItem {
+ private Color color;
+ private String name;
+
+ public ColorItem() {
+ this(Color.BLACK, null);
+ }
+
+ public ColorItem(Color color) {
+ this(color, null);
+ }
+
+ public ColorItem(Color color, String name) {
+ this.color = color;
+ this.name = name;
+ }
+
+ public Color getColor() {
+ return color;
+ }
+
+ public void setColor(Color color) {
+ if (color == null) {
+ throw new IllegalArgumentException("color is null.");
+ }
+
+ this.color = color;
+ }
+
+ public void setColor(String color) {
+ if (color == null) {
+ throw new IllegalArgumentException("color is null.");
+ }
+
+ setColor(Color.decode(color));
+ }
+
+ public String getName() {
+ String name = this.name;
+
+ if (name == null) {
+ name = String.format("#%02X%02X%02X", color.getRed(), color.getGreen(),
+ color.getBlue());
+ }
+
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/LinkButtonDataRenderer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/LinkButtonDataRenderer.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/LinkButtonDataRenderer.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/LinkButtonDataRenderer.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,38 @@
+/*
+ * 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.content;
+
+import pivot.wtk.Button;
+import pivot.wtk.TextDecoration;
+
+/**
+ * Default link button data renderer.
+ *
+ * @author gbrown
+ */
+public class LinkButtonDataRenderer extends ButtonDataRenderer {
+ public LinkButtonDataRenderer() {
+ label.getStyles().put("wrapText", true);
+ }
+
+ @Override
+ public void render(Object data, Button button, boolean highlighted) {
+ super.render(data, button, highlighted);
+
+ label.getStyles().put("textDecoration", highlighted ?
+ TextDecoration.UNDERLINE : null);
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListButtonColorRenderer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListButtonColorRenderer.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListButtonColorRenderer.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListButtonColorRenderer.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,52 @@
+/*
+ * 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.content;
+
+import java.awt.Color;
+
+import pivot.wtk.Button;
+import pivot.wtk.ImageView;
+
+/**
+ * List button renderer for displaying color swatches.
+ *
+ * @author gbrown
+ */
+public class ListButtonColorRenderer extends ImageView
+ implements Button.DataRenderer {
+ private ListViewColorRenderer.ColorBadge colorBadge =
+ new ListViewColorRenderer.ColorBadge();
+
+ public ListButtonColorRenderer() {
+ setImage(colorBadge);
+ }
+
+ public void render(Object data, Button button, boolean highlighted) {
+ Color color;
+ if (data instanceof ColorItem) {
+ ColorItem colorItem = (ColorItem)data;
+ color = colorItem.getColor();
+ } else {
+ if (data instanceof Color) {
+ color = (Color)data;
+ } else {
+ color = Color.decode(data.toString());
+ }
+ }
+
+ colorBadge.setColor(color);
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListButtonDataRenderer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListButtonDataRenderer.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListButtonDataRenderer.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListButtonDataRenderer.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,47 @@
+/*
+ * 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.content;
+
+import pivot.wtk.Button;
+import pivot.wtk.HorizontalAlignment;
+
+/**
+ * Default list button data renderer.
+ * <p>
+ * TODO Add showIcon property to this class so the size of the button doesn't
+ * change when changing selection between items with and without icons.
+ *
+ * @author gbrown
+ */
+public class ListButtonDataRenderer extends ButtonDataRenderer {
+ public ListButtonDataRenderer() {
+ getStyles().put("horizontalAlignment", HorizontalAlignment.LEFT);
+ }
+
+ @Override
+ public void render(Object data, Button button, boolean highlight) {
+ if (data == null) {
+ data = "";
+ } else {
+ if (data instanceof ListItem) {
+ ListItem listItem = (ListItem)data;
+ data = new ButtonData(listItem.getIcon(), listItem.getText());
+ }
+ }
+
+ super.render(data, button, highlight);
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListItem.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListItem.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListItem.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListItem.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,80 @@
+/*
+ * 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.content;
+
+import java.net.URL;
+
+import pivot.wtk.ApplicationContext;
+import pivot.wtk.media.Image;
+
+/**
+ * Default list item implementation.
+ *
+ * @author gbrown
+ */
+public class ListItem {
+ private Image icon;
+ private String text;
+
+ public ListItem() {
+ this(null, null);
+ }
+
+ public ListItem(Image icon) {
+ this(icon, null);
+ }
+
+ public ListItem(String text) {
+ this(null, text);
+ }
+
+ public ListItem(Image icon, String text) {
+ this.icon = icon;
+ this.text = text;
+ }
+
+ public Image getIcon() {
+ return icon;
+ }
+
+ public void setIcon(Image icon) {
+ this.icon = icon;
+ }
+
+ public void setIcon(URL iconURL) {
+ Image icon = (Image)ApplicationContext.getResourceCache().get(iconURL);
+
+ if (icon == null) {
+ icon = Image.load(iconURL);
+ ApplicationContext.getResourceCache().put(iconURL, icon);
+ }
+
+ setIcon(icon);
+ }
+
+ public void setIcon(String iconName) {
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ setIcon(classLoader.getResource(iconName));
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListViewColorRenderer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListViewColorRenderer.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListViewColorRenderer.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListViewColorRenderer.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,93 @@
+/*
+ * 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.content;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+
+import pivot.wtk.ListView;
+import pivot.wtk.media.Image;
+
+/**
+ * List view renderer for displaying color swatches.
+ *
+ * @author gbrown
+ */
+public class ListViewColorRenderer extends ListViewItemRenderer {
+ /**
+ * Internal image class for rendering color swatches.
+ *
+ * @author gbrown
+ */
+ public static class ColorBadge extends Image {
+ private Color color = Color.BLACK;
+ public static final int SIZE = 14;
+
+ public int getWidth() {
+ return SIZE;
+ }
+
+ public int getHeight() {
+ return SIZE;
+ }
+
+ public Color getColor() {
+ return color;
+ }
+
+ public void setColor(Color color) {
+ this.color = color;
+ }
+
+ public void paint(Graphics2D graphics) {
+ graphics.setColor(Color.WHITE);
+ graphics.fillRect(0, 0, SIZE, SIZE);
+ graphics.setColor(color);
+ graphics.fillRect(2, 2, SIZE - 4, SIZE - 4);
+ graphics.setColor(Color.GRAY);
+ graphics.drawRect(0, 0, SIZE - 1, SIZE - 1);
+ }
+ }
+
+ private ColorBadge colorBadge = new ColorBadge();
+ private ListItem listItem = new ListItem(colorBadge);
+
+ public ListViewColorRenderer() {
+ setShowIcon(true);
+ }
+
+ public void render(Object item, ListView listView, boolean selected,
+ boolean checked, boolean highlighted, boolean disabled) {
+ ColorItem colorItem;
+ if (item instanceof ColorItem) {
+ colorItem = (ColorItem)item;
+ } else {
+ Color color;
+ if (item instanceof Color) {
+ color = (Color)item;
+ } else {
+ color = Color.decode(item.toString());
+ }
+
+ colorItem = new ColorItem(color);
+ }
+
+ colorBadge.setColor(colorItem.getColor());
+ listItem.setText(colorItem.getName());
+
+ super.render(listItem, listView, selected, checked, highlighted, disabled);
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListViewItemEditor.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListViewItemEditor.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListViewItemEditor.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListViewItemEditor.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,268 @@
+/*
+ * 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.content;
+
+import pivot.collections.List;
+import pivot.util.Vote;
+import pivot.wtk.Bounds;
+import pivot.wtk.Component;
+import pivot.wtk.ComponentKeyListener;
+import pivot.wtk.Container;
+import pivot.wtk.ContainerMouseListener;
+import pivot.wtk.Display;
+import pivot.wtk.Insets;
+import pivot.wtk.Keyboard;
+import pivot.wtk.ListView;
+import pivot.wtk.ListViewItemListener;
+import pivot.wtk.ListViewListener;
+import pivot.wtk.Mouse;
+import pivot.wtk.TextInput;
+import pivot.wtk.Window;
+import pivot.wtk.WindowStateListener;
+
+/**
+ * Default list view item editor.
+ *
+ * @author gbrown
+ */
+public class ListViewItemEditor implements ListView.ItemEditor {
+ private ListView listView = null;
+ private int index = -1;
+
+ private TextInput textInput = null;
+ private Window popup = null;
+
+ private ListViewListener listViewListener = new ListViewListener() {
+ public void listDataChanged(ListView listView, List<?> previousListData) {
+ cancel();
+ }
+
+ public void itemRendererChanged(ListView listView, ListView.ItemRenderer previousItemRenderer) {
+ // No-op
+ }
+
+ public void itemEditorChanged(ListView listView, ListView.ItemEditor previousItemEditor) {
+ cancel();
+ }
+
+ public void selectModeChanged(ListView listView, ListView.SelectMode previousSelectMode) {
+ // No-op
+ }
+
+ public void checkmarksEnabledChanged(ListView listView) {
+ // No-op
+ }
+
+ public void selectedItemKeyChanged(ListView listView, String previousSelectedItemKey) {
+ // No-op
+ }
+
+ public void selectedItemsKeyChanged(ListView listView, String previousSelectedItemsKey) {
+ // No-op
+ }
+ };
+
+ private ListViewItemListener listViewItemListener = new ListViewItemListener() {
+ public void itemInserted(ListView listView, int index) {
+ cancel();
+ }
+
+ public void itemsRemoved(ListView listView, int index, int count) {
+ cancel();
+ }
+
+ public void itemUpdated(ListView listView, int index) {
+ cancel();
+ }
+
+ public void itemsSorted(ListView listView) {
+ cancel();
+ }
+ };
+
+ private ComponentKeyListener textInputKeyHandler = new ComponentKeyListener() {
+ @SuppressWarnings("unchecked")
+ public boolean keyPressed(Component component, int keyCode, Keyboard.KeyLocation keyLocation) {
+ if (keyCode == Keyboard.KeyCode.ENTER) {
+ save();
+ } else if (keyCode == Keyboard.KeyCode.ESCAPE) {
+ cancel();
+ }
+
+ return false;
+ }
+
+ public boolean keyReleased(Component component, int keyCode, Keyboard.KeyLocation keyLocation) {
+ return false;
+ }
+
+ public boolean keyTyped(Component component, char character) {
+ return false;
+ }
+ };
+
+ private WindowStateListener popupWindowStateHandler = new WindowStateListener() {
+ public Vote previewWindowOpen(Window window, Display display) {
+ return Vote.APPROVE;
+ }
+
+ public void windowOpenVetoed(Window window, Vote reason) {
+ }
+
+ public void windowOpened(Window window) {
+ Display display = window.getDisplay();
+ display.getContainerMouseListeners().add(displayMouseHandler);
+
+ listView.getListViewListeners().add(listViewListener);
+ listView.getListViewItemListeners().add(listViewItemListener);
+ }
+
+ public Vote previewWindowClose(Window window) {
+ return Vote.APPROVE;
+ }
+
+ public void windowCloseVetoed(Window window, Vote reason) {
+ }
+
+ public void windowClosed(Window window, Display display) {
+ display.getContainerMouseListeners().remove(displayMouseHandler);
+
+ listView.getListViewListeners().remove(listViewListener);
+ listView.getListViewItemListeners().remove(listViewItemListener);
+
+ listView.requestFocus();
+
+ listView = null;
+ index = -1;
+ textInput = null;
+ popup = null;
+ }
+ };
+
+ private ContainerMouseListener displayMouseHandler = new ContainerMouseListener() {
+ public boolean mouseMove(Container container, int x, int y) {
+ return false;
+ }
+
+ public boolean mouseDown(Container container, Mouse.Button button, int x, int y) {
+ Display display = (Display)container;
+ Window window = (Window)display.getComponentAt(x, y);
+ if (popup != window) {
+ save();
+ }
+
+ return false;
+ }
+
+ public boolean mouseUp(Container container, Mouse.Button button, int x, int y) {
+ return false;
+ }
+
+ public boolean mouseWheel(Container container, Mouse.ScrollType scrollType,
+ int scrollAmount, int wheelRotation, int x, int y) {
+ return true;
+ }
+ };
+
+ public void edit(ListView listView, int index) {
+ if (this.listView != null) {
+ throw new IllegalStateException("Currently editing.");
+ }
+
+ this.listView = listView;
+ this.index = index;
+
+ // Get the data being edited
+ List<?> listData = listView.getListData();
+ ListItem listItem = (ListItem)listData.get(index);
+
+ // Get the item bounds
+ Bounds itemBounds = listView.getItemBounds(index);
+ int itemIndent = listView.getItemIndent();
+ itemBounds.x += itemIndent;
+ itemBounds.width -= itemIndent;
+
+ // Render the item data
+ ListViewItemRenderer itemRenderer = (ListViewItemRenderer)listView.getItemRenderer();
+ itemRenderer.render(listItem, listView, false, false, false, false);
+ itemRenderer.setSize(itemBounds.width, itemBounds.height);
+
+ // Calculate the text bounds
+ Bounds textBounds = itemRenderer.getTextBounds();
+
+ if (textBounds != null) {
+ textInput = new TextInput();
+ Insets padding = (Insets)textInput.getStyles().get("padding");
+
+ // Calculate the bounds of what we're editing
+ Bounds editBounds = new Bounds(itemBounds);
+ editBounds.x += textBounds.x - (padding.left + 1);
+ editBounds.width -= textBounds.x;
+ editBounds.width += (padding.left + 1);
+
+ // Scroll to make the text as visible as possible
+ listView.scrollAreaToVisible(editBounds.x, editBounds.y,
+ textBounds.width + padding.left + 1, editBounds.height);
+
+ // Constrain the bounds by what is visible through Viewport ancestors
+ editBounds = listView.getVisibleArea(editBounds.x, editBounds.y,
+ editBounds.width, editBounds.height);
+
+ textInput.setText(listItem.getText());
+ textInput.setPreferredWidth(editBounds.width);
+ textInput.getComponentKeyListeners().add(textInputKeyHandler);
+
+ // Create and open the popup
+ popup = new Window(textInput);
+ popup.getWindowStateListeners().add(popupWindowStateHandler);
+
+ popup.setLocation(editBounds.x, editBounds.y
+ + (editBounds.height - textInput.getPreferredHeight(-1)) / 2);
+ popup.open(listView.getWindow());
+
+ textInput.requestFocus();
+ }
+ }
+
+ public boolean isEditing() {
+ return (listView != null);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void save() {
+ if (!isEditing()) {
+ throw new IllegalStateException();
+ }
+
+ List<Object> listData = (List<Object>)listView.getListData();
+ ListItem listItem = (ListItem)listData.get(index);
+
+ // Update the item data
+ String text = textInput.getText();
+ listItem.setText(text);
+
+ // Notifying the parent will close the popup
+ listData.update(index, listItem);
+ }
+
+ public void cancel() {
+ if (!isEditing()) {
+ throw new IllegalStateException();
+ }
+
+ popup.close();
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListViewItemRenderer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListViewItemRenderer.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListViewItemRenderer.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/ListViewItemRenderer.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,170 @@
+/*
+ * 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.content;
+
+import java.awt.Color;
+import java.awt.Font;
+
+import pivot.wtk.Bounds;
+import pivot.wtk.Component;
+import pivot.wtk.FlowPane;
+import pivot.wtk.HorizontalAlignment;
+import pivot.wtk.ImageView;
+import pivot.wtk.Insets;
+import pivot.wtk.Label;
+import pivot.wtk.ListView;
+import pivot.wtk.VerticalAlignment;
+import pivot.wtk.media.Image;
+
+/**
+ * Default list view item renderer.
+ *
+ * @author gbrown
+ */
+public class ListViewItemRenderer extends FlowPane implements ListView.ItemRenderer {
+ protected ImageView imageView = new ImageView();
+ protected Label label = new Label();
+
+ public static final int DEFAULT_ICON_WIDTH = 16;
+ public static final int DEFAULT_ICON_HEIGHT = 16;
+ public static boolean DEFAULT_SHOW_ICON = false;
+
+ public ListViewItemRenderer() {
+ getStyles().put("horizontalAlignment", HorizontalAlignment.LEFT);
+ getStyles().put("verticalAlignment", VerticalAlignment.CENTER);
+ getStyles().put("padding", new Insets(2, 3, 2, 3));
+
+ add(imageView);
+ add(label);
+
+ imageView.setPreferredSize(DEFAULT_ICON_WIDTH, DEFAULT_ICON_HEIGHT);
+ imageView.setDisplayable(DEFAULT_SHOW_ICON);
+ }
+
+ @Override
+ public void setSize(int width, int height) {
+ super.setSize(width, height);
+
+ // Since this component doesn't have a parent, it won't be validated
+ // via layout; ensure that it is valid here
+ validate();
+ }
+
+ public void render(Object item, ListView listView, boolean selected,
+ boolean checked, boolean highlighted, boolean disabled) {
+ Image icon = null;
+ String text = null;
+
+ if (item instanceof ListItem) {
+ ListItem listItem = (ListItem)item;
+ icon = listItem.getIcon();
+ text = listItem.getText();
+ } else if (item instanceof Image) {
+ icon = (Image)item;
+ } else {
+ if (item != null) {
+ text = item.toString();
+ }
+ }
+
+ // Update the image view
+ imageView.setImage(icon);
+
+ // Show/hide the label
+ label.setText(text);
+
+ renderStyles(listView, selected, highlighted, disabled);
+ }
+
+ protected void renderStyles(ListView listView, boolean selected,
+ boolean highlighted, boolean disabled) {
+ Component.StyleDictionary listViewStyles = listView.getStyles();
+
+ Component.StyleDictionary imageViewStyles = imageView.getStyles();
+ Component.StyleDictionary labelStyles = label.getStyles();
+
+ imageViewStyles.put("opacity", listView.isEnabled() ? 1.0f : 0.5f);
+
+ if (label.getText() != null) {
+ Object labelFont = listViewStyles.get("font");
+ if (labelFont instanceof Font) {
+ labelStyles.put("font", labelFont);
+ }
+
+ Object color = null;
+ if (listView.isEnabled() && !disabled) {
+ if (selected) {
+ if (listView.isFocused()) {
+ color = listViewStyles.get("selectionColor");
+ } else {
+ color = listViewStyles.get("inactiveSelectionColor");
+ }
+ } else {
+ color = listViewStyles.get("color");
+ }
+ } else {
+ color = listViewStyles.get("disabledColor");
+ }
+
+ if (color instanceof Color) {
+ labelStyles.put("color", color);
+ }
+ }
+ }
+
+ public int getIconWidth() {
+ return imageView.getPreferredWidth(-1);
+ }
+
+ public void setIconWidth(int iconWidth) {
+ if (iconWidth == -1) {
+ throw new IllegalArgumentException();
+ }
+
+ imageView.setPreferredWidth(iconWidth);
+ }
+
+ public int getIconHeight() {
+ return imageView.getPreferredHeight(-1);
+ }
+
+ public void setIconHeight(int iconHeight) {
+ if (iconHeight == -1) {
+ throw new IllegalArgumentException();
+ }
+
+ imageView.setPreferredHeight(iconHeight);
+ }
+
+ public boolean getShowIcon() {
+ return imageView.isDisplayable();
+ }
+
+ public void setShowIcon(boolean showIcon) {
+ imageView.setDisplayable(showIcon);
+ }
+
+ /**
+ * Gets the bounds of the text that is rendered by this renderer.
+ *
+ * @return
+ * The bounds of the rendered text, or <tt>null</tt> if this renderer did
+ * not render any text.
+ */
+ public Bounds getTextBounds() {
+ return (label.isVisible() ? label.getBounds() : null);
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/MenuBarItemDataRenderer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/MenuBarItemDataRenderer.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/MenuBarItemDataRenderer.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/MenuBarItemDataRenderer.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,115 @@
+/*
+ * 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.content;
+
+import java.awt.Color;
+import java.awt.Font;
+
+import pivot.wtk.Button;
+import pivot.wtk.FlowPane;
+import pivot.wtk.HorizontalAlignment;
+import pivot.wtk.MenuBar;
+import pivot.wtk.VerticalAlignment;
+import pivot.wtk.ImageView;
+import pivot.wtk.Label;
+import pivot.wtk.media.Image;
+
+/**
+ * Default menu bar item data renderer.
+ *
+ * @author gbrown
+ */
+public class MenuBarItemDataRenderer extends FlowPane implements Button.DataRenderer {
+ protected ImageView imageView = new ImageView();
+ protected Label label = new Label();
+
+ public MenuBarItemDataRenderer() {
+ getStyles().put("horizontalAlignment", HorizontalAlignment.LEFT);
+ getStyles().put("verticalAlignment", VerticalAlignment.CENTER);
+ getStyles().put("padding", 3);
+
+ add(imageView);
+ add(label);
+
+ imageView.getStyles().put("backgroundColor", null);
+ }
+
+ @Override
+ public void setSize(int width, int height) {
+ super.setSize(width, height);
+
+ // Since this component doesn't have a parent, it won't be validated
+ // via layout; ensure that it is valid here
+ validate();
+ }
+
+ public void render(Object data, Button button, boolean highlighted) {
+ Image icon = null;
+ String text = null;
+
+ if (data instanceof ButtonData) {
+ ButtonData buttonData = (ButtonData)data;
+ icon = buttonData.getIcon();
+ text = buttonData.getText();
+ } else if (data instanceof Image) {
+ icon = (Image)data;
+ } else {
+ if (data != null) {
+ text = data.toString();
+ }
+ }
+
+ // Update the image view
+ MenuBar.Item menuBarItem = (MenuBar.Item)button;
+ MenuBar menuBar = menuBarItem.getMenuBar();
+
+ if (icon == null) {
+ imageView.setDisplayable(false);
+ } else {
+ imageView.setDisplayable(true);
+ imageView.setImage(icon);
+ imageView.getStyles().put("opacity", button.isEnabled() ? 1.0f : 0.5f);
+ }
+
+ // Update the label
+ if (text == null) {
+ label.setDisplayable(false);
+ } else {
+ label.setDisplayable(true);
+ Object font = menuBar.getStyles().get("font");
+ if (font instanceof Font) {
+ label.getStyles().put("font", font);
+ }
+
+ Object color;
+ if (button.isEnabled()) {
+ if (highlighted) {
+ color = menuBar.getStyles().get("highlightColor");
+ } else {
+ color = menuBar.getStyles().get("color");
+ }
+ } else {
+ color = menuBar.getStyles().get("disabledColor");
+ }
+
+ if (color instanceof Color) {
+ label.getStyles().put("color", color);
+ }
+
+ label.setText(text);
+ }
+ }
+}
Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/MenuButtonDataRenderer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/MenuButtonDataRenderer.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/MenuButtonDataRenderer.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/content/MenuButtonDataRenderer.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.content;
+
+import pivot.wtk.Button;
+import pivot.wtk.HorizontalAlignment;
+
+/**
+ * Default menu button data renderer.
+ *
+ * @author gbrown
+ */
+public class MenuButtonDataRenderer extends ButtonDataRenderer {
+ public MenuButtonDataRenderer() {
+ getStyles().put("horizontalAlignment", HorizontalAlignment.LEFT);
+ }
+
+ @Override
+ public void render(Object data, Button button, boolean highlight) {
+ if (data == null) {
+ data = "";
+ }
+
+ super.render(data, button, highlight);
+ }
+}