/** Returns the width of the layer multiplied by its x scale. * <em>Note:</em> not all layers know their size. Those that don't return 0. */ public float scaledWidth () { return scaleX() * width(); } /** Returns the height of the layer multiplied by its y scale.
/** * Like {@link #hitTest} except that it ignores a configured {@link HitTester}. This allows one * to configure a hit tester which checks custom properties and then falls back on the default * hit testing implementation. */ public Layer hitTestDefault(Point p) { return (p.x >= 0 && p.y >= 0 && p.x < width() && p.y < height()) ? this : null; }
protected float addTest(float lx, float ly, Layer layer, String descrip) { return addTest(lx, ly, layer, descrip, layer.width()); }
protected float addTest(float lx, float ly, Layer layer, String descrip, float twidth) { return addTest(lx, ly, layer, layer.width(), layer.height(), descrip, twidth); }
/** * Adds {@code child} to this group layer, positioning it such that its center is at ({@code tx}, * {@code tx}). The layer must report a non-zero size, thus this will not work on an unclipped * group layer. * * <p>This is equivalent to: {@code add(child.setTranslation(tx - child.width()/2, * ty - child.height()/2))}. */ public void addCenterAt (Layer child, float tx, float ty) { add(child.setTranslation(tx - child.width()/2, ty - child.height()/2)); }
/** Returns the y-component of the layer's origin. */ public float originY () { if (isSet(Flag.ODIRTY)) { float height = height(); if (height > 0) { this.originX = origin.ox(width()); this.originY = origin.oy(height); setFlag(Flag.ODIRTY, false); } } return originY; } /** Writes this layer's origin into {@code into}.
/** Returns the x-component of the layer's origin. */ public float originX () { if (isSet(Flag.ODIRTY)) { float width = width(); if (width > 0) { this.originX = origin.ox(width); this.originY = origin.oy(height()); setFlag(Flag.ODIRTY, false); } } return originX; } /** Returns the y-component of the layer's origin. */
/** * Returns true if a coordinate on the screen touches a {@link Layer}. Note: if the supplied * layer has no size, this will always return false. */ public static boolean hitTest(Layer layer, float x, float y) { Point point = screenToLayer(layer, x, y); return (point.x() >= 0 && point.y() >= 0 && point.x() <= layer.width() && point.y() <= layer.height()); }
protected void drawDebugRect(Surface surf) { float x = 0, y = 0, w = this.width(), h = this.height(); if (w > 0 && h > 0) { surf.setFillColor(paintNestLevel >= DEBUG_COLORS.length ? 0xFF000000 : DEBUG_COLORS[paintNestLevel]); int thick = 2; surf.drawLine(x, y, x+w, y, thick); surf.drawLine(x+w, y, x+w, y+h, thick); surf.drawLine(x+w, y+h, x, y+h, thick); surf.drawLine(x, y+h, x, y, thick); } }
/** Helper function for {@link #totalBounds}. */ protected static void addBounds (Layer root, Layer l, Rectangle bounds, Point scratch) { float w = l.width(), h = l.height(); if (w != 0 || h != 0) { // grow bounds bounds.add(LayerUtil.layerToParent(l, root, scratch.set(0, 0), scratch)); bounds.add(LayerUtil.layerToParent(l, root, scratch.set(w, h), scratch)); } if (l instanceof GroupLayer) { GroupLayer group = (GroupLayer) l; for (int ii = 0, ll = group.children(); ii < ll; ++ii) { addBounds(root, group.childAt(ii), bounds, scratch); } } } }
/** Performs the recursion for {@link #layerUnderPoint(Layer,float,float)}. */ protected static Layer layerUnderPoint (Layer layer, Point pt) { float x = pt.x, y = pt.y; if (layer instanceof GroupLayer) { GroupLayer gl = (GroupLayer)layer; for (int ii = gl.children()-1; ii >= 0; ii--) { Layer child = gl.childAt(ii); if (!child.visible()) continue; // ignore invisible children try { // transform the point into the child's coordinate system child.transform().inverseTransform(pt.set(x, y), pt); pt.x += child.originX(); pt.y += child.originY(); Layer l = layerUnderPoint(child, pt); if (l != null) return l; } catch (NoninvertibleTransformException nte) { continue; } } } if (x >= 0 && x < layer.width() && y >= 0 && y < layer.height()) { return layer; } return null; }