diff --git a/NotificationsWindow.java b/NotificationsWindow.java index d0fc032..e4082f9 100644 --- a/NotificationsWindow.java +++ b/NotificationsWindow.java @@ -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)); + + 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.setMaximumSize(new Dimension(w * 7 / 20, h)); - type.setMaximumSize(new Dimension(w * 6 / 20, h)); - text.setMaximumSize(new Dimension(w * 5 / 20, h)); + 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,22 +429,23 @@ 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); + + typeImg = new ImageComponent(); + + text = new JLabel(); + text.setFont(f3); - setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); - add(Box.createHorizontalStrut(4)); + 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); } diff --git a/TwoToggleButton.java b/TwoToggleButton.java index f994816..923bda8 100644 --- a/TwoToggleButton.java +++ b/TwoToggleButton.java @@ -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); diff --git a/graphics/boostedNotification.png b/graphics/boostedNotification.png new file mode 100644 index 0000000..bf4a6c0 Binary files /dev/null and b/graphics/boostedNotification.png differ diff --git a/graphics/favouritedNotification.png b/graphics/favouritedNotification.png new file mode 100755 index 0000000..0e20124 Binary files /dev/null and b/graphics/favouritedNotification.png differ