use of com.android.ide.common.rendering.api.ViewInfo in project android by JetBrains.
the class IconPreviewFactory method renderDragImage.
/**
* Return a component image to display while dragging a component from the palette.
* Return null if such an image cannot be rendered. The palette must provide a fallback in this case.
*/
@Nullable
public BufferedImage renderDragImage(@NotNull Palette.Item item, @NotNull ScreenView screenView) {
XmlElementFactory elementFactory = XmlElementFactory.getInstance(screenView.getModel().getProject());
String xml = item.getDragPreviewXml();
if (xml.equals(NO_PREVIEW)) {
return null;
}
XmlTag tag;
try {
tag = elementFactory.createTagFromText(xml);
} catch (IncorrectOperationException exception) {
return null;
}
NlModel model = screenView.getModel();
NlComponent component = ApplicationManager.getApplication().runWriteAction((Computable<NlComponent>) () -> model.createComponent(screenView, tag, null, null, InsertType.CREATE_PREVIEW));
if (component == null) {
return null;
}
// Some components require a parent to render correctly.
xml = String.format(LINEAR_LAYOUT, CONTAINER_ID, component.getTag().getText());
RenderResult result = renderImage(myExecutorService, myRenderTimeoutSeconds, getRenderTask(model.getConfiguration()), xml);
if (result == null || !result.hasImage()) {
return null;
}
ImagePool.Image image = result.getRenderedImage();
List<ViewInfo> infos = result.getRootViews();
if (infos.isEmpty()) {
return null;
}
infos = infos.get(0).getChildren();
if (infos == null || infos.isEmpty()) {
return null;
}
ViewInfo view = infos.get(0);
if (image.getHeight() < view.getBottom() || image.getWidth() < view.getRight() || view.getBottom() <= view.getTop() || view.getRight() <= view.getLeft()) {
return null;
}
@AndroidCoordinate int shadowWitdh = SHADOW_SIZE * screenView.getConfiguration().getDensity().getDpiValue() / Density.DEFAULT_DENSITY;
@SwingCoordinate int shadowIncrement = 1 + Coordinates.getSwingDimension(screenView, shadowWitdh);
BufferedImage imageCopy = image.getCopy();
if (imageCopy == null) {
return null;
}
return imageCopy.getSubimage(view.getLeft(), view.getTop(), Math.min(view.getRight() + shadowIncrement, image.getWidth()), Math.min(view.getBottom() + shadowIncrement, image.getHeight()));
}
use of com.android.ide.common.rendering.api.ViewInfo in project android by JetBrains.
the class AttributesTransaction method apply.
/**
* Apply the current transaction, without saving to XML
* It will trigger a layout.
*/
public void apply() {
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());
}
}
use of com.android.ide.common.rendering.api.ViewInfo in project android by JetBrains.
the class NlComponentFixture method requireViewClass.
public void requireViewClass(@NotNull String fqn) {
ViewInfo viewInfo = myComponent.viewInfo;
Object viewObject = viewInfo.getViewObject();
assertEquals(fqn, viewObject.getClass().getName());
}
use of com.android.ide.common.rendering.api.ViewInfo in project android by JetBrains.
the class ViewEditorImpl method measureChildren.
@Nullable
@Override
public Map<NlComponent, Dimension> measureChildren(@NotNull NlComponent parent, @Nullable RenderTask.AttributeFilter filter) {
// TODO: Reuse snapshot!
Map<NlComponent, Dimension> unweightedSizes = Maps.newHashMap();
XmlTag parentTag = parent.getTag();
if (parentTag.isValid()) {
if (parent.getChildCount() == 0) {
return Collections.emptyMap();
}
Map<XmlTag, NlComponent> tagToComponent = Maps.newHashMapWithExpectedSize(parent.getChildCount());
for (NlComponent child : parent.getChildren()) {
tagToComponent.put(child.getTag(), child);
}
NlModel model = myScreen.getModel();
XmlFile xmlFile = model.getFile();
AndroidFacet facet = model.getFacet();
RenderService renderService = RenderService.get(facet);
RenderLogger logger = renderService.createLogger();
final RenderTask task = renderService.createTask(xmlFile, getConfiguration(), logger, null);
if (task == null) {
return null;
}
// Measure unweighted bounds
Map<XmlTag, ViewInfo> map = task.measureChildren(parentTag, filter);
task.dispose();
if (map != null) {
for (Map.Entry<XmlTag, ViewInfo> entry : map.entrySet()) {
ViewInfo viewInfo = entry.getValue();
viewInfo = RenderService.getSafeBounds(viewInfo);
Dimension size = new Dimension(viewInfo.getRight() - viewInfo.getLeft(), viewInfo.getBottom() - viewInfo.getTop());
NlComponent child = tagToComponent.get(entry.getKey());
if (child != null) {
unweightedSizes.put(child, size);
}
}
}
}
return unweightedSizes;
}
use of com.android.ide.common.rendering.api.ViewInfo in project android by JetBrains.
the class ConstraintModel method updateConstraintLayoutRoots.
/**
* Traverse the hierarchy to find all ConstraintLayout instances
* and update them. We set all the wrap_content sizes of the ConstraintLayout children
* from layout lib
* @param container
*
*/
private void updateConstraintLayoutRoots(WidgetContainer container) {
if (container == null) {
return;
}
Map<NlComponent, Dimension> wrapContentSizes = Maps.newHashMap();
if (container instanceof ConstraintWidgetContainer) {
NlComponent component = (NlComponent) ((WidgetCompanion) container.getCompanionWidget()).getWidgetModel();
Insets padding = component.getPadding(true);
container.setDimension(pxToDp(component.w - padding.width()), pxToDp(component.h - padding.height()));
int x = pxToDp(component.x);
int y = pxToDp(component.y);
x += pxToDp(padding.left);
y += pxToDp(padding.top);
WidgetContainer parentContainer = (WidgetContainer) container.getParent();
if (parentContainer != null) {
if (!(parentContainer instanceof ConstraintWidgetContainer)) {
x = pxToDp(component.x - component.getParent().x);
y = pxToDp(component.y - component.getParent().y);
} else {
x -= parentContainer.getDrawX();
y -= parentContainer.getDrawY();
}
}
if (container.getX() != x || container.getY() != y) {
container.setOrigin(x, y);
container.forceUpdateDrawPosition();
}
}
if (!(container instanceof ConstraintWidgetContainer)) {
NlComponent component = (NlComponent) ((WidgetCompanion) container.getCompanionWidget()).getWidgetModel();
container.setDimension(pxToDp(component.w), pxToDp(component.h));
}
if (container instanceof ConstraintWidgetContainer && container.getChildren().size() > 0) {
NlComponent root = (NlComponent) ((WidgetCompanion) container.getCompanionWidget()).getWidgetModel();
XmlTag parentTag = root.getTag();
if (parentTag.isValid()) {
Map<XmlTag, NlComponent> tagToComponent = Maps.newHashMapWithExpectedSize(root.getChildCount());
for (NlComponent child : root.getChildren()) {
tagToComponent.put(child.getTag(), child);
}
XmlFile xmlFile = myNlModel.getFile();
AndroidFacet facet = myNlModel.getFacet();
RenderService renderService = RenderService.get(facet);
RenderLogger logger = renderService.createLogger();
final RenderTask task = renderService.createTask(xmlFile, myNlModel.getConfiguration(), logger, null);
if (task != null) {
// Measure wrap_content bounds
Map<XmlTag, ViewInfo> map = task.measureChildren(parentTag, new RenderTask.AttributeFilter() {
@Override
public String getAttribute(@NotNull XmlTag n, @Nullable String namespace, @NotNull String localName) {
// Change attributes to wrap_content
if (ATTR_LAYOUT_WIDTH.equals(localName) && ANDROID_URI.equals(namespace)) {
return VALUE_WRAP_CONTENT;
}
if (ATTR_LAYOUT_HEIGHT.equals(localName) && ANDROID_URI.equals(namespace)) {
return VALUE_WRAP_CONTENT;
}
return null;
}
});
task.dispose();
if (map != null) {
for (Map.Entry<XmlTag, ViewInfo> entry : map.entrySet()) {
ViewInfo viewInfo = entry.getValue();
viewInfo = RenderService.getSafeBounds(viewInfo);
Dimension size = new Dimension(viewInfo.getRight() - viewInfo.getLeft(), viewInfo.getBottom() - viewInfo.getTop());
NlComponent child = tagToComponent.get(entry.getKey());
if (child != null) {
wrapContentSizes.put(child, size);
}
}
}
}
}
}
for (ConstraintWidget child : container.getChildren()) {
NlComponent component = (NlComponent) ((WidgetCompanion) child.getCompanionWidget()).getWidgetModel();
Dimension dimension = wrapContentSizes.get(component);
if (dimension != null) {
child.setWrapWidth(pxToDp((int) dimension.getWidth()));
child.setWrapHeight(pxToDp((int) dimension.getHeight()));
}
if (child instanceof WidgetContainer) {
updateConstraintLayoutRoots((WidgetContainer) child);
}
}
}
Aggregations