Skip to content

Commit 766bef1

Browse files
committed
Add color, size, add new textStyle, CharSequence text
1 parent ae42598 commit 766bef1

File tree

4 files changed

+274
-19
lines changed

4 files changed

+274
-19
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.omega_r.libs.omegatypes
2+
3+
import android.content.Context
4+
import android.content.res.ColorStateList
5+
import android.os.Build
6+
import java.io.Serializable
7+
8+
/**
9+
* Created by Anton Knyazev on 18.05.2019.
10+
*/
11+
12+
abstract class Color : Serializable {
13+
14+
abstract fun getColorInt(context: Context): Int
15+
16+
open fun getColorStateList(context: Context): ColorStateList {
17+
return ColorStateList.valueOf(getColorInt(context))
18+
}
19+
20+
companion object {
21+
22+
@JvmStatic
23+
fun fromInt(color: Int): Color = IntColor(color)
24+
25+
@JvmStatic
26+
fun fromResource(colorRes: Int): Color = ResourceColor(colorRes)
27+
}
28+
29+
class IntColor(private val colorInt: Int) : Color() {
30+
override fun getColorInt(context: Context) = colorInt
31+
}
32+
33+
class ResourceColor(private val colorRes: Int) : Color() {
34+
35+
override fun getColorInt(context: Context): Int {
36+
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
37+
context.getColor(colorRes)
38+
} else {
39+
context.resources.getColor(colorRes)
40+
}
41+
}
42+
43+
override fun getColorStateList(context: Context): ColorStateList {
44+
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
45+
context.getColorStateList(colorRes)
46+
} else {
47+
context.resources.getColorStateList(colorRes)
48+
}
49+
}
50+
51+
}
52+
53+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package com.omega_r.libs.omegatypes
2+
3+
import android.content.Context
4+
import android.util.DisplayMetrics
5+
import android.util.TypedValue.*
6+
import java.io.Serializable
7+
8+
/**
9+
* Created by Anton Knyazev on 18.05.2019.
10+
*/
11+
abstract class Size : Serializable {
12+
13+
companion object {
14+
15+
@JvmStatic
16+
fun from(size: Float, unit: Unit): Size = SimpleSize(size, unit)
17+
18+
@JvmStatic
19+
fun from(dimensionRes: Int): Size = DimensionResourceSize(dimensionRes)
20+
21+
}
22+
23+
abstract fun getSize(context: Context, unit: Unit): Float
24+
25+
protected abstract fun getRawSize(context: Context): Float
26+
27+
fun getPixelOffset(context: Context): Int {
28+
return getSize(context, Unit.PX).toInt()
29+
}
30+
31+
fun getPixelSize(context: Context): Int {
32+
val f = getSize(context, Unit.PX)
33+
34+
// A size conversion involves rounding the base value, and ensuring that a
35+
// non-zero base value is at least one pixel in size.
36+
val res = (if (f >= 0) f + 0.5f else f - 0.5f).toInt()
37+
if (res != 0) return res
38+
val value = getRawSize(context)
39+
if (value == 0f) return 0
40+
if (value > 0) return 1
41+
return -1
42+
}
43+
44+
protected fun getFactor(displayMetrics: DisplayMetrics, unit: Unit): Float {
45+
return displayMetrics.run {
46+
when (unit) {
47+
Unit.PX -> 1.0f
48+
Unit.DP -> density
49+
Unit.SP -> scaledDensity
50+
Unit.PT -> xdpi * (1.0f / 72)
51+
Unit.IN -> xdpi
52+
Unit.MM -> xdpi * (1.0f / 25.4f)
53+
}
54+
}
55+
}
56+
57+
protected fun getFactor(displayMetrics: DisplayMetrics, oldUnit: Unit, newUnit: Unit): Float {
58+
if (oldUnit == newUnit) {
59+
return 1f
60+
}
61+
return getFactor(displayMetrics, newUnit) / getFactor(displayMetrics, oldUnit)
62+
}
63+
64+
protected fun getFactor(context: Context, oldUnit: Unit, newUnit: Unit): Float {
65+
return context.resources.displayMetrics.run {
66+
getFactor(this, newUnit) / getFactor(this, oldUnit)
67+
}
68+
}
69+
70+
protected fun Float.applyFactor(context: Context, oldUnit: Unit, newUnit: Unit): Float {
71+
return this * getFactor(context, oldUnit, newUnit)
72+
}
73+
74+
enum class Unit(val typedValueUnit: Int) {
75+
PX(COMPLEX_UNIT_PX),
76+
DP(COMPLEX_UNIT_DIP),
77+
SP(COMPLEX_UNIT_SP),
78+
PT(COMPLEX_UNIT_PT),
79+
IN(COMPLEX_UNIT_IN),
80+
MM(COMPLEX_UNIT_MM);
81+
82+
companion object {
83+
84+
@JvmStatic
85+
fun from(typedValueUnit: Int): Unit? {
86+
return values().firstOrNull { typedValueUnit == it.typedValueUnit }
87+
}
88+
89+
}
90+
91+
}
92+
93+
private class SimpleSize(private val size: Float, private val unit: Unit) : Size() {
94+
95+
override fun getRawSize(context: Context): Float = size
96+
97+
override fun getSize(context: Context, unit: Unit): Float {
98+
return size.applyFactor(context, this.unit, unit)
99+
}
100+
}
101+
102+
private class DimensionResourceSize(private val sizeRes: Int) : Size() {
103+
104+
override fun getSize(context: Context, unit: Unit) = context.resources.run {
105+
getDimension(sizeRes).applyFactor(context, Unit.PX, unit)
106+
}
107+
108+
override fun getRawSize(context: Context) = context.resources.getDimension(sizeRes)
109+
110+
}
111+
}
112+

omegatypes/src/main/java/com/omega_r/libs/omegatypes/Text.kt

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import java.io.Serializable
1414
import java.util.*
1515
import kotlin.text.StringBuilder
1616

17-
open class Text(protected val defaultTextStyle: TextStyle? ) : Serializable {
17+
open class Text(protected val defaultTextStyle: TextStyle?) : Serializable {
1818

1919
companion object {
2020
@JvmStatic
@@ -34,7 +34,8 @@ open class Text(protected val defaultTextStyle: TextStyle? ) : Serializable {
3434

3535
@JvmStatic
3636
@JvmOverloads
37-
fun from(stringHolder: StringHolder, textStyle: TextStyle? = null): Text = stringHolder.getStringText()?.let { from(it, textStyle) } ?: empty()
37+
fun from(stringHolder: StringHolder, textStyle: TextStyle? = null): Text = stringHolder.getStringText()?.let { from(it, textStyle) }
38+
?: empty()
3839

3940
@JvmStatic
4041
@JvmOverloads
@@ -106,6 +107,38 @@ open class Text(protected val defaultTextStyle: TextStyle? ) : Serializable {
106107

107108
}
108109

110+
111+
private class CharSequenceText internal constructor(
112+
private val charSequence: CharSequence,
113+
textStyle: TextStyle?) : Text(textStyle) {
114+
115+
override fun isEmpty(): Boolean = charSequence.isEmpty()
116+
117+
override fun getString(context: Context): String? {
118+
return charSequence.toString()
119+
}
120+
121+
override fun getCharSequence(context: Context, textStyle: TextStyle?): CharSequence? {
122+
return (defaultTextStyle + textStyle)?.applyStyle(context, charSequence) ?: charSequence
123+
}
124+
125+
override fun equals(other: Any?): Boolean {
126+
if (this === other) return true
127+
if (javaClass != other?.javaClass) return false
128+
129+
other as CharSequenceText
130+
131+
return charSequence == other.charSequence
132+
}
133+
134+
override fun hashCode(): Int {
135+
var result = super.hashCode()
136+
result = 31 * result + charSequence.hashCode()
137+
return result
138+
}
139+
140+
}
141+
109142
private class ResourceText internal constructor(
110143
private val stringRes: Int,
111144
textStyle: TextStyle?
@@ -142,7 +175,7 @@ open class Text(protected val defaultTextStyle: TextStyle? ) : Serializable {
142175
override fun isEmpty(): Boolean = stringRes <= 0
143176

144177
override fun getString(context: Context): String {
145-
if (formatArgs.firstOrNull { it is Text} != null) {
178+
if (formatArgs.firstOrNull { it is Text } != null) {
146179
val list = formatArgs.map {
147180
when (it) {
148181
is Text -> it.getString(context)
@@ -175,7 +208,7 @@ open class Text(protected val defaultTextStyle: TextStyle? ) : Serializable {
175208
private class ArrayText internal constructor(
176209
private vararg val texts: Text,
177210
textStyle: TextStyle?
178-
): Text(textStyle) {
211+
) : Text(textStyle) {
179212

180213
override fun isEmpty(): Boolean {
181214
if (texts.isEmpty()) return false
@@ -265,14 +298,14 @@ fun Context.toast(text: Text, duration: Int = Toast.LENGTH_SHORT, textStyle: Tex
265298
return Toast.makeText(this, text.getCharSequence(this, textStyle), duration).apply { show() }
266299
}
267300

268-
operator fun Text.plus(text: Text) : Text {
301+
operator fun Text.plus(text: Text): Text {
269302
if (this is TextBuilder.BuilderText) {
270303
return this + text
271304
}
272305
return TextBuilder.BuilderText(this) + text
273306
}
274307

275-
operator fun Text.plus(string: String) : Text {
308+
operator fun Text.plus(string: String): Text {
276309
if (this is TextBuilder.BuilderText) {
277310
return this + string
278311
}

omegatypes/src/main/java/com/omega_r/libs/omegatypes/TextStyle.kt

Lines changed: 70 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,50 @@ package com.omega_r.libs.omegatypes
22

33
import android.content.Context
44
import android.graphics.*
5-
import android.os.Build
65
import android.text.SpannableString
7-
import android.text.style.ForegroundColorSpan
8-
import android.text.style.StyleSpan
6+
import android.text.style.*
97

108
/**
119
* Created by Anton Knyazev on 25.04.2019.
1210
*/
1311
abstract class TextStyle {
1412

1513
companion object {
16-
fun color(colorRes: Int): TextStyle = Color(colorRes)
1714

18-
fun bold(): TextStyle = TypeFaceStyle(Typeface.BOLD)
15+
private val boldTextStyle = FontStyleTextStyle(Typeface.BOLD)
1916

20-
fun italic(): TextStyle = TypeFaceStyle(Typeface.ITALIC)
17+
private val italicTextStyle = FontStyleTextStyle(Typeface.ITALIC)
18+
19+
private val underlineTextStyle = UnderlineTextStyle()
20+
21+
private val strikethroughTextStyle = StrikethroughTextStyle()
22+
23+
@JvmStatic
24+
fun color(color: Color): TextStyle = ColorTextStyle(color)
25+
26+
@JvmStatic
27+
fun color(colorInt: Int): TextStyle = ColorTextStyle(Color.fromInt(colorInt))
28+
29+
@JvmStatic
30+
fun bold(): TextStyle = boldTextStyle
31+
32+
@JvmStatic
33+
fun italic(): TextStyle = italicTextStyle
34+
35+
@JvmStatic
36+
fun underline(): TextStyle = underlineTextStyle
37+
38+
@JvmStatic
39+
fun strikethrough(): TextStyle = strikethroughTextStyle
40+
41+
@JvmStatic
42+
fun font(fontName: Text): TextStyle = FontTextStyle(fontName)
43+
44+
@JvmStatic
45+
fun font(fontName: String): TextStyle = FontTextStyle(fontName.toText())
46+
47+
@JvmStatic
48+
fun size(size: Size): TextStyle = SizeTextStyle(size)
2149

2250
}
2351

@@ -61,26 +89,55 @@ abstract class TextStyle {
6189
}
6290
}
6391

64-
private class Color(private val colorRes: Int) : TextStyle() {
92+
private class ColorTextStyle(private val color: Color) : TextStyle() {
6593

6694
override fun SpannableString.applyStyle(context: Context) {
67-
val color = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
68-
context.getColor(colorRes)
69-
} else {
70-
context.resources.getColor(colorRes)
71-
}
95+
val color = color.getColorInt(context)
7296
setSpan(ForegroundColorSpan(color), 0, length, 0)
7397
}
7498

7599
}
76100

77-
private class TypeFaceStyle(private val typeFaceStyle: Int) : TextStyle() {
101+
private class FontStyleTextStyle(private val typeFaceStyle: Int) : TextStyle() {
78102

79103
override fun SpannableString.applyStyle(context: Context) {
80104
setSpan(StyleSpan(typeFaceStyle), 0, length, 0)
81105
}
82106
}
83107

108+
private class UnderlineTextStyle : TextStyle() {
109+
110+
override fun SpannableString.applyStyle(context: Context) {
111+
setSpan(UnderlineSpan(), 0, length, 0)
112+
}
113+
}
114+
115+
private class FontTextStyle(private val fontNameText: Text) : TextStyle() {
116+
117+
override fun SpannableString.applyStyle(context: Context) {
118+
fontNameText.getString(context)?.let {
119+
setSpan(TypefaceSpan(it),0, length, 0)
120+
}
121+
}
122+
123+
}
124+
125+
private class SizeTextStyle(private val size: Size) : TextStyle() {
126+
127+
override fun SpannableString.applyStyle(context: Context) {
128+
setSpan(AbsoluteSizeSpan(size.getPixelSize(context), false), 0, length, 0)
129+
}
130+
131+
}
132+
133+
private class StrikethroughTextStyle : TextStyle() {
134+
135+
override fun SpannableString.applyStyle(context: Context) {
136+
setSpan(StrikethroughSpan(), 0, length, 0)
137+
}
138+
139+
}
140+
84141
}
85142

86143
operator fun TextStyle?.plus(textStyle: TextStyle?): TextStyle? {

0 commit comments

Comments
 (0)