Search in sources :

Example 6 with ViewInfo

use of com.android.ide.common.rendering.api.ViewInfo in project android_frameworks_base by ResurrectionRemix.

the class RenderSessionImpl method createViewInfo.

/**
     * Creates a {@link ViewInfo} for the view. The {@code ViewInfo} corresponding to the children
     * of the {@code view} are not created. Consequently, the children of {@code ViewInfo} is not
     * set.
     * @param offset an offset for the view bounds. Used only if view is part of the content frame.
     */
private ViewInfo createViewInfo(View view, int offset, boolean setExtendedInfo, boolean isContentFrame) {
    if (view == null) {
        return null;
    }
    ViewParent parent = view.getParent();
    ViewInfo result;
    if (isContentFrame) {
        // Account for parent scroll values when calculating the bounding box
        int scrollX = parent != null ? ((View) parent).getScrollX() : 0;
        int scrollY = parent != null ? ((View) parent).getScrollY() : 0;
        // The view is part of the layout added by the user. Hence,
        // the ViewCookie may be obtained only through the Context.
        result = new ViewInfo(view.getClass().getName(), getContext().getViewKey(view), -scrollX + view.getLeft(), -scrollY + view.getTop() + offset, -scrollX + view.getRight(), -scrollY + view.getBottom() + offset, view, view.getLayoutParams());
    } else {
        // We are part of the system decor.
        SystemViewInfo r = new SystemViewInfo(view.getClass().getName(), getViewKey(view), view.getLeft(), view.getTop(), view.getRight(), view.getBottom(), view, view.getLayoutParams());
        result = r;
        // 3. The overflow popup button.
        if (view instanceof ListMenuItemView) {
            // Mark 2.
            // All menus in the popup are of type ListMenuItemView.
            r.setViewType(ViewType.ACTION_BAR_OVERFLOW_MENU);
        } else {
            // Mark 3.
            ViewGroup.LayoutParams lp = view.getLayoutParams();
            if (lp instanceof ActionMenuView.LayoutParams && ((ActionMenuView.LayoutParams) lp).isOverflowButton) {
                r.setViewType(ViewType.ACTION_BAR_OVERFLOW);
            } else {
                // actionProviderClass.
                while (parent != mViewRoot && parent instanceof ViewGroup) {
                    if (parent instanceof ActionMenuView) {
                        r.setViewType(ViewType.ACTION_BAR_MENU);
                        break;
                    }
                    parent = parent.getParent();
                }
            }
        }
    }
    if (setExtendedInfo) {
        MarginLayoutParams marginParams = null;
        LayoutParams params = view.getLayoutParams();
        if (params instanceof MarginLayoutParams) {
            marginParams = (MarginLayoutParams) params;
        }
        result.setExtendedInfo(view.getBaseline(), marginParams != null ? marginParams.leftMargin : 0, marginParams != null ? marginParams.topMargin : 0, marginParams != null ? marginParams.rightMargin : 0, marginParams != null ? marginParams.bottomMargin : 0);
    }
    return result;
}
Also used : ListMenuItemView(com.android.internal.view.menu.ListMenuItemView) MarginLayoutParams(android.view.ViewGroup.MarginLayoutParams) LayoutParams(android.view.ViewGroup.LayoutParams) ViewParent(android.view.ViewParent) ViewGroup(android.view.ViewGroup) LayoutParams(android.view.ViewGroup.LayoutParams) ActionMenuView(android.widget.ActionMenuView) MarginLayoutParams(android.view.ViewGroup.MarginLayoutParams) ViewInfo(com.android.ide.common.rendering.api.ViewInfo)

Example 7 with ViewInfo

use of com.android.ide.common.rendering.api.ViewInfo in project android by JetBrains.

the class AttributesTransaction method setAttribute.

@Override
public void setAttribute(@Nullable String namespace, @NotNull String name, @Nullable String value) {
    myLock.writeLock().lock();
    try {
        assert isValid;
        String key = attributeKey(namespace, name);
        PendingAttribute attribute = myPendingAttributes.get(key);
        boolean modified = true;
        if (attribute != null) {
            if (StringUtil.equals(attribute.value, value)) {
                // No change. We do not need to propagate the attribute value to the view
                modified = false;
            } else {
                attribute.value = value;
            }
        } else {
            attribute = new PendingAttribute(namespace, name, value);
            myPendingAttributes.put(key, attribute);
        }
        ViewInfo viewInfo = myComponent.viewInfo;
        if (viewInfo != null) {
            View cachedView = myCachedView.get();
            if (cachedView == viewInfo.getViewObject()) {
                // We still have the same view info so we can just apply the delta (the passed attribute)
                if (modified && cachedView != null) {
                    applyAttributeToView(attribute, viewInfo, myModel);
                }
            } else {
                // The view object has changed so we need to re-apply all the attributes
                applyAllPendingAttributesToView(viewInfo);
            }
        }
    } finally {
        myLock.writeLock().unlock();
    }
}
Also used : View(android.view.View) ViewInfo(com.android.ide.common.rendering.api.ViewInfo)

Example 8 with ViewInfo

use of com.android.ide.common.rendering.api.ViewInfo in project android by JetBrains.

the class AttributesTransaction method commit.

/**
   * Commits all the pending changes to the model. After this method has been called, no more writes or reads can be made from
   * this transaction.
   *
   * @return true if the XML was changed as result of this call
   */
public boolean commit() {
    ViewInfo viewInfo = myComponent.viewInfo;
    if (hasPendingRelayout && viewInfo != null) {
        View currentView = (View) viewInfo.getViewObject();
        if (currentView != myCachedView.get()) {
            // The view has changed since the last update so re-apply everything
            applyAllPendingAttributesToView(myComponent.viewInfo);
        }
        triggerViewRelayout((View) myComponent.viewInfo.getViewObject());
    }
    myLock.writeLock().lock();
    try {
        assert isValid;
        if (!myComponent.getTag().isValid()) {
            return finishTransaction();
        }
        if (!ApplicationManager.getApplication().isWriteAccessAllowed()) {
            return ApplicationManager.getApplication().runWriteAction((Computable<Boolean>) this::commit);
        }
        boolean modified = false;
        for (PendingAttribute attribute : myPendingAttributes.values()) {
            String originalValue = myOriginalValues.get(attributeKey(attribute.namespace, attribute.name));
            String currentValue = myComponent.getAttribute(attribute.namespace, attribute.name);
            if (!StringUtil.equals(currentValue, attribute.value)) {
                // The value has changed from what's in the XML
                if (!StringUtil.equals(originalValue, currentValue)) {
                    // The attribute value has changed since we started the transaction, deal with the conflict.
                    if (StringUtil.isEmpty(attribute.value)) {
                        // leave the attribute with the modified value.
                        continue;
                    } else if (StringUtil.equals(originalValue, attribute.value)) {
                        // The attribute has been modified without the change being send through this transaction. Leave the modified value.
                        continue;
                    }
                }
                modified = true;
                myComponent.setAttribute(attribute.namespace, attribute.name, attribute.value);
            }
        }
        isSuccessful = true;
        finishTransaction();
        return modified;
    } finally {
        myLock.writeLock().unlock();
    }
}
Also used : View(android.view.View) Computable(com.intellij.openapi.util.Computable) ViewInfo(com.android.ide.common.rendering.api.ViewInfo)

Example 9 with ViewInfo

use of com.android.ide.common.rendering.api.ViewInfo in project android by JetBrains.

the class ModelBuilder method buildViewInfos.

private List<ViewInfo> buildViewInfos(@NotNull NlModel model) {
    List<ViewInfo> infos = Lists.newArrayList();
    XmlFile file = model.getFile();
    assertThat(file).isNotNull();
    assertThat(file.getRootTag()).isNotNull();
    infos.add(myRoot.createViewInfo(null, file.getRootTag()));
    return infos;
}
Also used : XmlFile(com.intellij.psi.xml.XmlFile) ViewInfo(com.android.ide.common.rendering.api.ViewInfo)

Example 10 with ViewInfo

use of com.android.ide.common.rendering.api.ViewInfo in project android by JetBrains.

the class NlModelTest method testMoveInHierarchyWithWrongXmlTags.

public void testMoveInHierarchyWithWrongXmlTags() throws Exception {
    ModelBuilder modelBuilder = model("linear.xml", component(LINEAR_LAYOUT).withBounds(0, 0, 1000, 1000).matchParentWidth().matchParentHeight().withAttribute(ANDROID_URI, ATTR_ORIENTATION, VALUE_VERTICAL).children(component(FRAME_LAYOUT).withBounds(100, 100, 100, 100).width("100dp").height("100dp").children(component(BUTTON).withBounds(100, 100, 100, 100).width("100dp").height("100dp"))));
    NlModel model = modelBuilder.build();
    assertEquals("NlComponent{tag=<LinearLayout>, bounds=[0,0:1000x1000, instance=0}\n" + "    NlComponent{tag=<FrameLayout>, bounds=[100,100:100x100, instance=1}\n" + "        NlComponent{tag=<Button>, bounds=[100,100:100x100, instance=2}", myTreeDumper.toTree(model.getComponents()));
    XmlTag originalRoot = model.getFile().getRootTag();
    assertThat(originalRoot).isNotNull();
    XmlTag originalFrameLayout = originalRoot.getSubTags()[0];
    final Project project = model.getProject();
    WriteCommandAction.runWriteCommandAction(project, () -> {
        PsiDocumentManager manager = PsiDocumentManager.getInstance(project);
        Document document = manager.getDocument(model.getFile());
        assertThat(document).isNotNull();
        document.setText("<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" + "    android:layout_width=\"match_parent\"\n" + "    android:layout_height=\"match_parent\"\n" + "    android:orientation=\"vertical\">\n" + "    <Button\n" + "        android:layout_width=\"100dp\"\n" + "        android:layout_height=\"100dp\"\n" + "        android:text=\"Button\" />\n" + "    <FrameLayout\n" + "        android:layout_width=\"100dp\"\n" + "        android:layout_height=\"100dp\">\n" + "\n" + "    </FrameLayout>\n" + "\n" + "</LinearLayout>");
        manager.commitAllDocuments();
    });
    // Manually construct the view hierarchy
    // Assert that component identity is preserved
    List<ViewInfo> views = Lists.newArrayList();
    XmlTag newRoot = model.getFile().getRootTag();
    assertThat(newRoot).isNotNull();
    XmlTag[] newRootSubTags = newRoot.getSubTags();
    XmlTag newButton = newRootSubTags[0];
    assertThat(originalRoot).isSameAs(newRoot);
    assertThat(originalFrameLayout).isSameAs(newButton);
    TagSnapshot snapshot = TagSnapshot.createTagSnapshot(newRoot);
    ViewInfo viewInfo = new ViewInfo("android.widget.LinearLayout", snapshot, 0, 0, 500, 500);
    views.add(viewInfo);
    ViewInfo buttonInfo = new ViewInfo("android.widget.Button", snapshot.children.get(0), 0, 0, 500, 500);
    buttonInfo.setChildren(Collections.emptyList());
    ViewInfo frameViewInfo = new ViewInfo("android.widget.TextView", snapshot.children.get(1), 0, 0, 300, 300);
    frameViewInfo.setChildren(Collections.emptyList());
    viewInfo.setChildren(Arrays.asList(buttonInfo, frameViewInfo));
    model.updateHierarchy(newRoot, views);
    assertEquals("NlComponent{tag=<LinearLayout>, bounds=[0,0:500x500, instance=3}\n" + // since before the reparse instance=1 was associated with a <FrameLayout> !
    "    NlComponent{tag=<Button>, bounds=[0,0:500x500, instance=4}\n" + "    NlComponent{tag=<FrameLayout>, bounds=[0,0:300x300, instance=5}", myTreeDumper.toTree(model.getComponents()));
}
Also used : ModelBuilder(com.android.tools.idea.uibuilder.fixtures.ModelBuilder) Project(com.intellij.openapi.project.Project) TagSnapshot(com.android.tools.idea.rendering.TagSnapshot) Document(com.intellij.openapi.editor.Document) XmlTag(com.intellij.psi.xml.XmlTag) PsiDocumentManager(com.intellij.psi.PsiDocumentManager) ViewInfo(com.android.ide.common.rendering.api.ViewInfo)

Aggregations

ViewInfo (com.android.ide.common.rendering.api.ViewInfo)37 ViewGroup (android.view.ViewGroup)11 LayoutParams (android.view.ViewGroup.LayoutParams)6 MarginLayoutParams (android.view.ViewGroup.MarginLayoutParams)6 SessionParams (com.android.ide.common.rendering.api.SessionParams)6 XmlTag (com.intellij.psi.xml.XmlTag)6 ViewParent (android.view.ViewParent)5 ActionMenuView (android.widget.ActionMenuView)5 ListMenuItemView (com.android.internal.view.menu.ListMenuItemView)5 LayoutLibTestCallback (com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback)5 LayoutPullParser (com.android.layoutlib.bridge.intensive.setup.LayoutPullParser)5 NotNull (org.jetbrains.annotations.NotNull)5 Test (org.junit.Test)5 View (android.view.View)3 RenderLogger (com.android.tools.idea.rendering.RenderLogger)3 XmlFile (com.intellij.psi.xml.XmlFile)3 ListView (android.widget.ListView)2 Configuration (com.android.tools.idea.configurations.Configuration)2 RenderService (com.android.tools.idea.rendering.RenderService)2 RenderTask (com.android.tools.idea.rendering.RenderTask)2