/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutDevice.java
Java | 389 lines | 220 code | 53 blank | 116 comment | 40 complexity | 388c509730cc7ad1fcd61e625e87d879 MD5 | raw file
- /*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package com.android.ide.eclipse.adt.internal.sdk;
- import com.android.ide.common.resources.configuration.CountryCodeQualifier;
- import com.android.ide.common.resources.configuration.DensityQualifier;
- import com.android.ide.common.resources.configuration.FolderConfiguration;
- import com.android.ide.common.resources.configuration.KeyboardStateQualifier;
- import com.android.ide.common.resources.configuration.NavigationMethodQualifier;
- import com.android.ide.common.resources.configuration.NavigationStateQualifier;
- import com.android.ide.common.resources.configuration.NetworkCodeQualifier;
- import com.android.ide.common.resources.configuration.ScreenDimensionQualifier;
- import com.android.ide.common.resources.configuration.ScreenOrientationQualifier;
- import com.android.ide.common.resources.configuration.ScreenRatioQualifier;
- import com.android.ide.common.resources.configuration.ScreenSizeQualifier;
- import com.android.ide.common.resources.configuration.TextInputMethodQualifier;
- import com.android.ide.common.resources.configuration.TouchScreenQualifier;
- import org.w3c.dom.Document;
- import org.w3c.dom.Element;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.List;
- /**
- * Class representing a layout device.
- *
- * A Layout device is a collection of {@link FolderConfiguration} that can be used to render Android
- * layout files.
- *
- * It also contains a single xdpi/ydpi that is independent of the {@link FolderConfiguration}.
- *
- * If the device is meant to represent a true device, then most of the FolderConfigurations' content
- * should be identical, with only a few qualifiers (orientation, keyboard state) that would differ.
- * However it is simpler to reuse the FolderConfiguration class (with the non changing qualifiers
- * duplicated in each configuration) as it's what's being used by the rendering library.
- *
- * To create, edit and delete LayoutDevice objects, see {@link LayoutDeviceManager}.
- * The class is not technically immutable but behaves as such outside of its package.
- */
- public class LayoutDevice {
- private final String mName;
- /**
- * Wrapper around a {@link FolderConfiguration}.
- * <p/>This adds a name, accessible through {@link #getName()}.
- * <p/>The folder config can be accessed through {@link #getConfig()}.
- *
- */
- public final static class DeviceConfig {
- private final String mName;
- private final FolderConfiguration mConfig;
- DeviceConfig(String name, FolderConfiguration config) {
- mName = name;
- mConfig = config;
- }
- public String getName() {
- return mName;
- }
- public FolderConfiguration getConfig() {
- return mConfig;
- }
- }
- /** editable list of the config */
- private final ArrayList<DeviceConfig> mConfigs = new ArrayList<DeviceConfig>();
- /** Read-only list */
- private List<DeviceConfig> mROList;
- private float mXDpi = Float.NaN;
- private float mYDpi = Float.NaN;
- LayoutDevice(String name) {
- mName = name;
- }
- /**
- * Saves the Layout Device into a document under a given node
- * @param doc the document.
- * @param parentNode the parent node.
- */
- void saveTo(Document doc, Element parentNode) {
- // create the device node
- Element deviceNode = createNode(doc, parentNode, LayoutDevicesXsd.NODE_DEVICE);
- // create the name attribute (no namespace on this one).
- deviceNode.setAttribute(LayoutDevicesXsd.ATTR_NAME, mName);
- // create a default with the x/y dpi
- Element defaultNode = createNode(doc, deviceNode, LayoutDevicesXsd.NODE_DEFAULT);
- if (Float.isNaN(mXDpi) == false) {
- Element xdpiNode = createNode(doc, defaultNode, LayoutDevicesXsd.NODE_XDPI);
- xdpiNode.setTextContent(Float.toString(mXDpi));
- }
- if (Float.isNaN(mYDpi) == false) {
- Element xdpiNode = createNode(doc, defaultNode, LayoutDevicesXsd.NODE_YDPI);
- xdpiNode.setTextContent(Float.toString(mYDpi));
- }
- // then save all the configs.
- synchronized (mConfigs) {
- for (DeviceConfig config : mConfigs) {
- saveConfigTo(doc, deviceNode, config.getName(), config.getConfig());
- }
- }
- }
- /**
- * Creates and returns a new NS-enabled node.
- * @param doc the {@link Document}
- * @param parentNode the parent node. The new node is appended to this one as a child.
- * @param name the name of the node.
- * @return the newly created node.
- */
- private Element createNode(Document doc, Element parentNode, String name) {
- Element newNode = doc.createElementNS(
- LayoutDevicesXsd.NS_LAYOUT_DEVICE_XSD, name);
- newNode.setPrefix(doc.lookupPrefix(LayoutDevicesXsd.NS_LAYOUT_DEVICE_XSD));
- parentNode.appendChild(newNode);
- return newNode;
- }
- /**
- * Saves a {@link FolderConfiguration} in a {@link Document}.
- * @param doc the Document in which to save
- * @param parent the parent node
- * @param configName the name of the config
- * @param config the config to save
- */
- private void saveConfigTo(Document doc, Element parent, String configName,
- FolderConfiguration config) {
- Element configNode = createNode(doc, parent, LayoutDevicesXsd.NODE_CONFIG);
- // create the name attribute (no namespace on this one).
- configNode.setAttribute(LayoutDevicesXsd.ATTR_NAME, configName);
- // now do the qualifiers
- CountryCodeQualifier ccq = config.getCountryCodeQualifier();
- if (ccq != null) {
- Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_COUNTRY_CODE);
- node.setTextContent(Integer.toString(ccq.getCode()));
- }
- NetworkCodeQualifier ncq = config.getNetworkCodeQualifier();
- if (ncq != null) {
- Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_NETWORK_CODE);
- node.setTextContent(Integer.toString(ncq.getCode()));
- }
- ScreenSizeQualifier slsq = config.getScreenSizeQualifier();
- if (slsq != null) {
- Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_SCREEN_SIZE);
- node.setTextContent(slsq.getFolderSegment());
- }
- ScreenRatioQualifier srq = config.getScreenRatioQualifier();
- if (srq != null) {
- Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_SCREEN_RATIO);
- node.setTextContent(srq.getFolderSegment());
- }
- ScreenOrientationQualifier soq = config.getScreenOrientationQualifier();
- if (soq != null) {
- Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_SCREEN_ORIENTATION);
- node.setTextContent(soq.getFolderSegment());
- }
- DensityQualifier dq = config.getDensityQualifier();
- if (dq != null) {
- Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_PIXEL_DENSITY);
- node.setTextContent(dq.getFolderSegment());
- }
- TouchScreenQualifier ttq = config.getTouchTypeQualifier();
- if (ttq != null) {
- Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_TOUCH_TYPE);
- node.setTextContent(ttq.getFolderSegment());
- }
- KeyboardStateQualifier ksq = config.getKeyboardStateQualifier();
- if (ksq != null) {
- Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_KEYBOARD_STATE);
- node.setTextContent(ksq.getFolderSegment());
- }
- TextInputMethodQualifier timq = config.getTextInputMethodQualifier();
- if (timq != null) {
- Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_TEXT_INPUT_METHOD);
- node.setTextContent(timq.getFolderSegment());
- }
- NavigationStateQualifier nsq = config.getNavigationStateQualifier();
- if (nsq != null) {
- Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_NAV_STATE);
- node.setTextContent(nsq.getFolderSegment());
- }
- NavigationMethodQualifier nmq = config.getNavigationMethodQualifier();
- if (nmq != null) {
- Element node = createNode(doc, configNode, LayoutDevicesXsd.NODE_NAV_METHOD);
- node.setTextContent(nmq.getFolderSegment());
- }
- ScreenDimensionQualifier sdq = config.getScreenDimensionQualifier();
- if (sdq != null) {
- Element sizeNode = createNode(doc, configNode, LayoutDevicesXsd.NODE_SCREEN_DIMENSION);
- Element node = createNode(doc, sizeNode, LayoutDevicesXsd.NODE_SIZE);
- node.setTextContent(Integer.toString(sdq.getValue1()));
- node = createNode(doc, sizeNode, LayoutDevicesXsd.NODE_SIZE);
- node.setTextContent(Integer.toString(sdq.getValue2()));
- }
- }
- /**
- * Adds config to the LayoutDevice.
- * <p/>This ensures that no two configurations have the same. If a config already exists
- * with the same name, the new config replaces it.
- *
- * @param name the name of the config.
- * @param config the config.
- */
- void addConfig(String name, FolderConfiguration config) {
- synchronized (mConfigs) {
- doAddConfig(name, config);
- seal();
- }
- }
- /**
- * Adds a list of config to the LayoutDevice
- * <p/>This ensures that no two configurations have the same. If a config already exists
- * with the same name, the new config replaces it.
- * @param configs the configs to add.
- */
- void addConfigs(List<DeviceConfig> configs) {
- synchronized (mConfigs) {
- // add the configs manually one by one, to check for no duplicate.
- for (DeviceConfig config : configs) {
- String name = config.getName();
- for (DeviceConfig c : mConfigs) {
- if (c.getName().equals(name)) {
- mConfigs.remove(c);
- break;
- }
- }
- mConfigs.add(config);
- }
- seal();
- }
- }
- /**
- * Removes a config by its name.
- * @param name the name of the config to remove.
- */
- void removeConfig(String name) {
- synchronized (mConfigs) {
- for (DeviceConfig config : mConfigs) {
- if (config.getName().equals(name)) {
- mConfigs.remove(config);
- seal();
- return;
- }
- }
- }
- }
- /**
- * Adds config to the LayoutDevice. This is to be used to add plenty of
- * configurations. It must be followed by {@link #_seal()}.
- * <p/>This ensures that no two configurations have the same. If a config already exists
- * with the same name, the new config replaces it.
- * <p/><strong>This must be called inside a <code>synchronized(mConfigs)</code> block.</strong>
- *
- * @param name the name of the config
- * @param config the config.
- */
- private void doAddConfig(String name, FolderConfiguration config) {
- // remove config that would have the same name to ensure no duplicate
- for (DeviceConfig c : mConfigs) {
- if (c.getName().equals(name)) {
- mConfigs.remove(c);
- break;
- }
- }
- mConfigs.add(new DeviceConfig(name, config));
- }
- /**
- * Seals the layout device by setting up {@link #mROList}.
- * <p/><strong>This must be called inside a <code>synchronized(mConfigs)</code> block.</strong>
- */
- private void seal() {
- mROList = Collections.unmodifiableList(mConfigs);
- }
- void setXDpi(float xdpi) {
- mXDpi = xdpi;
- }
- void setYDpi(float ydpi) {
- mYDpi = ydpi;
- }
- public String getName() {
- return mName;
- }
- /**
- * Returns an unmodifiable list of all the {@link DeviceConfig}.
- */
- public List<DeviceConfig> getConfigs() {
- synchronized (mConfigs) {
- return mROList;
- }
- }
- /**
- * Returns a {@link DeviceConfig} by its name.
- */
- public DeviceConfig getDeviceConfigByName(String name) {
- synchronized (mConfigs) {
- for (DeviceConfig config : mConfigs) {
- if (config.getName().equals(name)) {
- return config;
- }
- }
- }
- return null;
- }
- /**
- * Returns a {@link FolderConfiguration} by its name.
- */
- public FolderConfiguration getFolderConfigByName(String name) {
- synchronized (mConfigs) {
- for (DeviceConfig config : mConfigs) {
- if (config.getName().equals(name)) {
- return config.getConfig();
- }
- }
- }
- return null;
- }
- /**
- * Returns the dpi of the Device screen in X.
- * @return the dpi of screen or {@link Float#NaN} if it's not set.
- */
- public float getXDpi() {
- return mXDpi;
- }
- /**
- * Returns the dpi of the Device screen in Y.
- * @return the dpi of screen or {@link Float#NaN} if it's not set.
- */
- public float getYDpi() {
- return mYDpi;
- }
- }