Fix UTF8 bug, create first executable JAR file
[jvcard.git] / src / com / googlecode / lanterna / gui2 / Borders.java
... / ...
CommitLineData
1/*
2 * This file is part of lanterna (http://code.google.com/p/lanterna/).
3 *
4 * lanterna is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Copyright (C) 2010-2015 Martin
18 */
19package com.googlecode.lanterna.gui2;
20
21import com.googlecode.lanterna.*;
22import com.googlecode.lanterna.graphics.TextGraphics;
23
24import java.util.Arrays;
25import java.util.List;
26
27/**
28 * This class containers a couple of border implementation and utility methods for instantiating them. It also contains
29 * a utility method for joining border line graphics together with adjacent lines so they blend in together:
30 * {@code joinLinesWithFrame(..)}.
31 * @author Martin
32 */
33public class Borders {
34 private Borders() {
35 }
36
37 //Different ways to draw the border
38 private enum BorderStyle {
39 Solid,
40 Bevel,
41 ReverseBevel,
42 }
43
44 /**
45 * Creates a {@code Border} that is drawn as a solid color single line surrounding the wrapped component
46 * @return New solid color single line {@code Border}
47 */
48 public static Border singleLine() {
49 return singleLine("");
50 }
51
52 /**
53 * Creates a {@code Border} that is drawn as a solid color single line surrounding the wrapped component with a
54 * title string normally drawn at the top-left side
55 * @param title The title to draw on the border
56 * @return New solid color single line {@code Border} with a title
57 */
58 public static Border singleLine(String title) {
59 return new SingleLine(title, BorderStyle.Solid);
60 }
61
62 /**
63 * Creates a {@code Border} that is drawn as a bevel color single line surrounding the wrapped component
64 * @return New bevel color single line {@code Border}
65 */
66 public static Border singleLineBevel() {
67 return singleLineBevel("");
68 }
69
70 /**
71 * Creates a {@code Border} that is drawn as a bevel color single line surrounding the wrapped component with a
72 * title string normally drawn at the top-left side
73 * @param title The title to draw on the border
74 * @return New bevel color single line {@code Border} with a title
75 */
76 public static Border singleLineBevel(String title) {
77 return new SingleLine(title, BorderStyle.Bevel);
78 }
79
80 /**
81 * Creates a {@code Border} that is drawn as a reverse bevel color single line surrounding the wrapped component
82 * @return New reverse bevel color single line {@code Border}
83 */
84 public static Border singleLineReverseBevel() {
85 return singleLineReverseBevel("");
86 }
87
88 /**
89 * Creates a {@code Border} that is drawn as a reverse bevel color single line surrounding the wrapped component
90 * with a title string normally drawn at the top-left side
91 * @param title The title to draw on the border
92 * @return New reverse bevel color single line {@code Border} with a title
93 */
94 public static Border singleLineReverseBevel(String title) {
95 return new SingleLine(title, BorderStyle.ReverseBevel);
96 }
97
98 /**
99 * Creates a {@code Border} that is drawn as a solid color double line surrounding the wrapped component
100 * @return New solid color double line {@code Border}
101 */
102 public static Border doubleLine() {
103 return doubleLine("");
104 }
105
106 /**
107 * Creates a {@code Border} that is drawn as a solid color double line surrounding the wrapped component with a
108 * title string normally drawn at the top-left side
109 * @param title The title to draw on the border
110 * @return New solid color double line {@code Border} with a title
111 */
112 public static Border doubleLine(String title) {
113 return new DoubleLine(title, BorderStyle.Solid);
114 }
115
116 /**
117 * Creates a {@code Border} that is drawn as a bevel color double line surrounding the wrapped component
118 * @return New bevel color double line {@code Border}
119 */
120 public static Border doubleLineBevel() {
121 return doubleLineBevel("");
122 }
123
124 /**
125 * Creates a {@code Border} that is drawn as a bevel color double line surrounding the wrapped component with a
126 * title string normally drawn at the top-left side
127 * @param title The title to draw on the border
128 * @return New bevel color double line {@code Border} with a title
129 */
130 public static Border doubleLineBevel(String title) {
131 return new DoubleLine(title, BorderStyle.Bevel);
132 }
133
134 /**
135 * Creates a {@code Border} that is drawn as a reverse bevel color double line surrounding the wrapped component
136 * @return New reverse bevel color double line {@code Border}
137 */
138 public static Border doubleLineReverseBevel() {
139 return doubleLineReverseBevel("");
140 }
141
142 /**
143 * Creates a {@code Border} that is drawn as a reverse bevel color double line surrounding the wrapped component
144 * with a title string normally drawn at the top-left side
145 * @param title The title to draw on the border
146 * @return New reverse bevel color double line {@code Border} with a title
147 */
148 public static Border doubleLineReverseBevel(String title) {
149 return new DoubleLine(title, BorderStyle.ReverseBevel);
150 }
151
152 private static abstract class StandardBorder extends AbstractBorder {
153 private final String title;
154 protected final BorderStyle borderStyle;
155
156 protected StandardBorder(String title, BorderStyle borderStyle) {
157 if (title == null) {
158 throw new IllegalArgumentException("Cannot create a border with null title");
159 }
160 this.borderStyle = borderStyle;
161 this.title = title;
162 }
163
164 public String getTitle() {
165 return title;
166 }
167
168 @Override
169 public String toString() {
170 return getClass().getSimpleName() + "{" + title + "}";
171 }
172 }
173
174 private static abstract class AbstractBorderRenderer implements Border.BorderRenderer {
175 private final BorderStyle borderStyle;
176
177 protected AbstractBorderRenderer(BorderStyle borderStyle) {
178 this.borderStyle = borderStyle;
179 }
180
181 @Override
182 public TerminalSize getPreferredSize(Border component) {
183 StandardBorder border = (StandardBorder)component;
184 Component wrappedComponent = border.getComponent();
185 TerminalSize preferredSize;
186 if (wrappedComponent == null) {
187 preferredSize = TerminalSize.ZERO;
188 } else {
189 preferredSize = wrappedComponent.getPreferredSize();
190 }
191 preferredSize = preferredSize.withRelativeColumns(2).withRelativeRows(2);
192 String borderTitle = border.getTitle();
193 return preferredSize.max(new TerminalSize((borderTitle.isEmpty() ? 2 : TerminalTextUtils.getColumnWidth(borderTitle) + 4), 2));
194 }
195
196 @Override
197 public TerminalPosition getWrappedComponentTopLeftOffset() {
198 return TerminalPosition.OFFSET_1x1;
199 }
200
201 @Override
202 public TerminalSize getWrappedComponentSize(TerminalSize borderSize) {
203 return borderSize
204 .withRelativeColumns(-Math.min(2, borderSize.getColumns()))
205 .withRelativeRows(-Math.min(2, borderSize.getRows()));
206 }
207
208 @Override
209 public void drawComponent(TextGUIGraphics graphics, Border component) {
210 StandardBorder border = (StandardBorder)component;
211 Component wrappedComponent = border.getComponent();
212 if(wrappedComponent == null) {
213 return;
214 }
215 TerminalSize drawableArea = graphics.getSize();
216
217 char horizontalLine = getHorizontalLine(graphics);
218 char verticalLine = getVerticalLine(graphics);
219 char bottomLeftCorner = getBottomLeftCorner(graphics);
220 char topLeftCorner = getTopLeftCorner(graphics);
221 char bottomRightCorner = getBottomRightCorner(graphics);
222 char topRightCorner = getTopRightCorner(graphics);
223
224 if(borderStyle == BorderStyle.Bevel) {
225 graphics.applyThemeStyle(graphics.getThemeDefinition(StandardBorder.class).getPreLight());
226 }
227 else {
228 graphics.applyThemeStyle(graphics.getThemeDefinition(StandardBorder.class).getNormal());
229 }
230 graphics.setCharacter(0, drawableArea.getRows() - 1, bottomLeftCorner);
231 if(drawableArea.getRows() > 2) {
232 graphics.drawLine(new TerminalPosition(0, drawableArea.getRows() - 2), new TerminalPosition(0, 1), verticalLine);
233 }
234 graphics.setCharacter(0, 0, topLeftCorner);
235 if(drawableArea.getColumns() > 2) {
236 graphics.drawLine(new TerminalPosition(1, 0), new TerminalPosition(drawableArea.getColumns() - 2, 0), horizontalLine);
237 }
238
239 if(borderStyle == BorderStyle.ReverseBevel) {
240 graphics.applyThemeStyle(graphics.getThemeDefinition(StandardBorder.class).getPreLight());
241 }
242 else {
243 graphics.applyThemeStyle(graphics.getThemeDefinition(StandardBorder.class).getNormal());
244 }
245 graphics.setCharacter(drawableArea.getColumns() - 1, 0, topRightCorner);
246 if(drawableArea.getRows() > 2) {
247 graphics.drawLine(new TerminalPosition(drawableArea.getColumns() - 1, 1),
248 new TerminalPosition(drawableArea.getColumns() - 1, drawableArea.getRows() - 2),
249 verticalLine);
250 }
251 graphics.setCharacter(drawableArea.getColumns() - 1, drawableArea.getRows() - 1, bottomRightCorner);
252 if(drawableArea.getColumns() > 2) {
253 graphics.drawLine(new TerminalPosition(1, drawableArea.getRows() - 1),
254 new TerminalPosition(drawableArea.getColumns() - 2, drawableArea.getRows() - 1),
255 horizontalLine);
256 }
257
258 if(drawableArea.getColumns() >= TerminalTextUtils.getColumnWidth(border.getTitle()) + 4) {
259 graphics.putString(2, 0, border.getTitle());
260 }
261
262 wrappedComponent.draw(graphics.newTextGraphics(getWrappedComponentTopLeftOffset(), getWrappedComponentSize(drawableArea)));
263
264
265 joinLinesWithFrame(graphics);
266 }
267
268 protected abstract char getHorizontalLine(TextGUIGraphics graphics);
269 protected abstract char getVerticalLine(TextGUIGraphics graphics);
270 protected abstract char getBottomLeftCorner(TextGUIGraphics graphics);
271 protected abstract char getTopLeftCorner(TextGUIGraphics graphics);
272 protected abstract char getBottomRightCorner(TextGUIGraphics graphics);
273 protected abstract char getTopRightCorner(TextGUIGraphics graphics);
274 }
275
276 /**
277 * This method will attempt to join line drawing characters with the outermost bottom and top rows and left and
278 * right columns. For example, if a vertical left border character is ║ and the character immediately to the right
279 * of it is ─, then the border character will be updated to ╟ to join the two together. Please note that this method
280 * will <b>only</b> join the outer border columns and rows.
281 * @param graphics Graphics to use when inspecting and joining characters
282 */
283 public static void joinLinesWithFrame(TextGraphics graphics) {
284 TerminalSize drawableArea = graphics.getSize();
285 if(drawableArea.getRows() <= 2 || drawableArea.getColumns() <= 2) {
286 //Too small
287 return;
288 }
289
290 int upperRow = 0;
291 int lowerRow = drawableArea.getRows() - 1;
292 int leftRow = 0;
293 int rightRow = drawableArea.getColumns() - 1;
294
295 List<Character> junctionFromBelowSingle = Arrays.asList(
296 Symbols.SINGLE_LINE_VERTICAL,
297 Symbols.BOLD_FROM_NORMAL_SINGLE_LINE_VERTICAL,
298 Symbols.SINGLE_LINE_CROSS,
299 Symbols.DOUBLE_LINE_HORIZONTAL_SINGLE_LINE_CROSS,
300 Symbols.SINGLE_LINE_BOTTOM_LEFT_CORNER,
301 Symbols.SINGLE_LINE_BOTTOM_RIGHT_CORNER,
302 Symbols.SINGLE_LINE_T_LEFT,
303 Symbols.SINGLE_LINE_T_RIGHT,
304 Symbols.SINGLE_LINE_T_UP,
305 Symbols.SINGLE_LINE_T_DOUBLE_LEFT,
306 Symbols.SINGLE_LINE_T_DOUBLE_RIGHT,
307 Symbols.DOUBLE_LINE_T_SINGLE_UP);
308 List<Character> junctionFromBelowDouble = Arrays.asList(
309 Symbols.DOUBLE_LINE_VERTICAL,
310 Symbols.DOUBLE_LINE_CROSS,
311 Symbols.DOUBLE_LINE_VERTICAL_SINGLE_LINE_CROSS,
312 Symbols.DOUBLE_LINE_BOTTOM_LEFT_CORNER,
313 Symbols.DOUBLE_LINE_BOTTOM_RIGHT_CORNER,
314 Symbols.DOUBLE_LINE_T_LEFT,
315 Symbols.DOUBLE_LINE_T_RIGHT,
316 Symbols.DOUBLE_LINE_T_UP,
317 Symbols.DOUBLE_LINE_T_SINGLE_LEFT,
318 Symbols.DOUBLE_LINE_T_SINGLE_RIGHT,
319 Symbols.SINGLE_LINE_T_DOUBLE_UP);
320 List<Character> junctionFromAboveSingle = Arrays.asList(
321 Symbols.SINGLE_LINE_VERTICAL,
322 Symbols.BOLD_TO_NORMAL_SINGLE_LINE_VERTICAL,
323 Symbols.SINGLE_LINE_CROSS,
324 Symbols.DOUBLE_LINE_HORIZONTAL_SINGLE_LINE_CROSS,
325 Symbols.SINGLE_LINE_TOP_LEFT_CORNER,
326 Symbols.SINGLE_LINE_TOP_RIGHT_CORNER,
327 Symbols.SINGLE_LINE_T_LEFT,
328 Symbols.SINGLE_LINE_T_RIGHT,
329 Symbols.SINGLE_LINE_T_DOWN,
330 Symbols.SINGLE_LINE_T_DOUBLE_LEFT,
331 Symbols.SINGLE_LINE_T_DOUBLE_RIGHT,
332 Symbols.DOUBLE_LINE_T_SINGLE_DOWN);
333 List<Character> junctionFromAboveDouble = Arrays.asList(
334 Symbols.DOUBLE_LINE_VERTICAL,
335 Symbols.DOUBLE_LINE_CROSS,
336 Symbols.DOUBLE_LINE_VERTICAL_SINGLE_LINE_CROSS,
337 Symbols.DOUBLE_LINE_TOP_LEFT_CORNER,
338 Symbols.DOUBLE_LINE_TOP_RIGHT_CORNER,
339 Symbols.DOUBLE_LINE_T_LEFT,
340 Symbols.DOUBLE_LINE_T_RIGHT,
341 Symbols.DOUBLE_LINE_T_DOWN,
342 Symbols.DOUBLE_LINE_T_SINGLE_LEFT,
343 Symbols.DOUBLE_LINE_T_SINGLE_RIGHT,
344 Symbols.SINGLE_LINE_T_DOUBLE_DOWN);
345 List<Character> junctionFromLeftSingle = Arrays.asList(
346 Symbols.SINGLE_LINE_HORIZONTAL,
347 Symbols.BOLD_TO_NORMAL_SINGLE_LINE_HORIZONTAL,
348 Symbols.SINGLE_LINE_CROSS,
349 Symbols.DOUBLE_LINE_VERTICAL_SINGLE_LINE_CROSS,
350 Symbols.SINGLE_LINE_BOTTOM_LEFT_CORNER,
351 Symbols.SINGLE_LINE_TOP_LEFT_CORNER,
352 Symbols.SINGLE_LINE_T_UP,
353 Symbols.SINGLE_LINE_T_DOWN,
354 Symbols.SINGLE_LINE_T_RIGHT,
355 Symbols.SINGLE_LINE_T_DOUBLE_UP,
356 Symbols.SINGLE_LINE_T_DOUBLE_DOWN,
357 Symbols.DOUBLE_LINE_T_SINGLE_RIGHT);
358 List<Character> junctionFromLeftDouble = Arrays.asList(
359 Symbols.DOUBLE_LINE_HORIZONTAL,
360 Symbols.DOUBLE_LINE_CROSS,
361 Symbols.DOUBLE_LINE_HORIZONTAL_SINGLE_LINE_CROSS,
362 Symbols.DOUBLE_LINE_BOTTOM_LEFT_CORNER,
363 Symbols.DOUBLE_LINE_TOP_LEFT_CORNER,
364 Symbols.DOUBLE_LINE_T_UP,
365 Symbols.DOUBLE_LINE_T_DOWN,
366 Symbols.DOUBLE_LINE_T_RIGHT,
367 Symbols.DOUBLE_LINE_T_SINGLE_UP,
368 Symbols.DOUBLE_LINE_T_SINGLE_DOWN,
369 Symbols.SINGLE_LINE_T_DOUBLE_RIGHT);
370 List<Character> junctionFromRightSingle = Arrays.asList(
371 Symbols.SINGLE_LINE_HORIZONTAL,
372 Symbols.BOLD_FROM_NORMAL_SINGLE_LINE_HORIZONTAL,
373 Symbols.SINGLE_LINE_CROSS,
374 Symbols.DOUBLE_LINE_VERTICAL_SINGLE_LINE_CROSS,
375 Symbols.SINGLE_LINE_BOTTOM_RIGHT_CORNER,
376 Symbols.SINGLE_LINE_TOP_RIGHT_CORNER,
377 Symbols.SINGLE_LINE_T_UP,
378 Symbols.SINGLE_LINE_T_DOWN,
379 Symbols.SINGLE_LINE_T_LEFT,
380 Symbols.SINGLE_LINE_T_DOUBLE_UP,
381 Symbols.SINGLE_LINE_T_DOUBLE_DOWN,
382 Symbols.DOUBLE_LINE_T_SINGLE_LEFT);
383 List<Character> junctionFromRightDouble = Arrays.asList(
384 Symbols.DOUBLE_LINE_HORIZONTAL,
385 Symbols.DOUBLE_LINE_CROSS,
386 Symbols.DOUBLE_LINE_HORIZONTAL_SINGLE_LINE_CROSS,
387 Symbols.DOUBLE_LINE_BOTTOM_RIGHT_CORNER,
388 Symbols.DOUBLE_LINE_TOP_RIGHT_CORNER,
389 Symbols.DOUBLE_LINE_T_UP,
390 Symbols.DOUBLE_LINE_T_DOWN,
391 Symbols.DOUBLE_LINE_T_LEFT,
392 Symbols.DOUBLE_LINE_T_SINGLE_UP,
393 Symbols.DOUBLE_LINE_T_SINGLE_DOWN,
394 Symbols.SINGLE_LINE_T_DOUBLE_LEFT);
395
396 //Go horizontally and check vertical neighbours if it's possible to extend lines into the border
397 for(int column = 1; column < drawableArea.getColumns() - 1; column++) {
398 //Check first row
399 TextCharacter borderCharacter = graphics.getCharacter(column, upperRow);
400 if(borderCharacter == null) {
401 continue;
402 }
403 TextCharacter neighbourCharacter = graphics.getCharacter(column, upperRow + 1);
404 if(neighbourCharacter != null) {
405 char neighbour = neighbourCharacter.getCharacter();
406 if(borderCharacter.getCharacter() == Symbols.SINGLE_LINE_HORIZONTAL) {
407 if(junctionFromBelowSingle.contains(neighbour)) {
408 graphics.setCharacter(column, upperRow, borderCharacter.withCharacter(Symbols.SINGLE_LINE_T_DOWN));
409 }
410 else if(junctionFromBelowDouble.contains(neighbour)) {
411 graphics.setCharacter(column, upperRow, borderCharacter.withCharacter(Symbols.SINGLE_LINE_T_DOUBLE_DOWN));
412 }
413 }
414 else if(borderCharacter.getCharacter() == Symbols.DOUBLE_LINE_HORIZONTAL) {
415 if(junctionFromBelowSingle.contains(neighbour)) {
416 graphics.setCharacter(column, upperRow, borderCharacter.withCharacter(Symbols.DOUBLE_LINE_T_SINGLE_DOWN));
417 }
418 else if(junctionFromBelowDouble.contains(neighbour)) {
419 graphics.setCharacter(column, upperRow, borderCharacter.withCharacter(Symbols.DOUBLE_LINE_T_DOWN));
420 }
421 }
422 }
423
424 //Check last row
425 borderCharacter = graphics.getCharacter(column, lowerRow);
426 if(borderCharacter == null) {
427 continue;
428 }
429 neighbourCharacter = graphics.getCharacter(column, lowerRow - 1);
430 if(neighbourCharacter != null) {
431 char neighbour = neighbourCharacter.getCharacter();
432 if(borderCharacter.getCharacter() == Symbols.SINGLE_LINE_HORIZONTAL) {
433 if(junctionFromAboveSingle.contains(neighbour)) {
434 graphics.setCharacter(column, lowerRow, borderCharacter.withCharacter(Symbols.SINGLE_LINE_T_UP));
435 }
436 else if(junctionFromAboveDouble.contains(neighbour)) {
437 graphics.setCharacter(column, lowerRow, borderCharacter.withCharacter(Symbols.SINGLE_LINE_T_DOUBLE_UP));
438 }
439 }
440 else if(borderCharacter.getCharacter() == Symbols.DOUBLE_LINE_HORIZONTAL) {
441 if(junctionFromAboveSingle.contains(neighbour)) {
442 graphics.setCharacter(column, lowerRow, borderCharacter.withCharacter(Symbols.DOUBLE_LINE_T_SINGLE_UP));
443 }
444 else if(junctionFromAboveDouble.contains(neighbour)) {
445 graphics.setCharacter(column, lowerRow, borderCharacter.withCharacter(Symbols.DOUBLE_LINE_T_UP));
446 }
447 }
448 }
449 }
450
451 //Go vertically and check horizontal neighbours if it's possible to extend lines into the border
452 for(int row = 1; row < drawableArea.getRows() - 1; row++) {
453 //Check first column
454 TextCharacter borderCharacter = graphics.getCharacter(leftRow, row);
455 if(borderCharacter == null) {
456 continue;
457 }
458 TextCharacter neighbourCharacter = graphics.getCharacter(leftRow + 1, row);
459 if(neighbourCharacter != null) {
460 char neighbour = neighbourCharacter.getCharacter();
461 if(borderCharacter.getCharacter() == Symbols.SINGLE_LINE_VERTICAL) {
462 if(junctionFromRightSingle.contains(neighbour)) {
463 graphics.setCharacter(leftRow, row, borderCharacter.withCharacter(Symbols.SINGLE_LINE_T_RIGHT));
464 }
465 else if(junctionFromRightDouble.contains(neighbour)) {
466 graphics.setCharacter(leftRow, row, borderCharacter.withCharacter(Symbols.SINGLE_LINE_T_DOUBLE_RIGHT));
467 }
468 }
469 else if(borderCharacter.getCharacter() == Symbols.DOUBLE_LINE_VERTICAL) {
470 if(junctionFromRightSingle.contains(neighbour)) {
471 graphics.setCharacter(leftRow, row, borderCharacter.withCharacter(Symbols.DOUBLE_LINE_T_SINGLE_RIGHT));
472 }
473 else if(junctionFromRightDouble.contains(neighbour)) {
474 graphics.setCharacter(leftRow, row, borderCharacter.withCharacter(Symbols.DOUBLE_LINE_T_RIGHT));
475 }
476 }
477 }
478
479 //Check last column
480 borderCharacter = graphics.getCharacter(rightRow, row);
481 if(borderCharacter == null) {
482 continue;
483 }
484 neighbourCharacter = graphics.getCharacter(rightRow - 1, row);
485 if(neighbourCharacter != null) {
486 char neighbour = neighbourCharacter.getCharacter();
487 if(borderCharacter.getCharacter() == Symbols.SINGLE_LINE_VERTICAL) {
488 if(junctionFromLeftSingle.contains(neighbour)) {
489 graphics.setCharacter(rightRow, row, borderCharacter.withCharacter(Symbols.SINGLE_LINE_T_LEFT));
490 }
491 else if(junctionFromLeftDouble.contains(neighbour)) {
492 graphics.setCharacter(rightRow, row, borderCharacter.withCharacter(Symbols.SINGLE_LINE_T_DOUBLE_LEFT));
493 }
494 }
495 else if(borderCharacter.getCharacter() == Symbols.DOUBLE_LINE_VERTICAL) {
496 if(junctionFromLeftSingle.contains(neighbour)) {
497 graphics.setCharacter(rightRow, row, borderCharacter.withCharacter(Symbols.DOUBLE_LINE_T_SINGLE_LEFT));
498 }
499 else if(junctionFromLeftDouble.contains(neighbour)) {
500 graphics.setCharacter(rightRow, row, borderCharacter.withCharacter(Symbols.DOUBLE_LINE_T_LEFT));
501 }
502 }
503 }
504 }
505 }
506
507 private static class SingleLine extends StandardBorder {
508 private SingleLine(String title, BorderStyle borderStyle) {
509 super(title, borderStyle);
510 }
511
512 @Override
513 protected BorderRenderer createDefaultRenderer() {
514 return new SingleLineRenderer(borderStyle);
515 }
516 }
517
518 private static class SingleLineRenderer extends AbstractBorderRenderer {
519 public SingleLineRenderer(BorderStyle borderStyle) {
520 super(borderStyle);
521 }
522
523 @Override
524 protected char getTopRightCorner(TextGUIGraphics graphics) {
525 return graphics.getThemeDefinition(SingleLineRenderer.class).getCharacter("TOP_RIGHT_CORNER", Symbols.SINGLE_LINE_TOP_RIGHT_CORNER);
526 }
527
528 @Override
529 protected char getBottomRightCorner(TextGUIGraphics graphics) {
530 return graphics.getThemeDefinition(SingleLineRenderer.class).getCharacter("BOTTOM_RIGHT_CORNER", Symbols.SINGLE_LINE_BOTTOM_RIGHT_CORNER);
531 }
532
533 @Override
534 protected char getTopLeftCorner(TextGUIGraphics graphics) {
535 return graphics.getThemeDefinition(SingleLineRenderer.class).getCharacter("TOP_LEFT_CORNER", Symbols.SINGLE_LINE_TOP_LEFT_CORNER);
536 }
537
538 @Override
539 protected char getBottomLeftCorner(TextGUIGraphics graphics) {
540 return graphics.getThemeDefinition(SingleLineRenderer.class).getCharacter("BOTTOM_LEFT_CORNER", Symbols.SINGLE_LINE_BOTTOM_LEFT_CORNER);
541 }
542
543 @Override
544 protected char getVerticalLine(TextGUIGraphics graphics) {
545 return graphics.getThemeDefinition(SingleLineRenderer.class).getCharacter("VERTICAL_LINE", Symbols.SINGLE_LINE_VERTICAL);
546 }
547
548 @Override
549 protected char getHorizontalLine(TextGUIGraphics graphics) {
550 return graphics.getThemeDefinition(SingleLineRenderer.class).getCharacter("HORIZONTAL_LINE", Symbols.SINGLE_LINE_HORIZONTAL);
551 }
552 }
553
554 private static class DoubleLine extends StandardBorder {
555 private DoubleLine(String title, BorderStyle borderStyle) {
556 super(title, borderStyle);
557 }
558
559 @Override
560 protected BorderRenderer createDefaultRenderer() {
561 return new DoubleLineRenderer(borderStyle);
562 }
563 }
564
565 private static class DoubleLineRenderer extends AbstractBorderRenderer {
566 public DoubleLineRenderer(BorderStyle borderStyle) {
567 super(borderStyle);
568 }
569
570 @Override
571 protected char getTopRightCorner(TextGUIGraphics graphics) {
572 return graphics.getThemeDefinition(DoubleLine.class).getCharacter("TOP_RIGHT_CORNER", Symbols.DOUBLE_LINE_TOP_RIGHT_CORNER);
573 }
574
575 @Override
576 protected char getBottomRightCorner(TextGUIGraphics graphics) {
577 return graphics.getThemeDefinition(DoubleLine.class).getCharacter("BOTTOM_RIGHT_CORNER", Symbols.DOUBLE_LINE_BOTTOM_RIGHT_CORNER);
578 }
579
580 @Override
581 protected char getTopLeftCorner(TextGUIGraphics graphics) {
582 return graphics.getThemeDefinition(DoubleLine.class).getCharacter("TOP_LEFT_CORNER", Symbols.DOUBLE_LINE_TOP_LEFT_CORNER);
583 }
584
585 @Override
586 protected char getBottomLeftCorner(TextGUIGraphics graphics) {
587 return graphics.getThemeDefinition(DoubleLine.class).getCharacter("BOTTOM_LEFT_CORNER", Symbols.DOUBLE_LINE_BOTTOM_LEFT_CORNER);
588 }
589
590 @Override
591 protected char getVerticalLine(TextGUIGraphics graphics) {
592 return graphics.getThemeDefinition(DoubleLine.class).getCharacter("VERTICAL_LINE", Symbols.DOUBLE_LINE_VERTICAL);
593 }
594
595 @Override
596 protected char getHorizontalLine(TextGUIGraphics graphics) {
597 return graphics.getThemeDefinition(DoubleLine.class).getCharacter("HORIZONTAL_LINE", Symbols.DOUBLE_LINE_HORIZONTAL);
598 }
599 }
600}