Commit | Line | Data |
---|---|---|
cd92b0ba KL |
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 | ||
e8a11f98 KL |
34 | import jexer.bits.CellAttributes; |
35 | ||
cd92b0ba | 36 | /** |
12b55d76 KL |
37 | * A Line represents a single line of text on the screen, as a collection of |
38 | * words. | |
cd92b0ba | 39 | */ |
12b55d76 | 40 | public class Line { |
cd92b0ba KL |
41 | |
42 | /** | |
12b55d76 | 43 | * The list of words. |
cd92b0ba | 44 | */ |
12b55d76 | 45 | private ArrayList<Word> words = new ArrayList<Word>(); |
cd92b0ba | 46 | |
e8a11f98 KL |
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 | ||
cd92b0ba | 57 | /** |
12b55d76 | 58 | * The current cursor position on this line. |
cd92b0ba | 59 | */ |
e8a11f98 | 60 | private int cursor = 0; |
cd92b0ba KL |
61 | |
62 | /** | |
12b55d76 | 63 | * The current word that the cursor position is in. |
cd92b0ba | 64 | */ |
12b55d76 | 65 | private Word currentWord; |
cd92b0ba KL |
66 | |
67 | /** | |
12b55d76 | 68 | * We use getDisplayLength() a lot, so cache the value. |
cd92b0ba | 69 | */ |
12b55d76 | 70 | private int displayLength = -1; |
cd92b0ba | 71 | |
e8a11f98 KL |
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 | ||
cd92b0ba | 98 | /** |
12b55d76 | 99 | * Get a (shallow) copy of the list of words. |
cd92b0ba | 100 | * |
12b55d76 | 101 | * @return the list of words |
cd92b0ba | 102 | */ |
12b55d76 KL |
103 | public List<Word> getWords() { |
104 | return new ArrayList<Word>(words); | |
cd92b0ba KL |
105 | } |
106 | ||
107 | /** | |
12b55d76 | 108 | * Get the on-screen display length. |
cd92b0ba | 109 | * |
12b55d76 | 110 | * @return the number of cells needed to display this line |
cd92b0ba | 111 | */ |
12b55d76 KL |
112 | public int getDisplayLength() { |
113 | if (displayLength != -1) { | |
114 | return displayLength; | |
cd92b0ba | 115 | } |
12b55d76 KL |
116 | int n = 0; |
117 | for (Word word: words) { | |
118 | n += word.getDisplayLength(); | |
cd92b0ba | 119 | } |
12b55d76 | 120 | displayLength = n; |
e8a11f98 KL |
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 | } | |
12b55d76 | 127 | return displayLength; |
cd92b0ba KL |
128 | } |
129 | ||
130 | /** | |
e8a11f98 KL |
131 | * Construct a new Line from an existing text string, and highlight |
132 | * certain strings. | |
cd92b0ba | 133 | * |
12b55d76 | 134 | * @param str the text string |
e8a11f98 KL |
135 | * @param defaultColor the color for unhighlighted text |
136 | * @param highlighter the highlighter to use | |
12b55d76 | 137 | */ |
e8a11f98 KL |
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); | |
12b55d76 KL |
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 | } | |
cd92b0ba | 153 | } |
e8a11f98 KL |
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); | |
cd92b0ba KL |
167 | } |
168 | ||
169 | /** | |
12b55d76 | 170 | * Decrement the cursor by one. If at the first column, do nothing. |
e8a11f98 KL |
171 | * |
172 | * @return true if the cursor position changed | |
cd92b0ba | 173 | */ |
e8a11f98 KL |
174 | public boolean left() { |
175 | if (cursor == 0) { | |
176 | return false; | |
cd92b0ba | 177 | } |
e8a11f98 KL |
178 | // TODO: switch word |
179 | cursor--; | |
180 | return true; | |
cd92b0ba KL |
181 | } |
182 | ||
183 | /** | |
12b55d76 | 184 | * Increment the cursor by one. If at the last column, do nothing. |
e8a11f98 KL |
185 | * |
186 | * @return true if the cursor position changed | |
cd92b0ba | 187 | */ |
e8a11f98 KL |
188 | public boolean right() { |
189 | if (getDisplayLength() == 0) { | |
190 | return false; | |
cd92b0ba | 191 | } |
e8a11f98 KL |
192 | if (cursor == getDisplayLength() - 1) { |
193 | return false; | |
194 | } | |
195 | // TODO: switch word | |
196 | cursor++; | |
197 | return true; | |
cd92b0ba KL |
198 | } |
199 | ||
200 | /** | |
12b55d76 | 201 | * Go to the first column of this line. |
e8a11f98 KL |
202 | * |
203 | * @return true if the cursor position changed | |
cd92b0ba | 204 | */ |
e8a11f98 KL |
205 | public boolean home() { |
206 | if (cursor > 0) { | |
207 | cursor = 0; | |
208 | currentWord = words.get(0); | |
209 | return true; | |
210 | } | |
211 | return false; | |
cd92b0ba KL |
212 | } |
213 | ||
214 | /** | |
12b55d76 | 215 | * Go to the last column of this line. |
e8a11f98 KL |
216 | * |
217 | * @return true if the cursor position changed | |
cd92b0ba | 218 | */ |
e8a11f98 KL |
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; | |
cd92b0ba KL |
229 | } |
230 | ||
231 | /** | |
12b55d76 | 232 | * Delete the character under the cursor. |
cd92b0ba | 233 | */ |
12b55d76 KL |
234 | public void del() { |
235 | // TODO | |
cd92b0ba KL |
236 | } |
237 | ||
238 | /** | |
12b55d76 | 239 | * Delete the character immediately preceeding the cursor. |
cd92b0ba | 240 | */ |
12b55d76 KL |
241 | public void backspace() { |
242 | // TODO | |
cd92b0ba KL |
243 | } |
244 | ||
245 | /** | |
e8a11f98 | 246 | * Insert a character at the cursor. |
cd92b0ba | 247 | * |
e8a11f98 | 248 | * @param ch the character to insert |
cd92b0ba | 249 | */ |
12b55d76 KL |
250 | public void addChar(final char ch) { |
251 | // TODO | |
cd92b0ba KL |
252 | } |
253 | ||
e8a11f98 KL |
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 | ||
cd92b0ba | 263 | } |