Merge branch 'feature/bufferedimage' into 'master'
Feature/bufferedimage See merge request FlareMicrosystems/visualforecast-1000!1
This commit is contained in:
@@ -2,6 +2,6 @@
|
|||||||
<classpath>
|
<classpath>
|
||||||
<classpathentry kind="src" path="src"/>
|
<classpathentry kind="src" path="src"/>
|
||||||
<classpathentry kind="src" path="resources"/>
|
<classpathentry kind="src" path="resources"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
eclipse.preferences.version=1
|
eclipse.preferences.version=1
|
||||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||||
org.eclipse.jdt.core.compiler.source=1.8
|
org.eclipse.jdt.core.compiler.source=1.6
|
||||||
|
|||||||
37
src/com/flaremicro/flaretv/visualforecast/Executor.java
Normal file
37
src/com/flaremicro/flaretv/visualforecast/Executor.java
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import com.flaremicro.flaretv.visualforecast.interfaces.Tickable;
|
||||||
|
|
||||||
|
public class Executor {
|
||||||
|
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
|
||||||
|
|
||||||
|
private final Tickable tickable;
|
||||||
|
private final long sleepNanos;
|
||||||
|
|
||||||
|
//private long nextTick = 0;
|
||||||
|
|
||||||
|
Executor(Tickable tickable, long sleepNanos) {
|
||||||
|
this.tickable = tickable;
|
||||||
|
this.sleepNanos = sleepNanos;
|
||||||
|
}
|
||||||
|
|
||||||
|
Executor(Tickable tickable, int ticksPerSecond) {
|
||||||
|
this(tickable, (long) ((1 / (double) ticksPerSecond) * 1000000000L));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void end() {
|
||||||
|
scheduler.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void begin() {
|
||||||
|
scheduler.scheduleAtFixedRate(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
tickable.tick();
|
||||||
|
}
|
||||||
|
}, 0, sleepNanos, TimeUnit.NANOSECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import com.flaremicro.util.Util;
|
||||||
|
|
||||||
|
public class PropertyManager {
|
||||||
|
private final Properties underlyingProperties = new Properties();
|
||||||
|
private static File propFile = new File("./vf1000.properties");
|
||||||
|
|
||||||
|
public boolean load() {
|
||||||
|
Reader reader = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
reader = new FileReader(propFile);
|
||||||
|
underlyingProperties.load(reader);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Util.cleanClose(reader);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean store() {
|
||||||
|
Writer writer = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
writer = new FileWriter(propFile);
|
||||||
|
underlyingProperties.store(writer, "VisualForecast 1000 Properties file. Functional provider must be set for successful boot!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally{
|
||||||
|
Util.cleanClose(writer);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,24 +3,29 @@ package com.flaremicro.flaretv.visualforecast;
|
|||||||
import java.awt.BasicStroke;
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.awt.FontFormatException;
|
|
||||||
import java.awt.GradientPaint;
|
import java.awt.GradientPaint;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.GraphicsConfiguration;
|
import java.awt.GraphicsConfiguration;
|
||||||
import java.awt.Polygon;
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.event.ComponentEvent;
|
||||||
|
import java.awt.event.ComponentListener;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import java.awt.image.VolatileImage;
|
import java.awt.image.VolatileImage;
|
||||||
import java.io.IOException;
|
|
||||||
import java.text.DateFormat;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.concurrent.locks.LockSupport;
|
|
||||||
|
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
import com.flaremicro.flaretv.visualforecast.icons.IconProvider;
|
import static com.flaremicro.flaretv.visualforecast.graphics.RenderConstants.*;
|
||||||
|
|
||||||
public class RenderPanel extends JPanel implements Runnable {
|
import com.flaremicro.flaretv.visualforecast.flavour.DayForecastFlavour;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.flavour.Flavour;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.graphics.DrawingUtil;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.graphics.FontManager;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.interfaces.Tickable;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.providerapi.MockForecastProvider;
|
||||||
|
|
||||||
|
public class RenderPanel extends JPanel implements Tickable, ComponentListener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -29,65 +34,32 @@ public class RenderPanel extends JPanel implements Runnable {
|
|||||||
|
|
||||||
private VolatileImage frameBuffer = null;
|
private VolatileImage frameBuffer = null;
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the panel.
|
|
||||||
*/
|
|
||||||
|
|
||||||
private Color backgroundPurple = new Color(0x2b29b3);
|
|
||||||
private Color backgroundOrange = new Color(0xff8c00);
|
|
||||||
private Color backgroundBlue = new Color(0x394aa8);
|
|
||||||
|
|
||||||
private Font font = null;
|
private Font font = null;
|
||||||
|
|
||||||
float fontMult = 20F;
|
private Flavour currentFlavour = new DayForecastFlavour();
|
||||||
|
|
||||||
private int animationTick = 0;
|
private int iconAnimationTicks = 0;
|
||||||
|
private long ticks = 0;
|
||||||
|
|
||||||
private String[] testString;
|
private Rectangle redrawBound = new Rectangle(0, 0, 1, 1);
|
||||||
|
private Rectangle exclusiveRedrawBound = null;
|
||||||
|
|
||||||
|
private String currentTown = "";
|
||||||
|
private String currentForecast = "";
|
||||||
|
|
||||||
public RenderPanel() {
|
public RenderPanel() {
|
||||||
try
|
this.addComponentListener(this);
|
||||||
{
|
this.setDoubleBuffered(true);
|
||||||
font = Font.createFont(Font.TRUETYPE_FONT, this.getClass().getResourceAsStream("/Star4000.ttf"));
|
font = FontManager.getInstance().getOrCreateFont(Font.TRUETYPE_FONT, this.getClass().getResource("/Star4000.ttf"));
|
||||||
}
|
currentFlavour.initFlavour(this, MockForecastProvider.provideMockForecast(), ticks, iconAnimationTicks);
|
||||||
catch (FontFormatException e)
|
//new Thread(new TickThread(this, 30)).start();
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
testString = "The sandwiches at gas stations\nare disgusting, we advise you\ndo not eat them".split("\n");
|
|
||||||
new Thread(this).start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int W = 640, H = 480;
|
private Graphics2D prepareFrameBuffer() {
|
||||||
private static final int INFOBAR_HEIGHT = 80;
|
|
||||||
private static final int TOPBAR_HEIGHT = 80;
|
|
||||||
private static final int MAINBAR_HEIGHT = H - INFOBAR_HEIGHT - TOPBAR_HEIGHT;
|
|
||||||
|
|
||||||
private static final int HEADERBAR_Y = 20;
|
|
||||||
private static final double HEADERBAR_SHEAR = 0.2;
|
|
||||||
private static final int HEADERBAR_OFFSET = 20;
|
|
||||||
private static final int HEADERBAR_WIDTH = 400 + HEADERBAR_OFFSET;
|
|
||||||
private static final int HEADERBAR_HEIGHT = TOPBAR_HEIGHT - HEADERBAR_Y;
|
|
||||||
|
|
||||||
private static final int TIMEBAR_Y = 40;
|
|
||||||
private static final int TIMEBAR_OFFSET = 20;
|
|
||||||
private static final int TIMEBAR_WIDTH = 230 + HEADERBAR_OFFSET;
|
|
||||||
private static final int TIMEBAR_HEIGHT = TOPBAR_HEIGHT - TIMEBAR_Y;
|
|
||||||
|
|
||||||
private static final int STROKE_WIDTH = 2;
|
|
||||||
private static final int STROKE_OFFSET = STROKE_WIDTH / 2;
|
|
||||||
|
|
||||||
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("MMMM d");
|
|
||||||
private static final DateFormat TIME_FORMAT = new SimpleDateFormat("hh:mm:ss a");
|
|
||||||
|
|
||||||
public Graphics2D prepareFrameBuffer() {
|
|
||||||
GraphicsConfiguration gc = this.getGraphicsConfiguration();
|
GraphicsConfiguration gc = this.getGraphicsConfiguration();
|
||||||
if (frameBuffer == null || frameBuffer.validate(gc) != VolatileImage.IMAGE_INCOMPATIBLE)
|
if (frameBuffer == null || frameBuffer.validate(gc) == VolatileImage.IMAGE_INCOMPATIBLE)
|
||||||
{
|
{
|
||||||
|
System.out.println("new image req'd");
|
||||||
frameBuffer = gc.createCompatibleVolatileImage(W, H);
|
frameBuffer = gc.createCompatibleVolatileImage(W, H);
|
||||||
}
|
}
|
||||||
return (Graphics2D) frameBuffer.getGraphics();
|
return (Graphics2D) frameBuffer.getGraphics();
|
||||||
@@ -115,29 +87,41 @@ public class RenderPanel extends JPanel implements Runnable {
|
|||||||
public void paintComponent(Graphics g) {
|
public void paintComponent(Graphics g) {
|
||||||
super.paintComponent(g);
|
super.paintComponent(g);
|
||||||
Graphics2D g2d = prepareFrameBuffer();
|
Graphics2D g2d = prepareFrameBuffer();
|
||||||
if (font == null)
|
|
||||||
font = g2d.getFont();
|
drawMainRegion(g2d);
|
||||||
|
if (currentFlavour != null)
|
||||||
|
{
|
||||||
|
if (this.getBounds().equals(g.getClipBounds()))
|
||||||
|
this.currentFlavour.drawFlavour(this, g2d, ticks, iconAnimationTicks);
|
||||||
|
if (g.getClipBounds() != null)
|
||||||
|
this.currentFlavour.drawBoundLimitedFlavour(this, g2d, g.getClipBounds(), ticks, iconAnimationTicks);
|
||||||
|
}
|
||||||
|
g2d.dispose();
|
||||||
|
g.drawImage(frameBuffer, 0, 0, getWidth(), getHeight(), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawMainRegion(Graphics2D g2d) {
|
||||||
g2d.setFont(font.deriveFont(24F));
|
g2d.setFont(font.deriveFont(24F));
|
||||||
|
|
||||||
g2d.setStroke(new BasicStroke(2));
|
g2d.setStroke(new BasicStroke(2));
|
||||||
|
|
||||||
g2d.setColor(this.backgroundPurple);
|
g2d.setColor(BG_PURPLE);
|
||||||
g2d.fillRect(0, 0, W, TOPBAR_HEIGHT);
|
g2d.fillRect(0, 0, W, TOPBAR_HEIGHT);
|
||||||
|
|
||||||
g2d.setPaint(new GradientPaint(0, HEADERBAR_Y, backgroundOrange, 0, HEADERBAR_Y + (HEADERBAR_HEIGHT + 10), backgroundPurple));
|
g2d.setPaint(new GradientPaint(0, HEADERBAR_Y, BG_OORANGE, 0, HEADERBAR_Y + (HEADERBAR_HEIGHT + 10), BG_PURPLE));
|
||||||
g2d.shear(HEADERBAR_SHEAR, 0);
|
g2d.shear(HEADERBAR_SHEAR, 0);
|
||||||
g2d.fillRect(-HEADERBAR_OFFSET, HEADERBAR_Y, HEADERBAR_WIDTH, HEADERBAR_HEIGHT);
|
g2d.fillRect(-HEADERBAR_OFFSET, HEADERBAR_Y, HEADERBAR_WIDTH, HEADERBAR_HEIGHT);
|
||||||
|
|
||||||
g2d.setPaint(new GradientPaint(0, HEADERBAR_Y, backgroundPurple.brighter().brighter().brighter(), 0, HEADERBAR_Y + (HEADERBAR_HEIGHT + 10), backgroundPurple));
|
g2d.setPaint(new GradientPaint(0, HEADERBAR_Y, BG_PURPLE.brighter().brighter().brighter(), 0, HEADERBAR_Y + (HEADERBAR_HEIGHT + 10), BG_PURPLE));
|
||||||
g2d.fillRect(W - TIMEBAR_WIDTH + TIMEBAR_OFFSET, TIMEBAR_Y, TIMEBAR_WIDTH, TIMEBAR_HEIGHT);
|
g2d.fillRect(W - TIMEBAR_WIDTH + TIMEBAR_OFFSET, TIMEBAR_Y, TIMEBAR_WIDTH, TIMEBAR_HEIGHT);
|
||||||
g2d.shear(-HEADERBAR_SHEAR, 0);
|
g2d.shear(-HEADERBAR_SHEAR, 0);
|
||||||
|
|
||||||
g2d.setPaint(new GradientPaint(0, TOPBAR_HEIGHT, backgroundPurple, 0, MAINBAR_HEIGHT, backgroundOrange));
|
g2d.setPaint(new GradientPaint(0, TOPBAR_HEIGHT, BG_PURPLE, 0, MAINBAR_HEIGHT, BG_OORANGE));
|
||||||
g2d.fillRect(0, TOPBAR_HEIGHT, W, MAINBAR_HEIGHT);
|
g2d.fillRect(0, TOPBAR_HEIGHT, W, MAINBAR_HEIGHT);
|
||||||
|
|
||||||
g2d.fillRect(0, TOPBAR_HEIGHT, W, MAINBAR_HEIGHT);
|
g2d.fillRect(0, TOPBAR_HEIGHT, W, MAINBAR_HEIGHT);
|
||||||
|
|
||||||
g2d.setColor(this.backgroundBlue);
|
g2d.setColor(BG_BLUE);
|
||||||
g2d.fillRect(0, H - INFOBAR_HEIGHT, W, INFOBAR_HEIGHT);
|
g2d.fillRect(0, H - INFOBAR_HEIGHT, W, INFOBAR_HEIGHT);
|
||||||
|
|
||||||
g2d.setColor(Color.DARK_GRAY);
|
g2d.setColor(Color.DARK_GRAY);
|
||||||
@@ -146,105 +130,123 @@ public class RenderPanel extends JPanel implements Runnable {
|
|||||||
g2d.setColor(Color.WHITE);
|
g2d.setColor(Color.WHITE);
|
||||||
g2d.drawLine(0, H - INFOBAR_HEIGHT + STROKE_WIDTH + STROKE_OFFSET, W, H - INFOBAR_HEIGHT + STROKE_WIDTH + STROKE_OFFSET);
|
g2d.drawLine(0, H - INFOBAR_HEIGHT + STROKE_WIDTH + STROKE_OFFSET, W, H - INFOBAR_HEIGHT + STROKE_WIDTH + STROKE_OFFSET);
|
||||||
|
|
||||||
drawGradientRect(g2d, 60, TOPBAR_HEIGHT, W - 120, MAINBAR_HEIGHT, 20, backgroundBlue.brighter(), backgroundBlue.darker());
|
|
||||||
g2d.setColor(backgroundBlue.brighter());
|
|
||||||
g2d.drawRect(60 + STROKE_OFFSET, TOPBAR_HEIGHT + STROKE_OFFSET, W - 120 - STROKE_WIDTH, MAINBAR_HEIGHT - STROKE_WIDTH);
|
|
||||||
// g2d.setColor(Color.GRAY);
|
// g2d.setColor(Color.GRAY);
|
||||||
// g2d.drawRect(60, TOPBAR_HEIGHT+2, W-120, MAINBAR_HEIGHT-4);
|
// g2d.drawRect(60, TOPBAR_HEIGHT+2, W-120, MAINBAR_HEIGHT-4);
|
||||||
|
|
||||||
String dateString = DATE_FORMAT.format(System.currentTimeMillis()) + getDayOfMonthSuffix();
|
String dateString = DATE_FORMAT.format(System.currentTimeMillis()) + getDayOfMonthSuffix();
|
||||||
String timeString = TIME_FORMAT.format(System.currentTimeMillis());
|
String timeString = TIME_FORMAT.format(System.currentTimeMillis());
|
||||||
|
|
||||||
// g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
DrawingUtil.drawOutlinedString(g2d, 60, HEADERBAR_Y + 18, currentForecast, Color.WHITE, Color.BLACK, 2);
|
||||||
// RenderingHints.VALUE_ANTIALIAS_ON);
|
|
||||||
drawOutlinedString(g2d, 60, HEADERBAR_Y + 18, "Your local forecast", Color.WHITE, Color.BLACK, 1);
|
|
||||||
int sw = g2d.getFontMetrics().stringWidth(dateString);
|
int sw = g2d.getFontMetrics().stringWidth(dateString);
|
||||||
drawOutlinedString(g2d, W - sw - 60, TIMEBAR_Y + 18, dateString, Color.WHITE, Color.BLACK, 1);
|
DrawingUtil.drawOutlinedString(g2d, W - sw - 60, TIMEBAR_Y + 18, dateString, Color.WHITE, Color.BLACK, 2);
|
||||||
sw = g2d.getFontMetrics().stringWidth(timeString);
|
sw = g2d.getFontMetrics().stringWidth(timeString);
|
||||||
drawOutlinedString(g2d, W - sw - 60, TIMEBAR_Y + 36, timeString, Color.WHITE, Color.BLACK, 1);
|
DrawingUtil.drawOutlinedString(g2d, W - sw - 60, TIMEBAR_Y + 36, timeString, Color.WHITE, Color.BLACK, 2);
|
||||||
g2d.setFont(font.deriveFont(36F));
|
g2d.setFont(font.deriveFont(36F));
|
||||||
drawOutlinedString(g2d, 60, HEADERBAR_Y + 52, "New Westminster, BC", Color.YELLOW, Color.BLACK, 2);
|
DrawingUtil.drawOutlinedString(g2d, 60, HEADERBAR_Y + 52, currentTown, Color.YELLOW, Color.BLACK, 2);
|
||||||
|
|
||||||
int w2 = g2d.getFontMetrics().stringWidth("EXTREME WEATHER ADVISORY");
|
g2d.setFont(font.deriveFont(26F));
|
||||||
drawOutlinedString(g2d, (W >> 1) - (w2 >> 1), TOPBAR_HEIGHT + 48, "EXTREME WEATHER ADVISORY", Color.RED, Color.BLACK, 2);
|
DrawingUtil.drawOutlinedString(g2d, -20, H - INFOBAR_HEIGHT + 30, "Welcome to WeatherBC! Stay tuned for your long range forcast", Color.WHITE, Color.BLACK, 2);
|
||||||
|
|
||||||
g2d.setFont(font.deriveFont(30F));
|
}
|
||||||
for (int i = 0; i < testString.length; i++)
|
|
||||||
|
public void tick() {
|
||||||
|
this.ticks++;
|
||||||
|
if (ticks / 3.75F > this.iconAnimationTicks)
|
||||||
{
|
{
|
||||||
drawOutlinedString(g2d, 90, TOPBAR_HEIGHT + 78 + 25 * i, testString[i], Color.WHITE, Color.BLACK, 1);
|
this.iconAnimationTicks++;
|
||||||
}
|
//Clock and icon animations, should use repaint regions later
|
||||||
|
if (getWidth() > 0 && getHeight() > 0)
|
||||||
// g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
|
||||||
// RenderingHints.VALUE_ANTIALIAS_ON);
|
|
||||||
IconProvider.drawIcon(g2d, IconProvider.SNOWFLAKE, 80, 300, 80, animationTick);
|
|
||||||
IconProvider.drawIcon(g2d, IconProvider.CLOUD, 160, 300, 80, animationTick);
|
|
||||||
IconProvider.drawIcon(g2d, IconProvider.PARTLY_CLOUDY, 160 + 80, 300, 80, animationTick);
|
|
||||||
IconProvider.drawIcon(g2d, IconProvider.CLOUDY_CLOUDY, 160 + 160, 300, 80, animationTick);
|
|
||||||
IconProvider.drawIcon(g2d, IconProvider.RAIN, 160 + 160 + 80, 300, 80, animationTick);
|
|
||||||
IconProvider.drawIcon(g2d, IconProvider.SCATTERD_SHOWERS, 160 + 160 + 160, 300, 80, animationTick);
|
|
||||||
|
|
||||||
g2d.dispose();
|
|
||||||
g.drawImage(frameBuffer, 0, 0, getWidth(), getHeight(), this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void drawGradientRect(Graphics2D g, int x, int y, int w, int h, int borderWidth, Color innerColor, Color outerColor) {
|
|
||||||
|
|
||||||
g.setColor(innerColor);
|
|
||||||
g.fillRect(x, y, w, h);
|
|
||||||
|
|
||||||
g.setPaint(new GradientPaint(x, 0, outerColor, x + borderWidth, 0, innerColor));
|
|
||||||
g.fillRect(x, y, borderWidth, h);
|
|
||||||
|
|
||||||
g.setPaint(new GradientPaint(x + w - borderWidth, 0, innerColor, x + w, 0, outerColor));
|
|
||||||
g.fillRect(x + w - borderWidth, y, borderWidth, h);
|
|
||||||
|
|
||||||
g.setPaint(new GradientPaint(0, y, outerColor, 0, y + borderWidth, innerColor));
|
|
||||||
g.setClip(new Polygon(new int[] { x, x + w, x + w - borderWidth, x + borderWidth }, new int[] { y, y, y + borderWidth, y + borderWidth }, 4));
|
|
||||||
g.fillRect(x, y, w, borderWidth);
|
|
||||||
|
|
||||||
g.setClip(new Polygon(new int[] { x, x + w, x + w - borderWidth, x + borderWidth }, new int[] { y + h, y + h, y + h - borderWidth, y + h - borderWidth }, 4));
|
|
||||||
g.setPaint(new GradientPaint(0, y + h - borderWidth, innerColor, 0, y + h, outerColor));
|
|
||||||
g.fillRect(x, y + h - borderWidth, w, borderWidth);
|
|
||||||
|
|
||||||
g.setClip(null);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void drawOutlinedString(Graphics2D g2d, int x, int y, String text, Color textColor, Color outline, int outlineSize) {
|
|
||||||
g2d.setColor(outline);
|
|
||||||
for (int i = 1; i <= outlineSize; i++)
|
|
||||||
{
|
{
|
||||||
g2d.drawString(text, x + i, y);
|
repaint(this.redrawBound);
|
||||||
g2d.drawString(text, x - i, y);
|
}
|
||||||
g2d.drawString(text, x, y + i);
|
}
|
||||||
g2d.drawString(text, x, y - i);
|
if (this.currentFlavour != null)
|
||||||
g2d.drawString(text, x + i, y + i);
|
this.currentFlavour.tick(this, ticks, iconAnimationTicks);
|
||||||
g2d.drawString(text, x - i, y - i);
|
|
||||||
g2d.drawString(text, x - i, y + i);
|
|
||||||
g2d.drawString(text, x + i, y - i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g2d.setColor(textColor);
|
public BufferedImage getSnapshot() {
|
||||||
g2d.drawString(text, x, y);
|
return frameBuffer.getSnapshot();
|
||||||
/*
|
}
|
||||||
* AffineTransform transform = g2d.getTransform();
|
|
||||||
* transform.translate(x, y); g2d.transform(transform);
|
private void addRedrawBound(int x, int y, int w, int h, boolean isExclusive){
|
||||||
* g2d.setColor(outline); FontRenderContext frc =
|
|
||||||
* g2d.getFontRenderContext(); TextLayout tl = new TextLayout(text,
|
float wScale = getWidth() / (float) W;
|
||||||
* g2d.getFont(), frc); Shape shape = tl.getOutline(null);
|
float hScale = getHeight() / (float) H;
|
||||||
* g2d.setStroke(new BasicStroke(outlineSize)); g2d.draw(shape);
|
Rectangle rect = new Rectangle((int) (x * wScale), (int) (y * hScale), (int) (w * wScale), (int) (h * hScale));
|
||||||
* g2d.setColor(textColor); g2d.fill(shape);
|
if(isExclusive)
|
||||||
*/
|
this.exclusiveRedrawBound = rect;
|
||||||
|
if (redrawBound == null)
|
||||||
|
this.redrawBound = new Rectangle((int) (x * wScale), (int) (y * hScale), (int) (w * wScale), (int) (h * hScale));
|
||||||
|
else this.redrawBound.add(rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addRedrawBound(int x, int y, int w, int h) {
|
||||||
|
addRedrawBound(x, y, w, h, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public void componentResized(ComponentEvent e) {
|
||||||
|
loseRedrawRegion();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loseRedrawRegion() {
|
||||||
|
this.redrawBound = null;
|
||||||
|
addRedrawBound(W - TIMEBAR_WIDTH + TIMEBAR_OFFSET, TIMEBAR_Y, TIMEBAR_WIDTH, TIMEBAR_HEIGHT, false);
|
||||||
|
if (this.currentFlavour != null)
|
||||||
|
this.currentFlavour.redrawRegionlost(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void componentMoved(ComponentEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void componentShown(ComponentEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void componentHidden(ComponentEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void nextFlavour() {
|
||||||
|
this.currentFlavour = new DayForecastFlavour();
|
||||||
|
this.currentFlavour.initFlavour(this, MockForecastProvider.provideMockForecast(), ticks, iconAnimationTicks);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentTown(String currentTown){
|
||||||
|
this.currentTown = currentTown;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentForecast(String currentForecast){
|
||||||
|
this.currentForecast = currentForecast;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void requestFullRepaint() {
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void requestBoundedRepaint() {
|
||||||
|
repaint(redrawBound);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void requestExclusiveBoundedRepaint() {
|
||||||
|
repaint(exclusiveRedrawBound);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
this.animationTick++;
|
this.iconAnimationTicks++;
|
||||||
repaint();
|
repaint();
|
||||||
LockSupport.parkNanos(125000000);
|
LockSupport.parkNanos(125000000);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
package com.flaremicro.flaretv.visualforecast;
|
|
||||||
|
|
||||||
import javax.swing.JFrame;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.border.EmptyBorder;
|
|
||||||
import javax.swing.event.ChangeEvent;
|
|
||||||
import javax.swing.event.ChangeListener;
|
|
||||||
import javax.swing.JSpinner;
|
|
||||||
import javax.swing.SpinnerNumberModel;
|
|
||||||
|
|
||||||
public class SmallTextInfo extends JFrame {
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
private JPanel contentPane;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the frame.
|
|
||||||
*/
|
|
||||||
public SmallTextInfo(RenderPanel rp) {
|
|
||||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
||||||
setBounds(100, 100, 295, 93);
|
|
||||||
contentPane = new JPanel();
|
|
||||||
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
|
|
||||||
setContentPane(contentPane);
|
|
||||||
contentPane.setLayout(null);
|
|
||||||
|
|
||||||
JSpinner spinner = new JSpinner();
|
|
||||||
spinner.setModel(new SpinnerNumberModel(new Float(rp.fontMult), null, null, new Float(0.5F)));
|
|
||||||
spinner.setBounds(12, 12, 255, 22);
|
|
||||||
spinner.addChangeListener(new ChangeListener(){
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stateChanged(ChangeEvent e) {
|
|
||||||
rp.fontMult = (Float)spinner.getValue();
|
|
||||||
rp.repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
contentPane.add(spinner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.flaremicro.flaretv.visualforecast;
|
package com.flaremicro.flaretv.visualforecast;
|
||||||
|
|
||||||
|
import java.util.concurrent.locks.LockSupport;
|
||||||
|
|
||||||
import com.flaremicro.flaretv.visualforecast.interfaces.Tickable;
|
import com.flaremicro.flaretv.visualforecast.interfaces.Tickable;
|
||||||
|
|
||||||
public class TickThread implements Runnable {
|
public class TickThread implements Runnable {
|
||||||
@@ -7,20 +9,25 @@ public class TickThread implements Runnable {
|
|||||||
private boolean running = true;
|
private boolean running = true;
|
||||||
private final long sleepNanos;
|
private final long sleepNanos;
|
||||||
|
|
||||||
private long nextTick = 0;
|
//private long nextTick = 0;
|
||||||
|
|
||||||
TickThread(Tickable tickable, long sleepNanos) {
|
TickThread(Tickable tickable, long sleepNanos) {
|
||||||
this.tickable = tickable;
|
this.tickable = tickable;
|
||||||
this.sleepNanos = sleepNanos;
|
this.sleepNanos = sleepNanos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TickThread(Tickable tickable, int ticksPerSecond) {
|
||||||
|
this(tickable, (long) ((1/(double)ticksPerSecond) * 1000000000L));
|
||||||
|
}
|
||||||
|
|
||||||
public void end() {
|
public void end() {
|
||||||
this.running = false;
|
this.running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
|
long nanosLost = 0;
|
||||||
while (running) {
|
while (running) {
|
||||||
while(System.nanoTime() < nextTick)
|
/*while(System.nanoTime() < nextTick)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -32,12 +39,13 @@ public class TickThread implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
nextTick = System.nanoTime() + sleepNanos;
|
nextTick = System.nanoTime() + sleepNanos;
|
||||||
|
tickable.tick();*/
|
||||||
tickable.tick();
|
tickable.tick();
|
||||||
/*long nanosLost = System.nanoTime();
|
|
||||||
panel.tick();
|
|
||||||
nanosLost -= System.nanoTime();
|
nanosLost -= System.nanoTime();
|
||||||
if(sleepNanos+nanosLost > 0)
|
//Unnecessary conditional?
|
||||||
LockSupport.parkNanos(sleepNanos+nanosLost);*/
|
//if(sleepNanos+nanosLost > 0)
|
||||||
|
LockSupport.parkNanos(sleepNanos+nanosLost);
|
||||||
|
nanosLost = System.nanoTime();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,16 +2,26 @@ package com.flaremicro.flaretv.visualforecast;
|
|||||||
|
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.event.KeyListener;
|
||||||
|
import java.awt.event.WindowEvent;
|
||||||
|
import java.awt.event.WindowListener;
|
||||||
|
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
|
|
||||||
public class VisualForecastFrame extends JFrame {
|
import com.flaremicro.flaretv.visualforecast.providerapi.ForecastProviderManager;
|
||||||
|
|
||||||
|
public class VisualForecastFrame extends JFrame implements WindowListener, KeyListener{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private RenderPanel contentPane;
|
private RenderPanel renderPane;
|
||||||
|
private ForecastProviderManager forecastProviderManager;
|
||||||
|
private Executor executor;
|
||||||
|
private PropertyManager propertyManager;
|
||||||
|
private boolean isFullscreen = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Launch the application.
|
* Launch the application.
|
||||||
@@ -22,6 +32,9 @@ public class VisualForecastFrame extends JFrame {
|
|||||||
try {
|
try {
|
||||||
VisualForecastFrame frame = new VisualForecastFrame();
|
VisualForecastFrame frame = new VisualForecastFrame();
|
||||||
frame.setVisible(true);
|
frame.setVisible(true);
|
||||||
|
frame.init();
|
||||||
|
//GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[1].setFullScreenWindow(frame);
|
||||||
|
frame.createBufferStrategy(2);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@@ -29,17 +42,108 @@ public class VisualForecastFrame extends JFrame {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void end()
|
||||||
|
{
|
||||||
|
if(executor != null)
|
||||||
|
executor.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init()
|
||||||
|
{
|
||||||
|
end();
|
||||||
|
executor = new Executor(this.renderPane, 30);
|
||||||
|
executor.begin();
|
||||||
|
|
||||||
|
forecastProviderManager = new ForecastProviderManager();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the frame.
|
* Create the frame.
|
||||||
*/
|
*/
|
||||||
public VisualForecastFrame() {
|
public VisualForecastFrame() {
|
||||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
||||||
setBounds(100, 100, 640*2, 480*2);
|
setBounds(100, 100, 640*2, 480*2);
|
||||||
contentPane = new RenderPanel();
|
renderPane = new RenderPanel();
|
||||||
contentPane.setBorder(null);
|
renderPane.setBorder(null);
|
||||||
contentPane.setLayout(new BorderLayout(0, 0));
|
renderPane.setLayout(new BorderLayout(0, 0));
|
||||||
setContentPane(contentPane);
|
setContentPane(renderPane);
|
||||||
setUndecorated(true);
|
setUndecorated(true);
|
||||||
|
addWindowListener(this);
|
||||||
|
addKeyListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowOpened(WindowEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowClosing(WindowEvent e) {
|
||||||
|
|
||||||
|
end();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowClosed(WindowEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowIconified(WindowEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowDeiconified(WindowEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowActivated(WindowEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowDeactivated(WindowEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyTyped(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
if(e.getKeyCode() == KeyEvent.VK_F11)
|
||||||
|
{
|
||||||
|
if(isFullscreen)
|
||||||
|
{
|
||||||
|
isFullscreen = false;
|
||||||
|
this.getGraphicsConfiguration().getDevice().setFullScreenWindow(null);
|
||||||
|
setBounds(100, 100, 640*2, 480*2);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
isFullscreen = true;
|
||||||
|
this.getGraphicsConfiguration().getDevice().setFullScreenWindow(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyReleased(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,283 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.flavour;
|
||||||
|
|
||||||
|
import static com.flaremicro.flaretv.visualforecast.graphics.RenderConstants.MAINBAR_HEIGHT;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.FontMetrics;
|
||||||
|
import java.awt.GradientPaint;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.Transparency;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import com.flaremicro.flaretv.visualforecast.RenderPanel;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.forecast.DayForecast;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.forecast.ForecastDetails;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.forecast.TownForecast;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.forecast.ValueCheck;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.graphics.DrawingUtil;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.graphics.FontManager;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.graphics.RenderConstants;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.IconProvider;
|
||||||
|
|
||||||
|
public class DayForecastFlavour implements Flavour {
|
||||||
|
private int dayOffset = 0;
|
||||||
|
private Font font;
|
||||||
|
private Font smallFont;
|
||||||
|
private ForecastDetails details;
|
||||||
|
private TownForecast currentTown = null;
|
||||||
|
private TownForecast previousTown = null;
|
||||||
|
private int townIndex;
|
||||||
|
|
||||||
|
private BufferedImage mainBound = null;
|
||||||
|
private BufferedImage prevBound = null;
|
||||||
|
|
||||||
|
private int ticksBeforeChange = 200;
|
||||||
|
private int animationTicks = -1;
|
||||||
|
|
||||||
|
public DayForecastFlavour() {
|
||||||
|
font = FontManager.getInstance().getOrCreateFont(Font.TRUETYPE_FONT, this.getClass().getResource("/Star4000.ttf"));
|
||||||
|
smallFont = FontManager.getInstance().getOrCreateFont(Font.TRUETYPE_FONT, this.getClass().getResource("/Star4000 Small.ttf"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick(RenderPanel renderer, long ticks, int iconTicks) {
|
||||||
|
if(animationTicks >= 0)
|
||||||
|
{
|
||||||
|
animationTicks += 8;
|
||||||
|
if(animationTicks > RenderConstants.W - 60)
|
||||||
|
{
|
||||||
|
animationTicks = -1;
|
||||||
|
prevBound.flush();
|
||||||
|
prevBound = null;
|
||||||
|
renderer.requestFullRepaint();
|
||||||
|
renderer.loseRedrawRegion();
|
||||||
|
}
|
||||||
|
else renderer.requestExclusiveBoundedRepaint();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ticksBeforeChange--;
|
||||||
|
if (ticksBeforeChange < 0)
|
||||||
|
{
|
||||||
|
animationTicks = 0;
|
||||||
|
if(prevBound != null)
|
||||||
|
prevBound.flush();
|
||||||
|
if(mainBound != null)
|
||||||
|
mainBound.flush();
|
||||||
|
prevBound = renderer.getGraphicsConfiguration().createCompatibleImage(526, MAINBAR_HEIGHT - 28, Transparency.BITMASK);
|
||||||
|
mainBound = renderer.getGraphicsConfiguration().createCompatibleImage(526, MAINBAR_HEIGHT - 28, Transparency.BITMASK);
|
||||||
|
mainBound.setAccelerationPriority(1);
|
||||||
|
prevBound.setAccelerationPriority(1);
|
||||||
|
|
||||||
|
ticksBeforeChange = 200;
|
||||||
|
dayOffset = dayOffset + 4;
|
||||||
|
if (dayOffset >= 8)
|
||||||
|
{
|
||||||
|
dayOffset = 0;
|
||||||
|
townIndex++;
|
||||||
|
if (townIndex >= details.getTownForecast().length)
|
||||||
|
{
|
||||||
|
renderer.nextFlavour();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
previousTown = currentTown;
|
||||||
|
currentTown = details.getTownForecast()[townIndex];
|
||||||
|
renderer.setCurrentTown(currentTown.getTownName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Flicker workaround
|
||||||
|
BufferedImage throwaway = new BufferedImage(1, 1, BufferedImage.TYPE_3BYTE_BGR);
|
||||||
|
Graphics2D g2d = throwaway.createGraphics();
|
||||||
|
this.drawFlavour(renderer, g2d, ticks, iconTicks);
|
||||||
|
g2d.dispose();
|
||||||
|
throwaway.flush();
|
||||||
|
|
||||||
|
renderer.loseRedrawRegion();
|
||||||
|
renderer.requestFullRepaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initFlavour(RenderPanel renderer, ForecastDetails details, long ticks, int iconTicks) {
|
||||||
|
this.details = details;
|
||||||
|
renderer.setCurrentForecast("7 Day Forecast");
|
||||||
|
if (details == null || details.getTownForecast() == null || details.getTownForecast().length <= 0)
|
||||||
|
this.details = null;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
townIndex = 0;
|
||||||
|
currentTown = details.getTownForecast()[townIndex];
|
||||||
|
renderer.setCurrentTown(currentTown.getTownName());
|
||||||
|
}
|
||||||
|
redrawRegionlost(renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDay(int offset) {
|
||||||
|
if (offset == 0)
|
||||||
|
return "Today";
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
cal.add(Calendar.HOUR, offset * 24);
|
||||||
|
return cal.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.US);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawFlavour(RenderPanel renderer, Graphics2D g2d, long ticks, int iconTicks) {
|
||||||
|
if (details == null || currentTown == null || currentTown.getDayForecast() == null || currentTown.getDayForecast().length <= 0)
|
||||||
|
{
|
||||||
|
DrawingUtil.drawGradientRect(g2d, RenderConstants.SIDE_OFFSET + 80, RenderConstants.TOPBAR_HEIGHT + 90, RenderConstants.W - RenderConstants.SIDE_OFFSET * 2 - 160, (RenderConstants.TOPBAR_HEIGHT + 20), 10, new Color(0x220088), new Color(0x110055));
|
||||||
|
g2d.setFont(font.deriveFont(26F));
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET + 60 + (RenderConstants.W - RenderConstants.SIDE_OFFSET * 2 - 120) / 2 - (g2d.getFontMetrics().stringWidth("Forcast data") / 2), RenderConstants.TOPBAR_HEIGHT + 130, "Forecast data", Color.WHITE, Color.BLACK, 2);
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET + 60 + (RenderConstants.W - RenderConstants.SIDE_OFFSET * 2 - 120) / 2 - (g2d.getFontMetrics().stringWidth("temporarily unavailable") / 2), RenderConstants.TOPBAR_HEIGHT + 160, "temporarily unavailable", Color.WHITE, Color.BLACK, 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(animationTicks < 0)
|
||||||
|
{
|
||||||
|
drawTownForecast(g2d, currentTown, dayOffset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Graphics2D gimg = prevBound.createGraphics();
|
||||||
|
Graphics2D gimg2 = mainBound.createGraphics();
|
||||||
|
gimg.translate(-RenderConstants.SIDE_OFFSET+1, -RenderConstants.TOPBAR_HEIGHT - 14);
|
||||||
|
gimg2.translate(-RenderConstants.SIDE_OFFSET+1, -RenderConstants.TOPBAR_HEIGHT - 14);
|
||||||
|
gimg.setStroke(new BasicStroke(2));
|
||||||
|
gimg2.setStroke(new BasicStroke(2));
|
||||||
|
if(dayOffset == 0)
|
||||||
|
{
|
||||||
|
drawTownForecast(gimg, previousTown, dayOffset + 4);
|
||||||
|
drawTownForecast(gimg2, currentTown, dayOffset);
|
||||||
|
} else {
|
||||||
|
drawTownForecast(gimg, currentTown, dayOffset - 4);
|
||||||
|
drawTownForecast(gimg2, currentTown, dayOffset);
|
||||||
|
}
|
||||||
|
gimg.dispose();
|
||||||
|
gimg2.dispose();
|
||||||
|
|
||||||
|
g2d.setClip(animationTicks + RenderConstants.SIDE_OFFSET, RenderConstants.TOPBAR_HEIGHT+14, 526-animationTicks, MAINBAR_HEIGHT - 28);
|
||||||
|
g2d.drawImage(prevBound, RenderConstants.SIDE_OFFSET-1, RenderConstants.TOPBAR_HEIGHT + 14, renderer);
|
||||||
|
g2d.setClip(0, RenderConstants.TOPBAR_HEIGHT+15, animationTicks, MAINBAR_HEIGHT - 28);
|
||||||
|
g2d.drawImage(mainBound, RenderConstants.SIDE_OFFSET-1, RenderConstants.TOPBAR_HEIGHT + 14, renderer);
|
||||||
|
g2d.setClip(null);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(animationTicks < 0)
|
||||||
|
{
|
||||||
|
mainBound = renderer.getSnapshot().getSubimage(RenderConstants.SIDE_OFFSET-1, RenderConstants.TOPBAR_HEIGHT + 14, 526, MAINBAR_HEIGHT - 28);
|
||||||
|
mainBound.setAccelerationPriority(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawTownForecast(Graphics2D g2d, TownForecast townForecast, int dayOffset)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Math.min(4, townForecast.getDayForecast().length - dayOffset); i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
DayForecast forecast = townForecast.getDayForecast()[i + dayOffset];
|
||||||
|
g2d.setColor(RenderConstants.BG_BLUE.brighter().brighter());
|
||||||
|
g2d.fillRect(RenderConstants.SIDE_OFFSET + 131 * i, RenderConstants.TOPBAR_HEIGHT + 15, 127, MAINBAR_HEIGHT - 30);
|
||||||
|
|
||||||
|
g2d.setPaint(new GradientPaint(0, RenderConstants.TOPBAR_HEIGHT + 40, new Color(0x7777FF), 0, (RenderConstants.TOPBAR_HEIGHT + 40) + MAINBAR_HEIGHT - 60, new Color(0x0000BB)));
|
||||||
|
g2d.fillRoundRect(RenderConstants.SIDE_OFFSET + 5 + 131 * i, RenderConstants.TOPBAR_HEIGHT + 20, 117, MAINBAR_HEIGHT - 40, 10, 10);
|
||||||
|
g2d.setColor(Color.BLACK);
|
||||||
|
g2d.drawRoundRect(RenderConstants.SIDE_OFFSET + 5 + 131 * i, RenderConstants.TOPBAR_HEIGHT + 20, 117, MAINBAR_HEIGHT - 40, 10, 10);
|
||||||
|
g2d.drawRect(RenderConstants.SIDE_OFFSET + 131 * i, RenderConstants.TOPBAR_HEIGHT + 15, 127, MAINBAR_HEIGHT - 30);
|
||||||
|
|
||||||
|
String day = getDay(i + dayOffset);
|
||||||
|
|
||||||
|
g2d.setFont(font.deriveFont(26F));
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET + (131 * i) + (127 / 2) - (g2d.getFontMetrics().stringWidth(day) / 2), RenderConstants.TOPBAR_HEIGHT + 50, day, Color.WHITE, Color.BLACK, 2);
|
||||||
|
|
||||||
|
String statLine1;
|
||||||
|
String statLine2;
|
||||||
|
if (ValueCheck.valueNoData(forecast.weatherLine1))
|
||||||
|
{
|
||||||
|
statLine1 = "MISSING";
|
||||||
|
statLine2 = "DATA";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
statLine1 = forecast.weatherLine1;
|
||||||
|
statLine2 = ValueCheck.valueNoData(forecast.weatherLine2) ? "" : forecast.weatherLine2;
|
||||||
|
}
|
||||||
|
FontMetrics metrics = g2d.getFontMetrics();
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET + (131 * i) + (127 / 2) - (metrics.stringWidth(statLine1) / 2), RenderConstants.TOPBAR_HEIGHT + 170, statLine1, Color.WHITE, Color.BLACK, 2);
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET + (131 * i) + (127 / 2) - (metrics.stringWidth(statLine2) / 2), RenderConstants.TOPBAR_HEIGHT + 200, statLine2, Color.WHITE, Color.BLACK, 2);
|
||||||
|
|
||||||
|
if (!ValueCheck.valueNoData(forecast.hiTemp) && !ValueCheck.valueNoData(forecast.loTemp))
|
||||||
|
{
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET + (131 * i) + 30 - (metrics.stringWidth(String.valueOf(forecast.hiTemp)) >> 1), RenderConstants.TOPBAR_HEIGHT + 295, String.valueOf(forecast.hiTemp), Color.WHITE, Color.BLACK, 2);
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET + (131 * i) + 92 - (metrics.stringWidth(String.valueOf(forecast.loTemp)) >> 1), RenderConstants.TOPBAR_HEIGHT + 295, String.valueOf(forecast.loTemp), Color.WHITE, Color.BLACK, 2);
|
||||||
|
|
||||||
|
g2d.setFont(smallFont.deriveFont(24F));
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET + (131 * i) + 20, RenderConstants.TOPBAR_HEIGHT + 270, "Hi", Color.RED, Color.BLACK, 2);
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET + (131 * i) + 82, RenderConstants.TOPBAR_HEIGHT + 270, "Lo", Color.CYAN, Color.BLACK, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ValueCheck.valueNoData(forecast.percipPercent))
|
||||||
|
{
|
||||||
|
String formattedPercent = String.format("%.2f%%", forecast.percipPercent);
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET + (131 * i) + (127 / 2) - (g2d.getFontMetrics().stringWidth("Precip.") / 2), RenderConstants.TOPBAR_HEIGHT + 230, "Precip.", Color.YELLOW, Color.BLACK, 2);
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET + (131 * i) + (127 / 2) - (g2d.getFontMetrics().stringWidth(formattedPercent) / 2), RenderConstants.TOPBAR_HEIGHT + 245, formattedPercent, Color.WHITE, Color.BLACK, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawBoundLimitedFlavour(RenderPanel renderer, Graphics2D g2d, Rectangle bounds, long ticks, int iconTicks) {
|
||||||
|
if (details != null && currentTown != null && currentTown.getDayForecast() != null && currentTown.getDayForecast().length > 0)
|
||||||
|
{
|
||||||
|
if(animationTicks < 0)
|
||||||
|
{
|
||||||
|
g2d.drawImage(mainBound, RenderConstants.SIDE_OFFSET-1, RenderConstants.TOPBAR_HEIGHT + 14, renderer);
|
||||||
|
drawIcons(g2d, currentTown, dayOffset, iconTicks);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g2d.setClip(animationTicks + RenderConstants.SIDE_OFFSET-1, RenderConstants.TOPBAR_HEIGHT+14, 526, MAINBAR_HEIGHT - 28);
|
||||||
|
g2d.drawImage(prevBound, RenderConstants.SIDE_OFFSET-1, RenderConstants.TOPBAR_HEIGHT + 14, renderer);
|
||||||
|
if(dayOffset == 0)
|
||||||
|
{
|
||||||
|
drawIcons(g2d, previousTown, dayOffset + 4, iconTicks);
|
||||||
|
g2d.setClip(0, RenderConstants.TOPBAR_HEIGHT+14, animationTicks, MAINBAR_HEIGHT - 28);
|
||||||
|
g2d.drawImage(mainBound, RenderConstants.SIDE_OFFSET-1, RenderConstants.TOPBAR_HEIGHT + 14, renderer);
|
||||||
|
drawIcons(g2d, currentTown, dayOffset, iconTicks);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
drawIcons(g2d, currentTown, dayOffset - 4, iconTicks);
|
||||||
|
g2d.setClip(0, RenderConstants.TOPBAR_HEIGHT+14, animationTicks, MAINBAR_HEIGHT - 28);
|
||||||
|
g2d.drawImage(mainBound, RenderConstants.SIDE_OFFSET-1, RenderConstants.TOPBAR_HEIGHT + 14, renderer);
|
||||||
|
drawIcons(g2d, currentTown, dayOffset, iconTicks);
|
||||||
|
}
|
||||||
|
g2d.setClip(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawIcons(Graphics2D g2d, TownForecast currentTown, int dayOffset, int iconTicks){
|
||||||
|
|
||||||
|
for (int i = 0; i < Math.min(4, currentTown.getDayForecast().length - dayOffset); i++)
|
||||||
|
{
|
||||||
|
DayForecast forecast = currentTown.getDayForecast()[i + dayOffset];
|
||||||
|
IconProvider.drawIcon(g2d, IconProvider.INDEXED_ICONS[forecast.iconId & IconProvider.INDEXED_ICONS.length - 1], RenderConstants.SIDE_OFFSET + (131 * i) + 24, RenderConstants.TOPBAR_HEIGHT + 60, 80, iconTicks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void redrawRegionlost(RenderPanel renderer) {
|
||||||
|
if(animationTicks >= 0)
|
||||||
|
renderer.addRedrawBound(0, RenderConstants.TOPBAR_HEIGHT, RenderConstants.W, RenderConstants.MAINBAR_HEIGHT);
|
||||||
|
else
|
||||||
|
renderer.addRedrawBound(RenderConstants.SIDE_OFFSET + 24, RenderConstants.TOPBAR_HEIGHT + 60, 604, 84);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,261 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.flavour;
|
||||||
|
|
||||||
|
import static com.flaremicro.flaretv.visualforecast.graphics.RenderConstants.MAINBAR_HEIGHT;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.FontMetrics;
|
||||||
|
import java.awt.GradientPaint;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.Transparency;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import com.flaremicro.flaretv.visualforecast.RenderPanel;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.forecast.DayForecast;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.forecast.ForecastDetails;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.forecast.TownForecast;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.forecast.ValueCheck;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.graphics.DrawingUtil;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.graphics.FontManager;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.graphics.RenderConstants;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.IconProvider;
|
||||||
|
|
||||||
|
public class DayForecastFlavourOldAnimation implements Flavour {
|
||||||
|
private int dayOffset = 0;
|
||||||
|
private Font font;
|
||||||
|
private Font smallFont;
|
||||||
|
private ForecastDetails details;
|
||||||
|
private TownForecast currentTown = null;
|
||||||
|
private TownForecast previousTown = null;
|
||||||
|
private int townIndex;
|
||||||
|
|
||||||
|
private BufferedImage lastBound = null;
|
||||||
|
|
||||||
|
private int ticksBeforeChange = 200;
|
||||||
|
private int animationTicks = -1;
|
||||||
|
|
||||||
|
public DayForecastFlavourOldAnimation() {
|
||||||
|
font = FontManager.getInstance().getOrCreateFont(Font.TRUETYPE_FONT, this.getClass().getResource("/Star4000.ttf"));
|
||||||
|
smallFont = FontManager.getInstance().getOrCreateFont(Font.TRUETYPE_FONT, this.getClass().getResource("/Star4000 Small.ttf"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick(RenderPanel renderer, long ticks, int iconTicks) {
|
||||||
|
if(animationTicks >= 0)
|
||||||
|
{
|
||||||
|
animationTicks += 8;
|
||||||
|
if(animationTicks > RenderConstants.W - 60)
|
||||||
|
{
|
||||||
|
animationTicks = -1;
|
||||||
|
renderer.requestFullRepaint();
|
||||||
|
renderer.loseRedrawRegion();
|
||||||
|
}
|
||||||
|
else renderer.requestExclusiveBoundedRepaint();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ticksBeforeChange--;
|
||||||
|
if (ticksBeforeChange < 0)
|
||||||
|
{
|
||||||
|
animationTicks = 0;
|
||||||
|
lastBound = renderer.getGraphicsConfiguration().createCompatibleImage(526*2+RenderConstants.SIDE_OFFSET, MAINBAR_HEIGHT - 28, Transparency.BITMASK);
|
||||||
|
lastBound.setAccelerationPriority(1);
|
||||||
|
ticksBeforeChange = 200;
|
||||||
|
dayOffset = dayOffset + 4;
|
||||||
|
if (dayOffset >= 8)
|
||||||
|
{
|
||||||
|
dayOffset = 0;
|
||||||
|
townIndex++;
|
||||||
|
if (townIndex >= details.getTownForecast().length)
|
||||||
|
{
|
||||||
|
renderer.nextFlavour();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
previousTown = currentTown;
|
||||||
|
currentTown = details.getTownForecast()[townIndex];
|
||||||
|
renderer.setCurrentTown(currentTown.getTownName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
renderer.loseRedrawRegion();
|
||||||
|
renderer.requestFullRepaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initFlavour(RenderPanel renderer, ForecastDetails details, long ticks, int iconTicks) {
|
||||||
|
this.details = details;
|
||||||
|
renderer.setCurrentForecast("7 Day Forecast");
|
||||||
|
if (details == null || details.getTownForecast() == null || details.getTownForecast().length <= 0)
|
||||||
|
this.details = null;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
townIndex = 0;
|
||||||
|
currentTown = details.getTownForecast()[townIndex];
|
||||||
|
renderer.setCurrentTown(currentTown.getTownName());
|
||||||
|
}
|
||||||
|
redrawRegionlost(renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDay(int offset) {
|
||||||
|
if (offset == 0)
|
||||||
|
return "Today";
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
cal.add(Calendar.HOUR, offset * 24);
|
||||||
|
return cal.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.US);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawFlavour(RenderPanel renderer, Graphics2D g2d, long ticks, int iconTicks) {
|
||||||
|
if (details == null || currentTown == null || currentTown.getDayForecast() == null || currentTown.getDayForecast().length <= 0)
|
||||||
|
{
|
||||||
|
DrawingUtil.drawGradientRect(g2d, RenderConstants.SIDE_OFFSET + 80, RenderConstants.TOPBAR_HEIGHT + 90, RenderConstants.W - RenderConstants.SIDE_OFFSET * 2 - 160, (RenderConstants.TOPBAR_HEIGHT + 20), 10, new Color(0x220088), new Color(0x110055));
|
||||||
|
g2d.setFont(font.deriveFont(26F));
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET + 60 + (RenderConstants.W - RenderConstants.SIDE_OFFSET * 2 - 120) / 2 - (g2d.getFontMetrics().stringWidth("Forcast data") / 2), RenderConstants.TOPBAR_HEIGHT + 130, "Forecast data", Color.WHITE, Color.BLACK, 2);
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET + 60 + (RenderConstants.W - RenderConstants.SIDE_OFFSET * 2 - 120) / 2 - (g2d.getFontMetrics().stringWidth("temporarily unavailable") / 2), RenderConstants.TOPBAR_HEIGHT + 160, "temporarily unavailable", Color.WHITE, Color.BLACK, 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(animationTicks < 0)
|
||||||
|
{
|
||||||
|
drawTownForecast(g2d, currentTown, dayOffset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Graphics2D gimg = lastBound.createGraphics();
|
||||||
|
gimg.translate(-RenderConstants.SIDE_OFFSET+1, -RenderConstants.TOPBAR_HEIGHT - 14);
|
||||||
|
gimg.setStroke(new BasicStroke(2));
|
||||||
|
if(dayOffset == 0)
|
||||||
|
{
|
||||||
|
drawTownForecast(gimg, previousTown, dayOffset + 4);
|
||||||
|
gimg.translate(RenderConstants.W - (RenderConstants.SIDE_OFFSET), 0);
|
||||||
|
drawTownForecast(gimg, currentTown, dayOffset);
|
||||||
|
gimg.translate(RenderConstants.SIDE_OFFSET - RenderConstants.W, 0);
|
||||||
|
} else {
|
||||||
|
drawTownForecast(gimg, currentTown, dayOffset - 4);
|
||||||
|
gimg.translate(RenderConstants.W - (RenderConstants.SIDE_OFFSET), 0);
|
||||||
|
drawTownForecast(gimg, currentTown, dayOffset);
|
||||||
|
gimg.translate(RenderConstants.SIDE_OFFSET - RenderConstants.W, 0);
|
||||||
|
}
|
||||||
|
gimg.dispose();
|
||||||
|
|
||||||
|
g2d.translate(-animationTicks, 0);
|
||||||
|
g2d.drawImage(lastBound, RenderConstants.SIDE_OFFSET, RenderConstants.TOPBAR_HEIGHT + 15, renderer);
|
||||||
|
g2d.translate(animationTicks, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(animationTicks < 0)
|
||||||
|
{
|
||||||
|
lastBound = renderer.getSnapshot().getSubimage(RenderConstants.SIDE_OFFSET-1, RenderConstants.TOPBAR_HEIGHT + 14, 526, MAINBAR_HEIGHT - 28);
|
||||||
|
lastBound.setAccelerationPriority(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawTownForecast(Graphics2D g2d, TownForecast townForecast, int dayOffset)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Math.min(4, townForecast.getDayForecast().length - dayOffset); i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
DayForecast forecast = townForecast.getDayForecast()[i + dayOffset];
|
||||||
|
g2d.setColor(RenderConstants.BG_BLUE.brighter().brighter());
|
||||||
|
g2d.fillRect(RenderConstants.SIDE_OFFSET + 131 * i, RenderConstants.TOPBAR_HEIGHT + 15, 127, MAINBAR_HEIGHT - 30);
|
||||||
|
|
||||||
|
g2d.setPaint(new GradientPaint(0, RenderConstants.TOPBAR_HEIGHT + 40, new Color(0x7777FF), 0, (RenderConstants.TOPBAR_HEIGHT + 40) + MAINBAR_HEIGHT - 60, new Color(0x0000BB)));
|
||||||
|
g2d.fillRoundRect(RenderConstants.SIDE_OFFSET + 5 + 131 * i, RenderConstants.TOPBAR_HEIGHT + 20, 117, MAINBAR_HEIGHT - 40, 10, 10);
|
||||||
|
g2d.setColor(Color.BLACK);
|
||||||
|
g2d.drawRoundRect(RenderConstants.SIDE_OFFSET + 5 + 131 * i, RenderConstants.TOPBAR_HEIGHT + 20, 117, MAINBAR_HEIGHT - 40, 10, 10);
|
||||||
|
g2d.drawRect(RenderConstants.SIDE_OFFSET + 131 * i, RenderConstants.TOPBAR_HEIGHT + 15, 127, MAINBAR_HEIGHT - 30);
|
||||||
|
|
||||||
|
String day = getDay(i + dayOffset);
|
||||||
|
|
||||||
|
g2d.setFont(font.deriveFont(26F));
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET + (131 * i) + (127 / 2) - (g2d.getFontMetrics().stringWidth(day) / 2), RenderConstants.TOPBAR_HEIGHT + 50, day, Color.WHITE, Color.BLACK, 2);
|
||||||
|
|
||||||
|
String statLine1;
|
||||||
|
String statLine2;
|
||||||
|
if (ValueCheck.valueNoData(forecast.weatherLine1))
|
||||||
|
{
|
||||||
|
statLine1 = "MISSING";
|
||||||
|
statLine2 = "DATA";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
statLine1 = forecast.weatherLine1;
|
||||||
|
statLine2 = ValueCheck.valueNoData(forecast.weatherLine2) ? "" : forecast.weatherLine2;
|
||||||
|
}
|
||||||
|
FontMetrics metrics = g2d.getFontMetrics();
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET + (131 * i) + (127 / 2) - (metrics.stringWidth(statLine1) / 2), RenderConstants.TOPBAR_HEIGHT + 170, statLine1, Color.WHITE, Color.BLACK, 2);
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET + (131 * i) + (127 / 2) - (metrics.stringWidth(statLine2) / 2), RenderConstants.TOPBAR_HEIGHT + 200, statLine2, Color.WHITE, Color.BLACK, 2);
|
||||||
|
|
||||||
|
if (!ValueCheck.valueNoData(forecast.hiTemp) && !ValueCheck.valueNoData(forecast.loTemp))
|
||||||
|
{
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET + (131 * i) + 30 - (metrics.stringWidth(String.valueOf(forecast.hiTemp)) >> 1), RenderConstants.TOPBAR_HEIGHT + 295, String.valueOf(forecast.hiTemp), Color.WHITE, Color.BLACK, 2);
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET + (131 * i) + 92 - (metrics.stringWidth(String.valueOf(forecast.loTemp)) >> 1), RenderConstants.TOPBAR_HEIGHT + 295, String.valueOf(forecast.loTemp), Color.WHITE, Color.BLACK, 2);
|
||||||
|
|
||||||
|
g2d.setFont(smallFont.deriveFont(24F));
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET + (131 * i) + 20, RenderConstants.TOPBAR_HEIGHT + 270, "Hi", Color.RED, Color.BLACK, 2);
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET + (131 * i) + 82, RenderConstants.TOPBAR_HEIGHT + 270, "Lo", Color.CYAN, Color.BLACK, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ValueCheck.valueNoData(forecast.percipPercent))
|
||||||
|
{
|
||||||
|
String formattedPercent = String.format("%.2f%%", forecast.percipPercent);
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET + (131 * i) + (127 / 2) - (g2d.getFontMetrics().stringWidth("Precip.") / 2), RenderConstants.TOPBAR_HEIGHT + 230, "Precip.", Color.YELLOW, Color.BLACK, 2);
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, RenderConstants.SIDE_OFFSET + (131 * i) + (127 / 2) - (g2d.getFontMetrics().stringWidth(formattedPercent) / 2), RenderConstants.TOPBAR_HEIGHT + 245, formattedPercent, Color.WHITE, Color.BLACK, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawBoundLimitedFlavour(RenderPanel renderer, Graphics2D g2d, Rectangle bounds, long ticks, int iconTicks) {
|
||||||
|
if (details != null && currentTown != null && currentTown.getDayForecast() != null && currentTown.getDayForecast().length > 0)
|
||||||
|
{
|
||||||
|
if(animationTicks < 0)
|
||||||
|
{
|
||||||
|
g2d.drawImage(lastBound, RenderConstants.SIDE_OFFSET-1, RenderConstants.TOPBAR_HEIGHT + 14, renderer);
|
||||||
|
drawIcons(g2d, currentTown, dayOffset, iconTicks);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g2d.translate(-animationTicks, 0);
|
||||||
|
g2d.drawImage(lastBound, RenderConstants.SIDE_OFFSET-1, RenderConstants.TOPBAR_HEIGHT + 14, renderer);
|
||||||
|
if(dayOffset == 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
drawIcons(g2d, previousTown, dayOffset + 4, iconTicks);
|
||||||
|
g2d.translate(RenderConstants.W - (RenderConstants.SIDE_OFFSET), 0);
|
||||||
|
drawIcons(g2d, currentTown, dayOffset, iconTicks);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
drawIcons(g2d, currentTown, dayOffset - 4, iconTicks);
|
||||||
|
g2d.translate(RenderConstants.W - (RenderConstants.SIDE_OFFSET), 0);
|
||||||
|
drawIcons(g2d, currentTown, dayOffset, iconTicks);
|
||||||
|
}
|
||||||
|
g2d.translate(animationTicks + (RenderConstants.SIDE_OFFSET) - RenderConstants.W, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawIcons(Graphics2D g2d, TownForecast currentTown, int dayOffset, int iconTicks){
|
||||||
|
|
||||||
|
for (int i = 0; i < Math.min(4, currentTown.getDayForecast().length - dayOffset); i++)
|
||||||
|
{
|
||||||
|
DayForecast forecast = currentTown.getDayForecast()[i + dayOffset];
|
||||||
|
IconProvider.drawIcon(g2d, IconProvider.INDEXED_ICONS[forecast.iconId & IconProvider.INDEXED_ICONS.length - 1], RenderConstants.SIDE_OFFSET + (131 * i) + 24, RenderConstants.TOPBAR_HEIGHT + 60, 80, iconTicks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void redrawRegionlost(RenderPanel renderer) {
|
||||||
|
if(animationTicks >= 0)
|
||||||
|
renderer.addRedrawBound(0, RenderConstants.TOPBAR_HEIGHT, RenderConstants.W, RenderConstants.MAINBAR_HEIGHT);
|
||||||
|
else
|
||||||
|
renderer.addRedrawBound(RenderConstants.SIDE_OFFSET + 24, RenderConstants.TOPBAR_HEIGHT + 60, 604, 84);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.flavour;
|
||||||
|
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Rectangle;
|
||||||
|
|
||||||
|
import com.flaremicro.flaretv.visualforecast.RenderPanel;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.forecast.ForecastDetails;
|
||||||
|
|
||||||
|
public interface Flavour {
|
||||||
|
public void tick(RenderPanel renderer, long ticks, int iconTicks);
|
||||||
|
public void initFlavour(RenderPanel renderer, ForecastDetails details, long ticks, int iconTicks);
|
||||||
|
public void drawFlavour(RenderPanel renderer, Graphics2D g, long ticks, int iconTicks);
|
||||||
|
public void drawBoundLimitedFlavour(RenderPanel renderer, Graphics2D g, Rectangle bounds, long ticks, int iconTicks);
|
||||||
|
public void redrawRegionlost(RenderPanel renderer);
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.flavour;
|
||||||
|
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Rectangle;
|
||||||
|
|
||||||
|
import com.flaremicro.flaretv.visualforecast.RenderPanel;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.forecast.ForecastDetails;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.graphics.DrawingUtil;
|
||||||
|
|
||||||
|
import static com.flaremicro.flaretv.visualforecast.graphics.RenderConstants.*;
|
||||||
|
|
||||||
|
public class TextFlavour implements Flavour{
|
||||||
|
|
||||||
|
public TextFlavour(String title, String scrollText)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
int w2 = g2d.getFontMetrics().stringWidth("EXTREME WEATHER ADVISORY");
|
||||||
|
drawOutlinedString(g2d, (W >> 1) - (w2 >> 1), TOPBAR_HEIGHT + 48, "EXTREME WEATHER ADVISORY", Color.RED, Color.BLACK, 2);
|
||||||
|
|
||||||
|
g2d.setFont(font.deriveFont(30F));
|
||||||
|
for (int i = 0; i < testString.length; i++)
|
||||||
|
{
|
||||||
|
drawOutlinedString(g2d, 90, TOPBAR_HEIGHT + 78 + 25 * i, testString[i], Color.WHITE, Color.BLACK, 1);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick(RenderPanel renderer, long ticks, int iconTicks) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initFlavour(RenderPanel renderer, ForecastDetails details, long ticks, int iconTicks) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawFlavour(RenderPanel renderer, Graphics2D g2d, long ticks, int iconTicks) {
|
||||||
|
DrawingUtil.drawGradientRect(g2d, 60, TOPBAR_HEIGHT, W - 120, MAINBAR_HEIGHT, 20, BG_BLUE.brighter(), BG_BLUE.darker());
|
||||||
|
g2d.setColor(BG_BLUE.brighter());
|
||||||
|
g2d.drawRect(60 + STROKE_OFFSET, TOPBAR_HEIGHT + STROKE_OFFSET, W - 120 - STROKE_WIDTH, MAINBAR_HEIGHT - STROKE_WIDTH);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawBoundLimitedFlavour(RenderPanel renderer, Graphics2D g2d, Rectangle bounds, long ticks, int iconTicks) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void redrawRegionlost(RenderPanel renderer) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.forecast;
|
||||||
|
|
||||||
|
public class DayForecast {
|
||||||
|
public byte hiTemp;
|
||||||
|
public byte loTemp;
|
||||||
|
public byte iconId;
|
||||||
|
public String weatherLine1;
|
||||||
|
public String weatherLine2;
|
||||||
|
public float percipPercent;
|
||||||
|
|
||||||
|
public DayForecast(byte hiTemp, byte loTemp, byte iconId, String weatherLine1, String weatherLine2, float percipPercent){
|
||||||
|
this.hiTemp = hiTemp;
|
||||||
|
this.loTemp = loTemp;
|
||||||
|
this.iconId = (byte)(iconId & 63);
|
||||||
|
this.weatherLine1 = weatherLine1;
|
||||||
|
this.weatherLine2 = weatherLine2;
|
||||||
|
this.percipPercent = percipPercent;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.forecast;
|
||||||
|
|
||||||
|
public class ForecastDetails {
|
||||||
|
//Perhaps could be hashmap?
|
||||||
|
private TownForecast[] towns;
|
||||||
|
|
||||||
|
public ForecastDetails(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setTownForecast(TownForecast[] towns){
|
||||||
|
this.towns = towns;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TownForecast[] getTownForecast()
|
||||||
|
{
|
||||||
|
return towns;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.forecast;
|
||||||
|
|
||||||
|
public class TownForecast {
|
||||||
|
public TownForecast(String townName, DayForecast[] dayForecast){
|
||||||
|
this.townName = townName;
|
||||||
|
this.dayForecast = dayForecast;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String townName;
|
||||||
|
private final DayForecast[] dayForecast;
|
||||||
|
|
||||||
|
public DayForecast[] getDayForecast() {
|
||||||
|
return dayForecast;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTownName() {
|
||||||
|
return townName;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.forecast;
|
||||||
|
|
||||||
|
public class ValueCheck {
|
||||||
|
//Utility for no data
|
||||||
|
public static final byte NO_DATA_BYTE = Byte.MIN_VALUE;
|
||||||
|
public static final short NO_DATA_SHORT = Short.MIN_VALUE;
|
||||||
|
public static final int NO_DATA_INT = Integer.MIN_VALUE;
|
||||||
|
public static final long NO_DATA_LONG = Long.MIN_VALUE;
|
||||||
|
public static final float NO_DATA_FLOAT = Float.NaN;
|
||||||
|
public static final double NO_DATA_DOUBLE = Double.NaN;
|
||||||
|
|
||||||
|
public static final boolean valueNoData(byte f)
|
||||||
|
{
|
||||||
|
return f == NO_DATA_BYTE;
|
||||||
|
}
|
||||||
|
public static final boolean valueNoData(short f)
|
||||||
|
{
|
||||||
|
return f == NO_DATA_SHORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final boolean valueNoData(int f)
|
||||||
|
{
|
||||||
|
return f == NO_DATA_INT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final boolean valueNoData(long f)
|
||||||
|
{
|
||||||
|
return f == NO_DATA_LONG;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final boolean valueNoData(float f)
|
||||||
|
{
|
||||||
|
return Float.isInfinite(f) || Float.isNaN(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final boolean valueNoData(double d)
|
||||||
|
{
|
||||||
|
return Double.isInfinite(d) || Double.isNaN(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final boolean valueNoData(Object o)
|
||||||
|
{
|
||||||
|
return o == null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.graphics;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.GradientPaint;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Polygon;
|
||||||
|
|
||||||
|
public class DrawingUtil {
|
||||||
|
public static void drawGradientRect(Graphics2D g, int x, int y, int w, int h, int borderWidth, Color innerColor, Color outerColor) {
|
||||||
|
|
||||||
|
g.setColor(innerColor);
|
||||||
|
g.fillRect(x, y, w, h);
|
||||||
|
|
||||||
|
g.setPaint(new GradientPaint(x, 0, outerColor, x + borderWidth, 0, innerColor));
|
||||||
|
g.fillRect(x, y, borderWidth, h);
|
||||||
|
|
||||||
|
g.setPaint(new GradientPaint(x + w - borderWidth, 0, innerColor, x + w, 0, outerColor));
|
||||||
|
g.fillRect(x + w - borderWidth, y, borderWidth, h);
|
||||||
|
|
||||||
|
g.setPaint(new GradientPaint(0, y, outerColor, 0, y + borderWidth, innerColor));
|
||||||
|
g.setClip(new Polygon(new int[] { x, x + w, x + w - borderWidth, x + borderWidth }, new int[] { y, y, y + borderWidth, y + borderWidth }, 4));
|
||||||
|
g.fillRect(x, y, w, borderWidth);
|
||||||
|
|
||||||
|
g.setClip(new Polygon(new int[] { x, x + w, x + w - borderWidth, x + borderWidth }, new int[] { y + h, y + h, y + h - borderWidth, y + h - borderWidth }, 4));
|
||||||
|
g.setPaint(new GradientPaint(0, y + h - borderWidth, innerColor, 0, y + h, outerColor));
|
||||||
|
g.fillRect(x, y + h - borderWidth, w, borderWidth);
|
||||||
|
|
||||||
|
g.setClip(null);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void drawOutlinedString(Graphics2D g2d, int x, int y, String text, Color textColor, Color outline, int outlineSize) {
|
||||||
|
g2d.setColor(outline);
|
||||||
|
for (int i = 1; i <= outlineSize; i++)
|
||||||
|
{
|
||||||
|
g2d.drawString(text, x + i, y);
|
||||||
|
g2d.drawString(text, x - i, y);
|
||||||
|
g2d.drawString(text, x, y + i);
|
||||||
|
g2d.drawString(text, x, y - i);
|
||||||
|
g2d.drawString(text, x + i, y + i);
|
||||||
|
g2d.drawString(text, x - i, y - i);
|
||||||
|
g2d.drawString(text, x - i, y + i);
|
||||||
|
g2d.drawString(text, x + i, y - i);
|
||||||
|
}
|
||||||
|
|
||||||
|
g2d.setColor(textColor);
|
||||||
|
g2d.drawString(text, x, y);
|
||||||
|
/*
|
||||||
|
* AffineTransform transform = g2d.getTransform();
|
||||||
|
* transform.translate(x, y); g2d.transform(transform);
|
||||||
|
* g2d.setColor(outline); FontRenderContext frc =
|
||||||
|
* g2d.getFontRenderContext(); TextLayout tl = new TextLayout(text,
|
||||||
|
* g2d.getFont(), frc); Shape shape = tl.getOutline(null);
|
||||||
|
* g2d.setStroke(new BasicStroke(outlineSize)); g2d.draw(shape);
|
||||||
|
* g2d.setColor(textColor); g2d.fill(shape);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void drawOutlinedString(Graphics2D g2d, int x, int y, String text, Color textColor, Color outline, int outlineSize, float outlineStep) {
|
||||||
|
g2d.setColor(outline);
|
||||||
|
for (int i = 1; i <= outlineSize; i++)
|
||||||
|
{
|
||||||
|
g2d.drawString(text, x + i*outlineStep, y);
|
||||||
|
g2d.drawString(text, x - i*outlineStep, y);
|
||||||
|
g2d.drawString(text, x, y + i*outlineStep);
|
||||||
|
g2d.drawString(text, x, y - i*outlineStep);
|
||||||
|
g2d.drawString(text, x + i*outlineStep, y + i*outlineStep);
|
||||||
|
g2d.drawString(text, x - i*outlineStep, y - i*outlineStep);
|
||||||
|
g2d.drawString(text, x - i*outlineStep, y + i*outlineStep);
|
||||||
|
g2d.drawString(text, x + i*outlineStep, y - i*outlineStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
g2d.setColor(textColor);
|
||||||
|
g2d.drawString(text, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.graphics;
|
||||||
|
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.FontFormatException;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class FontManager {
|
||||||
|
private final Font baseFont;
|
||||||
|
private static FontManager instance = null;
|
||||||
|
|
||||||
|
private Map<URL, Integer> urlToFontMapping = new HashMap<URL, Integer>();
|
||||||
|
private List<Font> fonts = new ArrayList<Font>();
|
||||||
|
|
||||||
|
private FontManager() {
|
||||||
|
BufferedImage bufferedImage = new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_BINARY);
|
||||||
|
Graphics g = bufferedImage.createGraphics();
|
||||||
|
baseFont = g.getFont();
|
||||||
|
g.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FontManager getInstance() {
|
||||||
|
if (instance == null)
|
||||||
|
{
|
||||||
|
instance = new FontManager();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Font getFont(int fontId){
|
||||||
|
if(fontId < 0 || fontId >= fonts.size())
|
||||||
|
return baseFont;
|
||||||
|
else return fonts.get(fontId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Font getFont(URL fontResource){
|
||||||
|
Integer i = urlToFontMapping.get(fontResource);
|
||||||
|
if(i == null)
|
||||||
|
return baseFont;
|
||||||
|
else return fonts.get(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFontID(URL fontResource){
|
||||||
|
Integer i = urlToFontMapping.get(fontResource);
|
||||||
|
if(i == null)
|
||||||
|
return -1;
|
||||||
|
else return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Font getOrCreateFont(int fontFormat, URL fontResource)
|
||||||
|
{
|
||||||
|
if(fontResource == null)
|
||||||
|
return baseFont.deriveFont(Font.PLAIN);
|
||||||
|
int i = getOrPrepareFont(fontFormat, fontResource);
|
||||||
|
return fonts.get(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOrPrepareFont(int fontFormat, URL fontResource)
|
||||||
|
{
|
||||||
|
Integer i = urlToFontMapping.get(fontResource);
|
||||||
|
if(i == null)
|
||||||
|
{
|
||||||
|
Font f = baseFont.deriveFont(Font.PLAIN);
|
||||||
|
if(fontResource == null)
|
||||||
|
return -1;
|
||||||
|
InputStream stream = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
stream = fontResource.openStream();
|
||||||
|
f = Font.createFont(fontFormat, stream);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
catch (FontFormatException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally{
|
||||||
|
if(stream != null)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
stream.close();
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
synchronized(fonts)
|
||||||
|
{
|
||||||
|
i = fonts.size();
|
||||||
|
fonts.add(f);
|
||||||
|
urlToFontMapping.put(fontResource, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.graphics;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
|
||||||
|
public class RenderConstants {
|
||||||
|
public static final int W = 640, H = 480;
|
||||||
|
public static final int INFOBAR_HEIGHT = 80;
|
||||||
|
public static final int TOPBAR_HEIGHT = 80;
|
||||||
|
public static final int MAINBAR_HEIGHT = H - INFOBAR_HEIGHT - TOPBAR_HEIGHT;
|
||||||
|
|
||||||
|
public static final int HEADERBAR_Y = 20;
|
||||||
|
public static final double HEADERBAR_SHEAR = 0.2;
|
||||||
|
public static final int HEADERBAR_OFFSET = 20;
|
||||||
|
public static final int HEADERBAR_WIDTH = 400 + HEADERBAR_OFFSET;
|
||||||
|
public static final int HEADERBAR_HEIGHT = TOPBAR_HEIGHT - HEADERBAR_Y;
|
||||||
|
|
||||||
|
public static final int TIMEBAR_Y = 40;
|
||||||
|
public static final int TIMEBAR_OFFSET = 20;
|
||||||
|
public static final int TIMEBAR_WIDTH = 230 + HEADERBAR_OFFSET;
|
||||||
|
public static final int TIMEBAR_HEIGHT = TOPBAR_HEIGHT - TIMEBAR_Y;
|
||||||
|
|
||||||
|
public static final int STROKE_WIDTH = 2;
|
||||||
|
public static final int STROKE_OFFSET = STROKE_WIDTH / 2;
|
||||||
|
|
||||||
|
public static final int SIDE_OFFSET = 60;
|
||||||
|
|
||||||
|
public static final DateFormat DATE_FORMAT = new SimpleDateFormat("MMMM d");
|
||||||
|
public static final DateFormat TIME_FORMAT = new SimpleDateFormat("hh:mm:ss a");
|
||||||
|
|
||||||
|
|
||||||
|
public static final Color BG_PURPLE = new Color(0x2b29b3);
|
||||||
|
public static final Color BG_OORANGE = new Color(0xff8c00);
|
||||||
|
public static final Color BG_BLUE = new Color(0x394aa8);
|
||||||
|
}
|
||||||
@@ -2,6 +2,13 @@ package com.flaremicro.flaretv.visualforecast.icons;
|
|||||||
|
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
|
||||||
public interface Icon {
|
public abstract class Icon {
|
||||||
public void drawIcon(Graphics2D g2d, float scale, int animationStep);
|
|
||||||
|
public Icon(int i){
|
||||||
|
this.id = (byte)i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final byte id;
|
||||||
|
public abstract boolean isAnimated();
|
||||||
|
public abstract void drawIcon(Graphics2D g2d, float scale, int animationStep);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,39 +3,79 @@ package com.flaremicro.flaretv.visualforecast.icons;
|
|||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.geom.AffineTransform;
|
import java.awt.geom.AffineTransform;
|
||||||
|
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.impl.BlizzardIcon;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.impl.ButterIcon;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.impl.CloudIcon;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.impl.FogIcon;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.impl.IceCubeIcon;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.impl.InvalidIcon;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.impl.LightningIcon;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.impl.LightningOverlay;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.impl.LightningStormIcon;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.impl.PartlyCloudyIcon;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.impl.RainIcon;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.impl.RainSnowIcon;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.impl.SmallCloudIcon;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.impl.SnowIcon;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.impl.SnowflakeIcon;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.impl.SunIcon;
|
||||||
|
|
||||||
public class IconProvider {
|
public class IconProvider {
|
||||||
|
|
||||||
public static int SUN = 0;
|
public static final Icon[] INDEXED_ICONS = new Icon[64];
|
||||||
public static int CLOUD = 1;
|
|
||||||
public static int PARTLY_CLOUDY = 2;
|
|
||||||
public static int CLOUDY_CLOUDY = 3;
|
|
||||||
public static int RAIN = 4;
|
|
||||||
public static int SCATTERD_SHOWERS = 5;
|
|
||||||
public static int SNOWFLAKE = 6;
|
|
||||||
|
|
||||||
|
public static final Icon INVALID = registerIcon(setMainIcon(new InvalidIcon(0)));
|
||||||
|
public static final Icon SUN = registerIcon(new SunIcon(1));
|
||||||
|
public static final Icon CLOUD = registerIcon(new CloudIcon(2));
|
||||||
|
public static final Icon PARTLY_CLOUDY = registerIcon(new PartlyCloudyIcon(3, CLOUD, SUN));
|
||||||
|
public static final Icon CLOUDY_CLOUDY = registerIcon(new PartlyCloudyIcon(4, CLOUD, CLOUD));
|
||||||
|
public static final Icon RAIN_LIGHTEST = registerIcon(new RainIcon(5, 2, 2F, CLOUD));
|
||||||
|
public static final Icon RAIN_LIGHT = registerIcon(new RainIcon(6, 3, 2F, CLOUD));
|
||||||
|
public static final Icon RAIN = registerIcon(new RainIcon(7, 3, 1F, CLOUD));
|
||||||
|
public static final Icon RAIN_HEAVY = registerIcon(new RainIcon(8, 4, 1F, CLOUD));
|
||||||
|
public static final Icon RAIN_HEAVIEST = registerIcon(new RainIcon(9, 5, 1F, CLOUD));
|
||||||
|
public static final Icon RAIN_VANCOUVER = registerIcon(new RainIcon(10, 6, 1F, CLOUD));
|
||||||
|
public static final Icon SCATTERD_SHOWERS = registerIcon(new PartlyCloudyIcon(11, new RainIcon(-1, 2, 4F, CLOUD), SUN));
|
||||||
|
public static final Icon SNOWFLAKE = registerIcon(new SnowflakeIcon(12));
|
||||||
|
public static final Icon SNOW = registerIcon(new SnowIcon(13, CLOUD, SNOWFLAKE));
|
||||||
|
public static final Icon BLIZZARD = registerIcon(new BlizzardIcon(14, CLOUD, SNOWFLAKE));
|
||||||
|
public static final Icon RAIN_SNOW = registerIcon(new RainSnowIcon(15, RAIN_LIGHTEST, SNOWFLAKE, true));
|
||||||
|
public static final Icon FREEZING_RAIN = registerIcon(new RainSnowIcon(16, RAIN_LIGHT, SNOWFLAKE, false));
|
||||||
|
public static final Icon LIGHTNING_BOLT = registerIcon(new LightningIcon(17));
|
||||||
|
public static final Icon LIGHTNING_STORM = registerIcon(new LightningStormIcon(18, CLOUD, LIGHTNING_BOLT));
|
||||||
|
public static final Icon SMALL_CLOUD = registerIcon(new SmallCloudIcon(19));
|
||||||
|
public static final Icon LIGHTNING_BLIZZARD = registerIcon(new LightningOverlay(20, SMALL_CLOUD, LIGHTNING_BOLT, BLIZZARD));
|
||||||
|
public static final Icon SCATTERD_THUNDERSTORMS = registerIcon(new PartlyCloudyIcon(21, LIGHTNING_STORM, SUN));
|
||||||
|
public static final Icon FOG = registerIcon(new FogIcon(22, CLOUD));
|
||||||
|
public static final Icon ICE_CUBE = registerIcon(new IceCubeIcon(23));
|
||||||
|
public static final Icon HAIL = registerIcon(new BlizzardIcon(24, CLOUD, ICE_CUBE));
|
||||||
|
public static final Icon BUTTER = registerIcon(new ButterIcon(25));
|
||||||
|
public static final Icon BUTTER_RAIN = registerIcon(new BlizzardIcon(26, CLOUD, BUTTER));
|
||||||
|
//public static final Icon INVALID_RAIN = registerIcon(new LightningOverlay(27, SUN, BUTTER, new BlizzardIcon(-1, LIGHTNING_BOLT, INVALID)));
|
||||||
|
|
||||||
private static final Icon[] CLASS_DEFS = new Icon[64];
|
private static Icon registerIcon(Icon icon)
|
||||||
|
{
|
||||||
static{
|
INDEXED_ICONS[icon.id] = icon;
|
||||||
CLASS_DEFS[SUN] = new SunIcon();
|
return icon;
|
||||||
CLASS_DEFS[CLOUD] = new CloudIcon();
|
|
||||||
CLASS_DEFS[PARTLY_CLOUDY] = new PartlyCloudyIcon(CLASS_DEFS[CLOUD], CLASS_DEFS[SUN]);
|
|
||||||
CLASS_DEFS[CLOUDY_CLOUDY] = new PartlyCloudyIcon(CLASS_DEFS[CLOUD], CLASS_DEFS[CLOUD]);
|
|
||||||
CLASS_DEFS[RAIN] = new RainIcon(2, 1F, CLASS_DEFS[CLOUD]);
|
|
||||||
CLASS_DEFS[SCATTERD_SHOWERS] = new PartlyCloudyIcon(new RainIcon(2, 4F, CLASS_DEFS[CLOUD]), CLASS_DEFS[SUN]);
|
|
||||||
CLASS_DEFS[SNOWFLAKE] = new SnowflakeIcon();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void drawIcon(Graphics2D g2d, int icon, int x, int y, int scale, int animationStep)
|
private static Icon setMainIcon(Icon icon) {
|
||||||
|
for(int i = 0; i < INDEXED_ICONS.length; i++){
|
||||||
|
INDEXED_ICONS[i] = icon;
|
||||||
|
}
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void drawIcon(Graphics2D g2d, Icon icon, int x, int y, int scale, int animationStep)
|
||||||
{
|
{
|
||||||
if(icon >= 0 && CLASS_DEFS.length > icon)
|
if(icon != null)
|
||||||
{
|
{
|
||||||
AffineTransform af = g2d.getTransform();
|
AffineTransform af = g2d.getTransform();
|
||||||
g2d.translate(x, y);
|
g2d.translate(x, y);
|
||||||
g2d.scale(scale, scale);
|
g2d.scale(scale, scale);
|
||||||
//1g2d.setColor(Color.RED);
|
//1g2d.setColor(Color.RED);
|
||||||
//g2d.fill(new Rectangle2D.Float(0, 0, 1F, 1F));
|
//g2d.fill(new Rectangle2D.Float(0, 0, 1F, 1F));
|
||||||
CLASS_DEFS[icon].drawIcon(g2d, scale, animationStep);
|
icon.drawIcon(g2d, scale, animationStep);
|
||||||
g2d.setTransform(af);
|
g2d.setTransform(af);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.icons.impl;
|
||||||
|
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.geom.AffineTransform;
|
||||||
|
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.Icon;
|
||||||
|
|
||||||
|
public class BlizzardIcon extends Icon {
|
||||||
|
private final Icon cloudIcon;
|
||||||
|
private final Icon snowflakeIcon;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public BlizzardIcon(int id, Icon cloudIcon, Icon snowflakeIcon)
|
||||||
|
{
|
||||||
|
super(id);
|
||||||
|
this.cloudIcon = cloudIcon;
|
||||||
|
this.snowflakeIcon = snowflakeIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawIcon(Graphics2D g2d, float scale, int animationStep) {
|
||||||
|
AffineTransform af = g2d.getTransform();
|
||||||
|
g2d.scale(0.25F, 0.25F);
|
||||||
|
g2d.translate(0, 3);
|
||||||
|
snowflakeIcon.drawIcon(g2d, scale*0.25F, animationStep);
|
||||||
|
g2d.translate(1, -1);
|
||||||
|
snowflakeIcon.drawIcon(g2d, scale*0.25F, animationStep+1);
|
||||||
|
g2d.translate(1, 1);
|
||||||
|
snowflakeIcon.drawIcon(g2d, scale*0.25F, animationStep+2);
|
||||||
|
g2d.translate(1, -1);
|
||||||
|
snowflakeIcon.drawIcon(g2d, scale*0.25F, animationStep+3);
|
||||||
|
g2d.setTransform(af);
|
||||||
|
g2d.translate(0F, -0.10F);
|
||||||
|
g2d.scale(1F, 0.8F);
|
||||||
|
cloudIcon.drawIcon(g2d, scale, animationStep);
|
||||||
|
g2d.setTransform(af);
|
||||||
|
g2d.translate(0.3F, 0);
|
||||||
|
g2d.scale(0.7F, 0.7F);
|
||||||
|
snowflakeIcon.drawIcon(g2d, scale*0.7F, animationStep+4);
|
||||||
|
g2d.setTransform(af);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnimated() {
|
||||||
|
return cloudIcon.isAnimated() || snowflakeIcon.isAnimated();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.icons.impl;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.geom.Path2D;
|
||||||
|
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.Icon;
|
||||||
|
|
||||||
|
public class ButterIcon extends Icon {
|
||||||
|
|
||||||
|
Path2D.Float iceOutline = new Path2D.Float();
|
||||||
|
|
||||||
|
Path2D.Float[] iceFaces = new Path2D.Float[3];
|
||||||
|
Path2D.Float[] iceShines = new Path2D.Float[3];
|
||||||
|
|
||||||
|
Color[] iceFaceColors = new Color[] {
|
||||||
|
new Color(0xfff8a0),
|
||||||
|
new Color(0xfff14c),
|
||||||
|
new Color(0xccbc00),
|
||||||
|
};
|
||||||
|
Color[] iceShineAnimation = new Color[] {
|
||||||
|
new Color(0xFFFFFF),
|
||||||
|
};
|
||||||
|
|
||||||
|
public ButterIcon(int id) {
|
||||||
|
super(id);
|
||||||
|
|
||||||
|
iceOutline.moveTo(0F, 0.161F);
|
||||||
|
iceOutline.lineTo(0.542F, 0F);
|
||||||
|
iceOutline.lineTo(1.0F, 0.093F);
|
||||||
|
iceOutline.lineTo(1.0F, 0.441F);
|
||||||
|
iceOutline.lineTo(0.489F, 0.650F);
|
||||||
|
iceOutline.lineTo(0.0F, 0.531F);
|
||||||
|
iceOutline.closePath();
|
||||||
|
|
||||||
|
iceFaces[1] = new Path2D.Float();
|
||||||
|
iceFaces[1].moveTo(0F, 0.161F);
|
||||||
|
iceFaces[1].lineTo(0.542F, 0F);
|
||||||
|
iceFaces[1].lineTo(1.0F, 0.093F);
|
||||||
|
iceFaces[1].lineTo(0.489F, 0.263F);
|
||||||
|
iceFaces[1].closePath();
|
||||||
|
|
||||||
|
iceFaces[2] = new Path2D.Float();
|
||||||
|
iceFaces[2].moveTo(0.489F, 0.263F);
|
||||||
|
iceFaces[2].lineTo(1.0F, 0.093F);
|
||||||
|
iceFaces[2].lineTo(1.0F, 0.441F);
|
||||||
|
iceFaces[2].lineTo(0.489F, 0.650F);
|
||||||
|
iceFaces[2].closePath();
|
||||||
|
|
||||||
|
iceFaces[0] = new Path2D.Float();
|
||||||
|
iceFaces[0].moveTo(0.0F, 0.161F);
|
||||||
|
iceFaces[0].lineTo(0.489F, 0.263F);
|
||||||
|
iceFaces[0].lineTo(0.489F, 0.650F);
|
||||||
|
iceFaces[0].lineTo(0.0F, 0.531F);
|
||||||
|
iceFaces[0].closePath();
|
||||||
|
|
||||||
|
iceShines[1] = new Path2D.Float();
|
||||||
|
iceShines[1].moveTo(0.537F, 0.013F);
|
||||||
|
iceShines[1].lineTo(0.930F, 0.099F);
|
||||||
|
iceShines[1].lineTo(0.673F, 0.185F);
|
||||||
|
iceShines[1].lineTo(0.556F, 0.187F);
|
||||||
|
iceShines[1].lineTo(0.556F, 0.187F);
|
||||||
|
iceShines[1].lineTo(0.742F, 0.086);
|
||||||
|
iceShines[1].closePath();
|
||||||
|
|
||||||
|
iceShines[2] = new Path2D.Float();
|
||||||
|
iceShines[2].moveTo(0.981F, 0.134F);
|
||||||
|
iceShines[2].lineTo(0.981F, 0.423F);
|
||||||
|
iceShines[2].lineTo(0.515F, 0.624F);
|
||||||
|
iceShines[2].lineTo(0.571F, 0.557F);
|
||||||
|
iceShines[2].lineTo(0.915F, 0.372F);
|
||||||
|
iceShines[2].closePath();
|
||||||
|
|
||||||
|
iceShines[0] = new Path2D.Float();
|
||||||
|
iceShines[0].moveTo(0.018F, 0.187F);
|
||||||
|
iceShines[0].lineTo(0.205F, 0.229F);
|
||||||
|
iceShines[0].lineTo(0.060F, 0.249F);
|
||||||
|
iceShines[0].lineTo(0.044F, 0.475F);
|
||||||
|
iceShines[0].lineTo(0.021F, 0.508F);
|
||||||
|
iceShines[0].closePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawIcon(Graphics2D g2d, float scale, int animationStep) {
|
||||||
|
g2d.setColor(Color.BLACK);
|
||||||
|
g2d.setStroke(new BasicStroke(4 / scale));
|
||||||
|
g2d.translate(0F, 0.325F);
|
||||||
|
g2d.setColor(Color.BLACK);
|
||||||
|
g2d.draw(iceOutline);
|
||||||
|
for(int i = 0; i < iceFaces.length; i++)
|
||||||
|
{
|
||||||
|
g2d.setColor(iceFaceColors[i]);
|
||||||
|
g2d.fill(iceFaces[i]);
|
||||||
|
g2d.setColor(iceShineAnimation[(i+animationStep) % iceShineAnimation.length]);
|
||||||
|
g2d.fill(iceShines[i]);
|
||||||
|
}
|
||||||
|
g2d.translate(0F, -0.325F);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnimated() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
package com.flaremicro.flaretv.visualforecast.icons;
|
package com.flaremicro.flaretv.visualforecast.icons.impl;
|
||||||
|
|
||||||
import java.awt.BasicStroke;
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.geom.Ellipse2D;
|
import java.awt.geom.Ellipse2D;
|
||||||
|
|
||||||
public class CloudIcon implements Icon {
|
import com.flaremicro.flaretv.visualforecast.icons.Icon;
|
||||||
Ellipse2D.Float[] cloudCircles = new Ellipse2D.Float[]{
|
|
||||||
|
public class CloudIcon extends Icon {
|
||||||
|
private final Ellipse2D.Float[] cloudCircles = new Ellipse2D.Float[]{
|
||||||
new Ellipse2D.Float(0, 0.5F, 0.28F, 0.325F),
|
new Ellipse2D.Float(0, 0.5F, 0.28F, 0.325F),
|
||||||
new Ellipse2D.Float(0.142F, 0.619F, 0.287F, 0.231F),
|
new Ellipse2D.Float(0.142F, 0.619F, 0.287F, 0.231F),
|
||||||
new Ellipse2D.Float(0.666F, 0.597F, 0.208F, 0.234F),
|
new Ellipse2D.Float(0.666F, 0.597F, 0.208F, 0.234F),
|
||||||
@@ -18,21 +20,21 @@ public class CloudIcon implements Icon {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Ellipse2D.Float[] extraStroke = new Ellipse2D.Float[]{
|
private final Ellipse2D.Float[] extraStroke = new Ellipse2D.Float[]{
|
||||||
new Ellipse2D.Float(0.142F, 0.619F, 0.287F, 0.231F),
|
new Ellipse2D.Float(0.142F, 0.619F, 0.287F, 0.231F),
|
||||||
new Ellipse2D.Float(0.666F, 0.597F, 0.208F, 0.234F)
|
new Ellipse2D.Float(0.666F, 0.597F, 0.208F, 0.234F)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Ellipse2D.Float[] overStroke = new Ellipse2D.Float[]{
|
private final Ellipse2D.Float[] overStroke = new Ellipse2D.Float[]{
|
||||||
new Ellipse2D.Float(0.233F, 0.150F, 0.369F, 0.677F),
|
new Ellipse2D.Float(0.233F, 0.150F, 0.369F, 0.677F),
|
||||||
new Ellipse2D.Float(0.113F, 0.326F, 0.266F, 0.356F),
|
new Ellipse2D.Float(0.113F, 0.326F, 0.266F, 0.356F),
|
||||||
new Ellipse2D.Float(0.749F, 0.412F, 0.251F, 0.417F),
|
new Ellipse2D.Float(0.749F, 0.412F, 0.251F, 0.417F),
|
||||||
new Ellipse2D.Float(0.652F, 0.555F, 0.150F, 0.136F),
|
new Ellipse2D.Float(0.652F, 0.555F, 0.150F, 0.136F),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ellipse2D.Float[] lightCircles = new Ellipse2D.Float[]{
|
private final Ellipse2D.Float[] lightCircles = new Ellipse2D.Float[]{
|
||||||
new Ellipse2D.Float(0.309F, 0.173F, 0.209F, 0.235F),
|
new Ellipse2D.Float(0.309F, 0.173F, 0.209F, 0.235F),
|
||||||
new Ellipse2D.Float(0.554F, 0.276F, 0.204F, 0.314F),
|
new Ellipse2D.Float(0.554F, 0.276F, 0.204F, 0.314F),
|
||||||
new Ellipse2D.Float(0.770F, 0.440F, 0.204F, 0.235F),
|
new Ellipse2D.Float(0.770F, 0.440F, 0.204F, 0.235F),
|
||||||
@@ -40,7 +42,7 @@ public class CloudIcon implements Icon {
|
|||||||
new Ellipse2D.Float(0.259F, 0.460F, 0.314F, 0.235F),
|
new Ellipse2D.Float(0.259F, 0.460F, 0.314F, 0.235F),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ellipse2D.Float[] overLight = new Ellipse2D.Float[]{
|
private final Ellipse2D.Float[] overLight = new Ellipse2D.Float[]{
|
||||||
new Ellipse2D.Float(0.328F, 0.188F, 0.209F, 0.235F),
|
new Ellipse2D.Float(0.328F, 0.188F, 0.209F, 0.235F),
|
||||||
new Ellipse2D.Float(0.573F, 0.296F, 0.204F, 0.314F),
|
new Ellipse2D.Float(0.573F, 0.296F, 0.204F, 0.314F),
|
||||||
new Ellipse2D.Float(0.789F, 0.456F, 0.204F, 0.235F),
|
new Ellipse2D.Float(0.789F, 0.456F, 0.204F, 0.235F),
|
||||||
@@ -48,6 +50,10 @@ public class CloudIcon implements Icon {
|
|||||||
new Ellipse2D.Float(0.288F, 0.476F, 0.314F, 0.235F),
|
new Ellipse2D.Float(0.288F, 0.476F, 0.314F, 0.235F),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public CloudIcon(int id)
|
||||||
|
{
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawIcon(Graphics2D g2d, float scale, int animationStep) {
|
public void drawIcon(Graphics2D g2d, float scale, int animationStep) {
|
||||||
@@ -86,4 +92,10 @@ public class CloudIcon implements Icon {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnimated() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.icons.impl;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.geom.Path2D;
|
||||||
|
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.Icon;
|
||||||
|
|
||||||
|
public class FogIcon extends Icon {
|
||||||
|
private final Icon cloudIcon;
|
||||||
|
|
||||||
|
private Path2D fogPath = new Path2D.Float();
|
||||||
|
|
||||||
|
Color[] aniColor = {
|
||||||
|
new Color(0xC0C0C0),
|
||||||
|
new Color(0xC8C8C8),
|
||||||
|
new Color(0xD0D0D0),
|
||||||
|
new Color(0xD8D8D8),
|
||||||
|
new Color(0xD0D0D0),
|
||||||
|
new Color(0xC8C8C8),
|
||||||
|
new Color(0xC0C0C0),
|
||||||
|
new Color(0xB8B8B8),
|
||||||
|
new Color(0xB0B0B0),
|
||||||
|
new Color(0xA8A8A8),
|
||||||
|
new Color(0xB0B0B0),
|
||||||
|
new Color(0xB8B8B8),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
public FogIcon(int id, Icon cloudIcon)
|
||||||
|
{
|
||||||
|
super(id);
|
||||||
|
this.cloudIcon = cloudIcon;
|
||||||
|
fogPath.moveTo(0F, 0.1F);
|
||||||
|
fogPath.curveTo(0F, 0.1F, 0.25F, 0F, 0.5F, 0.1F);
|
||||||
|
fogPath.curveTo(0.5F, 0.1F, 0.75F, 0.2F, 1.0F, 0.1F);
|
||||||
|
fogPath.lineTo(1F, 0.2F);
|
||||||
|
fogPath.curveTo(1F, 0.2F, 0.75F, 0.3F, 0.5F, 0.2F);
|
||||||
|
fogPath.curveTo(0.5F, 0.2F, 0.25F, 0.1F, 0F, 0.2F);
|
||||||
|
fogPath.closePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawIcon(Graphics2D g2d, float scale, int animationStep) {
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
g2d.setStroke(new BasicStroke(4/scale));
|
||||||
|
g2d.translate(0, 0.4F + 0.2F*i);
|
||||||
|
g2d.setColor(Color.BLACK);
|
||||||
|
g2d.draw(fogPath);
|
||||||
|
g2d.setColor(aniColor[(animationStep + i) % aniColor.length]);
|
||||||
|
g2d.fill(fogPath);
|
||||||
|
g2d.translate(0, -0.4F - 0.2*i);
|
||||||
|
}
|
||||||
|
//Fog?
|
||||||
|
g2d.translate(0F, -0.10F);
|
||||||
|
g2d.scale(1F, 0.8F);
|
||||||
|
cloudIcon.drawIcon(g2d, scale, animationStep);
|
||||||
|
g2d.scale(1F, 1.25F);
|
||||||
|
g2d.translate(0F, 0.10F);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnimated() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.icons.impl;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.geom.Path2D;
|
||||||
|
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.Icon;
|
||||||
|
|
||||||
|
public class IceCubeIcon extends Icon {
|
||||||
|
|
||||||
|
Path2D.Float iceOutline = new Path2D.Float();
|
||||||
|
|
||||||
|
Path2D.Float[] iceFaces = new Path2D.Float[3];
|
||||||
|
Path2D.Float[] iceShines = new Path2D.Float[3];
|
||||||
|
|
||||||
|
Path2D.Float iceBeams = new Path2D.Float();
|
||||||
|
|
||||||
|
Color[] iceFaceColors = new Color[] {
|
||||||
|
new Color(0xb9dbff),
|
||||||
|
new Color(0x92b1ff),
|
||||||
|
new Color(0x3886ff),
|
||||||
|
};
|
||||||
|
Color[] iceShineAnimation = new Color[] {
|
||||||
|
new Color(0x92B1FF),
|
||||||
|
new Color(0xA2C1FF),
|
||||||
|
new Color(0xB2D1FF),
|
||||||
|
new Color(0xC2E1FF),
|
||||||
|
new Color(0xD2F1FF),
|
||||||
|
new Color(0xE2FFFF),
|
||||||
|
new Color(0xFFFFFF),
|
||||||
|
new Color(0xE2FFFF),
|
||||||
|
new Color(0xD2F1FF),
|
||||||
|
new Color(0xC2E1FF),
|
||||||
|
new Color(0xB2D1FF),
|
||||||
|
new Color(0xA2C1FF),
|
||||||
|
};
|
||||||
|
|
||||||
|
public IceCubeIcon(int id) {
|
||||||
|
super(id);
|
||||||
|
|
||||||
|
iceBeams.moveTo(0.15F, 0.35F);
|
||||||
|
iceBeams.lineTo(0.25F, 0.15F);
|
||||||
|
|
||||||
|
iceBeams.moveTo(0.60F, 0.2F);
|
||||||
|
iceBeams.lineTo(0.70F, 0F);
|
||||||
|
|
||||||
|
iceBeams.moveTo(0.9F, 0.25F);
|
||||||
|
iceBeams.lineTo(1.0F, 0.05F);
|
||||||
|
|
||||||
|
iceOutline.moveTo(0F, 0.161F);
|
||||||
|
iceOutline.lineTo(0.542F, 0F);
|
||||||
|
iceOutline.lineTo(1.0F, 0.093F);
|
||||||
|
iceOutline.lineTo(1.0F, 0.441F);
|
||||||
|
iceOutline.lineTo(0.489F, 0.650F);
|
||||||
|
iceOutline.lineTo(0.0F, 0.531F);
|
||||||
|
iceOutline.closePath();
|
||||||
|
|
||||||
|
iceFaces[1] = new Path2D.Float();
|
||||||
|
iceFaces[1].moveTo(0F, 0.161F);
|
||||||
|
iceFaces[1].lineTo(0.542F, 0F);
|
||||||
|
iceFaces[1].lineTo(1.0F, 0.093F);
|
||||||
|
iceFaces[1].lineTo(0.489F, 0.263F);
|
||||||
|
iceFaces[1].closePath();
|
||||||
|
|
||||||
|
iceFaces[2] = new Path2D.Float();
|
||||||
|
iceFaces[2].moveTo(0.489F, 0.263F);
|
||||||
|
iceFaces[2].lineTo(1.0F, 0.093F);
|
||||||
|
iceFaces[2].lineTo(1.0F, 0.441F);
|
||||||
|
iceFaces[2].lineTo(0.489F, 0.650F);
|
||||||
|
iceFaces[2].closePath();
|
||||||
|
|
||||||
|
iceFaces[0] = new Path2D.Float();
|
||||||
|
iceFaces[0].moveTo(0.0F, 0.161F);
|
||||||
|
iceFaces[0].lineTo(0.489F, 0.263F);
|
||||||
|
iceFaces[0].lineTo(0.489F, 0.650F);
|
||||||
|
iceFaces[0].lineTo(0.0F, 0.531F);
|
||||||
|
iceFaces[0].closePath();
|
||||||
|
|
||||||
|
iceShines[1] = new Path2D.Float();
|
||||||
|
iceShines[1].moveTo(0.537F, 0.013F);
|
||||||
|
iceShines[1].lineTo(0.930F, 0.099F);
|
||||||
|
iceShines[1].lineTo(0.673F, 0.185F);
|
||||||
|
iceShines[1].lineTo(0.556F, 0.187F);
|
||||||
|
iceShines[1].lineTo(0.556F, 0.187F);
|
||||||
|
iceShines[1].lineTo(0.742F, 0.086);
|
||||||
|
iceShines[1].closePath();
|
||||||
|
|
||||||
|
iceShines[2] = new Path2D.Float();
|
||||||
|
iceShines[2].moveTo(0.981F, 0.134F);
|
||||||
|
iceShines[2].lineTo(0.981F, 0.423F);
|
||||||
|
iceShines[2].lineTo(0.515F, 0.624F);
|
||||||
|
iceShines[2].lineTo(0.571F, 0.557F);
|
||||||
|
iceShines[2].lineTo(0.915F, 0.372F);
|
||||||
|
iceShines[2].closePath();
|
||||||
|
|
||||||
|
iceShines[0] = new Path2D.Float();
|
||||||
|
iceShines[0].moveTo(0.018F, 0.187F);
|
||||||
|
iceShines[0].lineTo(0.205F, 0.229F);
|
||||||
|
iceShines[0].lineTo(0.060F, 0.249F);
|
||||||
|
iceShines[0].lineTo(0.044F, 0.475F);
|
||||||
|
iceShines[0].lineTo(0.021F, 0.508F);
|
||||||
|
iceShines[0].closePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawIcon(Graphics2D g2d, float scale, int animationStep) {
|
||||||
|
g2d.setColor(Color.BLACK);
|
||||||
|
g2d.setStroke(new BasicStroke(2 / scale));
|
||||||
|
g2d.draw(iceBeams);
|
||||||
|
g2d.setStroke(new BasicStroke(4 / scale));
|
||||||
|
g2d.translate(0F, 0.325F);
|
||||||
|
g2d.draw(iceOutline);
|
||||||
|
for(int i = 0; i < iceFaces.length; i++)
|
||||||
|
{
|
||||||
|
g2d.setColor(iceFaceColors[i]);
|
||||||
|
g2d.fill(iceFaces[i]);
|
||||||
|
g2d.setColor(iceShineAnimation[(i+animationStep) % iceShineAnimation.length]);
|
||||||
|
g2d.fill(iceShines[i]);
|
||||||
|
}
|
||||||
|
g2d.translate(0F, -0.325F);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnimated() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.icons.impl;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.graphics.DrawingUtil;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.graphics.FontManager;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.Icon;
|
||||||
|
|
||||||
|
public class InvalidIcon extends Icon {
|
||||||
|
|
||||||
|
private Font fnt = FontManager.getInstance().getOrCreateFont(Font.TRUETYPE_FONT, this.getClass().getResource("/Star4000.ttf"));
|
||||||
|
|
||||||
|
public InvalidIcon(int i)
|
||||||
|
{
|
||||||
|
super(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawIcon(Graphics2D g2d, float scale, int animationStep) {
|
||||||
|
g2d.setFont(fnt.deriveFont(0.8F));
|
||||||
|
g2d.translate(0.2F, 0.8F);
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, 0, 0, "X", Color.YELLOW, Color.BLACK, 1, 2/scale);
|
||||||
|
g2d.translate(0.2F, 0F);
|
||||||
|
DrawingUtil.drawOutlinedString(g2d, 0, 0, "?", Color.RED, Color.BLACK, 1, 2/scale);
|
||||||
|
g2d.translate(-0.4F, -0.8F);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnimated() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.icons.impl;
|
||||||
|
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.Icon;
|
||||||
|
|
||||||
|
public class LightningCloudIcon extends Icon {
|
||||||
|
|
||||||
|
private final Icon boltIcon;
|
||||||
|
private final Icon smallCloudIcon;
|
||||||
|
|
||||||
|
public LightningCloudIcon(int id, Icon smallCloudIcon, Icon boltIcon) {
|
||||||
|
super(id);
|
||||||
|
this.smallCloudIcon = smallCloudIcon;
|
||||||
|
this.boltIcon = boltIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawIcon(Graphics2D g2d, float scale, int animationStep) {
|
||||||
|
g2d.scale(0.8F, 0.5F);
|
||||||
|
g2d.translate(0.0F, 0.8F);
|
||||||
|
boltIcon.drawIcon(g2d, scale/1.5F, animationStep);
|
||||||
|
g2d.translate(-0.0F, -0.8F);
|
||||||
|
g2d.scale(1.25F, 2);
|
||||||
|
|
||||||
|
g2d.scale(0.6F, 0.4F);
|
||||||
|
g2d.translate(0.3F, 0.5F);
|
||||||
|
smallCloudIcon.drawIcon(g2d, scale/2, animationStep);
|
||||||
|
g2d.translate(-0.3F, -0.5F);
|
||||||
|
g2d.scale(1.66666666667F, 2.5F);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnimated() {
|
||||||
|
return boltIcon.isAnimated() || smallCloudIcon.isAnimated();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.icons.impl;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.geom.Path2D;
|
||||||
|
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.Icon;
|
||||||
|
|
||||||
|
public class LightningIcon extends Icon {
|
||||||
|
Path2D.Float boltPath = new Path2D.Float();
|
||||||
|
Path2D.Float shinePath = new Path2D.Float();
|
||||||
|
|
||||||
|
Color[] shine = {
|
||||||
|
new Color(0xFFDD00),
|
||||||
|
new Color(0xFFFFFF),
|
||||||
|
new Color(0xFFFFFF),
|
||||||
|
new Color(0xFFEE88),
|
||||||
|
new Color(0xFFDD00),
|
||||||
|
new Color(0xFFFFFF),
|
||||||
|
new Color(0xFFFFFF),
|
||||||
|
new Color(0xFFEE88),
|
||||||
|
new Color(0xFFDD00),
|
||||||
|
new Color(0xFFDD00),
|
||||||
|
new Color(0xFFDD00),
|
||||||
|
};
|
||||||
|
|
||||||
|
Color[] bolt = {
|
||||||
|
new Color(0xFFFF00),
|
||||||
|
new Color(0xFFDD00),
|
||||||
|
new Color(0xFFDD00),
|
||||||
|
new Color(0xFFEE00),
|
||||||
|
new Color(0xFFFF00),
|
||||||
|
new Color(0xFFDD00),
|
||||||
|
new Color(0xFFDD00),
|
||||||
|
new Color(0xFFEE00),
|
||||||
|
new Color(0xFFFF00),
|
||||||
|
new Color(0xFFFF00),
|
||||||
|
new Color(0xFFFF00),
|
||||||
|
};
|
||||||
|
|
||||||
|
public LightningIcon(int id)
|
||||||
|
{
|
||||||
|
super(id);
|
||||||
|
boltPath.moveTo(0.380, 0);
|
||||||
|
boltPath.lineTo(0.680, 0);
|
||||||
|
boltPath.lineTo(0.577, 0.206);
|
||||||
|
boltPath.lineTo(0.750, 0.206);
|
||||||
|
boltPath.lineTo(0.545, 0.617);
|
||||||
|
boltPath.lineTo(0.678, 0.617);
|
||||||
|
boltPath.lineTo(0.330, 1);
|
||||||
|
boltPath.lineTo(0.453, 0.679);
|
||||||
|
boltPath.lineTo(0.333, 0.679);
|
||||||
|
boltPath.lineTo(0.461, 0.360);
|
||||||
|
boltPath.lineTo(0.250, 0.360);
|
||||||
|
boltPath.closePath();
|
||||||
|
|
||||||
|
shinePath.moveTo(0.417, 0.0);
|
||||||
|
shinePath.lineTo(0.518, 0);
|
||||||
|
shinePath.lineTo(0.413,0.260);
|
||||||
|
shinePath.lineTo(0.586,0.260);
|
||||||
|
shinePath.lineTo(0.417,0.631);
|
||||||
|
shinePath.lineTo(0.550,0.631);
|
||||||
|
shinePath.lineTo(0.349,0.970);
|
||||||
|
shinePath.lineTo(0.489,0.666);
|
||||||
|
shinePath.lineTo(0.369,0.666);
|
||||||
|
shinePath.lineTo(0.508,0.327);
|
||||||
|
shinePath.lineTo(0.297,0.327);
|
||||||
|
shinePath.closePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawIcon(Graphics2D g2d, float scale, int animationStep) {
|
||||||
|
g2d.setStroke(new BasicStroke(4/scale));
|
||||||
|
g2d.setColor(Color.BLACK);
|
||||||
|
g2d.draw(boltPath);
|
||||||
|
g2d.setColor(bolt[animationStep % bolt.length]);
|
||||||
|
g2d.fill(boltPath);
|
||||||
|
g2d.setColor(shine[animationStep % shine.length]);
|
||||||
|
g2d.fill(shinePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnimated() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.icons.impl;
|
||||||
|
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.Icon;
|
||||||
|
|
||||||
|
public class LightningOverlay extends Icon {
|
||||||
|
|
||||||
|
private final Icon boltIcon;
|
||||||
|
private final Icon smallCloudIcon;
|
||||||
|
private final Icon weatherIcon;
|
||||||
|
|
||||||
|
public LightningOverlay(int id, Icon smallCloudIcon, Icon boltIcon, Icon weatherIcon) {
|
||||||
|
super(id);
|
||||||
|
this.smallCloudIcon = smallCloudIcon;
|
||||||
|
this.boltIcon = boltIcon;
|
||||||
|
this.weatherIcon = weatherIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawIcon(Graphics2D g2d, float scale, int animationStep) {
|
||||||
|
weatherIcon.drawIcon(g2d, scale, animationStep);
|
||||||
|
|
||||||
|
g2d.scale(0.8F, 0.5F);
|
||||||
|
g2d.translate(0.3F, 0.8F);
|
||||||
|
boltIcon.drawIcon(g2d, scale/1.5F, animationStep);
|
||||||
|
g2d.translate(-0.3F, -0.8F);
|
||||||
|
g2d.scale(1.25F, 2);
|
||||||
|
|
||||||
|
g2d.scale(0.6F, 0.4F);
|
||||||
|
g2d.translate(0.6F, 0.5F);
|
||||||
|
smallCloudIcon.drawIcon(g2d, scale/2, animationStep);
|
||||||
|
g2d.translate(-0.6F, -0.5F);
|
||||||
|
g2d.scale(1.66666666667F, 2.5F);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnimated() {
|
||||||
|
return weatherIcon.isAnimated() || boltIcon.isAnimated() || smallCloudIcon.isAnimated();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.icons.impl;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.Icon;
|
||||||
|
|
||||||
|
public class LightningStormIcon extends Icon {
|
||||||
|
private final Icon boltIcon;
|
||||||
|
private final Icon cloudIcon;
|
||||||
|
|
||||||
|
|
||||||
|
public LightningStormIcon(int id, Icon cloudIcon, Icon boltIcon)
|
||||||
|
{
|
||||||
|
super(id);
|
||||||
|
this.cloudIcon = cloudIcon;
|
||||||
|
this.boltIcon = boltIcon;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawIcon(Graphics2D g2d, float scale, int animationStep) {
|
||||||
|
g2d.setStroke(new BasicStroke(4/scale));
|
||||||
|
g2d.translate(0F, 0.15F);
|
||||||
|
g2d.scale(0.8F, 0.8F);
|
||||||
|
boltIcon.drawIcon(g2d, scale, animationStep);
|
||||||
|
g2d.scale(1.25F, 1.25F);
|
||||||
|
g2d.translate(0F, -0.25F);
|
||||||
|
g2d.scale(1F, 0.8F);
|
||||||
|
cloudIcon.drawIcon(g2d, scale, animationStep);
|
||||||
|
g2d.scale(1F, 1.25F);
|
||||||
|
g2d.translate(0F, 0.10F);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnimated() {
|
||||||
|
return cloudIcon.isAnimated() || boltIcon.isAnimated();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
package com.flaremicro.flaretv.visualforecast.icons;
|
package com.flaremicro.flaretv.visualforecast.icons.impl;
|
||||||
|
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
|
||||||
public class PartlyCloudyIcon implements Icon {
|
import com.flaremicro.flaretv.visualforecast.icons.Icon;
|
||||||
|
|
||||||
|
public class PartlyCloudyIcon extends Icon {
|
||||||
private Icon cloud;
|
private Icon cloud;
|
||||||
private Icon sun;
|
private Icon sun;
|
||||||
|
|
||||||
public PartlyCloudyIcon(Icon cloud, Icon sun)
|
public PartlyCloudyIcon(int id, Icon cloud, Icon sun)
|
||||||
{
|
{
|
||||||
|
super(id);
|
||||||
this.cloud = cloud;
|
this.cloud = cloud;
|
||||||
this.sun = sun;
|
this.sun = sun;
|
||||||
}
|
}
|
||||||
@@ -25,4 +28,9 @@ public class PartlyCloudyIcon implements Icon {
|
|||||||
g2d.translate(0, -0.07F);
|
g2d.translate(0, -0.07F);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnimated() {
|
||||||
|
return sun.isAnimated() || cloud.isAnimated();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
package com.flaremicro.flaretv.visualforecast.icons;
|
package com.flaremicro.flaretv.visualforecast.icons.impl;
|
||||||
|
|
||||||
import java.awt.BasicStroke;
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
|
|
||||||
public class RainIcon implements Icon {
|
import com.flaremicro.flaretv.visualforecast.icons.Icon;
|
||||||
|
|
||||||
|
public class RainIcon extends Icon {
|
||||||
private final int rainCount;
|
private final int rainCount;
|
||||||
private final float rainSpace;
|
private final float rainSpace;
|
||||||
private final Icon cloudIcon;
|
private final Icon cloudIcon;
|
||||||
@@ -26,8 +28,9 @@ public class RainIcon implements Icon {
|
|||||||
new Color(0x0066FF),
|
new Color(0x0066FF),
|
||||||
};
|
};
|
||||||
|
|
||||||
public RainIcon(int rainCount, float rainSpace, Icon cloudIcon)
|
public RainIcon(int id, int rainCount, float rainSpace, Icon cloudIcon)
|
||||||
{
|
{
|
||||||
|
super(id);
|
||||||
this.rainCount = rainCount;
|
this.rainCount = rainCount;
|
||||||
this.rainSpace = rainSpace * 0.125F;
|
this.rainSpace = rainSpace * 0.125F;
|
||||||
this.cloudIcon = cloudIcon;
|
this.cloudIcon = cloudIcon;
|
||||||
@@ -73,4 +76,9 @@ public class RainIcon implements Icon {
|
|||||||
g2d.translate(0F, 0.10F);
|
g2d.translate(0F, 0.10F);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnimated() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.icons.impl;
|
||||||
|
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.Icon;
|
||||||
|
|
||||||
|
public class RainSnowIcon extends Icon {
|
||||||
|
private final Icon rainIcon;
|
||||||
|
private final Icon snowflakeIcon;
|
||||||
|
private final boolean snow;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public RainSnowIcon(int id, Icon rainIcon, Icon snowflakeIcon, boolean snow)
|
||||||
|
{
|
||||||
|
super(id);
|
||||||
|
this.rainIcon = rainIcon;
|
||||||
|
this.snowflakeIcon = snowflakeIcon;
|
||||||
|
this.snow = snow;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawIcon(Graphics2D g2d, float scale, int animationStep) {
|
||||||
|
if(snow)
|
||||||
|
{
|
||||||
|
g2d.scale(0.25F, 0.25F);
|
||||||
|
g2d.translate(2, 3);
|
||||||
|
snowflakeIcon.drawIcon(g2d, scale*0.25F, animationStep);
|
||||||
|
g2d.translate(1, -1);
|
||||||
|
snowflakeIcon.drawIcon(g2d, scale*0.25F, animationStep);
|
||||||
|
g2d.translate(-3, -2);
|
||||||
|
g2d.scale(4, 4);
|
||||||
|
}
|
||||||
|
rainIcon.drawIcon(g2d, scale, animationStep);
|
||||||
|
g2d.translate(0.3F, 0);
|
||||||
|
g2d.scale(0.7F, 0.7F);
|
||||||
|
snowflakeIcon.drawIcon(g2d, scale*0.7F, animationStep);
|
||||||
|
g2d.scale(1.42857142857F, 1.42857142857F);
|
||||||
|
g2d.translate(-0.3F, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnimated() {
|
||||||
|
return rainIcon.isAnimated() || snowflakeIcon.isAnimated();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.icons.impl;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.geom.Path2D;
|
||||||
|
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.Icon;
|
||||||
|
|
||||||
|
public class SleetIcon extends Icon {
|
||||||
|
|
||||||
|
Path2D.Float iceOutline = new Path2D.Float();
|
||||||
|
|
||||||
|
Path2D.Float[] iceFaces = new Path2D.Float[3];
|
||||||
|
Path2D.Float[] iceShines = new Path2D.Float[3];
|
||||||
|
|
||||||
|
Color[] iceFaceColors = new Color[] {
|
||||||
|
new Color(0xfff8a0),
|
||||||
|
new Color(0xfff14c),
|
||||||
|
new Color(0xccbc00),
|
||||||
|
};
|
||||||
|
Color[] iceShineAnimation = new Color[] {
|
||||||
|
new Color(0xFFFFFF),
|
||||||
|
};
|
||||||
|
|
||||||
|
public SleetIcon(int id) {
|
||||||
|
super(id);
|
||||||
|
|
||||||
|
iceOutline.moveTo(0F, 0.161F);
|
||||||
|
iceOutline.lineTo(0.542F, 0F);
|
||||||
|
iceOutline.lineTo(1.0F, 0.093F);
|
||||||
|
iceOutline.lineTo(1.0F, 0.441F);
|
||||||
|
iceOutline.lineTo(0.489F, 0.650F);
|
||||||
|
iceOutline.lineTo(0.0F, 0.531F);
|
||||||
|
iceOutline.closePath();
|
||||||
|
|
||||||
|
iceFaces[1] = new Path2D.Float();
|
||||||
|
iceFaces[1].moveTo(0F, 0.161F);
|
||||||
|
iceFaces[1].lineTo(0.542F, 0F);
|
||||||
|
iceFaces[1].lineTo(1.0F, 0.093F);
|
||||||
|
iceFaces[1].lineTo(0.489F, 0.263F);
|
||||||
|
iceFaces[1].closePath();
|
||||||
|
|
||||||
|
iceFaces[2] = new Path2D.Float();
|
||||||
|
iceFaces[2].moveTo(0.489F, 0.263F);
|
||||||
|
iceFaces[2].lineTo(1.0F, 0.093F);
|
||||||
|
iceFaces[2].lineTo(1.0F, 0.441F);
|
||||||
|
iceFaces[2].lineTo(0.489F, 0.650F);
|
||||||
|
iceFaces[2].closePath();
|
||||||
|
|
||||||
|
iceFaces[0] = new Path2D.Float();
|
||||||
|
iceFaces[0].moveTo(0.0F, 0.161F);
|
||||||
|
iceFaces[0].lineTo(0.489F, 0.263F);
|
||||||
|
iceFaces[0].lineTo(0.489F, 0.650F);
|
||||||
|
iceFaces[0].lineTo(0.0F, 0.531F);
|
||||||
|
iceFaces[0].closePath();
|
||||||
|
|
||||||
|
iceShines[1] = new Path2D.Float();
|
||||||
|
iceShines[1].moveTo(0.537F, 0.013F);
|
||||||
|
iceShines[1].lineTo(0.930F, 0.099F);
|
||||||
|
iceShines[1].lineTo(0.673F, 0.185F);
|
||||||
|
iceShines[1].lineTo(0.556F, 0.187F);
|
||||||
|
iceShines[1].lineTo(0.556F, 0.187F);
|
||||||
|
iceShines[1].lineTo(0.742F, 0.086);
|
||||||
|
iceShines[1].closePath();
|
||||||
|
|
||||||
|
iceShines[2] = new Path2D.Float();
|
||||||
|
iceShines[2].moveTo(0.981F, 0.134F);
|
||||||
|
iceShines[2].lineTo(0.981F, 0.423F);
|
||||||
|
iceShines[2].lineTo(0.515F, 0.624F);
|
||||||
|
iceShines[2].lineTo(0.571F, 0.557F);
|
||||||
|
iceShines[2].lineTo(0.915F, 0.372F);
|
||||||
|
iceShines[2].closePath();
|
||||||
|
|
||||||
|
iceShines[0] = new Path2D.Float();
|
||||||
|
iceShines[0].moveTo(0.018F, 0.187F);
|
||||||
|
iceShines[0].lineTo(0.205F, 0.229F);
|
||||||
|
iceShines[0].lineTo(0.060F, 0.249F);
|
||||||
|
iceShines[0].lineTo(0.044F, 0.475F);
|
||||||
|
iceShines[0].lineTo(0.021F, 0.508F);
|
||||||
|
iceShines[0].closePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawIcon(Graphics2D g2d, float scale, int animationStep) {
|
||||||
|
g2d.setColor(Color.BLACK);
|
||||||
|
g2d.setStroke(new BasicStroke(4 / scale));
|
||||||
|
g2d.translate(0F, 0.325F);
|
||||||
|
g2d.setColor(Color.BLACK);
|
||||||
|
g2d.draw(iceOutline);
|
||||||
|
for(int i = 0; i < iceFaces.length; i++)
|
||||||
|
{
|
||||||
|
g2d.setColor(iceFaceColors[i]);
|
||||||
|
g2d.fill(iceFaces[i]);
|
||||||
|
g2d.setColor(iceShineAnimation[(i+animationStep) % iceShineAnimation.length]);
|
||||||
|
g2d.fill(iceShines[i]);
|
||||||
|
}
|
||||||
|
g2d.translate(0F, -0.325F);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnimated() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.icons.impl;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.geom.Ellipse2D;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.Icon;
|
||||||
|
|
||||||
|
public class SmallCloudIcon extends Icon {
|
||||||
|
public SmallCloudIcon(int id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private final Ellipse2D.Float[] cloudCircles = new Ellipse2D.Float[]{
|
||||||
|
new Ellipse2D.Float(0.456F, 0.241F, 0.346F, 0.748F),
|
||||||
|
new Ellipse2D.Float(0.655F, 0.238F, 0.356F, 0.748F),
|
||||||
|
new Ellipse2D.Float(0.480F, 0.043F, 0.341F, 0.523F),
|
||||||
|
new Ellipse2D.Float(0.191F, 0.000F, 0.454F, 0.656F),
|
||||||
|
new Ellipse2D.Float(0.217F, 0.261F, 0.454F, 0.732F),
|
||||||
|
new Ellipse2D.Float(0.000F, 0.199F, 0.428F, 0.801F)
|
||||||
|
};
|
||||||
|
|
||||||
|
private final Ellipse2D.Float[] lightCircles = new Ellipse2D.Float[]{
|
||||||
|
new Ellipse2D.Float(0.196F, 0.052F, 0.439F, 0.748F),
|
||||||
|
new Ellipse2D.Float(0.030F, 0.230F, 0.439F, 0.654F),
|
||||||
|
new Ellipse2D.Float(0.709F, 0.300F, 0.218F, 0.335F),
|
||||||
|
new Ellipse2D.Float(0.429F, 0.498F, 0.218F, 0.335F)
|
||||||
|
};
|
||||||
|
|
||||||
|
private final Ellipse2D.Float[] overLight = new Ellipse2D.Float[]{
|
||||||
|
new Ellipse2D.Float(0.183F, 0.124F, 0.478F, 0.713F),
|
||||||
|
new Ellipse2D.Float(0.040F, 0.264F, 0.478F, 0.713F),
|
||||||
|
new Ellipse2D.Float(0.716F, 0.335F, 0.237F, 0.365F),
|
||||||
|
new Ellipse2D.Float(0.437F, 0.532F, 0.237F, 0.365F)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawIcon(Graphics2D g2d, float scale, int animationStep) {
|
||||||
|
g2d.setColor(Color.BLACK);
|
||||||
|
g2d.setStroke(new BasicStroke(4/scale));
|
||||||
|
for(int i = 0; i < cloudCircles.length; i++)
|
||||||
|
{
|
||||||
|
g2d.draw(cloudCircles[i]);
|
||||||
|
}
|
||||||
|
g2d.setColor(Color.LIGHT_GRAY);
|
||||||
|
for(int i = 0; i < cloudCircles.length; i++)
|
||||||
|
{
|
||||||
|
g2d.fill(cloudCircles[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < lightCircles.length; i++)
|
||||||
|
{
|
||||||
|
g2d.setColor(Color.LIGHT_GRAY.brighter());
|
||||||
|
g2d.fill(lightCircles[i]);
|
||||||
|
g2d.setColor(Color.LIGHT_GRAY);
|
||||||
|
g2d.fill(overLight[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnimated() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.icons.impl;
|
||||||
|
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.geom.AffineTransform;
|
||||||
|
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.Icon;
|
||||||
|
|
||||||
|
public class SnowIcon extends Icon {
|
||||||
|
private final Icon cloudIcon;
|
||||||
|
private final Icon snowflakeIcon;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public SnowIcon(int id, Icon cloudIcon, Icon snowflakeIcon)
|
||||||
|
{
|
||||||
|
super(id);
|
||||||
|
this.cloudIcon = cloudIcon;
|
||||||
|
this.snowflakeIcon = snowflakeIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawIcon(Graphics2D g2d, float scale, int animationStep) {
|
||||||
|
AffineTransform af = g2d.getTransform();
|
||||||
|
g2d.scale(0.25F, 0.25F);
|
||||||
|
g2d.translate(0.5F, 2F);
|
||||||
|
snowflakeIcon.drawIcon(g2d, scale*0.25F, animationStep);
|
||||||
|
g2d.translate(2F, 1F);
|
||||||
|
snowflakeIcon.drawIcon(g2d, scale*0.25F, animationStep);
|
||||||
|
g2d.setTransform(af);
|
||||||
|
g2d.translate(0F, -0.10F);
|
||||||
|
g2d.scale(1F, 0.8F);
|
||||||
|
cloudIcon.drawIcon(g2d, scale, animationStep);
|
||||||
|
g2d.setTransform(af);
|
||||||
|
g2d.translate(0.3F, 0);
|
||||||
|
g2d.scale(0.7F, 0.7F);
|
||||||
|
snowflakeIcon.drawIcon(g2d, scale*0.7F, animationStep);
|
||||||
|
g2d.setTransform(af);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnimated() {
|
||||||
|
return snowflakeIcon.isAnimated() || cloudIcon.isAnimated();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,17 +1,35 @@
|
|||||||
package com.flaremicro.flaretv.visualforecast.icons;
|
package com.flaremicro.flaretv.visualforecast.icons.impl;
|
||||||
|
|
||||||
import java.awt.BasicStroke;
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
|
|
||||||
public class SnowflakeIcon implements Icon {
|
import com.flaremicro.flaretv.visualforecast.icons.Icon;
|
||||||
|
|
||||||
|
public class SnowflakeIcon extends Icon {
|
||||||
Path2D.Float flakePath = new Path2D.Float();
|
Path2D.Float flakePath = new Path2D.Float();
|
||||||
Path2D.Float gradPath = new Path2D.Float();
|
Path2D.Float gradPath = new Path2D.Float();
|
||||||
Path2D.Float trianglePath = new Path2D.Float();
|
Path2D.Float trianglePath = new Path2D.Float();
|
||||||
|
|
||||||
public SnowflakeIcon()
|
Color[] animColor = {
|
||||||
|
new Color(0x2288FF),
|
||||||
|
new Color(0x4499FF),
|
||||||
|
new Color(0x66AAFF),
|
||||||
|
new Color(0x88BBFF),
|
||||||
|
new Color(0xAACCFF),
|
||||||
|
new Color(0xCCDDFF),
|
||||||
|
new Color(0xAACCFF),
|
||||||
|
new Color(0x88BBFF),
|
||||||
|
new Color(0x66AAFF),
|
||||||
|
new Color(0x4499FF),
|
||||||
|
new Color(0x2288FF),
|
||||||
|
new Color(0x2288FF),
|
||||||
|
};
|
||||||
|
|
||||||
|
public SnowflakeIcon(int id)
|
||||||
{
|
{
|
||||||
|
super(id);
|
||||||
flakePath.moveTo(0.400, 0);
|
flakePath.moveTo(0.400, 0);
|
||||||
flakePath.lineTo(0.600, 0);
|
flakePath.lineTo(0.600, 0);
|
||||||
flakePath.lineTo(0.600, 0.327);
|
flakePath.lineTo(0.600, 0.327);
|
||||||
@@ -94,13 +112,18 @@ public class SnowflakeIcon implements Icon {
|
|||||||
g2d.setColor(Color.WHITE);
|
g2d.setColor(Color.WHITE);
|
||||||
g2d.fill(flakePath);
|
g2d.fill(flakePath);
|
||||||
//g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
//g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
g2d.setPaint(new Color(0x2288FF));
|
g2d.setPaint(animColor[animationStep % animColor.length]);//new Color(0x2288FF));
|
||||||
g2d.fill(gradPath);
|
g2d.fill(gradPath);
|
||||||
g2d.setStroke(new BasicStroke(1/scale));
|
//g2d.setStroke(new BasicStroke(1/scale));
|
||||||
g2d.draw(gradPath);
|
//g2d.draw(gradPath);
|
||||||
//g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
|
//g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
|
||||||
g2d.setPaint(Color.BLACK);
|
g2d.setColor(Color.BLACK);
|
||||||
g2d.fill(trianglePath);
|
g2d.fill(trianglePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnimated() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.flaremicro.flaretv.visualforecast.icons;
|
package com.flaremicro.flaretv.visualforecast.icons.impl;
|
||||||
|
|
||||||
import java.awt.BasicStroke;
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
@@ -6,7 +6,9 @@ import java.awt.Graphics2D;
|
|||||||
import java.awt.geom.Ellipse2D;
|
import java.awt.geom.Ellipse2D;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
|
|
||||||
public class SunIcon implements Icon {
|
import com.flaremicro.flaretv.visualforecast.icons.Icon;
|
||||||
|
|
||||||
|
public class SunIcon extends Icon {
|
||||||
Path2D.Float sunPath = new Path2D.Float();
|
Path2D.Float sunPath = new Path2D.Float();
|
||||||
Ellipse2D.Float sunCircle1 = new Ellipse2D.Float(0.2F, 0.2F, 0.6F, 0.6F);
|
Ellipse2D.Float sunCircle1 = new Ellipse2D.Float(0.2F, 0.2F, 0.6F, 0.6F);
|
||||||
Ellipse2D.Float sunInternalCircle1 = new Ellipse2D.Float(0.28F, 0.22F, 0.5F, 0.5F);
|
Ellipse2D.Float sunInternalCircle1 = new Ellipse2D.Float(0.28F, 0.22F, 0.5F, 0.5F);
|
||||||
@@ -25,8 +27,9 @@ public class SunIcon implements Icon {
|
|||||||
new Color(255, 140, 0),
|
new Color(255, 140, 0),
|
||||||
new Color(255, 120, 0),
|
new Color(255, 120, 0),
|
||||||
};
|
};
|
||||||
public SunIcon()
|
public SunIcon(int id)
|
||||||
{
|
{
|
||||||
|
super(id);
|
||||||
sunPath.moveTo(0.5F, 0.0F);
|
sunPath.moveTo(0.5F, 0.0F);
|
||||||
sunPath.lineTo(0.605F, 0.106F);
|
sunPath.lineTo(0.605F, 0.106F);
|
||||||
sunPath.lineTo(0.750F, 0.067F);
|
sunPath.lineTo(0.750F, 0.067F);
|
||||||
@@ -72,4 +75,9 @@ public class SunIcon implements Icon {
|
|||||||
g2d.draw(sunCircle1);
|
g2d.draw(sunCircle1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnimated() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.providerapi;
|
||||||
|
|
||||||
|
public abstract class ForecastProvider {
|
||||||
|
ForecastProviderManager pluginManager;
|
||||||
|
|
||||||
|
protected final void setAsProvider(String authority)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void init();
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.providerapi;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import com.flaremicro.util.Util;
|
||||||
|
|
||||||
|
public class ForecastProviderManager {
|
||||||
|
public static final float API_VERSION = 0.0F;
|
||||||
|
private Logger log = Util.getDefaultLogger();
|
||||||
|
private ForecastProvider loadedProvider;
|
||||||
|
|
||||||
|
public void loadProviders(File file) {
|
||||||
|
Util.getDefaultLogger().info("Loading provider " + file.getName());
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
URLClassLoader classLoader = new URLClassLoader(new URL[] { file.toURI().toURL() });
|
||||||
|
Properties properties = new Properties();
|
||||||
|
InputStream propStream = classLoader.getResourceAsStream("provider.inf");
|
||||||
|
properties.load(propStream);
|
||||||
|
Util.cleanClose(propStream);
|
||||||
|
|
||||||
|
String mainClassStr = properties.getProperty("main-class", "");
|
||||||
|
Class<?> mainClass = classLoader.loadClass(mainClassStr);
|
||||||
|
Object instance = mainClass.newInstance();
|
||||||
|
if (instance instanceof ForecastProvider)
|
||||||
|
{
|
||||||
|
loadedProvider = (ForecastProvider) instance;
|
||||||
|
loadedProvider.init();
|
||||||
|
log.info("Provider " + file.getName() + " loaded!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log.info("Provider " + file.getName() + " main class is wrong object type");
|
||||||
|
log.info("(Does main class not extend ForecastProvider?)");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException e)
|
||||||
|
{
|
||||||
|
log.info("Provider " + file.getName() + " main class not found:");
|
||||||
|
e.printStackTrace();
|
||||||
|
log.info("(Is the information file invalid?)");
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
log.info("Provider " + file.getName() + " failed to read information file:");
|
||||||
|
e.printStackTrace();
|
||||||
|
log.info("(Is the information file defined?)");
|
||||||
|
}
|
||||||
|
catch (InstantiationException e)
|
||||||
|
{
|
||||||
|
log.info("Provider " + file.getName() + " failed to instantiate main class:");
|
||||||
|
e.printStackTrace();
|
||||||
|
log.info("(Does main class not implement empty constructor?)");
|
||||||
|
}
|
||||||
|
catch (IllegalAccessException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
package com.flaremicro.flaretv.visualforecast.providerapi;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import com.flaremicro.flaretv.visualforecast.forecast.DayForecast;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.forecast.ForecastDetails;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.forecast.TownForecast;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.forecast.ValueCheck;
|
||||||
|
import com.flaremicro.flaretv.visualforecast.icons.IconProvider;
|
||||||
|
|
||||||
|
public class MockForecastProvider {
|
||||||
|
|
||||||
|
|
||||||
|
private static final String[] townNames = {
|
||||||
|
"Vancouver",
|
||||||
|
"Burnaby",
|
||||||
|
"Kamloops",
|
||||||
|
"Kelona",
|
||||||
|
"Lytton"
|
||||||
|
};
|
||||||
|
|
||||||
|
private final static WeatherType[] possibleWeather = {
|
||||||
|
new WeatherType(IconProvider.BLIZZARD.id, "Blizzard", true),
|
||||||
|
new WeatherType(IconProvider.CLOUD.id, "Cloudy", false),
|
||||||
|
new WeatherType(IconProvider.CLOUDY_CLOUDY.id, "Very", "Cloudy", false),
|
||||||
|
new WeatherType(IconProvider.FREEZING_RAIN.id, "Freezing", "Rain", true),
|
||||||
|
new WeatherType(IconProvider.LIGHTNING_STORM.id, "Thunder", "Storm", true),
|
||||||
|
new WeatherType(IconProvider.LIGHTNING_BLIZZARD.id, "Blizzard", "T'Storm", true),
|
||||||
|
new WeatherType(IconProvider.PARTLY_CLOUDY.id, "Partly", "Cloudy", false),
|
||||||
|
new WeatherType(IconProvider.RAIN.id, "Rain", true),
|
||||||
|
new WeatherType(IconProvider.RAIN_HEAVIEST.id, "Extreme","Rain", true),
|
||||||
|
new WeatherType(IconProvider.RAIN_HEAVY.id, "Heavy","Rain", true),
|
||||||
|
new WeatherType(IconProvider.RAIN_LIGHT.id, "Light","Rain", true),
|
||||||
|
new WeatherType(IconProvider.RAIN_LIGHTEST.id, "Drizzle", true),
|
||||||
|
new WeatherType(IconProvider.RAIN_SNOW.id, "Rain","Snow", true),
|
||||||
|
new WeatherType(IconProvider.RAIN_VANCOUVER.id, "Vancouver","Rain", true),
|
||||||
|
new WeatherType(IconProvider.SCATTERD_SHOWERS.id, "Scattered","Showers", true),
|
||||||
|
new WeatherType(IconProvider.SCATTERD_THUNDERSTORMS.id, "Scattered","T'Storms", true),
|
||||||
|
new WeatherType(IconProvider.SNOW.id, "Snow", true),
|
||||||
|
new WeatherType(IconProvider.SUN.id, "Sun", false),
|
||||||
|
new WeatherType(IconProvider.FOG.id, "Fog", false),
|
||||||
|
new WeatherType(IconProvider.HAIL.id, "Hail", false),
|
||||||
|
new WeatherType(IconProvider.BUTTER_RAIN.id, "Paula", "Dean", false),
|
||||||
|
new WeatherType(IconProvider.BUTTER.id, "Unsalted", "Butter", false),
|
||||||
|
//new WeatherType(IconProvider.INVALID_RAIN.id, "Your", "Mom", false),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
public static ForecastDetails provideMockForecast()
|
||||||
|
{
|
||||||
|
Random random = new Random();
|
||||||
|
ForecastDetails fd = new ForecastDetails();
|
||||||
|
fd.setTownForecast(provideTownForecast(random));
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TownForecast[] provideTownForecast(Random random) {
|
||||||
|
TownForecast[] tf = new TownForecast[townNames.length];
|
||||||
|
for(int i = 0; i < tf.length; i++)
|
||||||
|
{
|
||||||
|
tf[i] = new TownForecast(townNames[i], provideDayForecast(random));
|
||||||
|
}
|
||||||
|
return tf;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DayForecast[] provideDayForecast(Random random)
|
||||||
|
{
|
||||||
|
DayForecast[] df = new DayForecast[8];
|
||||||
|
for(int i = 0; i < df.length; i++)
|
||||||
|
{
|
||||||
|
if(random.nextInt(11) == 10)
|
||||||
|
{
|
||||||
|
df[i] = new DayForecast(ValueCheck.NO_DATA_BYTE, ValueCheck.NO_DATA_BYTE, (byte)0, null, null, ValueCheck.NO_DATA_FLOAT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byte hiTemp = (byte)(random.nextInt(60)-20);
|
||||||
|
byte loTemp = (byte)(random.nextInt(60)-20);
|
||||||
|
if(hiTemp < loTemp)
|
||||||
|
{
|
||||||
|
byte temp = hiTemp;
|
||||||
|
hiTemp = loTemp;
|
||||||
|
loTemp = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte iconId = 0;
|
||||||
|
String weatherLine1 = null;
|
||||||
|
String weatherLine2 = null;
|
||||||
|
float percipPercent = ValueCheck.NO_DATA_FLOAT;
|
||||||
|
|
||||||
|
WeatherType wt = possibleWeather[random.nextInt(possibleWeather.length)];
|
||||||
|
iconId = wt.iconId;
|
||||||
|
weatherLine1 = wt.line1;
|
||||||
|
weatherLine2 = wt.line2;
|
||||||
|
|
||||||
|
if(wt.hasPercipitation)
|
||||||
|
{
|
||||||
|
percipPercent = random.nextFloat() * 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
df[i] = new DayForecast(hiTemp, loTemp, iconId, weatherLine1, weatherLine2, percipPercent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return df;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class WeatherType{
|
||||||
|
byte iconId;
|
||||||
|
String line1;
|
||||||
|
String line2;
|
||||||
|
boolean hasPercipitation;
|
||||||
|
|
||||||
|
public WeatherType(byte iconId, String line1, boolean hasPercipitation){
|
||||||
|
this(iconId, line1, null, hasPercipitation);
|
||||||
|
}
|
||||||
|
public WeatherType(byte iconId, String line1, String line2, boolean hasPercipitation){
|
||||||
|
this.iconId = iconId;
|
||||||
|
this.line1 = line1;
|
||||||
|
this.line2 = line2;
|
||||||
|
this.hasPercipitation = hasPercipitation;
|
||||||
|
}
|
||||||
|
}
|
||||||
93
src/com/flaremicro/util/Util.java
Normal file
93
src/com/flaremicro/util/Util.java
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
package com.flaremicro.util;
|
||||||
|
|
||||||
|
import java.applet.Applet;
|
||||||
|
import java.io.Closeable;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.logging.ConsoleHandler;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import com.flaremicro.util.logging.LogFormatter;
|
||||||
|
import com.flaremicro.util.logging.LogOutputStream;
|
||||||
|
|
||||||
|
|
||||||
|
public class Util {
|
||||||
|
public static final long INSTANCE_ID = Math.abs(new Random().nextLong());
|
||||||
|
public static final String LOGGER_NAME = "VisualForecast 1000 Logger";
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
initLogger();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Logger getDefaultLogger() {
|
||||||
|
return Logger.getLogger(LOGGER_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initLogger() {
|
||||||
|
Logger log = getDefaultLogger();
|
||||||
|
log.setUseParentHandlers(false);
|
||||||
|
ConsoleHandler handler = new ConsoleHandler();
|
||||||
|
handler.setFormatter(new LogFormatter());
|
||||||
|
log.addHandler(handler);
|
||||||
|
System.setErr(new PrintStream(new LogOutputStream(log, java.util.logging.Level.SEVERE)));
|
||||||
|
System.setOut(new PrintStream(new LogOutputStream(log, java.util.logging.Level.INFO)));
|
||||||
|
log.info("Initialized logger successfully");
|
||||||
|
log.info("Using native Java logger, ID 0J3QvtGCINGD0YHQtdC70LXRgdGBINCbNNCI");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse arguments, in arg=value format, or just arg for arguments with no
|
||||||
|
* value. Values can contain = signs, but not arguments.
|
||||||
|
*
|
||||||
|
* @param args
|
||||||
|
* @param keyToLower
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static HashMap<String, String> parseArgs(String args[], boolean keyToLower) {
|
||||||
|
HashMap<String, String> map = new HashMap<String, String>();
|
||||||
|
for (String s : args)
|
||||||
|
{
|
||||||
|
String[] res = s.split("=", 2);
|
||||||
|
if (keyToLower)
|
||||||
|
res[0].toLowerCase();
|
||||||
|
if (res.length > 1)
|
||||||
|
{
|
||||||
|
map.put(res[0], res[1]);
|
||||||
|
}
|
||||||
|
else map.put(res[0], "");
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean cleanClose(Closeable closeable) {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (closeable != null)
|
||||||
|
closeable.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HashMap<String, String> toArguments(Applet applet, String[] expectedParameters) {
|
||||||
|
HashMap<String, String> arguments = new HashMap<String, String>();
|
||||||
|
if (applet == null || expectedParameters == null)
|
||||||
|
return arguments;
|
||||||
|
for (String parameter : expectedParameters)
|
||||||
|
{
|
||||||
|
String value = applet.getParameter(parameter);
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
arguments.put(parameter, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return arguments;
|
||||||
|
}
|
||||||
|
}
|
||||||
31
src/com/flaremicro/util/logging/LogFormatter.java
Normal file
31
src/com/flaremicro/util/logging/LogFormatter.java
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package com.flaremicro.util.logging;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.logging.Formatter;
|
||||||
|
import java.util.logging.Handler;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.LogRecord;
|
||||||
|
|
||||||
|
|
||||||
|
public class LogFormatter extends Formatter {
|
||||||
|
String sep = System.getProperty("line.separator");
|
||||||
|
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
@Override
|
||||||
|
public String format(LogRecord record) {
|
||||||
|
String fmessage = "";
|
||||||
|
if(record.getLevel() == Level.SEVERE)
|
||||||
|
fmessage += "["+format.format(System.currentTimeMillis())+"][SEVERE]";
|
||||||
|
else if(record.getLevel() == Level.WARNING)
|
||||||
|
fmessage += "["+format.format(System.currentTimeMillis())+"][WARNING]";
|
||||||
|
else if(record.getLevel() == Level.INFO)
|
||||||
|
fmessage += "["+format.format(System.currentTimeMillis())+"][INFO]";
|
||||||
|
return fmessage += this.formatMessage(record) + sep;
|
||||||
|
}
|
||||||
|
public String getHead(Handler h) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTail(Handler h) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
38
src/com/flaremicro/util/logging/LogOutputStream.java
Normal file
38
src/com/flaremicro/util/logging/LogOutputStream.java
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package com.flaremicro.util.logging;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class LogOutputStream extends OutputStream {
|
||||||
|
|
||||||
|
String buffer = "";
|
||||||
|
Logger logger;
|
||||||
|
Level level;
|
||||||
|
|
||||||
|
public LogOutputStream(Logger logger, Level level)
|
||||||
|
{
|
||||||
|
this.logger = logger;
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(int b) throws IOException {
|
||||||
|
buffer += (char)((byte)b);
|
||||||
|
if(buffer.endsWith("\n") || buffer.endsWith("\r\n"))
|
||||||
|
{
|
||||||
|
buffer = buffer.replace("\r", "").replace("\n", "");
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flush()
|
||||||
|
{
|
||||||
|
logger.log(level, buffer);
|
||||||
|
buffer = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user