Resources system rewrite + new "--save-config DIR" option
[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.launcher.Main;
7 import be.nikiroo.jvcard.resources.StringUtils;
8 import be.nikiroo.jvcard.resources.enums.ColorOption;
9 import be.nikiroo.jvcard.resources.enums.StringId;
10 import be.nikiroo.jvcard.tui.UiColors;
11
12 import com.googlecode.lanterna.TextColor;
13 import com.googlecode.lanterna.gui2.AbstractListBox.ListItemRenderer;
14 import com.googlecode.lanterna.gui2.ActionListBox;
15 import com.googlecode.lanterna.gui2.Direction;
16 import com.googlecode.lanterna.gui2.LinearLayout;
17 import com.googlecode.lanterna.gui2.TextGUIGraphics;
18
19 abstract public class MainContentList extends MainContent implements Runnable {
20 private ActionListBox lines;
21
22 /**
23 * This class represent a part of a text line to draw in this
24 * {@link MainContentList}.
25 *
26 * @author niki
27 *
28 */
29 public class TextPart {
30 private String text;
31 private ColorOption element;
32
33 public TextPart(String text, ColorOption element) {
34 this.text = text;
35 this.element = element;
36 }
37
38 public String getText() {
39 return text;
40 }
41
42 public ColorOption getElement() {
43 return element;
44 }
45
46 public TextColor getForegroundColor() {
47 if (element != null)
48 return UiColors.getForegroundColor(element);
49 return UiColors.getForegroundColor(ColorOption.DEFAULT);
50 }
51
52 public TextColor getBackgroundColor() {
53 if (element != null)
54 return UiColors.getBackgroundColor(element);
55 return UiColors.getBackgroundColor(ColorOption.DEFAULT);
56 }
57 }
58
59 public MainContentList() {
60 super(Direction.VERTICAL);
61
62 lines = new ActionListBox();
63
64 lines.setListItemRenderer(new ListItemRenderer<Runnable, ActionListBox>() {
65 /**
66 * This is the main drawing method for a single list box item, it
67 * applies the current theme to setup the colors and then calls
68 * {@code getLabel(..)} and draws the result using the supplied
69 * {@code TextGUIGraphics}. The graphics object is created just for
70 * this item and is restricted so that it can only draw on the area
71 * this item is occupying. The top-left corner (0x0) should be the
72 * starting point 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 currently
84 * selected, otherwise {@code false}, but please notice
85 * what context 'selected' refers to here (see
86 * {@code setSelectedIndex})
87 * @param focused
88 * Will be set to {@code true} if the list box currently
89 * has input focus, otherwise {@code false}
90 */
91 public void drawItem(TextGUIGraphics graphics,
92 ActionListBox listBox, int index, Runnable item,
93 boolean selected, boolean focused) {
94
95 // width "-1" to reserve space for the optional vertical
96 // scroll bar
97 List<TextPart> parts = MainContentList.this.getLabel(index,
98 lines.getSize().getColumns() - 1, selected, focused);
99
100 int position = 0;
101 for (TextPart part : parts) {
102 graphics.setForegroundColor(part.getForegroundColor());
103 graphics.setBackgroundColor(part.getBackgroundColor());
104
105 String label = StringUtils.sanitize(part.getText(),
106 Main.isUnicode());
107
108 graphics.putString(position, 0, label);
109 position += label.length();
110 }
111 }
112 });
113
114 addComponent(lines,
115 LinearLayout.createLayoutData(LinearLayout.Alignment.Fill));
116 }
117
118 /**
119 * Add an item to this {@link MainContentList}.
120 *
121 * @param line
122 * the item to add
123 */
124 public void addItem(String line) {
125 lines.addItem(line, this);
126 }
127
128 /**
129 * Delete the given item.
130 *
131 * Remark: it will only delete the first found instance if multiple
132 * instances of this item are present.
133 *
134 * @param line
135 * the line to delete
136 *
137 * @return TRUE if the item was deleted
138 */
139 public boolean removeItem(String line) {
140 boolean deleted = false;
141
142 List<Runnable> copy = lines.getItems();
143 for (int index = 0; index < copy.size(); index++) {
144 if (copy.get(index).toString().equals(line)) {
145 deleted = true;
146 copy.remove(index);
147 break;
148 }
149 }
150
151 int index = getSelectedIndex();
152 clearItems();
153 for (Runnable run : copy) {
154 addItem(run.toString());
155 }
156 setSelectedIndex(index);
157
158 return deleted;
159 }
160
161 /**
162 * Clear all the items in this {@link MainContentList}
163 */
164 public void clearItems() {
165 lines.clearItems();
166 }
167
168 /**
169 * Get the index of the currently selected line.
170 *
171 * @return the index
172 */
173 public int getSelectedIndex() {
174 return lines.getSelectedIndex();
175 }
176
177 /**
178 * Change the index of the currently selected line.
179 *
180 * @param index
181 * the new index
182 */
183 public void setSelectedIndex(int index) {
184 lines.setSelectedIndex(index);
185 }
186
187 /**
188 * Return the default content separator for text fields.
189 *
190 * @return the separator
191 */
192 public String getSeparator() {
193 return Main.trans(StringId.DEAULT_FIELD_SEPARATOR);
194 }
195
196 @Override
197 public void run() {
198 // item selected.
199 // ignore.
200 }
201
202 @Override
203 public String move(int x, int y) {
204 setSelectedIndex(getSelectedIndex() + x);
205 // TODO: y?
206 return null;
207 }
208
209 @Override
210 public int getCount() {
211 return lines.getItemCount();
212 }
213
214 /**
215 * Return the representation of the selected line, in {@link TextPart}s.
216 *
217 * @param index
218 * the line index
219 * @param width
220 * the max width of the line
221 * @param selected
222 * TRUE if the item is selected
223 * @param focused
224 * TRUE if the item is focused
225 *
226 * @return the text representation
227 */
228 protected List<TextPart> getLabel(int index, int width, boolean selected,
229 boolean focused) {
230 List<TextPart> parts = new LinkedList<TextPart>();
231
232 if (selected && focused) {
233 parts.add(new TextPart("" + lines.getItems().get(index),
234 ColorOption.CONTACT_LINE_SELECTED));
235 } else {
236 parts.add(new TextPart("" + lines.getItems().get(index),
237 ColorOption.CONTACT_LINE));
238 }
239
240 return parts;
241 }
242 }