Skip to content

Commit 477b24b

Browse files
committed
Fix fg and bg styling
- In ListView and MenuView fix how styling for background and foreground are used. - In Catalog app fix same issue in ScenarioListCell - Backport #1063 - Fixes #1066
1 parent f6fae64 commit 477b24b

File tree

5 files changed

+155
-11
lines changed

5 files changed

+155
-11
lines changed

spring-shell-core/src/main/java/org/springframework/shell/component/view/control/ListView.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023 the original author or authors.
2+
* Copyright 2023-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -169,6 +169,8 @@ protected void drawInternal(Screen screen) {
169169
Rectangle rect = getInnerRect();
170170
int y = rect.y();
171171
int selectedStyle = resolveThemeStyle(StyleSettings.TAG_HIGHLIGHT, ScreenItem.STYLE_BOLD);
172+
int selectedForegroundColor = resolveThemeForeground(StyleSettings.TAG_HIGHLIGHT, -1, -1);
173+
int selectedBackgroundColor = resolveThemeBackground(StyleSettings.TAG_HIGHLIGHT, -1, -1);
172174
int i = 0;
173175

174176
for (ListCell<T> c : cells) {
@@ -178,10 +180,13 @@ protected void drawInternal(Screen screen) {
178180
}
179181
c.setRect(rect.x(), y++, rect.width(), 1);
180182
if (i == start + pos) {
183+
c.setForegroundColor(selectedForegroundColor);
184+
c.setBackgroundColor(selectedBackgroundColor);
181185
c.setStyle(selectedStyle);
182186
}
183187
else {
184188
c.setBackgroundColor(-1);
189+
c.setForegroundColor(-1);
185190
c.setStyle(-1);
186191
}
187192
c.draw(screen);

spring-shell-core/src/main/java/org/springframework/shell/component/view/control/MenuView.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023 the original author or authors.
2+
* Copyright 2023-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -143,9 +143,15 @@ public Dimension getPreferredDimension() {
143143
protected void drawInternal(Screen screen) {
144144
Rectangle rect = getInnerRect();
145145
int y = rect.y();
146-
Writer writer = screen.writerBuilder().layer(getLayer()).build();
147-
int themeStyle = resolveThemeStyle(StyleSettings.TAG_HIGHLIGHT, ScreenItem.STYLE_BOLD);
148-
Writer writer2 = screen.writerBuilder().layer(getLayer()).style(themeStyle).build();
146+
int selectedStyle = resolveThemeStyle(StyleSettings.TAG_HIGHLIGHT, ScreenItem.STYLE_BOLD);
147+
int selectedForegroundColor = resolveThemeForeground(StyleSettings.TAG_HIGHLIGHT, -1, -1);
148+
int selectedBackgroundColor = resolveThemeBackground(StyleSettings.TAG_HIGHLIGHT, -1, -1);
149+
Writer writer = screen.writerBuilder()
150+
.layer(getLayer()).build();
151+
Writer selectedWriter = screen.writerBuilder()
152+
.layer(getLayer())
153+
.color(selectedForegroundColor)
154+
.style(selectedStyle).build();
149155
int i = 0;
150156
boolean hasCheck = false;
151157
for (MenuItem item : items) {
@@ -174,7 +180,11 @@ else if (item.checkStyle == MenuItemCheckStyle.CHECKED) {
174180
}
175181
String text = prefix + item.getTitle();
176182
if (activeItemIndex == i) {
177-
writer2.text(text, rect.x(), y);
183+
selectedWriter.text(text, rect.x(), y);
184+
if (selectedBackgroundColor > -1) {
185+
Rectangle itemRect = new Rectangle(rect.x(), y, rect.width(), 1);
186+
selectedWriter.background(itemRect, selectedBackgroundColor);
187+
}
178188
}
179189
else {
180190
writer.text(text, rect.x(), y);

spring-shell-core/src/test/java/org/springframework/shell/component/view/control/ListViewTests.java

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023 the original author or authors.
2+
* Copyright 2023-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -35,9 +35,15 @@
3535
import org.springframework.shell.component.view.event.MouseEvent;
3636
import org.springframework.shell.component.view.event.MouseHandler;
3737
import org.springframework.shell.component.view.event.MouseHandler.MouseHandlerResult;
38+
import org.springframework.shell.component.view.screen.Color;
3839
import org.springframework.shell.component.view.screen.Screen;
3940
import org.springframework.shell.component.view.screen.Screen.Writer;
4041
import org.springframework.shell.geom.Rectangle;
42+
import org.springframework.shell.style.StyleSettings;
43+
import org.springframework.shell.style.Theme;
44+
import org.springframework.shell.style.ThemeRegistry;
45+
import org.springframework.shell.style.ThemeResolver;
46+
import org.springframework.shell.style.ThemeSettings;
4147

4248
import static org.assertj.core.api.Assertions.assertThat;
4349

@@ -52,6 +58,38 @@ class ListViewTests extends AbstractViewTests {
5258
private static final String SCROLL_METHOD = "scrollIndex";
5359
ListView<String> view;
5460

61+
ThemeResolver themeResolver;
62+
63+
@BeforeEach
64+
public void setupListView() {
65+
ThemeRegistry themeRegistry = new ThemeRegistry();
66+
themeRegistry.register(new Theme() {
67+
@Override
68+
public String getName() {
69+
return "default";
70+
}
71+
72+
@Override
73+
public ThemeSettings getSettings() {
74+
75+
return new ThemeSettings() {
76+
@Override
77+
public StyleSettings styles() {
78+
return new StyleSettings() {
79+
@Override
80+
public String highlight() {
81+
return "bold,italic,bg-rgb:#0000FF,fg-rgb:#FF0000";
82+
}
83+
};
84+
}
85+
};
86+
}
87+
});
88+
89+
themeResolver = new ThemeResolver(themeRegistry, "default");
90+
}
91+
92+
5593
@Nested
5694
class Events {
5795

@@ -189,6 +227,32 @@ void hasBorder() {
189227
assertThat(forScreen(screen24x80)).hasBorder(0, 0, 80, 24);
190228
}
191229

230+
@Test
231+
void selectedHighlightNoTheme() {
232+
view = new ListView<>();
233+
view.setShowBorder(true);
234+
view.setRect(0, 0, 10, 7);
235+
view.setItems(Arrays.asList("item1", "item2", "item3"));
236+
view.draw(screen7x10);
237+
assertThat(forScreen(screen7x10)).hasStyle(1, 1, 1);
238+
assertThat(forScreen(screen7x10)).hasForegroundColor(1, 1, -1);
239+
assertThat(forScreen(screen7x10)).hasBackgroundColor(1, 1, -1);
240+
}
241+
242+
@Test
243+
void selectedHighlightThemeSet() {
244+
view = new ListView<>();
245+
view.setThemeResolver(themeResolver);
246+
view.setThemeName("default");
247+
view.setShowBorder(true);
248+
view.setRect(0, 0, 10, 7);
249+
view.setItems(Arrays.asList("item1", "item2", "item3"));
250+
view.draw(screen7x10);
251+
assertThat(forScreen(screen7x10)).hasStyle(1, 1, 5);
252+
assertThat(forScreen(screen7x10)).hasForegroundColor(1, 1, Color.RED);
253+
assertThat(forScreen(screen7x10)).hasBackgroundColor(1, 1, Color.BLUE);
254+
}
255+
192256
@Test
193257
void showingAllCells() {
194258
view = new ListView<>();

spring-shell-core/src/test/java/org/springframework/shell/component/view/control/MenuViewTests.java

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023 the original author or authors.
2+
* Copyright 2023-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -32,6 +32,12 @@
3232
import org.springframework.shell.component.view.event.KeyEvent.Key;
3333
import org.springframework.shell.component.view.event.MouseEvent;
3434
import org.springframework.shell.component.view.event.MouseHandler.MouseHandlerResult;
35+
import org.springframework.shell.component.view.screen.Color;
36+
import org.springframework.shell.style.StyleSettings;
37+
import org.springframework.shell.style.Theme;
38+
import org.springframework.shell.style.ThemeRegistry;
39+
import org.springframework.shell.style.ThemeResolver;
40+
import org.springframework.shell.style.ThemeSettings;
3541
import org.springframework.test.util.ReflectionTestUtils;
3642

3743
import static org.assertj.core.api.Assertions.assertThat;
@@ -42,6 +48,37 @@ class MenuViewTests extends AbstractViewTests {
4248
private static final String RADIO_ACTIVE_FIELD = "radioActive";
4349
private static final String CHECKED_ACTIVE_FIELD = "checkedActive";
4450

51+
ThemeResolver themeResolver;
52+
53+
@BeforeEach
54+
public void setupMenuView() {
55+
ThemeRegistry themeRegistry = new ThemeRegistry();
56+
themeRegistry.register(new Theme() {
57+
@Override
58+
public String getName() {
59+
return "default";
60+
}
61+
62+
@Override
63+
public ThemeSettings getSettings() {
64+
65+
return new ThemeSettings() {
66+
@Override
67+
public StyleSettings styles() {
68+
return new StyleSettings() {
69+
@Override
70+
public String highlight() {
71+
return "bold,italic,bg-rgb:#0000FF,fg-rgb:#FF0000";
72+
}
73+
};
74+
}
75+
};
76+
}
77+
});
78+
79+
themeResolver = new ThemeResolver(themeRegistry, "default");
80+
}
81+
4582
@Nested
4683
class Construction {
4784

@@ -127,20 +164,48 @@ void constructUsingRunnable() {
127164
@Nested
128165
class Styling {
129166

167+
MenuView view;
168+
130169
@Test
131170
void hasBorder() {
132171
MenuItem menuItem = new MenuView.MenuItem("sub1");
133-
MenuView view = new MenuView(Arrays.asList(menuItem));
172+
view = new MenuView(Arrays.asList(menuItem));
134173
view.setShowBorder(true);
135174
view.setRect(0, 0, 80, 24);
136175
view.draw(screen24x80);
137176
assertThat(forScreen(screen24x80)).hasBorder(0, 0, 80, 24);
138177
}
139178

179+
@Test
180+
void selectedHighlightNoTheme() {
181+
MenuItem menuItem = new MenuView.MenuItem("sub1");
182+
view = new MenuView(Arrays.asList(menuItem));
183+
view.setShowBorder(true);
184+
view.setRect(0, 0, 10, 7);
185+
view.draw(screen7x10);
186+
assertThat(forScreen(screen7x10)).hasStyle(1, 1, 1);
187+
assertThat(forScreen(screen7x10)).hasForegroundColor(1, 1, -1);
188+
assertThat(forScreen(screen7x10)).hasBackgroundColor(1, 1, -1);
189+
}
190+
191+
@Test
192+
void selectedHighlightThemeSet() {
193+
MenuItem menuItem = new MenuView.MenuItem("sub1");
194+
view = new MenuView(Arrays.asList(menuItem));
195+
view.setThemeResolver(themeResolver);
196+
view.setThemeName("default");
197+
view.setShowBorder(true);
198+
view.setRect(0, 0, 10, 7);
199+
view.draw(screen7x10);
200+
assertThat(forScreen(screen7x10)).hasStyle(1, 1, 5);
201+
assertThat(forScreen(screen7x10)).hasForegroundColor(1, 1, Color.RED);
202+
assertThat(forScreen(screen7x10)).hasBackgroundColor(1, 1, Color.BLUE);
203+
}
204+
140205
@Test
141206
void defaultItemCheckStyleIsNoCheck() {
142207
MenuItem menuItem = new MenuView.MenuItem("sub1");
143-
MenuView view = new MenuView(Arrays.asList(menuItem));
208+
view = new MenuView(Arrays.asList(menuItem));
144209
assertThat(view.getItems()).allSatisfy(item -> {
145210
assertThat(item.getCheckStyle()).isEqualTo(MenuItemCheckStyle.NOCHECK);
146211
});

spring-shell-samples/spring-shell-sample-catalog/src/main/java/org/springframework/shell/samples/catalog/Catalog.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ protected void drawBackground(Screen screen) {
235235
@Override
236236
protected void drawContent(Screen screen) {
237237
Rectangle rect = getRect();
238-
Writer writer = screen.writerBuilder().style(getStyle()).build();
238+
Writer writer = screen.writerBuilder().style(getStyle()).color(getForegroundColor()).build();
239239
writer.text(String.format("%-20s %s", getItem().name(), getItem().description()), rect.x(), rect.y());
240240
}
241241
}

0 commit comments

Comments
 (0)