1 package be
.nikiroo
.jvcard
.tui
;
4 import java
.util
.Arrays
;
5 import java
.util
.LinkedList
;
8 import be
.nikiroo
.jvcard
.Card
;
9 import be
.nikiroo
.jvcard
.Contact
;
10 import be
.nikiroo
.jvcard
.i18n
.Trans
;
11 import be
.nikiroo
.jvcard
.i18n
.Trans
.StringId
;
12 import be
.nikiroo
.jvcard
.tui
.KeyAction
.Mode
;
13 import be
.nikiroo
.jvcard
.tui
.UiColors
.Element
;
14 import be
.nikiroo
.jvcard
.tui
.panes
.ContactDetails
;
15 import be
.nikiroo
.jvcard
.tui
.panes
.ContactList
;
16 import be
.nikiroo
.jvcard
.tui
.panes
.MainContent
;
18 import com
.googlecode
.lanterna
.TerminalSize
;
19 import com
.googlecode
.lanterna
.gui2
.BasicWindow
;
20 import com
.googlecode
.lanterna
.gui2
.BorderLayout
;
21 import com
.googlecode
.lanterna
.gui2
.Direction
;
22 import com
.googlecode
.lanterna
.gui2
.Interactable
;
23 import com
.googlecode
.lanterna
.gui2
.Label
;
24 import com
.googlecode
.lanterna
.gui2
.LinearLayout
;
25 import com
.googlecode
.lanterna
.gui2
.Panel
;
26 import com
.googlecode
.lanterna
.gui2
.TextBox
;
27 import com
.googlecode
.lanterna
.gui2
.TextGUIGraphics
;
28 import com
.googlecode
.lanterna
.gui2
.Window
;
29 import com
.googlecode
.lanterna
.input
.KeyStroke
;
30 import com
.googlecode
.lanterna
.input
.KeyType
;
33 * This is the main "window" of the program. It will host one
34 * {@link MainContent} at any one time.
39 public class MainWindow
extends BasicWindow
{
40 private List
<KeyAction
> defaultActions
= new LinkedList
<KeyAction
>();
41 private List
<KeyAction
> actions
= new LinkedList
<KeyAction
>();
42 private List
<MainContent
> content
= new LinkedList
<MainContent
>();
43 private boolean actionsPadded
;
44 private Boolean waitForOneKeyAnswer
; // true, false, (null = do not wait for
47 private Panel titlePanel
;
48 private Panel mainPanel
;
49 private Panel contentPanel
;
50 private Panel actionPanel
;
51 private Panel messagePanel
;
58 public MainWindow(MainContent content
) {
59 super(content
== null ?
"" : content
.getTitle());
61 setHints(Arrays
.asList(Window
.Hint
.FULL_SCREEN
,
62 Window
.Hint
.NO_DECORATIONS
, Window
.Hint
.FIT_TERMINAL_WINDOW
));
64 defaultActions
.add(new KeyAction(Mode
.BACK
, 'q',
65 StringId
.KEY_ACTION_BACK
));
66 defaultActions
.add(new KeyAction(Mode
.BACK
, KeyType
.Escape
,
68 defaultActions
.add(new KeyAction(Mode
.HELP
, 'h',
69 StringId
.KEY_ACTION_HELP
));
70 defaultActions
.add(new KeyAction(Mode
.HELP
, KeyType
.F1
, StringId
.NULL
));
72 actionPanel
= new Panel();
73 contentPanel
= new Panel();
74 mainPanel
= new Panel();
75 messagePanel
= new Panel();
76 titlePanel
= new Panel();
78 Panel actionMessagePanel
= new Panel();
80 LinearLayout llayout
= new LinearLayout(Direction
.HORIZONTAL
);
81 llayout
.setSpacing(0);
82 actionPanel
.setLayoutManager(llayout
);
84 llayout
= new LinearLayout(Direction
.VERTICAL
);
85 llayout
.setSpacing(0);
86 titlePanel
.setLayoutManager(llayout
);
88 llayout
= new LinearLayout(Direction
.VERTICAL
);
89 llayout
.setSpacing(0);
90 messagePanel
.setLayoutManager(llayout
);
92 BorderLayout blayout
= new BorderLayout();
93 mainPanel
.setLayoutManager(blayout
);
95 blayout
= new BorderLayout();
96 contentPanel
.setLayoutManager(blayout
);
98 blayout
= new BorderLayout();
99 actionMessagePanel
.setLayoutManager(blayout
);
102 .addComponent(messagePanel
, BorderLayout
.Location
.TOP
);
103 actionMessagePanel
.addComponent(actionPanel
,
104 BorderLayout
.Location
.CENTER
);
106 mainPanel
.addComponent(titlePanel
, BorderLayout
.Location
.TOP
);
107 mainPanel
.addComponent(contentPanel
, BorderLayout
.Location
.CENTER
);
109 .addComponent(actionMessagePanel
, BorderLayout
.Location
.BOTTOM
);
111 pushContent(content
);
113 setComponent(mainPanel
);
116 public void pushContent(MainContent content
) {
117 List
<KeyAction
> actions
= null;
120 contentPanel
.removeAllComponents();
121 if (content
!= null) {
122 title
= content
.getTitle();
123 actions
= content
.getKeyBindings();
124 contentPanel
.addComponent(content
, BorderLayout
.Location
.CENTER
);
125 this.content
.add(content
);
127 Interactable focus
= content
.nextFocus(null);
133 setActions(actions
, true, true);
138 public MainContent
popContent() {
139 MainContent removed
= null;
140 MainContent prev
= null;
141 if (content
.size() > 0)
142 removed
= content
.remove(content
.size() - 1);
143 if (content
.size() > 0)
144 prev
= content
.remove(content
.size() - 1);
151 * Set the application title.
154 * the new title or NULL for the default title
156 public void setTitle(String title
) {
158 title
= Trans
.StringId
.TITLE
.trans();
161 if (!title
.equals(this.title
)) {
162 super.setTitle(title
);
166 Label lbl
= new Label(title
);
167 titlePanel
.removeAllComponents();
169 titlePanel
.addComponent(lbl
, LinearLayout
170 .createLayoutData(LinearLayout
.Alignment
.Center
));
174 * Show the given message on screen. It will disappear at the next action.
177 * the message to display
179 * TRUE for an error message, FALSE for an information message
181 public void setMessage(String mess
, boolean error
) {
182 messagePanel
.removeAllComponents();
184 Element element
= (error ? UiColors
.Element
.LINE_MESSAGE_ERR
185 : UiColors
.Element
.LINE_MESSAGE
);
186 Label lbl
= element
.createLabel(" " + mess
+ " ");
187 messagePanel
.addComponent(lbl
, LinearLayout
188 .createLayoutData(LinearLayout
.Alignment
.Center
));
192 public void setQuestion(String mess
, boolean oneKey
) {
193 messagePanel
.removeAllComponents();
195 waitForOneKeyAnswer
= oneKey
;
197 Panel hpanel
= new Panel();
198 LinearLayout llayout
= new LinearLayout(Direction
.HORIZONTAL
);
199 llayout
.setSpacing(0);
200 hpanel
.setLayoutManager(llayout
);
202 Label lbl
= UiColors
.Element
.LINE_MESSAGE_QUESTION
.createLabel(" "
204 text
= new TextBox(new TerminalSize(getSize().getColumns()
205 - lbl
.getSize().getColumns(), 1));
207 hpanel
.addComponent(lbl
, LinearLayout
208 .createLayoutData(LinearLayout
.Alignment
.Beginning
));
209 hpanel
.addComponent(text
, LinearLayout
210 .createLayoutData(LinearLayout
.Alignment
.Fill
));
212 messagePanel
.addComponent(hpanel
, LinearLayout
213 .createLayoutData(LinearLayout
.Alignment
.Beginning
));
220 public void draw(TextGUIGraphics graphics
) {
222 if (!actionsPadded
) {
223 // fill with "desc" colour
224 actionPanel
.addComponent(UiColors
.Element
.ACTION_DESC
225 .createLabel(StringUtils
.padString("", graphics
.getSize()
227 actionsPadded
= true;
229 super.draw(graphics
);
232 private void setActions(List
<KeyAction
> actions
, boolean allowKeys
,
233 boolean enableDefaultactions
) {
235 this.actions
.clear();
236 actionsPadded
= false;
238 if (enableDefaultactions
)
239 this.actions
.addAll(defaultActions
);
242 this.actions
.addAll(actions
);
244 actionPanel
.removeAllComponents();
245 for (KeyAction action
: this.actions
) {
246 String trans
= " " + action
.getStringId().trans() + " ";
248 if (" ".equals(trans
))
251 String keyTrans
= "";
252 switch (action
.getKey().getKeyType()) {
260 keyTrans
= " " + action
.getKey().getCharacter() + " ";
263 keyTrans
= "" + action
.getKey().getKeyType();
265 if (keyTrans
.length() > width
) {
266 keyTrans
= keyTrans
.substring(0, width
);
267 } else if (keyTrans
.length() < width
) {
269 + new String(new char[width
- keyTrans
.length()])
275 Panel kPane
= new Panel();
276 LinearLayout layout
= new LinearLayout(Direction
.HORIZONTAL
);
277 layout
.setSpacing(0);
278 kPane
.setLayoutManager(layout
);
280 kPane
.addComponent(UiColors
.Element
.ACTION_KEY
281 .createLabel(keyTrans
));
282 kPane
.addComponent(UiColors
.Element
.ACTION_DESC
.createLabel(trans
));
284 actionPanel
.addComponent(kPane
);
288 private String
handleQuestion(KeyStroke key
) {
289 String answer
= null;
291 if (waitForOneKeyAnswer
) {
292 answer
= "" + key
.getCharacter();
294 if (key
.getKeyType() == KeyType
.Enter
) {
296 answer
= text
.getText();
302 if (answer
!= null) {
303 Interactable focus
= null;
304 if (this.content
.size() > 0)
305 // focus = content.get(0).getDefaultFocusElement();
306 focus
= content
.get(0).nextFocus(null);
315 public boolean handleInput(KeyStroke key
) {
316 boolean handled
= false;
318 if (waitForOneKeyAnswer
!= null) {
319 String answer
= handleQuestion(key
);
320 if (answer
!= null) {
321 waitForOneKeyAnswer
= null;
322 setMessage("ANS: " + answer
, false);
327 setMessage(null, false);
329 for (KeyAction action
: actions
) {
330 if (!action
.match(key
))
335 if (action
.onAction()) {
336 switch (action
.getMode()) {
341 if (action
.getKey().getKeyType() == KeyType
.ArrowUp
)
343 if (action
.getKey().getKeyType() == KeyType
.ArrowDown
)
345 if (action
.getKey().getKeyType() == KeyType
.ArrowLeft
)
347 if (action
.getKey().getKeyType() == KeyType
.ArrowRight
)
350 if (content
.size() > 0) {
351 String err
= content
.get(content
.size() - 1).move(
354 setMessage(err
, true);
358 // mode with windows:
360 Card card
= action
.getCard();
362 pushContent(new ContactList(card
));
365 case CONTACT_DETAILS
:
366 Contact contact
= action
.getContact();
367 if (contact
!= null) {
368 pushContent(new ContactDetails(contact
));
371 // mode interpreted by MainWindow:
374 // setMessage("Help! I need somebody! Help!", false);
375 setQuestion("Test question?", false);
380 if (content
.size() == 0)
394 handled
= super.handleInput(key
);