Skip to content

Commit

Permalink
Merge pull request #1007 from wordpress-mobile/feature/add-styling-op…
Browse files Browse the repository at this point in the history
…tions-to-task-list

Feature/add styling options to task list
  • Loading branch information
AmandaRiu authored Oct 10, 2022
2 parents e91ec10 + 5e98273 commit 4bcc78e
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 19 deletions.
5 changes: 5 additions & 0 deletions app/src/main/kotlin/org/wordpress/aztec/demo/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ open class MainActivity : AppCompatActivity(),
private val UNDERLINE = "<u style=\"color:lime\">Underline</u><br>"
private val STRIKETHROUGH = "<s style=\"color:#ff666666\" class=\"test\">Strikethrough</s><br>" // <s> or <strike> or <del>
private val ORDERED = "<ol style=\"color:green\"><li>Ordered</li><li>should have color</li></ol>"
private val TASK_LIST = "<ul type=\"task-list\">\n" +
" <li><input type=\"checkbox\" class=\"task-list-item-checkbox\">Unchecked</li>\n" +
" <li><input type=\"checkbox\" class=\"task-list-item-checkbox\" checked>Checked</li>\n" +
"</ul>"
private val ORDERED_WITH_START = "<h4>Start in 10 List:</h4>" +
"<ol start=\"10\">\n" +
" <li>Ten</li>\n" +
Expand Down Expand Up @@ -186,6 +190,7 @@ open class MainActivity : AppCompatActivity(),
ITALIC +
UNDERLINE +
STRIKETHROUGH +
TASK_LIST +
ORDERED +
ORDERED_WITH_START +
ORDERED_REVERSED +
Expand Down
11 changes: 10 additions & 1 deletion aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,8 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
var lastPressedXCoord: Int = 0
var lastPressedYCoord: Int = 0

private lateinit var listItemStyle: BlockFormatter.ListItemStyle

override fun onDraw(canvas: Canvas) {
plugins.filterIsInstance<IOnDrawPlugin>().forEach {
it.onDraw(canvas)
Expand Down Expand Up @@ -452,8 +454,14 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
styles.getDimensionPixelSize(R.styleable.AztecText_bulletPadding, 0),
styles.getDimensionPixelSize(R.styleable.AztecText_bulletWidth, 0),
verticalParagraphPadding)

listItemStyle = BlockFormatter.ListItemStyle(
styles.getBoolean(R.styleable.AztecText_taskListStrikethroughChecked, false),
styles.getColor(R.styleable.AztecText_taskListCheckedTextColor, 0))

blockFormatter = BlockFormatter(editor = this,
listStyle = listStyle,
listItemStyle = listItemStyle,
quoteStyle = BlockFormatter.QuoteStyle(
styles.getColor(R.styleable.AztecText_quoteBackground, 0),
styles.getColor(R.styleable.AztecText_quoteColor, 0),
Expand Down Expand Up @@ -788,7 +796,7 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
BlockElementWatcher(this)
.add(HeadingHandler(alignmentRendering))
.add(ListHandler())
.add(ListItemHandler(alignmentRendering))
.add(ListItemHandler(alignmentRendering, listItemStyle))
.add(QuoteHandler())
.add(PreformatHandler())
.install(this)
Expand Down Expand Up @@ -1599,6 +1607,7 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
editable.getSpans(start, end, EndOfParagraphMarker::class.java).forEach { it.verticalPadding = verticalParagraphPadding }
editable.getSpans(start, end, AztecURLSpan::class.java).forEach { it.linkStyle = linkFormatter.linkStyle }
editable.getSpans(start, end, AztecCodeSpan::class.java).forEach { it.codeStyle = inlineFormatter.codeStyle }
editable.getSpans(start, end, AztecListItemSpan::class.java).forEach { it.listItemStyle = listItemStyle }

val imageSpans = editable.getSpans(start, end, AztecImageSpan::class.java)
imageSpans.forEach {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import kotlin.reflect.KClass

class BlockFormatter(editor: AztecText,
private val listStyle: ListStyle,
private val listItemStyle: ListItemStyle,
private val quoteStyle: QuoteStyle,
private val headerStyle: HeaderStyles,
private val preformatStyle: PreformatStyle,
Expand All @@ -62,6 +63,7 @@ class BlockFormatter(editor: AztecText,

data class QuoteStyle(val quoteBackground: Int, val quoteColor: Int, val quoteTextColor: Int, val quoteBackgroundAlpha: Float, val quoteMargin: Int, val quotePadding: Int, val quoteWidth: Int, val verticalPadding: Int)
data class PreformatStyle(val preformatBackground: Int, val preformatBackgroundAlpha: Float, val preformatColor: Int, val verticalPadding: Int, val leadingMargin: Int, val preformatBorderColor: Int, val preformatBorderRadius: Int, val preformatBorderThickness: Int, val preformatTextSize: Int)
data class ListItemStyle(val strikeThroughCheckedItems: Boolean, val checkedItemsTextColor: Int)
data class HeaderStyles(val verticalPadding: Int, val styles: Map<AztecHeadingSpan.Heading, HeadingStyle>) {
data class HeadingStyle(val fontSize: Int, val fontColor: Int)
}
Expand Down Expand Up @@ -452,7 +454,7 @@ class BlockFormatter(editor: AztecText,
return when (textFormat) {
AztecTextFormat.FORMAT_ORDERED_LIST -> listOf(createOrderedListSpan(nestingLevel, alignmentRendering, attrs, listStyle), createListItemSpan(nestingLevel + 1, alignmentRendering))
AztecTextFormat.FORMAT_UNORDERED_LIST -> listOf(createUnorderedListSpan(nestingLevel, alignmentRendering, attrs, listStyle), createListItemSpan(nestingLevel + 1, alignmentRendering))
AztecTextFormat.FORMAT_TASK_LIST -> listOf(createTaskListSpan(nestingLevel, alignmentRendering, attrs, editor.context, listStyle), createListItemSpan(nestingLevel + 1, alignmentRendering))
AztecTextFormat.FORMAT_TASK_LIST -> listOf(createTaskListSpan(nestingLevel, alignmentRendering, attrs, editor.context, listStyle), createListItemSpan(nestingLevel + 1, alignmentRendering, listItemStyle = listItemStyle))
AztecTextFormat.FORMAT_QUOTE -> listOf(createAztecQuoteSpan(nestingLevel, attrs, alignmentRendering, quoteStyle))
AztecTextFormat.FORMAT_HEADING_1,
AztecTextFormat.FORMAT_HEADING_2,
Expand Down Expand Up @@ -500,7 +502,7 @@ class BlockFormatter(editor: AztecText,
typeIsAssignableTo(AztecOrderedListSpan::class) -> createOrderedListSpan(nestingLevel, alignmentRendering, attrs, listStyle)
typeIsAssignableTo(AztecUnorderedListSpan::class) -> createUnorderedListSpan(nestingLevel, alignmentRendering, attrs, listStyle)
typeIsAssignableTo(AztecTaskListSpan::class) -> createTaskListSpan(nestingLevel, alignmentRendering, attrs, editor.context, listStyle)
typeIsAssignableTo(AztecListItemSpan::class) -> createListItemSpan(nestingLevel, alignmentRendering, attrs)
typeIsAssignableTo(AztecListItemSpan::class) -> createListItemSpan(nestingLevel, alignmentRendering, attrs, listItemStyle)
typeIsAssignableTo(AztecQuoteSpan::class) -> createAztecQuoteSpan(nestingLevel, attrs, alignmentRendering, quoteStyle)
typeIsAssignableTo(AztecHeadingSpan::class) -> createHeadingSpan(nestingLevel, textFormat, attrs, alignmentRendering, headerStyle)
typeIsAssignableTo(AztecPreformatSpan::class) -> createPreformatSpan(nestingLevel, alignmentRendering, attrs, preformatStyle)
Expand Down Expand Up @@ -812,7 +814,7 @@ class BlockFormatter(editor: AztecText,
BlockHandler.set(editableText, listSpan, start, end)
// special case for styling single empty lines
if (end - start == 1 && (editableText[end - 1] == '\n' || editableText[end - 1] == Constants.END_OF_BUFFER_MARKER)) {
ListItemHandler.newListItem(editableText, start, end, listSpan.nestingLevel + 1, alignmentRendering)
ListItemHandler.newListItem(editableText, start, end, listSpan.nestingLevel + 1, alignmentRendering, listItemStyle)
} else {
val listEnd = if (end == editableText.length) end else end - 1
val listContent = editableText.substring(start, listEnd)
Expand All @@ -831,7 +833,7 @@ class BlockFormatter(editor: AztecText,
start + lineStart,
start + lineEnd,
listSpan.nestingLevel + 1,
alignmentRendering)
alignmentRendering, listItemStyle)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.wordpress.aztec.handlers

import android.text.Spannable
import org.wordpress.aztec.AlignmentRendering
import org.wordpress.aztec.formatting.BlockFormatter
import org.wordpress.aztec.spans.AztecListItemSpan
import org.wordpress.aztec.spans.AztecListItemSpan.Companion.CHECKED
import org.wordpress.aztec.spans.AztecTaskListSpan
Expand All @@ -10,12 +11,13 @@ import org.wordpress.aztec.spans.createListItemSpan
import org.wordpress.aztec.watchers.TextDeleter

class ListItemHandler(
val alignmentRendering: AlignmentRendering
val alignmentRendering: AlignmentRendering,
val listItemStyle: BlockFormatter.ListItemStyle
) : BlockHandler<AztecListItemSpan>(AztecListItemSpan::class.java) {

override fun handleNewlineAtStartOfBlock() {
// newline added at start of bullet so, add a new bullet
newListItem(text, newlineIndex, newlineIndex + 1, block.span.nestingLevel, alignmentRendering)
newListItem(text, newlineIndex, newlineIndex + 1, block.span.nestingLevel, alignmentRendering, listItemStyle)

// push current bullet forward
block.start = newlineIndex + 1
Expand Down Expand Up @@ -58,7 +60,7 @@ class ListItemHandler(
newListItemStart = newlineIndex
}

newListItem(text, newListItemStart, block.end, block.span.nestingLevel, alignmentRendering)
newListItem(text, newListItemStart, block.end, block.span.nestingLevel, alignmentRendering, listItemStyle)
block.end = newListItemStart
}

Expand All @@ -69,7 +71,7 @@ class ListItemHandler(
}

// attach a new bullet around the end-of-text marker
newListItem(text, markerIndex, markerIndex + 1, block.span.nestingLevel, alignmentRendering)
newListItem(text, markerIndex, markerIndex + 1, block.span.nestingLevel, alignmentRendering, listItemStyle)

// the current list item has bled over to the marker so, let's adjust its range to just before the marker.
// There's a newline there hopefully :)
Expand All @@ -82,10 +84,11 @@ class ListItemHandler(
start: Int,
end: Int,
nestingLevel: Int,
alignmentRendering: AlignmentRendering
alignmentRendering: AlignmentRendering,
listItemStyle: BlockFormatter.ListItemStyle
) {
val isInTaskList = !text.getSpans(start, end, AztecTaskListSpan::class.java).isNullOrEmpty()
set(text, createListItemSpan(nestingLevel, alignmentRendering).apply {
set(text, createListItemSpan(nestingLevel, alignmentRendering, listItemStyle = listItemStyle).apply {
if (isInTaskList) {
this.attributes.setValue(CHECKED, "false")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
package org.wordpress.aztec.spans

import android.text.Layout
import android.text.TextPaint
import android.text.style.CharacterStyle
import org.wordpress.aztec.AlignmentRendering
import org.wordpress.aztec.AztecAttributes
import org.wordpress.aztec.ITextFormat
import org.wordpress.aztec.formatting.BlockFormatter
import java.lang.StringBuilder

fun createListItemSpan(nestingLevel: Int,
alignmentRendering: AlignmentRendering,
attributes: AztecAttributes = AztecAttributes()) : IAztecBlockSpan =
when (alignmentRendering) {
AlignmentRendering.SPAN_LEVEL -> AztecListItemSpanAligned(nestingLevel, attributes, null)
AlignmentRendering.VIEW_LEVEL -> AztecListItemSpan(nestingLevel, attributes)
}
attributes: AztecAttributes = AztecAttributes(),
listItemStyle: BlockFormatter.ListItemStyle = BlockFormatter.ListItemStyle(false, 0)): IAztecBlockSpan = when (alignmentRendering) {
AlignmentRendering.SPAN_LEVEL -> AztecListItemSpanAligned(nestingLevel, attributes, null, listItemStyle)
AlignmentRendering.VIEW_LEVEL -> AztecListItemSpan(nestingLevel, attributes, listItemStyle)
}

/**
* We need to have two classes for handling alignment at either the Span-level (ListItemSpanAligned)
Expand All @@ -24,7 +27,9 @@ fun createListItemSpan(nestingLevel: Int,
*/
open class AztecListItemSpan(
override var nestingLevel: Int,
override var attributes: AztecAttributes) : IAztecCompositeBlockSpan {
override var attributes: AztecAttributes,
var listItemStyle: BlockFormatter.ListItemStyle = BlockFormatter.ListItemStyle(
false, 0)) : CharacterStyle(), IAztecCompositeBlockSpan {
fun toggleCheck() {
if (attributes.getValue(CHECKED) == "true") {
attributes.setValue(CHECKED, "false")
Expand Down Expand Up @@ -74,13 +79,27 @@ open class AztecListItemSpan(

override var endBeforeBleed: Int = -1
override var startBeforeCollapse: Int = -1

companion object {
const val CHECKED = "checked"
}

override fun updateDrawState(tp: TextPaint) {
val isChecked = attributes.getValue(CHECKED) == "true"

if (listItemStyle.strikeThroughCheckedItems) {
tp.isStrikeThruText = isChecked
}

if (listItemStyle.checkedItemsTextColor != 0 && isChecked) {
tp.color = listItemStyle.checkedItemsTextColor
}
}
}

class AztecListItemSpanAligned(
nestingLevel: Int,
attributes: AztecAttributes,
override var align: Layout.Alignment?
) : AztecListItemSpan(nestingLevel, attributes), IAztecAlignmentSpan
override var align: Layout.Alignment?,
listItemStyle: BlockFormatter.ListItemStyle = BlockFormatter.ListItemStyle(false, 0)
) : AztecListItemSpan(nestingLevel, attributes, listItemStyle), IAztecAlignmentSpan
2 changes: 2 additions & 0 deletions aztec/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@
<attr name="headingFourFontColor" format="reference|color" />
<attr name="headingFiveFontColor" format="reference|color" />
<attr name="headingSixFontColor" format="reference|color" />
<attr name="taskListStrikethroughChecked" format="reference|boolean" />
<attr name="taskListCheckedTextColor" format="reference|color" />
</declare-styleable>

<declare-styleable name="AztecToolbar">
Expand Down
3 changes: 3 additions & 0 deletions aztec/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
<item name="bulletMargin">@dimen/bullet_margin</item>
<item name="bulletPadding">@dimen/bullet_padding</item>
<item name="bulletWidth">@dimen/bullet_width</item>
<!-- Task list -->
<item name="taskListCheckedTextColor">@android:color/darker_gray</item>
<item name="taskListStrikethroughChecked">true</item>
<!-- Code -->
<item name="codeBackground">@color/code_background</item>
<item name="codeBackgroundAlpha">75%</item>
Expand Down

0 comments on commit 4bcc78e

Please sign in to comment.