Exp trackers plugin redesign
Restyled the whole exp trackers plugin panel to follow my proposed design on issue #1342 - Restyled and recolored the exp tracker - Removed the contracted state, trackers are now always expanded as they are now thinner than before - Progress bars are now color matched to the skill using a new enum SkillColor - Added new progresss bar custom component - Added error panel for "no exp gained" that disappears once the player earns experience - Restyled the overall exp panel - Hid the overall exp panel until the player earns experience - Added "Reset" right click menu to individual skill trackers - Added "Reset All" right click menu to the overall skill tracker
This commit is contained in:
committed by
Tomas Slusny
parent
6ec0d60ec4
commit
9a72dd5969
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Psikoi <https://github.com/psikoi>
|
||||||
|
* 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.plugins.xptracker;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
public enum SkillColor
|
||||||
|
{
|
||||||
|
ATTACK(105, 32, 7),
|
||||||
|
DEFENCE(98, 119, 190),
|
||||||
|
STRENGTH(4, 149, 90),
|
||||||
|
HITPOINTS(131, 126, 126),
|
||||||
|
RANGED(109, 144, 23),
|
||||||
|
PRAYER(159, 147, 35),
|
||||||
|
MAGIC(50, 80, 193),
|
||||||
|
COOKING(112, 35, 134),
|
||||||
|
WOODCUTTING(52, 140, 37),
|
||||||
|
FLETCHING(3, 141, 125),
|
||||||
|
FISHING(106, 132, 164),
|
||||||
|
FIREMAKING(189, 120, 25),
|
||||||
|
CRAFTING(151, 110, 77),
|
||||||
|
SMITHING(108, 107, 82),
|
||||||
|
MINING(93, 143, 167),
|
||||||
|
HERBLORE(7, 133, 9),
|
||||||
|
AGILITY(58, 60, 137),
|
||||||
|
THIEVING(108, 52, 87),
|
||||||
|
SLAYER(100, 100, 100),
|
||||||
|
FARMING(101, 152, 63),
|
||||||
|
RUNECRAFT(170, 141, 26),
|
||||||
|
HUNTER(92, 89, 65),
|
||||||
|
CONSTRUCTION(130, 116, 95);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final Color color;
|
||||||
|
|
||||||
|
SkillColor(int red, int green, int blue)
|
||||||
|
{
|
||||||
|
this.color = new Color(red, green, blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||||
|
* Copyright (c) 2018, Psikoi <https://github.com/psikoi>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -26,54 +27,54 @@ package net.runelite.client.plugins.xptracker;
|
|||||||
|
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
import java.awt.GridLayout;
|
import java.awt.GridLayout;
|
||||||
import java.awt.Rectangle;
|
|
||||||
import java.awt.RenderingHints;
|
|
||||||
import java.awt.event.MouseAdapter;
|
|
||||||
import java.awt.event.MouseEvent;
|
|
||||||
import java.awt.event.MouseListener;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.awt.image.LookupOp;
|
|
||||||
import java.awt.image.LookupTable;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.JButton;
|
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JLayeredPane;
|
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.JPopupMenu;
|
import javax.swing.JPopupMenu;
|
||||||
import javax.swing.JProgressBar;
|
|
||||||
import javax.swing.SwingConstants;
|
import javax.swing.SwingConstants;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.border.CompoundBorder;
|
|
||||||
import javax.swing.border.EmptyBorder;
|
import javax.swing.border.EmptyBorder;
|
||||||
import javax.swing.border.LineBorder;
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.api.Skill;
|
import net.runelite.api.Skill;
|
||||||
import net.runelite.client.game.SkillIconManager;
|
import net.runelite.client.game.SkillIconManager;
|
||||||
import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;
|
import net.runelite.client.ui.ColorScheme;
|
||||||
|
import net.runelite.client.ui.FontManager;
|
||||||
|
import net.runelite.client.ui.components.ProgressBar;
|
||||||
import net.runelite.client.util.LinkBrowser;
|
import net.runelite.client.util.LinkBrowser;
|
||||||
import org.pushingpixels.substance.internal.SubstanceSynapse;
|
import net.runelite.client.util.StackFormatter;
|
||||||
|
import net.runelite.client.util.SwingUtil;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
class XpInfoBox extends JPanel
|
class XpInfoBox extends JPanel
|
||||||
{
|
{
|
||||||
private static final Rectangle ICON_BOUNDS = new Rectangle(0, 0, 26, 26);
|
|
||||||
|
|
||||||
private final Client client;
|
private final Client client;
|
||||||
private final JPanel panel;
|
private final JPanel panel;
|
||||||
|
|
||||||
|
@Getter(AccessLevel.PACKAGE)
|
||||||
private final Skill skill;
|
private final Skill skill;
|
||||||
|
|
||||||
|
/* The tracker's wrapping container */
|
||||||
private final JPanel container = new JPanel();
|
private final JPanel container = new JPanel();
|
||||||
|
|
||||||
|
/* Contains the skill icon and the stats panel */
|
||||||
|
private final JPanel headerPanel = new JPanel();
|
||||||
|
|
||||||
|
/* Contains all the skill information (exp gained, per hour, etc) */
|
||||||
private final JPanel statsPanel = new JPanel();
|
private final JPanel statsPanel = new JPanel();
|
||||||
private final JProgressBar progressBar = new JProgressBar();
|
|
||||||
private final JLabel xpHr = new JLabel();
|
private final ProgressBar progressBar = new ProgressBar();
|
||||||
private final JLabel xpGained = new JLabel();
|
|
||||||
private final JLabel xpLeft = new JLabel();
|
private final JLabel expGained = new JLabel();
|
||||||
|
private final JLabel expHour = new JLabel();
|
||||||
|
private final JLabel expLeft = new JLabel();
|
||||||
private final JLabel actionsLeft = new JLabel();
|
private final JLabel actionsLeft = new JLabel();
|
||||||
private final JLabel levelLabel = new JShadowedLabel();
|
|
||||||
|
|
||||||
XpInfoBox(XpTrackerPlugin xpTrackerPlugin, Client client, JPanel panel, Skill skill, SkillIconManager iconManager) throws IOException
|
XpInfoBox(XpTrackerPlugin xpTrackerPlugin, Client client, JPanel panel, Skill skill, SkillIconManager iconManager) throws IOException
|
||||||
{
|
{
|
||||||
@@ -82,121 +83,81 @@ class XpInfoBox extends JPanel
|
|||||||
this.skill = skill;
|
this.skill = skill;
|
||||||
|
|
||||||
setLayout(new BorderLayout());
|
setLayout(new BorderLayout());
|
||||||
setBorder(new CompoundBorder
|
setBorder(new EmptyBorder(10, 0, 0, 0));
|
||||||
(
|
setOpaque(false);
|
||||||
new EmptyBorder(2, 0, 2, 0),
|
|
||||||
new LineBorder(getBackground().brighter(), 1)
|
|
||||||
));
|
|
||||||
|
|
||||||
// Expand stats panel on click
|
|
||||||
Color backgroundColor = getBackground();
|
|
||||||
|
|
||||||
MouseListener panelMouseListener = new MouseAdapter()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void mouseEntered(MouseEvent e)
|
|
||||||
{
|
|
||||||
container.setBackground(backgroundColor.darker().darker());
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void mouseExited(MouseEvent e)
|
|
||||||
{
|
|
||||||
container.setBackground(backgroundColor);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void mouseReleased(MouseEvent e)
|
|
||||||
{
|
|
||||||
if (SwingUtilities.isLeftMouseButton(e))
|
|
||||||
{
|
|
||||||
showStatsPanel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
container.setLayout(new BorderLayout());
|
container.setLayout(new BorderLayout());
|
||||||
container.setBorder(new EmptyBorder(5, 5, 5, 5));
|
container.setOpaque(true);
|
||||||
container.addMouseListener(panelMouseListener);
|
container.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||||
|
|
||||||
// Create open xp tracker menu
|
// Create open xp tracker menu
|
||||||
final JMenuItem openXpTracker = new JMenuItem("Open XP tracker");
|
final JMenuItem openXpTracker = new JMenuItem("Open online tracker");
|
||||||
openXpTracker.addActionListener(e -> LinkBrowser.browse(XpPanel.buildXpTrackerUrl(client.getLocalPlayer(), skill)));
|
openXpTracker.addActionListener(e -> LinkBrowser.browse(XpPanel.buildXpTrackerUrl(client.getLocalPlayer(), skill)));
|
||||||
|
|
||||||
|
// Create reset menu
|
||||||
|
final JMenuItem reset = new JMenuItem("Reset");
|
||||||
|
reset.addActionListener(e -> reset());
|
||||||
|
|
||||||
// Create popup menu
|
// Create popup menu
|
||||||
final JPopupMenu popupMenu = new JPopupMenu();
|
final JPopupMenu popupMenu = new JPopupMenu();
|
||||||
|
popupMenu.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||||
popupMenu.add(openXpTracker);
|
popupMenu.add(openXpTracker);
|
||||||
|
popupMenu.add(reset);
|
||||||
container.setComponentPopupMenu(popupMenu);
|
container.setComponentPopupMenu(popupMenu);
|
||||||
|
|
||||||
// Create icon panel
|
JLabel skillIcon = new JLabel(new ImageIcon(iconManager.getSkillImage(skill)));
|
||||||
final JPanel iconBarPanel = new JPanel();
|
skillIcon.setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
iconBarPanel.setLayout(new BorderLayout(5, 0));
|
skillIcon.setVerticalAlignment(SwingConstants.CENTER);
|
||||||
iconBarPanel.setOpaque(false);
|
skillIcon.setPreferredSize(new Dimension(35, 35));
|
||||||
|
|
||||||
// Create skill/reset icon
|
headerPanel.setOpaque(false);
|
||||||
final BufferedImage skillImage = iconManager.getSkillImage(skill);
|
headerPanel.setLayout(new BorderLayout());
|
||||||
final JButton skillIcon = new JButton();
|
|
||||||
|
|
||||||
skillIcon.putClientProperty(SubstanceSynapse.FLAT_LOOK, Boolean.TRUE);
|
statsPanel.setLayout(new BorderLayout());
|
||||||
skillIcon.putClientProperty(SubstanceSynapse.BUTTON_NEVER_PAINT_BACKGROUND, Boolean.TRUE);
|
statsPanel.setBorder(new EmptyBorder(9, 5, 9, 10));
|
||||||
skillIcon.setIcon(new ImageIcon(skillImage));
|
|
||||||
skillIcon.setRolloverIcon(new ImageIcon(createHoverImage(skillImage)));
|
|
||||||
|
|
||||||
skillIcon.setToolTipText("Reset " + skill.getName() + " tracker");
|
|
||||||
skillIcon.addActionListener(e -> xpTrackerPlugin.resetSkillState(skill));
|
|
||||||
skillIcon.setBounds(ICON_BOUNDS);
|
|
||||||
skillIcon.setOpaque(false);
|
|
||||||
skillIcon.setFocusPainted(false);
|
|
||||||
|
|
||||||
// Create level label
|
|
||||||
levelLabel.setHorizontalAlignment(JLabel.CENTER);
|
|
||||||
levelLabel.setForeground(Color.YELLOW);
|
|
||||||
levelLabel.setBounds(ICON_BOUNDS);
|
|
||||||
levelLabel.setOpaque(false);
|
|
||||||
|
|
||||||
// Create pane for grouping skill icon and level label
|
|
||||||
final JLayeredPane layeredPane = new JLayeredPane();
|
|
||||||
layeredPane.add(skillIcon, new Integer(1));
|
|
||||||
layeredPane.add(levelLabel, new Integer(2));
|
|
||||||
layeredPane.setPreferredSize(ICON_BOUNDS.getSize());
|
|
||||||
iconBarPanel.add(layeredPane, BorderLayout.LINE_START);
|
|
||||||
|
|
||||||
// Create progress bar
|
|
||||||
progressBar.setStringPainted(true);
|
|
||||||
progressBar.setValue(0);
|
|
||||||
progressBar.setMinimum(0);
|
|
||||||
progressBar.setMaximum(100);
|
|
||||||
progressBar.setBackground(Color.RED);
|
|
||||||
progressBar.addMouseListener(panelMouseListener);
|
|
||||||
iconBarPanel.add(progressBar, BorderLayout.CENTER);
|
|
||||||
|
|
||||||
container.add(iconBarPanel, BorderLayout.NORTH);
|
|
||||||
|
|
||||||
// Stats panel
|
|
||||||
statsPanel.setLayout(new GridLayout(2, 2));
|
|
||||||
statsPanel.setBorder(new EmptyBorder(3, 0, 0, 0));
|
|
||||||
statsPanel.setOpaque(false);
|
statsPanel.setOpaque(false);
|
||||||
|
|
||||||
statsPanel.add(xpGained);
|
JPanel leftPanel = new JPanel();
|
||||||
xpHr.setHorizontalAlignment(SwingConstants.RIGHT);
|
leftPanel.setOpaque(false);
|
||||||
statsPanel.add(xpHr);
|
leftPanel.setLayout(new GridLayout(2, 1));
|
||||||
statsPanel.add(xpLeft);
|
|
||||||
actionsLeft.setHorizontalAlignment(SwingConstants.RIGHT);
|
|
||||||
statsPanel.add(actionsLeft);
|
|
||||||
|
|
||||||
add(container, BorderLayout.CENTER);
|
expGained.setFont(FontManager.getRunescapeSmallFont());
|
||||||
}
|
expHour.setFont(FontManager.getRunescapeSmallFont());
|
||||||
|
|
||||||
private void showStatsPanel()
|
leftPanel.add(expGained);
|
||||||
{
|
leftPanel.add(expHour);
|
||||||
if (statsPanel.isShowing())
|
|
||||||
{
|
JPanel rightPanel = new JPanel();
|
||||||
container.remove(statsPanel);
|
rightPanel.setOpaque(false);
|
||||||
revalidate();
|
rightPanel.setLayout(new GridLayout(2, 1));
|
||||||
}
|
|
||||||
else
|
expLeft.setFont(FontManager.getRunescapeSmallFont());
|
||||||
{
|
actionsLeft.setFont(FontManager.getRunescapeSmallFont());
|
||||||
container.add(statsPanel, BorderLayout.SOUTH);
|
|
||||||
revalidate();
|
rightPanel.add(expLeft);
|
||||||
}
|
rightPanel.add(actionsLeft);
|
||||||
|
|
||||||
|
statsPanel.add(leftPanel, BorderLayout.WEST);
|
||||||
|
statsPanel.add(rightPanel, BorderLayout.EAST);
|
||||||
|
|
||||||
|
headerPanel.add(skillIcon, BorderLayout.WEST);
|
||||||
|
headerPanel.add(statsPanel, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
JPanel progressWrapper = new JPanel();
|
||||||
|
progressWrapper.setOpaque(false);
|
||||||
|
progressWrapper.setLayout(new BorderLayout());
|
||||||
|
progressWrapper.setBorder(new EmptyBorder(0, 7, 7, 7));
|
||||||
|
|
||||||
|
progressBar.setMaximumValue(100);
|
||||||
|
progressBar.setBackground(new Color(61, 56, 49));
|
||||||
|
progressBar.setForeground(SkillColor.values()[skill.ordinal()].getColor());
|
||||||
|
|
||||||
|
progressWrapper.add(progressBar, BorderLayout.NORTH);
|
||||||
|
|
||||||
|
container.add(headerPanel, BorderLayout.NORTH);
|
||||||
|
container.add(progressWrapper, BorderLayout.SOUTH);
|
||||||
|
|
||||||
|
add(container, BorderLayout.NORTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
@@ -221,46 +182,46 @@ class XpInfoBox extends JPanel
|
|||||||
panel.revalidate();
|
panel.revalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
levelLabel.setText(String.valueOf(xpSnapshotSingle.getCurrentLevel()));
|
// Update information labels
|
||||||
xpGained.setText(XpPanel.formatLine(xpSnapshotSingle.getXpGainedInSession(), "xp gained"));
|
expGained.setText(htmlLabel("XP Gained: ", xpSnapshotSingle.getXpGainedInSession()));
|
||||||
xpLeft.setText(XpPanel.formatLine(xpSnapshotSingle.getXpRemainingToGoal(), "xp left"));
|
expLeft.setText(htmlLabel("XP Left: ", xpSnapshotSingle.getXpRemainingToGoal()));
|
||||||
actionsLeft.setText(XpPanel.formatLine(xpSnapshotSingle.getActionsRemainingToGoal(), "actions left"));
|
actionsLeft.setText(htmlLabel("Actions: ", xpSnapshotSingle.getActionsRemainingToGoal()));
|
||||||
|
|
||||||
final int progress = xpSnapshotSingle.getSkillProgressToGoal();
|
// Update progress bar
|
||||||
|
progressBar.setValue(xpSnapshotSingle.getSkillProgressToGoal());
|
||||||
progressBar.setValue(progress);
|
progressBar.setCenterLabel(xpSnapshotSingle.getSkillProgressToGoal() + "%");
|
||||||
progressBar.setBackground(Color.getHSBColor((progress / 100.f) * (120.f / 360.f), 1, 1));
|
progressBar.setLeftLabel("Lvl. " + xpSnapshotSingle.getCurrentLevel());
|
||||||
|
progressBar.setRightLabel("Lvl. " + (xpSnapshotSingle.getCurrentLevel() + 1));
|
||||||
|
|
||||||
progressBar.setToolTipText("<html>"
|
progressBar.setToolTipText("<html>"
|
||||||
+ XpPanel.formatLine(xpSnapshotSingle.getActionsInSession(), "actions")
|
+ xpSnapshotSingle.getActionsInSession() + " actions done"
|
||||||
+ "<br/>"
|
+ "<br/>"
|
||||||
+ XpPanel.formatLine(xpSnapshotSingle.getActionsPerHour(), "actions/hr")
|
+ xpSnapshotSingle.getActionsPerHour() + " actions/hr"
|
||||||
+ "<br/>"
|
+ "<br/>"
|
||||||
+ xpSnapshotSingle.getTimeTillGoal() + " till next lvl"
|
+ xpSnapshotSingle.getTimeTillGoal() + " till next lvl"
|
||||||
+ "</html>");
|
+ "</html>");
|
||||||
|
|
||||||
|
progressBar.repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always update xp/hr as time always changes
|
// Update exp per hour seperately, everytime (not only when there's an update)
|
||||||
xpHr.setText(XpPanel.formatLine(xpSnapshotSingle.getXpPerHour(), "xp/hr"));
|
expHour.setText(htmlLabel("XP/Hour: ", xpSnapshotSingle.getXpPerHour()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BufferedImage createHoverImage(BufferedImage image)
|
public static String htmlLabel(String key, int value)
|
||||||
{
|
{
|
||||||
LookupTable lookup = new LookupTable(0, 4)
|
String valueStr = value + "";
|
||||||
|
|
||||||
|
if (value > 9999999 || value < -9999999)
|
||||||
{
|
{
|
||||||
@Override
|
valueStr = "Lots!";
|
||||||
public int[] lookupPixel(int[] src, int[] dest)
|
}
|
||||||
{
|
else
|
||||||
if (dest[3] != 0)
|
{
|
||||||
{
|
valueStr = StackFormatter.quantityToRSDecimalStack(value);
|
||||||
dest[3] = 60;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return dest;
|
return "<html><body style = 'color:" + SwingUtil.toHexColor(ColorScheme.LIGHT_GRAY_COLOR) + "'>" + key + "<span style = 'color:white'>" + valueStr + "</span></body></html>";
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
LookupOp op = new LookupOp(lookup, new RenderingHints(null));
|
|
||||||
return op.filter(image, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Cameron <moberg@tuta.io>
|
* Copyright (c) 2017, Cameron <moberg@tuta.io>
|
||||||
|
* Copyright (c) 2018, Psikoi <https://github.com/psikoi>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -29,64 +30,93 @@ import java.awt.GridLayout;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.swing.BorderFactory;
|
|
||||||
import javax.swing.BoxLayout;
|
import javax.swing.BoxLayout;
|
||||||
import javax.swing.JButton;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JPopupMenu;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.api.Actor;
|
import net.runelite.api.Actor;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.api.Skill;
|
import net.runelite.api.Skill;
|
||||||
import net.runelite.client.game.SkillIconManager;
|
import net.runelite.client.game.SkillIconManager;
|
||||||
|
import net.runelite.client.ui.ColorScheme;
|
||||||
|
import net.runelite.client.ui.FontManager;
|
||||||
import net.runelite.client.ui.PluginPanel;
|
import net.runelite.client.ui.PluginPanel;
|
||||||
|
import net.runelite.client.ui.components.PluginErrorPanel;
|
||||||
import net.runelite.client.util.LinkBrowser;
|
import net.runelite.client.util.LinkBrowser;
|
||||||
import net.runelite.client.util.StackFormatter;
|
|
||||||
import okhttp3.HttpUrl;
|
import okhttp3.HttpUrl;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
class XpPanel extends PluginPanel
|
class XpPanel extends PluginPanel
|
||||||
{
|
{
|
||||||
private final Map<Skill, XpInfoBox> infoBoxes = new HashMap<>();
|
private final Map<Skill, XpInfoBox> infoBoxes = new HashMap<>();
|
||||||
private final JLabel totalXpGained = new JLabel();
|
|
||||||
private final JLabel totalXpHr = new JLabel();
|
private final JLabel overallExpGained = new JLabel(XpInfoBox.htmlLabel("Gained: ", 0));
|
||||||
|
private final JLabel overallExpHour = new JLabel(XpInfoBox.htmlLabel("Per hour: ", 0));
|
||||||
|
|
||||||
|
private final JPanel overallPanel = new JPanel();
|
||||||
|
|
||||||
|
/* This displays the "No exp gained" text */
|
||||||
|
private final PluginErrorPanel errorPanel = new PluginErrorPanel();
|
||||||
|
|
||||||
XpPanel(XpTrackerPlugin xpTrackerPlugin, Client client, SkillIconManager iconManager)
|
XpPanel(XpTrackerPlugin xpTrackerPlugin, Client client, SkillIconManager iconManager)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||||
|
setBackground(ColorScheme.DARK_GRAY_COLOR);
|
||||||
|
|
||||||
final JPanel layoutPanel = new JPanel();
|
final JPanel layoutPanel = new JPanel();
|
||||||
layoutPanel.setLayout(new BorderLayout(0, 3));
|
layoutPanel.setOpaque(false);
|
||||||
|
layoutPanel.setLayout(new BorderLayout());
|
||||||
add(layoutPanel);
|
add(layoutPanel);
|
||||||
|
|
||||||
final JPanel totalPanel = new JPanel();
|
overallPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||||
totalPanel.setLayout(new BorderLayout());
|
overallPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||||
totalPanel.setBorder(BorderFactory.createLineBorder(getBackground().brighter(), 1, true));
|
overallPanel.setLayout(new BorderLayout());
|
||||||
|
overallPanel.setVisible(false); // this will only become visible when the player gets exp
|
||||||
|
|
||||||
final JPanel infoPanel = new JPanel();
|
// Create open xp tracker menu
|
||||||
infoPanel.setLayout(new GridLayout(4, 1));
|
final JMenuItem openXpTracker = new JMenuItem("Open online tracker");
|
||||||
infoPanel.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
|
openXpTracker.addActionListener(e -> LinkBrowser.browse(XpPanel.buildXpTrackerUrl(client.getLocalPlayer(), Skill.OVERALL)));
|
||||||
|
|
||||||
final JButton resetButton = new JButton("Reset All");
|
// Create reset all menu
|
||||||
resetButton.addActionListener(e -> xpTrackerPlugin.resetAndInitState());
|
final JMenuItem reset = new JMenuItem("Reset All");
|
||||||
|
reset.addActionListener(e -> xpTrackerPlugin.resetAndInitState());
|
||||||
|
|
||||||
final JButton openTrackerButton = new JButton("Open XP tracker");
|
// Create popup menu
|
||||||
openTrackerButton.addActionListener(e -> LinkBrowser.browse(buildXpTrackerUrl(client.getLocalPlayer(), Skill.OVERALL)));
|
final JPopupMenu popupMenu = new JPopupMenu();
|
||||||
|
popupMenu.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||||
|
popupMenu.add(openXpTracker);
|
||||||
|
popupMenu.add(reset);
|
||||||
|
overallPanel.setComponentPopupMenu(popupMenu);
|
||||||
|
|
||||||
totalXpGained.setText(formatLine(0, "total xp gained"));
|
final JLabel overallIcon = new JLabel(new ImageIcon(iconManager.getSkillImage(Skill.OVERALL)));
|
||||||
totalXpHr.setText(formatLine(0, "total xp/hr"));
|
|
||||||
|
final JPanel overallInfo = new JPanel();
|
||||||
|
overallInfo.setOpaque(false);
|
||||||
|
overallInfo.setLayout(new GridLayout(2, 1));
|
||||||
|
overallInfo.setBorder(new EmptyBorder(0, 10, 0, 0));
|
||||||
|
|
||||||
|
overallExpGained.setFont(FontManager.getRunescapeSmallFont());
|
||||||
|
overallExpHour.setFont(FontManager.getRunescapeSmallFont());
|
||||||
|
|
||||||
|
overallInfo.add(overallExpGained);
|
||||||
|
overallInfo.add(overallExpHour);
|
||||||
|
|
||||||
|
overallPanel.add(overallIcon, BorderLayout.WEST);
|
||||||
|
overallPanel.add(overallInfo, BorderLayout.CENTER);
|
||||||
|
|
||||||
infoPanel.add(totalXpGained);
|
|
||||||
infoPanel.add(totalXpHr);
|
|
||||||
infoPanel.add(resetButton);
|
|
||||||
infoPanel.add(openTrackerButton);
|
|
||||||
totalPanel.add(infoPanel, BorderLayout.CENTER);
|
|
||||||
layoutPanel.add(totalPanel, BorderLayout.NORTH);
|
|
||||||
|
|
||||||
final JPanel infoBoxPanel = new JPanel();
|
final JPanel infoBoxPanel = new JPanel();
|
||||||
|
infoBoxPanel.setOpaque(false);
|
||||||
infoBoxPanel.setLayout(new BoxLayout(infoBoxPanel, BoxLayout.Y_AXIS));
|
infoBoxPanel.setLayout(new BoxLayout(infoBoxPanel, BoxLayout.Y_AXIS));
|
||||||
layoutPanel.add(infoBoxPanel, BorderLayout.CENTER);
|
layoutPanel.add(infoBoxPanel, BorderLayout.CENTER);
|
||||||
|
layoutPanel.add(overallPanel, BorderLayout.NORTH);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -96,7 +126,6 @@ class XpPanel extends PluginPanel
|
|||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
infoBoxes.put(skill, new XpInfoBox(xpTrackerPlugin, client, infoBoxPanel, skill, iconManager));
|
infoBoxes.put(skill, new XpInfoBox(xpTrackerPlugin, client, infoBoxPanel, skill, iconManager));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,6 +133,10 @@ class XpPanel extends PluginPanel
|
|||||||
{
|
{
|
||||||
log.warn(null, e);
|
log.warn(null, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
errorPanel.setContent("Exp trackers", "You have not gained experience yet.");
|
||||||
|
errorPanel.setBorder(new EmptyBorder(0, 0, 0, 0));
|
||||||
|
add(errorPanel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static String buildXpTrackerUrl(final Actor player, final Skill skill)
|
static String buildXpTrackerUrl(final Actor player, final Skill skill)
|
||||||
@@ -150,30 +183,23 @@ class XpPanel extends PluginPanel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateTotal(XpSnapshotTotal xpSnapshotTotal)
|
|
||||||
|
public void updateTotal(XpSnapshotTotal xpSnapshotTotal)
|
||||||
{
|
{
|
||||||
|
// if player has gained exp and hasn't switched displays yet, hide error panel and show overall info
|
||||||
|
if (xpSnapshotTotal.getXpGainedInSession() > 0 && !overallPanel.isVisible())
|
||||||
|
{
|
||||||
|
overallPanel.setVisible(true);
|
||||||
|
remove(errorPanel);
|
||||||
|
}
|
||||||
|
|
||||||
SwingUtilities.invokeLater(() -> rebuildAsync(xpSnapshotTotal));
|
SwingUtilities.invokeLater(() -> rebuildAsync(xpSnapshotTotal));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void rebuildAsync(XpSnapshotTotal xpSnapshotTotal)
|
private void rebuildAsync(XpSnapshotTotal xpSnapshotTotal)
|
||||||
{
|
{
|
||||||
totalXpGained.setText(formatLine(xpSnapshotTotal.getXpGainedInSession(), "total xp gained"));
|
overallExpGained.setText(XpInfoBox.htmlLabel("Gained: ", xpSnapshotTotal.getXpGainedInSession()));
|
||||||
totalXpHr.setText(formatLine(xpSnapshotTotal.getXpPerHour(), "total xp/hr"));
|
overallExpHour.setText(XpInfoBox.htmlLabel("Per hour: ", xpSnapshotTotal.getXpPerHour()));
|
||||||
}
|
}
|
||||||
|
|
||||||
static String formatLine(double number, String description)
|
|
||||||
{
|
|
||||||
String numberStr;
|
|
||||||
if (number < 100000)
|
|
||||||
{
|
|
||||||
numberStr = StackFormatter.formatNumber(number);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int num = (int) (Math.log(number) / Math.log(1000));
|
|
||||||
numberStr = String.format("%.1f%c", number / Math.pow(1000, num), "KMB".charAt(num - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
return numberStr + " " + description;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Psikoi <https://github.com/psikoi>
|
||||||
|
* 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.components;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
|
import lombok.Setter;
|
||||||
|
import net.runelite.client.ui.FontManager;
|
||||||
|
import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A progress bar to be displayed underneath the GE offer item panels
|
||||||
|
*/
|
||||||
|
public class ProgressBar extends JPanel
|
||||||
|
{
|
||||||
|
@Setter
|
||||||
|
private int maximumValue;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
private int value;
|
||||||
|
|
||||||
|
private final JLabel leftLabel = new JShadowedLabel();
|
||||||
|
private final JLabel rightLabel = new JShadowedLabel();
|
||||||
|
private final JLabel centerLabel = new JShadowedLabel();
|
||||||
|
|
||||||
|
public ProgressBar()
|
||||||
|
{
|
||||||
|
setLayout(new BorderLayout());
|
||||||
|
setBackground(Color.GREEN.darker());
|
||||||
|
setPreferredSize(new Dimension(100, 16));
|
||||||
|
|
||||||
|
leftLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||||
|
leftLabel.setForeground(Color.WHITE);
|
||||||
|
leftLabel.setBorder(new EmptyBorder(2, 5, 0, 0));
|
||||||
|
|
||||||
|
rightLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||||
|
rightLabel.setForeground(Color.WHITE);
|
||||||
|
rightLabel.setBorder(new EmptyBorder(2, 0, 0, 5));
|
||||||
|
|
||||||
|
centerLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||||
|
centerLabel.setForeground(Color.WHITE);
|
||||||
|
centerLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
|
centerLabel.setBorder(new EmptyBorder(2, 0, 0, 0));
|
||||||
|
|
||||||
|
add(leftLabel, BorderLayout.WEST);
|
||||||
|
add(centerLabel, BorderLayout.CENTER);
|
||||||
|
add(rightLabel, BorderLayout.EAST);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paint(Graphics g)
|
||||||
|
{
|
||||||
|
double percentage = getPercentage();
|
||||||
|
int topWidth = (int) (getSize().width * (percentage / 100));
|
||||||
|
|
||||||
|
super.paint(g);
|
||||||
|
g.setColor(getForeground());
|
||||||
|
g.fillRect(0, 0, topWidth, 16);
|
||||||
|
super.paintComponents(g);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setLeftLabel(String txt)
|
||||||
|
{
|
||||||
|
this.leftLabel.setText(txt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRightLabel(String txt)
|
||||||
|
{
|
||||||
|
this.rightLabel.setText(txt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCenterLabel(String txt)
|
||||||
|
{
|
||||||
|
this.centerLabel.setText(txt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getPercentage()
|
||||||
|
{
|
||||||
|
if (value == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (value * 100) / maximumValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.1 KiB |
Reference in New Issue
Block a user