From d52879324f55eecc8dea4555be52aa776e556725 Mon Sep 17 00:00:00 2001 From: Snowyfox Date: Tue, 31 May 2022 06:02:54 -0400 Subject: [PATCH] Fixed aliased image rendering in window components. Added icons to notifications. --- NotificationsWindow.java | 104 +++++++++++++++++++++++----- TwoToggleButton.java | 55 ++++++++++----- graphics/boostedNotification.png | Bin 0 -> 389 bytes graphics/favouritedNotification.png | Bin 0 -> 1289 bytes 4 files changed, 125 insertions(+), 34 deletions(-) create mode 100644 graphics/boostedNotification.png create mode 100755 graphics/favouritedNotification.png 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 0000000000000000000000000000000000000000..bf4a6c08f0f4e738beb09b9f02cb3b8bbac09cf2 GIT binary patch literal 389 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzwj^(N7l!{JxM1({$v_d#0*}aI z1_nK45N51cYF`EvWH0gbb!C6XD$l{7B(BhP3n(O6;u=xnoS&PUnpeW$T$GwvlA5AW zo>`Ki;O^-g5Z=fq4pj8k)5S3);_%z>i+qO_IG%L;|9|?;!k1|w0;022rS*M1Ue7H! zI{C$Q=98~a^K=V0wsv^9xTRd;IMG^}xb=MC6psRK5AMEurhzt)5uRubTP(<>DD zj`ic+1dW^4GMtS$*Ursq#R;Wb!ezeGhck&!XPMKA^`LJYD@<);T3K0RVxznm7Oe literal 0 HcmV?d00001 diff --git a/graphics/favouritedNotification.png b/graphics/favouritedNotification.png new file mode 100755 index 0000000000000000000000000000000000000000..0e20124113928776d62a46fc0db39ecd1cac5ee7 GIT binary patch literal 1289 zcmV+k1@`)hP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+TE60mg6c6MgKL59)czD5W~S3*19ve!|wyeuDrUE zO8TqKiopV-gEqpU`u~58e&G_9g`AHTQV0t!mt2yJhAsP*$DJ29?&Ff#h36|fogD&` zqSpPsKf-_?^_$Zu!3T~GcPC4XA)#%uxQMuIU8u%AJcpy(XF7%oG)Yy~1$XNT zwf{sjYLB}r!i2V>?KSL{T`6b@EfMW>#P$2@JLPmppUAI}o-O`^{em=&fF2!sLnxf} zLp%E~J6$3j+%7zaaC*M7Z{>7xlA{A(Yn!!J_tj+=u;efobu4AHFmCP98gB)Zh@W4q z2fLSqVn~SsoEtXTic&bS0Apjv8)t4@M_sr;qLV5SwMY@=LNFR&Bq>14>U!ZOQIl?J zz+bQ(6jnL4@Nk=kyTS&?8yjKwFec-%XFe$O%AnSILNPCP#tOQm?`){(DOPfrY)74I;&<2EaiUz&GBBJcf#w-Hd|}Adq{c5p0rXz;e!G|3qil zL)oi$-uvLAH=leC8hVC>5JNvvbJXafk0HirF~v-#=FD5LXlBWBlB76seL_AaODW|H zrx`P6yqz&1=T%l+-Rjq{#?{ue<|0(IxZ+DFu~Z-4y z#%eXy+_2S}HrIR$EjDY3T0W^wtas%H)Ob>pL8=doCpB1OJf`4&ocPWR#KbXx$4-Ei zL^`v@*g5IsIa2X#?oUrVi87R&uh`E5ux(k{<4iH&oFl zDxU45w^Y$5Dqh(~KUPJbsCb%dGpAlnz>!?kSMYi6-=2_f?C3)V*@q|N%?bIZs7wc^ zue)>UBuozxpQqF7@uOExpU1kMevTdqztsKs+@jAvjsN0A4S$Fd{RWNX0aef5=j8wZ z00v@9M??Vs0RI60puMM)00009a7bBm000XU000XU0RWnu7ytkO2XskIMF-{u9|t%e zQ;R(f0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJAV*0}P*;Ht7XSbNzez+vR9M69 zS6dE%APl3%`(GJ9G=!+YY)8zDOZ<|wwCn*X{h>uZK021S6+ls+^DZ6$jTP2`qP_r; zE`)U8qF!+!oC8hutP40bl@YrQ6fkq+sY2QElS5!^_9E|{mHQ@IxdA2NRB}tU%9|Kf z1w2YmDM@(MKid!B*@T#86s8qVJAx1nOs#@Nt#RYvp&htYUy-7oq@A@*o|Ull4iLxx z{A6sKXF-R!_h3nuYdc0D>g}1uke^(W@jetABePg3j0F}300000NkvXXu0mjfosw9I literal 0 HcmV?d00001