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