Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.codejive.twinkle.core.widget;

import org.codejive.twinkle.core.text.Canvas;
import org.codejive.twinkle.util.StyledIterator;

public interface StringWidget extends Widget {

CharSequence render();

default void render(Canvas canvas) {
StyledIterator iter = StyledIterator.of(render());
int y = 0;
while (iter.hasNext()) {
canvas.putStringAt(0, y++, iter);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.codejive.twinkle.widgets.list;

import org.codejive.twinkle.core.util.Size;
import org.codejive.twinkle.core.widget.StringWidget;
import org.codejive.twinkle.util.Printable;
import org.jspecify.annotations.NonNull;

public class List implements StringWidget {
private @NonNull ListModel list;
private @NonNull ListRenderer renderer;

protected List(@NonNull ListModel list, @NonNull ListRenderer renderer) {
this.list = list;
this.renderer = renderer;
}

@Override
public @NonNull Size size() {
return null;
}

@Override
public CharSequence render() {
return renderer.render(list, 0, list.items().size());
}

public static @NonNull List create() {
return new List(ListModel.ofStrings(), ListRenderer.create());
}

public static @NonNull List ofStrings(String... texts) {
return new List(ListModel.ofStrings(texts), ListRenderer.create());
}

public static @NonNull List ofPrintables(Printable... texts) {
return new List(ListModel.ofPrintables(texts), ListRenderer.create());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.codejive.twinkle.widgets.list;

import org.codejive.twinkle.ansi.Color;
import org.codejive.twinkle.ansi.Style;
import org.jspecify.annotations.NonNull;

public class ListConfig {
public @NonNull Color listbackgroundColor = Color.DEFAULT;
public @NonNull Style itemStyle = Style.DEFAULT;
public @NonNull Style selectedItemStyle = Style.INVERSE;
public @NonNull Style highlightedItemStyle = Style.FAINT;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.codejive.twinkle.widgets.list;

import org.codejive.twinkle.util.Printable;

public class ListItem {
public Printable content;
public boolean selected;
public boolean highlighted;

protected ListItem(Printable content, boolean selected, boolean highlighted) {
this.content = content;
this.selected = selected;
this.highlighted = highlighted;
}

public static ListItem of(Printable content) {
return new ListItem(content, false, false);
}

public static ListItem of(Printable content, boolean selected, boolean highlighted) {
return new ListItem(content, selected, highlighted);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package org.codejive.twinkle.widgets.list;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.codejive.twinkle.core.text.Line;
import org.codejive.twinkle.util.Printable;

public class ListModel {
private final List<ListItem> items;

public ListModel() {
this.items = new ArrayList<>();
}

public List<ListItem> items() {
return items;
}

public ListModel add(String text) {
items.add(ListItem.of(Line.of(text)));
return this;
}

public ListModel add(Printable text) {
items.add(ListItem.of(text));
return this;
}

public static ListModel ofStrings(String... texts) {
return ofStrings(Arrays.asList(texts));
}

public static ListModel ofStrings(List<String> texts) {
ListModel model = new ListModel();
for (String text : texts) {
model.add(text);
}
return model;
}

public static ListModel ofPrintables(Printable... texts) {
return ofPrintables(Arrays.asList(texts));
}

public static ListModel ofPrintables(List<Printable> texts) {
ListModel model = new ListModel();
for (Printable text : texts) {
model.add(text);
}
return model;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.codejive.twinkle.widgets.list;

import java.util.stream.Collectors;
import org.codejive.twinkle.ansi.Ansi;
import org.jspecify.annotations.NonNull;

public class ListRenderer {
private final @NonNull ListConfig config;

protected ListRenderer(@NonNull ListConfig config) {
this.config = config;
}

public CharSequence render(@NonNull ListModel list, int startIndex, int count) {
int endIndex = Math.min(startIndex + count, list.items().size());
return list.items().subList(startIndex, endIndex).stream()
.map(this::renderItem)
.collect(Collectors.joining("\n"));
}

public CharSequence renderItem(@NonNull ListItem item) {
String content =
Ansi.STYLE_RESET
+ config.listbackgroundColor.toAnsiBg()
+ config.itemStyle.toAnsiString();
if (item.selected) {
content += config.selectedItemStyle.toAnsiString();
}
if (item.highlighted) {
content += config.highlightedItemStyle.toAnsiString();
}
content += item.content.toAnsiString();
return content;
}

public static @NonNull ListRenderer create() {
return new ListRenderer(new ListConfig());
}
}
26 changes: 26 additions & 0 deletions twinkle-core/src/test/java/examples/ListDemo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// java
package examples;

import org.codejive.twinkle.ansi.Ansi;
import org.codejive.twinkle.core.text.Buffer;
import org.codejive.twinkle.core.text.Line;
import org.codejive.twinkle.widgets.Framed;
import org.codejive.twinkle.widgets.list.List;

public class ListDemo {
public static void main(String[] args) throws InterruptedException {
List l =
List.ofStrings(
"First Item", "Second Item", "Third Item", "Fourth Item", "Fifth Item");
Framed f = Framed.of(l).title(Line.of(" Simple List "));
Buffer buf = Buffer.of(42, 22);

System.out.print(Ansi.hideCursor());
try {
f.render(buf);
System.out.println(buf.toAnsiString());
} finally {
System.out.print(Ansi.showCursor());
}
}
}
Loading