From 5ec840b29a43494127b40f57ef820fa8bb3a3db5 Mon Sep 17 00:00:00 2001 From: l2- Date: Sun, 20 Aug 2017 16:45:41 +0200 Subject: [PATCH] Added discord button to the title bar --- .../java/net/runelite/client/ui/ClientUI.java | 3 + .../net/runelite/client/ui/TitleBarPane.java | 131 ++++++++++++++++++ .../net/runelite/client/ui/discord.png | Bin 0 -> 3626 bytes .../runelite/client/ui/discord_inverted.png | Bin 0 -> 68458 bytes 4 files changed, 134 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/ui/TitleBarPane.java create mode 100644 runelite-client/src/main/resources/net/runelite/client/ui/discord.png create mode 100644 runelite-client/src/main/resources/net/runelite/client/ui/discord_inverted.png diff --git a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java index 349373d938..45848d86d4 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java @@ -36,6 +36,7 @@ import javax.swing.SwingUtilities; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.client.RuneLite; +import org.pushingpixels.substance.internal.ui.SubstanceRootPaneUI; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -57,6 +58,8 @@ public final class ClientUI extends JFrame { init(); pack(); + TitleBarPane titleBarPane = new TitleBarPane(this.getRootPane(), (SubstanceRootPaneUI)this.getRootPane().getUI()); + titleBarPane.editTitleBar(this); setTitle("RuneLite"); setIconImage(RuneLite.ICON); setLocationRelativeTo(getOwner()); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/TitleBarPane.java b/runelite-client/src/main/java/net/runelite/client/ui/TitleBarPane.java new file mode 100644 index 0000000000..ad717174c6 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/ui/TitleBarPane.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2017. l2- + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.ui; + +import java.awt.Desktop; +import java.awt.Image; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import javax.imageio.ImageIO; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JRootPane; +import org.pushingpixels.substance.api.SubstanceLookAndFeel; +import org.pushingpixels.substance.internal.ui.SubstanceRootPaneUI; +import org.pushingpixels.substance.internal.utils.SubstanceTitlePane; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Created by X on 8/20/2017. + */ +public class TitleBarPane extends SubstanceTitlePane +{ + private static final Logger logger = LoggerFactory.getLogger(TitleBarPane.class); + + private static final String DISCORD_INVITE = "https://discord.gg/R4BQ8tU"; + + private BufferedImage discordIcon; + private BufferedImage invertedIcon; + + public TitleBarPane(JRootPane root, SubstanceRootPaneUI ui) + { + super(root, ui); + + try + { + discordIcon = ImageIO.read(ClientUI.class.getResourceAsStream("discord.png")); + invertedIcon = ImageIO.read(ClientUI.class.getResourceAsStream("discord_inverted.png")); + } + catch (IOException ex) + { + logger.warn("unable to load discord icons", ex); + } + } + + public void editTitleBar(JFrame frame) + { + if (discordIcon == null || invertedIcon == null) + { + return; + } + + JComponent titleBar = SubstanceLookAndFeel.getTitlePaneComponent(frame); + + JButton discordButton = new JButton(); + int heigth = titleBar.getHeight() - 3; + int width = heigth; + int x = titleBar.getWidth() - 100; + int y = 1; + ImageIcon icon = new ImageIcon(discordIcon.getScaledInstance(width - 3, heigth - 3, Image.SCALE_SMOOTH)); + ImageIcon invIcon = new ImageIcon(invertedIcon.getScaledInstance(width - 3, heigth - 3, Image.SCALE_SMOOTH)); + + discordButton.setIcon(icon); + discordButton.setRolloverIcon(invIcon); + discordButton.putClientProperty("substancelaf.componentFlat", Boolean.TRUE); + discordButton.putClientProperty("substancelaf.internal.titlePane.extraComponentKind", ExtraComponentKind.TRAILING); + discordButton.setFocusable(false); + discordButton.setBounds(x, y, icon.getIconWidth() + 4, icon.getIconHeight() + 2); + discordButton.setToolTipText("Join Discord"); + + discordButton.addMouseListener(new MouseAdapter() + { + @Override + public void mouseClicked(MouseEvent e) + { + super.mouseClicked(e); + try + { + Desktop.getDesktop().browse(new URL(DISCORD_INVITE).toURI()); + } + catch (IOException | URISyntaxException ex) + { + logger.warn("error opening browser", ex); + } + } + }); + + titleBar.addComponentListener(new ComponentAdapter() + { + @Override + public void componentResized(ComponentEvent e) + { + super.componentResized(e); + discordButton.setBounds(titleBar.getWidth() - 100, y, discordButton.getWidth(), discordButton.getHeight()); + } + }); + + titleBar.add(discordButton); + } +} diff --git a/runelite-client/src/main/resources/net/runelite/client/ui/discord.png b/runelite-client/src/main/resources/net/runelite/client/ui/discord.png new file mode 100644 index 0000000000000000000000000000000000000000..60b8fb5483c66a0a915310dd51cd537c1618c46d GIT binary patch literal 3626 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 QMEvcOuBMSjHOxNZKgtAwdjJ3c literal 0 HcmV?d00001 diff --git a/runelite-client/src/main/resources/net/runelite/client/ui/discord_inverted.png b/runelite-client/src/main/resources/net/runelite/client/ui/discord_inverted.png new file mode 100644 index 0000000000000000000000000000000000000000..ab5fccaf293efb2ba60cb4aee921f7d37afc003a GIT binary patch literal 68458 zcmeHP2|QH$7r&meZ!J_k9^`ets_4G- z(6BkJBQC2-us}%cxTUt;On*j(eL_f&kNX_GlMh;QR6&|AAsmt)wKmiY@|XjqRV~^-7jl^n zjdr&#(SshTL({FC-7TT>m!X16DbY+wNDP{87aBAb8nzQ!c~enw8?-kX8g1V0tp9#m zhE%g^Z>FL%^>dW;<_0VgQr{%#?5r_SrP4}f+Gt(3pWI@MHHx-JkDC#oBl*1J4g@8H zOZP_G(Y38oBBQcW_fWRP3iUVF1$ri}TGi0qRF&#&3_&k^{HnXvG_%J0&k^wV>^?QQ zZJ5V$(S+YR54dMa8ef7ETAny}coT9n_vGQ6$B&yD8z0RpFzrRP|iz?rqcScA;5-YhqXC(A27ilP!sR5*8o$^4l<3_x zK3XwhV-jNTZoW9);Gpiw=DVpLl25`6ab?pBUXK;jF8Ou3MrpC>g8eIHj>UGNI{m9E%_4JN8_Z&DnAH z4vZ^voIXqIZB%o#WVDx)i)yy&@6zG7MUKrorhH6RRnsv!# zGR&Q{9U78_|304TloGe_t%IxsK6y@3ND4m5%hBjBKi95(0=G`lXviy- z7hOFrYnz(F2JzJ3-vVZqC|{^}{QFkb+^8*Zm#RM z011<_c~h27vA~B_4v%YgcV`5uW{I%u&@itzG z&$j0`f1R*Pv&*r|^K0Tq3o#dgEHNd4TCvKp`Zs27^3s>nEUSHQhg()`j636Y%q{Z8 z-te4i{nPi&|1g(4xUO_*gHnTMsb}eFWdUUcW$XEG=C{Sz&(AqK_3Rv*IW}b#cPdU* zJcyndYoPUTMssX)?8Dgl%PSXeTdbCylznBbRc7Pjv#xE~c^iWk>$#qBaaz1A%RD_U zee#3c^xVV|i8%`*7No{Mz!#r?pM5Jk`SQ5)O^*a>GqOFice&wL$>1;F$S7`$$dA}{ zb=MzV27=-tk0ny&7R&i_xMm#Z;bXGun0I!|@hPyi1i-)g$eO>`~=YOV-6X z#NM;O%iwdi1a^cT*k`?`TqDv@BUZNb>CODcc|IREEqk$}=3`uJR%}sgQti1m-L`dY zA$5P=(fM;~ysP$>yTvzg&+VG3jYR)EHhn{Vnx8GsHUNLASy6MfX1H_u!}FKV_@;Ea zy^}HgWVrdy2EzvZS9?)m&m-5} z`n`T|SJ3U1+ks*~u_-|zLC(QOhrB~w##d`a&h)LW!)>WI`)YRF>{%>c%U184`n;K{ zhAA5B^`FeTs&mz-RKwl%&V83S7pq^bC+KOYX6SDG^;-S+){c;uaW6$1cFII)-dyIr z{bXg)hoHnU$r>ZoW*;}U30?5Z(f^r9sV0p%IJte4@8m-w+l%Ci@RKyFb*n=k;g+gS zT+nW*I)BHJf5P)-ZdbaYeMYS*XYZ8c!+AF1Hcw+`$B&8GD(^YNV0OM%;F0jdn@m#_ z=0{}X-{4=lZ!J$-80u= z5=hg(vOinZ^S*6rt8-+AU%v8=`5OY37vA1ec!_VrTTv&Grl4JK>mIf)vvtvQt-s{< zH8@VzPk%rSEO%khKbS4Z8pnx~iC z9)8|f-6p#;?~~3y_iLBrb#@uvx>oDN=QRJm`~9`wtiEM+8fENDY59Eoo9D9h1)iH) z%lK>fy95;_vLELBeP6D|z|lVJ!L+v)5@kPM>yCTpt1hl9?)1lr(wBy zCyLL0vi0E3v=@T+e%>mFm(yHt8q*$Q9_tYEZON)7S8eYYRzG<2Y{z$t+Mgv)=;*s{ zpV#4dYu%HUJ@+E;?NtZkj>YZr)A&-ivi4N=&gRvX_3I_Q-d&aQc~LXB=RotEyg8Li z+pqYvXVx~2a=zjmb8hwu&o@4A^t&VO*_P#=$c@R!S-K&oZAbp4o$j42vhlMjpMJ>S z{(el)gZuG%22b-lc6fE(==@ke=BeN2DP5K2xsQFPw58|S=B@Z(+-mX|_cY|b(UR`E zNAK!(uP^XT=%}u<=oAPFtm+Q`7$%7u9u^%|9xNXGHvShwJ-wGko4Z=RC*rEsR4K>H zbf4-j&yX3T>G%2m+lQ6aQPn3S+an{cd;Wf=>rKJiap!7Fi%KV6yR}VQYx##o-&zZO z>wM+jovxR(ZTww+w@Q!4mkS>q?k0YV7#9)IGmJl~*06 zLjxh`OHc2;1%iH?4nc2LLeT6e2$JzSvf_q0#0MR-GBa`9#s~HEF6#Z#1719w15kV( zExoI%#!=aCAFB-%j=oNRvrAW*;Kj zo=GuM8q?m5@hrCxfKuWJI&QnD#X-~$dOVy=0Af<$_d!n*Mh@X|!DWoxlAGm30>BeN zl*y5^CJ}A2dS?yAzq{#SK*I-B8=OP{YKfobaP1>}O~Vy9hw7ShPS>+r#a8S}_ym zXvIfwFWq@|5P(uZw184tKU8(p@<1zIYI_*c4<-Sq1wjcYwY9vWr<4TlU5D);}D<0hS#A6oS2vB8IvERs;aWXK(R|`KL<)Kmg7t6tQ4v-vI%7 zGk|tdxyc?|2*6DV;svZUNr1&8fESX=O)&xjfX4uJ4xrruxanl@5>~1V00iKTH;I4% z;4wg%188;tUTUe_7%N2v00QvFBY;3yiWeXNAOP8K1(6AGb`WGL7dN&S?E+POKa25qt5=gq2 zMHqeCNo@|sxZg1#0Mp+V_9YRe!C(}g=%WuZt8W5{2C=^P0Y+(n240k)^qD~e6Qefz zopMPB=mU)6fYD@8T8AQxK2wzZV5RGK$^rqf0!PViA7B&*l>9KNLlH)wDMo#xweE*w zRvrOp0b#^WUzSiDFyfcm8WdrWnWE+o3;hqrfB?+>Y=Eq4C<<5quovx%RXoh>NBryup+GR?->{i+#>yT}Og1NC8fcCY^+qT-gaCxV(7Xnk zC`#)&4G$%Z^mK@NBNRiB0Q8bFka@I7Fc6<;u0_-vq2M3_5CTWzLNkGAU_u+uKNn3!GQ!IBx0Z!7RiI#4NV7=ykT%fBk-dR!28KS;$1zhg+j%Kll!4U3f z+8v6vFv%67zHkLx#-LE7ff2?-v3RV+1kVquIYQJIu7JxJ6$sNHF~ZDBQ5o4wDJKLS zBYPQMgQzcD0hiGRKw^&&9HoolV0t$Xg|(D&K-8fgAELf+1zi3Q3F<)pD;_aWYIm&s za)MoIF%$JzU_^ZGgHQ}I0SG}da$%7ScGzThtcZFe6jTU60FHIS7)j1x;J_kIPKfOX z21I?~3b+hIjzw}vZNl8q6-oDU(wHuA3Jb8r-{%fdU$_D;_wDQ-U zxDO0z|7xtU_Iv6bA?gcPz-6-C{Q}mYiT3+FvNj^xL*vdGlK$OjV4-KD-`js9M1A23 zxQwvSub}4~&G~+>+&w}wC$wx)%@U%%a0OhZYN>yM77(=O`n_`32<<%3vPUyBi2A}6 zaG9pH{z+PZ(46b{$Xz2eb3n@$-K-$$3s=Bpx)#Y7&;rNm9Jwd%lUR+P)_#Vwfv7KB z0hbxJOump7SZ3zPt#hx$OzgDw3^)^r`oa}(dB7gXH_!sl=p4C4?w1&io7Os}vw)~C zTmhGv_C&ssRxq^Y$gKPXzUqLt}<5@gnLAR{*&O@p0);&IwNiJCqB_Y;1r4uz#G$Y$CaJA0PlA z0B=3>xb>uBg&TAL&;dXP!0L2ygI&-8KnDOFfE!LKRv1AC0385y0IW_IH`oOo0CWJ* z0l49$VucZO0MG$I2f*rdaf4mZ0YC=;9e^87DpnXl2LK%abO5YQ7dO}i9RPFy&;hvN zq+*2;bO6u+KnK9;ba8`S&;i)o0RkXD_MbpL!ha5le_-Uh_