Update lanterna, fix bugs, implement save...
[jvcard.git] / src / be / nikiroo / jvcard / tui / panes / MainContentList.java
1 package be.nikiroo.jvcard.tui.panes;
2
3 import java.util.LinkedList;
4 import java.util.List;
5
6 import be.nikiroo.jvcard.tui.UiColors;
7 import be.nikiroo.jvcard.tui.UiColors.Element;
8
9 import com.googlecode.lanterna.TextColor;
10 import com.googlecode.lanterna.gui2.ActionListBox;
11 import com.googlecode.lanterna.gui2.Direction;
12 import com.googlecode.lanterna.gui2.LinearLayout;
13 import com.googlecode.lanterna.gui2.TextGUIGraphics;
14 import com.googlecode.lanterna.gui2.AbstractListBox.ListItemRenderer;
15
16 abstract public class MainContentList extends MainContent implements Runnable {
17 private ActionListBox lines;
18
19 /**
20 * This class represent a part of a text line to draw in this
21 * {@link MainContentList}.
22 *
23 * @author niki
24 *
25 */
26 public class TextPart {
27 private String text;
28 private Element element;
29
30 public TextPart(String text, Element element) {
31 this.text = text;
32 this.element = element;
33 }
34
35 public String getText() {
36 return text;
37 }
38
39 public Element getElement() {
40 return element;
41 }
42
43 public TextColor getForegroundColor() {
44 if (element != null)
45 return element.getForegroundColor();
46 return Element.DEFAULT.getForegroundColor();
47 }
48
49 public TextColor getBackgroundColor() {
50 if (element != null)
51 return element.getBackgroundColor();
52 return Element.DEFAULT.getBackgroundColor();
53 }
54 }
55
56 public MainContentList(final UiColors.Element normalStyle,
57 final UiColors.Element selectedStyle) {
58 super(Direction.VERTICAL);
59
60 lines = new ActionListBox();
61
62 lines
63 .setListItemRenderer(new ListItemRenderer<Runnable, ActionListBox>() {
64 /**
65 * This is the main drawing method for a single list box
66 * item, it applies the current theme to setup the colors
67 * and then calls {@code getLabel(..)} and draws the result
68 * using the supplied {@code TextGUIGraphics}. The graphics
69 * object is created just for this item and is restricted so
70 * that it can only draw on the area this item is occupying.
71 * The top-left corner (0x0) should be the starting point
72 * when drawing the item.
73 *
74 * @param graphics
75 * Graphics object to draw with
76 * @param listBox
77 * List box we are drawing an item from
78 * @param index
79 * Index of the item we are drawing
80 * @param item
81 * The item we are drawing
82 * @param selected
83 * Will be set to {@code true} if the item is
84 * currently selected, otherwise {@code false},
85 * but please notice what context 'selected'
86 * refers to here (see {@code setSelectedIndex})
87 * @param focused
88 * Will be set to {@code true} if the list box
89 * currently has input focus, otherwise {@code
90 * false}
91 */
92 public void drawItem(TextGUIGraphics graphics,
93 ActionListBox listBox, int index, Runnable item,
94 boolean selected, boolean focused) {
95
96 // width "-1" to reserve space for the optional vertical
97 // scroll bar
98 List<TextPart> parts = MainContentList.this.getLabel(
99 index, lines.getSize().getColumns() - 1,
100 selected, focused);
101
102 int position = 0;
103 for (TextPart part : parts) {
104 graphics.setForegroundColor(part
105 .getForegroundColor());
106 graphics.setBackgroundColor(part
107 .getBackgroundColor());
108 String label = part.getText();
109
110 graphics.putString(position, 0, label);
111 position += label.length();
112 }
113 }
114 });
115
116 addComponent(lines, LinearLayout
117 .createLayoutData(LinearLayout.Alignment.Fill));
118 }
119
120 /**
121 * Add an item to this {@link MainContentList}.
122 *
123 * @param line
124 * the item to add
125 */
126 public void addItem(String line) {
127 lines.addItem(line, this);
128 }
129
130 /**
131 * Clear all the items in this {@link MainContentList}
132 */
133 public void clearItems() {
134 lines.clearItems();
135 }
136
137 /**
138 * Get the index of the currently selected line.
139 *
140 * @return the index
141 */
142 public int getSelectedIndex() {
143 return lines.getSelectedIndex();
144 }
145
146 /**
147 * Change the index of the currently selected line.
148 *
149 * @param index
150 * the new index
151 */
152 public void setSelectedIndex(int index) {
153 lines.setSelectedIndex(index);
154 }
155
156
157 /**
158 * Return the default content separator for text fields.
159 *
160 * @return the separator
161 */
162 public String getSeparator() {
163 // we could use: " ", "┃", "│"...
164 return "┃";
165 }
166
167 @Override
168 public void run() {
169 // item selected.
170 // ignore.
171 }
172
173 @Override
174 public String move(int x, int y) {
175 setSelectedIndex(getSelectedIndex() + x);
176 // TODO: y?
177 return null;
178 }
179
180 @Override
181 public int getCount() {
182 return lines.getItemCount();
183 }
184
185 /**
186 * Return the representation of the selected line, in {@link TextPart}s.
187 *
188 * @param index
189 * the line index
190 * @param width
191 * the max width of the line
192 * @param selected
193 * TRUE if the item is selected
194 * @param focused
195 * TRUE if the item is focused
196 *
197 * @return the text representation
198 */
199 protected List<TextPart> getLabel(int index, int width, boolean selected,
200 boolean focused) {
201 List<TextPart> parts = new LinkedList<TextPart>();
202
203 if (selected && focused) {
204 parts.add(new TextPart("" + lines.getItems().get(index),
205 Element.CONTACT_LINE_SELECTED));
206 } else {
207 parts.add(new TextPart("" + lines.getItems().get(index),
208 Element.CONTACT_LINE));
209 }
210
211 return parts;
212 }
213 }