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