From b34dc31d326d0f40b1c3296015ca01c80142a272 Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Mon, 7 Sep 2026 14:59:40 +0200 Subject: [PATCH] Clip a wrapped title rather than ellipsise it (#267) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- .../calendula/ui/common/EventTitleOverflow.kt | 26 +++++++++---------- .../ui/common/EventTitleOverflowTest.kt | 8 +++--- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/de/jeanlucmakiola/calendula/ui/common/EventTitleOverflow.kt b/app/src/main/java/de/jeanlucmakiola/calendula/ui/common/EventTitleOverflow.kt index 89304a3..1542165 100644 --- a/app/src/main/java/de/jeanlucmakiola/calendula/ui/common/EventTitleOverflow.kt +++ b/app/src/main/java/de/jeanlucmakiola/calendula/ui/common/EventTitleOverflow.kt @@ -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 * "…" 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: - * - * - **[rtl].** With `softWrap` off Compose lays the line out at its full - * intrinsic width and clips to the node's left edge, which in RTL is the *end* - * of the string — an Arabic title would lose its beginning. The ellipsis - * truncates at the logical end in both directions. - * - **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. + * 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 + * left edge, which in RTL is the *end* of the string — an Arabic title would + * lose its beginning. The ellipsis truncates at the logical end in both + * directions. Wrapping needs `softWrap` on, which clips the right end either + * way, so more than one line needs no such exception. */ fun eventTitleOverflowFor(rtl: Boolean, singleLine: Boolean): EventTitleOverflow = - if (rtl || !singleLine) { - EventTitleOverflow(TextOverflow.Ellipsis, softWrap = true) - } else { - EventTitleOverflow(TextOverflow.Clip, softWrap = false) + when { + !singleLine -> EventTitleOverflow(TextOverflow.Clip, softWrap = true) + rtl -> EventTitleOverflow(TextOverflow.Ellipsis, softWrap = true) + else -> EventTitleOverflow(TextOverflow.Clip, softWrap = false) } /** [eventTitleOverflowFor] against the current layout direction. */ diff --git a/app/src/test/java/de/jeanlucmakiola/calendula/ui/common/EventTitleOverflowTest.kt b/app/src/test/java/de/jeanlucmakiola/calendula/ui/common/EventTitleOverflowTest.kt index 7fd56b7..def31a9 100644 --- a/app/src/test/java/de/jeanlucmakiola/calendula/ui/common/EventTitleOverflowTest.kt +++ b/app/src/test/java/de/jeanlucmakiola/calendula/ui/common/EventTitleOverflowTest.kt @@ -25,16 +25,16 @@ class EventTitleOverflowTest { } @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) - assertThat(result.overflow).isEqualTo(TextOverflow.Ellipsis) + assertThat(result.overflow).isEqualTo(TextOverflow.Clip) assertThat(result.softWrap).isTrue() } @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) - assertThat(result.overflow).isEqualTo(TextOverflow.Ellipsis) + assertThat(result.overflow).isEqualTo(TextOverflow.Clip) assertThat(result.softWrap).isTrue() } }