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.workbench;
35
36 import com.vaadin.ui.Alignment;
37 import com.vaadin.ui.Button;
38 import com.vaadin.ui.Component;
39 import com.vaadin.ui.CssLayout;
40 import com.vaadin.ui.HorizontalLayout;
41 import com.vaadin.ui.Label;
42 import com.vaadin.ui.Panel;
43 import com.vaadin.ui.VerticalLayout;
44 import info.magnolia.i18nsystem.SimpleTranslator;
45 import info.magnolia.icons.MagnoliaIcons;
46 import info.magnolia.ui.api.view.View;
47 import info.magnolia.ui.framework.ioc.AdmincentralFlavour;
48 import info.magnolia.ui.theme.ResurfaceTheme;
49 import info.magnolia.ui.workbench.contenttool.ContentToolDefinition;
50 import info.magnolia.ui.workbench.definition.ContentPresenterDefinition;
51 import info.magnolia.ui.workbench.list.ListPresenterDefinition;
52 import info.magnolia.ui.workbench.search.SearchPresenterDefinition;
53 import info.magnolia.ui.workbench.tree.TreeView;
54
55 import java.io.Serializable;
56 import java.util.HashMap;
57 import java.util.Map;
58
59 import com.vaadin.event.ShortcutAction;
60 import com.vaadin.event.ShortcutListener;
61
62
63
64
65 public class WorkbenchViewImpl extends VerticalLayout implements WorkbenchView, Serializable {
66
67 protected final HorizontalLayout toolBar = new HorizontalLayout();
68
69 private final CssLayout filterBar = new CssLayout();
70
71 private final HorizontalLayout viewModes = new HorizontalLayout();
72
73 protected final Panel keyboardEventPanel;
74
75 private StatusBarView statusBar;
76
77 private Map<String, ContentView> contentViews = new HashMap<String, ContentView>();
78
79 private Map<String, Button> contentViewsButton = new HashMap<String, Button>();
80
81 private String currentViewType;
82
83 private WorkbenchView.Listener listener;
84
85 private Label title;
86
87 private Button toggleButton;
88
89 public WorkbenchViewImpl() {
90 setSizeFull();
91 addStyleName("workbench");
92 setSpacing(false);
93 setMargin(false);
94
95 HorizontalLayout toolBarWrapper = new HorizontalLayout();
96 toolBarWrapper.addStyleName("toolbar");
97 toolBarWrapper.setWidth(100.0F, Unit.PERCENTAGE);
98 toolBarWrapper.setSpacing(true);
99 toolBarWrapper.setDefaultComponentAlignment(Alignment.BOTTOM_LEFT);
100
101 title = new Label();
102 title.addStyleName("heading-1");
103 title.setVisible(false);
104 toolBarWrapper.addComponent(title);
105 toolBarWrapper.setExpandRatio(title, 0);
106
107 Label spacer = new Label();
108 toolBarWrapper.addComponent(spacer);
109 toolBarWrapper.setExpandRatio(spacer, 1f);
110
111 toolBar.addStyleName("tools");
112 toolBar.setSpacing(true);
113
114 createFilterToggle();
115
116 viewModes.setStyleName("view-modes");
117 viewModes.setSpacing(true);
118 toolBar.addComponent(viewModes);
119 toolBar.setComponentAlignment(viewModes, Alignment.BOTTOM_RIGHT);
120
121 toolBarWrapper.addComponent(toolBar);
122 toolBarWrapper.setComponentAlignment(toolBar, Alignment.BOTTOM_RIGHT);
123 toolBarWrapper.setExpandRatio(toolBar, 0);
124
125 addComponent(toolBarWrapper);
126 setExpandRatio(toolBarWrapper, 0.0F);
127
128 addComponent(filterBar);
129 setExpandRatio(filterBar, 0.0F);
130 filterBar.addStyleName("filter-bar");
131 filterBar.setWidth(100, Unit.PERCENTAGE);
132 filterBar.setVisible(false);
133
134 this.keyboardEventPanel = new Panel();
135 this.keyboardEventPanel.setSizeFull();
136 this.keyboardEventPanel.addStyleName("keyboard-panel");
137 addComponent(keyboardEventPanel, 2);
138 setExpandRatio(keyboardEventPanel, 1.0F);
139
140 bindKeyboardHandlers();
141 }
142
143 private void createFilterToggle() {
144 toggleButton = new Button(MagnoliaIcons.SEARCH_RESULT_FILTERS);
145 toggleButton.addStyleNames(ResurfaceTheme.BUTTON_ICON);
146 toggleButton.addStyleName("filter-toggle");
147 toggleButton.setVisible(false);
148
149 toolBar.addComponent(toggleButton);
150 toolBar.setComponentAlignment(toggleButton, Alignment.BOTTOM_RIGHT);
151
152 toggleButton.addClickListener(event -> {
153 boolean filterVisible = filterBar.isVisible();
154
155 filterBar.setVisible(!filterVisible);
156
157 if (!filterVisible) {
158 toggleButton.addStyleName("active");
159 } else {
160 toggleButton.removeStyleName("active");
161 }
162 });
163 }
164
165
166
167
168 @Deprecated
169 public WorkbenchViewImpl(SimpleTranslator i18n) {
170 this();
171 }
172
173 public void bindKeyboardHandlers() {
174
175 final ShortcutListener enterShortcut = new ShortcutListener("Enter shortcut", ShortcutAction.KeyCode.ENTER, null) {
176 @Override
177 public void handleAction(Object sender, Object target) {
178 getSelectedView().onShortcutKey(KeyCode.ENTER, null);
179 }
180 };
181 keyboardEventPanel.addShortcutListener(enterShortcut);
182
183 final ShortcutListener deleteShortcut = new ShortcutListener("Delete shortcut", ShortcutAction.KeyCode.DELETE, null) {
184 @Override
185 public void handleAction(Object sender, Object target) {
186 getSelectedView().onShortcutKey(KeyCode.DELETE, null);
187 }
188 };
189
190
191 }
192
193 @Override
194 public void setSearchQuery(String query) {
195 if (listener != null) {
196 listener.onSearchQueryChange(query);
197 }
198 }
199
200
201
202
203
204
205 @Deprecated
206 @Override
207 public void addContentView(String viewType, ContentView view, ContentPresenterDefinition contentViewDefintion) {
208 addContentView(viewType, view, contentViewDefintion.getIcon());
209 }
210
211
212
213
214 public void addContentView(String viewType, ContentView view, String viewTypeIcon) {
215 contentViews.put(viewType, view);
216
217 if (view instanceof TreeView) {
218 ((TreeView) view).setActionManager(keyboardEventPanel);
219 }
220
221
222 if (contentViews.containsKey(ListPresenterDefinition.VIEW_TYPE) && contentViews.containsKey(SearchPresenterDefinition.VIEW_TYPE)) {
223 int contentToolsCount = toolBar.getComponentCount();
224 if (contentToolsCount > 1) {
225 toolBar.getComponent(contentToolsCount - 1).setVisible(true);
226 }
227 }
228
229 if (SearchPresenterDefinition.VIEW_TYPE.equals(viewType)) {
230
231 return;
232 }
233
234
235 Button button;
236 if (!AdmincentralFlavour.get().isM5()) {
237 button = new Button(MagnoliaIcons.forCssClass(viewTypeIcon).orElse(MagnoliaIcons.VIEW_LIST),
238 clickEvent -> fireViewTypeChangedEvent(viewType));
239 } else {
240 button = buildButton(viewType, viewTypeIcon);
241 }
242 button.addStyleName(ResurfaceTheme.BUTTON_ICON);
243 contentViewsButton.put(viewType, button);
244 viewModes.addComponent(button);
245 viewModes.setVisible(contentViews.size() > 1);
246 }
247
248 @Override
249 public void setViewType(String type) {
250 final Component c = contentViews.get(type).asVaadinComponent();
251
252 keyboardEventPanel.setContent(c);
253
254 if (SearchPresenterDefinition.VIEW_TYPE.equals(currentViewType) && !SearchPresenterDefinition.VIEW_TYPE.equals(type)) {
255 setSearchQuery(null);
256 }
257 setViewTypeStyling(type);
258 currentViewType = type;
259 }
260
261 private void fireViewTypeChangedEvent(String viewType) {
262 this.listener.onViewTypeChanged(viewType);
263 }
264
265 @Override
266 public void setStatusBarView(StatusBarView statusBar) {
267 if (AdmincentralFlavour.get().isM5()) {
268 Component c = statusBar.asVaadinComponent();
269 if (this.statusBar == null) {
270 addComponent(c, getComponentCount());
271 } else {
272 replaceComponent(this.statusBar.asVaadinComponent(), c);
273 }
274 setExpandRatio(c, 0);
275 }
276 this.statusBar = statusBar;
277 }
278
279 @Override
280 public View getStatusBarView() {
281 return this.statusBar;
282 }
283
284 @Override
285 public ContentView getSelectedView() {
286 return contentViews.get(currentViewType);
287 }
288
289 @Override
290 public Component asVaadinComponent() {
291 return this;
292 }
293
294 @Override
295 public void setListener(WorkbenchView.Listener listener) {
296 this.listener = listener;
297 }
298
299 @Override
300 public void setTitle(String title) {
301 this.title.setValue(title);
302 this.title.setVisible(true);
303 }
304
305 @Deprecated
306 private Button buildButton(final String viewType, final String icon) {
307 Button button = new Button();
308 button.addClickListener((Button.ClickListener) event -> fireViewTypeChangedEvent(viewType));
309 button.setCaptionAsHtml(true);
310 button.setCaption("<span class=\"" + icon + "\"></span>");
311 return button;
312 }
313
314 private void setViewTypeStyling(final String viewType) {
315 for (Map.Entry<String, Button> entry : contentViewsButton.entrySet()) {
316 entry.getValue().removeStyleName("active");
317 if (entry.getKey().equals(viewType)) {
318 entry.getValue().addStyleName("active");
319 }
320 }
321
322 if (viewType.equals(SearchPresenterDefinition.VIEW_TYPE) && contentViews.containsKey(ListPresenterDefinition.VIEW_TYPE)) {
323 contentViewsButton.get(ListPresenterDefinition.VIEW_TYPE).addStyleName("active");
324 }
325 }
326
327 @Override
328 public void setMultiselect(boolean multiselect) {
329 for (String type : contentViews.keySet()) {
330 contentViews.get(type).setMultiselect(multiselect);
331 }
332 }
333
334 @Override
335 public void addContentTool(View view) {
336 addContentTool(view, ContentToolDefinition.Alignment.RIGHT, 0);
337 }
338
339 @Override
340 public void addContentTool(View view, ContentToolDefinition.Alignment alignment, float expandRatio) {
341 final Component toolComponent = view.asVaadinComponent();
342
343 toolComponent.addStyleName("content-tool");
344
345 toolBar.addComponent(toolComponent, 0);
346 toolBar.setExpandRatio(toolComponent, expandRatio);
347
348 Alignment vaadinAlignment;
349 switch (alignment) {
350 case RIGHT:
351 vaadinAlignment = Alignment.MIDDLE_RIGHT;
352 break;
353 case LEFT:
354 vaadinAlignment = Alignment.MIDDLE_LEFT;
355 break;
356 case CENTER:
357 vaadinAlignment = Alignment.MIDDLE_CENTER;
358 break;
359 default:
360 vaadinAlignment = Alignment.MIDDLE_RIGHT;
361 }
362
363 toolBar.setComponentAlignment(toolComponent, vaadinAlignment);
364 }
365
366 @Override
367 public void addFilterComponent(View view) {
368 final Component filterComponent = view.asVaadinComponent();
369
370 filterComponent.addStyleName("content-filter");
371 filterBar.addComponent(filterComponent);
372 toggleButton.setVisible(true);
373 }
374 }