• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 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.eclipse.adt.internal.sdk;
18 
19 import com.android.ide.eclipse.adt.internal.resources.configurations.CountryCodeQualifier;
20 import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
21 import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier;
22 import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier;
23 import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationStateQualifier;
24 import com.android.ide.eclipse.adt.internal.resources.configurations.NetworkCodeQualifier;
25 import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier;
26 import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenDimensionQualifier;
27 import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier;
28 import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier;
29 import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier;
30 import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier;
31 import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier;
32 
33 import org.w3c.dom.Document;
34 import org.w3c.dom.Element;
35 
36 import java.util.Collections;
37 import java.util.HashMap;
38 import java.util.Map;
39 import java.util.Map.Entry;
40 
41 /**
42  * Class representing a layout device.
43  *
44  * A Layout device is a collection of {@link FolderConfiguration} that can be used to render Android
45  * layout files.
46  *
47  * It also contains a single xdpi/ydpi that is independent of the {@link FolderConfiguration}.
48  *
49  * If the device is meant to represent a true device, then most of the FolderConfigurations' content
50  * should be identical, with only a few qualifiers (orientation, keyboard state) that would differ.
51  * However it is simpler to reuse the FolderConfiguration class (with the non changing qualifiers
52  * duplicated in each configuration) as it's what's being used by the rendering library.
53  *
54  * To create, edit and delete LayoutDevice objects, see {@link LayoutDeviceManager}.
55  * The class is not technically immutable but behaves as such outside of its package.
56  */
57 public class LayoutDevice {
58 
59     private final String mName;
60 
61     /** editable map of the config */
62     private Map<String, FolderConfiguration> mEditMap = new HashMap<String, FolderConfiguration>();
63     /** unmodifiable map returned by {@link #getConfigs()}. */
64     private Map<String, FolderConfiguration> mMap;
65     private float mXDpi = Float.NaN;
66     private float mYDpi = Float.NaN;
67 
LayoutDevice(String name)68     LayoutDevice(String name) {
69         mName = name;
70     }
71 
72     /**
73      * Saves the Layout Device into a document under a given node
74      * @param doc the document.
75      * @param parentNode the parent node.
76      */
saveTo(Document doc, Element parentNode)77     void saveTo(Document doc, Element parentNode) {
78         // create the device node
79         Element deviceNode = createNode(doc, parentNode, LayoutDevicesXsd.NODE_DEVICE);
80 
81         // create the name attribute (no namespace on this one).
82         deviceNode.setAttribute(LayoutDevicesXsd.ATTR_NAME, mName);
83 
84         // create a default with the x/y dpi
85         Element defaultNode = createNode(doc, deviceNode, LayoutDevicesXsd.NODE_DEFAULT);
86         if (Float.isNaN(mXDpi) == false) {
87             Element xdpiNode = createNode(doc, defaultNode, LayoutDevicesXsd.NODE_XDPI);
88             xdpiNode.setTextContent(Float.toString(mXDpi));
89         }
90         if (Float.isNaN(mYDpi) == false) {
91             Element xdpiNode = createNode(doc, defaultNode, LayoutDevicesXsd.NODE_YDPI);
92             xdpiNode.setTextContent(Float.toString(mYDpi));
93         }
94 
95         // then save all the configs.
96         for (Entry<String, FolderConfiguration> entry : mEditMap.entrySet()) {
97             saveConfigTo(doc, deviceNode, entry.getKey(), entry.getValue());
98         }
99     }
100 
101     /**
102      * Creates and returns a new NS-enabled node.
103      * @param doc the {@link Document}
104      * @param parentNode the parent node. The new node is appended to this one as a child.
105      * @param name the name of the node.
106      * @return the newly created node.
107      */
createNode(Document doc, Element parentNode, String name)108     private Element createNode(Document doc, Element parentNode, String name) {
109         Element newNode = doc.createElementNS(
110                 LayoutDevicesXsd.NS_LAYOUT_DEVICE_XSD, name);
111         newNode.setPrefix(doc.lookupPrefix(LayoutDevicesXsd.NS_LAYOUT_DEVICE_XSD));
112         parentNode.appendChild(newNode);
113 
114         return newNode;
115     }
116 
117     /**
118      * Saves a {@link FolderConfiguration} in a {@link Document}.
119      * @param doc the Document in which to save
120      * @param parent the parent node
121      * @param configName the name of the config
122      * @param config the config to save
123      */
saveConfigTo(Document doc, Element parent, String configName, FolderConfiguration config)124     private void saveConfigTo(Document doc, Element parent, String configName,
125             FolderConfiguration config) {
126         Element configNode = createNode(doc, parent, LayoutDevicesXsd.NODE_CONFIG);
127 
128         // create the name attribute (no namespace on this one).
129         configNode.setAttribute(LayoutDevicesXsd.ATTR_NAME, configName);
130 
131         // now do the qualifiers
132         CountryCodeQualifier ccq = config.getCountryCodeQualifier();
133         if (ccq != null) {
134             Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_COUNTRY_CODE);
135             node.setTextContent(Integer.toString(ccq.getCode()));
136         }
137 
138         NetworkCodeQualifier ncq = config.getNetworkCodeQualifier();
139         if (ncq != null) {
140             Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_NETWORK_CODE);
141             node.setTextContent(Integer.toString(ncq.getCode()));
142         }
143 
144         ScreenSizeQualifier ssq = config.getScreenSizeQualifier();
145         if (ssq != null) {
146             Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_SCREEN_SIZE);
147             node.setTextContent(ssq.getFolderSegment());
148         }
149 
150         ScreenRatioQualifier srq = config.getScreenRatioQualifier();
151         if (srq != null) {
152             Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_SCREEN_RATIO);
153             node.setTextContent(srq.getFolderSegment());
154         }
155 
156         ScreenOrientationQualifier soq = config.getScreenOrientationQualifier();
157         if (soq != null) {
158             Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_SCREEN_ORIENTATION);
159             node.setTextContent(soq.getFolderSegment());
160         }
161 
162         PixelDensityQualifier pdq = config.getPixelDensityQualifier();
163         if (pdq != null) {
164             Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_PIXEL_DENSITY);
165             node.setTextContent(pdq.getFolderSegment());
166         }
167 
168         TouchScreenQualifier ttq = config.getTouchTypeQualifier();
169         if (ttq != null) {
170             Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_TOUCH_TYPE);
171             node.setTextContent(ttq.getFolderSegment());
172         }
173 
174         KeyboardStateQualifier ksq = config.getKeyboardStateQualifier();
175         if (ksq != null) {
176             Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_KEYBOARD_STATE);
177             node.setTextContent(ksq.getFolderSegment());
178         }
179 
180         TextInputMethodQualifier timq = config.getTextInputMethodQualifier();
181         if (timq != null) {
182             Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_TEXT_INPUT_METHOD);
183             node.setTextContent(timq.getFolderSegment());
184         }
185 
186         NavigationStateQualifier nsq = config.getNavigationStateQualifier();
187         if (nsq != null) {
188             Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_NAV_STATE);
189             node.setTextContent(nsq.getFolderSegment());
190         }
191 
192         NavigationMethodQualifier nmq = config.getNavigationMethodQualifier();
193         if (nmq != null) {
194             Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_NAV_METHOD);
195             node.setTextContent(nmq.getFolderSegment());
196         }
197 
198         ScreenDimensionQualifier sdq = config.getScreenDimensionQualifier();
199         if (sdq != null) {
200             Element sizeNode = createNode(doc, configNode, LayoutDevicesXsd.NODE_SCREEN_DIMENSION);
201 
202             Element node = createNode(doc, sizeNode, LayoutDevicesXsd.NODE_SIZE);
203             node.setTextContent(Integer.toString(sdq.getValue1()));
204 
205             node = createNode(doc, sizeNode, LayoutDevicesXsd.NODE_SIZE);
206             node.setTextContent(Integer.toString(sdq.getValue2()));
207         }
208     }
209 
addConfig(String name, FolderConfiguration config)210     void addConfig(String name, FolderConfiguration config) {
211         mEditMap.put(name, config);
212         _seal();
213     }
214 
addConfigs(Map<String, FolderConfiguration> configs)215     void addConfigs(Map<String, FolderConfiguration> configs) {
216         mEditMap.putAll(configs);
217         _seal();
218     }
219 
removeConfig(String name)220     void removeConfig(String name) {
221         mEditMap.remove(name);
222         _seal();
223     }
224 
225     /**
226      * Adds config to the LayoutDevice. This is to be used to add plenty of configurations.
227      * It must be followed by {@link #_seal()}.
228      * @param name the name of the config
229      * @param config the config.
230      */
_addConfig(String name, FolderConfiguration config)231     void _addConfig(String name, FolderConfiguration config) {
232         mEditMap.put(name, config);
233     }
234 
_seal()235     void _seal() {
236         mMap = Collections.unmodifiableMap(mEditMap);
237     }
238 
setXDpi(float xdpi)239     void setXDpi(float xdpi) {
240         mXDpi = xdpi;
241     }
242 
setYDpi(float ydpi)243     void setYDpi(float ydpi) {
244         mYDpi = ydpi;
245     }
246 
getName()247     public String getName() {
248         return mName;
249     }
250 
getConfigs()251     public Map<String, FolderConfiguration> getConfigs() {
252         return mMap;
253     }
254 
255     /**
256      * Returns the dpi of the Device screen in X.
257      * @return the dpi of screen or {@link Float#NaN} if it's not set.
258      */
getXDpi()259     public float getXDpi() {
260         return mXDpi;
261     }
262 
263     /**
264      * Returns the dpi of the Device screen in Y.
265      * @return the dpi of screen or {@link Float#NaN} if it's not set.
266      */
getYDpi()267     public float getYDpi() {
268         return mYDpi;
269     }
270  }
271