Fix --noutf, fix onAction being called to many times, lot of small fixes
[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.i18n.Trans.StringId;
7 import be.nikiroo.jvcard.tui.StringUtils;
8 import be.nikiroo.jvcard.tui.UiColors;
9 import be.nikiroo.jvcard.tui.UiColors.Element;
10
11 import com.googlecode.lanterna.TextColor;
12 import com.googlecode.lanterna.gui2.AbstractListBox.ListItemRenderer;
13 import com.googlecode.lanterna.gui2.ActionListBox;
14 import com.googlecode.lanterna.gui2.Direction;
15 import com.googlecode.lanterna.gui2.LinearLayout;
16 import com.googlecode.lanterna.gui2.TextGUIGraphics;
17
18 abstract public class MainContentList extends MainContent implements Runnable {
19 private ActionListBox lines;
20
21 /**
22 * This class represent a part of a text line to draw in this
23 * {@link MainContentList}.
24 *
25 * @author niki
26 *
27 */
28 public class TextPart {
29 private String text;
30 private Element element;
31
32 public TextPart(String text, Element element) {
33 this.text = text;
34 this.element = element;
35 }
36
37 public String getText() {
38 return text;
39 }
40
41 public Element getElement() {
42 return element;
43 }
44
45 public TextColor getForegroundColor() {
46 if (element != null)
47 return element.getForegroundColor();
48 return Element.DEFAULT.getForegroundColor();
49 }
50
51 public TextColor getBackgroundColor() {
52 if (element != null)
53 return element.getBackgroundColor();
54 return Element.DEFAULT.getBackgroundColor();
55 }
56 }
57
58 public MainContentList(final UiColors.Element normalStyle,
59 final UiColors.Element selectedStyle) {
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 UiColors.getInstance().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 * Clear all the items in this {@link MainContentList}
130 */
131 public void clearItems() {
132 lines.clearItems();
133 }
134
135 /**
136 * Get the index of the currently selected line.
137 *
138 * @return the index
139 */
140 public int getSelectedIndex() {
141 return lines.getSelectedIndex();
142 }
143
144 /**
145 * Change the index of the currently selected line.
146 *
147 * @param index
148 * the new index
149 */
150 public void setSelectedIndex(int index) {
151 lines.setSelectedIndex(index);
152 }
153
154 /**
155 * Return the default content separator for text fields.
156 *
157 * @return the separator
158 */
159 public String getSeparator() {
160 return StringId.DEAULT_FIELD_SEPARATOR.trans();
161 }
162
163 @Override
164 public void run() {
165 // item selected.
166 // ignore.
167 }
168
169 @Override
170 public String move(int x, int y) {
171 setSelectedIndex(getSelectedIndex() + x);
172 // TODO: y?
173 return null;
174 }
175
176 @Override
177 public int getCount() {
178 return lines.getItemCount();
179 }
180
181 /**
182 * Return the representation of the selected line, in {@link TextPart}s.
183 *
184 * @param index
185 * the line index
186 * @param width
187 * the max width of the line
188 * @param selected
189 * TRUE if the item is selected
190 * @param focused
191 * TRUE if the item is focused
192 *
193 * @return the text representation
194 */
195 protected List<TextPart> getLabel(int index, int width, boolean selected,
196 boolean focused) {
197 List<TextPart> parts = new LinkedList<TextPart>();
198
199 if (selected && focused) {
200 parts.add(new TextPart("" + lines.getItems().get(index),
201 Element.CONTACT_LINE_SELECTED));
202 } else {
203 parts.add(new TextPart("" + lines.getItems().get(index),
204 Element.CONTACT_LINE));
205 }
206
207 return parts;
208 }
209 }