2 * Jexer - Java Text User Interface
4 * The MIT License (MIT)
6 * Copyright (C) 2017 Kevin Lamonte
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:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
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.
26 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
29 package jexer
.backend
;
31 import java
.util
.LinkedList
;
32 import java
.util
.List
;
34 import jexer
.bits
.Cell
;
35 import jexer
.bits
.CellAttributes
;
38 * MultiScreen mirrors its I/O to several screens.
40 public class MultiScreen
implements Screen
{
43 * The list of screens to use.
45 private List
<Screen
> screens
= new LinkedList
<Screen
>();
48 * Public constructor requires one screen.
50 * @param screen the screen to add
52 public MultiScreen(final Screen screen
) {
57 * Add a screen to the list.
59 * @param screen the screen to add
61 public void addScreen(final Screen screen
) {
66 * Remove a screen from the list.
68 * @param screen the screen to remove
70 public void removeScreen(final Screen screen
) {
71 if (screens
.size() > 1) {
72 screens
.remove(screen
);
77 * Set drawing offset for x.
79 * @param offsetX new drawing offset
81 public void setOffsetX(final int offsetX
) {
82 for (Screen screen
: screens
) {
83 screen
.setOffsetX(offsetX
);
88 * Set drawing offset for y.
90 * @param offsetY new drawing offset
92 public void setOffsetY(final int offsetY
) {
93 for (Screen screen
: screens
) {
94 screen
.setOffsetY(offsetY
);
99 * Get right drawing clipping boundary.
101 * @return drawing boundary
103 public int getClipRight() {
104 return screens
.get(0).getClipRight();
108 * Set right drawing clipping boundary.
110 * @param clipRight new boundary
112 public void setClipRight(final int clipRight
) {
113 for (Screen screen
: screens
) {
114 screen
.setClipRight(clipRight
);
119 * Get bottom drawing clipping boundary.
121 * @return drawing boundary
123 public int getClipBottom() {
124 return screens
.get(0).getClipBottom();
128 * Set bottom drawing clipping boundary.
130 * @param clipBottom new boundary
132 public void setClipBottom(final int clipBottom
) {
133 for (Screen screen
: screens
) {
134 screen
.setClipBottom(clipBottom
);
139 * Get left drawing clipping boundary.
141 * @return drawing boundary
143 public int getClipLeft() {
144 return screens
.get(0).getClipLeft();
148 * Set left drawing clipping boundary.
150 * @param clipLeft new boundary
152 public void setClipLeft(final int clipLeft
) {
153 for (Screen screen
: screens
) {
154 screen
.setClipLeft(clipLeft
);
159 * Get top drawing clipping boundary.
161 * @return drawing boundary
163 public int getClipTop() {
164 return screens
.get(0).getClipTop();
168 * Set top drawing clipping boundary.
170 * @param clipTop new boundary
172 public void setClipTop(final int clipTop
) {
173 for (Screen screen
: screens
) {
174 screen
.setClipTop(clipTop
);
181 * @return if true, the logical screen is not in sync with the physical
184 public boolean isDirty() {
185 return screens
.get(0).isDirty();
189 * Get the attributes at one location.
191 * @param x column coordinate. 0 is the left-most column.
192 * @param y row coordinate. 0 is the top-most row.
193 * @return attributes at (x, y)
195 public CellAttributes
getAttrXY(final int x
, final int y
) {
196 return screens
.get(0).getAttrXY(x
, y
);
200 * Set the attributes at one location.
202 * @param x column coordinate. 0 is the left-most column.
203 * @param y row coordinate. 0 is the top-most row.
204 * @param attr attributes to use (bold, foreColor, backColor)
206 public void putAttrXY(final int x
, final int y
,
207 final CellAttributes attr
) {
209 for (Screen screen
: screens
) {
210 screen
.putAttrXY(x
, y
, attr
);
215 * Set the attributes at one location.
217 * @param x column coordinate. 0 is the left-most column.
218 * @param y row coordinate. 0 is the top-most row.
219 * @param attr attributes to use (bold, foreColor, backColor)
220 * @param clip if true, honor clipping/offset
222 public void putAttrXY(final int x
, final int y
,
223 final CellAttributes attr
, final boolean clip
) {
225 for (Screen screen
: screens
) {
226 screen
.putAttrXY(x
, y
, attr
, clip
);
231 * Fill the entire screen with one character with attributes.
233 * @param ch character to draw
234 * @param attr attributes to use (bold, foreColor, backColor)
236 public void putAll(final char ch
, final CellAttributes attr
) {
237 for (Screen screen
: screens
) {
238 screen
.putAll(ch
, attr
);
243 * Render one character with attributes.
245 * @param x column coordinate. 0 is the left-most column.
246 * @param y row coordinate. 0 is the top-most row.
247 * @param ch character + attributes to draw
249 public void putCharXY(final int x
, final int y
, final Cell ch
) {
250 for (Screen screen
: screens
) {
251 screen
.putCharXY(x
, y
, ch
);
256 * Render one character with attributes.
258 * @param x column coordinate. 0 is the left-most column.
259 * @param y row coordinate. 0 is the top-most row.
260 * @param ch character to draw
261 * @param attr attributes to use (bold, foreColor, backColor)
263 public void putCharXY(final int x
, final int y
, final char ch
,
264 final CellAttributes attr
) {
266 for (Screen screen
: screens
) {
267 screen
.putCharXY(x
, y
, ch
, attr
);
272 * Render one character without changing the underlying attributes.
274 * @param x column coordinate. 0 is the left-most column.
275 * @param y row coordinate. 0 is the top-most row.
276 * @param ch character to draw
278 public void putCharXY(final int x
, final int y
, final char ch
) {
279 for (Screen screen
: screens
) {
280 screen
.putCharXY(x
, y
, ch
);
285 * Render a string. Does not wrap if the string exceeds the line.
287 * @param x column coordinate. 0 is the left-most column.
288 * @param y row coordinate. 0 is the top-most row.
289 * @param str string to draw
290 * @param attr attributes to use (bold, foreColor, backColor)
292 public void putStringXY(final int x
, final int y
, final String str
,
293 final CellAttributes attr
) {
295 for (Screen screen
: screens
) {
296 screen
.putStringXY(x
, y
, str
, attr
);
301 * Render a string without changing the underlying attribute. Does not
302 * wrap if the string exceeds the line.
304 * @param x column coordinate. 0 is the left-most column.
305 * @param y row coordinate. 0 is the top-most row.
306 * @param str string to draw
308 public void putStringXY(final int x
, final int y
, final String str
) {
309 for (Screen screen
: screens
) {
310 screen
.putStringXY(x
, y
, str
);
315 * Draw a vertical line from (x, y) to (x, y + n).
317 * @param x column coordinate. 0 is the left-most column.
318 * @param y row coordinate. 0 is the top-most row.
319 * @param n number of characters to draw
320 * @param ch character to draw
321 * @param attr attributes to use (bold, foreColor, backColor)
323 public void vLineXY(final int x
, final int y
, final int n
,
324 final char ch
, final CellAttributes attr
) {
326 for (Screen screen
: screens
) {
327 screen
.vLineXY(x
, y
, n
, ch
, attr
);
332 * Draw a horizontal line from (x, y) to (x + n, y).
334 * @param x column coordinate. 0 is the left-most column.
335 * @param y row coordinate. 0 is the top-most row.
336 * @param n number of characters to draw
337 * @param ch character to draw
338 * @param attr attributes to use (bold, foreColor, backColor)
340 public void hLineXY(final int x
, final int y
, final int n
,
341 final char ch
, final CellAttributes attr
) {
343 for (Screen screen
: screens
) {
344 screen
.hLineXY(x
, y
, n
, ch
, attr
);
349 * Change the width. Everything on-screen will be destroyed and must be
352 * @param width new screen width
354 public void setWidth(final int width
) {
355 for (Screen screen
: screens
) {
356 screen
.setWidth(width
);
361 * Change the height. Everything on-screen will be destroyed and must be
364 * @param height new screen height
366 public void setHeight(final int height
) {
367 for (Screen screen
: screens
) {
368 screen
.setHeight(height
);
373 * Change the width and height. Everything on-screen will be destroyed
374 * and must be redrawn.
376 * @param width new screen width
377 * @param height new screen height
379 public void setDimensions(final int width
, final int height
) {
380 for (Screen screen
: screens
) {
381 screen
.setDimensions(width
, height
);
388 * @return current screen height
390 public int getHeight() {
391 return screens
.get(0).getHeight();
397 * @return current screen width
399 public int getWidth() {
400 return screens
.get(0).getWidth();
404 * Reset screen to not-bold, white-on-black. Also flushes the offset and
407 public void reset() {
408 for (Screen screen
: screens
) {
414 * Flush the offset and clip variables.
416 public void resetClipping() {
417 for (Screen screen
: screens
) {
418 screen
.resetClipping();
423 * Clear the logical screen.
425 public void clear() {
426 for (Screen screen
: screens
) {
432 * Draw a box with a border and empty background.
434 * @param left left column of box. 0 is the left-most row.
435 * @param top top row of the box. 0 is the top-most row.
436 * @param right right column of box
437 * @param bottom bottom row of the box
438 * @param border attributes to use for the border
439 * @param background attributes to use for the background
441 public void drawBox(final int left
, final int top
,
442 final int right
, final int bottom
,
443 final CellAttributes border
, final CellAttributes background
) {
445 for (Screen screen
: screens
) {
446 screen
.drawBox(left
, top
, right
, bottom
, border
, background
);
451 * Draw a box with a border and empty background.
453 * @param left left column of box. 0 is the left-most row.
454 * @param top top row of the box. 0 is the top-most row.
455 * @param right right column of box
456 * @param bottom bottom row of the box
457 * @param border attributes to use for the border
458 * @param background attributes to use for the background
459 * @param borderType if 1, draw a single-line border; if 2, draw a
460 * double-line border; if 3, draw double-line top/bottom edges and
461 * single-line left/right edges (like Qmodem)
462 * @param shadow if true, draw a "shadow" on the box
464 public void drawBox(final int left
, final int top
,
465 final int right
, final int bottom
,
466 final CellAttributes border
, final CellAttributes background
,
467 final int borderType
, final boolean shadow
) {
469 for (Screen screen
: screens
) {
470 screen
.drawBox(left
, top
, right
, bottom
, border
, background
,
478 * @param left left column of box. 0 is the left-most row.
479 * @param top top row of the box. 0 is the top-most row.
480 * @param right right column of box
481 * @param bottom bottom row of the box
483 public void drawBoxShadow(final int left
, final int top
,
484 final int right
, final int bottom
) {
486 for (Screen screen
: screens
) {
487 screen
.drawBoxShadow(left
, top
, right
, bottom
);
492 * Classes must provide an implementation to push the logical screen to
493 * the physical device.
495 public void flushPhysical() {
496 for (Screen screen
: screens
) {
497 screen
.flushPhysical();
502 * Put the cursor at (x,y).
504 * @param visible if true, the cursor should be visible
505 * @param x column coordinate to put the cursor on
506 * @param y row coordinate to put the cursor on
508 public void putCursor(final boolean visible
, final int x
, final int y
) {
509 for (Screen screen
: screens
) {
510 screen
.putCursor(visible
, x
, y
);
517 public void hideCursor() {
518 for (Screen screen
: screens
) {
524 * Set the window title.
526 * @param title the new title
528 public void setTitle(final String title
) {
529 for (Screen screen
: screens
) {
530 screen
.setTitle(title
);