Merge branch 'master' of elynx.fr:repo/jvcard
[jvcard.git] / src / com / googlecode / lanterna / gui2 / AbstractComposite.java
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 */
19 package com.googlecode.lanterna.gui2;
20
21 import com.googlecode.lanterna.TerminalPosition;
22 import com.googlecode.lanterna.input.KeyStroke;
23
24 import java.util.Collection;
25 import java.util.Collections;
26
27 /**
28 * This abstract implementation contains common code for the different {@code Composite} implementations. A
29 * {@code Composite} component is one that encapsulates a single component, like borders. Because of this, a
30 * {@code Composite} can be seen as a special case of a {@code Container} and indeed this abstract class does in fact
31 * implement the {@code Container} interface as well, to make the composites easier to work with internally.
32 * @author martin
33 * @param <T> Should always be itself, see {@code AbstractComponent}
34 */
35 public abstract class AbstractComposite<T extends Container> extends AbstractComponent<T> implements Composite, Container {
36
37 private Component component;
38
39 /**
40 * Default constructor
41 */
42 public AbstractComposite() {
43 component = null;
44 }
45
46 @Override
47 public void setComponent(Component component) {
48 Component oldComponent = this.component;
49 if(oldComponent == component) {
50 return;
51 }
52 if(oldComponent != null) {
53 removeComponent(oldComponent);
54 }
55 if(component != null) {
56 this.component = component;
57 component.onAdded(this);
58 component.setPosition(TerminalPosition.TOP_LEFT_CORNER);
59 invalidate();
60 }
61 }
62
63 @Override
64 public Component getComponent() {
65 return component;
66 }
67
68 @Override
69 public int getChildCount() {
70 return component != null ? 1 : 0;
71 }
72
73 @Override
74 public Collection<Component> getChildren() {
75 if(component != null) {
76 return Collections.singletonList(component);
77 }
78 else {
79 return Collections.emptyList();
80 }
81 }
82
83 @Override
84 public boolean containsComponent(Component component) {
85 return component != null && component.hasParent(this);
86 }
87
88 @Override
89 public boolean removeComponent(Component component) {
90 if(this.component == component) {
91 this.component = null;
92 component.onRemoved(this);
93 invalidate();
94 return true;
95 }
96 return false;
97 }
98
99 @Override
100 public boolean isInvalid() {
101 return component != null && component.isInvalid();
102 }
103
104 @Override
105 public void invalidate() {
106 super.invalidate();
107
108 //Propagate
109 if(component != null) {
110 component.invalidate();
111 }
112 }
113
114 @Override
115 public Interactable nextFocus(Interactable fromThis) {
116 if(fromThis == null && getComponent() instanceof Interactable) {
117 return (Interactable)getComponent();
118 }
119 else if(getComponent() instanceof Container) {
120 return ((Container)getComponent()).nextFocus(fromThis);
121 }
122 return null;
123 }
124
125 @Override
126 public Interactable previousFocus(Interactable fromThis) {
127 if(fromThis == null && getComponent() instanceof Interactable) {
128 return (Interactable)getComponent();
129 }
130 else if(getComponent() instanceof Container) {
131 return ((Container)getComponent()).previousFocus(fromThis);
132 }
133 return null;
134 }
135
136 @Override
137 public boolean handleInput(KeyStroke key) {
138 return false;
139 }
140
141 @Override
142 public void updateLookupMap(InteractableLookupMap interactableLookupMap) {
143 if(getComponent() instanceof Container) {
144 ((Container)getComponent()).updateLookupMap(interactableLookupMap);
145 }
146 else if(getComponent() instanceof Interactable) {
147 interactableLookupMap.add((Interactable)getComponent());
148 }
149 }
150 }