1 /*
2  * Copyright (C) Azureus Software, Inc, All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details ( see the LICENSE file ).
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18 
19 package com.aelitis.azureus.ui.swt.skin;
20 
21 import org.eclipse.swt.SWT;
22 import org.eclipse.swt.graphics.Point;
23 import org.eclipse.swt.layout.FormData;
24 import org.eclipse.swt.widgets.*;
25 
26 import org.gudy.azureus2.core3.config.COConfigurationManager;
27 import org.gudy.azureus2.core3.util.AERunnable;
28 import org.gudy.azureus2.core3.util.AERunnableBoolean;
29 import org.gudy.azureus2.core3.util.Debug;
30 import org.gudy.azureus2.ui.swt.Utils;
31 
32 /**
33  * @author TuxPaper
34  * @created Jun 8, 2006
35  *
36  */
37 public class SWTSkinUtils
38 {
39 
40 	public static final int TILE_NONE = 0;
41 
42 	public static final int TILE_Y = 1;
43 
44 	public static final int TILE_X = 2;
45 
46 	public static final int TILE_CENTER_X = 4;
47 
48 	public static final int TILE_CENTER_Y = 8;
49 
50 	public static final int TILE_BOTH = TILE_X | TILE_Y;
51 
52 	private static Listener imageDownListener;
53 
54 	//private static Listener imageOverListener;
55 
56 	static {
57 		//imageOverListener = new SWTSkinImageChanger("-over", SWT.MouseEnter,
58 		//		SWT.MouseExit);
59 		imageDownListener = new SWTSkinImageChanger("-down", SWT.MouseDown,
60 				SWT.MouseUp);
61 	}
62 
getAlignment(String sAlign, int def)63 	public static int getAlignment(String sAlign, int def) {
64 		int align;
65 
66 		if (sAlign == null) {
67 			align = def;
68 		} else if (sAlign.equalsIgnoreCase("center")) {
69 			align = SWT.CENTER;
70 		} else if (sAlign.equalsIgnoreCase("bottom")) {
71 			align = SWT.BOTTOM;
72 		} else if (sAlign.equalsIgnoreCase("top")) {
73 			align = SWT.TOP;
74 		} else if (sAlign.equalsIgnoreCase("left")) {
75 			align = SWT.LEFT;
76 		} else if (sAlign.equalsIgnoreCase("right")) {
77 			align = SWT.RIGHT;
78 		} else {
79 			align = def;
80 		}
81 
82 		return align;
83 	}
84 
85 	/**
86 	 * @param tileMode
87 	 * @return
88 	 */
getTileMode(String sTileMode)89 	public static int getTileMode(String sTileMode) {
90 		int tileMode = TILE_NONE;
91 		if (sTileMode == null || sTileMode == "") {
92 			return tileMode;
93 		}
94 
95 		sTileMode = sTileMode.toLowerCase();
96 
97 		if (sTileMode.equals("tile")) {
98 			tileMode = TILE_X | TILE_Y;
99 		} else if (sTileMode.equals("tile-x")) {
100 			tileMode = TILE_X;
101 		} else if (sTileMode.equals("tile-y")) {
102 			tileMode = TILE_Y;
103 		} else if (sTileMode.equals("center-x")) {
104 			tileMode = TILE_CENTER_X;
105 		} else if (sTileMode.equals("center-y")) {
106 			tileMode = TILE_CENTER_Y;
107 		}
108 
109 		return tileMode;
110 	}
111 
addMouseImageChangeListeners(Control widget)112 	static void addMouseImageChangeListeners(Control widget) {
113 		if (widget.getData("hasMICL") != null) {
114 			return;
115 		}
116 
117 		//widget.addListener(SWT.MouseEnter, imageOverListener);
118 		//widget.addListener(SWT.MouseExit, imageOverListener);
119 		//		new MouseEnterExitListener(widget);
120 
121 		widget.addListener(SWT.MouseDown, imageDownListener);
122 		widget.addListener(SWT.MouseUp, imageDownListener);
123 
124 		widget.setData("hasMICL", "1");
125 	}
126 
setVisibility(SWTSkin skin, String configID, String viewID, boolean visible)127 	public static void setVisibility(SWTSkin skin, String configID,
128 			String viewID, boolean visible) {
129 		setVisibility(skin, configID, viewID, visible, true, false);
130 	}
131 
setVisibility(SWTSkin skin, String configID, String viewID, final boolean visible, boolean save, boolean fast)132 	public static void setVisibility(SWTSkin skin, String configID,
133 			String viewID, final boolean visible, boolean save, boolean fast) {
134 
135 		SWTSkinObject skinObject = skin.getSkinObject(viewID);
136 
137 		if (skinObject == null) {
138 			Debug.out("setVisibility on non existing skin object: " + viewID);
139 			return;
140 		}
141 
142 		if (skinObject.isVisible() == visible && skin.getShell().isVisible()) {
143 			return;
144 		}
145 
146 		final Control control = skinObject.getControl();
147 
148 		if (control != null && !control.isDisposed()) {
149 			Point size;
150 			if (visible) {
151 				final FormData fd = (FormData) control.getLayoutData();
152 				size = (Point) control.getData("v3.oldHeight");
153 				//System.out.println(control.getData("SkinID") + " oldHeight = " + size + ";v=" + control.getVisible() + ";s=" + control.getSize());
154 				if (size == null) {
155 					size = control.computeSize(SWT.DEFAULT, SWT.DEFAULT);
156 					if (fd.height > 0) {
157 						size.y = fd.height;
158 					}
159 					if (fd.width > 0) {
160 						size.x = fd.width;
161 					}
162 				}
163 			} else {
164 				size = new Point(0, 0);
165 			}
166 			setVisibility(skin, configID, skinObject, size, save, fast, null);
167 		}
168 	}
169 
setVisibility(SWTSkin skin, String configID, final SWTSkinObject skinObject, final Point destSize, boolean save, boolean fast, Runnable runAfterSlide)170 	public static void setVisibility(SWTSkin skin, String configID,
171 			final SWTSkinObject skinObject, final Point destSize, boolean save,
172 			boolean fast, Runnable runAfterSlide) {
173 		boolean visible = destSize.x != 0 || destSize.y != 0;
174 		try {
175 			if (skinObject == null) {
176 				return;
177 			}
178 			final Control control = skinObject.getControl();
179 			if (control != null && !control.isDisposed()) {
180 				if (visible) {
181 					FormData fd = (FormData) control.getLayoutData();
182 					fd.width = 0;
183 					fd.height = 0;
184 					control.setData("oldSize", new Point(0, 0));
185 
186 					skinObject.setVisible(visible);
187 
188 					// FormData should now be 0,0, but setVisible may have
189 					// explicitly changed it
190 					fd = (FormData) control.getLayoutData();
191 
192 					if (fd.width != 0 || fd.height != 0) {
193 						return;
194 					}
195 
196 					//if (destSize != null) {
197 						if (fd.width != destSize.x || fd.height != destSize.y) {
198 							if (fast) {
199 								fd.width = destSize.x;
200 								fd.height = destSize.y;
201 								control.setLayoutData(fd);
202 								Utils.relayout(control);
203 							} else {
204 								slide(skinObject, fd, destSize, runAfterSlide);
205 								runAfterSlide = null; // prevent calling again
206 							}
207 						}
208 					/*} else {
209 						if (fd.width == 0) {
210 							fd.width = SWT.DEFAULT;
211 						}
212 						if (fd.height == 0) {
213 							fd.height = SWT.DEFAULT;
214 						}
215 						control.setLayoutData(fd);
216 						Utils.relayout(control);
217 					}*/
218 					control.setData("v3.oldHeight", null);
219 				} else {
220 					final FormData fd = (FormData) control.getLayoutData();
221 					if (fd != null) {
222 						Point oldSize = new Point(fd.width, fd.height);
223 						if (oldSize.y <= 0) {
224 							oldSize = null;
225 						}
226 						control.setData("v3.oldHeight", oldSize);
227 
228 						if (fast) {
229 							skinObject.setVisible(false);
230 						} else {
231 							slide(skinObject, fd, destSize, runAfterSlide);
232 							runAfterSlide = null; // prevent calling again
233 						}
234 					}
235 				}
236 			}
237 
238 		} finally {
239 			if (save
240 					&& COConfigurationManager.getBooleanParameter(configID) != visible) {
241 				COConfigurationManager.setParameter(configID, visible);
242 			}
243 
244 			if (runAfterSlide != null) {
245 				runAfterSlide.run();
246 			}
247 		}
248 	}
249 
slide(final SWTSkinObject skinObject, final FormData fd, final Point destSize, final Runnable runOnCompletion)250 	public static void slide(final SWTSkinObject skinObject, final FormData fd,
251 			final Point destSize, final Runnable runOnCompletion) {
252 		final Control control = skinObject.getControl();
253 		//System.out.println("slide to " + size + " via "+ Debug.getCompressedStackTrace());
254 		Boolean exit = Utils.execSWTThreadWithBool("slide",
255 				new AERunnableBoolean() {
256 					public boolean runSupport() {
257 						boolean exit = control.getData("slide.active") != null;
258 						Runnable oldROC = (Runnable) control.getData("slide.runOnCompletion");
259 						if (oldROC != null) {
260 							oldROC.run();
261 						}
262 						control.setData("slide.destSize", destSize);
263 						control.setData("slide.runOnCompletion", runOnCompletion);
264 						if (destSize.y > 0) {
265 							skinObject.setVisible(true);
266 						}
267 						return exit;
268 					}
269 				}, 1000);
270 
271 		if (exit == null || exit) {
272 			return;
273 		}
274 
275 		AERunnable runnable = new AERunnable() {
276 			boolean firstTime = true;
277 
278 			float pct = 0.4f;
279 
280 			public void runSupport() {
281 				if (control.isDisposed()) {
282 					return;
283 				}
284 				Point size = (Point) control.getData("slide.destSize");
285 				if (size == null) {
286 					return;
287 				}
288 
289 				if (firstTime) {
290 					firstTime = false;
291 					control.setData("slide.active", "1");
292 				}
293 
294 				int newWidth = (int) (fd.width + (size.x - fd.width) * pct);
295 				int h = fd.height >= 0 ? fd.height : control.getSize().y;
296 				int newHeight = (int) (h + (size.y - h) * pct);
297 				pct += 0.01;
298 				//System.out.println(control + "] newh=" + newHeight + "/" + newWidth + " to " + size.y);
299 
300 				if (newWidth == fd.width && newHeight == h) {
301 					fd.width = size.x;
302 					fd.height = size.y;
303 					//System.out.println(control + "] side to " + size.y + " done" + size.x);
304 					control.setLayoutData(fd);
305 					Utils.relayout(control);
306 					control.getParent().layout();
307 
308 					control.setData("slide.active", null);
309 					control.setData("slide.destSize", null);
310 
311 					if (newHeight == 0) {
312 						skinObject.setVisible(false);
313 						Utils.relayout(control);
314 					}
315 
316 					Runnable oldROC = (Runnable) control.getData("slide.runOnCompletion");
317 					if (oldROC != null) {
318 						control.setData("slide.runOnCompletion", null);
319 						oldROC.run();
320 					}
321 				} else {
322 					fd.width = newWidth;
323 					fd.height = newHeight;
324 					control.setLayoutData(fd);
325 					//Utils.relayout(control, false);
326 					control.getParent().layout();
327 
328 					Utils.execSWTThreadLater(20, this);
329 				}
330 			}
331 		};
332 		control.getDisplay().asyncExec(runnable);
333 	}
334 
335 	public static class MouseEnterExitListener
336 		implements Listener
337 	{
338 
339 		boolean bOver = false;
340 
MouseEnterExitListener(Widget widget)341 		public MouseEnterExitListener(Widget widget) {
342 
343 			widget.addListener(SWT.MouseMove, this);
344 			widget.addListener(SWT.MouseExit, this);
345 		}
346 
handleEvent(Event event)347 		public void handleEvent(Event event) {
348 			Control control = (Control) event.widget;
349 
350 			SWTSkinObject skinObject = (SWTSkinObject) control.getData("SkinObject");
351 
352 			if (event.type == SWT.MouseMove) {
353 				if (bOver) {
354 					return;
355 				}
356 				System.out.println(System.currentTimeMillis() + ": " + skinObject
357 						+ "-- OVER");
358 				bOver = true;
359 				skinObject.switchSuffix("-over", 2, true);
360 
361 			} else {
362 				bOver = false;
363 				System.out.println(System.currentTimeMillis() + ": " + skinObject
364 						+ "-- NOOVER");
365 				skinObject.switchSuffix("", 2, true);
366 			}
367 
368 		}
369 
370 	}
371 
372 
findBrowserSO(SWTSkinObject so)373 	public static SWTSkinObjectBrowser findBrowserSO(SWTSkinObject so) {
374 		if (so instanceof SWTSkinObjectBrowser) {
375 			return (SWTSkinObjectBrowser) so;
376 		}
377 		if (so instanceof SWTSkinObjectContainer) {
378 			SWTSkinObjectContainer soContainer = (SWTSkinObjectContainer) so;
379 			SWTSkinObject[] children = soContainer.getChildren();
380 			for (int i = 0; i < children.length; i++) {
381 				SWTSkinObject child = children[i];
382 				SWTSkinObjectBrowser found = findBrowserSO(child);
383 				if (found != null) {
384 					return found;
385 				}
386 			}
387 		}
388 		return null;
389 	}
390 
391 }
392