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.vaadin.gwt.client.editor.model.focus;
35
36 import info.magnolia.ui.vaadin.gwt.client.editor.dom.MgnlArea;
37 import info.magnolia.ui.vaadin.gwt.client.editor.dom.MgnlComponent;
38 import info.magnolia.ui.vaadin.gwt.client.editor.dom.MgnlElement;
39 import info.magnolia.ui.vaadin.gwt.client.editor.event.ComponentStopMoveEvent;
40 import info.magnolia.ui.vaadin.gwt.client.editor.event.SelectElementEvent;
41 import info.magnolia.ui.vaadin.gwt.client.editor.jsni.scroll.ElementScrollPositionPreserver;
42 import info.magnolia.ui.vaadin.gwt.client.editor.model.Model;
43 import info.magnolia.ui.vaadin.gwt.client.shared.AbstractElement;
44
45 import com.google.gwt.dom.client.Element;
46 import com.google.web.bindery.event.shared.EventBus;
47
48
49
50
51
52
53
54
55 public class FocusModelImpl implements FocusModel {
56
57 private final Model model;
58 private final EventBus eventBus;
59
60
61
62 private MgnlArea selectedAreaElement;
63 private MgnlComponent selectedComponentElement;
64
65 public FocusModelImpl(EventBus eventBus, Model model) {
66 this.eventBus = eventBus;
67 this.model = model;
68 }
69
70 @Override
71 public void selectElement(Element element) {
72 selectElement(model.getMgnlElement(element));
73 }
74
75 @Override
76 public void selectElement(AbstractElement element) {
77 selectElement(model.getMgnlElement(element));
78 }
79
80
81
82
83
84 private void selectElement(MgnlElement mgnlElement) {
85
86 if (mgnlElement == null) {
87 mgnlElement = model.getRootPage();
88 }
89
90
91 if (model.isMoving()) {
92 if (!mgnlElement.isRelated(selectedComponentElement)) {
93 eventBus.fireEvent(new ComponentStopMoveEvent(null, false));
94 }
95 return;
96 }
97
98
99 ElementScrollPositionPreserver scrollPositionPreserver = null;
100 if (!mgnlElement.isPage()) {
101 scrollPositionPreserver = mgnlElement.preserve();
102 }
103
104 doSelectMgnlElement(mgnlElement);
105
106
107 if (scrollPositionPreserver != null) {
108 scrollPositionPreserver.restorePosition();
109 }
110
111 }
112
113 private void doSelectMgnlElement(MgnlElement mgnlElement) {
114 MgnlArea area = null;
115 MgnlComponent component = null;
116
117 if (mgnlElement.isComponent()) {
118 component = (MgnlComponent) mgnlElement;
119 area = mgnlElement.getParentArea();
120 } else if (mgnlElement.isArea()) {
121 area = (MgnlArea) mgnlElement;
122 }
123
124
125 setComponentSelection(component);
126 setAreaSelection(area);
127
128
129 togglePageFocus(mgnlElement.isPage());
130
131 dispatchElementSelection(mgnlElement);
132 }
133
134
135
136
137
138
139
140
141
142
143
144
145
146 @Override
147 public void init() {
148 for (MgnlArea root : model.getRootAreas()) {
149 root.setVisible(true);
150
151 if (root.getComponents().isEmpty()) {
152 root.setPlaceHolderVisible(true);
153 }
154 }
155 }
156
157
158
159
160
161
162 @Override
163 public void resetFocus() {
164 this.selectedAreaElement = null;
165 this.selectedComponentElement = null;
166 }
167
168
169
170
171
172
173
174 private void setComponentSelection(MgnlComponent component) {
175 if (selectedComponentElement == component) {
176 return;
177 }
178 if (selectedComponentElement != null) {
179 selectedComponentElement.removeFocus();
180 }
181 if (component != null) {
182 component.setFocus();
183 }
184 this.selectedComponentElement = component;
185 }
186
187
188
189
190
191
192 private void setAreaSelection(MgnlArea area) {
193
194 if (selectedAreaElement != null) {
195
196 selectedAreaElement.removeFocus();
197
198
199 if (!selectedAreaElement.isRelated(area)) {
200
201 toggleChildComponentVisibility(selectedAreaElement, false);
202 toggleAreaVisibility(selectedAreaElement, false);
203 }
204
205
206
207 else if (selectedAreaElement.getAscendants().contains(area) || (area != null && !area.getDescendants().contains(selectedAreaElement))) {
208 toggleChildComponentVisibility(selectedAreaElement, false);
209 }
210 }
211
212
213 if (area != null) {
214 toggleAreaVisibility(area, true);
215 toggleChildComponentVisibility(area, true);
216
217 area.setFocus(selectedComponentElement != null);
218 }
219 this.selectedAreaElement = area;
220 }
221
222 private void toggleAreaVisibility(MgnlArea area, boolean visible) {
223 MgnlArea parentArea = area.getParentArea();
224 if (parentArea != null) {
225 toggleAreaVisibility(parentArea, visible);
226 toggleChildComponentVisibility(parentArea, visible);
227
228 }
229
230 if (!model.getRootAreas().contains(area)) {
231 area.setVisible(visible);
232 }
233
234 toggleNestedAreasVisibility(area, visible);
235 }
236
237 private void toggleChildComponentVisibility(MgnlArea area, boolean visible) {
238
239 if (!model.getRootAreas().contains(area) || !area.getComponents().isEmpty()) {
240 area.setPlaceHolderVisible(visible);
241 }
242
243
244 if (!visible && !area.getComponents().isEmpty()) {
245 area.setPlaceHolderVisible(false);
246 }
247
248 for (MgnlComponent component : area.getComponents()) {
249
250 component.setVisible(visible);
251
252
253 for (MgnlArea childArea : component.getAreas()) {
254 childArea.setVisible(visible);
255 toggleNestedAreasVisibility(childArea, visible);
256 }
257 }
258 }
259
260 private void toggleNestedAreasVisibility(MgnlArea area, boolean visible) {
261 for (MgnlArea childArea : area.getAreas()) {
262 childArea.setVisible(visible);
263 toggleNestedAreasVisibility(childArea, visible);
264 }
265 }
266
267
268
269
270
271 private void togglePageFocus(boolean visible) {
272 for (MgnlArea root : model.getRootAreas()) {
273 root.toggleInitFocus(visible);
274 }
275 }
276
277 private void dispatchElementSelection(MgnlElement mgnlElement) {
278 mgnlElement = (mgnlElement != null) ? mgnlElement : model.getRootPage();
279 if (mgnlElement != null) {
280 eventBus.fireEvent(new SelectElementEvent(mgnlElement.getTypedElement()));
281 }
282 }
283 }