Clip a wrapped title rather than ellipsise it (#267)
Wrapping at word boundaries brought the "…" back with it, which is the half of #164 that was worth keeping: on a chip this narrow the ellipsis costs a couple of readable characters. A wrapped title now ends at the last whole word it could fit and clips there, spending none. Only a single RTL line still needs the ellipsis — softWrap off clips to the node's left edge, which in RTL is the string's end. Wrapping turns softWrap on, which cuts the logical end in both directions, so more than one line needs no exception.
This commit is contained in:
@@ -11,23 +11,21 @@ data class EventTitleOverflow(val overflow: TextOverflow, val softWrap: Boolean)
|
|||||||
/**
|
/**
|
||||||
* Overflow for an event chip's title (#164). Chips are narrow enough that the
|
* Overflow for an event chip's title (#164). Chips are narrow enough that the
|
||||||
* "…" costs a couple of readable characters, so the title runs to the chip's
|
* "…" costs a couple of readable characters, so the title runs to the chip's
|
||||||
* edge and clips mid-glyph instead.
|
* edge and clips instead — mid-glyph on one line, at the last whole word it
|
||||||
|
* could fit on several.
|
||||||
*
|
*
|
||||||
* Two cases keep the ellipsis:
|
* One case keeps the ellipsis: a single **[rtl]** line. With `softWrap` off
|
||||||
*
|
* Compose lays the line out at its full intrinsic width and clips to the node's
|
||||||
* - **[rtl].** With `softWrap` off Compose lays the line out at its full
|
* left edge, which in RTL is the *end* of the string — an Arabic title would
|
||||||
* intrinsic width and clips to the node's left edge, which in RTL is the *end*
|
* lose its beginning. The ellipsis truncates at the logical end in both
|
||||||
* of the string — an Arabic title would lose its beginning. The ellipsis
|
* directions. Wrapping needs `softWrap` on, which clips the right end either
|
||||||
* truncates at the logical end in both directions.
|
* way, so more than one line needs no such exception.
|
||||||
* - **More than one line** ([singleLine] false). Wrapping needs `softWrap` on,
|
|
||||||
* and clipping with it on breaks the last line at the last whole word — less
|
|
||||||
* title than the ellipsis showed, not more.
|
|
||||||
*/
|
*/
|
||||||
fun eventTitleOverflowFor(rtl: Boolean, singleLine: Boolean): EventTitleOverflow =
|
fun eventTitleOverflowFor(rtl: Boolean, singleLine: Boolean): EventTitleOverflow =
|
||||||
if (rtl || !singleLine) {
|
when {
|
||||||
EventTitleOverflow(TextOverflow.Ellipsis, softWrap = true)
|
!singleLine -> EventTitleOverflow(TextOverflow.Clip, softWrap = true)
|
||||||
} else {
|
rtl -> EventTitleOverflow(TextOverflow.Ellipsis, softWrap = true)
|
||||||
EventTitleOverflow(TextOverflow.Clip, softWrap = false)
|
else -> EventTitleOverflow(TextOverflow.Clip, softWrap = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** [eventTitleOverflowFor] against the current layout direction. */
|
/** [eventTitleOverflowFor] against the current layout direction. */
|
||||||
|
|||||||
@@ -25,16 +25,16 @@ class EventTitleOverflowTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `a multi-line block keeps the ellipsis, since wrapping needs softWrap`() {
|
fun `a multi-line block wraps whole words and clips, spending none on a dot`() {
|
||||||
val result = eventTitleOverflowFor(rtl = false, singleLine = false)
|
val result = eventTitleOverflowFor(rtl = false, singleLine = false)
|
||||||
assertThat(result.overflow).isEqualTo(TextOverflow.Ellipsis)
|
assertThat(result.overflow).isEqualTo(TextOverflow.Clip)
|
||||||
assertThat(result.softWrap).isTrue()
|
assertThat(result.softWrap).isTrue()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `multi-line in RTL keeps the ellipsis too`() {
|
fun `multi-line in RTL clips too, since softWrap cuts the logical end`() {
|
||||||
val result = eventTitleOverflowFor(rtl = true, singleLine = false)
|
val result = eventTitleOverflowFor(rtl = true, singleLine = false)
|
||||||
assertThat(result.overflow).isEqualTo(TextOverflow.Ellipsis)
|
assertThat(result.overflow).isEqualTo(TextOverflow.Clip)
|
||||||
assertThat(result.softWrap).isTrue()
|
assertThat(result.softWrap).isTrue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user