Cleaned up directories. Fixed issue with tween location & immediate manager.start() bug

This commit is contained in:
nathan 2015-11-02 02:32:32 +01:00
parent 7ac732626e
commit 99904f4bd9
10 changed files with 132 additions and 62 deletions

View File

@ -4,12 +4,14 @@
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/dist" />
<excludeFolder url="file://$MODULE_DIR$/libs" />
</content>
<orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="dorkbox tween_engine" level="application" />
<orderEntry type="module" module-name="Dorkbox-Util" />
<orderEntry type="module" module-name="JavaLauncher-Util" />
<orderEntry type="module" module-name="TweenEngine" />
</component>
<component name="org.twodividedbyzero.idea.findbugs">
<option name="_basePreferences">

View File

@ -20,6 +20,10 @@ Primary Features:
- This is for cross-platform use, specifically - linux 32/64, mac 32/64, and windows 32/64. Java 6+
```
Growl.IMAGE_PATH (type String, default value 'resources')
- Location of the dialog image resources. By default they must be in the 'resources' directory relative to the application
```
![growl-light image](https://raw.githubusercontent.com/dorkbox/Growl/master/growl-light.png)

View File

@ -16,24 +16,25 @@
package dorkbox.util.growl;
import dorkbox.util.ActionHandler;
import dorkbox.util.LocationResolver;
import dorkbox.util.SwingUtil;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
/**
* Popup notification messages, similar to the popular "Growl" notification system on macosx, that display in the corner of the monitor.
* </p>
* They can follow the mouse (if the screen is unspecified), and have a variety of features, such as "shaking" to draw attention,
* animating upon movement (for collating w/ multiple in a single location), and automatically hiding after a set duration.
* </p>
* These notifications are for a single screen only, and cannot be anchored to an application.
*
* </p> They can follow the mouse (if the screen is unspecified), and have a variety of features, such as "shaking" to draw attention,
* animating upon movement (for collating w/ multiple in a single location), and automatically hiding after a set duration. </p> These
* notifications are for a single screen only, and cannot be anchored to an application.
* <p>
* <pre>
* {@code
* Growl.create()
@ -50,26 +51,14 @@ class Growl {
public static final int FOREVER = 0;
/**
* Location of the dialog image resources. By default they must be in the 'resources' directory relative to the application
*/
public static String IMAGE_PATH = "resources";
private static Map<String, BufferedImage> imageCache = new HashMap<String, BufferedImage>(4);
private static Map<String, ImageIcon> imageIconCache = new HashMap<String, ImageIcon>(4);
String title;
String text;
Pos position = Pos.BOTTOM_RIGHT;
int hideAfterDurationInMillis = 5000;
boolean hideCloseButton;
boolean isDark = false;
int screenNumber = Short.MIN_VALUE;
private Image graphic;
private ActionHandler<Growl> onAction;
private GrowlPopup growlPopup;
private String name;
private int shakeDurationInMillis = 0;
private int shakeAmplitude = 0;
/**
* Builder pattern to create the growl notification.
*/
@ -78,6 +67,69 @@ class Growl {
return new Growl();
}
/**
* Permits one to override the default images for the dialogs. This is NOT thread safe, and must be performed BEFORE using the GROWL
* system.
* <p>
* The image names are as follows:
* <p>
* 'dialog-confirm.png' 'dialog-error.png' 'dialog-information.png' 'dialog-warning.png'
*
* @param imageName the name of the image, either your own if you want want it cached, or one of the above.
* @param image the BufferedImage that you want to cache.
*/
public static
void setImagePath(String imageName, BufferedImage image) {
if (imageCache.containsKey(imageName)) {
throw new RuntimeException("Unable to set an image that already has been set. This action must be done as soon as possible.");
}
imageCache.put(imageName, image);
}
private static
BufferedImage getImage(String imageName) {
BufferedImage bufferedImage = imageCache.get(imageName);
InputStream resourceAsStream = null;
try {
if (bufferedImage == null) {
String name = IMAGE_PATH + File.separatorChar + imageName;
resourceAsStream = LocationResolver.getResourceAsStream(name);
bufferedImage = ImageIO.read(resourceAsStream);
imageCache.put(imageName, bufferedImage);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (resourceAsStream != null) {
try {
resourceAsStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return bufferedImage;
}
String title;
String text;
Pos position = Pos.BOTTOM_RIGHT;
int hideAfterDurationInMillis = 5000;
boolean hideCloseButton;
boolean isDark = false;
int screenNumber = Short.MIN_VALUE;
private Image graphic;
private ActionHandler<Growl> onAction;
private GrowlPopup growlPopup;
private String name;
private int shakeDurationInMillis = 0;
private int shakeAmplitude = 0;
private
Growl() {
}
@ -163,7 +215,7 @@ class Growl {
*/
public
void showWarning() {
name = "/dorkbox/util/growl/dialog-warning.png";
name = "dialog-warning.png";
graphic(getImage(name));
show();
}
@ -173,7 +225,7 @@ class Growl {
*/
public
void showInformation() {
name = "/dorkbox/util/growl/dialog-information.png";
name = "dialog-information.png";
graphic(getImage(name));
show();
}
@ -183,7 +235,7 @@ class Growl {
*/
public
void showError() {
name = "/dorkbox/util/growl/dialog-error.png";
name = "dialog-error.png";
graphic(getImage(name));
show();
}
@ -193,7 +245,7 @@ class Growl {
*/
public
void showConfirm() {
name = "/dorkbox/util/growl/dialog-confirm.png";
name = "dialog-confirm.png";
graphic(getImage(name));
show();
}
@ -282,7 +334,6 @@ class Growl {
});
}
/**
* Specifies which screen to display on. If <0, it will show on screen 0. If > max-screens, it will show on the last screen.
*/
@ -300,20 +351,5 @@ class Growl {
growlPopup = null;
graphic = null;
}
private
BufferedImage getImage(String imageName) {
BufferedImage bufferedImage = imageCache.get(imageName);
try {
if (bufferedImage == null) {
bufferedImage = ImageIO.read(Growl.class.getResourceAsStream(imageName));
imageCache.put(imageName, bufferedImage);
}
} catch (IOException e) {
e.printStackTrace();
}
return bufferedImage;
}
}

View File

@ -364,7 +364,6 @@ class GrowlPopup extends JFrame {
// popups at TOP grow down, popups at BOTTOM grow up
int targetY;
if (isShowFromTop(position)) {
targetY = anchorY + (popupIndex * (HEIGHT + 10));
}
@ -377,7 +376,7 @@ class GrowlPopup extends JFrame {
if (notification.hideAfterDurationInMillis > 0 && hideTween == null) {
// begin a timeline to get rid of the popup (default is 5 seconds)
hideTween = Tween.set(this, 0, accessor)
hideTween = Tween.set(this, GrowlPopupAccessor.OPACITY, accessor)
.delay(FADE_DURATION + (notification.hideAfterDurationInMillis / 1000.0F))
.target(0)
.addCallback(new TweenCallback() {
@ -388,10 +387,10 @@ class GrowlPopup extends JFrame {
}
});
tweenManager.add(hideTween);
}
if (!timer.isRunning()) {
timer.start();
if (!timer.isRunning()) {
timer.start();
}
}
}
}
@ -407,8 +406,28 @@ class GrowlPopup extends JFrame {
final int popupIndex = this.popupIndex;
final ArrayList<GrowlPopup> growlPopups = popups.get(idAndPosition);
int length = growlPopups.size();
final ArrayList<GrowlPopup> copies = new ArrayList<GrowlPopup>(length);
// if we are the LAST tween, don't adjust anything (since nothing will move anyways)
if (popupIndex == length - 1) {
growlPopups.remove(popupIndex);
if (tween != null) {
tween.kill();
}
if (hideTween != null) {
hideTween.kill();
}
// if there's nothing left, stop the timer.
if (copies.isEmpty()) {
timer.stop();
}
return;
}
int adjustedI = 0;
for (int i = 0; i < length; i++) {
final GrowlPopup popup = growlPopups.get(i);
@ -418,6 +437,7 @@ class GrowlPopup extends JFrame {
}
if (i != popupIndex) {
// move the others into the correct position
int newPopupIndex = adjustedI++;
popup.popupIndex = newPopupIndex;
@ -433,14 +453,15 @@ class GrowlPopup extends JFrame {
copies.add(popup);
// now animate that popup to it's new location
Tween tween = Tween.to(popup, 1, accessor, MOVE_DURATION)
Tween tween = Tween.to(popup, GrowlPopupAccessor.Y_POS, accessor, MOVE_DURATION)
.target((float) changedY)
.ease(TweenEquations.Linear);
tweenManager.add(tween);
popup.tween = tween;
} else {
if (this.hideTween != null) {
}
else {
if (hideTween != null) {
hideTween.kill();
}
}
@ -453,6 +474,10 @@ class GrowlPopup extends JFrame {
if (copies.isEmpty()) {
timer.stop();
}
else if (!timer.isRunning()) {
tweenManager.resetUpdateTime();
timer.start();
}
}
}
@ -483,7 +508,7 @@ class GrowlPopup extends JFrame {
void shake(final int durationInMillis, final int amplitude) {
System.err.println("shake");
Tween tween = Tween.to(this, 2, accessor, 0.05F)
Tween tween = Tween.to(this, GrowlPopupAccessor.X_Y_POS, accessor, 0.05F)
.targetRelative(amplitude, amplitude)
.repeatAutoReverse(durationInMillis / 50, 0)
.ease(TweenEquations.Linear);

View File

@ -19,6 +19,11 @@ import dorkbox.util.tweenengine.TweenAccessor;
class GrowlPopupAccessor implements TweenAccessor<GrowlPopup> {
static final int OPACITY = 0;
static final int Y_POS = 1;
static final int X_Y_POS = 2;
GrowlPopupAccessor() {
}
@ -26,13 +31,13 @@ class GrowlPopupAccessor implements TweenAccessor<GrowlPopup> {
public
int getValues(final GrowlPopup target, final int tweenType, final float[] returnValues) {
switch (tweenType) {
case 0:
case OPACITY:
returnValues[0] = target.getOpacity_Compat();
return 1;
case 1:
case Y_POS:
returnValues[0] = (float) target.getY();
return 1;
case 2:
case X_Y_POS:
returnValues[0] = (float) target.getX();
returnValues[1] = (float) target.getY();
return 2;
@ -44,13 +49,14 @@ class GrowlPopupAccessor implements TweenAccessor<GrowlPopup> {
public
void setValues(final GrowlPopup target, final int tweenType, final float[] newValues) {
switch (tweenType) {
case 0:
case OPACITY:
target.setOpacity_Compat(newValues[0]);
return;
case 1:
case Y_POS:
//noinspection NumericCastThatLosesPrecision
target.setY((int) newValues[0]);
case 2:
return;
case X_Y_POS:
//noinspection NumericCastThatLosesPrecision
target.setLocation((int) newValues[0], (int) newValues[1]);
}

View File

@ -4,9 +4,6 @@ import java.awt.Window;
class WindowUtil_Java7plus implements WindowUtil {
String test = "asdasd";
static String basdasdasd = "asdasdasdasdasd";
@Override
public
float getOpacity(final Window window) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB