TEditor 50% complete
[nikiroo-utils.git] / src / jexer / teditor / Line.java
1 /*
2 * Jexer - Java Text User Interface
3 *
4 * The MIT License (MIT)
5 *
6 * Copyright (C) 2017 Kevin Lamonte
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 *
26 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
27 * @version 1
28 */
29 package jexer.teditor;
30
31 import java.util.ArrayList;
32 import java.util.List;
33
34 import jexer.bits.CellAttributes;
35
36 /**
37 * A Line represents a single line of text on the screen, as a collection of
38 * words.
39 */
40 public class Line {
41
42 /**
43 * The list of words.
44 */
45 private ArrayList<Word> words = new ArrayList<Word>();
46
47 /**
48 * The default color for the TEditor class.
49 */
50 private CellAttributes defaultColor = null;
51
52 /**
53 * The text highlighter to use.
54 */
55 private Highlighter highlighter = null;
56
57 /**
58 * The current cursor position on this line.
59 */
60 private int cursor = 0;
61
62 /**
63 * The current word that the cursor position is in.
64 */
65 private Word currentWord;
66
67 /**
68 * We use getDisplayLength() a lot, so cache the value.
69 */
70 private int displayLength = -1;
71
72 /**
73 * Get the current cursor position.
74 *
75 * @return the cursor position
76 */
77 public int getCursor() {
78 return cursor;
79 }
80
81 /**
82 * Set the current cursor position.
83 *
84 * @param cursor the new cursor position
85 */
86 public void setCursor(final int cursor) {
87 if ((cursor < 0)
88 || ((cursor >= getDisplayLength())
89 && (getDisplayLength() > 0))
90 ) {
91 throw new IndexOutOfBoundsException("Max length is " +
92 getDisplayLength() + ", requested position " + cursor);
93 }
94 this.cursor = cursor;
95 // TODO: set word
96 }
97
98 /**
99 * Get a (shallow) copy of the list of words.
100 *
101 * @return the list of words
102 */
103 public List<Word> getWords() {
104 return new ArrayList<Word>(words);
105 }
106
107 /**
108 * Get the on-screen display length.
109 *
110 * @return the number of cells needed to display this line
111 */
112 public int getDisplayLength() {
113 if (displayLength != -1) {
114 return displayLength;
115 }
116 int n = 0;
117 for (Word word: words) {
118 n += word.getDisplayLength();
119 }
120 displayLength = n;
121
122 // If we have any visible characters, add one to the display so that
123 // the cursor is immediately after the data.
124 if (displayLength > 0) {
125 displayLength++;
126 }
127 return displayLength;
128 }
129
130 /**
131 * Construct a new Line from an existing text string, and highlight
132 * certain strings.
133 *
134 * @param str the text string
135 * @param defaultColor the color for unhighlighted text
136 * @param highlighter the highlighter to use
137 */
138 public Line(final String str, final CellAttributes defaultColor,
139 final Highlighter highlighter) {
140
141 this.defaultColor = defaultColor;
142 this.highlighter = highlighter;
143
144 currentWord = new Word(this.defaultColor, this.highlighter);
145 words.add(currentWord);
146 for (int i = 0; i < str.length(); i++) {
147 char ch = str.charAt(i);
148 Word newWord = currentWord.addChar(ch);
149 if (newWord != currentWord) {
150 words.add(newWord);
151 currentWord = newWord;
152 }
153 }
154 for (Word word: words) {
155 word.applyHighlight();
156 }
157 }
158
159 /**
160 * Construct a new Line from an existing text string.
161 *
162 * @param str the text string
163 * @param defaultColor the color for unhighlighted text
164 */
165 public Line(final String str, final CellAttributes defaultColor) {
166 this(str, defaultColor, null);
167 }
168
169 /**
170 * Decrement the cursor by one. If at the first column, do nothing.
171 *
172 * @return true if the cursor position changed
173 */
174 public boolean left() {
175 if (cursor == 0) {
176 return false;
177 }
178 // TODO: switch word
179 cursor--;
180 return true;
181 }
182
183 /**
184 * Increment the cursor by one. If at the last column, do nothing.
185 *
186 * @return true if the cursor position changed
187 */
188 public boolean right() {
189 if (getDisplayLength() == 0) {
190 return false;
191 }
192 if (cursor == getDisplayLength() - 1) {
193 return false;
194 }
195 // TODO: switch word
196 cursor++;
197 return true;
198 }
199
200 /**
201 * Go to the first column of this line.
202 *
203 * @return true if the cursor position changed
204 */
205 public boolean home() {
206 if (cursor > 0) {
207 cursor = 0;
208 currentWord = words.get(0);
209 return true;
210 }
211 return false;
212 }
213
214 /**
215 * Go to the last column of this line.
216 *
217 * @return true if the cursor position changed
218 */
219 public boolean end() {
220 if (cursor != getDisplayLength() - 1) {
221 cursor = getDisplayLength() - 1;
222 if (cursor < 0) {
223 cursor = 0;
224 }
225 currentWord = words.get(words.size() - 1);
226 return true;
227 }
228 return false;
229 }
230
231 /**
232 * Delete the character under the cursor.
233 */
234 public void del() {
235 // TODO
236 }
237
238 /**
239 * Delete the character immediately preceeding the cursor.
240 */
241 public void backspace() {
242 // TODO
243 }
244
245 /**
246 * Insert a character at the cursor.
247 *
248 * @param ch the character to insert
249 */
250 public void addChar(final char ch) {
251 // TODO
252 }
253
254 /**
255 * Replace a character at the cursor.
256 *
257 * @param ch the character to replace
258 */
259 public void replaceChar(final char ch) {
260 // TODO
261 }
262
263 }