Skip to content

Commit 9021238

Browse files
committed
Overhaul StatusBar for better text use
- Can change item text - Can position items by priority(true left, false right) and primary(sort for draw attempt) - Fixes #1112
1 parent 02011c8 commit 9021238

File tree

2 files changed

+276
-6
lines changed

2 files changed

+276
-6
lines changed

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

Lines changed: 107 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.
@@ -17,30 +17,39 @@
1717

1818
import java.util.ArrayList;
1919
import java.util.Arrays;
20+
import java.util.Collections;
2021
import java.util.List;
2122
import java.util.ListIterator;
2223

2324
import org.slf4j.Logger;
2425
import org.slf4j.LoggerFactory;
2526

27+
import org.springframework.lang.Nullable;
2628
import org.springframework.shell.component.message.ShellMessageBuilder;
2729
import org.springframework.shell.component.view.event.MouseEvent;
2830
import org.springframework.shell.component.view.event.MouseHandler;
2931
import org.springframework.shell.component.view.screen.Screen;
3032
import org.springframework.shell.component.view.screen.Screen.Writer;
3133
import org.springframework.shell.geom.Rectangle;
3234
import org.springframework.shell.style.StyleSettings;
35+
import org.springframework.util.StringUtils;
3336

3437
/**
3538
* {@link StatusBarView} shows {@link StatusItem items} horizontally and is
3639
* typically used in layouts which builds complete terminal UI's.
3740
*
41+
* {@link StatusItem item} {@code primary} denotes if item is drawn to left
42+
* or right, {@code priority} on which order items are drawn until bar runs
43+
* out of space. Default {@code primary} is {@code true} and {@code priority}
44+
* is {@code 0}.
45+
*
3846
* @author Janne Valkealahti
3947
*/
4048
public class StatusBarView extends BoxView {
4149

4250
private final Logger log = LoggerFactory.getLogger(StatusBarView.class);
4351
private final List<StatusItem> items = new ArrayList<>();
52+
private String itemSeparator = " | ";
4453

4554
public StatusBarView() {
4655
this(new StatusItem[0]);
@@ -59,18 +68,64 @@ protected String getBackgroundStyle() {
5968
return StyleSettings.TAG_STATUSBAR_BACKGROUND;
6069
}
6170

71+
/**
72+
* Gets the item separator.
73+
*
74+
* @return a separator
75+
*/
76+
@Nullable
77+
public String getItemSeparator() {
78+
return itemSeparator;
79+
}
80+
81+
/**
82+
* Sets the item separator. Separator can be {@code null} or empty which
83+
* essentially disables it.
84+
*
85+
* @param itemSeparator the item separator
86+
*/
87+
public void setItemSeparator(@Nullable String itemSeparator) {
88+
this.itemSeparator = itemSeparator;
89+
}
90+
6291
@Override
6392
protected void drawInternal(Screen screen) {
6493
Rectangle rect = getInnerRect();
6594
log.debug("Drawing status bar to {}", rect);
6695
Writer writer = screen.writerBuilder().build();
67-
int x = rect.x();
96+
97+
int primaryX = rect.x();
98+
int nonprimaryX = rect.x() + rect.width();
99+
boolean primaryWritten = false;
100+
boolean nonprimaryWritten = false;
101+
68102
ListIterator<StatusItem> iter = items.listIterator();
69103
while (iter.hasNext()) {
70104
StatusItem item = iter.next();
71-
String text = String.format(" %s%s", item.getTitle(), iter.hasNext() ? " |" : "");
72-
writer.text(text, x, rect.y());
73-
x += text.length();
105+
String text = item.getTitle();
106+
if (text == null) {
107+
continue;
108+
}
109+
String sep = getItemSeparator();
110+
if (nonprimaryX - primaryX < (text.length() + (sep != null ? sep.length() : 0))) {
111+
break;
112+
}
113+
if (item.primary) {
114+
if (primaryWritten && StringUtils.hasText(sep)) {
115+
text = sep + text;
116+
}
117+
writer.text(text, primaryX, rect.y());
118+
primaryX += text.length();
119+
primaryWritten = true;
120+
}
121+
else {
122+
if (nonprimaryWritten && StringUtils.hasText(sep)) {
123+
text = text + sep;
124+
}
125+
writer.text(text, nonprimaryX - text.length(), rect.y());
126+
nonprimaryX -= text.length();
127+
nonprimaryWritten = true;
128+
}
74129
}
75130
super.drawInternal(screen);
76131
}
@@ -121,6 +176,19 @@ private StatusItem itemAt(int x, int y) {
121176
public void setItems(List<StatusItem> items) {
122177
this.items.clear();
123178
this.items.addAll(items);
179+
Collections.sort(this.items, (o1, o2) -> {
180+
int ret = o1.priority - o2.priority;
181+
if (ret == 0) {
182+
if (o1.primary && !o2.primary) {
183+
ret = -1;
184+
}
185+
else if (!o1.primary && o2.primary) {
186+
ret = 1;
187+
}
188+
}
189+
return ret;
190+
});
191+
// this.items.sort(null);
124192
registerHotKeys();
125193
}
126194

@@ -152,6 +220,8 @@ public static class StatusItem {
152220
private String title;
153221
private Runnable action;
154222
private Integer hotKey;
223+
private boolean primary = true;
224+
private int priority = 0;
155225

156226
public StatusItem(String title) {
157227
this(title, null);
@@ -167,6 +237,14 @@ public StatusItem(String title, Runnable action, Integer hotKey) {
167237
this.hotKey = hotKey;
168238
}
169239

240+
public StatusItem(String title, Runnable action, Integer hotKey, boolean primary, int priority) {
241+
this.title = title;
242+
this.action = action;
243+
this.hotKey = hotKey;
244+
this.primary = primary;
245+
this.priority = priority;
246+
}
247+
170248
public static StatusItem of(String title) {
171249
return new StatusItem(title);
172250
}
@@ -179,10 +257,18 @@ public static StatusItem of(String title, Runnable action, Integer hotKey) {
179257
return new StatusItem(title, action, hotKey);
180258
}
181259

260+
public static StatusItem of(String title, Runnable action, Integer hotKey, boolean primary, int priority) {
261+
return new StatusItem(title, action, hotKey, primary, priority);
262+
}
263+
182264
public String getTitle() {
183265
return title;
184266
}
185267

268+
public void setTitle(String title) {
269+
this.title = title;
270+
}
271+
186272
public Runnable getAction() {
187273
return action;
188274
}
@@ -201,6 +287,22 @@ public StatusItem setHotKey(Integer hotKey) {
201287
return this;
202288
}
203289

290+
public int getPriority() {
291+
return priority;
292+
}
293+
294+
public void setPriority(int priority) {
295+
this.priority = priority;
296+
}
297+
298+
public boolean isPrimary() {
299+
return primary;
300+
}
301+
302+
public void setPrimary(boolean primary) {
303+
this.primary = primary;
304+
}
305+
204306
}
205307

206308
/**

0 commit comments

Comments
 (0)