/* * 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.editors.layout.gle2; import com.android.ide.eclipse.adt.internal.editors.layout.uimodel.UiViewElementNode; import com.android.layoutlib.api.ILayoutResult; import com.android.layoutlib.api.ILayoutResult.ILayoutViewInfo; import org.eclipse.swt.graphics.Rectangle; import java.util.ArrayList; /** * Maps a {@link ILayoutViewInfo} in a structure more adapted to our needs. * The only large difference is that we keep both the original bounds of the view info * and we pre-compute the selection bounds which are absolute to the rendered image (where * as the original bounds are relative to the parent view.) * <p/> * Each view also know its parent, which should be handy later. * <p/> * We can't alter {@link ILayoutViewInfo} as it is part of the LayoutBridge and needs to * have a fixed API. */ /* package */ class CanvasViewInfo { /** * Minimal size of the selection, in case an empty view or layout is selected. */ private static final int SELECTION_MIN_SIZE = 6; private final Rectangle mAbsRect; private final Rectangle mSelectionRect; private final String mName; private final UiViewElementNode mUiViewKey; private final CanvasViewInfo mParent; private final ArrayList<CanvasViewInfo> mChildren = new ArrayList<CanvasViewInfo>(); /** * Constructs a {@link CanvasViewInfo} hierarchy based on a given {@link ILayoutViewInfo} * hierarchy. This call is recursive and builds a full tree. * * @param viewInfo The root of the {@link ILayoutViewInfo} hierarchy. */ public CanvasViewInfo(ILayoutViewInfo viewInfo) { this(viewInfo, null /*parent*/, 0 /*parentX*/, 0 /*parentY*/); } private CanvasViewInfo(ILayoutViewInfo viewInfo, CanvasViewInfo parent, int parentX, int parentY) { mParent = parent; mName = viewInfo.getName(); // The ILayoutViewInfo#getViewKey() method returns a key which depends on the // IXmlPullParser used to parse the layout files. In this case, the parser is // guaranteed to be an UiElementPullParser, which creates keys that are of type // UiViewElementNode. // We'll simply crash if the type is not right, as this is not supposed to happen // and nothing could work if there's a type mismatch. mUiViewKey = (UiViewElementNode) viewInfo.getViewKey(); int x = viewInfo.getLeft(); int y = viewInfo.getTop(); int w = viewInfo.getRight() - x; int h = viewInfo.getBottom() - y; if (parent != null) { x += parentX; y += parentY; } mAbsRect = new Rectangle(x, y, w - 1, h - 1); if (viewInfo.getChildren() != null) { for (ILayoutViewInfo child : viewInfo.getChildren()) { mChildren.add(new CanvasViewInfo(child, this, x, y)); } } // adjust selection bounds for views which are too small to select if (w < SELECTION_MIN_SIZE) { int d = (SELECTION_MIN_SIZE - w) / 2; x -= d; w += SELECTION_MIN_SIZE - w; } if (h < SELECTION_MIN_SIZE) { int d = (SELECTION_MIN_SIZE - h) / 2; y -= d; h += SELECTION_MIN_SIZE - h; } mSelectionRect = new Rectangle(x, y, w - 1, h - 1); } /** * Returns the original {@link ILayoutResult} bounds in absolute coordinates * over the whole graphic. */ public Rectangle getAbsRect() { return mAbsRect; } /* * Returns the absolute selection bounds of the view info as a rectangle. * The selection bounds will always have a size greater or equal to * {@link #SELECTION_MIN_SIZE}. * The width/height is inclusive (i.e. width = right-left-1). * This is in absolute "screen" coordinates (relative to the rendered bitmap). */ public Rectangle getSelectionRect() { return mSelectionRect; } /** * Returns the view key. Could be null, although unlikely. * @return An {@link UiViewElementNode} that uniquely identifies the object in the XML model. * @see ILayoutViewInfo#getViewKey() */ public UiViewElementNode getUiViewKey() { return mUiViewKey; } /** * Returns the parent {@link CanvasViewInfo}. * It is null for the root and non-null for children. */ public CanvasViewInfo getParent() { return mParent; } /** * Returns the list of children of this {@link CanvasViewInfo}. * The list is never null. It can be empty. * By contract, this.getChildren().get(0..n-1).getParent() == this. */ public ArrayList<CanvasViewInfo> getChildren() { return mChildren; } /** * Returns the name of the {@link CanvasViewInfo}. * Could be null, although unlikely. * Experience shows this is the full qualified Java name of the View. * @see ILayoutViewInfo#getName() */ public String getName() { return mName; } }