Переглянути джерело

Revamped UI completely.

Added icons.
pull/2/head
veronie 4 роки тому
джерело
коміт
c226835208
30 змінених файлів з 1613 додано та 104 видалено
  1. +1
    -0
      xyz.veronie.bgg.ui/.classpath
  2. +6
    -25
      xyz.veronie.bgg.ui/Application.e4xmi
  3. +5
    -3
      xyz.veronie.bgg.ui/META-INF/MANIFEST.MF
  4. BIN
      xyz.veronie.bgg.ui/icons/download-button.png
  5. BIN
      xyz.veronie.bgg.ui/icons/export_nandeck_60x60.png
  6. BIN
      xyz.veronie.bgg.ui/icons/folder-symbol.png
  7. BIN
      xyz.veronie.bgg.ui/icons/noun_Download_60x60.png
  8. BIN
      xyz.veronie.bgg.ui/icons/noun_Family_60x60.png
  9. BIN
      xyz.veronie.bgg.ui/icons/noun_List_60x60.png
  10. BIN
      xyz.veronie.bgg.ui/icons/noun_Meeple_60x60.png
  11. BIN
      xyz.veronie.bgg.ui/icons/noun_Save_60x60.png
  12. BIN
      xyz.veronie.bgg.ui/icons/noun_Undo_60x60.png
  13. BIN
      xyz.veronie.bgg.ui/icons/noun_open_60x60.png
  14. BIN
      xyz.veronie.bgg.ui/icons/only_new_60x60.png
  15. BIN
      xyz.veronie.bgg.ui/icons/result_add_60x60.png
  16. BIN
      xyz.veronie.bgg.ui/icons/result_intersect_60x60.png
  17. BIN
      xyz.veronie.bgg.ui/icons/result_replace_60x60.png
  18. BIN
      xyz.veronie.bgg.ui/icons/result_subtract_60x60.png
  19. BIN
      xyz.veronie.bgg.ui/icons/save-button.png
  20. BIN
      xyz.veronie.bgg.ui/icons/save-button_20x20.png
  21. +438
    -0
      xyz.veronie.bgg.ui/src/org/eclipse/wb/swt/ResourceManager.java
  22. +447
    -0
      xyz.veronie.bgg.ui/src/org/eclipse/wb/swt/SWTResourceManager.java
  23. +68
    -45
      xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/dialogs/SaveGameListDialog.java
  24. +6
    -3
      xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/handlers/HandleSaveGamelist.java
  25. +16
    -0
      xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/helpers/BatColors.java
  26. +18
    -0
      xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/helpers/BatLayouts.java
  27. +274
    -0
      xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/parts/BatMain.java
  28. +1
    -28
      xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/parts/BggResultPart.java
  29. +298
    -0
      xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/parts/FetchPart.java
  30. +35
    -0
      xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/parts/internal/CenterImageLabelProvider.java

+ 1
- 0
xyz.veronie.bgg.ui/.classpath Переглянути файл

@@ -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>

+ 6
- 25
xyz.veronie.bgg.ui/Application.e4xmi Переглянути файл

@@ -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"/>


+ 5
- 3
xyz.veronie.bgg.ui/META-INF/MANIFEST.MF Переглянути файл

@@ -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

BIN
xyz.veronie.bgg.ui/icons/download-button.png Переглянути файл

Перед Після
Ширина: 512  |  Висота: 512  |  Розмір: 1.5KB

BIN
xyz.veronie.bgg.ui/icons/export_nandeck_60x60.png Переглянути файл

Перед Після
Ширина: 60  |  Висота: 60  |  Розмір: 5.5KB

BIN
xyz.veronie.bgg.ui/icons/folder-symbol.png Переглянути файл

Перед Після
Ширина: 512  |  Висота: 512  |  Розмір: 2.2KB

BIN
xyz.veronie.bgg.ui/icons/noun_Download_60x60.png Переглянути файл

Перед Після
Ширина: 60  |  Висота: 60  |  Розмір: 2.0KB

BIN
xyz.veronie.bgg.ui/icons/noun_Family_60x60.png Переглянути файл

Перед Після
Ширина: 60  |  Висота: 60  |  Розмір: 2.4KB

BIN
xyz.veronie.bgg.ui/icons/noun_List_60x60.png Переглянути файл

Перед Після
Ширина: 60  |  Висота: 60  |  Розмір: 2.1KB

BIN
xyz.veronie.bgg.ui/icons/noun_Meeple_60x60.png Переглянути файл

Перед Після
Ширина: 60  |  Висота: 60  |  Розмір: 1.8KB

BIN
xyz.veronie.bgg.ui/icons/noun_Save_60x60.png Переглянути файл

Перед Після
Ширина: 60  |  Висота: 60  |  Розмір: 1.6KB

BIN
xyz.veronie.bgg.ui/icons/noun_Undo_60x60.png Переглянути файл

Перед Після
Ширина: 60  |  Висота: 60  |  Розмір: 2.0KB

BIN
xyz.veronie.bgg.ui/icons/noun_open_60x60.png Переглянути файл

Перед Після
Ширина: 60  |  Висота: 60  |  Розмір: 1.8KB

BIN
xyz.veronie.bgg.ui/icons/only_new_60x60.png Переглянути файл

Перед Після
Ширина: 60  |  Висота: 60  |  Розмір: 6.9KB

BIN
xyz.veronie.bgg.ui/icons/result_add_60x60.png Переглянути файл

Перед Після
Ширина: 60  |  Висота: 60  |  Розмір: 7.9KB

BIN
xyz.veronie.bgg.ui/icons/result_intersect_60x60.png Переглянути файл

Перед Після
Ширина: 60  |  Висота: 60  |  Розмір: 6.5KB

BIN
xyz.veronie.bgg.ui/icons/result_replace_60x60.png Переглянути файл

Перед Після
Ширина: 60  |  Висота: 60  |  Розмір: 7.3KB

BIN
xyz.veronie.bgg.ui/icons/result_subtract_60x60.png Переглянути файл

Перед Після
Ширина: 60  |  Висота: 60  |  Розмір: 7.0KB

BIN
xyz.veronie.bgg.ui/icons/save-button.png Переглянути файл

Перед Після
Ширина: 16  |  Висота: 16  |  Розмір: 1.9KB

BIN
xyz.veronie.bgg.ui/icons/save-button_20x20.png Переглянути файл

Перед Після
Ширина: 20  |  Висота: 20  |  Розмір: 3.5KB

+ 438
- 0
xyz.veronie.bgg.ui/src/org/eclipse/wb/swt/ResourceManager.java Переглянути файл

@@ -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();
}
}

+ 447
- 0
xyz.veronie.bgg.ui/src/org/eclipse/wb/swt/SWTResourceManager.java Переглянути файл

@@ -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();
}
}

+ 68
- 45
xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/dialogs/SaveGameListDialog.java Переглянути файл

@@ -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;


+ 6
- 3
xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/handlers/HandleSaveGamelist.java Переглянути файл

@@ -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) {


+ 16
- 0
xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/helpers/BatColors.java Переглянути файл

@@ -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);
}
}

+ 18
- 0
xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/helpers/BatLayouts.java Переглянути файл

@@ -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;
}
}

+ 274
- 0
xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/parts/BatMain.java Переглянути файл

@@ -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();
// }
}
}

+ 1
- 28
xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/parts/BggResultPart.java Переглянути файл

@@ -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));


+ 298
- 0
xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/parts/FetchPart.java Переглянути файл

@@ -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.");
}
}

+ 35
- 0
xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/parts/internal/CenterImageLabelProvider.java Переглянути файл

@@ -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);
};

Завантаження…
Відмінити
Зберегти