Fixed aliased image rendering in window components.

Added icons to notifications.
This commit is contained in:
Snowyfox 2022-05-31 06:02:54 -04:00
parent e6fea4c061
commit d52879324f
4 changed files with 125 additions and 34 deletions

View File

@ -13,11 +13,14 @@ import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.Image;
import java.awt.Graphics;
import java.util.List;
import java.util.ArrayList;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Cursor;
import java.awt.Insets;
import cafe.biskuteri.hinoki.Tree;
import java.io.IOException;
import java.awt.event.ComponentListener;
@ -309,13 +312,20 @@ implements ComponentListener {
private JLabel
type;
private ImageComponent
typeImg;
private JLabel
name, text;
// ---%-@-%---
public void
setType(String n) { type.setText(n); }
setType(String n)
{
type.setText(n);
typeImg.image = ImageApi.local(n + "Notification");
}
public void
setName(String n) { name.setText(n); }
@ -326,18 +336,32 @@ implements ComponentListener {
// - -%- -
public void
componentResized(ComponentEvent eC)
doLayout()
{
int w = getWidth(), h = getHeight();
name.setPreferredSize(new Dimension(w * 7 / 20, h));
type.setPreferredSize(new Dimension(w * 6 / 20, h));
text.setPreferredSize(new Dimension(w * 5 / 20, h));
name.setMaximumSize(new Dimension(w * 7 / 20, h));
type.setMaximumSize(new Dimension(w * 6 / 20, h));
text.setMaximumSize(new Dimension(w * 5 / 20, h));
int x0 = w * 0/20;
int x1 = w * 7/20;
int x2 = w * 13/20;
int x3 = w * 15/20;
int x4 = w * 20/20;
name.setLocation(x0 + 4, 0);
name.setSize((x1 - 4) - (x0 + 4), h);
type.setLocation(x1 + 4, 0);
type.setSize((x2 - 1) - (x1 + 4), h);
typeImg.setLocation((x2 + 1), 2);
typeImg.setSize((x3 - 4) - (x2 + 1), (h - 2) - 2);
text.setLocation(x3 + 4, 0);
text.setSize((x4 - 4) - (x3 + 4), h);
}
public void
componentResized(ComponentEvent eC) { doLayout(); }
public void
componentShown(ComponentEvent eC) { }
@ -347,6 +371,51 @@ implements ComponentListener {
public void
componentMoved(ComponentEvent eC) { }
// ---%-@-%---
private static class
ImageComponent extends JComponent {
private Image
image,
scaled;
private boolean
snapdown = false;
// -=%=-
protected void
paintComponent(Graphics g)
{
if (image == null) return;
int w = getWidth(), h = getHeight();
int ow = image.getWidth(this);
int oh = image.getHeight(this);
int nh = h;
int nw = ow * nh/oh;
if (snapdown)
{
int sw, sh;
for (sw = 1; sw < nw; sw *= 2);
for (sh = 1; sh < nh; sh *= 2);
nw = sw / 2;
nh = sh / 2;
}
if (scaled == null)
scaled = image.getScaledInstance(
nw, nh,
Image.SCALE_SMOOTH
);
int x = (w - nw) / 2;
int y = (h - nh) / 2;
g.drawImage(scaled, x, y, this);
}
}
// ---%-@-%---
NotificationComponent()
@ -360,21 +429,22 @@ implements ComponentListener {
Border b1 = BorderFactory.createMatteBorder(0, 0, 1, 0, c);
name = new JLabel();
type = new JLabel();
text = new JLabel();
name.setFont(f1);
type = new JLabel();
type.setFont(f2);
text.setFont(f3);
type.setHorizontalAlignment(JLabel.RIGHT);
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
add(Box.createHorizontalStrut(4));
typeImg = new ImageComponent();
text = new JLabel();
text.setFont(f3);
setLayout(null);
add(name);
add(Box.createHorizontalStrut(8));
add(type);
add(Box.createHorizontalStrut(8));
add(typeImg);
add(text);
add(Box.createHorizontalStrut(4));
this.addComponentListener(this);
setBorder(b1);

View File

@ -7,6 +7,7 @@ import java.awt.Image;
import java.awt.Graphics;
import java.awt.Dimension;
import java.awt.Shape;
import java.awt.Rectangle;
import java.awt.geom.Ellipse2D;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
@ -253,6 +254,9 @@ implements KeyListener, MouseListener, FocusListener {
// - -%- -
private Image
scaled;
private int
nextEventID = ActionEvent.ACTION_FIRST;
@ -266,10 +270,21 @@ implements KeyListener, MouseListener, FocusListener {
// ---%-@-%---
public void
setImage(Image n) { image = n; }
setImage(Image n)
{
image = n;
scaled = null;
}
// - -%- -
public boolean
imageUpdate(Image i, int f, int x, int y, int w, int h)
{
if ((f | WIDTH) != 0) repaint();
return super.imageUpdate(i, f, x, y, w, h);
}
protected void
paintComponent(Graphics g)
{
@ -281,26 +296,32 @@ implements KeyListener, MouseListener, FocusListener {
if (image == null) return;
int w1 = button.getWidth(this);
int h1 = button.getHeight(this);
int w2 = image.getWidth(this);
int h2 = image.getHeight(this);
if (w2 == -1) w2 = w1;
if (h2 == -1) h2 = h1;
if (h2 > w2) {
h2 = h2 * w1 / w2;
w2 = w1;
}
else {
w2 = w2 * h1 / h2;
h2 = h1;
}
int ow = image.getWidth(this);
int oh = image.getHeight(this);
if (ow == -1) return;
int nx = 6;
int ny = 6;
int nw = button.getWidth(this) - 12;
int nh = button.getHeight(this) - 12;
Shape defaultClip, roundClip;
defaultClip = g.getClip();
roundClip = new Ellipse2D.Float(6, 6, w1 - 12, h1 - 12);
roundClip = new Ellipse2D.Float(nx, ny, nw, nh);
if (scaled == null)
{
int sw = ow > oh ? -1 : nw;
int sh = oh > ow ? -1 : nh;
scaled = image.getScaledInstance(
sw, sh,
Image.SCALE_SMOOTH
);
}
// () Be careful to be idempotent when calling
// async methods like #drawImage.
g.setClip(roundClip);
g.drawImage(image, 0, 0, w2, h2, getParent());
g.drawImage(scaled, nx, ny, getParent());
// I don't know why, but when we repaint ourselves, our
// parent doesn't repaint, so nothing seems to happen.
g.setClip(defaultClip);

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB