1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.ui.framework.layout.field;
35
36 import info.magnolia.icons.MagnoliaIcons;
37 import info.magnolia.objectfactory.annotation.Multibinding;
38 import info.magnolia.ui.field.EditorPropertyDefinition;
39 import info.magnolia.ui.field.MultiFieldDefinition;
40 import info.magnolia.ui.field.ValueBoundProperty;
41
42 import java.util.Optional;
43
44 import javax.inject.Inject;
45
46 import org.apache.commons.lang3.StringUtils;
47 import org.vaadin.jonatan.contexthelp.ContextHelp;
48
49 import com.vaadin.ui.AbstractField;
50 import com.vaadin.ui.Button;
51 import com.vaadin.ui.Component;
52 import com.vaadin.ui.CustomField;
53 import com.vaadin.ui.Label;
54 import com.vaadin.ui.TabSheet;
55 import com.vaadin.ui.UI;
56
57
58
59
60
61
62
63
64
65 @Multibinding
66 public interface FieldLayoutComponent extends Component {
67
68
69
70
71 void init(EditorPropertyDefinition definition, Component innerField);
72
73 default Position getPosition() {
74 return Position.horizontal;
75 }
76
77 enum Position {
78
79
80
81 vertical,
82
83
84
85 horizontal
86 }
87
88 class ValidationLabel extends Label implements FieldLayoutComponent {
89
90 private Component field;
91
92 @Override
93 public void init(EditorPropertyDefinition definition, Component innerField) {
94 this.field = innerField;
95 addStyleName("validation-display");
96 }
97
98 @Override
99 public Position getPosition() {
100 return Position.vertical;
101 }
102
103 @Override
104 public void setValue(String value) {
105 super.setValue(value);
106 if (value.isEmpty()) {
107 Optional.ofNullable(field).ifPresent(component -> component.removeStyleName("error"));
108 setVisible(false);
109 } else {
110 Optional.ofNullable(field).ifPresent(component -> component.addStyleName("error"));
111
112 setVisible(true);
113 }
114 }
115 }
116
117 class Description extends Button implements FieldLayoutComponent {
118
119 private final UI ui;
120
121 @Inject
122 Description(UI ui) {
123 this.ui = ui;
124 }
125
126 @Override
127 public void init(EditorPropertyDefinition definition, Component innerField) {
128 if (StringUtils.isNotEmpty(definition.getDescription())) {
129 setIcon(MagnoliaIcons.HELP_MARK);
130 addStyleName("help-button v-button-icon icon-button");
131 ContextHelp contextHelp = ui.getExtensions().stream()
132 .filter(ContextHelp.class::isInstance)
133 .findFirst()
134 .map(ContextHelp.class::cast)
135 .orElseGet(() -> {
136 final ContextHelp help = new ContextHelp();
137 help.extend(ui);
138 return help;
139 });
140 addClickListener(event -> contextHelp.showHelpFor(this));
141 contextHelp.addHelpForComponent(this, definition.getDescription());
142 } else {
143 setVisible(false);
144 }
145 }
146 }
147
148 class Root<T> extends CustomField<T> {
149
150 private final Component root;
151 private final Component field;
152
153 @Inject
154 Root(Component mainField, Component root, EditorPropertyDefinition definition) {
155 this.field = mainField;
156 this.root = root;
157 this.addStyleName("form-field-layout");
158 mainField.addStyleName("hide-caption");
159
160 setCaption(StringUtils.isEmpty(field.getCaption()) ? null : field.getCaption());
161 setVisible(field.isVisible());
162 relayRequirementIndicator(mainField, definition);
163 getContent();
164 }
165
166
167
168
169 private void relayRequirementIndicator(Component mainField, EditorPropertyDefinition definition) {
170 if (definition instanceof ValueBoundProperty) {
171 setRequiredIndicatorVisible(((ValueBoundProperty<?>) definition).isRequired());
172 if (mainField instanceof AbstractField) {
173 ((AbstractField<?>) mainField).setRequiredIndicatorVisible(false);
174 }
175 } else if (definition instanceof MultiFieldDefinition) {
176 setRequiredIndicatorVisible(((MultiFieldDefinition<?>) definition).isRequired());
177 }
178 }
179
180 @Override
181 protected Component initContent() {
182 return root;
183 }
184
185 @Override
186 protected void doSetValue(T value) {
187 }
188
189 @Override
190 public T getValue() {
191 return null;
192 }
193
194 @Override
195 public void focus() {
196 performTabSelection(field);
197 if (field instanceof Focusable) {
198 ((Focusable) field).focus();
199 }
200 }
201
202
203
204
205 private void performTabSelection(Component f) {
206 Component t = f;
207 do {
208 f = t;
209 t = f.getParent();
210 } while (!(t == null || t instanceof TabSheet));
211 if (t != null) {
212 ((TabSheet) t).setSelectedTab(f);
213 }
214 }
215 }
216 }