diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
deleted file mode 100644
index 30aa626..0000000
--- a/.idea/codeStyles/Project.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
deleted file mode 100644
index 40ed937..0000000
--- a/.idea/compiler.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
deleted file mode 100644
index 97626ba..0000000
--- a/.idea/encodings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index 7b9dd4c..0000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,109 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 5ca53e9..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
deleted file mode 100644
index 7f68460..0000000
--- a/.idea/runConfigurations.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 94a25f7..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/drawabletoolbox/.gitignore b/drawabletoolbox/.gitignore
index 796b96d..c3dc67f 100644
--- a/drawabletoolbox/.gitignore
+++ b/drawabletoolbox/.gitignore
@@ -1 +1,26 @@
-/build
+# Gradle files
+.gradle/
+build/
+version.properties
+
+# Local configuration file (sdk path, etc)
+local.properties
+
+# Log Files
+*.log
+gradlew
+gradlew.bat
+# Android Studio Navigation editor temp files
+.navigation/
+
+# Android Studio captures folder
+captures/
+
+# IntelliJ
+*.iml
+.idea/
+# Uncomment the following line if you do not want to check your keystore files in.
+#*.jks
+
+# External native build folder generated in Android Studio 2.2 and later
+.externalNativeBuild
diff --git a/drawabletoolbox/src/main/java/top/defaults/drawabletoolbox/DrawableBuilder.kt b/drawabletoolbox/src/main/java/top/defaults/drawabletoolbox/DrawableBuilder.kt
index 749797c..6c1e2e8 100644
--- a/drawabletoolbox/src/main/java/top/defaults/drawabletoolbox/DrawableBuilder.kt
+++ b/drawabletoolbox/src/main/java/top/defaults/drawabletoolbox/DrawableBuilder.kt
@@ -4,416 +4,445 @@ import android.content.res.ColorStateList
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.os.Build
+import android.support.annotation.ColorInt
+import android.support.annotation.Px
import android.util.StateSet
import java.util.*
import java.util.concurrent.atomic.AtomicInteger
class DrawableBuilder {
- private var properties = DrawableProperties()
- private var order: AtomicInteger = AtomicInteger(1)
- private var transformsMap = TreeMap Drawable>()
- private var baseDrawable: Drawable? = null
-
- fun batch(properties: DrawableProperties) = apply { this.properties = properties.copy() }
- fun baseDrawable(drawable: Drawable) = apply { baseDrawable = drawable }
-
- //
- fun shape(shape: Int) = apply { properties.shape = shape }
- fun rectangle() = apply { shape(GradientDrawable.RECTANGLE) }
- fun oval() = apply { shape(GradientDrawable.OVAL) }
- fun line() = apply { shape(GradientDrawable.LINE) }
- fun ring() = apply { shape(GradientDrawable.RING) }
- fun innerRadius(innerRadius: Int) = apply { properties.innerRadius = innerRadius }
- fun innerRadiusRatio(innerRadiusRatio: Float) = apply { properties.innerRadiusRatio = innerRadiusRatio }
- fun thickness(thickness: Int) = apply { properties.thickness = thickness }
- fun thicknessRatio(thicknessRatio: Float) = apply { properties.thicknessRatio = thicknessRatio }
- @JvmOverloads fun useLevelForRing(use: Boolean = true) = apply { properties.useLevelForRing = use }
-
- //
- fun cornerRadius(cornerRadius: Int) = apply { properties.cornerRadius = cornerRadius }
- fun topLeftRadius(topLeftRadius: Int) = apply { properties.topLeftRadius = topLeftRadius }
- fun topRightRadius(topRightRadius: Int) = apply { properties.topRightRadius = topRightRadius }
- fun bottomRightRadius(bottomRightRadius: Int) = apply { properties.bottomRightRadius = bottomRightRadius }
- fun bottomLeftRadius(bottomLeftRadius: Int) = apply { properties.bottomLeftRadius = bottomLeftRadius }
- fun rounded() = apply { cornerRadius(Int.MAX_VALUE) }
- fun cornerRadii(topLeftRadius: Int, topRightRadius: Int, bottomRightRadius: Int, bottomLeftRadius: Int) = apply {
- topLeftRadius(topLeftRadius); topRightRadius(topRightRadius); bottomRightRadius(bottomRightRadius); bottomLeftRadius(bottomLeftRadius)
- }
-
- //
- @JvmOverloads fun gradient(useGradient: Boolean = true) = apply { properties.useGradient = useGradient }
- fun gradientType(type: Int) = apply { properties.type = type }
- fun linearGradient() = apply { gradientType(GradientDrawable.LINEAR_GRADIENT) }
- fun radialGradient() = apply { gradientType(GradientDrawable.RADIAL_GRADIENT) }
- fun sweepGradient() = apply { gradientType(GradientDrawable.SWEEP_GRADIENT) }
- fun angle(angle: Int) = apply { properties.angle = angle }
- fun centerX(centerX: Float) = apply { properties.centerX = centerX }
- fun centerY(centerY: Float) = apply { properties.centerY = centerY }
- fun center(centerX: Float, centerY: Float) = apply { centerX(centerX); centerY(centerY) }
- @JvmOverloads fun useCenterColor(useCenterColor: Boolean = true) = apply { properties.useCenterColor = useCenterColor }
- fun startColor(startColor: Int) = apply { properties.startColor = startColor }
- fun centerColor(centerColor: Int) = apply {
- properties.centerColor = centerColor
- useCenterColor(true)
- }
- fun endColor(endColor: Int) = apply { properties.endColor = endColor }
- fun gradientColors(startColor: Int, endColor: Int, centerColor: Int?) = apply {
- startColor(startColor); endColor(endColor)
- useCenterColor(centerColor != null)
- centerColor?.let {
- centerColor(it)
- }
- }
- fun gradientRadiusType(gradientRadiusType: Int) = apply { properties.gradientRadiusType = gradientRadiusType }
- fun gradientRadius(gradientRadius: Float) = apply { properties.gradientRadius = gradientRadius }
- fun gradientRadius(radius: Float, type: Int) = apply { gradientRadius(radius); gradientRadiusType(type) }
- fun gradientRadiusInPixel(radius: Float) = apply { gradientRadius(radius); gradientRadiusType(DrawableProperties.RADIUS_TYPE_PIXELS) }
- fun gradientRadiusInFraction(radius: Float) = apply { gradientRadius(radius); gradientRadiusType(DrawableProperties.RADIUS_TYPE_FRACTION) }
- fun useLevelForGradient(use: Boolean) = apply { properties.useLevelForGradient = use }
- fun useLevelForGradient() = apply { useLevelForGradient(true) }
-
- //
- fun width(width: Int) = apply { properties.width = width }
- fun height(height: Int) = apply { properties.height = height }
- fun size(width: Int, height: Int) = apply { width(width); height(height) }
- fun size(size: Int) = apply { width(size).height(size) }
-
- //
- fun solidColor(solidColor: Int) = apply { properties.solidColor = solidColor }
+ private var properties = DrawableProperties()
+ private var order: AtomicInteger = AtomicInteger(1)
+ private var transformsMap = TreeMap Drawable>()
+ private var baseDrawable: Drawable? = null
+
+ fun batch(properties: DrawableProperties) = apply { this.properties = properties.copy() }
+ fun baseDrawable(drawable: Drawable) = apply { baseDrawable = drawable }
+
+ //
+ fun shape(shape: Int) = apply { properties.shape = shape }
+ fun rectangle() = apply { shape(GradientDrawable.RECTANGLE) }
+ fun oval() = apply { shape(GradientDrawable.OVAL) }
+ fun line() = apply { shape(GradientDrawable.LINE) }
+ fun ring() = apply { shape(GradientDrawable.RING) }
+ fun innerRadius(innerRadius: Int) = apply { properties.innerRadius = innerRadius }
+ fun innerRadiusRatio(innerRadiusRatio: Float) = apply { properties.innerRadiusRatio = innerRadiusRatio }
+ fun thickness(thickness: Int) = apply { properties.thickness = thickness }
+ fun thicknessRatio(thicknessRatio: Float) = apply { properties.thicknessRatio = thicknessRatio }
+ @JvmOverloads
+ fun useLevelForRing(use: Boolean = true) = apply { properties.useLevelForRing = use }
+
+ //
+ fun cornerRadius(@Px cornerRadius: Int) = apply { properties.cornerRadius = cornerRadius }
+ fun topLeftRadius(@Px topLeftRadius: Int) = apply { properties.topLeftRadius = topLeftRadius }
+ fun topRightRadius(@Px topRightRadius: Int) = apply { properties.topRightRadius = topRightRadius }
+ fun bottomRightRadius(@Px bottomRightRadius: Int) = apply { properties.bottomRightRadius = bottomRightRadius }
+ fun bottomLeftRadius(@Px bottomLeftRadius: Int) = apply { properties.bottomLeftRadius = bottomLeftRadius }
+ fun rounded() = apply { cornerRadius(Int.MAX_VALUE) }
+ fun cornerRadii(
+ @Px topLeftRadius: Int,
+ @Px topRightRadius: Int,
+ @Px bottomRightRadius: Int,
+ @Px bottomLeftRadius: Int
+ ) = apply {
+ topLeftRadius(topLeftRadius);
+ topRightRadius(topRightRadius);
+ bottomRightRadius(bottomRightRadius);
+ bottomLeftRadius(bottomLeftRadius)
+ }
+
+ //
+ @JvmOverloads
+ fun gradient(useGradient: Boolean = true) = apply { properties.useGradient = useGradient }
+ fun gradientType(type: Int) = apply { properties.type = type }
+ fun linearGradient() = apply { gradientType(GradientDrawable.LINEAR_GRADIENT) }
+ fun radialGradient() = apply { gradientType(GradientDrawable.RADIAL_GRADIENT) }
+ fun sweepGradient() = apply { gradientType(GradientDrawable.SWEEP_GRADIENT) }
+ fun angle(angle: Int) = apply { properties.angle = angle }
+ fun centerX(centerX: Float) = apply { properties.centerX = centerX }
+ fun centerY(centerY: Float) = apply { properties.centerY = centerY }
+ fun center(centerX: Float, centerY: Float) = apply { centerX(centerX); centerY(centerY) }
+ @JvmOverloads
+ fun useCenterColor(useCenterColor: Boolean = true) = apply { properties.useCenterColor = useCenterColor }
+ fun startColor(@ColorInt startColor: Int) = apply { properties.startColor = startColor }
+ fun centerColor(@ColorInt centerColor: Int) = apply {
+ properties.centerColor = centerColor
+ useCenterColor(true)
+ }
+
+ fun endColor(@ColorInt endColor: Int) = apply { properties.endColor = endColor }
+ fun gradientColors(@ColorInt startColor: Int, @ColorInt endColor: Int, @ColorInt centerColor: Int?) = apply {
+ startColor(startColor); endColor(endColor)
+ useCenterColor(centerColor != null)
+ centerColor?.let {
+ centerColor(it)
+ }
+ }
+
+ fun gradientRadiusType(gradientRadiusType: Int) = apply { properties.gradientRadiusType = gradientRadiusType }
+ fun gradientRadius(gradientRadius: Float) = apply { properties.gradientRadius = gradientRadius }
+ fun gradientRadius(@Px radius: Float, type: Int) = apply { gradientRadius(radius); gradientRadiusType(type) }
+ fun gradientRadiusInPixel(@Px radius: Float) = apply { gradientRadius(radius); gradientRadiusType(DrawableProperties.RADIUS_TYPE_PIXELS) }
+ fun gradientRadiusInFraction(@Px radius: Float) = apply { gradientRadius(radius); gradientRadiusType(DrawableProperties.RADIUS_TYPE_FRACTION) }
+ fun useLevelForGradient(use: Boolean) = apply { properties.useLevelForGradient = use }
+ fun useLevelForGradient() = apply { useLevelForGradient(true) }
+
+ //
+ fun width(@Px width: Int) = apply { properties.width = width }
+ fun height(@Px height: Int) = apply { properties.height = height }
+ fun size(@Px width: Int, @Px height: Int) = apply { width(width); height(height) }
+ fun size(@Px size: Int) = apply { width(size).height(size) }
+
+ //
+ fun solidColor(@ColorInt solidColor: Int) = apply { properties.solidColor = solidColor }
+ @ColorInt
private var solidColorPressed: Int? = null
- fun solidColorPressed(color: Int?) = apply { solidColorPressed = color }
+ fun solidColorPressed(@ColorInt color: Int?) = apply { solidColorPressed = color }
+ @ColorInt
private var solidColorPressedWhenRippleUnsupported: Int? = null
- fun solidColorPressedWhenRippleUnsupported(color: Int?) = apply { solidColorPressedWhenRippleUnsupported = color }
+ fun solidColorPressedWhenRippleUnsupported(@ColorInt color: Int?) = apply { solidColorPressedWhenRippleUnsupported = color }
+ @ColorInt
private var solidColorDisabled: Int? = null
- fun solidColorDisabled(color: Int?) = apply { solidColorDisabled = color }
+ fun solidColorDisabled(@ColorInt color: Int?) = apply { solidColorDisabled = color }
+ @ColorInt
private var solidColorSelected: Int? = null
- fun solidColorSelected(color: Int?) = apply { solidColorSelected = color }
- fun solidColorStateList(colorStateList: ColorStateList) = apply { properties.solidColorStateList = colorStateList }
+ fun solidColorSelected(@ColorInt color: Int?) = apply { solidColorSelected = color }
+ fun solidColorStateList(colorStateList: ColorStateList) = apply { properties.solidColorStateList = colorStateList }
- //
- fun strokeWidth(strokeWidth: Int) = apply { properties.strokeWidth = strokeWidth }
+ //
+ fun strokeWidth(@Px strokeWidth: Int) = apply { properties.strokeWidth = strokeWidth }
- fun strokeColor(strokeColor: Int) = apply { properties.strokeColor = strokeColor }
+ fun strokeColor(@ColorInt strokeColor: Int) = apply { properties.strokeColor = strokeColor }
+ @ColorInt
private var strokeColorPressed: Int? = null
- fun strokeColorPressed(color: Int?) = apply { strokeColorPressed = color }
+ fun strokeColorPressed(@ColorInt color: Int?) = apply { strokeColorPressed = color }
+ @ColorInt
private var strokeColorDisabled: Int? = null
- fun strokeColorDisabled(color: Int?) = apply { strokeColorDisabled = color }
+ fun strokeColorDisabled(@ColorInt color: Int?) = apply { strokeColorDisabled = color }
+ @ColorInt
private var strokeColorSelected: Int? = null
- fun strokeColorSelected(color: Int?) = apply { strokeColorSelected = color }
- fun strokeColorStateList(colorStateList: ColorStateList) = apply { properties.strokeColorStateList = colorStateList }
-
- fun dashWidth(dashWidth: Int) = apply { properties.dashWidth = dashWidth }
- fun dashGap(dashGap: Int) = apply { properties.dashGap = dashGap }
- fun hairlineBordered() = apply { strokeWidth(1) }
- fun shortDashed() = apply { dashWidth(12).dashGap(12) }
- fun mediumDashed() = apply { dashWidth(24).dashGap(24) }
- fun longDashed() = apply { dashWidth(36).dashGap(36) }
- fun dashed() = apply { mediumDashed() }
-
- //
- private var rotateOrder = 0
- @JvmOverloads fun rotate(boolean: Boolean = true) = apply {
- properties.useRotate = boolean
- rotateOrder = if (boolean) {
- order.getAndIncrement()
- } else {
- 0
- }
- }
- fun pivotX(pivotX: Float) = apply { properties.pivotX = pivotX }
- fun pivotY(pivotY: Float) = apply { properties.pivotY = pivotY }
- fun pivot(pivotX: Float, pivotY: Float) = apply { pivotX(pivotX).pivotY(pivotY) }
- fun fromDegrees(degrees: Float) = apply { properties.fromDegrees = degrees }
- fun toDegrees(degrees: Float) = apply { properties.toDegrees = degrees }
- fun degrees(fromDegrees: Float, toDegrees: Float) = apply { fromDegrees(fromDegrees).toDegrees(toDegrees) }
- fun degrees(degrees: Float) = apply { fromDegrees(degrees).toDegrees(degrees) }
- fun rotate(fromDegrees: Float, toDegrees: Float) = apply { rotate().fromDegrees(fromDegrees).toDegrees(toDegrees) }
- fun rotate(degrees: Float) = apply { rotate().degrees(degrees) }
-
- //
- private var scaleOrder = 0
- @JvmOverloads fun scale(boolean: Boolean = true) = apply {
- properties.useScale = boolean
- scaleOrder = if (boolean) {
- order.getAndIncrement()
- } else {
- 0
- }
- }
- fun scaleLevel(level: Int) = apply { properties.scaleLevel = level }
- fun scaleGravity(gravity: Int) = apply { properties.scaleGravity = gravity }
- fun scaleWidth(scale: Float) = apply { properties.scaleWidth = scale }
- fun scaleHeight(scale: Float) = apply { properties.scaleHeight = scale }
- fun scale(scale: Float) = apply { scale().scaleWidth(scale).scaleHeight(scale) }
- fun scale(scaleWidth: Float, scaleHeight: Float) = apply { scale().scaleWidth(scaleWidth).scaleHeight(scaleHeight) }
-
- // flip
- @JvmOverloads fun flip(boolean: Boolean = true) = apply { properties.useFlip = boolean }
- fun orientation(orientation: Int) = apply { properties.orientation = orientation }
- fun flipVertical() = apply { flip().orientation(FlipDrawable.ORIENTATION_VERTICAL) }
-
- //
- @JvmOverloads fun ripple(boolean: Boolean = true) = apply { properties.useRipple = boolean }
- fun rippleColor(color: Int) = apply { properties.rippleColor = color }
- fun rippleColorStateList(colorStateList: ColorStateList) = apply { properties.rippleColorStateList = colorStateList }
- fun rippleRadius(radius: Int) = apply { properties.rippleRadius = radius }
-
- fun build(): Drawable {
- if (baseDrawable != null) {
- return wrap(baseDrawable!!)
- }
-
- var drawable: Drawable
-
- // fall back when ripple is unavailable on devices with API < 21
- if (shouldFallbackRipple()) {
- if (solidColorPressedWhenRippleUnsupported != null) {
- solidColorPressed(solidColorPressedWhenRippleUnsupported)
- } else {
- solidColorPressed(properties.rippleColor)
- }
- }
-
- if (needStateListDrawable()) {
- drawable = StateListDrawableBuilder()
- .pressed(buildPressedDrawable())
- .disabled(buildDisabledDrawable())
- .selected(buildSelectedDrawable())
- .normal(buildNormalDrawable())
- .build()
- } else {
- drawable = GradientDrawable()
- setupGradientDrawable(drawable)
- }
- drawable = wrap(drawable)
- return drawable
- }
-
- private fun getSolidColorStateList(): ColorStateList {
- if (properties.solidColorStateList != null) {
- return properties.solidColorStateList!!
- }
-
- val states = mutableListOf()
- val colors = mutableListOf()
-
- solidColorPressed?.let {
- states.add(intArrayOf(android.R.attr.state_pressed))
- colors.add(it)
- }
- solidColorDisabled?.let {
- states.add(intArrayOf(-android.R.attr.state_enabled))
- colors.add(it)
- }
- solidColorSelected?.let {
- states.add(intArrayOf(android.R.attr.state_selected))
- colors.add(it)
- }
- states.add(StateSet.WILD_CARD)
- colors.add(properties.solidColor)
-
- return ColorStateList(states.toTypedArray(), colors.toIntArray())
- }
-
- private fun getStrokeColorStateList(): ColorStateList {
- if (properties.strokeColorStateList != null) {
- return properties.strokeColorStateList!!
- }
-
- val states = mutableListOf()
- val colors = mutableListOf()
-
- strokeColorPressed?.let {
- states.add(intArrayOf(android.R.attr.state_pressed))
- colors.add(it)
- }
- strokeColorDisabled?.let {
- states.add(intArrayOf(-android.R.attr.state_enabled))
- colors.add(it)
- }
- strokeColorSelected?.let {
- states.add(intArrayOf(android.R.attr.state_selected))
- colors.add(it)
- }
- states.add(StateSet.WILD_CARD)
- colors.add(properties.strokeColor)
-
- return ColorStateList(states.toTypedArray(), colors.toIntArray())
- }
-
- private fun buildPressedDrawable(): Drawable? {
- if (solidColorPressed == null && strokeColorPressed == null) return null
-
- val pressedDrawable = GradientDrawable()
- setupGradientDrawable(pressedDrawable)
- solidColorPressed?.let {
- pressedDrawable.setColor(it)
- }
- strokeColorPressed?.let {
- setStrokeColor(pressedDrawable, it)
- }
- return pressedDrawable
- }
-
- private fun buildDisabledDrawable(): Drawable? {
- if (solidColorDisabled == null && strokeColorDisabled == null) return null
-
- val disabledDrawable = GradientDrawable()
- setupGradientDrawable(disabledDrawable)
- solidColorDisabled?.let {
- disabledDrawable.setColor(it)
- }
- strokeColorDisabled?.let {
- setStrokeColor(disabledDrawable, it)
- }
- return disabledDrawable
- }
-
- private fun buildSelectedDrawable(): Drawable? {
- if (solidColorSelected == null && strokeColorSelected == null) return null
-
- val selectedDrawable = GradientDrawable()
- setupGradientDrawable(selectedDrawable)
- solidColorSelected?.let {
- selectedDrawable.setColor(it)
- }
- strokeColorSelected?.let {
- setStrokeColor(selectedDrawable, it)
- }
- return selectedDrawable
- }
-
- private fun buildNormalDrawable(): Drawable {
- val pressedDrawable = GradientDrawable()
- setupGradientDrawable(pressedDrawable)
- return pressedDrawable
- }
-
- private fun setupGradientDrawable(drawable: GradientDrawable) {
- properties.apply {
- drawable.shape = shape
- if (shape == GradientDrawable.RING) {
- setInnerRadius(drawable, innerRadius)
- setInnerRadiusRatio(drawable, innerRadiusRatio)
- setThickness(drawable, thickness)
- setThicknessRatio(drawable, thicknessRatio)
- setUseLevelForShape(drawable, useLevelForRing)
- }
- drawable.cornerRadii = getCornerRadii()
- if (useGradient) {
- drawable.gradientType = type
- setGradientRadiusType(drawable, gradientRadiusType)
- setGradientRadius(drawable, gradientRadius)
- drawable.setGradientCenter(centerX, centerY)
- setOrientation(drawable, getOrientation())
- setColors(drawable, getColors())
- drawable.useLevel = useLevelForGradient
- } else {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- drawable.color = getSolidColorStateList()
- } else {
- drawable.setColor(solidColor)
- }
- }
- drawable.setSize(width, height)
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- drawable.setStroke(strokeWidth, getStrokeColorStateList(), dashWidth.toFloat(), dashGap.toFloat())
- } else {
- drawable.setStroke(strokeWidth, strokeColor, dashWidth.toFloat(), dashGap.toFloat())
- }
- }
- }
-
- private fun needStateListDrawable(): Boolean {
- return Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP
- && (hasStrokeColorStateList() || (!properties.useGradient && hasSolidColorStateList()))
- }
-
- private fun needRotateDrawable(): Boolean {
- return properties.useRotate &&
- !(properties.pivotX == 0.5f && properties.pivotY == 0.5f
- && properties.fromDegrees == 0f && properties.toDegrees == 0f)
- }
-
- private fun needScaleDrawable(): Boolean {
- return properties.useScale
- }
-
- private fun wrap(drawable: Drawable): Drawable {
- var wrappedDrawable = drawable
-
- if (rotateOrder > 0) {
- transformsMap[rotateOrder] = ::wrapRotateIfNeeded
- }
- if (scaleOrder > 0) {
- transformsMap[scaleOrder] = ::wrapScaleIfNeeded
- }
-
- for (action in transformsMap.values) {
- wrappedDrawable = action.invoke(wrappedDrawable)
- }
-
- if (properties.useFlip) {
- wrappedDrawable = FlipDrawableBuilder()
- .drawable(wrappedDrawable)
- .orientation(properties.orientation)
- .build()
- }
-
- if (isRippleSupported() && properties.useRipple) {
- wrappedDrawable = RippleDrawableBuilder()
- .drawable(wrappedDrawable)
- .color(properties.rippleColor)
- .colorStateList(properties.rippleColorStateList)
- .radius(properties.rippleRadius)
- .build()
- }
-
- return wrappedDrawable
- }
-
- private fun shouldFallbackRipple(): Boolean {
- return properties.useRipple && !isRippleSupported()
- }
-
- private fun isRippleSupported(): Boolean {
- return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
- }
-
- private fun wrapRotateIfNeeded(drawable: Drawable): Drawable {
- if (!needRotateDrawable()) return drawable
-
- with(properties) {
- return RotateDrawableBuilder()
- .drawable(drawable)
- .pivotX(pivotX)
- .pivotY(pivotY)
- .fromDegrees(fromDegrees)
- .toDegrees(toDegrees)
- .build()
- }
- }
-
- private fun wrapScaleIfNeeded(drawable: Drawable): Drawable {
- if (!needScaleDrawable()) return drawable
-
- with(properties) {
- return ScaleDrawableBuilder()
- .drawable(drawable)
- .level(scaleLevel)
- .scaleGravity(scaleGravity)
- .scaleWidth(scaleWidth)
- .scaleHeight(scaleHeight)
- .build()
- }
- }
-
- private fun hasSolidColorStateList(): Boolean {
- return solidColorPressed != null || solidColorDisabled != null || solidColorSelected != null
- }
-
- private fun hasStrokeColorStateList(): Boolean {
- return strokeColorPressed != null || strokeColorDisabled != null || strokeColorSelected != null
- }
+ fun strokeColorSelected(@ColorInt color: Int?) = apply { strokeColorSelected = color }
+ fun strokeColorStateList(colorStateList: ColorStateList) = apply { properties.strokeColorStateList = colorStateList }
+
+ fun dashWidth(@Px dashWidth: Int) = apply { properties.dashWidth = dashWidth }
+ fun dashGap(dashGap: Int) = apply { properties.dashGap = dashGap }
+ fun hairlineBordered() = apply { strokeWidth(1) }
+ fun shortDashed() = apply { dashWidth(12).dashGap(12) }
+ fun mediumDashed() = apply { dashWidth(24).dashGap(24) }
+ fun longDashed() = apply { dashWidth(36).dashGap(36) }
+ fun dashed() = apply { mediumDashed() }
+
+ //
+ private var rotateOrder = 0
+ @JvmOverloads
+ fun rotate(boolean: Boolean = true) = apply {
+ properties.useRotate = boolean
+ rotateOrder = if (boolean) {
+ order.getAndIncrement()
+ } else {
+ 0
+ }
+ }
+
+ fun pivotX(pivotX: Float) = apply { properties.pivotX = pivotX }
+ fun pivotY(pivotY: Float) = apply { properties.pivotY = pivotY }
+ fun pivot(pivotX: Float, pivotY: Float) = apply { pivotX(pivotX).pivotY(pivotY) }
+ fun fromDegrees(degrees: Float) = apply { properties.fromDegrees = degrees }
+ fun toDegrees(degrees: Float) = apply { properties.toDegrees = degrees }
+ fun degrees(fromDegrees: Float, toDegrees: Float) = apply { fromDegrees(fromDegrees).toDegrees(toDegrees) }
+ fun degrees(degrees: Float) = apply { fromDegrees(degrees).toDegrees(degrees) }
+ fun rotate(fromDegrees: Float, toDegrees: Float) = apply { rotate().fromDegrees(fromDegrees).toDegrees(toDegrees) }
+ fun rotate(degrees: Float) = apply { rotate().degrees(degrees) }
+
+ //
+ private var scaleOrder = 0
+ @JvmOverloads
+ fun scale(boolean: Boolean = true) = apply {
+ properties.useScale = boolean
+ scaleOrder = if (boolean) {
+ order.getAndIncrement()
+ } else {
+ 0
+ }
+ }
+
+ fun scaleLevel(level: Int) = apply { properties.scaleLevel = level }
+ fun scaleGravity(gravity: Int) = apply { properties.scaleGravity = gravity }
+ fun scaleWidth(@Px scale: Float) = apply { properties.scaleWidth = scale }
+ fun scaleHeight(@Px scale: Float) = apply { properties.scaleHeight = scale }
+ fun scale(scale: Float) = apply { scale().scaleWidth(scale).scaleHeight(scale) }
+ fun scale(scaleWidth: Float, scaleHeight: Float) = apply { scale().scaleWidth(scaleWidth).scaleHeight(scaleHeight) }
+
+ // flip
+ @JvmOverloads
+ fun flip(boolean: Boolean = true) = apply { properties.useFlip = boolean }
+ fun orientation(orientation: Int) = apply { properties.orientation = orientation }
+ fun flipVertical() = apply { flip().orientation(FlipDrawable.ORIENTATION_VERTICAL) }
+
+ //
+ @JvmOverloads
+ fun ripple(boolean: Boolean = true) = apply { properties.useRipple = boolean }
+ fun rippleColor(@ColorInt color: Int) = apply { properties.rippleColor = color }
+ fun rippleColorStateList(colorStateList: ColorStateList) = apply { properties.rippleColorStateList = colorStateList }
+ fun rippleRadius(radius: Int) = apply { properties.rippleRadius = radius }
+
+ fun build(): Drawable {
+ if (baseDrawable != null) {
+ return wrap(baseDrawable!!)
+ }
+
+ var drawable: Drawable
+
+ // fall back when ripple is unavailable on devices with API < 21
+ if (shouldFallbackRipple()) {
+ if (solidColorPressedWhenRippleUnsupported != null) {
+ solidColorPressed(solidColorPressedWhenRippleUnsupported)
+ } else {
+ solidColorPressed(properties.rippleColor)
+ }
+ }
+
+ if (needStateListDrawable()) {
+ drawable = StateListDrawableBuilder()
+ .pressed(buildPressedDrawable())
+ .disabled(buildDisabledDrawable())
+ .selected(buildSelectedDrawable())
+ .normal(buildNormalDrawable())
+ .build()
+ } else {
+ drawable = GradientDrawable()
+ setupGradientDrawable(drawable)
+ }
+ drawable = wrap(drawable)
+ return drawable
+ }
+
+ private fun getSolidColorStateList(): ColorStateList {
+ if (properties.solidColorStateList != null) {
+ return properties.solidColorStateList!!
+ }
+
+ val states = mutableListOf()
+ val colors = mutableListOf()
+
+ solidColorPressed?.let {
+ states.add(intArrayOf(android.R.attr.state_pressed))
+ colors.add(it)
+ }
+ solidColorDisabled?.let {
+ states.add(intArrayOf(-android.R.attr.state_enabled))
+ colors.add(it)
+ }
+ solidColorSelected?.let {
+ states.add(intArrayOf(android.R.attr.state_selected))
+ colors.add(it)
+ }
+ states.add(StateSet.WILD_CARD)
+ colors.add(properties.solidColor)
+
+ return ColorStateList(states.toTypedArray(), colors.toIntArray())
+ }
+
+ private fun getStrokeColorStateList(): ColorStateList {
+ if (properties.strokeColorStateList != null) {
+ return properties.strokeColorStateList!!
+ }
+
+ val states = mutableListOf()
+ val colors = mutableListOf()
+
+ strokeColorPressed?.let {
+ states.add(intArrayOf(android.R.attr.state_pressed))
+ colors.add(it)
+ }
+ strokeColorDisabled?.let {
+ states.add(intArrayOf(-android.R.attr.state_enabled))
+ colors.add(it)
+ }
+ strokeColorSelected?.let {
+ states.add(intArrayOf(android.R.attr.state_selected))
+ colors.add(it)
+ }
+ states.add(StateSet.WILD_CARD)
+ colors.add(properties.strokeColor)
+
+ return ColorStateList(states.toTypedArray(), colors.toIntArray())
+ }
+
+ private fun buildPressedDrawable(): Drawable? {
+ if (solidColorPressed == null && strokeColorPressed == null) return null
+
+ val pressedDrawable = GradientDrawable()
+ setupGradientDrawable(pressedDrawable)
+ solidColorPressed?.let {
+ pressedDrawable.setColor(it)
+ }
+ strokeColorPressed?.let {
+ setStrokeColor(pressedDrawable, it)
+ }
+ return pressedDrawable
+ }
+
+ private fun buildDisabledDrawable(): Drawable? {
+ if (solidColorDisabled == null && strokeColorDisabled == null) return null
+
+ val disabledDrawable = GradientDrawable()
+ setupGradientDrawable(disabledDrawable)
+ solidColorDisabled?.let {
+ disabledDrawable.setColor(it)
+ }
+ strokeColorDisabled?.let {
+ setStrokeColor(disabledDrawable, it)
+ }
+ return disabledDrawable
+ }
+
+ private fun buildSelectedDrawable(): Drawable? {
+ if (solidColorSelected == null && strokeColorSelected == null) return null
+
+ val selectedDrawable = GradientDrawable()
+ setupGradientDrawable(selectedDrawable)
+ solidColorSelected?.let {
+ selectedDrawable.setColor(it)
+ }
+ strokeColorSelected?.let {
+ setStrokeColor(selectedDrawable, it)
+ }
+ return selectedDrawable
+ }
+
+ private fun buildNormalDrawable(): Drawable {
+ val pressedDrawable = GradientDrawable()
+ setupGradientDrawable(pressedDrawable)
+ return pressedDrawable
+ }
+
+ private fun setupGradientDrawable(drawable: GradientDrawable) {
+ properties.apply {
+ drawable.shape = shape
+ if (shape == GradientDrawable.RING) {
+ setInnerRadius(drawable, innerRadius)
+ setInnerRadiusRatio(drawable, innerRadiusRatio)
+ setThickness(drawable, thickness)
+ setThicknessRatio(drawable, thicknessRatio)
+ setUseLevelForShape(drawable, useLevelForRing)
+ }
+ drawable.cornerRadii = getCornerRadii()
+ if (useGradient) {
+ drawable.gradientType = type
+ setGradientRadiusType(drawable, gradientRadiusType)
+ setGradientRadius(drawable, gradientRadius)
+ drawable.setGradientCenter(centerX, centerY)
+ setOrientation(drawable, getOrientation())
+ setColors(drawable, getColors())
+ drawable.useLevel = useLevelForGradient
+ } else {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ drawable.color = getSolidColorStateList()
+ } else {
+ drawable.setColor(solidColor)
+ }
+ }
+ drawable.setSize(width, height)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ drawable.setStroke(strokeWidth, getStrokeColorStateList(), dashWidth.toFloat(), dashGap.toFloat())
+ } else {
+ drawable.setStroke(strokeWidth, strokeColor, dashWidth.toFloat(), dashGap.toFloat())
+ }
+ }
+ }
+
+ private fun needStateListDrawable(): Boolean {
+ return Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP
+ && (hasStrokeColorStateList() || (!properties.useGradient && hasSolidColorStateList()))
+ }
+
+ private fun needRotateDrawable(): Boolean {
+ return properties.useRotate &&
+ !(properties.pivotX == 0.5f && properties.pivotY == 0.5f
+ && properties.fromDegrees == 0f && properties.toDegrees == 0f)
+ }
+
+ private fun needScaleDrawable(): Boolean {
+ return properties.useScale
+ }
+
+ private fun wrap(drawable: Drawable): Drawable {
+ var wrappedDrawable = drawable
+
+ if (rotateOrder > 0) {
+ transformsMap[rotateOrder] = ::wrapRotateIfNeeded
+ }
+
+ if (scaleOrder > 0) {
+ transformsMap[scaleOrder] = ::wrapScaleIfNeeded
+ }
+
+ for (action in transformsMap.values) {
+ wrappedDrawable = action.invoke(wrappedDrawable)
+ }
+
+ if (properties.useFlip) {
+ wrappedDrawable = FlipDrawableBuilder()
+ .drawable(wrappedDrawable)
+ .orientation(properties.orientation)
+ .build()
+ }
+
+ if (isRippleSupported() && properties.useRipple) {
+ wrappedDrawable = RippleDrawableBuilder()
+ .drawable(wrappedDrawable)
+ .color(properties.rippleColor)
+ .colorStateList(properties.rippleColorStateList)
+ .radius(properties.rippleRadius)
+ .build()
+ }
+
+ return wrappedDrawable
+ }
+
+ private fun shouldFallbackRipple(): Boolean {
+ return properties.useRipple && !isRippleSupported()
+ }
+
+ private fun isRippleSupported(): Boolean {
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
+ }
+
+ private fun wrapRotateIfNeeded(drawable: Drawable): Drawable {
+ if (!needRotateDrawable()) return drawable
+
+ with(properties) {
+ return RotateDrawableBuilder()
+ .drawable(drawable)
+ .pivotX(pivotX)
+ .pivotY(pivotY)
+ .fromDegrees(fromDegrees)
+ .toDegrees(toDegrees)
+ .build()
+ }
+ }
+
+ private fun wrapScaleIfNeeded(drawable: Drawable): Drawable {
+ if (!needScaleDrawable()) return drawable
+
+ with(properties) {
+ return ScaleDrawableBuilder()
+ .drawable(drawable)
+ .level(scaleLevel)
+ .scaleGravity(scaleGravity)
+ .scaleWidth(scaleWidth)
+ .scaleHeight(scaleHeight)
+ .build()
+ }
+ }
+
+ private fun hasSolidColorStateList(): Boolean {
+ return solidColorPressed != null || solidColorDisabled != null || solidColorSelected != null
+ }
+
+ private fun hasStrokeColorStateList(): Boolean {
+ return strokeColorPressed != null || strokeColorDisabled != null || strokeColorSelected != null
+ }
}
\ No newline at end of file