| @@ -13,5 +13,6 @@ | |||
| <attribute name="maven.pomderived" value="true"/> | |||
| </attributes> | |||
| </classpathentry> | |||
| <classpathentry kind="lib" path="swing2swt.jar"/> | |||
| <classpathentry kind="output" path="target/classes"/> | |||
| </classpath> | |||
| @@ -1,30 +1,10 @@ | |||
| <?xml version="1.0" encoding="ASCII"?> | |||
| <application:Application xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:application="http://www.eclipse.org/ui/2010/UIModel/application" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic" xmlns:menu="http://www.eclipse.org/ui/2010/UIModel/application/ui/menu" xmi:id="_Lw_ZsEqSEeqT5sxfmvJ5Tg" elementId="xyz.veronie.bgg.ui.application"> | |||
| <children xsi:type="basic:TrimmedWindow" xmi:id="_QDxdgEqSEeqT5sxfmvJ5Tg" elementId="xyz.veronie.bgg.ui.trimmedwindow.main" label="BGG Tool Another" width="1600" height="900"> | |||
| <children xsi:type="basic:PartSashContainer" xmi:id="_B_h_UEqVEeqT5sxfmvJ5Tg" elementId="xyz.veronie.bgg.ui.partsashcontainer.0"> | |||
| <children xsi:type="basic:PartSashContainer" xmi:id="_tbnr0EqTEeqT5sxfmvJ5Tg" elementId="xyz.veronie.bgg.ui.partsashcontainer.main" horizontal="true"> | |||
| <children xsi:type="basic:PartSashContainer" xmi:id="_4NsHQEqTEeqT5sxfmvJ5Tg" elementId="xyz.veronie.bgg.ui.partsashcontainer.left"> | |||
| <children xsi:type="basic:PartStack" xmi:id="_7KNiwEqTEeqT5sxfmvJ5Tg" elementId="xyz.veronie.bgg.ui.partstack.leftupper" containerData="800"> | |||
| <children xsi:type="basic:Part" xmi:id="_9ocfwEqTEeqT5sxfmvJ5Tg" elementId="xyz.veronie.bgg.ui.part.resultconfig" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.parts.PreparePart" label="Prepare"/> | |||
| </children> | |||
| <children xsi:type="basic:PartStack" xmi:id="_0MbRQEqTEeqT5sxfmvJ5Tg" elementId="de.wt.bgg.ui.partstack.rightupper" containerData="800"> | |||
| <children xsi:type="basic:Part" xmi:id="_-Mdy0EqTEeqT5sxfmvJ5Tg" elementId="de.wt.bgg.ui.part.gamesconfig" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.parts.DownloadThingDetailsPart" label="Download details"/> | |||
| </children> | |||
| </children> | |||
| <children xsi:type="basic:PartSashContainer" xmi:id="_AF1vQEqUEeqT5sxfmvJ5Tg" elementId="xyz.veronie.bgg.ui.partsashcontainer.right"> | |||
| <children xsi:type="basic:PartStack" xmi:id="_0OB_gJ2wEeqjssfAjxHZ-w" elementId="xyz.veronie.bgg.ui.partstack.leftlower" containerData="800"> | |||
| <children xsi:type="basic:Part" xmi:id="_97XbwEqTEeqT5sxfmvJ5Tg" elementId="xyz.veronie.bgg.ui.part.resulttable" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.parts.BggResultPart" label="BGG Result"> | |||
| <toolbar xmi:id="_ZZOF8J3AEeqjssfAjxHZ-w" elementId="xyz.veronie.bgg.ui.toolbar.0"> | |||
| <children xsi:type="menu:DirectToolItem" xmi:id="_c42V4J29EeqjssfAjxHZ-w" elementId="xyz.veronie.bgg.ui.directtoolitem.saveResult" label="save result" iconURI="platform:/plugin/xyz.veronie.bgg.ui/icons/save-button.png" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.handlers.HandleSaveGamelist"/> | |||
| <children xsi:type="menu:DirectToolItem" xmi:id="_VeUlQFZdEeu8-NdCRpPGXA" elementId="xyz.veronie.bgg.ui.directtoolitem.openlist" label="open list" iconURI="platform:/plugin/xyz.veronie.bgg.ui/icons/folder-symbol.png"/> | |||
| </toolbar> | |||
| </children> | |||
| </children> | |||
| <children xsi:type="basic:PartStack" xmi:id="_2M6HAJ2wEeqjssfAjxHZ-w" elementId="xyz.veronie.bgg.ui.rightlower" containerData="200"> | |||
| <children xsi:type="basic:Part" xmi:id="_Ckm3wEqUEeqT5sxfmvJ5Tg" elementId="de.wt.bgg.ui.part.gamestable" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.parts.ThingListPart" label="Games list"/> | |||
| </children> | |||
| </children> | |||
| </children> | |||
| <children xsi:type="basic:TrimmedWindow" xmi:id="_QDxdgEqSEeqT5sxfmvJ5Tg" elementId="xyz.veronie.bgg.ui.trimmedwindow.main" label="BGG Tool Another" width="700" height="700"> | |||
| <children xsi:type="basic:PartStack" xmi:id="_uw_Z4F9REeuvNqpgCDWpdQ" elementId="xyz.veronie.bgg.ui.partstack.0"> | |||
| <children xsi:type="basic:Part" xmi:id="_co2toF9CEeuvNqpgCDWpdQ" elementId="xyz.veronie.bgg.ui.part.batmain" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.parts.BatMain" label="Home"/> | |||
| <children xsi:type="basic:Part" xmi:id="_JsfvUF9YEeuvNqpgCDWpdQ" elementId="xyz.veronie.bgg.ui.part.fetch" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.parts.FetchPart" label="Fetch"/> | |||
| <children xsi:type="basic:Part" xmi:id="_ACADIF9cEeutIcDDGAEMFw" elementId="xyz.veronie.bgg.ui.part.prepare" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.parts.PreparePart" label="Prepare"/> | |||
| </children> | |||
| <mainMenu xmi:id="_wtXeQEs0EeqGDvPDavxXPQ" elementId="org.eclipse.ui.main.menu"/> | |||
| <trimBars xmi:id="_I6MLEFv-EeqNgfoocONcgg" elementId="xyz.veronie.bgg.ui.trimbar.bottom" side="Bottom"> | |||
| @@ -34,6 +14,7 @@ | |||
| <children xsi:type="menu:ToolBar" xmi:id="_AX9yMIucEeqEpr8WQZMuMQ" elementId="xyz.veronie.bgg.ui.toolbar.testbar"/> | |||
| </trimBars> | |||
| </children> | |||
| <commands xmi:id="_lA5t8F9TEeuvNqpgCDWpdQ" elementId="xyz.veronie.bgg.ui.command.save" commandName="Save" description="save game list"/> | |||
| <addons xmi:id="_Lw_ZsUqSEeqT5sxfmvJ5Tg" elementId="org.eclipse.e4.core.commands.service" contributionURI="bundleclass://org.eclipse.e4.core.commands/org.eclipse.e4.core.commands.CommandServiceAddon"/> | |||
| <addons xmi:id="_Lw_ZskqSEeqT5sxfmvJ5Tg" elementId="org.eclipse.e4.ui.contexts.service" contributionURI="bundleclass://org.eclipse.e4.ui.services/org.eclipse.e4.ui.services.ContextServiceAddon"/> | |||
| <addons xmi:id="_Lw_Zs0qSEeqT5sxfmvJ5Tg" elementId="org.eclipse.e4.ui.bindings.service" contributionURI="bundleclass://org.eclipse.e4.ui.bindings/org.eclipse.e4.ui.bindings.BindingServiceAddon"/> | |||
| @@ -3,6 +3,8 @@ Bundle-ManifestVersion: 2 | |||
| Bundle-Name: Secondtry | |||
| Bundle-SymbolicName: xyz.veronie.bgg.ui;singleton:=true | |||
| Bundle-Version: 1.0.0.qualifier | |||
| Bundle-ClassPath: lib/sqlite-jdbc-3.34.0.jar, | |||
| swing2swt.jar | |||
| Require-Bundle: org.eclipse.core.runtime, | |||
| org.eclipse.swt, | |||
| org.eclipse.e4.core.di, | |||
| @@ -15,9 +17,9 @@ Require-Bundle: org.eclipse.core.runtime, | |||
| org.eclipse.osgi.services, | |||
| javax.inject, | |||
| org.eclipse.e4.ui.model.workbench | |||
| Automatic-Module-Name: de.wt.secondtry | |||
| Bundle-RequiredExecutionEnvironment: JavaSE-1.8 | |||
| Import-Package: javax.inject;version="1.0.0", | |||
| Import-Package: javax.annotation;version="1.0.0";resolution:=optional, | |||
| javax.inject;version="1.0.0", | |||
| org.eclipse.e4.ui.model.application.descriptor.basic, | |||
| org.eclipse.e4.ui.model.application.ui.basic | |||
| Bundle-ClassPath: lib/sqlite-jdbc-3.34.0.jar | |||
| Automatic-Module-Name: de.wt.secondtry | |||
| @@ -0,0 +1,438 @@ | |||
| /******************************************************************************* | |||
| * Copyright (c) 2011 Google, Inc. and others | |||
| * All rights reserved. This program and the accompanying materials | |||
| * are made available under the terms of the Eclipse Public License v1.0 | |||
| * which accompanies this distribution, and is available at | |||
| * http://www.eclipse.org/legal/epl-v10.html | |||
| * | |||
| * Contributors: | |||
| * Google, Inc. - initial API and implementation | |||
| * Wim Jongman - 1.8 and higher compliance | |||
| *******************************************************************************/ | |||
| package org.eclipse.wb.swt; | |||
| import java.io.File; | |||
| import java.io.InputStream; | |||
| import java.lang.reflect.Constructor; | |||
| import java.lang.reflect.Method; | |||
| import java.net.MalformedURLException; | |||
| import java.net.URL; | |||
| import java.util.HashMap; | |||
| import java.util.Iterator; | |||
| import java.util.Map; | |||
| import org.eclipse.core.runtime.Platform; | |||
| import org.eclipse.jface.resource.CompositeImageDescriptor; | |||
| import org.eclipse.jface.resource.ImageDescriptor; | |||
| import org.eclipse.swt.graphics.Image; | |||
| import org.eclipse.swt.graphics.ImageData; | |||
| import org.eclipse.swt.graphics.ImageDataProvider; | |||
| import org.eclipse.swt.graphics.Point; | |||
| import org.eclipse.swt.graphics.Rectangle; | |||
| import org.osgi.framework.Bundle; | |||
| /** | |||
| * Utility class for managing OS resources associated with SWT/JFace controls | |||
| * such as colors, fonts, images, etc. | |||
| * | |||
| * This class is created automatically when you fiddle around with images and | |||
| * colors in WB. You might want to prevent your application from using this | |||
| * class and provide your own more effective means of resource caching. | |||
| * | |||
| * Even though this class can be used to manage these resources, if they are | |||
| * here for the duration of the application and not used then you still have an | |||
| * effective resource leak. | |||
| * | |||
| * Application code must explicitly invoke the <code>dispose()</code> method to | |||
| * release the operating system resources managed by cached objects when those | |||
| * objects and OS resources are no longer needed. | |||
| * | |||
| * This class may be freely distributed as part of any application or plugin. | |||
| * <p> | |||
| * | |||
| * @author scheglov_ke | |||
| * @author Dan Rubel | |||
| * @author Wim Jongman | |||
| */ | |||
| public class ResourceManager extends SWTResourceManager { | |||
| /** | |||
| * The map where we store our images. | |||
| */ | |||
| private static Map<ImageDescriptor, Image> m_descriptorImageMap = new HashMap<ImageDescriptor, Image>(); | |||
| /** | |||
| * Returns an {@link ImageDescriptor} stored in the file at the specified path | |||
| * relative to the specified class. | |||
| * | |||
| * @param clazz the {@link Class} relative to which to find the image | |||
| * descriptor. | |||
| * @param path the path to the image file. | |||
| * @return the {@link ImageDescriptor} stored in the file at the specified path. | |||
| */ | |||
| public static ImageDescriptor getImageDescriptor(Class<?> clazz, String path) { | |||
| return ImageDescriptor.createFromFile(clazz, path); | |||
| } | |||
| /** | |||
| * Returns an {@link ImageDescriptor} stored in the file at the specified path. | |||
| * | |||
| * @param path the path to the image file. | |||
| * @return the {@link ImageDescriptor} stored in the file at the specified path. | |||
| */ | |||
| public static ImageDescriptor getImageDescriptor(String path) { | |||
| try { | |||
| return ImageDescriptor.createFromURL(new File(path).toURI().toURL()); | |||
| } catch (MalformedURLException e) { | |||
| return null; | |||
| } | |||
| } | |||
| /** | |||
| * Returns an {@link Image} based on the specified {@link ImageDescriptor}. | |||
| * | |||
| * @param descriptor the {@link ImageDescriptor} for the {@link Image}. | |||
| * @return the {@link Image} based on the specified {@link ImageDescriptor}. | |||
| */ | |||
| public static Image getImage(ImageDescriptor descriptor) { | |||
| if (descriptor == null) { | |||
| return null; | |||
| } | |||
| Image image = m_descriptorImageMap.get(descriptor); | |||
| if (image == null) { | |||
| image = descriptor.createImage(); | |||
| m_descriptorImageMap.put(descriptor, image); | |||
| } | |||
| return image; | |||
| } | |||
| /** | |||
| * Maps images to decorated images. | |||
| */ | |||
| @SuppressWarnings("unchecked") | |||
| private static Map<Image, Map<Image, Image>>[] m_decoratedImageMap = new Map[LAST_CORNER_KEY]; | |||
| /** | |||
| * Returns an {@link Image} composed of a base image decorated by another image. | |||
| * | |||
| * @param baseImage the base {@link Image} that should be decorated. | |||
| * @param decorator the {@link Image} to decorate the base image. | |||
| * @return {@link Image} The resulting decorated image. | |||
| */ | |||
| public static Image decorateImage(Image baseImage, Image decorator) { | |||
| return decorateImage(baseImage, decorator, BOTTOM_RIGHT); | |||
| } | |||
| /** | |||
| * Returns an {@link Image} composed of a base image decorated by another image. | |||
| * | |||
| * @param baseImage | |||
| * the base {@link Image} that should be decorated. | |||
| * @param decorator | |||
| * the {@link Image} to decorate the base image. | |||
| * @param corner | |||
| * the corner to place decorator image. | |||
| * @return the resulting decorated {@link Image}. | |||
| */ | |||
| public static Image decorateImage(final Image baseImage, final Image decorator, final int corner) { | |||
| if (corner <= 0 || corner >= LAST_CORNER_KEY) { | |||
| throw new IllegalArgumentException("Wrong decorate corner"); | |||
| } | |||
| Map<Image, Map<Image, Image>> cornerDecoratedImageMap = m_decoratedImageMap[corner]; | |||
| if (cornerDecoratedImageMap == null) { | |||
| cornerDecoratedImageMap = new HashMap<Image, Map<Image, Image>>(); | |||
| m_decoratedImageMap[corner] = cornerDecoratedImageMap; | |||
| } | |||
| Map<Image, Image> decoratedMap = cornerDecoratedImageMap.get(baseImage); | |||
| if (decoratedMap == null) { | |||
| decoratedMap = new HashMap<Image, Image>(); | |||
| cornerDecoratedImageMap.put(baseImage, decoratedMap); | |||
| } | |||
| // | |||
| Image result = decoratedMap.get(decorator); | |||
| if (result == null) { | |||
| final Rectangle bib = baseImage.getBounds(); | |||
| final Rectangle dib = decorator.getBounds(); | |||
| final Point baseImageSize = new Point(bib.width, bib.height); | |||
| CompositeImageDescriptor compositImageDesc = new CompositeImageDescriptor() { | |||
| @Override | |||
| protected void drawCompositeImage(int width, int height) { | |||
| drawImage(createCachedImageDataProvider(baseImage), 0, 0); | |||
| if (corner == TOP_LEFT) { | |||
| drawImage(getUnzoomedImageDataProvider(decorator.getImageData()) , 0, 0); | |||
| } else if (corner == TOP_RIGHT) { | |||
| drawImage(getUnzoomedImageDataProvider(decorator.getImageData()), bib.width - dib.width, 0); | |||
| } else if (corner == BOTTOM_LEFT) { | |||
| drawImage(getUnzoomedImageDataProvider(decorator.getImageData()), 0, bib.height - dib.height); | |||
| } else if (corner == BOTTOM_RIGHT) { | |||
| drawImage(getUnzoomedImageDataProvider(decorator.getImageData()), bib.width - dib.width, bib.height - dib.height); | |||
| } | |||
| } | |||
| @Override | |||
| protected Point getSize() { | |||
| return baseImageSize; | |||
| } | |||
| }; | |||
| // | |||
| result = compositImageDesc.createImage(); | |||
| decoratedMap.put(decorator, result); | |||
| } | |||
| return result; | |||
| } | |||
| private static ImageDataProvider getUnzoomedImageDataProvider(ImageData imageData) { | |||
| return zoom -> zoom == 100 ? imageData : null; | |||
| } | |||
| /** | |||
| * Dispose all of the cached images. | |||
| */ | |||
| public static void disposeImages() { | |||
| SWTResourceManager.disposeImages(); | |||
| // dispose ImageDescriptor images | |||
| { | |||
| for (Iterator<Image> I = m_descriptorImageMap.values().iterator(); I.hasNext();) { | |||
| I.next().dispose(); | |||
| } | |||
| m_descriptorImageMap.clear(); | |||
| } | |||
| // dispose decorated images | |||
| for (int i = 0; i < m_decoratedImageMap.length; i++) { | |||
| Map<Image, Map<Image, Image>> cornerDecoratedImageMap = m_decoratedImageMap[i]; | |||
| if (cornerDecoratedImageMap != null) { | |||
| for (Map<Image, Image> decoratedMap : cornerDecoratedImageMap.values()) { | |||
| for (Image image : decoratedMap.values()) { | |||
| image.dispose(); | |||
| } | |||
| decoratedMap.clear(); | |||
| } | |||
| cornerDecoratedImageMap.clear(); | |||
| } | |||
| } | |||
| // dispose plugin images | |||
| { | |||
| for (Iterator<Image> I = m_URLImageMap.values().iterator(); I.hasNext();) { | |||
| I.next().dispose(); | |||
| } | |||
| m_URLImageMap.clear(); | |||
| } | |||
| } | |||
| //////////////////////////////////////////////////////////////////////////// | |||
| // | |||
| // Plugin images support | |||
| // | |||
| //////////////////////////////////////////////////////////////////////////// | |||
| /** | |||
| * Maps URL to images. | |||
| */ | |||
| private static Map<String, Image> m_URLImageMap = new HashMap<String, Image>(); | |||
| /** | |||
| * Provider for plugin resources, used by WindowBuilder at design time. | |||
| */ | |||
| public interface PluginResourceProvider { | |||
| URL getEntry(String symbolicName, String path); | |||
| } | |||
| /** | |||
| * Instance of {@link PluginResourceProvider}, used by WindowBuilder at design | |||
| * time. | |||
| */ | |||
| private static PluginResourceProvider m_designTimePluginResourceProvider = null; | |||
| /** | |||
| * Returns an {@link Image} based on a plugin and file path. | |||
| * | |||
| * @param plugin the plugin {@link Object} containing the image | |||
| * @param name the path to the image within the plugin | |||
| * @return the {@link Image} stored in the file at the specified path | |||
| * | |||
| * @deprecated Use {@link #getPluginImage(String, String)} instead. | |||
| */ | |||
| @Deprecated | |||
| public static Image getPluginImage(Object plugin, String name) { | |||
| try { | |||
| URL url = getPluginImageURL(plugin, name); | |||
| if (url != null) { | |||
| return getPluginImageFromUrl(url); | |||
| } | |||
| } catch (Throwable e) { | |||
| // Ignore any exceptions | |||
| } | |||
| return null; | |||
| } | |||
| /** | |||
| * Returns an {@link Image} based on a {@link Bundle} and resource entry path. | |||
| * | |||
| * @param symbolicName the symbolic name of the {@link Bundle}. | |||
| * @param path the path of the resource entry. | |||
| * @return the {@link Image} stored in the file at the specified path. | |||
| */ | |||
| public static Image getPluginImage(String symbolicName, String path) { | |||
| try { | |||
| URL url = getPluginImageURL(symbolicName, path); | |||
| if (url != null) { | |||
| return getPluginImageFromUrl(url); | |||
| } | |||
| } catch (Throwable e) { | |||
| // Ignore any exceptions | |||
| } | |||
| return null; | |||
| } | |||
| /** | |||
| * Returns an {@link Image} based on given {@link URL}. | |||
| */ | |||
| private static Image getPluginImageFromUrl(URL url) { | |||
| try { | |||
| try { | |||
| String key = url.toExternalForm(); | |||
| Image image = m_URLImageMap.get(key); | |||
| if (image == null) { | |||
| InputStream stream = url.openStream(); | |||
| try { | |||
| image = getImage(stream); | |||
| m_URLImageMap.put(key, image); | |||
| } finally { | |||
| stream.close(); | |||
| } | |||
| } | |||
| return image; | |||
| } catch (Throwable e) { | |||
| // Ignore any exceptions | |||
| } | |||
| } catch (Throwable e) { | |||
| // Ignore any exceptions | |||
| } | |||
| return null; | |||
| } | |||
| /** | |||
| * Returns an {@link ImageDescriptor} based on a plugin and file path. | |||
| * | |||
| * @param plugin the plugin {@link Object} containing the image. | |||
| * @param name the path to th eimage within the plugin. | |||
| * @return the {@link ImageDescriptor} stored in the file at the specified path. | |||
| * | |||
| * @deprecated Use {@link #getPluginImageDescriptor(String, String)} instead. | |||
| */ | |||
| @Deprecated | |||
| public static ImageDescriptor getPluginImageDescriptor(Object plugin, String name) { | |||
| try { | |||
| try { | |||
| URL url = getPluginImageURL(plugin, name); | |||
| return ImageDescriptor.createFromURL(url); | |||
| } catch (Throwable e) { | |||
| // Ignore any exceptions | |||
| } | |||
| } catch (Throwable e) { | |||
| // Ignore any exceptions | |||
| } | |||
| return null; | |||
| } | |||
| /** | |||
| * Returns an {@link ImageDescriptor} based on a {@link Bundle} and resource | |||
| * entry path. | |||
| * | |||
| * @param symbolicName the symbolic name of the {@link Bundle}. | |||
| * @param path the path of the resource entry. | |||
| * @return the {@link ImageDescriptor} based on a {@link Bundle} and resource | |||
| * entry path. | |||
| */ | |||
| public static ImageDescriptor getPluginImageDescriptor(String symbolicName, String path) { | |||
| try { | |||
| URL url = getPluginImageURL(symbolicName, path); | |||
| if (url != null) { | |||
| return ImageDescriptor.createFromURL(url); | |||
| } | |||
| } catch (Throwable e) { | |||
| // Ignore any exceptions | |||
| } | |||
| return null; | |||
| } | |||
| /** | |||
| * Returns an {@link URL} based on a {@link Bundle} and resource entry path. | |||
| */ | |||
| private static URL getPluginImageURL(String symbolicName, String path) { | |||
| // try runtime plugins | |||
| { | |||
| Bundle bundle = Platform.getBundle(symbolicName); | |||
| if (bundle != null) { | |||
| return bundle.getEntry(path); | |||
| } | |||
| } | |||
| // try design time provider | |||
| if (m_designTimePluginResourceProvider != null) { | |||
| return m_designTimePluginResourceProvider.getEntry(symbolicName, path); | |||
| } | |||
| // no such resource | |||
| return null; | |||
| } | |||
| /** | |||
| * Returns an {@link URL} based on a plugin and file path. | |||
| * | |||
| * @param plugin the plugin {@link Object} containing the file path. | |||
| * @param name the file path. | |||
| * @return the {@link URL} representing the file at the specified path. | |||
| * @throws Exception | |||
| */ | |||
| private static URL getPluginImageURL(Object plugin, String name) throws Exception { | |||
| // try to work with 'plugin' as with OSGI BundleContext | |||
| try { | |||
| Class<?> BundleClass = Class.forName("org.osgi.framework.Bundle"); //$NON-NLS-1$ | |||
| Class<?> BundleContextClass = Class.forName("org.osgi.framework.BundleContext"); //$NON-NLS-1$ | |||
| if (BundleContextClass.isAssignableFrom(plugin.getClass())) { | |||
| Method getBundleMethod = BundleContextClass.getMethod("getBundle", new Class[0]); //$NON-NLS-1$ | |||
| Object bundle = getBundleMethod.invoke(plugin, new Object[0]); | |||
| // | |||
| Class<?> PathClass = Class.forName("org.eclipse.core.runtime.Path"); //$NON-NLS-1$ | |||
| Constructor<?> pathConstructor = PathClass.getConstructor(new Class[] { String.class }); | |||
| Object path = pathConstructor.newInstance(new Object[] { name }); | |||
| // | |||
| Class<?> IPathClass = Class.forName("org.eclipse.core.runtime.IPath"); //$NON-NLS-1$ | |||
| Class<?> PlatformClass = Class.forName("org.eclipse.core.runtime.Platform"); //$NON-NLS-1$ | |||
| Method findMethod = PlatformClass.getMethod("find", new Class[] { BundleClass, IPathClass }); //$NON-NLS-1$ | |||
| return (URL) findMethod.invoke(null, new Object[] { bundle, path }); | |||
| } | |||
| } catch (Throwable e) { | |||
| // Ignore any exceptions | |||
| } | |||
| // else work with 'plugin' as with usual Eclipse plugin | |||
| { | |||
| Class<?> PluginClass = Class.forName("org.eclipse.core.runtime.Plugin"); //$NON-NLS-1$ | |||
| if (PluginClass.isAssignableFrom(plugin.getClass())) { | |||
| // | |||
| Class<?> PathClass = Class.forName("org.eclipse.core.runtime.Path"); //$NON-NLS-1$ | |||
| Constructor<?> pathConstructor = PathClass.getConstructor(new Class[] { String.class }); | |||
| Object path = pathConstructor.newInstance(new Object[] { name }); | |||
| // | |||
| Class<?> IPathClass = Class.forName("org.eclipse.core.runtime.IPath"); //$NON-NLS-1$ | |||
| Method findMethod = PluginClass.getMethod("find", new Class[] { IPathClass }); //$NON-NLS-1$ | |||
| return (URL) findMethod.invoke(plugin, new Object[] { path }); | |||
| } | |||
| } | |||
| return null; | |||
| } | |||
| //////////////////////////////////////////////////////////////////////////// | |||
| // | |||
| // General | |||
| // | |||
| //////////////////////////////////////////////////////////////////////////// | |||
| /** | |||
| * Dispose of cached objects and their underlying OS resources. This should only | |||
| * be called when the cached objects are no longer needed (e.g. on application | |||
| * shutdown). | |||
| */ | |||
| public static void dispose() { | |||
| disposeColors(); | |||
| disposeFonts(); | |||
| disposeImages(); | |||
| } | |||
| } | |||
| @@ -0,0 +1,447 @@ | |||
| /******************************************************************************* | |||
| * Copyright (c) 2011 Google, Inc. | |||
| * All rights reserved. This program and the accompanying materials | |||
| * are made available under the terms of the Eclipse Public License v1.0 | |||
| * which accompanies this distribution, and is available at | |||
| * http://www.eclipse.org/legal/epl-v10.html | |||
| * | |||
| * Contributors: | |||
| * Google, Inc. - initial API and implementation | |||
| *******************************************************************************/ | |||
| package org.eclipse.wb.swt; | |||
| import java.io.FileInputStream; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.util.HashMap; | |||
| import java.util.Map; | |||
| import org.eclipse.swt.SWT; | |||
| import org.eclipse.swt.graphics.Color; | |||
| import org.eclipse.swt.graphics.Cursor; | |||
| import org.eclipse.swt.graphics.Font; | |||
| import org.eclipse.swt.graphics.FontData; | |||
| import org.eclipse.swt.graphics.GC; | |||
| import org.eclipse.swt.graphics.Image; | |||
| import org.eclipse.swt.graphics.ImageData; | |||
| import org.eclipse.swt.graphics.RGB; | |||
| import org.eclipse.swt.graphics.Rectangle; | |||
| import org.eclipse.swt.widgets.Display; | |||
| /** | |||
| * Utility class for managing OS resources associated with SWT controls such as colors, fonts, images, etc. | |||
| * <p> | |||
| * !!! IMPORTANT !!! Application code must explicitly invoke the <code>dispose()</code> method to release the | |||
| * operating system resources managed by cached objects when those objects and OS resources are no longer | |||
| * needed (e.g. on application shutdown) | |||
| * <p> | |||
| * This class may be freely distributed as part of any application or plugin. | |||
| * <p> | |||
| * @author scheglov_ke | |||
| * @author Dan Rubel | |||
| */ | |||
| public class SWTResourceManager { | |||
| //////////////////////////////////////////////////////////////////////////// | |||
| // | |||
| // Color | |||
| // | |||
| //////////////////////////////////////////////////////////////////////////// | |||
| private static Map<RGB, Color> m_colorMap = new HashMap<RGB, Color>(); | |||
| /** | |||
| * Returns the system {@link Color} matching the specific ID. | |||
| * | |||
| * @param systemColorID | |||
| * the ID value for the color | |||
| * @return the system {@link Color} matching the specific ID | |||
| */ | |||
| public static Color getColor(int systemColorID) { | |||
| Display display = Display.getCurrent(); | |||
| return display.getSystemColor(systemColorID); | |||
| } | |||
| /** | |||
| * Returns a {@link Color} given its red, green and blue component values. | |||
| * | |||
| * @param r | |||
| * the red component of the color | |||
| * @param g | |||
| * the green component of the color | |||
| * @param b | |||
| * the blue component of the color | |||
| * @return the {@link Color} matching the given red, green and blue component values | |||
| */ | |||
| public static Color getColor(int r, int g, int b) { | |||
| return getColor(new RGB(r, g, b)); | |||
| } | |||
| /** | |||
| * Returns a {@link Color} given its RGB value. | |||
| * | |||
| * @param rgb | |||
| * the {@link RGB} value of the color | |||
| * @return the {@link Color} matching the RGB value | |||
| */ | |||
| public static Color getColor(RGB rgb) { | |||
| Color color = m_colorMap.get(rgb); | |||
| if (color == null) { | |||
| Display display = Display.getCurrent(); | |||
| color = new Color(display, rgb); | |||
| m_colorMap.put(rgb, color); | |||
| } | |||
| return color; | |||
| } | |||
| /** | |||
| * Dispose of all the cached {@link Color}'s. | |||
| */ | |||
| public static void disposeColors() { | |||
| for (Color color : m_colorMap.values()) { | |||
| color.dispose(); | |||
| } | |||
| m_colorMap.clear(); | |||
| } | |||
| //////////////////////////////////////////////////////////////////////////// | |||
| // | |||
| // Image | |||
| // | |||
| //////////////////////////////////////////////////////////////////////////// | |||
| /** | |||
| * Maps image paths to images. | |||
| */ | |||
| private static Map<String, Image> m_imageMap = new HashMap<String, Image>(); | |||
| /** | |||
| * Returns an {@link Image} encoded by the specified {@link InputStream}. | |||
| * | |||
| * @param stream | |||
| * the {@link InputStream} encoding the image data | |||
| * @return the {@link Image} encoded by the specified input stream | |||
| */ | |||
| protected static Image getImage(InputStream stream) throws IOException { | |||
| try { | |||
| Display display = Display.getCurrent(); | |||
| ImageData data = new ImageData(stream); | |||
| if (data.transparentPixel > 0) { | |||
| return new Image(display, data, data.getTransparencyMask()); | |||
| } | |||
| return new Image(display, data); | |||
| } finally { | |||
| stream.close(); | |||
| } | |||
| } | |||
| /** | |||
| * Returns an {@link Image} stored in the file at the specified path. | |||
| * | |||
| * @param path | |||
| * the path to the image file | |||
| * @return the {@link Image} stored in the file at the specified path | |||
| */ | |||
| public static Image getImage(String path) { | |||
| Image image = m_imageMap.get(path); | |||
| if (image == null) { | |||
| try { | |||
| image = getImage(new FileInputStream(path)); | |||
| m_imageMap.put(path, image); | |||
| } catch (Exception e) { | |||
| image = getMissingImage(); | |||
| m_imageMap.put(path, image); | |||
| } | |||
| } | |||
| return image; | |||
| } | |||
| /** | |||
| * Returns an {@link Image} stored in the file at the specified path relative to the specified class. | |||
| * | |||
| * @param clazz | |||
| * the {@link Class} relative to which to find the image | |||
| * @param path | |||
| * the path to the image file, if starts with <code>'/'</code> | |||
| * @return the {@link Image} stored in the file at the specified path | |||
| */ | |||
| public static Image getImage(Class<?> clazz, String path) { | |||
| String key = clazz.getName() + '|' + path; | |||
| Image image = m_imageMap.get(key); | |||
| if (image == null) { | |||
| try { | |||
| image = getImage(clazz.getResourceAsStream(path)); | |||
| m_imageMap.put(key, image); | |||
| } catch (Exception e) { | |||
| image = getMissingImage(); | |||
| m_imageMap.put(key, image); | |||
| } | |||
| } | |||
| return image; | |||
| } | |||
| private static final int MISSING_IMAGE_SIZE = 10; | |||
| /** | |||
| * @return the small {@link Image} that can be used as placeholder for missing image. | |||
| */ | |||
| private static Image getMissingImage() { | |||
| Image image = new Image(Display.getCurrent(), MISSING_IMAGE_SIZE, MISSING_IMAGE_SIZE); | |||
| // | |||
| GC gc = new GC(image); | |||
| gc.setBackground(getColor(SWT.COLOR_RED)); | |||
| gc.fillRectangle(0, 0, MISSING_IMAGE_SIZE, MISSING_IMAGE_SIZE); | |||
| gc.dispose(); | |||
| // | |||
| return image; | |||
| } | |||
| /** | |||
| * Style constant for placing decorator image in top left corner of base image. | |||
| */ | |||
| public static final int TOP_LEFT = 1; | |||
| /** | |||
| * Style constant for placing decorator image in top right corner of base image. | |||
| */ | |||
| public static final int TOP_RIGHT = 2; | |||
| /** | |||
| * Style constant for placing decorator image in bottom left corner of base image. | |||
| */ | |||
| public static final int BOTTOM_LEFT = 3; | |||
| /** | |||
| * Style constant for placing decorator image in bottom right corner of base image. | |||
| */ | |||
| public static final int BOTTOM_RIGHT = 4; | |||
| /** | |||
| * Internal value. | |||
| */ | |||
| protected static final int LAST_CORNER_KEY = 5; | |||
| /** | |||
| * Maps images to decorated images. | |||
| */ | |||
| @SuppressWarnings("unchecked") | |||
| private static Map<Image, Map<Image, Image>>[] m_decoratedImageMap = new Map[LAST_CORNER_KEY]; | |||
| /** | |||
| * Returns an {@link Image} composed of a base image decorated by another image. | |||
| * | |||
| * @param baseImage | |||
| * the base {@link Image} that should be decorated | |||
| * @param decorator | |||
| * the {@link Image} to decorate the base image | |||
| * @return {@link Image} The resulting decorated image | |||
| */ | |||
| public static Image decorateImage(Image baseImage, Image decorator) { | |||
| return decorateImage(baseImage, decorator, BOTTOM_RIGHT); | |||
| } | |||
| /** | |||
| * Returns an {@link Image} composed of a base image decorated by another image. | |||
| * | |||
| * @param baseImage | |||
| * the base {@link Image} that should be decorated | |||
| * @param decorator | |||
| * the {@link Image} to decorate the base image | |||
| * @param corner | |||
| * the corner to place decorator image | |||
| * @return the resulting decorated {@link Image} | |||
| */ | |||
| public static Image decorateImage(final Image baseImage, final Image decorator, final int corner) { | |||
| if (corner <= 0 || corner >= LAST_CORNER_KEY) { | |||
| throw new IllegalArgumentException("Wrong decorate corner"); | |||
| } | |||
| Map<Image, Map<Image, Image>> cornerDecoratedImageMap = m_decoratedImageMap[corner]; | |||
| if (cornerDecoratedImageMap == null) { | |||
| cornerDecoratedImageMap = new HashMap<Image, Map<Image, Image>>(); | |||
| m_decoratedImageMap[corner] = cornerDecoratedImageMap; | |||
| } | |||
| Map<Image, Image> decoratedMap = cornerDecoratedImageMap.get(baseImage); | |||
| if (decoratedMap == null) { | |||
| decoratedMap = new HashMap<Image, Image>(); | |||
| cornerDecoratedImageMap.put(baseImage, decoratedMap); | |||
| } | |||
| // | |||
| Image result = decoratedMap.get(decorator); | |||
| if (result == null) { | |||
| Rectangle bib = baseImage.getBounds(); | |||
| Rectangle dib = decorator.getBounds(); | |||
| // | |||
| result = new Image(Display.getCurrent(), bib.width, bib.height); | |||
| // | |||
| GC gc = new GC(result); | |||
| gc.drawImage(baseImage, 0, 0); | |||
| if (corner == TOP_LEFT) { | |||
| gc.drawImage(decorator, 0, 0); | |||
| } else if (corner == TOP_RIGHT) { | |||
| gc.drawImage(decorator, bib.width - dib.width, 0); | |||
| } else if (corner == BOTTOM_LEFT) { | |||
| gc.drawImage(decorator, 0, bib.height - dib.height); | |||
| } else if (corner == BOTTOM_RIGHT) { | |||
| gc.drawImage(decorator, bib.width - dib.width, bib.height - dib.height); | |||
| } | |||
| gc.dispose(); | |||
| // | |||
| decoratedMap.put(decorator, result); | |||
| } | |||
| return result; | |||
| } | |||
| /** | |||
| * Dispose all of the cached {@link Image}'s. | |||
| */ | |||
| public static void disposeImages() { | |||
| // dispose loaded images | |||
| { | |||
| for (Image image : m_imageMap.values()) { | |||
| image.dispose(); | |||
| } | |||
| m_imageMap.clear(); | |||
| } | |||
| // dispose decorated images | |||
| for (int i = 0; i < m_decoratedImageMap.length; i++) { | |||
| Map<Image, Map<Image, Image>> cornerDecoratedImageMap = m_decoratedImageMap[i]; | |||
| if (cornerDecoratedImageMap != null) { | |||
| for (Map<Image, Image> decoratedMap : cornerDecoratedImageMap.values()) { | |||
| for (Image image : decoratedMap.values()) { | |||
| image.dispose(); | |||
| } | |||
| decoratedMap.clear(); | |||
| } | |||
| cornerDecoratedImageMap.clear(); | |||
| } | |||
| } | |||
| } | |||
| //////////////////////////////////////////////////////////////////////////// | |||
| // | |||
| // Font | |||
| // | |||
| //////////////////////////////////////////////////////////////////////////// | |||
| /** | |||
| * Maps font names to fonts. | |||
| */ | |||
| private static Map<String, Font> m_fontMap = new HashMap<String, Font>(); | |||
| /** | |||
| * Maps fonts to their bold versions. | |||
| */ | |||
| private static Map<Font, Font> m_fontToBoldFontMap = new HashMap<Font, Font>(); | |||
| /** | |||
| * Returns a {@link Font} based on its name, height and style. | |||
| * | |||
| * @param name | |||
| * the name of the font | |||
| * @param height | |||
| * the height of the font | |||
| * @param style | |||
| * the style of the font | |||
| * @return {@link Font} The font matching the name, height and style | |||
| */ | |||
| public static Font getFont(String name, int height, int style) { | |||
| return getFont(name, height, style, false, false); | |||
| } | |||
| /** | |||
| * Returns a {@link Font} based on its name, height and style. Windows-specific strikeout and underline | |||
| * flags are also supported. | |||
| * | |||
| * @param name | |||
| * the name of the font | |||
| * @param size | |||
| * the size of the font | |||
| * @param style | |||
| * the style of the font | |||
| * @param strikeout | |||
| * the strikeout flag (warning: Windows only) | |||
| * @param underline | |||
| * the underline flag (warning: Windows only) | |||
| * @return {@link Font} The font matching the name, height, style, strikeout and underline | |||
| */ | |||
| public static Font getFont(String name, int size, int style, boolean strikeout, boolean underline) { | |||
| String fontName = name + '|' + size + '|' + style + '|' + strikeout + '|' + underline; | |||
| Font font = m_fontMap.get(fontName); | |||
| if (font == null) { | |||
| FontData fontData = new FontData(name, size, style); | |||
| if (strikeout || underline) { | |||
| try { | |||
| Class<?> logFontClass = Class.forName("org.eclipse.swt.internal.win32.LOGFONT"); //$NON-NLS-1$ | |||
| Object logFont = FontData.class.getField("data").get(fontData); //$NON-NLS-1$ | |||
| if (logFont != null && logFontClass != null) { | |||
| if (strikeout) { | |||
| logFontClass.getField("lfStrikeOut").set(logFont, Byte.valueOf((byte) 1)); //$NON-NLS-1$ | |||
| } | |||
| if (underline) { | |||
| logFontClass.getField("lfUnderline").set(logFont, Byte.valueOf((byte) 1)); //$NON-NLS-1$ | |||
| } | |||
| } | |||
| } catch (Throwable e) { | |||
| System.err.println("Unable to set underline or strikeout" + " (probably on a non-Windows platform). " + e); //$NON-NLS-1$ //$NON-NLS-2$ | |||
| } | |||
| } | |||
| font = new Font(Display.getCurrent(), fontData); | |||
| m_fontMap.put(fontName, font); | |||
| } | |||
| return font; | |||
| } | |||
| /** | |||
| * Returns a bold version of the given {@link Font}. | |||
| * | |||
| * @param baseFont | |||
| * the {@link Font} for which a bold version is desired | |||
| * @return the bold version of the given {@link Font} | |||
| */ | |||
| public static Font getBoldFont(Font baseFont) { | |||
| Font font = m_fontToBoldFontMap.get(baseFont); | |||
| if (font == null) { | |||
| FontData fontDatas[] = baseFont.getFontData(); | |||
| FontData data = fontDatas[0]; | |||
| font = new Font(Display.getCurrent(), data.getName(), data.getHeight(), SWT.BOLD); | |||
| m_fontToBoldFontMap.put(baseFont, font); | |||
| } | |||
| return font; | |||
| } | |||
| /** | |||
| * Dispose all of the cached {@link Font}'s. | |||
| */ | |||
| public static void disposeFonts() { | |||
| // clear fonts | |||
| for (Font font : m_fontMap.values()) { | |||
| font.dispose(); | |||
| } | |||
| m_fontMap.clear(); | |||
| // clear bold fonts | |||
| for (Font font : m_fontToBoldFontMap.values()) { | |||
| font.dispose(); | |||
| } | |||
| m_fontToBoldFontMap.clear(); | |||
| } | |||
| //////////////////////////////////////////////////////////////////////////// | |||
| // | |||
| // Cursor | |||
| // | |||
| //////////////////////////////////////////////////////////////////////////// | |||
| /** | |||
| * Maps IDs to cursors. | |||
| */ | |||
| private static Map<Integer, Cursor> m_idToCursorMap = new HashMap<Integer, Cursor>(); | |||
| /** | |||
| * Returns the system cursor matching the specific ID. | |||
| * | |||
| * @param id | |||
| * int The ID value for the cursor | |||
| * @return Cursor The system cursor matching the specific ID | |||
| */ | |||
| public static Cursor getCursor(int id) { | |||
| Integer key = Integer.valueOf(id); | |||
| Cursor cursor = m_idToCursorMap.get(key); | |||
| if (cursor == null) { | |||
| cursor = new Cursor(Display.getDefault(), id); | |||
| m_idToCursorMap.put(key, cursor); | |||
| } | |||
| return cursor; | |||
| } | |||
| /** | |||
| * Dispose all of the cached cursors. | |||
| */ | |||
| public static void disposeCursors() { | |||
| for (Cursor cursor : m_idToCursorMap.values()) { | |||
| cursor.dispose(); | |||
| } | |||
| m_idToCursorMap.clear(); | |||
| } | |||
| //////////////////////////////////////////////////////////////////////////// | |||
| // | |||
| // General | |||
| // | |||
| //////////////////////////////////////////////////////////////////////////// | |||
| /** | |||
| * Dispose of cached objects and their underlying OS resources. This should only be called when the cached | |||
| * objects are no longer needed (e.g. on application shutdown). | |||
| */ | |||
| public static void dispose() { | |||
| disposeColors(); | |||
| disposeImages(); | |||
| disposeFonts(); | |||
| disposeCursors(); | |||
| } | |||
| } | |||
| @@ -1,70 +1,93 @@ | |||
| package xyz.veronie.bgg.ui.dialogs; | |||
| import static org.eclipse.jface.widgets.WidgetFactory.text; | |||
| import org.eclipse.jface.dialogs.Dialog; | |||
| import org.eclipse.jface.dialogs.IDialogConstants; | |||
| import org.eclipse.swt.SWT; | |||
| import org.eclipse.swt.events.FocusEvent; | |||
| import org.eclipse.swt.events.FocusListener; | |||
| import org.eclipse.swt.events.ModifyEvent; | |||
| import org.eclipse.swt.events.ModifyListener; | |||
| import org.eclipse.swt.graphics.Point; | |||
| import org.eclipse.swt.layout.GridData; | |||
| import org.eclipse.swt.layout.GridLayout; | |||
| import org.eclipse.swt.widgets.Composite; | |||
| import org.eclipse.swt.widgets.Control; | |||
| import org.eclipse.swt.widgets.Label; | |||
| import org.eclipse.swt.widgets.Shell; | |||
| import org.eclipse.swt.widgets.Text; | |||
| import org.eclipse.wb.swt.SWTResourceManager; | |||
| import xyz.veronie.bgg.ui.helpers.BatColors; | |||
| public class SaveGameListDialog extends Dialog { | |||
| private Text textField; | |||
| private String entryString; | |||
| /** | |||
| * Create the dialog. | |||
| * @param parentShell | |||
| */ | |||
| public SaveGameListDialog(Shell parentShell) { | |||
| super(parentShell); | |||
| } | |||
| @Override | |||
| protected Control createDialogArea(Composite parent) { | |||
| Composite container = (Composite) super.createDialogArea(parent); | |||
| GridLayout layout = new GridLayout(1, false); | |||
| layout.marginLeft = 16; | |||
| layout.marginTop = 16; | |||
| layout.marginRight = 16; | |||
| layout.marginBottom = 16; | |||
| container.setLayout(layout); | |||
| super(parentShell); | |||
| setShellStyle(SWT.APPLICATION_MODAL); | |||
| } | |||
| Text text = text(SWT.BORDER).message("Enter game list name") | |||
| .limitTo(255) | |||
| .layoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false)) | |||
| .create(container); | |||
| /** | |||
| * Create contents of the dialog. | |||
| * @param parent | |||
| */ | |||
| @Override | |||
| protected Control createDialogArea(Composite parent) { | |||
| parent.setBackground(BatColors.getBackgroundColor()); | |||
| Composite container = (Composite) super.createDialogArea(parent); | |||
| container.setFont(SWTResourceManager.getFont("Segoe UI", 11, SWT.NORMAL)); | |||
| container.setBackground(BatColors.getBackgroundColor()); | |||
| GridLayout gl_container = new GridLayout(1, false); | |||
| gl_container.verticalSpacing = 24; | |||
| gl_container.marginWidth = 24; | |||
| gl_container.marginTop = 24; | |||
| gl_container.marginRight = 24; | |||
| gl_container.marginLeft = 24; | |||
| gl_container.marginHeight = 24; | |||
| gl_container.marginBottom = 24; | |||
| gl_container.horizontalSpacing = 24; | |||
| container.setLayout(gl_container); | |||
| Label lblEnterAName = new Label(container, SWT.NONE); | |||
| lblEnterAName.setFont(SWTResourceManager.getFont("Segoe UI", 11, SWT.NORMAL)); | |||
| lblEnterAName.setText("Enter a name for the game list:"); | |||
| textField = new Text(container, SWT.BORDER); | |||
| textField.addModifyListener(new ModifyListener() { | |||
| public void modifyText(ModifyEvent e) { | |||
| Text t = (Text) e.widget; | |||
| entryString = t.getText(); | |||
| } | |||
| }); | |||
| textField.setFont(SWTResourceManager.getFont("Segoe UI", 11, SWT.NORMAL)); | |||
| textField.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); | |||
| return container; | |||
| } | |||
| FocusListener focusListener = new FocusListener() { | |||
| public void focusGained(FocusEvent e) { | |||
| } | |||
| /** | |||
| * Create contents of the button bar. | |||
| * @param parent | |||
| */ | |||
| @Override | |||
| protected void createButtonsForButtonBar(Composite parent) { | |||
| parent.setBackground(BatColors.getBackgroundColor()); | |||
| createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); | |||
| createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); | |||
| } | |||
| public void focusLost(FocusEvent e) { | |||
| Text t = (Text) e.widget; | |||
| entryString = t.getText(); | |||
| } | |||
| }; | |||
| text.addFocusListener(focusListener); | |||
| return container; | |||
| } | |||
| // overriding this methods allows you to set the | |||
| // title of the custom dialog | |||
| @Override | |||
| protected void configureShell(Shell newShell) { | |||
| super.configureShell(newShell); | |||
| newShell.setText("Enter game list name"); | |||
| } | |||
| /** | |||
| * Return the initial size of the dialog. | |||
| */ | |||
| @Override | |||
| protected Point getInitialSize() { | |||
| return new Point(450, 300); | |||
| } | |||
| @Override | |||
| protected Point getInitialSize() { | |||
| return new Point(450, 300); | |||
| } | |||
| public String getEntryText() { | |||
| return entryString; | |||
| @@ -1,8 +1,6 @@ | |||
| package xyz.veronie.bgg.ui.handlers; | |||
| import javax.inject.Inject; | |||
| import org.eclipse.e4.core.di.annotations.CanExecute; | |||
| import org.eclipse.e4.core.di.annotations.Execute; | |||
| import org.eclipse.jface.dialogs.Dialog; | |||
| @@ -15,9 +13,14 @@ import xyz.veronie.bgg.ui.dialogs.SaveGameListDialog; | |||
| public class HandleSaveGamelist { | |||
| @Inject | |||
| // @Inject | |||
| ThingProvider thingProvider; | |||
| public HandleSaveGamelist(ThingProvider thingProvider) { | |||
| this.thingProvider = thingProvider; | |||
| } | |||
| @Execute | |||
| public void execute(Shell shell) { | |||
| @@ -0,0 +1,16 @@ | |||
| package xyz.veronie.bgg.ui.helpers; | |||
| import org.eclipse.swt.graphics.Color; | |||
| import org.eclipse.wb.swt.SWTResourceManager; | |||
| public class BatColors { | |||
| public static Color getBackgroundColor() { | |||
| return SWTResourceManager.getColor(155,142,237); | |||
| } | |||
| public static Color getButtonBgColor() { | |||
| return SWTResourceManager.getColor(255,81,0); | |||
| } | |||
| } | |||
| @@ -0,0 +1,18 @@ | |||
| package xyz.veronie.bgg.ui.helpers; | |||
| import org.eclipse.swt.layout.GridLayout; | |||
| public class BatLayouts { | |||
| public static void applyStandardSpacing(GridLayout gl) { | |||
| gl.horizontalSpacing = 8; | |||
| gl.verticalSpacing = 24; | |||
| gl.marginWidth = 8; | |||
| gl.marginTop = 8; | |||
| gl.marginRight = 8; | |||
| gl.marginLeft = 8; | |||
| gl.marginHeight = 8; | |||
| gl.marginBottom = 8; | |||
| } | |||
| } | |||
| @@ -0,0 +1,274 @@ | |||
| package xyz.veronie.bgg.ui.parts; | |||
| import java.util.List; | |||
| import javax.annotation.PostConstruct; | |||
| import javax.inject.Inject; | |||
| import org.eclipse.e4.core.di.annotations.Optional; | |||
| import org.eclipse.e4.core.services.events.IEventBroker; | |||
| import org.eclipse.e4.ui.di.UIEventTopic; | |||
| import org.eclipse.e4.ui.model.application.MApplication; | |||
| import org.eclipse.e4.ui.model.application.ui.basic.MPart; | |||
| import org.eclipse.e4.ui.workbench.modeling.EModelService; | |||
| import org.eclipse.e4.ui.workbench.modeling.EPartService; | |||
| import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState; | |||
| import org.eclipse.jface.viewers.ArrayContentProvider; | |||
| import org.eclipse.jface.viewers.ColumnLabelProvider; | |||
| import org.eclipse.jface.viewers.ISelectionChangedListener; | |||
| import org.eclipse.jface.viewers.IStructuredSelection; | |||
| import org.eclipse.jface.viewers.SelectionChangedEvent; | |||
| import org.eclipse.jface.viewers.TableViewer; | |||
| import org.eclipse.jface.viewers.TableViewerColumn; | |||
| import org.eclipse.swt.SWT; | |||
| import org.eclipse.swt.events.MouseAdapter; | |||
| import org.eclipse.swt.events.MouseEvent; | |||
| import org.eclipse.swt.graphics.Color; | |||
| import org.eclipse.swt.graphics.Image; | |||
| import org.eclipse.swt.layout.GridData; | |||
| import org.eclipse.swt.layout.GridLayout; | |||
| import org.eclipse.swt.widgets.Button; | |||
| import org.eclipse.swt.widgets.Composite; | |||
| import org.eclipse.swt.widgets.Label; | |||
| import org.eclipse.swt.widgets.Table; | |||
| import org.eclipse.swt.widgets.TableColumn; | |||
| import org.eclipse.wb.swt.ResourceManager; | |||
| import org.eclipse.wb.swt.SWTResourceManager; | |||
| import xyz.veronie.bgg.result.Thing; | |||
| import xyz.veronie.bgg.result.ThingProvider; | |||
| import xyz.veronie.bgg.types.EventConstants; | |||
| import xyz.veronie.bgg.ui.handlers.HandleSaveGamelist; | |||
| import xyz.veronie.bgg.ui.helpers.BatColors; | |||
| import xyz.veronie.bgg.ui.helpers.BatLayouts; | |||
| public class BatMain { | |||
| private Table tableGameList; | |||
| private TableViewer tableViewer; | |||
| @Inject | |||
| private ThingProvider thingProvider; | |||
| @Inject | |||
| private IEventBroker eventBroker; | |||
| @Inject | |||
| public BatMain() { | |||
| } | |||
| @PostConstruct | |||
| public void postConstruct(Composite parent, MApplication application, EPartService partService, EModelService modelService) { | |||
| Color bgColor = BatColors.getBackgroundColor(); | |||
| parent.setBackground(bgColor); | |||
| GridLayout gl_parent = new GridLayout(1, false); | |||
| gl_parent.horizontalSpacing = 0; | |||
| gl_parent.verticalSpacing = 0; | |||
| gl_parent.marginWidth = 0; | |||
| gl_parent.marginHeight = 0; | |||
| parent.setLayout(gl_parent); | |||
| Composite main = new Composite(parent, SWT.NONE); | |||
| GridData gd_main = new GridData(SWT.LEFT, SWT.TOP, true, true, 1, 1); | |||
| gd_main.minimumHeight = 192; | |||
| gd_main.minimumWidth = 348; | |||
| main.setLayoutData(gd_main); | |||
| main.setBackground(bgColor); | |||
| GridLayout gl_main = new GridLayout(1, false); | |||
| gl_main.verticalSpacing = 24; | |||
| BatLayouts.applyStandardSpacing(gl_main); | |||
| main.setLayout(gl_main); | |||
| Composite buttonRow = new Composite(main, SWT.NONE); | |||
| buttonRow.setBackground(bgColor); | |||
| GridLayout gl_buttonRow = new GridLayout(5, false); | |||
| gl_buttonRow.verticalSpacing = 8; | |||
| gl_buttonRow.marginWidth = 0; | |||
| gl_buttonRow.marginHeight = 8; | |||
| gl_buttonRow.horizontalSpacing = 8; | |||
| BatLayouts.applyStandardSpacing(gl_buttonRow); | |||
| buttonRow.setLayout(gl_buttonRow); | |||
| buttonRow.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, false, 1, 1)); | |||
| Button btnFetch = new Button(buttonRow, SWT.NONE); | |||
| btnFetch.addMouseListener(new MouseAdapter() { | |||
| @Override | |||
| public void mouseUp(MouseEvent e) { | |||
| List<MPart> parts = modelService.findElements(application, "xyz.veronie.bgg.ui.part.fetch", MPart.class); | |||
| if(parts != null && parts.size() >= 1) { | |||
| MPart fetchPart = parts.get(0); | |||
| partService.showPart(fetchPart, PartState.CREATE); | |||
| partService.showPart(fetchPart, PartState.ACTIVATE); | |||
| } | |||
| } | |||
| }); | |||
| btnFetch.setToolTipText("Fetch games from BGG"); | |||
| btnFetch.setForeground(SWTResourceManager.getColor(SWT.COLOR_TRANSPARENT)); | |||
| btnFetch.setBackground(SWTResourceManager.getColor(SWT.COLOR_TRANSPARENT)); | |||
| btnFetch.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/noun_Download_60x60.png")); | |||
| Button btnSave = new Button(buttonRow, SWT.NONE); | |||
| btnSave.addMouseListener(new MouseAdapter() { | |||
| @Override | |||
| public void mouseUp(MouseEvent e) { | |||
| // TODO: find a loose coupling instead. Where is EHandlerService??? | |||
| HandleSaveGamelist handleSaveGameList = new HandleSaveGamelist(thingProvider); | |||
| if(handleSaveGameList.canExecute()) { | |||
| handleSaveGameList.execute(parent.getShell()); | |||
| } | |||
| } | |||
| }); | |||
| btnSave.setToolTipText("Save list of games"); | |||
| btnSave.setBackground(SWTResourceManager.getColor(SWT.COLOR_TRANSPARENT)); | |||
| btnSave.setForeground(SWTResourceManager.getColor(SWT.COLOR_TRANSPARENT)); | |||
| btnSave.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/noun_Save_60x60.png")); | |||
| Button btnLoad = new Button(buttonRow, SWT.NONE); | |||
| btnLoad.setBackground(SWTResourceManager.getColor(SWT.COLOR_TRANSPARENT)); | |||
| btnLoad.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/noun_open_60x60.png")); | |||
| btnLoad.setToolTipText("Load list of games"); | |||
| Button btnUndo = new Button(buttonRow, SWT.NONE); | |||
| btnUndo.setToolTipText("Undo game list operation"); | |||
| btnUndo.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/noun_Undo_60x60.png")); | |||
| btnUndo.setBackground(SWTResourceManager.getColor(SWT.COLOR_TRANSPARENT)); | |||
| Button btnExport = new Button(buttonRow, SWT.NONE); | |||
| btnExport.setBackground(SWTResourceManager.getColor(SWT.COLOR_TRANSPARENT)); | |||
| btnExport.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/export_nandeck_60x60.png")); | |||
| btnExport.setToolTipText("Export for nanDeck"); | |||
| tableViewer = new TableViewer(main, SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI); | |||
| tableGameList = tableViewer.getTable(); | |||
| tableGameList.setLinesVisible(true); | |||
| tableGameList.setHeaderVisible(true); | |||
| GridData gd_tableGameList = new GridData(SWT.LEFT, SWT.TOP, true, true, 1, 1); | |||
| gd_tableGameList.heightHint = 466; | |||
| tableGameList.setLayoutData(gd_tableGameList); | |||
| createColumns(tableViewer); | |||
| tableViewer.setContentProvider(new ArrayContentProvider()); | |||
| // Get the content for the viewer, setInput will call getElements in the | |||
| // contentProvider | |||
| tableViewer.setInput(thingProvider.getThings()); | |||
| // make the selection available to other views | |||
| // TODO: getSite().setSelectionProvider(viewer); | |||
| // Set the sorter for the table | |||
| tableViewer.addSelectionChangedListener(new ISelectionChangedListener() { | |||
| @Override | |||
| public void selectionChanged(SelectionChangedEvent event) { | |||
| IStructuredSelection selection = tableViewer.getStructuredSelection(); | |||
| Thing thing = (Thing)selection.getFirstElement(); | |||
| eventBroker.send(EventConstants.TOPIC_THING_SELECTION, thing); | |||
| } | |||
| }); | |||
| Composite statusRow = new Composite(main, SWT.NONE); | |||
| statusRow.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, false, 1, 1)); | |||
| GridLayout gl_statusRow = new GridLayout(1, false); | |||
| gl_statusRow.verticalSpacing = 8; | |||
| gl_statusRow.marginWidth = 8; | |||
| gl_statusRow.marginHeight = 8; | |||
| gl_statusRow.horizontalSpacing = 8; | |||
| BatLayouts.applyStandardSpacing(gl_statusRow); | |||
| statusRow.setLayout(gl_statusRow); | |||
| Label lblResultStatus = new Label(statusRow, SWT.NONE); | |||
| lblResultStatus.setText("0 items"); | |||
| } | |||
| public TableViewer getViewer() { | |||
| return tableViewer; | |||
| } | |||
| // This will create the columns for the table | |||
| private void createColumns(final TableViewer viewer) { | |||
| // https://stackoverflow.com/questions/12641354/putting-an-image-in-to-a-jface-table-cell-is-causing-gap-for-image-to-appear-in | |||
| TableViewerColumn col = createTableViewerColumn(Thing.IdHeader, 250, 0); | |||
| col.setLabelProvider(new ColumnLabelProvider() { | |||
| @Override | |||
| public String getText(Object element) { | |||
| Thing t = (Thing) element; | |||
| return t.getField((int)col.getColumn().getData()); | |||
| } | |||
| }); | |||
| TableViewerColumn col2 = createTableViewerColumn(Thing.ThumbHeader, 150, 1); | |||
| col2.setLabelProvider(new ColumnLabelProvider() { | |||
| @Override | |||
| public Image getImage(Object element) { | |||
| Thing t = (Thing) element; | |||
| Image img = t.getThumbnail(); | |||
| return img; | |||
| } | |||
| @Override | |||
| public String getText(Object element) { | |||
| return ""; | |||
| } | |||
| }); | |||
| TableViewerColumn col3 = createTableViewerColumn(Thing.NameHeader, 400, 2); | |||
| col3.setLabelProvider(new ColumnLabelProvider() { | |||
| @Override | |||
| public String getText(Object element) { | |||
| Thing t = (Thing) element; | |||
| return t.getField((int)col3.getColumn().getData()); | |||
| } | |||
| }); | |||
| } | |||
| private TableViewerColumn createTableViewerColumn(String title, int bound, final int colNumber) { | |||
| final TableViewerColumn viewerColumn = new TableViewerColumn(tableViewer, | |||
| SWT.NONE); | |||
| final TableColumn column = viewerColumn.getColumn(); | |||
| column.setText(title); | |||
| column.setWidth(bound); | |||
| column.setAlignment(SWT.LEFT); | |||
| column.setResizable(true); | |||
| column.setMoveable(true); | |||
| column.setData(colNumber); | |||
| return viewerColumn; | |||
| } | |||
| /** | |||
| * Passing the focus request to the viewer's control. | |||
| */ | |||
| public void setFocus() { | |||
| tableViewer.getControl().setFocus(); | |||
| } | |||
| @Inject | |||
| @Optional | |||
| private void subscribeTopicResultChanged | |||
| (@UIEventTopic(EventConstants.TOPIC_RESULT_CHANGED) | |||
| String empty) { | |||
| System.out.println("TOPIC_RESULT_CHANGED"); | |||
| List<Thing> things = thingProvider.getThings(); | |||
| tableViewer.setInput(things); | |||
| tableViewer.refresh(true); | |||
| // if(things != null) { | |||
| // statsLabel.setText(Integer.toString(things.size()) + " items"); | |||
| // statsLabel.redraw(); | |||
| // } | |||
| } | |||
| } | |||
| @@ -33,33 +33,6 @@ import xyz.veronie.bgg.result.Thing; | |||
| import xyz.veronie.bgg.result.ThingProvider; | |||
| import xyz.veronie.bgg.types.EventConstants; | |||
| abstract class CenterImageLabelProvider extends OwnerDrawLabelProvider { | |||
| protected void measure(Event event, Object element) { | |||
| } | |||
| protected void paint(Event event, Object element) { | |||
| Image img = getImage(element); | |||
| if (img != null) { | |||
| Rectangle bounds = ((TableItem) event.item).getBounds(event.index); | |||
| Rectangle imgBounds = img.getBounds(); | |||
| bounds.width /= 2; | |||
| bounds.width -= imgBounds.width / 2; | |||
| bounds.height /= 2; | |||
| bounds.height -= imgBounds.height / 2; | |||
| int x = bounds.width > 0 ? bounds.x + bounds.width : bounds.x; | |||
| int y = bounds.height > 0 ? bounds.y + bounds.height : bounds.y; | |||
| event.gc.drawImage(img, x, y); | |||
| } | |||
| } | |||
| protected abstract Image getImage(Object element); | |||
| }; | |||
| public class BggResultPart { | |||
| private TableViewer viewer; | |||
| @@ -72,7 +45,7 @@ public class BggResultPart { | |||
| private IEventBroker eventBroker; | |||
| @PostConstruct | |||
| public void createControls(Composite parent) { | |||
| public void createContents(Composite parent) { | |||
| Composite main = new Composite(parent, SWT.FILL); | |||
| main.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); | |||
| @@ -0,0 +1,298 @@ | |||
| package xyz.veronie.bgg.ui.parts; | |||
| import java.util.ArrayList; | |||
| import javax.annotation.PostConstruct; | |||
| import javax.inject.Inject; | |||
| import org.eclipse.e4.core.services.events.IEventBroker; | |||
| import org.eclipse.jface.dialogs.MessageDialog; | |||
| import org.eclipse.jface.viewers.IStructuredSelection; | |||
| import org.eclipse.swt.SWT; | |||
| import org.eclipse.swt.events.MouseAdapter; | |||
| import org.eclipse.swt.events.MouseEvent; | |||
| import org.eclipse.swt.events.SelectionEvent; | |||
| import org.eclipse.swt.layout.GridData; | |||
| import org.eclipse.swt.layout.GridLayout; | |||
| import org.eclipse.swt.widgets.Button; | |||
| import org.eclipse.swt.widgets.Composite; | |||
| import org.eclipse.swt.widgets.Control; | |||
| import org.eclipse.swt.widgets.Group; | |||
| import org.eclipse.wb.swt.ResourceManager; | |||
| import xyz.veronie.bgg.result.BggApi; | |||
| import xyz.veronie.bgg.result.ResultConfig; | |||
| import xyz.veronie.bgg.result.ResultConfigManager; | |||
| import xyz.veronie.bgg.result.Thing; | |||
| import xyz.veronie.bgg.result.ThingProvider; | |||
| import xyz.veronie.bgg.types.EventConstants; | |||
| import xyz.veronie.bgg.types.SourceFilter; | |||
| import xyz.veronie.bgg.ui.filters.BggUserSourceFilter; | |||
| import xyz.veronie.bgg.ui.filters.FamilySourceFilter; | |||
| import xyz.veronie.bgg.ui.filters.GeeklistSourceFilter; | |||
| import xyz.veronie.bgg.ui.helpers.BatColors; | |||
| import xyz.veronie.bgg.ui.helpers.BatLayouts; | |||
| import org.eclipse.swt.widgets.Label; | |||
| public class FetchPart { | |||
| @Inject | |||
| private ResultConfigManager configManager; | |||
| // inject all source filter composites | |||
| @Inject private BggUserSourceFilter bggUserSourceFilter; | |||
| @Inject private GeeklistSourceFilter geeklistSourceFilter; | |||
| @Inject private FamilySourceFilter familySourceFilter; | |||
| @Inject | |||
| private IEventBroker eventBroker; | |||
| @Inject | |||
| private ThingProvider thingProvider; | |||
| @Inject | |||
| private BggApi bggApi; | |||
| private Button btnBggUser; | |||
| private Button btnFamily; | |||
| private Button btnGeeklist; | |||
| private SourceFilter source; | |||
| private Composite main; | |||
| private Group filterGroup; | |||
| @Inject | |||
| public FetchPart() { | |||
| } | |||
| @PostConstruct | |||
| public void postConstruct(Composite parent) { | |||
| parent.setBackground(BatColors.getBackgroundColor()); | |||
| parent.setLayout(new GridLayout(1, false)); | |||
| main = new Composite(parent, SWT.NONE); | |||
| GridLayout gl_main = new GridLayout(1, false); | |||
| BatLayouts.applyStandardSpacing(gl_main); | |||
| main.setLayout(gl_main); | |||
| main.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true, 1, 1)); | |||
| Composite buttonRow = new Composite(main, SWT.NONE); | |||
| buttonRow.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1)); | |||
| GridLayout gl_buttonRow = new GridLayout(3, false); | |||
| BatLayouts.applyStandardSpacing(gl_main); | |||
| buttonRow.setLayout(gl_buttonRow); | |||
| btnBggUser = new Button(buttonRow, SWT.NONE); | |||
| btnBggUser.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/noun_Meeple_60x60.png")); | |||
| btnFamily = new Button(buttonRow, SWT.NONE); | |||
| btnFamily.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/noun_Family_60x60.png")); | |||
| btnGeeklist = new Button(buttonRow, SWT.NONE); | |||
| btnGeeklist.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/noun_List_60x60.png")); | |||
| btnBggUser.addMouseListener(new MouseAdapter() { | |||
| @Override | |||
| public void mouseUp(MouseEvent e) { | |||
| selectFilter(SourceFilter.BGG_USER); | |||
| } | |||
| }); | |||
| btnFamily.addMouseListener(new MouseAdapter() { | |||
| @Override | |||
| public void mouseUp(MouseEvent e) { | |||
| selectFilter(SourceFilter.FAMILY); | |||
| } | |||
| }); | |||
| btnGeeklist.addMouseListener(new MouseAdapter() { | |||
| @Override | |||
| public void mouseUp(MouseEvent e) { | |||
| selectFilter(SourceFilter.GEEKLIST); | |||
| } | |||
| }); | |||
| Composite centerComposite = new Composite(main, SWT.NONE); | |||
| centerComposite.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true, 1, 1)); | |||
| GridLayout gl_centerComposite = new GridLayout(1, false); | |||
| BatLayouts.applyStandardSpacing(gl_centerComposite); | |||
| centerComposite.setLayout(gl_centerComposite); | |||
| filterGroup = new Group(centerComposite, SWT.NONE); | |||
| filterGroup.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, true, 1, 1)); | |||
| filterGroup.setLayout(new GridLayout(1, false)); | |||
| Composite applyComposite = new Composite(main, SWT.NONE); | |||
| applyComposite.setLayout(new GridLayout(5, false)); | |||
| applyComposite.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, false, 1, 1)); | |||
| Button btnOnlyNew = new Button(applyComposite, SWT.NONE); | |||
| btnOnlyNew.addMouseListener(new MouseAdapter() { | |||
| @Override | |||
| public void mouseUp(MouseEvent e) { | |||
| } | |||
| }); | |||
| btnOnlyNew.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/only_new_60x60.png")); | |||
| btnOnlyNew.setToolTipText("Keep only new"); | |||
| Button btnReplace = new Button(applyComposite, SWT.NONE); | |||
| btnReplace.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/result_replace_60x60.png")); | |||
| btnReplace.setToolTipText("Replace"); | |||
| Button btnAdd = new Button(applyComposite, SWT.NONE); | |||
| btnAdd.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/result_add_60x60.png")); | |||
| btnAdd.setToolTipText("Add"); | |||
| Button btnSubtract = new Button(applyComposite, SWT.NONE); | |||
| btnSubtract.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/result_subtract_60x60.png")); | |||
| btnSubtract.setToolTipText("Subtract"); | |||
| Button btnIntersect = new Button(applyComposite, SWT.NONE); | |||
| btnIntersect.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/result_intersect_60x60.png")); | |||
| btnIntersect.setToolTipText("Intersect"); | |||
| // init filter using config manager | |||
| source = configManager.getResultConfig().source; | |||
| selectFilter(source); | |||
| showFilter(filterGroup, source); | |||
| } | |||
| private void selectFilter(SourceFilter source) { | |||
| switch(source) { | |||
| default: | |||
| case BGG_USER: | |||
| btnBggUser.setFocus(); | |||
| btnBggUser.setBackground(BatColors.getButtonBgColor()); | |||
| btnFamily.setBackground(null); | |||
| btnGeeklist.setBackground(null); | |||
| break; | |||
| case FAMILY: | |||
| btnBggUser.setFocus(); | |||
| btnBggUser.setBackground(null); | |||
| btnFamily.setBackground(BatColors.getButtonBgColor()); | |||
| btnGeeklist.setBackground(null); | |||
| break; | |||
| case GEEKLIST: | |||
| btnGeeklist.setFocus(); | |||
| btnBggUser.setBackground(null); | |||
| btnFamily.setBackground(null); | |||
| btnGeeklist.setBackground(BatColors.getButtonBgColor()); | |||
| break; | |||
| } | |||
| showFilter(filterGroup, source); | |||
| eventBroker.send(EventConstants.TOPIC_ACTION_CHANGED, source); | |||
| } | |||
| /// show different filter controls depending on selection in cbSource ComboViewer | |||
| private void showFilter(Composite parent, SourceFilter source) { | |||
| // clean up | |||
| for(Control child : parent.getChildren()) { | |||
| child.dispose(); | |||
| } | |||
| // create a new filter area based on selection: | |||
| switch(source) { | |||
| default: | |||
| case BGG_USER: | |||
| System.out.println("construct " + source); | |||
| bggUserSourceFilter.create(parent, SWT.FILL); | |||
| break; | |||
| case GEEKLIST: | |||
| System.out.println("construct " + source); | |||
| geeklistSourceFilter.create(parent, SWT.FILL); | |||
| break; | |||
| case FAMILY: | |||
| System.out.println("construct " + source); | |||
| familySourceFilter.create(parent, SWT.FILL); | |||
| break; | |||
| } | |||
| main.layout(true, true); | |||
| } | |||
| private void checkEntry() { | |||
| ResultConfig resultConfig = configManager.getResultConfig(); | |||
| if(source == SourceFilter.BGG_USER) { | |||
| String user = resultConfig.user; | |||
| if(user == null || user.isEmpty()) { | |||
| MessageDialog.openError(main.getShell(), "", "Please enter a user name."); | |||
| return; | |||
| } else { | |||
| eventBroker.send(EventConstants.TOPIC_STATUS, "Fetching " + source.toString() + " '" + user + "'..."); | |||
| try { | |||
| ArrayList<Thing> things = bggApi.getThingsForUser(user); | |||
| useThingsOnResult(things); | |||
| } | |||
| catch(IllegalArgumentException ex) { | |||
| MessageDialog.openError(main.getShell(), "", ex.getMessage()); | |||
| } | |||
| } | |||
| } else if(source == SourceFilter.GEEKLIST) { | |||
| Integer geeklistId = resultConfig.geeklistId; | |||
| if(geeklistId == null) { | |||
| MessageDialog.openError(main.getShell(), "", "Please enter a geeklist id."); | |||
| return; | |||
| } else { | |||
| eventBroker.send(EventConstants.TOPIC_STATUS, "Fetching for geeklist id '" + geeklistId + "'"); | |||
| try { | |||
| ArrayList<Thing> things = bggApi.getThingsForGeeklist(geeklistId); | |||
| useThingsOnResult(things); | |||
| } | |||
| catch(IllegalArgumentException ex) { | |||
| MessageDialog.openError(main.getShell(), "", ex.getMessage()); | |||
| } | |||
| } | |||
| } else if(source == SourceFilter.FAMILY) { | |||
| Integer familyId = resultConfig.familyId; | |||
| if(familyId == null) { | |||
| MessageDialog.openError(main.getShell(), "", "Please enter a family id."); | |||
| return; | |||
| } else { | |||
| eventBroker.send(EventConstants.TOPIC_STATUS, "Fetching for family id '" + familyId + "'"); | |||
| try { | |||
| ArrayList<Thing> things = bggApi.getThingsForFamily(familyId); | |||
| useThingsOnResult(things); | |||
| } | |||
| catch(IllegalArgumentException ex) { | |||
| MessageDialog.openError(main.getShell(), "", ex.getMessage()); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| private void useThingsOnResult(ArrayList<Thing> things) { | |||
| switch(configManager.getResultConfig().action) { | |||
| case REP: | |||
| thingProvider.replaceThings(things); | |||
| break; | |||
| case ADD: | |||
| thingProvider.addThings(things); | |||
| break; | |||
| case SUB: | |||
| thingProvider.subtractThings(things); | |||
| break; | |||
| case AND: | |||
| thingProvider.intersectThings(things); | |||
| break; | |||
| case ONLY_NEW: | |||
| thingProvider.keepOnlyNew(things); | |||
| break; | |||
| } | |||
| eventBroker.send(EventConstants.TOPIC_RESULT_CHANGED, ""); | |||
| eventBroker.send(EventConstants.TOPIC_STATUS, "Fetched " + Integer.toString(things.size()) + " things."); | |||
| } | |||
| } | |||
| @@ -0,0 +1,35 @@ | |||
| package xyz.veronie.bgg.ui.parts.internal; | |||
| import org.eclipse.jface.viewers.OwnerDrawLabelProvider; | |||
| import org.eclipse.swt.graphics.Image; | |||
| import org.eclipse.swt.graphics.Rectangle; | |||
| import org.eclipse.swt.widgets.Event; | |||
| import org.eclipse.swt.widgets.TableItem; | |||
| public abstract class CenterImageLabelProvider extends OwnerDrawLabelProvider { | |||
| protected void measure(Event event, Object element) { | |||
| } | |||
| protected void paint(Event event, Object element) { | |||
| Image img = getImage(element); | |||
| if (img != null) { | |||
| Rectangle bounds = ((TableItem) event.item).getBounds(event.index); | |||
| Rectangle imgBounds = img.getBounds(); | |||
| bounds.width /= 2; | |||
| bounds.width -= imgBounds.width / 2; | |||
| bounds.height /= 2; | |||
| bounds.height -= imgBounds.height / 2; | |||
| int x = bounds.width > 0 ? bounds.x + bounds.width : bounds.x; | |||
| int y = bounds.height > 0 ? bounds.y + bounds.height : bounds.y; | |||
| event.gc.drawImage(img, x, y); | |||
| } | |||
| } | |||
| protected abstract Image getImage(Object element); | |||
| }; | |||