Fix package reference
[fanfix.git] / src / jexer / backend / MultiScreen.java
CommitLineData
88a99379
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 */
29package jexer.backend;
30
31import java.util.LinkedList;
32import java.util.List;
33
34import jexer.bits.Cell;
35import jexer.bits.CellAttributes;
36
37/**
38 * MultiScreen mirrors its I/O to several screens.
39 */
40public class MultiScreen implements Screen {
41
42 /**
43 * The list of screens to use.
44 */
45 private List<Screen> screens = new LinkedList<Screen>();
46
47 /**
48 * Public constructor requires one screen.
49 *
50 * @param screen the screen to add
51 */
52 public MultiScreen(final Screen screen) {
53 screens.add(screen);
54 }
55
56 /**
57 * Add a screen to the list.
58 *
59 * @param screen the screen to add
60 */
61 public void addScreen(final Screen screen) {
62 screens.add(screen);
63 }
64
65 /**
66 * Remove a screen from the list.
67 *
68 * @param screen the screen to remove
69 */
70 public void removeScreen(final Screen screen) {
71 if (screens.size() > 1) {
72 screens.remove(screen);
73 }
74 }
75
76 /**
77 * Set drawing offset for x.
78 *
79 * @param offsetX new drawing offset
80 */
81 public void setOffsetX(final int offsetX) {
82 for (Screen screen: screens) {
83 screen.setOffsetX(offsetX);
84 }
85 }
86
87 /**
88 * Set drawing offset for y.
89 *
90 * @param offsetY new drawing offset
91 */
92 public void setOffsetY(final int offsetY) {
93 for (Screen screen: screens) {
94 screen.setOffsetY(offsetY);
95 }
96 }
97
98 /**
99 * Get right drawing clipping boundary.
100 *
101 * @return drawing boundary
102 */
103 public int getClipRight() {
104 return screens.get(0).getClipRight();
105 }
106
107 /**
108 * Set right drawing clipping boundary.
109 *
110 * @param clipRight new boundary
111 */
112 public void setClipRight(final int clipRight) {
113 for (Screen screen: screens) {
114 screen.setClipRight(clipRight);
115 }
116 }
117
118 /**
119 * Get bottom drawing clipping boundary.
120 *
121 * @return drawing boundary
122 */
123 public int getClipBottom() {
124 return screens.get(0).getClipBottom();
125 }
126
127 /**
128 * Set bottom drawing clipping boundary.
129 *
130 * @param clipBottom new boundary
131 */
132 public void setClipBottom(final int clipBottom) {
133 for (Screen screen: screens) {
134 screen.setClipBottom(clipBottom);
135 }
136 }
137
138 /**
139 * Get left drawing clipping boundary.
140 *
141 * @return drawing boundary
142 */
143 public int getClipLeft() {
144 return screens.get(0).getClipLeft();
145 }
146
147 /**
148 * Set left drawing clipping boundary.
149 *
150 * @param clipLeft new boundary
151 */
152 public void setClipLeft(final int clipLeft) {
153 for (Screen screen: screens) {
154 screen.setClipLeft(clipLeft);
155 }
156 }
157
158 /**
159 * Get top drawing clipping boundary.
160 *
161 * @return drawing boundary
162 */
163 public int getClipTop() {
164 return screens.get(0).getClipTop();
165 }
166
167 /**
168 * Set top drawing clipping boundary.
169 *
170 * @param clipTop new boundary
171 */
172 public void setClipTop(final int clipTop) {
173 for (Screen screen: screens) {
174 screen.setClipTop(clipTop);
175 }
176 }
177
178 /**
179 * Get dirty flag.
180 *
181 * @return if true, the logical screen is not in sync with the physical
182 * screen
183 */
184 public boolean isDirty() {
185 return screens.get(0).isDirty();
186 }
187
188 /**
189 * Get the attributes at one location.
190 *
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)
194 */
195 public CellAttributes getAttrXY(final int x, final int y) {
196 return screens.get(0).getAttrXY(x, y);
197 }
198
199 /**
200 * Set the attributes at one location.
201 *
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)
205 */
206 public void putAttrXY(final int x, final int y,
207 final CellAttributes attr) {
208
209 for (Screen screen: screens) {
210 screen.putAttrXY(x, y, attr);
211 }
212 }
213
214 /**
215 * Set the attributes at one location.
216 *
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
221 */
222 public void putAttrXY(final int x, final int y,
223 final CellAttributes attr, final boolean clip) {
224
225 for (Screen screen: screens) {
226 screen.putAttrXY(x, y, attr, clip);
227 }
228 }
229
230 /**
231 * Fill the entire screen with one character with attributes.
232 *
233 * @param ch character to draw
234 * @param attr attributes to use (bold, foreColor, backColor)
235 */
236 public void putAll(final char ch, final CellAttributes attr) {
237 for (Screen screen: screens) {
238 screen.putAll(ch, attr);
239 }
240 }
241
242 /**
243 * Render one character with attributes.
244 *
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
248 */
249 public void putCharXY(final int x, final int y, final Cell ch) {
250 for (Screen screen: screens) {
251 screen.putCharXY(x, y, ch);
252 }
253 }
254
255 /**
256 * Render one character with attributes.
257 *
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)
262 */
263 public void putCharXY(final int x, final int y, final char ch,
264 final CellAttributes attr) {
265
266 for (Screen screen: screens) {
267 screen.putCharXY(x, y, ch, attr);
268 }
269 }
270
271 /**
272 * Render one character without changing the underlying attributes.
273 *
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
277 */
278 public void putCharXY(final int x, final int y, final char ch) {
279 for (Screen screen: screens) {
280 screen.putCharXY(x, y, ch);
281 }
282 }
283
284 /**
285 * Render a string. Does not wrap if the string exceeds the line.
286 *
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)
291 */
292 public void putStringXY(final int x, final int y, final String str,
293 final CellAttributes attr) {
294
295 for (Screen screen: screens) {
296 screen.putStringXY(x, y, str, attr);
297 }
298 }
299
300 /**
301 * Render a string without changing the underlying attribute. Does not
302 * wrap if the string exceeds the line.
303 *
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
307 */
308 public void putStringXY(final int x, final int y, final String str) {
309 for (Screen screen: screens) {
310 screen.putStringXY(x, y, str);
311 }
312 }
313
314 /**
315 * Draw a vertical line from (x, y) to (x, y + n).
316 *
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)
322 */
323 public void vLineXY(final int x, final int y, final int n,
324 final char ch, final CellAttributes attr) {
325
326 for (Screen screen: screens) {
327 screen.vLineXY(x, y, n, ch, attr);
328 }
329 }
330
331 /**
332 * Draw a horizontal line from (x, y) to (x + n, y).
333 *
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)
339 */
340 public void hLineXY(final int x, final int y, final int n,
341 final char ch, final CellAttributes attr) {
342
343 for (Screen screen: screens) {
344 screen.hLineXY(x, y, n, ch, attr);
345 }
346 }
347
348 /**
349 * Change the width. Everything on-screen will be destroyed and must be
350 * redrawn.
351 *
352 * @param width new screen width
353 */
354 public void setWidth(final int width) {
355 for (Screen screen: screens) {
356 screen.setWidth(width);
357 }
358 }
359
360 /**
361 * Change the height. Everything on-screen will be destroyed and must be
362 * redrawn.
363 *
364 * @param height new screen height
365 */
366 public void setHeight(final int height) {
367 for (Screen screen: screens) {
368 screen.setHeight(height);
369 }
370 }
371
372 /**
373 * Change the width and height. Everything on-screen will be destroyed
374 * and must be redrawn.
375 *
376 * @param width new screen width
377 * @param height new screen height
378 */
379 public void setDimensions(final int width, final int height) {
380 for (Screen screen: screens) {
381 screen.setDimensions(width, height);
382 }
383 }
384
385 /**
386 * Get the height.
387 *
388 * @return current screen height
389 */
390 public int getHeight() {
391 return screens.get(0).getHeight();
392 }
393
394 /**
395 * Get the width.
396 *
397 * @return current screen width
398 */
399 public int getWidth() {
400 return screens.get(0).getWidth();
401 }
402
403 /**
404 * Reset screen to not-bold, white-on-black. Also flushes the offset and
405 * clip variables.
406 */
407 public void reset() {
408 for (Screen screen: screens) {
409 screen.reset();
410 }
411 }
412
413 /**
414 * Flush the offset and clip variables.
415 */
416 public void resetClipping() {
417 for (Screen screen: screens) {
418 screen.resetClipping();
419 }
420 }
421
422 /**
423 * Clear the logical screen.
424 */
425 public void clear() {
426 for (Screen screen: screens) {
427 screen.clear();
428 }
429 }
430
431 /**
432 * Draw a box with a border and empty background.
433 *
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
440 */
441 public void drawBox(final int left, final int top,
442 final int right, final int bottom,
443 final CellAttributes border, final CellAttributes background) {
444
445 for (Screen screen: screens) {
446 screen.drawBox(left, top, right, bottom, border, background);
447 }
448 }
449
450 /**
451 * Draw a box with a border and empty background.
452 *
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
463 */
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) {
468
469 for (Screen screen: screens) {
470 screen.drawBox(left, top, right, bottom, border, background,
471 borderType, shadow);
472 }
473 }
474
475 /**
476 * Draw a box shadow.
477 *
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
482 */
483 public void drawBoxShadow(final int left, final int top,
484 final int right, final int bottom) {
485
486 for (Screen screen: screens) {
487 screen.drawBoxShadow(left, top, right, bottom);
488 }
489 }
490
491 /**
492 * Classes must provide an implementation to push the logical screen to
493 * the physical device.
494 */
495 public void flushPhysical() {
496 for (Screen screen: screens) {
497 screen.flushPhysical();
498 }
499 }
500
501 /**
502 * Put the cursor at (x,y).
503 *
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
507 */
508 public void putCursor(final boolean visible, final int x, final int y) {
509 for (Screen screen: screens) {
510 screen.putCursor(visible, x, y);
511 }
512 }
513
514 /**
515 * Hide the cursor.
516 */
517 public void hideCursor() {
518 for (Screen screen: screens) {
519 screen.hideCursor();
520 }
521 }
522
523 /**
524 * Set the window title.
525 *
526 * @param title the new title
527 */
528 public void setTitle(final String title) {
529 for (Screen screen: screens) {
530 screen.setTitle(title);
531 }
532 }
533
534}