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