• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Eclipse Public License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.eclipse.org/org/documents/epl-v10.php
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.ide.common.layout;
18 
19 import static com.android.ide.common.layout.LayoutConstants.ANDROID_URI;
20 import static com.android.ide.common.layout.LayoutConstants.ATTR_EMS;
21 import static com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors.REQUEST_FOCUS;
22 
23 import com.android.ide.common.api.IMenuCallback;
24 import com.android.ide.common.api.INode;
25 import com.android.ide.common.api.INodeHandler;
26 import com.android.ide.common.api.IViewRule;
27 import com.android.ide.common.api.InsertType;
28 import com.android.ide.common.api.RuleAction;
29 
30 import java.util.List;
31 
32 /**
33  * An {@link IViewRule} for android.widget.EditText.
34  */
35 public class EditTextRule extends BaseViewRule {
36 
37     @Override
onCreate(INode node, INode parent, InsertType insertType)38     public void onCreate(INode node, INode parent, InsertType insertType) {
39         super.onCreate(node, parent, insertType);
40 
41         if (parent != null) {
42             INode focus = findFocus(findRoot(parent));
43             if (focus == null) {
44                 // Add <requestFocus>
45                 node.appendChild(REQUEST_FOCUS);
46             }
47 
48             if (parent.getBounds().w >= 320) {
49                 node.setAttribute(ANDROID_URI, ATTR_EMS, "10"); //$NON-NLS-1$
50             }
51         }
52     }
53 
54     /**
55      * {@inheritDoc}
56      * <p>
57      * Adds a "Request Focus" menu item.
58      */
59     @Override
addContextMenuActions(List<RuleAction> actions, final INode selectedNode)60     public void addContextMenuActions(List<RuleAction> actions, final INode selectedNode) {
61         super.addContextMenuActions(actions, selectedNode);
62 
63         final boolean hasFocus = hasFocus(selectedNode);
64         final String label = hasFocus ? "Clear Focus" : "Request Focus";
65 
66         IMenuCallback onChange = new IMenuCallback() {
67             @Override
68             public void action(RuleAction menuAction, List<? extends INode> selectedNodes,
69                     String valueId, Boolean newValue) {
70                 selectedNode.editXml(label, new INodeHandler() {
71                     @Override
72                     public void handle(INode node) {
73                         INode focus = findFocus(findRoot(node));
74                         if (focus != null && focus.getParent() != null) {
75                             focus.getParent().removeChild(focus);
76                         }
77                         if (!hasFocus) {
78                             node.appendChild(REQUEST_FOCUS);
79                         }
80                     }
81                 });
82             }
83         };
84 
85         actions.add(RuleAction.createAction("_setfocus", label, onChange, //$NON-NLS-1$
86                 null, 5, false /*supportsMultipleNodes*/));
87         actions.add(RuleAction.createSeparator(7));
88     }
89 
90     /** Returns true if the given node currently has focus */
hasFocus(INode node)91     private static boolean hasFocus(INode node) {
92         INode focus = findFocus(node);
93         if (focus != null) {
94             return focus.getParent() == node;
95         }
96 
97         return false;
98     }
99 
100     /** Returns the root/top level node in the view hierarchy that contains the given node */
findRoot(INode node)101     private static INode findRoot(INode node) {
102         // First find the parent
103         INode root = node;
104         while (root != null) {
105             INode parent = root.getParent();
106             if (parent == null) {
107                 break;
108             } else {
109                 root = parent;
110             }
111         }
112 
113         return root;
114     }
115 
116     /** Finds the focus node (not the node containing focus, but the actual request focus node
117      * under a given node */
findFocus(INode node)118     private static INode findFocus(INode node) {
119         if (node.getFqcn().equals(REQUEST_FOCUS)) {
120             return node;
121         }
122 
123         for (INode child : node.getChildren()) {
124             INode focus = findFocus(child);
125             if (focus != null) {
126                 return focus;
127             }
128         }
129         return null;
130     }
131 
132 }
133