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