Search in sources :

Example 26 with LayoutlibDelegate

use of com.android.tools.layoutlib.annotations.LayoutlibDelegate in project platform_frameworks_base by android.

the class LayoutInflater_Delegate method parseInclude.

@LayoutlibDelegate
public static void parseInclude(LayoutInflater thisInflater, XmlPullParser parser, Context context, View parent, AttributeSet attrs) throws XmlPullParserException, IOException {
    int type;
    if (parent instanceof ViewGroup) {
        // Apply a theme wrapper, if requested. This is sort of a weird
        // edge case, since developers think the <include> overwrites
        // values in the AttributeSet of the included View. So, if the
        // included View has a theme attribute, we'll need to ignore it.
        final TypedArray ta = context.obtainStyledAttributes(attrs, ATTRS_THEME);
        final int themeResId = ta.getResourceId(0, 0);
        final boolean hasThemeOverride = themeResId != 0;
        if (hasThemeOverride) {
            context = new ContextThemeWrapper(context, themeResId);
        }
        ta.recycle();
        // If the layout is pointing to a theme attribute, we have to
        // massage the value to get a resource identifier out of it.
        int layout = attrs.getAttributeResourceValue(null, ATTR_LAYOUT, 0);
        if (layout == 0) {
            final String value = attrs.getAttributeValue(null, ATTR_LAYOUT);
            if (value == null || value.length() <= 0) {
                throw new InflateException("You must specify a layout in the" + " include tag: <include layout=\"@layout/layoutID\" />");
            }
            // Attempt to resolve the "?attr/name" string to an identifier.
            layout = context.getResources().getIdentifier(value.substring(1), null, null);
        }
        // ---- START CHANGES
        if (layout != 0) {
            final TypedValue tempValue = new TypedValue();
            if (context.getTheme().resolveAttribute(layout, tempValue, true)) {
                layout = tempValue.resourceId;
            }
        }
        if (layout == 0) {
            final String value = attrs.getAttributeValue(null, ATTR_LAYOUT);
            if (value == null) {
                throw new InflateException("You must specifiy a layout in the" + " include tag: <include layout=\"@layout/layoutID\" />");
            } else {
                throw new InflateException("You must specifiy a valid layout " + "reference. The layout ID " + value + " is not valid.");
            }
        } else {
            final XmlResourceParser childParser = thisInflater.getContext().getResources().getLayout(layout);
            try {
                final AttributeSet childAttrs = Xml.asAttributeSet(childParser);
                while ((type = childParser.next()) != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT) {
                // Empty.
                }
                if (type != XmlPullParser.START_TAG) {
                    throw new InflateException(childParser.getPositionDescription() + ": No start tag found!");
                }
                final String childName = childParser.getName();
                if (TAG_MERGE.equals(childName)) {
                    // Inflate all children.
                    thisInflater.rInflate(childParser, parent, context, childAttrs, false);
                } else {
                    final View view = thisInflater.createViewFromTag(parent, childName, context, childAttrs, hasThemeOverride);
                    final ViewGroup group = (ViewGroup) parent;
                    final TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.Include);
                    final int id = a.getResourceId(com.android.internal.R.styleable.Include_id, View.NO_ID);
                    final int visibility = a.getInt(com.android.internal.R.styleable.Include_visibility, -1);
                    a.recycle();
                    // We try to load the layout params set in the <include /> tag. If
                    // they don't exist, we will rely on the layout params set in the
                    // included XML file.
                    // During a layoutparams generation, a runtime exception is thrown
                    // if either layout_width or layout_height is missing. We catch
                    // this exception and set localParams accordingly: true means we
                    // successfully loaded layout params from the <include /> tag,
                    // false means we need to rely on the included layout params.
                    ViewGroup.LayoutParams params = null;
                    try {
                        // ---- START CHANGES
                        sIsInInclude = true;
                        // ---- END CHANGES
                        params = group.generateLayoutParams(attrs);
                    } catch (RuntimeException ignored) {
                    // Ignore, just fail over to child attrs.
                    } finally {
                        // ---- START CHANGES
                        sIsInInclude = false;
                    // ---- END CHANGES
                    }
                    if (params == null) {
                        params = group.generateLayoutParams(childAttrs);
                    }
                    view.setLayoutParams(params);
                    // Inflate all children.
                    thisInflater.rInflateChildren(childParser, view, childAttrs, true);
                    if (id != View.NO_ID) {
                        view.setId(id);
                    }
                    switch(visibility) {
                        case 0:
                            view.setVisibility(View.VISIBLE);
                            break;
                        case 1:
                            view.setVisibility(View.INVISIBLE);
                            break;
                        case 2:
                            view.setVisibility(View.GONE);
                            break;
                    }
                    group.addView(view);
                }
            } finally {
                childParser.close();
            }
        }
    } else {
        throw new InflateException("<include /> can only be used inside of a ViewGroup");
    }
    LayoutInflater.consumeChildElements(parser);
}
Also used : XmlResourceParser(android.content.res.XmlResourceParser) AttributeSet(android.util.AttributeSet) TypedArray(android.content.res.TypedArray) TypedValue(android.util.TypedValue) LayoutlibDelegate(com.android.tools.layoutlib.annotations.LayoutlibDelegate)

Example 27 with LayoutlibDelegate

use of com.android.tools.layoutlib.annotations.LayoutlibDelegate in project platform_frameworks_base by android.

the class Canvas_Delegate method nativeDrawBitmapMatrix.

@LayoutlibDelegate
public static void nativeDrawBitmapMatrix(long nCanvas, Bitmap bitmap, long nMatrix, long nPaint) {
    // get the delegate from the native int.
    Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
    if (canvasDelegate == null) {
        return;
    }
    // get the delegate from the native int, which can be null
    Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nPaint);
    // get the delegate from the native int.
    Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
    if (bitmapDelegate == null) {
        return;
    }
    final BufferedImage image = getImageToDraw(bitmapDelegate, paintDelegate, sBoolOut);
    Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(nMatrix);
    if (matrixDelegate == null) {
        return;
    }
    final AffineTransform mtx = matrixDelegate.getAffineTransform();
    canvasDelegate.getSnapshot().draw(new GcSnapshot.Drawable() {

        @Override
        public void draw(Graphics2D graphics, Paint_Delegate paint) {
            if (paint != null && paint.isFilterBitmap()) {
                graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            }
            //FIXME add support for canvas, screen and bitmap densities.
            graphics.drawImage(image, mtx, null);
        }
    }, paintDelegate, true, /*compositeOnly*/
    false);
}
Also used : AffineTransform(java.awt.geom.AffineTransform) GcSnapshot(com.android.layoutlib.bridge.impl.GcSnapshot) BufferedImage(java.awt.image.BufferedImage) Graphics2D(java.awt.Graphics2D) LayoutlibDelegate(com.android.tools.layoutlib.annotations.LayoutlibDelegate)

Example 28 with LayoutlibDelegate

use of com.android.tools.layoutlib.annotations.LayoutlibDelegate in project platform_frameworks_base by android.

the class Canvas_Delegate method native_getCTM.

@LayoutlibDelegate
public static void native_getCTM(long canvas, long matrix) {
    // get the delegate from the native int.
    Canvas_Delegate canvasDelegate = sManager.getDelegate(canvas);
    if (canvasDelegate == null) {
        return;
    }
    Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(matrix);
    if (matrixDelegate == null) {
        return;
    }
    AffineTransform transform = canvasDelegate.getSnapshot().getTransform();
    matrixDelegate.set(Matrix_Delegate.makeValues(transform));
}
Also used : AffineTransform(java.awt.geom.AffineTransform) LayoutlibDelegate(com.android.tools.layoutlib.annotations.LayoutlibDelegate)

Example 29 with LayoutlibDelegate

use of com.android.tools.layoutlib.annotations.LayoutlibDelegate in project platform_frameworks_base by android.

the class Canvas_Delegate method native_setMatrix.

@LayoutlibDelegate
public static void native_setMatrix(long nCanvas, long nMatrix) {
    // get the delegate from the native int.
    Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
    if (canvasDelegate == null) {
        return;
    }
    Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(nMatrix);
    if (matrixDelegate == null) {
        return;
    }
    // get the current top graphics2D object.
    GcSnapshot snapshot = canvasDelegate.getSnapshot();
    // get the AffineTransform of the given matrix
    AffineTransform matrixTx = matrixDelegate.getAffineTransform();
    // give it to the graphics2D as a new matrix replacing all previous transform
    snapshot.setTransform(matrixTx);
    if (matrixDelegate.hasPerspective()) {
        assert false;
        Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_AFFINE, "android.graphics.Canvas#setMatrix(android.graphics.Matrix) only " + "supports affine transformations.", null, null);
    }
}
Also used : AffineTransform(java.awt.geom.AffineTransform) GcSnapshot(com.android.layoutlib.bridge.impl.GcSnapshot) LayoutlibDelegate(com.android.tools.layoutlib.annotations.LayoutlibDelegate)

Example 30 with LayoutlibDelegate

use of com.android.tools.layoutlib.annotations.LayoutlibDelegate in project platform_frameworks_base by android.

the class FontFamily_Delegate method nAddFontFromAsset.

@LayoutlibDelegate
static /*package*/
boolean nAddFontFromAsset(long nativeFamily, AssetManager mgr, String path) {
    FontFamily_Delegate ffd = sManager.getDelegate(nativeFamily);
    if (ffd == null) {
        return false;
    }
    ffd.mValid = true;
    if (mgr == null) {
        return false;
    }
    if (mgr instanceof BridgeAssetManager) {
        InputStream fontStream = null;
        try {
            AssetRepository assetRepository = ((BridgeAssetManager) mgr).getAssetRepository();
            if (assetRepository == null) {
                Bridge.getLog().error(LayoutLog.TAG_MISSING_ASSET, "Asset not found: " + path, null);
                return false;
            }
            if (!assetRepository.isSupported()) {
                // Don't log any warnings on unsupported IDEs.
                return false;
            }
            // Check cache
            FontInfo fontInfo = sCache.get(path);
            if (fontInfo != null) {
                // renew the font's lease.
                sCache.put(path, fontInfo);
                ffd.addFont(fontInfo);
                return true;
            }
            fontStream = assetRepository.openAsset(path, AssetManager.ACCESS_STREAMING);
            if (fontStream == null) {
                Bridge.getLog().error(LayoutLog.TAG_MISSING_ASSET, "Asset not found: " + path, path);
                return false;
            }
            Font font = Font.createFont(Font.TRUETYPE_FONT, fontStream);
            fontInfo = new FontInfo();
            fontInfo.mFont = font;
            fontInfo.mWeight = font.isBold() ? BOLD_FONT_WEIGHT : DEFAULT_FONT_WEIGHT;
            fontInfo.mIsItalic = font.isItalic();
            ffd.addFont(fontInfo);
            return true;
        } catch (IOException e) {
            Bridge.getLog().error(LayoutLog.TAG_MISSING_ASSET, "Unable to load font " + path, e, path);
        } catch (FontFormatException e) {
            if (path.endsWith(EXTENSION_OTF)) {
                // otf fonts are not supported on the user's config (JRE version + OS)
                Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, "OpenType fonts are not supported yet: " + path, null, path);
            } else {
                Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to load font " + path, e, path);
            }
        } finally {
            if (fontStream != null) {
                try {
                    fontStream.close();
                } catch (IOException ignored) {
                }
            }
        }
        return false;
    }
    // This should never happen. AssetManager is a final class (from user's perspective), and
    // we've replaced every creation of AssetManager with our implementation. We create an
    // exception and log it, but continue with rest of the rendering, without loading this font.
    Bridge.getLog().error(LayoutLog.TAG_BROKEN, "You have found a bug in the rendering library. Please file a bug at b.android.com.", new RuntimeException("Asset Manager is not an instance of BridgeAssetManager"), null);
    return false;
}
Also used : BridgeAssetManager(android.content.res.BridgeAssetManager) InputStream(java.io.InputStream) AssetRepository(com.android.ide.common.rendering.api.AssetRepository) IOException(java.io.IOException) FontFormatException(java.awt.FontFormatException) Font(java.awt.Font) LayoutlibDelegate(com.android.tools.layoutlib.annotations.LayoutlibDelegate)

Aggregations

LayoutlibDelegate (com.android.tools.layoutlib.annotations.LayoutlibDelegate)334 ArrayResourceValue (com.android.ide.common.rendering.api.ArrayResourceValue)56 DensityBasedResourceValue (com.android.ide.common.rendering.api.DensityBasedResourceValue)56 ResourceValue (com.android.ide.common.rendering.api.ResourceValue)56 BufferedImage (java.awt.image.BufferedImage)46 AffineTransform (java.awt.geom.AffineTransform)42 Area (java.awt.geom.Area)42 File (java.io.File)30 GcSnapshot (com.android.layoutlib.bridge.impl.GcSnapshot)29 FileNotFoundException (java.io.FileNotFoundException)24 Graphics2D (java.awt.Graphics2D)19 TypedValue (android.util.TypedValue)17 NotFoundException (android.content.res.Resources.NotFoundException)16 BridgeContext (com.android.layoutlib.bridge.android.BridgeContext)16 BridgeXmlBlockParser (com.android.layoutlib.bridge.android.BridgeXmlBlockParser)16 ArrayList (java.util.ArrayList)16 XmlPullParser (org.xmlpull.v1.XmlPullParser)16 XmlPullParserException (org.xmlpull.v1.XmlPullParserException)16 IOException (java.io.IOException)14 NinePatchInputStream (com.android.layoutlib.bridge.util.NinePatchInputStream)12