Author: mvw
Date: 2008-03-15 14:33:38-0700
New Revision: 14191

Modified:
   trunk/src/app/src/org/argouml/ui/ZoomSliderButton.java

Log:
Fix for issue 2421 about removal of the zoom button; this patch was supplied by 
Dave Thompson.

Modified: trunk/src/app/src/org/argouml/ui/ZoomSliderButton.java
Url: 
http://argouml.tigris.org/source/browse/argouml/trunk/src/app/src/org/argouml/ui/ZoomSliderButton.java?view=diff&rev=14191&p1=trunk/src/app/src/org/argouml/ui/ZoomSliderButton.java&p2=trunk/src/app/src/org/argouml/ui/ZoomSliderButton.java&r1=14190&r2=14191
==============================================================================
--- trunk/src/app/src/org/argouml/ui/ZoomSliderButton.java      (original)
+++ trunk/src/app/src/org/argouml/ui/ZoomSliderButton.java      2008-03-15 
14:33:38-0700
@@ -1,5 +1,5 @@
 // $Id$
-// Copyright (c) 2003-2006 The Regents of the University of California. All
+// Copyright (c) 2003-2008 The Regents of the University of California. All
 // Rights Reserved. Permission to use, copy, modify, and distribute this
 // software and its documentation without fee, and without a written
 // agreement is hereby granted, provided that the above copyright notice
@@ -33,15 +33,21 @@
 import java.awt.event.ActionListener;
 import java.awt.event.FocusAdapter;
 import java.awt.event.FocusEvent;
+import java.awt.event.MouseEvent;
 import java.util.Enumeration;
 
+import javax.swing.AbstractAction;
 import javax.swing.Icon;
 import javax.swing.JLabel;
 import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
 import javax.swing.JSlider;
 import javax.swing.JTextField;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
+import javax.swing.event.MouseInputAdapter;
+import javax.swing.event.PopupMenuEvent;
+import javax.swing.event.PopupMenuListener;
 
 import org.argouml.application.helpers.ResourceLoaderWrapper;
 import org.argouml.i18n.Translator;
@@ -94,15 +100,46 @@
      * The text field which shows the current zoom magnification value.
      */
     private JTextField          currentValue = null;
+    
+    /**
+     * Used to enable/disable the popup button.
+     */
+    private boolean             popupButtonIsActive = true;
+    
+    /**
+     * Indicates whether the popupmenu is showing or not.
+     */
+    private boolean             popupMenuIsShowing = false;
+    
+    /**
+     * Indicates whether the mouse is over the popup button or not.
+     */
+    private boolean             mouseIsOverPopupButton = false;
 
     /**
      * Constructs a new ZoomSliderButton.
      */
     public ZoomSliderButton() {
         super();
+        setAction( new AbstractAction() {
+            public void actionPerformed(ActionEvent e) {
+                /* If action comes in with *no* modifiers, it is a pure
+                 * keyboard event (e.g. spacebar), so do it.  Anything else
+                 * is probably a mouse event, so ignore it. Mouse events are
+                 * dealt with by mousePressed() instead (see bottom of page).
+                 */ 
+                if (e.getModifiers() == 0) {
+                    showPopup();
+                }
+            }
+        });
 
         Icon icon = ResourceLoaderWrapper.lookupIcon(RESOURCE_NAME);
 
+        MyMouseListener myMouseListener = new MyMouseListener();
+        addMouseMotionListener(myMouseListener);
+        addMouseListener(myMouseListener);
+
         setIcon(icon);
         setToolTipText(Translator.localize("button.zoom"));
     }
@@ -188,8 +225,13 @@
             slider.setValue((int) (ed.getScale() * 100d));
         }
 
-        super.showPopup();
-
+        if ( popupButtonIsActive ) {
+            super.showPopup();
+            JPopupMenu pm = (JPopupMenu) this.getPopupComponent().getParent();
+            PopupMenuListener pml = new MyPopupMenuListener();
+            pm.addPopupMenuListener(pml);
+            popupMenuIsShowing = true;
+        }
         slider.requestFocus();
     }
 
@@ -239,4 +281,70 @@
     private void updateCurrentValueLabel() {
         currentValue.setText(String.valueOf(slider.getValue()) + '%');
     }
+    
+    private class MyPopupMenuListener extends AbstractAction implements
+        PopupMenuListener {
+
+       /**
+         * Empty method to satisfy interface.
+         */
+       public void actionPerformed(ActionEvent e) {
+        }
+
+        /**
+         * Method gets fired when the popup dies.
+         * Conditionally re-enable the button depending on where the pointer 
+         * is.
+         */
+        public void popupMenuCanceled(PopupMenuEvent e) {
+            if (mouseIsOverPopupButton) {
+                popupButtonIsActive = false;
+            } else {
+                popupButtonIsActive = true;
+            }
+            popupMenuIsShowing = false;
+        }
+
+        public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
+        }
+
+        public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
+        }
+
+    };
+
+    private class MyMouseListener extends MouseInputAdapter {
+
+        /**
+         * Keeps track of mouseover status. 
+         */
+        public void mouseEntered(MouseEvent me) {
+            mouseIsOverPopupButton = true;
+        }
+        
+        /**
+         * Keeps track of mouseover status, and renables button if necessary.
+         */
+        public void mouseExited(MouseEvent me) {
+            mouseIsOverPopupButton = false;
+            if (!popupButtonIsActive && !popupMenuIsShowing)
+            {
+                popupButtonIsActive = true;
+            }
+        }
+
+        /**
+         * Catch the down stroke of mouse click to make the popup appear a tiny
+         * bit earlier.
+         */
+        public void mousePressed(MouseEvent me) {
+            if (popupButtonIsActive) {
+                showPopup();
+            }
+            else if ( !popupMenuIsShowing )
+            {
+                popupButtonIsActive = true;
+            }
+        }
+    }
 }

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to