1 /*******************************************************************************
2  * Copyright (c) 2009, 2017 Angelo Zerr and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
13  *     IBM Corporation - initial API and implementation
14  *     Simon Scholz <simon.scholz@vogella.com> - Bug 513300
15  *******************************************************************************/
16 package org.eclipse.e4.ui.css.swt.dom;
17 
18 import java.util.Objects;
19 import java.util.function.Supplier;
20 import org.eclipse.e4.ui.css.core.dom.CSSStylableElement;
21 import org.eclipse.e4.ui.css.core.engine.CSSEngine;
22 import org.eclipse.e4.ui.css.swt.helpers.CSSSWTImageHelper;
23 import org.eclipse.swt.events.ShellEvent;
24 import org.eclipse.swt.events.ShellListener;
25 import org.eclipse.swt.widgets.Composite;
26 import org.eclipse.swt.widgets.Shell;
27 import org.w3c.dom.Node;
28 
29 /**
30  * {@link CSSStylableElement} implementation which wrap SWT {@link Shell}.
31  *
32  */
33 public class ShellElement extends CompositeElement {
34 
35 	protected boolean isActive;
36 
37 	// Create SWT Shell Listener
38 	private ShellListener shellListener = new ShellListener() {
39 
40 		@Override
41 		public void shellActivated(ShellEvent e) {
42 			ShellElement.this.isActive = true;
43 			doApplyStyles();
44 		}
45 
46 		@Override
47 		public void shellDeactivated(ShellEvent e) {
48 			ShellElement.this.isActive = false;
49 			doApplyStyles();
50 		}
51 
52 		@Override
53 		public void shellDeiconified(ShellEvent e) {
54 		}
55 
56 		@Override
57 		public void shellIconified(ShellEvent e) {
58 		}
59 
60 		@Override
61 		public void shellClosed(ShellEvent e) {
62 			ShellElement.this.dispose();
63 		}
64 	};
65 
ShellElement(Shell shell, CSSEngine engine)66 	public ShellElement(Shell shell, CSSEngine engine) {
67 		super(shell, engine);
68 	}
69 
70 	@Override
initialize()71 	public void initialize() {
72 		super.initialize();
73 
74 		Shell shell = getShell();
75 
76 		if (!dynamicEnabled) {
77 			return;
78 		}
79 
80 		// Add Shell listener
81 		shell.addShellListener(shellListener);
82 	}
83 
84 	@Override
getParentNode()85 	public Node getParentNode() {
86 		// Shells are considered as root notes; see bug 375069
87 		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=375069
88 		return null;
89 	}
90 
getShell()91 	private Shell getShell() {
92 		return (Shell) getNativeWidget();
93 	}
94 
95 	@Override
dispose()96 	public void dispose() {
97 		super.dispose();
98 
99 		if (!dynamicEnabled) {
100 			return;
101 		}
102 
103 		Shell shell = getShell();
104 		if (!shell.isDisposed()) {
105 			shell.removeShellListener(shellListener);
106 		}
107 	}
108 
109 	@Override
isPseudoInstanceOf(String s)110 	public boolean isPseudoInstanceOf(String s) {
111 		if ("active".equalsIgnoreCase(s)) {
112 			return this.isActive;
113 		}
114 		if ("swt-parented".equalsIgnoreCase(s)) {
115 			return getShell().getParent() != null;
116 		}
117 		if ("swt-unparented".equalsIgnoreCase(s)) {
118 			return getShell().getParent() == null;
119 		}
120 		return super.isPseudoInstanceOf(s);
121 	}
122 
123 	@Override
internalGetAttribute(String attr)124 	protected Supplier<String> internalGetAttribute(String attr) {
125 		if("title".equals(attr)) {
126 			return () -> Objects.toString(getShell().getText(), "");
127 		}
128 		if ("parentage".equals(attr)) {
129 			return () -> {
130 				Shell shell = getShell();
131 				Composite parent = shell.getParent();
132 				if (parent == null) {
133 					return "";
134 				}
135 				StringBuilder sb = new StringBuilder();
136 				do {
137 					String id = WidgetElement.getID(parent);
138 					if (id != null && id.length() > 0) {
139 						sb.append(id).append(' ');
140 					}
141 					parent = parent.getParent();
142 				} while (parent != null);
143 				return sb.toString().trim();
144 			};
145 		}
146 		return super.internalGetAttribute(attr);
147 	}
148 
149 	@Override
reset()150 	public void reset() {
151 		CSSSWTImageHelper.restoreDefaultImage(getShell());
152 		super.reset();
153 	}
154 }
155