Fix --noutf, fix onAction being called to many times, lot of small fixes
[jvcard.git] / src / com / googlecode / lanterna / gui2 / AbstractWindow.java
CommitLineData
a3b510ab
NR
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.TerminalPosition;
22import com.googlecode.lanterna.input.KeyStroke;
23import com.googlecode.lanterna.TerminalSize;
24import com.googlecode.lanterna.input.KeyType;
25
26import java.util.*;
27
28/**
29 * Abstract Window has most of the code requiring for a window to function, all concrete window implementations extends
30 * from this in one way or another. You can define your own window by extending from this, as an alternative to building
31 * up the GUI externally by constructing a {@code BasicWindow} and adding components to it.
32 * @author Martin
33 */
34public abstract class AbstractWindow extends AbstractBasePane implements Window {
35 private String title;
36 private WindowBasedTextGUI textGUI;
37 private boolean visible;
38 private TerminalSize lastKnownSize;
39 private TerminalSize lastKnownDecoratedSize;
40 private TerminalPosition lastKnownPosition;
41 private TerminalPosition contentOffset;
42 private Set<Hint> hints;
43 private boolean closeWindowWithEscape;
44
45 /**
46 * Default constructor, this creates a window with no title
47 */
48 public AbstractWindow() {
49 this("");
50 }
51
52 /**
53 * Creates a window with a specific title that will (probably) be drawn in the window decorations
54 * @param title Title of this window
55 */
56 public AbstractWindow(String title) {
57 super();
58 this.title = title;
59 this.textGUI = null;
60 this.visible = true;
61 this.lastKnownPosition = null;
62 this.lastKnownSize = null;
63 this.lastKnownDecoratedSize = null;
64 this.closeWindowWithEscape = false;
65
66 this.hints = new HashSet<Hint>();
67 }
68
69 /**
70 * Setting this property to {@code true} will cause pressing the ESC key to close the window. This used to be the
71 * default behaviour of lanterna 3 during the development cycle but is not longer the case. You are encouraged to
72 * put proper buttons or other kind of components to clearly mark to the user how to close the window instead of
73 * magically taking ESC, but sometimes it can be useful (when doing testing, for example) to enable this mode.
74 * @param closeWindowWithEscape If {@code true}, this window will self-close if you press ESC key
75 */
76 public void setCloseWindowWithEscape(boolean closeWindowWithEscape) {
77 this.closeWindowWithEscape = closeWindowWithEscape;
78 }
79
80 @Override
81 public void setTextGUI(WindowBasedTextGUI textGUI) {
82 //This is kind of stupid check, but might cause it to blow up on people using the library incorrectly instead of
83 //just causing weird behaviour
84 if(this.textGUI != null && textGUI != null) {
85 throw new UnsupportedOperationException("Are you calling setTextGUI yourself? Please read the documentation"
86 + " in that case (this could also be a bug in Lanterna, please report it if you are sure you are "
87 + "not calling Window.setTextGUI(..) from your code)");
88 }
89 this.textGUI = textGUI;
90 }
91
92 @Override
93 public WindowBasedTextGUI getTextGUI() {
94 return textGUI;
95 }
96
97 /**
98 * Alters the title of the window to the supplied string
99 * @param title New title of the window
100 */
101 public void setTitle(String title) {
102 this.title = title;
103 invalidate();
104 }
105
106 @Override
107 public String getTitle() {
108 return title;
109 }
110
111 @Override
112 public boolean isVisible() {
113 return visible;
114 }
115
116 @Override
117 public void setVisible(boolean visible) {
118 this.visible = visible;
119 }
120 @Override
121 public void draw(TextGUIGraphics graphics) {
122 if(!graphics.getSize().equals(lastKnownSize)) {
123 getComponent().invalidate();
124 }
125 setSize(graphics.getSize(), false);
296a0b75 126 super.draw(graphics);
a3b510ab
NR
127 }
128
129 @Override
130 public boolean handleInput(KeyStroke key) {
131 boolean handled = super.handleInput(key);
132 if(!handled && closeWindowWithEscape && key.getKeyType() == KeyType.Escape) {
133 close();
134 return true;
135 }
136 return handled;
137 }
138
139 @Override
140 public TerminalPosition toGlobal(TerminalPosition localPosition) {
141 if(localPosition == null) {
142 return null;
143 }
144 return lastKnownPosition.withRelative(contentOffset.withRelative(localPosition));
145 }
146
147 @Override
148 public TerminalPosition fromGlobal(TerminalPosition globalPosition) {
149 if(globalPosition == null) {
150 return null;
151 }
152 return globalPosition.withRelative(
153 -lastKnownPosition.getColumn() - contentOffset.getColumn(),
154 -lastKnownPosition.getRow() - contentOffset.getRow());
155 }
156
157 @Override
158 public TerminalSize getPreferredSize() {
159 return contentHolder.getPreferredSize();
160 }
161
162 @Override
163 public void setHints(Collection<Hint> hints) {
164 this.hints = new HashSet<Hint>(hints);
165 invalidate();
166 }
167
168 @Override
169 public Set<Hint> getHints() {
170 return Collections.unmodifiableSet(hints);
171 }
172
173 @Override
174 public final TerminalPosition getPosition() {
175 return lastKnownPosition;
176 }
177
178 @Override
179 public final void setPosition(TerminalPosition topLeft) {
180 this.lastKnownPosition = topLeft;
181 }
182
183 @Override
184 public final TerminalSize getSize() {
185 return lastKnownSize;
186 }
187
188 @Override
189 public void setSize(TerminalSize size) {
190 setSize(size, true);
191 }
192
193 private void setSize(TerminalSize size, boolean invalidate) {
194 this.lastKnownSize = size;
195 if(invalidate) {
196 invalidate();
197 }
198 }
199
200 @Override
201 public final TerminalSize getDecoratedSize() {
202 return lastKnownDecoratedSize;
203 }
204
205 @Override
206 public final void setDecoratedSize(TerminalSize decoratedSize) {
207 this.lastKnownDecoratedSize = decoratedSize;
208 }
209
210 @Override
211 public void setContentOffset(TerminalPosition offset) {
212 this.contentOffset = offset;
213 }
214
215 @Override
216 public void close() {
217 if(textGUI != null) {
218 textGUI.removeWindow(this);
219 }
220 setComponent(null);
221 }
222
223 @Override
224 public void waitUntilClosed() {
225 WindowBasedTextGUI textGUI = getTextGUI();
226 if(textGUI != null) {
227 textGUI.waitForWindowToClose(this);
228 }
229 }
230}