2 * This file is part of lanterna (http://code.google.com/p/lanterna/).
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.
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.
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/>.
17 * Copyright (C) 2010-2015 Martin
19 package com
.googlecode
.lanterna
.gui2
;
21 import com
.googlecode
.lanterna
.TerminalPosition
;
22 import com
.googlecode
.lanterna
.input
.KeyStroke
;
25 * Default implementation of Interactable that extends from AbstractComponent. If you want to write your own component
26 * that is interactable, i.e. can receive keyboard (and mouse) input, you probably want to extend from this class as
27 * it contains some common implementations of the methods from {@code Interactable} interface
28 * @param <T> Should always be itself, see {@code AbstractComponent}
31 public abstract class AbstractInteractableComponent
<T
extends AbstractInteractableComponent
<T
>> extends AbstractComponent
<T
> implements Interactable
{
33 private InputFilter inputFilter
;
34 private boolean inFocus
;
39 protected AbstractInteractableComponent() {
45 public T
takeFocus() {
46 BasePane basePane
= getBasePane();
47 if(basePane
!= null) {
48 basePane
.setFocusedInteractable(this);
56 * This method is final in {@code AbstractInteractableComponent}, please override {@code afterEnterFocus} instead
59 public final void onEnterFocus(FocusChangeDirection direction
, Interactable previouslyInFocus
) {
61 afterEnterFocus(direction
, previouslyInFocus
);
65 * Called by {@code AbstractInteractableComponent} automatically after this component has received input focus. You
66 * can override this method if you need to trigger some action based on this.
67 * @param direction How focus was transferred, keep in mind this is from the previous component's point of view so
68 * if this parameter has value DOWN, focus came in from above
69 * @param previouslyInFocus Which interactable component had focus previously
71 @SuppressWarnings("EmptyMethod")
72 protected void afterEnterFocus(FocusChangeDirection direction
, Interactable previouslyInFocus
) {
73 //By default no action
79 * This method is final in {@code AbstractInteractableComponent}, please override {@code afterLeaveFocus} instead
82 public final void onLeaveFocus(FocusChangeDirection direction
, Interactable nextInFocus
) {
84 afterLeaveFocus(direction
, nextInFocus
);
88 * Called by {@code AbstractInteractableComponent} automatically after this component has lost input focus. You
89 * can override this method if you need to trigger some action based on this.
90 * @param direction How focus was transferred, keep in mind this is from the this component's point of view so
91 * if this parameter has value DOWN, focus is moving down to a component below
92 * @param nextInFocus Which interactable component is going to receive focus
94 @SuppressWarnings("EmptyMethod")
95 protected void afterLeaveFocus(FocusChangeDirection direction
, Interactable nextInFocus
) {
96 //By default no action
100 protected abstract InteractableRenderer
<T
> createDefaultRenderer();
103 public InteractableRenderer
<T
> getRenderer() {
104 return (InteractableRenderer
<T
>)super.getRenderer();
108 public boolean isFocused() {
113 public final synchronized Result
handleInput(KeyStroke keyStroke
) {
114 if(inputFilter
== null || inputFilter
.onInput(this, keyStroke
)) {
115 return handleKeyStroke(keyStroke
);
118 return Result
.UNHANDLED
;
123 * This method can be overridden to handle various user input (mostly from the keyboard) when this component is in
124 * focus. The input method from the interface, {@code handleInput(..)} is final in
125 * {@code AbstractInteractableComponent} to ensure the input filter is properly handled. If the filter decides that
126 * this event should be processed, it will call this method.
127 * @param keyStroke What input was entered by the user
128 * @return Result of processing the key-stroke
130 protected Result
handleKeyStroke(KeyStroke keyStroke
) {
131 // Skip the keystroke if ctrl, alt or shift was down
132 if(!keyStroke
.isAltDown() && !keyStroke
.isCtrlDown() && !keyStroke
.isShiftDown()) {
133 switch(keyStroke
.getKeyType()) {
135 return Result
.MOVE_FOCUS_DOWN
;
137 return Result
.MOVE_FOCUS_LEFT
;
139 return Result
.MOVE_FOCUS_RIGHT
;
141 return Result
.MOVE_FOCUS_UP
;
143 return Result
.MOVE_FOCUS_NEXT
;
145 return Result
.MOVE_FOCUS_PREVIOUS
;
147 getBasePane().setFocusedInteractable(this);
148 return Result
.HANDLED
;
152 return Result
.UNHANDLED
;
156 public TerminalPosition
getCursorLocation() {
157 return getRenderer().getCursorLocation(self());
161 public InputFilter
getInputFilter() {
166 public synchronized T
setInputFilter(InputFilter inputFilter
) {
167 this.inputFilter
= inputFilter
;