]> source.dussan.org Git - vaadin-framework.git/commitdiff
Adds context menu to empty space in Tree. #5992
authorJohn Alhroos <john.ahlroos@itmill.com>
Wed, 27 Apr 2011 09:33:13 +0000 (09:33 +0000)
committerJohn Alhroos <john.ahlroos@itmill.com>
Wed, 27 Apr 2011 09:33:13 +0000 (09:33 +0000)
svn changeset:18488/svn branch:6.6

src/com/vaadin/terminal/gwt/client/ui/VTree.java
src/com/vaadin/ui/Tree.java

index 43915af3c90c1a6ca964633f358a9f0e239bdffe..0ee86da0a0cc34c079b09ff34cd35ac9eacb7c0a 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
 @ITMillApache2LicenseForJavaFiles@
  */
 
@@ -19,6 +19,8 @@ import com.google.gwt.dom.client.NativeEvent;
 import com.google.gwt.dom.client.Node;
 import com.google.gwt.event.dom.client.BlurEvent;
 import com.google.gwt.event.dom.client.BlurHandler;
+import com.google.gwt.event.dom.client.ContextMenuEvent;
+import com.google.gwt.event.dom.client.ContextMenuHandler;
 import com.google.gwt.event.dom.client.FocusEvent;
 import com.google.gwt.event.dom.client.FocusHandler;
 import com.google.gwt.event.dom.client.KeyCodes;
@@ -56,7 +58,7 @@ import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation;
  */
 public class VTree extends SimpleFocusablePanel implements Paintable,
         VHasDropHandler, FocusHandler, BlurHandler, KeyPressHandler,
-        KeyDownHandler, SubPartAware {
+        KeyDownHandler, SubPartAware, ActionOwner {
 
     public static final String CLASSNAME = "v-tree";
 
@@ -103,6 +105,8 @@ public class VTree extends SimpleFocusablePanel implements Paintable,
 
     private boolean selectionHasChanged = false;
 
+    private String[] bodyActionKeys;
+
     public VLazyExecutor iconLoaded = new VLazyExecutor(50,
             new ScheduledCommand() {
 
@@ -120,6 +124,16 @@ public class VTree extends SimpleFocusablePanel implements Paintable,
         addFocusHandler(this);
         addBlurHandler(this);
 
+        /*
+         * Listen to context menu events on the empty space in the tree
+         */
+        sinkEvents(Event.ONCONTEXTMENU);
+        addDomHandler(new ContextMenuHandler() {
+            public void onContextMenu(ContextMenuEvent event) {
+                handleBodyContextMenu(event);
+            }
+        }, ContextMenuEvent.getType());
+
         /*
          * Firefox auto-repeat works correctly only if we use a key press
          * handler, other browsers handle it correctly when using a key down
@@ -237,6 +251,10 @@ public class VTree extends SimpleFocusablePanel implements Paintable,
 
         isNullSelectionAllowed = uidl.getBooleanAttribute("nullselect");
 
+        if (uidl.hasAttribute("alb")) {
+            bodyActionKeys = uidl.getStringArrayAttribute("alb");
+        }
+
         body.clear();
         for (final Iterator<?> i = uidl.getChildIterator(); i.hasNext();) {
             final UIDL childUidl = (UIDL) i.next();
@@ -2120,4 +2138,41 @@ public class VTree extends SimpleFocusablePanel implements Paintable,
         return locator;
     }
 
+    public Action[] getActions() {
+        if (bodyActionKeys == null) {
+            return new Action[] {};
+        }
+        final Action[] actions = new Action[bodyActionKeys.length];
+        for (int i = 0; i < actions.length; i++) {
+            final String actionKey = bodyActionKeys[i];
+            final TreeAction a = new TreeAction(this, null, actionKey);
+            a.setCaption(getActionCaption(actionKey));
+            a.setIconUrl(getActionIcon(actionKey));
+            actions[i] = a;
+        }
+        return actions;
+    }
+
+    public ApplicationConnection getClient() {
+        return client;
+    }
+
+    public String getPaintableId() {
+        return paintableId;
+    }
+
+    private void handleBodyContextMenu(ContextMenuEvent event) {
+        if (!readonly && !disabled) {
+            if (bodyActionKeys != null) {
+                int left = event.getNativeEvent().getClientX();
+                int top = event.getNativeEvent().getClientY();
+                top += Window.getScrollTop();
+                left += Window.getScrollLeft();
+                client.getContextMenu().showAt(this, left, top);
+            }
+            event.stopPropagation();
+            event.preventDefault();
+        }
+    }
+
 }
index 523f3fe739ad99e32d2c732e7edfc70fb84f2af0..38dbfdae75434506eb2f7f2f6a13da92be296566 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
 @ITMillApache2LicenseForJavaFiles@
  */
 
@@ -23,6 +23,7 @@ import com.vaadin.data.Item;
 import com.vaadin.data.util.ContainerHierarchicalWrapper;
 import com.vaadin.data.util.IndexedContainer;
 import com.vaadin.event.Action;
+import com.vaadin.event.Action.Handler;
 import com.vaadin.event.DataBoundTransferable;
 import com.vaadin.event.ItemClickEvent;
 import com.vaadin.event.ItemClickEvent.ItemClickListener;
@@ -437,7 +438,6 @@ public class Tree extends AbstractSelect implements Container.Hierarchical,
 
         // Actions
         if (variables.containsKey("action")) {
-
             final StringTokenizer st = new StringTokenizer(
                     (String) variables.get("action"), ",");
             if (st.countTokens() == 2) {
@@ -445,9 +445,15 @@ public class Tree extends AbstractSelect implements Container.Hierarchical,
                 final Action action = (Action) actionMapper.get(st.nextToken());
                 if (action != null && containsId(itemId)
                         && actionHandlers != null) {
-                    for (final Iterator<Action.Handler> i = actionHandlers
-                            .iterator(); i.hasNext();) {
-                        i.next().handleAction(action, this, itemId);
+                    // Item action
+                    for (Handler ah : actionHandlers) {
+                        ah.handleAction(action, this, itemId);
+                    }
+                } else if (action != null && actionHandlers != null
+                        && itemId == null) {
+                    // Body action
+                    for (Handler ah : actionHandlers) {
+                        ah.handleAction(action, this, null);
                     }
                 }
             }
@@ -551,6 +557,28 @@ public class Tree extends AbstractSelect implements Container.Hierarchical,
             iteratorStack.push(ids.iterator());
         }
 
+        /*
+         * Body actions - Actions which has the target null and can be invoked
+         * by right clicking on the Tree body
+         */
+        if (actionHandlers != null) {
+            final ArrayList<String> keys = new ArrayList<String>();
+            for (Handler ah : actionHandlers) {
+
+                // Getting action for the null item, which in this case
+                // means the body item
+                final Action[] aa = ah.getActions(null, this);
+                if (aa != null) {
+                    for (int ai = 0; ai < aa.length; ai++) {
+                        final String akey = actionMapper.key(aa[ai]);
+                        actionSet.add(aa[ai]);
+                        keys.add(akey);
+                    }
+                }
+            }
+            target.addAttribute("alb", keys.toArray());
+        }
+
         while (!iteratorStack.isEmpty()) {
 
             // Gets the iterator for current tree level