From 02011c898c53ce23faf72c6310954f0997cc4bb6 Mon Sep 17 00:00:00 2001 From: Janne Valkealahti Date: Sun, 28 Jul 2024 05:06:40 +0100 Subject: [PATCH] Screen writer support for AttributedString - New Screen.Writer has new text method taking AttributedString instead of just String - Fixes #1110 --- .../component/view/screen/DefaultScreen.java | 25 +++++++++++++++++++ .../shell/component/view/screen/Screen.java | 12 +++++++++ .../shell/style/ThemeResolver.java | 2 +- .../component/view/screen/ScreenTests.java | 8 ++++++ 4 files changed, 46 insertions(+), 1 deletion(-) diff --git a/spring-shell-core/src/main/java/org/springframework/shell/component/view/screen/DefaultScreen.java b/spring-shell-core/src/main/java/org/springframework/shell/component/view/screen/DefaultScreen.java index 483dd141..4c540278 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/component/view/screen/DefaultScreen.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/component/view/screen/DefaultScreen.java @@ -30,6 +30,8 @@ import org.springframework.shell.geom.HorizontalAlign; import org.springframework.shell.geom.Position; import org.springframework.shell.geom.Rectangle; import org.springframework.shell.geom.VerticalAlign; +import org.springframework.shell.style.ThemeResolver; +import org.springframework.shell.style.ThemeResolver.ResolvedValues; import org.springframework.util.Assert; /** @@ -312,6 +314,29 @@ public class DefaultScreen implements Screen, DisplayLines { } } + @Override + public void text(AttributedString text, int x, int y) { + Layer layer = getLayer(index); + for (int i = 0; i < text.length() && i < columns; i++) { + DefaultScreenItem item = layer.getScreenItem(x + i, y); + if (item != null) { + char c = text.charAt(i); + AttributedStyle as = text.styleAt(i); + ResolvedValues rv = ThemeResolver.resolveValues(as); + item.content = Character.toString(c); + if (rv.foreground() > -1) { + item.foreground = rv.foreground(); + } + if (rv.style() > -1) { + item.style = rv.style(); + } + if (rv.background() > -1) { + item.background = rv.background(); + } + } + } + } + @Override public void border(int x, int y, int width, int height) { log.trace("PrintBorder rows={}, columns={}, x={}, y={}, width={}, height={}", rows, columns, x, y, width, diff --git a/spring-shell-core/src/main/java/org/springframework/shell/component/view/screen/Screen.java b/spring-shell-core/src/main/java/org/springframework/shell/component/view/screen/Screen.java index 91f8db55..2598a49b 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/component/view/screen/Screen.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/component/view/screen/Screen.java @@ -15,6 +15,8 @@ */ package org.springframework.shell.component.view.screen; +import org.jline.utils.AttributedString; + import org.springframework.lang.Nullable; import org.springframework.shell.geom.HorizontalAlign; import org.springframework.shell.geom.Position; @@ -107,6 +109,16 @@ public interface Screen { */ void text(String text, int x, int y); + /** + * Write an attributed text horizontally starting from a position defined by + * {@code x} and {@code y} within a bounds of a {@link Screen}. + * + * @param text the text to write + * @param x the x position + * @param y the y position + */ + void text(AttributedString text, int x, int y); + /** * Write a border with a given rectangle coordinates. * diff --git a/spring-shell-core/src/main/java/org/springframework/shell/style/ThemeResolver.java b/spring-shell-core/src/main/java/org/springframework/shell/style/ThemeResolver.java index 76c1c1f9..b0591e73 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/style/ThemeResolver.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/style/ThemeResolver.java @@ -70,7 +70,7 @@ public class ThemeResolver { * @param attributedStyle the attibuted style * @return resolved values */ - public ResolvedValues resolveValues(AttributedStyle attributedStyle) { + public static ResolvedValues resolveValues(AttributedStyle attributedStyle) { long style = attributedStyle.getStyle(); long s = style & ~(F_FOREGROUND | F_BACKGROUND); s = (s & 0x00007FFF); diff --git a/spring-shell-core/src/test/java/org/springframework/shell/component/view/screen/ScreenTests.java b/spring-shell-core/src/test/java/org/springframework/shell/component/view/screen/ScreenTests.java index cc0a4e6c..63fe58e8 100644 --- a/spring-shell-core/src/test/java/org/springframework/shell/component/view/screen/ScreenTests.java +++ b/spring-shell-core/src/test/java/org/springframework/shell/component/view/screen/ScreenTests.java @@ -15,6 +15,7 @@ */ package org.springframework.shell.component.view.screen; +import org.jline.utils.AttributedString; import org.junit.jupiter.api.Test; import org.springframework.shell.component.view.control.AbstractViewTests; @@ -56,6 +57,13 @@ class ScreenTests extends AbstractViewTests { assertThat(forScreen(screen24x80)).hasHorizontalText("text", 0, 0, 4); } + @Test + void printsAttributedText() { + AttributedString text = new AttributedString("text"); + screen24x80.writerBuilder().build().text(text, 0, 0); + assertThat(forScreen(screen24x80)).hasHorizontalText("text", 0, 0, 4); + } + @Test void printsTextWithForegroundColor() { Writer writer = screen24x80.writerBuilder().color(Color.RED).build();