1 2 package $packageName$; 3 4 import java.util.ArrayList; 5 import java.util.Iterator; 6 7 import org.eclipse.core.runtime.IConfigurationElement; 8 import org.eclipse.core.runtime.IExtension; 9 import org.eclipse.core.runtime.Platform; 10 import org.eclipse.jface.resource.ImageDescriptor; 11 import org.eclipse.swt.SWT; 12 import org.eclipse.swt.graphics.Image; 13 import org.eclipse.swt.graphics.Point; 14 import org.eclipse.swt.layout.GridLayout; 15 import org.eclipse.swt.widgets.Composite; 16 import org.eclipse.swt.widgets.Label; 17 import org.eclipse.swt.widgets.Shell; 18 import org.eclipse.ui.plugin.AbstractUIPlugin; 19 import org.eclipse.ui.splash.AbstractSplashHandler; 20 21 /** 22 * @since 3.3 23 * 24 */ 25 public class ExtensibleSplashHandler extends AbstractSplashHandler { 26 27 private ArrayList fImageList; 28 29 private ArrayList fTooltipList; 30 31 private final static String F_SPLASH_EXTENSION_ID = "$pluginId$.splashExtension"; //$NON-NLS-1$ 32 33 private final static String F_ELEMENT_ICON = "icon"; //$NON-NLS-1$ 34 35 private final static String F_ELEMENT_TOOLTIP = "tooltip"; //$NON-NLS-1$ 36 37 private final static String F_DEFAULT_TOOLTIP = "Image"; //$NON-NLS-1$ 38 39 private final static int F_IMAGE_WIDTH = 50; 40 41 private final static int F_IMAGE_HEIGHT = 50; 42 43 private final static int F_SPLASH_SCREEN_BEVEL = 5; 44 45 private Composite fIconPanel; 46 47 /** 48 * 49 */ ExtensibleSplashHandler()50 public ExtensibleSplashHandler() { 51 fImageList = new ArrayList(); 52 fTooltipList = new ArrayList(); 53 fIconPanel = null; 54 } 55 56 /* (non-Javadoc) 57 * @see org.eclipse.ui.splash.AbstractSplashHandler#init(org.eclipse.swt.widgets.Shell) 58 */ init(Shell splash)59 public void init(Shell splash) { 60 // Store the shell 61 super.init(splash); 62 // Configure the shell layout 63 configureUISplash(); 64 // Load all splash extensions 65 loadSplashExtensions(); 66 // If no splash extensions were loaded abort the splash handler 67 if (hasSplashExtensions() == false) { 68 return; 69 } 70 // Create UI 71 createUI(); 72 // Configure the image panel bounds 73 configureUICompositeIconPanelBounds(); 74 // Enter event loop and prevent the RCP application from 75 // loading until all work is done 76 doEventLoop(); 77 } 78 79 /** 80 * @return 81 */ hasSplashExtensions()82 private boolean hasSplashExtensions() { 83 if (fImageList.isEmpty()) { 84 return false; 85 } else { 86 return true; 87 } 88 } 89 90 /** 91 * 92 */ createUI()93 private void createUI() { 94 // Create the icon panel 95 createUICompositeIconPanel(); 96 // Create the images 97 createUIImages(); 98 } 99 100 /** 101 * 102 */ createUIImages()103 private void createUIImages() { 104 Iterator imageIterator = fImageList.iterator(); 105 Iterator tooltipIterator = fTooltipList.iterator(); 106 int i = 1; 107 int columnCount = ((GridLayout)fIconPanel.getLayout()).numColumns; 108 // Create all the images 109 // Abort if we run out of columns (left-over images will not fit within 110 // the usable splash screen width) 111 while (imageIterator.hasNext() && 112 (i <= columnCount)) { 113 Image image = (Image)imageIterator.next(); 114 String tooltip = (String)tooltipIterator.next(); 115 // Create the image using a label widget 116 createUILabel(image, tooltip); 117 i++; 118 } 119 } 120 121 /** 122 * @param image 123 * @param tooltip 124 */ createUILabel(Image image, String tooltip)125 private void createUILabel(Image image, String tooltip) { 126 // Create the label (no text) 127 Label label = new Label(fIconPanel, SWT.NONE); 128 label.setImage(image); 129 label.setToolTipText(tooltip); 130 } 131 132 /** 133 * 134 */ createUICompositeIconPanel()135 private void createUICompositeIconPanel() { 136 Shell splash = getSplash(); 137 // Create the composite 138 fIconPanel = new Composite(splash, SWT.NONE); 139 // Determine the maximum number of columns that can fit on the splash 140 // screen. One 50x50 image per column. 141 int maxColumnCount = getUsableSplashScreenWidth() / F_IMAGE_WIDTH; 142 // Limit size to the maximum number of columns if the number of images 143 // exceed this amount; otherwise, use the exact number of columns 144 // required. 145 int actualColumnCount = Math.min(fImageList.size(), maxColumnCount); 146 // Configure the layout 147 GridLayout layout = new GridLayout(actualColumnCount, true); 148 layout.horizontalSpacing = 0; 149 layout.verticalSpacing = 0; 150 layout.marginHeight = 0; 151 layout.marginWidth = 0; 152 fIconPanel.setLayout(layout); 153 } 154 155 /** 156 * 157 */ configureUICompositeIconPanelBounds()158 private void configureUICompositeIconPanelBounds() { 159 // Determine the size of the panel and position it at the bottom-right 160 // of the splash screen. 161 Point panelSize = fIconPanel.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); 162 163 int x_coord = getSplash().getSize().x - F_SPLASH_SCREEN_BEVEL - panelSize.x; 164 int y_coord = getSplash().getSize().y - F_SPLASH_SCREEN_BEVEL - panelSize.y; 165 int x_width = panelSize.x; 166 int y_width = panelSize.y; 167 168 fIconPanel.setBounds(x_coord, y_coord, x_width, y_width); 169 } 170 171 /** 172 * @return 173 */ getUsableSplashScreenWidth()174 private int getUsableSplashScreenWidth() { 175 // Splash screen width minus two graphic border bevel widths 176 return getSplash().getSize().x - (F_SPLASH_SCREEN_BEVEL * 2); 177 } 178 179 /** 180 * 181 */ loadSplashExtensions()182 private void loadSplashExtensions() { 183 // Get all splash handler extensions 184 IExtension[] extensions = 185 Platform.getExtensionRegistry().getExtensionPoint( 186 F_SPLASH_EXTENSION_ID).getExtensions(); 187 // Process all splash handler extensions 188 for (int i = 0; i < extensions.length; i++) { 189 processSplashExtension(extensions[i]); 190 } 191 } 192 193 /** 194 * @param extension 195 */ processSplashExtension(IExtension extension)196 private void processSplashExtension(IExtension extension) { 197 // Get all splash handler configuration elements 198 IConfigurationElement[] elements = extension.getConfigurationElements(); 199 // Process all splash handler configuration elements 200 for (int j = 0; j < elements.length; j++) { 201 processSplashElements(elements[j]); 202 } 203 } 204 205 /** 206 * @param configurationElement 207 */ processSplashElements( IConfigurationElement configurationElement)208 private void processSplashElements( 209 IConfigurationElement configurationElement) { 210 // Attribute: icon 211 processSplashElementIcon(configurationElement); 212 // Attribute: tooltip 213 processSplashElementTooltip(configurationElement); 214 } 215 216 /** 217 * @param configurationElement 218 */ processSplashElementTooltip( IConfigurationElement configurationElement)219 private void processSplashElementTooltip( 220 IConfigurationElement configurationElement) { 221 // Get attribute tooltip 222 String tooltip = configurationElement.getAttribute(F_ELEMENT_TOOLTIP); 223 // If a tooltip is not defined, give it a default 224 if ((tooltip == null) || 225 (tooltip.length() == 0)) { 226 fTooltipList.add(F_DEFAULT_TOOLTIP); 227 } else { 228 fTooltipList.add(tooltip); 229 } 230 } 231 232 /** 233 * @param configurationElement 234 */ processSplashElementIcon( IConfigurationElement configurationElement)235 private void processSplashElementIcon( 236 IConfigurationElement configurationElement) { 237 // Get attribute icon 238 String iconImageFilePath = configurationElement.getAttribute(F_ELEMENT_ICON); 239 // Abort if an icon attribute was not specified 240 if ((iconImageFilePath == null) || 241 (iconImageFilePath.length() == 0)) { 242 return; 243 } 244 // Create a corresponding image descriptor 245 ImageDescriptor descriptor = 246 AbstractUIPlugin.imageDescriptorFromPlugin( 247 configurationElement.getNamespaceIdentifier(), 248 iconImageFilePath); 249 // Abort if no corresponding image was found 250 if (descriptor == null) { 251 return; 252 } 253 // Create the image 254 Image image = descriptor.createImage(); 255 // Abort if image creation failed 256 if (image == null) { 257 return; 258 } 259 // Abort if the image does not have dimensions of 50x50 260 if ((image.getBounds().width != F_IMAGE_WIDTH) || 261 (image.getBounds().height != F_IMAGE_HEIGHT)) { 262 // Dipose of the image 263 image.dispose(); 264 return; 265 } 266 // Store the image and tooltip 267 fImageList.add(image); 268 } 269 270 /** 271 * 272 */ configureUISplash()273 private void configureUISplash() { 274 // Configure layout 275 GridLayout layout = new GridLayout(1, true); 276 getSplash().setLayout(layout); 277 // Force shell to inherit the splash background 278 getSplash().setBackgroundMode(SWT.INHERIT_DEFAULT); 279 } 280 281 /** 282 * 283 */ doEventLoop()284 private void doEventLoop() { 285 Shell splash = getSplash(); 286 if (splash.getDisplay().readAndDispatch() == false) { 287 splash.getDisplay().sleep(); 288 } 289 } 290 291 /* (non-Javadoc) 292 * @see org.eclipse.ui.splash.AbstractSplashHandler#dispose() 293 */ dispose()294 public void dispose() { 295 super.dispose(); 296 // Check to see if any images were defined 297 if ((fImageList == null) || 298 fImageList.isEmpty()) { 299 return; 300 } 301 // Dispose of all the images 302 Iterator iterator = fImageList.iterator(); 303 while (iterator.hasNext()) { 304 Image image = (Image) iterator.next(); 305 image.dispose(); 306 } 307 } 308 } 309