You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by gb...@apache.org on 2009/03/24 18:26:12 UTC

svn commit: r757915 - in /incubator/pivot/trunk/wtk/src/pivot/wtk: ./ content/ skin/ skin/terra/

Author: gbrown
Date: Tue Mar 24 17:26:07 2009
New Revision: 757915

URL: http://svn.apache.org/viewvc?rev=757915&view=rev
Log:
Eliminate Popup class.

Removed:
    incubator/pivot/trunk/wtk/src/pivot/wtk/Popup.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/PopupListener.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/skin/PopupSkin.java
Modified:
    incubator/pivot/trunk/wtk/src/pivot/wtk/Frame.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/MenuPopup.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/Palette.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/Sheet.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/Theme.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/Tooltip.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/Window.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/content/TreeViewNodeEditor.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/skin/CalendarButtonSkin.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/skin/ListButtonSkin.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/skin/MenuBarItemSkin.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/skin/MenuButtonSkin.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/skin/MenuItemSkin.java
    incubator/pivot/trunk/wtk/src/pivot/wtk/skin/terra/TerraMenuPopupSkin.java

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/Frame.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/Frame.java?rev=757915&r1=757914&r2=757915&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/Frame.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/Frame.java Tue Mar 24 17:26:07 2009
@@ -34,8 +34,9 @@
     }
 
     public Frame(String title, Component content) {
-        super(title, content);
+        super(content, false);
 
+        setTitle(title);
         installSkin(Frame.class);
     }
 }

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/MenuPopup.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/MenuPopup.java?rev=757915&r1=757914&r2=757915&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/MenuPopup.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/MenuPopup.java Tue Mar 24 17:26:07 2009
@@ -22,7 +22,7 @@
  *
  * @author gbrown
  */
-public class MenuPopup extends Popup {
+public class MenuPopup extends Window {
     private class MenuPopupListenerList extends ListenerList<MenuPopupListener>
         implements MenuPopupListener {
         public void menuChanged(MenuPopup menuPopup, Menu previousMenu) {
@@ -33,6 +33,7 @@
     }
 
     private Menu menu;
+    private Component affiliate = null;
 
     private MenuPopupListenerList menuPopupListeners = new MenuPopupListenerList();
 
@@ -41,8 +42,9 @@
     }
 
     public MenuPopup(Menu menu) {
-        setMenu(menu);
+        super(true);
 
+        setMenu(menu);
         installSkin(MenuPopup.class);
     }
 
@@ -59,6 +61,10 @@
         }
     }
 
+    public Component getAffiliate() {
+        return affiliate;
+    }
+
     public void open(Display display, int x, int y) {
         // TODO Determine x, y and width, height
         setLocation(x, y);
@@ -87,6 +93,36 @@
         open(owner, location.x, location.y);
     }
 
+    /**
+     * Opens the popup.
+     *
+     * @param affiliate
+     * The component with which the popup is affiliated.
+     */
+    public void open(Component affiliate) {
+        if (affiliate == null) {
+            throw new IllegalArgumentException("affiliate is null.");
+        }
+
+        if (isOpen()
+            && getAffiliate() != affiliate) {
+            throw new IllegalStateException("Popup is already open with a different affiliate.");
+        }
+
+        this.affiliate = affiliate;
+
+        open(affiliate.getWindow());
+    }
+
+    @Override
+    public void close() {
+        super.close();
+
+        if (isClosed()) {
+            affiliate = null;
+        }
+    }
+
     public ListenerList<MenuPopupListener> getMenuPopupListeners() {
         return menuPopupListeners;
     }

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/Palette.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/Palette.java?rev=757915&r1=757914&r2=757915&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/Palette.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/Palette.java Tue Mar 24 17:26:07 2009
@@ -22,32 +22,23 @@
  * @author gbrown
  */
 public class Palette extends Window {
-    /**
-     * Creates a new palette.
-     */
     public Palette() {
-        this(null);
+        this(null, null);
     }
 
-    /**
-     * Creates a new palette with an initial content component.
-     *
-     * @param content
-     * The sheet's content component.
-     */
-    public Palette(Component content) {
-        super(content);
+    public Palette(String title) {
+        this(title, null);
+    }
 
-        installSkin(Palette.class);
+    public Palette(Component content) {
+        this(null, content);
     }
 
-    /**
-     * @return
-     * <tt>true</tt>; by default, palettes are auxilliary windows.
-     */
-    @Override
-    public boolean isAuxilliary() {
-        return true;
+    public Palette(String title, Component content) {
+        super(content, true);
+
+        setTitle(title);
+        installSkin(Palette.class);
     }
 
     @Override

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/Sheet.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/Sheet.java?rev=757915&r1=757914&r2=757915&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/Sheet.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/Sheet.java Tue Mar 24 17:26:07 2009
@@ -103,7 +103,7 @@
      * The sheet's content component.
      */
     public Sheet(Component content) {
-        super(content);
+        super(content, true);
 
         installSkin(Sheet.class);
     }
@@ -119,15 +119,6 @@
         });
     }
 
-    /**
-     * @return
-     * <tt>true</tt>; by default, sheets are auxilliary windows.
-     */
-    @Override
-    public boolean isAuxilliary() {
-        return true;
-    }
-
     @Override
     public final void setOwner(Window owner) {
         if (owner == null) {

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/Theme.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/Theme.java?rev=757915&r1=757914&r2=757915&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/Theme.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/Theme.java Tue Mar 24 17:26:07 2009
@@ -26,7 +26,6 @@
 import pivot.wtk.skin.FlowPaneSkin;
 import pivot.wtk.skin.ImageViewSkin;
 import pivot.wtk.skin.LabelSkin;
-import pivot.wtk.skin.PopupSkin;
 import pivot.wtk.skin.ScrollPaneSkin;
 import pivot.wtk.skin.SeparatorSkin;
 import pivot.wtk.skin.StackPaneSkin;
@@ -64,7 +63,6 @@
         componentSkinMap.put(FlowPane.class, FlowPaneSkin.class);
         componentSkinMap.put(ImageView.class, ImageViewSkin.class);
         componentSkinMap.put(Label.class, LabelSkin.class);
-        componentSkinMap.put(Popup.class, PopupSkin.class);
         componentSkinMap.put(ScrollPane.class, ScrollPaneSkin.class);
         componentSkinMap.put(Separator.class, SeparatorSkin.class);
         componentSkinMap.put(StackPane.class, StackPaneSkin.class);

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/Tooltip.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/Tooltip.java?rev=757915&r1=757914&r2=757915&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/Tooltip.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/Tooltip.java Tue Mar 24 17:26:07 2009
@@ -39,6 +39,8 @@
     private TooltipListenerList tooltipListeners = new TooltipListenerList();
 
     public Tooltip(String text) {
+        super(true);
+
         setText(text);
         installSkin(Tooltip.class);
     }
@@ -56,15 +58,6 @@
         }
     }
 
-    /**
-     * @return
-     * <tt>true</tt>; by default, tooltips are auxilliary windows.
-     */
-    @Override
-    public boolean isAuxilliary() {
-        return true;
-    }
-
     public ListenerList<TooltipListener> getTooltipListeners() {
         return tooltipListeners;
     }

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/Window.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/Window.java?rev=757915&r1=757914&r2=757915&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/Window.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/Window.java Tue Mar 24 17:26:07 2009
@@ -185,6 +185,8 @@
         }
     }
 
+    private boolean auxilliary;
+
     private Window owner = null;
     private ArrayList<Window> ownedWindows = new ArrayList<Window>();
 
@@ -208,19 +210,20 @@
     private static Window activeWindow = null;
 
     public Window() {
-        this(null, null);
+        this(null, false);
     }
 
-    public Window(String title) {
-        this(title, null);
+    public Window(boolean auxilliary) {
+        this(null, auxilliary);
     }
 
     public Window(Component content) {
-        this(null, content);
+        this(content, false);
     }
 
-    public Window(String title, Component content) {
-        setTitle(title);
+    public Window(Component content, boolean auxilliary) {
+        this.auxilliary = auxilliary;
+
         setContent(content);
         installSkin(Window.class);
     }
@@ -347,8 +350,22 @@
         return ownedWindows.getLength();
     }
 
-    public boolean isOwningAncestorOf(Window window) {
-        Window owner = window;
+    /**
+     * 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) {
@@ -616,14 +633,14 @@
     }
 
     /**
-     * Returns the window's auxilliary state. Auxilliary windows must have an
+     * 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 false;
+        return auxilliary;
     }
 
     /**

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/content/TreeViewNodeEditor.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/content/TreeViewNodeEditor.java?rev=757915&r1=757914&r2=757915&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/content/TreeViewNodeEditor.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/content/TreeViewNodeEditor.java Tue Mar 24 17:26:07 2009
@@ -22,14 +22,9 @@
 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.Mouse;
 import pivot.wtk.Point;
-import pivot.wtk.Popup;
 import pivot.wtk.TextInput;
 import pivot.wtk.TreeView;
 import pivot.wtk.TreeViewListener;
@@ -250,7 +245,7 @@
 
     private TreeView treeView = null;
     private Sequence<Integer> editPath = null;
-    private Popup popup = null;
+    private Window popup = null;
 
     private TreeViewHandler treeViewHandler = new TreeViewHandler();
 
@@ -293,7 +288,7 @@
         textInput.setPreferredWidth(textBounds.width);
         textInput.getComponentKeyListeners().add(textInputKeyHandler);
 
-        popup = new Popup(textInput);
+        popup = new Window(textInput, true);
         Point displayCoordinates = treeView.mapPointToAncestor(treeView.getDisplay(), 0, 0);
         popup.setLocation(displayCoordinates.x + textBounds.x, displayCoordinates.y +
             textBounds.y + (textBounds.height - textInput.getPreferredHeight(-1)) / 2);

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/skin/CalendarButtonSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/skin/CalendarButtonSkin.java?rev=757915&r1=757914&r2=757915&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/skin/CalendarButtonSkin.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/skin/CalendarButtonSkin.java Tue Mar 24 17:26:07 2009
@@ -18,6 +18,7 @@
 import java.util.Locale;
 
 import pivot.util.CalendarDate;
+import pivot.util.Vote;
 import pivot.wtk.Button;
 import pivot.wtk.Calendar;
 import pivot.wtk.CalendarButton;
@@ -26,13 +27,16 @@
 import pivot.wtk.Component;
 import pivot.wtk.ComponentKeyListener;
 import pivot.wtk.ComponentMouseButtonListener;
+import pivot.wtk.Container;
+import pivot.wtk.ContainerMouseListener;
 import pivot.wtk.Dimensions;
 import pivot.wtk.Direction;
 import pivot.wtk.Display;
 import pivot.wtk.Keyboard;
 import pivot.wtk.Mouse;
 import pivot.wtk.Point;
-import pivot.wtk.Popup;
+import pivot.wtk.Window;
+import pivot.wtk.WindowStateListener;
 
 /**
  * Abstract base class for calendar button skins.
@@ -48,10 +52,32 @@
 public abstract class CalendarButtonSkin extends ButtonSkin
     implements CalendarButtonListener, CalendarButtonSelectionListener {
     protected Calendar calendar;
-    protected Popup calendarPopup;
+    protected Window calendarPopup;
 
     protected boolean pressed = false;
 
+    private ComponentMouseButtonListener calendarPopupMouseButtonListener = new ComponentMouseButtonListener() {
+        public boolean mouseDown(Component component, Mouse.Button button, int x, int y) {
+            return false;
+        }
+
+        public boolean mouseUp(Component component, Mouse.Button button, int x, int y) {
+            return false;
+        }
+
+        public boolean mouseClick(Component component, Mouse.Button button, int x, int y, int count) {
+            CalendarButton calendarButton = (CalendarButton)getComponent();
+
+            CalendarDate date = calendar.getSelectedDate();
+            calendarButton.setSelectedDate(date);
+
+            calendarPopup.close();
+            getComponent().requestFocus();
+
+            return true;
+        }
+    };
+
     private ComponentKeyListener calendarPopupKeyListener = new ComponentKeyListener() {
         public boolean keyTyped(Component component, char character) {
             return false;
@@ -96,34 +122,68 @@
         }
     };
 
-    private ComponentMouseButtonListener calendarPopupMouseListener = new ComponentMouseButtonListener() {
-        public boolean mouseDown(Component component, Mouse.Button button, int x, int y) {
-            return false;
+    private WindowStateListener calendarPopupWindowStateListener = new WindowStateListener() {
+        public Vote previewWindowOpen(Window window, Display display) {
+            return Vote.APPROVE;
         }
 
-        public boolean mouseUp(Component component, Mouse.Button button, int x, int y) {
-            return false;
+        public void windowOpenVetoed(Window window, Vote reason) {
+            // No-op
         }
 
-        public boolean mouseClick(Component component, Mouse.Button button, int x, int y, int count) {
-            CalendarButton calendarButton = (CalendarButton)getComponent();
+        public void windowOpened(Window window) {
+            Display display = window.getDisplay();
+            display.getContainerMouseListeners().add(displayMouseListener);
+        }
 
-            CalendarDate date = calendar.getSelectedDate();
-            calendarButton.setSelectedDate(date);
+        public Vote previewWindowClose(Window window) {
+            return Vote.APPROVE;
+        }
 
-            calendarPopup.close();
-            getComponent().requestFocus();
+        public void windowCloseVetoed(Window window, Vote reason) {
+            // No-op
+        }
 
-            return true;
+        public void windowClosed(Window window, Display display) {
+            display.getContainerMouseListeners().remove(displayMouseListener);
+        }
+    };
+
+    private ContainerMouseListener displayMouseListener = new ContainerMouseListener() {
+        public void mouseMove(Container container, int x, int y) {
+        }
+
+        public void mouseDown(Container container, Mouse.Button button, int x, int y) {
+            Display display = (Display)container;
+            Component descendant = display.getDescendantAt(x, y);
+
+            if (!calendarPopup.isAncestor(descendant)
+                && descendant != CalendarButtonSkin.this.getComponent()) {
+                calendarPopup.close();
+            }
+        }
+
+        public void mouseUp(Container container, Mouse.Button button, int x, int y) {
+        }
+
+        public void mouseWheel(Container container, Mouse.ScrollType scrollType,
+            int scrollAmount, int wheelRotation, int x, int y) {
+            Display display = (Display)container;
+            Window window = (Window)display.getComponentAt(x, y);
+
+            if (window != calendarPopup) {
+                calendarPopup.close();
+            }
         }
     };
 
     public CalendarButtonSkin() {
         calendar = new Calendar();
 
-        calendarPopup = new Popup();
-        calendarPopup.getComponentMouseButtonListeners().add(calendarPopupMouseListener);
+        calendarPopup = new Window(true);
+        calendarPopup.getComponentMouseButtonListeners().add(calendarPopupMouseButtonListener);
         calendarPopup.getComponentKeyListeners().add(calendarPopupKeyListener);
+        calendarPopup.getWindowStateListeners().add(calendarPopupWindowStateListener);
     }
 
     @Override
@@ -293,7 +353,7 @@
 
                 calendarPopup.setLocation(x, y);
                 calendarPopup.setPreferredSize(popupSize);
-                calendarPopup.open(calendarButton);
+                calendarPopup.open(calendarButton.getWindow());
 
                 calendar.requestFocus();
             }

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/skin/ListButtonSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/skin/ListButtonSkin.java?rev=757915&r1=757914&r2=757915&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/skin/ListButtonSkin.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/skin/ListButtonSkin.java Tue Mar 24 17:26:07 2009
@@ -17,10 +17,13 @@
 
 import pivot.collections.ArrayList;
 import pivot.collections.List;
+import pivot.util.Vote;
 import pivot.wtk.Button;
 import pivot.wtk.Component;
 import pivot.wtk.ComponentKeyListener;
 import pivot.wtk.ComponentMouseButtonListener;
+import pivot.wtk.Container;
+import pivot.wtk.ContainerMouseListener;
 import pivot.wtk.Dimensions;
 import pivot.wtk.Direction;
 import pivot.wtk.Display;
@@ -31,7 +34,8 @@
 import pivot.wtk.ListView;
 import pivot.wtk.Mouse;
 import pivot.wtk.Point;
-import pivot.wtk.Popup;
+import pivot.wtk.Window;
+import pivot.wtk.WindowStateListener;
 
 /**
  * Abstract base class for list button skins.
@@ -47,7 +51,31 @@
 public abstract class ListButtonSkin extends ButtonSkin
     implements ListButtonListener, ListButtonSelectionListener {
     protected ListView listView;
-    protected Popup listViewPopup;
+    protected Window listViewPopup;
+
+    private ComponentMouseButtonListener listViewPopupMouseButtonListener = new ComponentMouseButtonListener() {
+        public boolean mouseDown(Component component, Mouse.Button button, int x, int y) {
+            return false;
+        }
+
+        public boolean mouseUp(Component component, Mouse.Button button, int x, int y) {
+            return false;
+        }
+
+        public boolean mouseClick(Component component, Mouse.Button button, int x, int y, int count) {
+            ListButton listButton = (ListButton)getComponent();
+
+            int index = listView.getSelectedIndex();
+
+            listView.clearSelection();
+            listButton.setSelectedIndex(index);
+
+            listViewPopup.close();
+            getComponent().requestFocus();
+
+            return true;
+        }
+    };
 
     private ComponentKeyListener listViewPopupKeyListener = new ComponentKeyListener() {
         public boolean keyTyped(Component component, char character) {
@@ -93,27 +121,58 @@
         }
     };
 
-    private ComponentMouseButtonListener listViewPopupMouseListener = new ComponentMouseButtonListener() {
-        public boolean mouseDown(Component component, Mouse.Button button, int x, int y) {
-            return false;
+    private WindowStateListener listViewPopupWindowStateListener = new WindowStateListener() {
+        public Vote previewWindowOpen(Window window, Display display) {
+            return Vote.APPROVE;
         }
 
-        public boolean mouseUp(Component component, Mouse.Button button, int x, int y) {
-            return false;
+        public void windowOpenVetoed(Window window, Vote reason) {
+            // No-op
         }
 
-        public boolean mouseClick(Component component, Mouse.Button button, int x, int y, int count) {
-            ListButton listButton = (ListButton)getComponent();
+        public void windowOpened(Window window) {
+            Display display = window.getDisplay();
+            display.getContainerMouseListeners().add(displayMouseListener);
+        }
 
-            int index = listView.getSelectedIndex();
+        public Vote previewWindowClose(Window window) {
+            return Vote.APPROVE;
+        }
 
-            listView.clearSelection();
-            listButton.setSelectedIndex(index);
+        public void windowCloseVetoed(Window window, Vote reason) {
+            // No-op
+        }
 
-            listViewPopup.close();
-            getComponent().requestFocus();
+        public void windowClosed(Window window, Display display) {
+            display.getContainerMouseListeners().remove(displayMouseListener);
+        }
+    };
 
-            return true;
+    private ContainerMouseListener displayMouseListener = new ContainerMouseListener() {
+        public void mouseMove(Container container, int x, int y) {
+        }
+
+        public void mouseDown(Container container, Mouse.Button button, int x, int y) {
+            Display display = (Display)container;
+            Component descendant = display.getDescendantAt(x, y);
+
+            if (!listViewPopup.isAncestor(descendant)
+                && descendant != ListButtonSkin.this.getComponent()) {
+                listViewPopup.close();
+            }
+        }
+
+        public void mouseUp(Container container, Mouse.Button button, int x, int y) {
+        }
+
+        public void mouseWheel(Container container, Mouse.ScrollType scrollType,
+            int scrollAmount, int wheelRotation, int x, int y) {
+            Display display = (Display)container;
+            Window window = (Window)display.getComponentAt(x, y);
+
+            if (window != listViewPopup) {
+                listViewPopup.close();
+            }
         }
     };
 
@@ -122,9 +181,10 @@
     public ListButtonSkin() {
         listView = new ListView();
 
-        listViewPopup = new Popup();
-        listViewPopup.getComponentMouseButtonListeners().add(listViewPopupMouseListener);
+        listViewPopup = new Window(true);
+        listViewPopup.getComponentMouseButtonListeners().add(listViewPopupMouseButtonListener);
         listViewPopup.getComponentKeyListeners().add(listViewPopupKeyListener);
+        listViewPopup.getWindowStateListeners().add(listViewPopupWindowStateListener);
     }
 
     @Override
@@ -312,7 +372,7 @@
 
                     listViewPopup.setLocation(x, y);
                     listViewPopup.setPreferredSize(popupSize);
-                    listViewPopup.open(listButton);
+                    listViewPopup.open(listButton.getWindow());
 
                     if (listView.getFirstSelectedIndex() == -1
                         && listView.getListData().getLength() > 0) {

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/skin/MenuBarItemSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/skin/MenuBarItemSkin.java?rev=757915&r1=757914&r2=757915&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/skin/MenuBarItemSkin.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/skin/MenuBarItemSkin.java Tue Mar 24 17:26:07 2009
@@ -19,6 +19,8 @@
 import pivot.wtk.Button;
 import pivot.wtk.Component;
 import pivot.wtk.ComponentKeyListener;
+import pivot.wtk.Container;
+import pivot.wtk.ContainerMouseListener;
 import pivot.wtk.Direction;
 import pivot.wtk.Display;
 import pivot.wtk.Keyboard;
@@ -38,42 +40,77 @@
 public abstract class MenuBarItemSkin extends ButtonSkin implements MenuBar.ItemListener {
     protected MenuPopup menuPopup = new MenuPopup();
 
-    public MenuBarItemSkin() {
-        menuPopup.getWindowStateListeners().add(new WindowStateListener() {
-            public Vote previewWindowOpen(Window window, Display display) {
-                return Vote.APPROVE;
-            }
+    private WindowStateListener menuPopupWindowListener = new WindowStateListener() {
+        public Vote previewWindowOpen(Window window, Display display) {
+            return Vote.APPROVE;
+        }
 
-            public void windowOpenVetoed(Window window, Vote reason) {
-                // No-op
-            }
+        public void windowOpenVetoed(Window window, Vote reason) {
+            // No-op
+        }
+
+        public void windowOpened(Window window) {
+            Display display = window.getDisplay();
+            display.getContainerMouseListeners().add(displayMouseListener);
+        }
 
-            public void windowOpened(Window window) {
-                // No-op
+        public Vote previewWindowClose(Window window) {
+            return Vote.APPROVE;
+        }
+
+        public void windowCloseVetoed(Window window, Vote reason) {
+            // No-op
+        }
+
+        public void windowClosed(Window window, Display display) {
+            display.getContainerMouseListeners().remove(displayMouseListener);
+
+            MenuBar.Item menuBarItem = (MenuBar.Item)getComponent();
+            if (menuBarItem.isFocused()) {
+                Component.clearFocus();
+            } else {
+                repaintComponent();
             }
 
-            public Vote previewWindowClose(Window window) {
-                return Vote.APPROVE;
+            MenuBar menuBar = menuBarItem.getMenuBar();
+            if (!menuBar.containsFocus()) {
+                menuBar.setActive(false);
             }
+        }
+    };
+
+    private ContainerMouseListener displayMouseListener = new ContainerMouseListener() {
+        public void mouseMove(Container container, int x, int y) {
+        }
 
-            public void windowCloseVetoed(Window window, Vote reason) {
-                // No-op
+        public void mouseDown(Container container, Mouse.Button button, int x, int y) {
+            Display display = (Display)container;
+            Component descendant = display.getDescendantAt(x, y);
+
+            if (!menuPopup.isAncestor(descendant)
+                && !menuPopup.isOwner(descendant.getWindow())
+                && descendant != MenuBarItemSkin.this.getComponent()) {
+                menuPopup.close();
             }
+        }
 
-            public void windowClosed(Window window, Display display) {
-                MenuBar.Item menuBarItem = (MenuBar.Item)getComponent();
-                if (menuBarItem.isFocused()) {
-                    Component.clearFocus();
-                } else {
-                    repaintComponent();
-                }
+        public void mouseUp(Container container, Mouse.Button button, int x, int y) {
+        }
+
+        public void mouseWheel(Container container, Mouse.ScrollType scrollType,
+            int scrollAmount, int wheelRotation, int x, int y) {
+            Display display = (Display)container;
+            Window window = (Window)display.getComponentAt(x, y);
 
-                MenuBar menuBar = menuBarItem.getMenuBar();
-                if (!menuBar.containsFocus()) {
-                    menuBar.setActive(false);
-                }
+            if (window != menuPopup
+                && !menuPopup.isOwner(window)) {
+                menuPopup.close();
             }
-        });
+        }
+    };
+
+    public MenuBarItemSkin() {
+        menuPopup.getWindowStateListeners().add(menuPopupWindowListener);
     }
 
     @Override

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/skin/MenuButtonSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/skin/MenuButtonSkin.java?rev=757915&r1=757914&r2=757915&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/skin/MenuButtonSkin.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/skin/MenuButtonSkin.java Tue Mar 24 17:26:07 2009
@@ -18,6 +18,8 @@
 import pivot.util.Vote;
 import pivot.wtk.Button;
 import pivot.wtk.Component;
+import pivot.wtk.Container;
+import pivot.wtk.ContainerMouseListener;
 import pivot.wtk.Dimensions;
 import pivot.wtk.Display;
 import pivot.wtk.Keyboard;
@@ -40,38 +42,73 @@
     protected boolean pressed = false;
     protected MenuPopup menuPopup = new MenuPopup();
 
-    public MenuButtonSkin() {
-        menuPopup.getWindowStateListeners().add(new WindowStateListener() {
-            public Vote previewWindowOpen(Window window, Display display) {
-                return Vote.APPROVE;
-            }
+    private WindowStateListener menuPopupWindowStateListener = new WindowStateListener() {
+        public Vote previewWindowOpen(Window window, Display display) {
+            return Vote.APPROVE;
+        }
 
-            public void windowOpenVetoed(Window window, Vote reason) {
-                // No-op
-            }
+        public void windowOpenVetoed(Window window, Vote reason) {
+            // No-op
+        }
 
-            public void windowOpened(Window window) {
-                // No-op
-            }
+        public void windowOpened(Window window) {
+            Display display = window.getDisplay();
+            display.getContainerMouseListeners().add(displayMouseListener);
+        }
 
-            public Vote previewWindowClose(Window window) {
-                return Vote.APPROVE;
-            }
+        public Vote previewWindowClose(Window window) {
+            return Vote.APPROVE;
+        }
+
+        public void windowCloseVetoed(Window window, Vote reason) {
+            // No-op
+        }
+
+        public void windowClosed(Window window, Display display) {
+            display.getContainerMouseListeners().remove(displayMouseListener);
+
+            MenuButton menuButton = (MenuButton)getComponent();
 
-            public void windowCloseVetoed(Window window, Vote reason) {
-                // No-op
+            if (menuButton.isFocusable()) {
+                menuButton.requestFocus();
             }
 
-            public void windowClosed(Window window, Display display) {
-                MenuButton menuButton = (MenuButton)getComponent();
+            repaintComponent();
+        }
+    };
 
-                if (menuButton.isFocusable()) {
-                    menuButton.requestFocus();
-                }
+    private ContainerMouseListener displayMouseListener = new ContainerMouseListener() {
+        public void mouseMove(Container container, int x, int y) {
+        }
 
-                repaintComponent();
+        public void mouseDown(Container container, Mouse.Button button, int x, int y) {
+            Display display = (Display)container;
+            Component descendant = display.getDescendantAt(x, y);
+
+            if (!menuPopup.isAncestor(descendant)
+                && !menuPopup.isOwner(descendant.getWindow())
+                && descendant != MenuButtonSkin.this.getComponent()) {
+                menuPopup.close();
             }
-        });
+        }
+
+        public void mouseUp(Container container, Mouse.Button button, int x, int y) {
+        }
+
+        public void mouseWheel(Container container, Mouse.ScrollType scrollType,
+            int scrollAmount, int wheelRotation, int x, int y) {
+            Display display = (Display)container;
+            Window window = (Window)display.getComponentAt(x, y);
+
+            if (window != menuPopup
+                && !menuPopup.isOwner(window)) {
+                menuPopup.close();
+            }
+        }
+    };
+
+    public MenuButtonSkin() {
+        menuPopup.getWindowStateListeners().add(menuPopupWindowStateListener);
     }
 
     @Override

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/skin/MenuItemSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/skin/MenuItemSkin.java?rev=757915&r1=757914&r2=757915&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/skin/MenuItemSkin.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/skin/MenuItemSkin.java Tue Mar 24 17:26:07 2009
@@ -15,9 +15,12 @@
  */
 package pivot.wtk.skin;
 
+import pivot.util.Vote;
 import pivot.wtk.ApplicationContext;
 import pivot.wtk.Button;
 import pivot.wtk.Component;
+import pivot.wtk.Container;
+import pivot.wtk.ContainerMouseListener;
 import pivot.wtk.Direction;
 import pivot.wtk.Display;
 import pivot.wtk.Keyboard;
@@ -25,6 +28,8 @@
 import pivot.wtk.MenuPopup;
 import pivot.wtk.Mouse;
 import pivot.wtk.Point;
+import pivot.wtk.Window;
+import pivot.wtk.WindowStateListener;
 
 /**
  * Abstract base class for menu item skins.
@@ -35,9 +40,76 @@
     protected MenuPopup menuPopup = new MenuPopup();
 
     protected int buttonPressInterval = 200;
-
     protected ApplicationContext.ScheduledCallback buttonPressCallback = null;
 
+    private WindowStateListener menuPopupWindowListener = new WindowStateListener() {
+        public Vote previewWindowOpen(Window window, Display display) {
+            return Vote.APPROVE;
+        }
+
+        public void windowOpenVetoed(Window window, Vote reason) {
+            // No-op
+        }
+
+        public void windowOpened(Window window) {
+            Display display = window.getDisplay();
+            display.getContainerMouseListeners().add(displayMouseListener);
+        }
+
+        public Vote previewWindowClose(Window window) {
+            return Vote.APPROVE;
+        }
+
+        public void windowCloseVetoed(Window window, Vote reason) {
+            // No-op
+        }
+
+        public void windowClosed(Window window, Display display) {
+            display.getContainerMouseListeners().remove(displayMouseListener);
+
+            Menu.Item menuItem = (Menu.Item)getComponent();
+            if (menuItem.isFocused()) {
+                Component.clearFocus();
+            } else {
+                repaintComponent();
+            }
+        }
+    };
+
+    private ContainerMouseListener displayMouseListener = new ContainerMouseListener() {
+        public void mouseMove(Container container, int x, int y) {
+        }
+
+        public void mouseDown(Container container, Mouse.Button button, int x, int y) {
+            Display display = (Display)container;
+            Component descendant = display.getDescendantAt(x, y);
+
+            if (!menuPopup.isAncestor(descendant)
+                && !menuPopup.isOwner(descendant.getWindow())
+                && descendant != MenuItemSkin.this.getComponent()) {
+                menuPopup.close();
+            }
+        }
+
+        public void mouseUp(Container container, Mouse.Button button, int x, int y) {
+        }
+
+        public void mouseWheel(Container container, Mouse.ScrollType scrollType,
+            int scrollAmount, int wheelRotation, int x, int y) {
+            Display display = (Display)container;
+            Window window = (Window)display.getComponentAt(x, y);
+
+            if (window != menuPopup
+                && !menuPopup.isOwner(window)) {
+                menuPopup.close();
+            }
+        }
+    };
+
+    public MenuItemSkin() {
+        menuPopup.getWindowStateListeners().add(menuPopupWindowListener);
+    }
+
     @Override
     public void install(Component component) {
         super.install(component);

Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/skin/terra/TerraMenuPopupSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/skin/terra/TerraMenuPopupSkin.java?rev=757915&r1=757914&r2=757915&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/skin/terra/TerraMenuPopupSkin.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/skin/terra/TerraMenuPopupSkin.java Tue Mar 24 17:26:07 2009
@@ -33,14 +33,14 @@
 import pivot.wtk.effects.DropShadowDecorator;
 import pivot.wtk.effects.Transition;
 import pivot.wtk.effects.TransitionListener;
-import pivot.wtk.skin.PopupSkin;
+import pivot.wtk.skin.WindowSkin;
 
 /**
  * Menu popup skin.
  *
  * @author gbrown
  */
-public class TerraMenuPopupSkin extends PopupSkin
+public class TerraMenuPopupSkin extends WindowSkin
     implements MenuPopupListener, ComponentClassListener {
     private Panorama panorama;
     private Border border;
@@ -216,9 +216,13 @@
             Component focusedComponent = Component.getFocusedComponent();
 
             if (focusedComponent != null
-                && focusedComponent != affiliate
-                && !menuPopup.isOwningAncestorOf(focusedComponent.getWindow())) {
-                menuPopup.close();
+                && focusedComponent != affiliate) {
+                Window window = focusedComponent.getWindow();
+
+                if (window != menuPopup
+                    && !menuPopup.isOwner(window)) {
+                    menuPopup.close();
+                }
             }
         }
     }