mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
Background span z priority (#436)
This commit is contained in:
parent
9074251e6d
commit
293bd991d5
11 changed files with 253 additions and 153 deletions
|
@ -8,6 +8,8 @@
|
|||
### Design & UX 🔳
|
||||
|
||||
* Updated subtitles for add-block or turn-into bottom sheet items (#429)
|
||||
* Text background should have the same height as the OS text-selection highlight (#392)
|
||||
* Text background should have z-axis priority lower as the one of the OS text-selection highlight (#426)
|
||||
|
||||
### Fixes & tech 🚒
|
||||
|
||||
|
@ -17,6 +19,7 @@
|
|||
* `PageViewModel` refactoring (#408)
|
||||
* Better logging for middleware requests and responses (#421)
|
||||
* Should persist home dashboard document order (#425)
|
||||
* New way to render background mark: using `Annotation` span instead of `BackgroundColorSpan` (#436)
|
||||
|
||||
### Middleware ⚙️
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@ fun Editable.extractMarks(): List<Mark> = getSpans(0, length, Span::class.java).
|
|||
is Span.Highlight -> Mark(
|
||||
range = getSpanStart(span)..getSpanEnd(span),
|
||||
type = Mark.Type.BACKGROUND_COLOR,
|
||||
param = span.backgroundColor.let { background ->
|
||||
ThemeColor.background[background]
|
||||
param = span.value.let { background ->
|
||||
ThemeColor.background[background.toInt()]
|
||||
}
|
||||
)
|
||||
is Span.Italic -> Mark(
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
package com.agileburo.anytype.core_ui.common
|
||||
|
||||
import android.graphics.Typeface
|
||||
import android.os.Parcelable
|
||||
import android.text.Editable
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.style.*
|
||||
import com.agileburo.anytype.core_utils.ext.VALUE_ROUNDED
|
||||
import com.agileburo.anytype.core_utils.ext.removeSpans
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
|
@ -90,7 +88,7 @@ fun Markup.toSpannable() = SpannableStringBuilder(body).apply {
|
|||
Markup.DEFAULT_SPANNABLE_FLAG
|
||||
)
|
||||
Markup.Type.BACKGROUND_COLOR -> setSpan(
|
||||
Span.Highlight(mark.background()),
|
||||
Span.Highlight(mark.background().toString()),
|
||||
mark.from,
|
||||
mark.to,
|
||||
Markup.DEFAULT_SPANNABLE_FLAG
|
||||
|
@ -148,7 +146,7 @@ fun Editable.setMarkup(markup: Markup) {
|
|||
Markup.DEFAULT_SPANNABLE_FLAG
|
||||
)
|
||||
Markup.Type.BACKGROUND_COLOR -> setSpan(
|
||||
Span.Highlight(mark.background()),
|
||||
Span.Highlight(mark.background().toString()),
|
||||
mark.from,
|
||||
mark.to,
|
||||
Markup.DEFAULT_SPANNABLE_FLAG
|
||||
|
|
|
@ -9,7 +9,6 @@ interface Span {
|
|||
class Italic : StyleSpan(Typeface.ITALIC), Span
|
||||
class Strikethrough : StrikethroughSpan(), Span
|
||||
class TextColor(color: Int) : ForegroundColorSpan(color), Span
|
||||
class Highlight(color: Int) : BackgroundColorSpan(color), Span
|
||||
class Url(url: String) : URLSpan(url), Span
|
||||
class Font(family: String) : TypefaceSpan(family), Span
|
||||
|
||||
|
@ -18,4 +17,10 @@ interface Span {
|
|||
const val KEYBOARD_KEY = "keyboard"
|
||||
}
|
||||
}
|
||||
|
||||
class Highlight(color: String) : Annotation(HIGHLIGHT_KEY, color), Span {
|
||||
companion object {
|
||||
const val HIGHLIGHT_KEY = "highlight"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,42 +10,42 @@ import androidx.appcompat.widget.AppCompatEditText
|
|||
import androidx.core.graphics.withTranslation
|
||||
import com.agileburo.anytype.core_ui.extensions.toast
|
||||
import com.agileburo.anytype.core_ui.tools.DefaultTextWatcher
|
||||
import com.agileburo.anytype.core_ui.widgets.text.highlight.HighlightAttributeReader
|
||||
import com.agileburo.anytype.core_ui.widgets.text.highlight.HighlightDrawer
|
||||
import me.saket.bettermovementmethod.BetterLinkMovementMethod
|
||||
import timber.log.Timber
|
||||
|
||||
class TextInputWidget : AppCompatEditText {
|
||||
|
||||
private val watchers: MutableList<TextWatcher> = mutableListOf()
|
||||
private var textRoundedBgHelper: TextRoundedBgHelper? = null
|
||||
private var highlightDrawer: HighlightDrawer? = null
|
||||
|
||||
var selectionDetector: ((IntRange) -> Unit)? = null
|
||||
|
||||
constructor(context: Context) : super(context)
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
|
||||
setupKeyboardMarkupHelpers(context, attrs)
|
||||
setupHighlightHelpers(context, attrs)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(
|
||||
context,
|
||||
attrs,
|
||||
defStyle
|
||||
) {
|
||||
setupKeyboardMarkupHelpers(context, attrs)
|
||||
}
|
||||
|
||||
private fun setupKeyboardMarkupHelpers(
|
||||
constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet
|
||||
) {
|
||||
val attributeReader = TextRoundedBgAttributeReader(context, attrs)
|
||||
textRoundedBgHelper = TextRoundedBgHelper(
|
||||
horizontalPadding = attributeReader.horizontalPadding,
|
||||
verticalPadding = attributeReader.verticalPadding,
|
||||
drawable = attributeReader.drawable,
|
||||
drawableLeft = attributeReader.drawableLeft,
|
||||
drawableMid = attributeReader.drawableMid,
|
||||
drawableRight = attributeReader.drawableRight
|
||||
)
|
||||
attrs: AttributeSet,
|
||||
defStyle: Int
|
||||
) : super(context, attrs, defStyle) {
|
||||
setupHighlightHelpers(context, attrs)
|
||||
}
|
||||
|
||||
private fun setupHighlightHelpers(context: Context, attrs: AttributeSet) {
|
||||
HighlightAttributeReader(context, attrs).let { reader ->
|
||||
highlightDrawer = HighlightDrawer(
|
||||
horizontalPadding = reader.horizontalPadding,
|
||||
verticalPadding = reader.verticalPadding,
|
||||
drawable = reader.drawable,
|
||||
drawableLeft = reader.drawableLeft,
|
||||
drawableMid = reader.drawableMid,
|
||||
drawableRight = reader.drawableRight
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun addTextChangedListener(watcher: TextWatcher) {
|
||||
|
@ -91,7 +91,7 @@ class TextInputWidget : AppCompatEditText {
|
|||
// need to draw bg first so that text can be on top during super.onDraw()
|
||||
if (text is Spanned && layout != null) {
|
||||
canvas?.withTranslation(totalPaddingLeft.toFloat(), totalPaddingTop.toFloat()) {
|
||||
textRoundedBgHelper?.draw(canvas, text as Spanned, layout)
|
||||
highlightDrawer?.draw(canvas, text as Spanned, layout)
|
||||
}
|
||||
}
|
||||
super.onDraw(canvas)
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
package com.agileburo.anytype.core_ui.widgets.text
|
||||
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.text.Annotation
|
||||
import android.text.Layout
|
||||
import android.text.Spanned
|
||||
import com.agileburo.anytype.core_ui.common.Span
|
||||
import com.agileburo.anytype.core_utils.ext.VALUE_ROUNDED
|
||||
|
||||
/**
|
||||
* Helper class to draw multi-line rounded background to certain parts of a text. The start/end
|
||||
* positions of the backgrounds are annotated with [android.text.Annotation] class. Each annotation
|
||||
* should have the annotation key set to **rounded**.
|
||||
*
|
||||
* i.e.:
|
||||
* ```
|
||||
* <!--without the quotes at the begining and end Android strips the whitespace and also starts
|
||||
* the annotation at the wrong position-->
|
||||
* <string name="ltr">"this is <annotation key="rounded">a regular</annotation> paragraph."</string>
|
||||
* ```
|
||||
*
|
||||
* **Note:** BiDi text is not supported.
|
||||
*
|
||||
* @param horizontalPadding the padding to be applied to left & right of the background
|
||||
* @param verticalPadding the padding to be applied to top & bottom of the background
|
||||
* @param drawable the drawable used to draw the background
|
||||
* @param drawableLeft the drawable used to draw left edge of the background
|
||||
* @param drawableMid the drawable used to draw for whole line
|
||||
* @param drawableRight the drawable used to draw right edge of the background
|
||||
*/
|
||||
|
||||
class TextRoundedBgHelper(
|
||||
val horizontalPadding: Int,
|
||||
verticalPadding: Int,
|
||||
drawable: Drawable,
|
||||
drawableLeft: Drawable,
|
||||
drawableMid: Drawable,
|
||||
drawableRight: Drawable
|
||||
) {
|
||||
|
||||
private val singleLineRenderer: TextRoundedBgRenderer by lazy {
|
||||
SingleLineRenderer(
|
||||
horizontalPadding = horizontalPadding,
|
||||
verticalPadding = verticalPadding,
|
||||
drawable = drawable
|
||||
)
|
||||
}
|
||||
|
||||
private val multiLineRenderer: TextRoundedBgRenderer by lazy {
|
||||
MultiLineRenderer(
|
||||
horizontalPadding = horizontalPadding,
|
||||
verticalPadding = verticalPadding,
|
||||
drawableLeft = drawableLeft,
|
||||
drawableMid = drawableMid,
|
||||
drawableRight = drawableRight
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this function during onDraw of another widget such as TextView.
|
||||
*
|
||||
* @param canvas Canvas to draw onto
|
||||
* @param text
|
||||
* @param layout Layout that contains the text
|
||||
*/
|
||||
fun draw(canvas: Canvas, text: Spanned, layout: Layout) {
|
||||
// ideally the calculations here should be cached since they are not cheap. However, proper
|
||||
// invalidation of the cache is required whenever anything related to text has changed.
|
||||
val spans = text.getSpans(0, text.length, Annotation::class.java)
|
||||
spans.forEach { span ->
|
||||
if (span.key == Span.Keyboard.KEYBOARD_KEY) {
|
||||
val spanStart = text.getSpanStart(span)
|
||||
val spanEnd = text.getSpanEnd(span)
|
||||
val startLine = layout.getLineForOffset(spanStart)
|
||||
val endLine = layout.getLineForOffset(spanEnd)
|
||||
|
||||
// start can be on the left or on the right depending on the language direction.
|
||||
val startOffset = (layout.getPrimaryHorizontal(spanStart)
|
||||
+ -1 * layout.getParagraphDirection(startLine) * horizontalPadding).toInt()
|
||||
// end can be on the left or on the right depending on the language direction.
|
||||
val endOffset = (layout.getPrimaryHorizontal(spanEnd)
|
||||
+ layout.getParagraphDirection(endLine) * horizontalPadding).toInt()
|
||||
|
||||
val renderer = if (startLine == endLine) singleLineRenderer else multiLineRenderer
|
||||
renderer.draw(canvas, layout, startLine, endLine, startOffset, endOffset)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.agileburo.anytype.core_ui.widgets.text
|
||||
package com.agileburo.anytype.core_ui.widgets.text.highlight
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
|
@ -22,17 +22,15 @@ import androidx.core.content.res.getDrawableOrThrow
|
|||
import com.agileburo.anytype.core_ui.R
|
||||
|
||||
/**
|
||||
* Reads default attributes that [TextRoundedBgHelper] needs from resources. The attributes read
|
||||
* are:
|
||||
*
|
||||
* - chHorizontalPadding: the padding to be applied to left & right of the background
|
||||
* - chVerticalPadding: the padding to be applied to top & bottom of the background
|
||||
* - chDrawable: the drawable used to draw the background
|
||||
* - chDrawableLeft: the drawable used to draw left edge of the background
|
||||
* - chDrawableMid: the drawable used to draw for whole line
|
||||
* - chDrawableRight: the drawable used to draw right edge of the background
|
||||
* Reads default attributes that [HighlightAttributeReader] needs from resources.
|
||||
* @property horizontalPadding: the padding to be applied to left & right of the background
|
||||
* @property verticalPadding: the padding to be applied to top & bottom of the background
|
||||
* @property drawable: the drawable used to draw the background
|
||||
* @property drawableLeft: the drawable used to draw left edge of the background
|
||||
* @property drawableMid: the drawable used to draw for whole line
|
||||
* @property drawableRight: the drawable used to draw right edge of the background
|
||||
*/
|
||||
class TextRoundedBgAttributeReader(context: Context, attrs: AttributeSet?) {
|
||||
class HighlightAttributeReader(context: Context, attrs: AttributeSet?) {
|
||||
|
||||
val horizontalPadding: Int
|
||||
val verticalPadding: Int
|
||||
|
@ -44,29 +42,29 @@ class TextRoundedBgAttributeReader(context: Context, attrs: AttributeSet?) {
|
|||
init {
|
||||
val typedArray = context.obtainStyledAttributes(
|
||||
attrs,
|
||||
R.styleable.TextRoundedBgHelper,
|
||||
R.styleable.HighlightDrawer,
|
||||
0,
|
||||
R.style.RoundedBgTextView
|
||||
)
|
||||
horizontalPadding = typedArray.getDimensionPixelSize(
|
||||
R.styleable.TextRoundedBgHelper_roundedTextHorizontalPadding,
|
||||
R.styleable.HighlightDrawer_roundedTextHorizontalPadding,
|
||||
0
|
||||
)
|
||||
verticalPadding = typedArray.getDimensionPixelSize(
|
||||
R.styleable.TextRoundedBgHelper_roundedTextVerticalPadding,
|
||||
R.styleable.HighlightDrawer_roundedTextVerticalPadding,
|
||||
0
|
||||
)
|
||||
drawable = typedArray.getDrawableOrThrow(
|
||||
R.styleable.TextRoundedBgHelper_roundedTextDrawable
|
||||
R.styleable.HighlightDrawer_roundedTextDrawable
|
||||
)
|
||||
drawableLeft = typedArray.getDrawableOrThrow(
|
||||
R.styleable.TextRoundedBgHelper_roundedTextDrawableLeft
|
||||
R.styleable.HighlightDrawer_roundedTextDrawableLeft
|
||||
)
|
||||
drawableMid = typedArray.getDrawableOrThrow(
|
||||
R.styleable.TextRoundedBgHelper_roundedTextDrawableMid
|
||||
R.styleable.HighlightDrawer_roundedTextDrawableMid
|
||||
)
|
||||
drawableRight = typedArray.getDrawableOrThrow(
|
||||
R.styleable.TextRoundedBgHelper_roundedTextDrawableRight
|
||||
R.styleable.HighlightDrawer_roundedTextDrawableRight
|
||||
)
|
||||
typedArray.recycle()
|
||||
}
|
|
@ -0,0 +1,179 @@
|
|||
package com.agileburo.anytype.core_ui.widgets.text.highlight
|
||||
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.text.Annotation
|
||||
import android.text.Layout
|
||||
import android.text.Spanned
|
||||
import androidx.core.graphics.drawable.DrawableCompat
|
||||
import com.agileburo.anytype.core_ui.common.Span
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Helper class to draw multi-line rounded background to certain parts of a text. The start/end
|
||||
* positions of the backgrounds are annotated with [android.text.Annotation] class. Each annotation
|
||||
* should have the annotation key set to **rounded**.
|
||||
*
|
||||
* i.e.:
|
||||
* ```
|
||||
* <!--without the quotes at the begining and end Android strips the whitespace and also starts
|
||||
* the annotation at the wrong position-->
|
||||
* <string name="ltr">"this is <annotation key="rounded">a regular</annotation> paragraph."</string>
|
||||
* ```
|
||||
*
|
||||
* **Note:** BiDi text is not supported.
|
||||
*
|
||||
* @param horizontalPadding the padding to be applied to left & right of the background
|
||||
* @param verticalPadding the padding to be applied to top & bottom of the background
|
||||
* @param drawable the drawable used to draw the background
|
||||
* @param drawableLeft the drawable used to draw left edge of the background
|
||||
* @param drawableMid the drawable used to draw for whole line
|
||||
* @param drawableRight the drawable used to draw right edge of the background
|
||||
*/
|
||||
|
||||
class HighlightDrawer(
|
||||
val horizontalPadding: Int,
|
||||
verticalPadding: Int,
|
||||
drawable: Drawable,
|
||||
drawableLeft: Drawable,
|
||||
val drawableMid: Drawable,
|
||||
drawableRight: Drawable
|
||||
) {
|
||||
|
||||
private val defaultSingleLineRenderer: TextRoundedBgRenderer by lazy {
|
||||
SingleLineRenderer(
|
||||
horizontalPadding = 0,
|
||||
verticalPadding = verticalPadding,
|
||||
drawable = drawableMid
|
||||
)
|
||||
}
|
||||
|
||||
private val defaultMultiLineRenderer: TextRoundedBgRenderer by lazy {
|
||||
MultiLineRenderer(
|
||||
horizontalPadding = 0,
|
||||
verticalPadding = verticalPadding,
|
||||
drawableLeft = drawableMid,
|
||||
drawableMid = drawableMid,
|
||||
drawableRight = drawableMid
|
||||
)
|
||||
}
|
||||
|
||||
private val singleLineHighlightCodeRenderer: TextRoundedBgRenderer by lazy {
|
||||
SingleLineRenderer(
|
||||
horizontalPadding = horizontalPadding,
|
||||
verticalPadding = verticalPadding,
|
||||
drawable = drawable
|
||||
)
|
||||
}
|
||||
|
||||
private val multiLineHighlightCodeRenderer: TextRoundedBgRenderer by lazy {
|
||||
MultiLineRenderer(
|
||||
horizontalPadding = horizontalPadding,
|
||||
verticalPadding = verticalPadding,
|
||||
drawableLeft = drawableLeft,
|
||||
drawableMid = drawableMid,
|
||||
drawableRight = drawableRight
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this function during onDraw of another widget such as TextView.
|
||||
*
|
||||
* @param canvas Canvas to draw onto
|
||||
* @param text
|
||||
* @param layout Layout that contains the text
|
||||
*/
|
||||
fun draw(canvas: Canvas, text: Spanned, layout: Layout) {
|
||||
text.getSpans(0, text.length, Annotation::class.java).forEach { span ->
|
||||
when (span.key) {
|
||||
Span.Keyboard.KEYBOARD_KEY -> drawCodeHighlight(
|
||||
span = span,
|
||||
text = text,
|
||||
layout = layout,
|
||||
canvas = canvas
|
||||
)
|
||||
Span.Highlight.HIGHLIGHT_KEY -> drawBackgroundHighlight(
|
||||
span = span,
|
||||
text = text,
|
||||
layout = layout,
|
||||
canvas = canvas
|
||||
)
|
||||
else -> Timber.e("Unexpected span: $span")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun drawBackgroundHighlight(
|
||||
span: Annotation,
|
||||
text: Spanned,
|
||||
layout: Layout,
|
||||
canvas: Canvas
|
||||
) {
|
||||
DrawableCompat.wrap(drawableMid).setTint(span.value.toInt())
|
||||
|
||||
val spanStart = text.getSpanStart(span)
|
||||
val spanEnd = text.getSpanEnd(span)
|
||||
val startLine = layout.getLineForOffset(spanStart)
|
||||
val endLine = layout.getLineForOffset(spanEnd)
|
||||
|
||||
val startOffset = layout.getPrimaryHorizontal(spanStart).toInt()
|
||||
val endOffset = layout.getPrimaryHorizontal(spanEnd).toInt()
|
||||
|
||||
if (startLine == endLine)
|
||||
defaultSingleLineRenderer.draw(
|
||||
canvas = canvas,
|
||||
layout = layout,
|
||||
startLine = startLine,
|
||||
endLine = endLine,
|
||||
startOffset = startOffset,
|
||||
endOffset = endOffset
|
||||
)
|
||||
else
|
||||
defaultMultiLineRenderer.draw(
|
||||
canvas = canvas,
|
||||
layout = layout,
|
||||
startLine = startLine,
|
||||
endLine = endLine,
|
||||
startOffset = startOffset,
|
||||
endOffset = endOffset
|
||||
)
|
||||
}
|
||||
|
||||
private fun drawCodeHighlight(
|
||||
text: Spanned,
|
||||
span: Annotation,
|
||||
layout: Layout,
|
||||
canvas: Canvas
|
||||
) {
|
||||
val spanStart = text.getSpanStart(span)
|
||||
val spanEnd = text.getSpanEnd(span)
|
||||
val startLine = layout.getLineForOffset(spanStart)
|
||||
val endLine = layout.getLineForOffset(spanEnd)
|
||||
|
||||
// start can be on the left or on the right depending on the language direction.
|
||||
val startOffset = (layout.getPrimaryHorizontal(spanStart)
|
||||
+ -1 * layout.getParagraphDirection(startLine) * horizontalPadding).toInt()
|
||||
// end can be on the left or on the right depending on the language direction.
|
||||
val endOffset = (layout.getPrimaryHorizontal(spanEnd)
|
||||
+ layout.getParagraphDirection(endLine) * horizontalPadding).toInt()
|
||||
|
||||
if (startLine == endLine)
|
||||
singleLineHighlightCodeRenderer.draw(
|
||||
canvas = canvas,
|
||||
layout = layout,
|
||||
startLine = startLine,
|
||||
endLine = endLine,
|
||||
startOffset = startOffset,
|
||||
endOffset = endOffset
|
||||
)
|
||||
else
|
||||
multiLineHighlightCodeRenderer.draw(
|
||||
canvas = canvas,
|
||||
layout = layout,
|
||||
startLine = startLine,
|
||||
endLine = endLine,
|
||||
startOffset = startOffset,
|
||||
endOffset = endOffset
|
||||
)
|
||||
}
|
||||
}
|
|
@ -14,11 +14,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.agileburo.anytype.core_ui.widgets.text
|
||||
package com.agileburo.anytype.core_ui.widgets.text.highlight
|
||||
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.text.Layout
|
||||
import com.agileburo.anytype.core_ui.widgets.text.getLineBottomWithoutPadding
|
||||
import com.agileburo.anytype.core_ui.widgets.text.getLineTopWithoutPadding
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
<attr name="active_background_color" format="color" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="TextRoundedBgHelper">
|
||||
<declare-styleable name="HighlightDrawer">
|
||||
<attr name="roundedTextHorizontalPadding" format="dimension" />
|
||||
<attr name="roundedTextVerticalPadding" format="dimension" />
|
||||
<attr name="roundedTextDrawable" format="reference" />
|
||||
|
|
|
@ -6,12 +6,12 @@ import android.text.Spanned
|
|||
import android.util.AttributeSet
|
||||
import androidx.appcompat.widget.AppCompatTextView
|
||||
import androidx.core.graphics.withTranslation
|
||||
import com.agileburo.anytype.core_ui.widgets.text.TextRoundedBgAttributeReader
|
||||
import com.agileburo.anytype.core_ui.widgets.text.TextRoundedBgHelper
|
||||
import com.agileburo.anytype.core_ui.widgets.text.highlight.HighlightAttributeReader
|
||||
import com.agileburo.anytype.core_ui.widgets.text.highlight.HighlightDrawer
|
||||
|
||||
class RoundedBgTextView : AppCompatTextView {
|
||||
|
||||
private val textRoundedBgHelper: TextRoundedBgHelper
|
||||
private val highlightDrawer: HighlightDrawer
|
||||
|
||||
@JvmOverloads
|
||||
constructor(
|
||||
|
@ -19,22 +19,27 @@ class RoundedBgTextView : AppCompatTextView {
|
|||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = android.R.attr.textViewStyle
|
||||
) : super(context, attrs, defStyleAttr) {
|
||||
val attributeReader = TextRoundedBgAttributeReader(context, attrs)
|
||||
textRoundedBgHelper = TextRoundedBgHelper(
|
||||
horizontalPadding = attributeReader.horizontalPadding,
|
||||
verticalPadding = attributeReader.verticalPadding,
|
||||
drawable = attributeReader.drawable,
|
||||
drawableLeft = attributeReader.drawableLeft,
|
||||
drawableMid = attributeReader.drawableMid,
|
||||
drawableRight = attributeReader.drawableRight
|
||||
)
|
||||
val attributeReader =
|
||||
HighlightAttributeReader(
|
||||
context,
|
||||
attrs
|
||||
)
|
||||
highlightDrawer =
|
||||
HighlightDrawer(
|
||||
horizontalPadding = attributeReader.horizontalPadding,
|
||||
verticalPadding = attributeReader.verticalPadding,
|
||||
drawable = attributeReader.drawable,
|
||||
drawableLeft = attributeReader.drawableLeft,
|
||||
drawableMid = attributeReader.drawableMid,
|
||||
drawableRight = attributeReader.drawableRight
|
||||
)
|
||||
}
|
||||
|
||||
override fun onDraw(canvas: Canvas) {
|
||||
// need to draw bg first so that text can be on top during super.onDraw()
|
||||
if (text is Spanned && layout != null) {
|
||||
canvas.withTranslation(totalPaddingLeft.toFloat(), totalPaddingTop.toFloat()) {
|
||||
textRoundedBgHelper.draw(canvas, text as Spanned, layout)
|
||||
highlightDrawer.draw(canvas, text as Spanned, layout)
|
||||
}
|
||||
}
|
||||
super.onDraw(canvas)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue