Skip to content

Commit

Permalink
Skill Calc plugin redesign
Browse files Browse the repository at this point in the history
Following the obsidian redesign update, this time I've ventured into
the skilling calculators. Major changes were made, here are the most
noticeable:

- Added a title to the top of the plugin panel
- Resized the skilling selectors to a 3x6 grid and used the MaterialTabs
for the selection behavior.
- Resized, recolored and reshaped the input panels and respective labels
to better fit the new theme and aesthetic.
- Added a new action "on enter", the textfield will now request focus
on the next logical textfield, (example, when enter is pressed on the
current level field, it will request focus on the target level)
- Reworded the input labels from "XP" to "Experience"
- Resized, recolored and reshaped the boost/modifier selectors
- Recolored the actions/selections indicator to a dark gray
- Recolored all item panels to a dark gray, and instead added a left
side thick border to indicate availability (green/red)
- Added required level indicator on the sub-title of each item
- Added hover effects for the individual items
- Added hover effects for the material tabs
  • Loading branch information
psikoi committed May 22, 2018
1 parent 84213d1 commit 566439e
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 118 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018, Kruithne <[email protected]>
* Copyright (c) 2018, Psikoi <https://github.com/psikoi>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand All @@ -25,13 +26,16 @@
package net.runelite.client.plugins.skillcalculator;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
Expand All @@ -43,6 +47,8 @@
import net.runelite.client.plugins.skillcalculator.beans.SkillData;
import net.runelite.client.plugins.skillcalculator.beans.SkillDataBonus;
import net.runelite.client.plugins.skillcalculator.beans.SkillDataEntry;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.FontManager;

class SkillCalculator extends JPanel
{
Expand Down Expand Up @@ -75,11 +81,20 @@ class SkillCalculator extends JPanel
this.uiInput = uiInput;

setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
setBorder(BorderFactory.createLineBorder(getBackground().brighter()));

// Register listeners on the input fields..
uiInput.uiFieldCurrentLevel.addActionListener(e -> onFieldCurrentLevelUpdated());
uiInput.uiFieldCurrentXP.addActionListener(e -> onFieldCurrentXPUpdated());
// Register listeners on the input fields and then move on to the next related text field
uiInput.uiFieldCurrentLevel.addActionListener(e ->
{
onFieldCurrentLevelUpdated();
uiInput.uiFieldTargetLevel.requestFocusInWindow();
});

uiInput.uiFieldCurrentXP.addActionListener(e ->
{
onFieldCurrentXPUpdated();
uiInput.uiFieldTargetXP.requestFocusInWindow();
});

uiInput.uiFieldTargetLevel.addActionListener(e -> onFieldTargetLevelUpdated());
uiInput.uiFieldTargetXP.addActionListener(e -> onFieldTargetXPUpdated());
}
Expand Down Expand Up @@ -110,6 +125,8 @@ void openCalculator(CalculatorType calculatorType)
// Create action slots for the skill actions.
renderActionSlots();

add(Box.createRigidArea(new Dimension(0, 15)));

// Update the input fields.
updateInputFields();
}
Expand Down Expand Up @@ -142,7 +159,7 @@ else if (size == 1)
if (neededXP > 0)
actionCount = (int) Math.ceil(neededXP / xp);

combinedActionSlot.setText(formatXPActionString(xp, actionCount));
combinedActionSlot.setText(formatXPActionString(xp, actionCount, "exp - "));
}

private void clearCombinedSlots()
Expand All @@ -163,15 +180,21 @@ private void renderBonusOptions()
JLabel uiLabel = new JLabel(bonus.name);
JCheckBox uiCheckbox = new JCheckBox();

// Adding an empty 8-pixel border on the left gives us nice padding.
uiOption.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0));
uiLabel.setForeground(Color.WHITE);
uiLabel.setFont(FontManager.getRunescapeSmallFont());

uiOption.setBorder(BorderFactory.createEmptyBorder(3, 7, 3, 0));
uiOption.setBackground(ColorScheme.DARKER_GRAY_COLOR);

// Adjust XP bonus depending on check-state of the boxes.
uiCheckbox.addActionListener(e -> adjustXPBonus(uiCheckbox.isSelected(), bonus.value));
uiCheckbox.setBackground(ColorScheme.MEDIUM_GRAY_COLOR);

uiOption.add(uiLabel, BorderLayout.WEST);
uiOption.add(uiCheckbox, BorderLayout.EAST);

add(uiOption);
add(Box.createRigidArea(new Dimension(0, 5)));
}
}
}
Expand All @@ -186,6 +209,8 @@ private void renderActionSlots()
{
UIActionSlot slot = new UIActionSlot(action);
uiActionSlots.add(slot); // Keep our own reference.

add(Box.createRigidArea(new Dimension(0, 5)));
add(slot); // Add component to the panel.

slot.addMouseListener(new MouseAdapter()
Expand Down Expand Up @@ -223,15 +248,15 @@ private void calculate()
if (neededXP > 0)
actionCount = (int) Math.ceil(neededXP / xp);

slot.setText(formatXPActionString(xp, actionCount));
slot.setText("Lvl. " + slot.action.level + " (" + formatXPActionString(xp, actionCount, "exp) - "));
slot.setAvailable(currentLevel >= slot.action.level);
slot.value = xp;
}
}

private String formatXPActionString(double xp, int actionCount)
private String formatXPActionString(double xp, int actionCount, String expExpression)
{
return XP_FORMAT.format(xp) + "xp - " + NumberFormat.getIntegerInstance().format(actionCount) + (actionCount > 1 ? " actions" : " action");
return XP_FORMAT.format(xp) + expExpression + NumberFormat.getIntegerInstance().format(actionCount) + (actionCount > 1 ? " actions" : " action");
}

private void updateInputFields()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018, Kruithne <[email protected]>
* Copyright (c) 2018, Psikoi <https://github.com/psikoi>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand All @@ -25,96 +26,108 @@

package net.runelite.client.plugins.skillcalculator;

import java.awt.Dimension;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import net.runelite.api.Client;
import net.runelite.client.game.SkillIconManager;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.PluginPanel;
import net.runelite.client.ui.components.materialtabs.MaterialTab;
import net.runelite.client.ui.components.materialtabs.MaterialTabGroup;

class SkillCalculatorPanel extends PluginPanel
{
private JButton activeButton;
private int uiButtonIndex = 0;
private final SkillCalculator uiCalculator;
private final SkillIconManager iconManager;
private final JPanel uiButtonGrid = new JPanel();
private final GridBagLayout uiButtonGridLayout = new GridBagLayout();
private final GridBagConstraints uiButtonGridConstraints = new GridBagConstraints();
private final MaterialTabGroup tabGroup;

private final MouseListener tabHoverListener;

SkillCalculatorPanel(SkillIconManager iconManager, Client client)
{
super();
getScrollPane().setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

tabHoverListener = new MouseAdapter()
{
@Override
public void mouseEntered(MouseEvent e)
{
MaterialTab tab = (MaterialTab) e.getSource();
tab.setBackground(ColorScheme.DARKER_GRAY_HOVER_COLOR);
}

@Override
public void mouseExited(MouseEvent e)
{
MaterialTab tab = (MaterialTab) e.getSource();
tab.setBackground(ColorScheme.DARKER_GRAY_COLOR);
}
};

this.iconManager = iconManager;

BoxLayout layout = new BoxLayout(this, BoxLayout.Y_AXIS);
setLayout(layout);
setBorder(new EmptyBorder(10, 10, 0, 10));
setLayout(new GridBagLayout());

uiButtonGridConstraints.fill = GridBagConstraints.BOTH;
uiButtonGridConstraints.weightx = 1;
uiButtonGridConstraints.ipady = 12;
uiButtonGridConstraints.insets = new Insets(2, 2, 2, 2);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
c.gridx = 0;
c.gridy = 0;

tabGroup = new MaterialTabGroup();
tabGroup.setLayout(new GridLayout(0, 6, 7, 7));

uiButtonGrid.setLayout(uiButtonGridLayout);
uiButtonGrid.setBackground(ColorScheme.DARK_GRAY_COLOR);
uiButtonGrid.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
addCalculatorButtons();

final UICalculatorInputArea uiInput = new UICalculatorInputArea();
uiInput.setBorder(new EmptyBorder(15, 0, 15, 0));
uiInput.setBackground(ColorScheme.DARK_GRAY_COLOR);

uiCalculator = new SkillCalculator(client, uiInput);

add(uiButtonGrid);
add(Box.createRigidArea(new Dimension(0, 8)));
add(uiInput);
add(Box.createRigidArea(new Dimension(0, 14)));
add(uiCalculator);
JLabel title = new JLabel("Skilling Calculator");
title.setBorder(new EmptyBorder(0, 1, 8, 0));
title.setForeground(Color.WHITE);

add(title, c);
c.gridy++;

add(tabGroup, c);
c.gridy++;

add(uiInput, c);
c.gridy++;

add(uiCalculator, c);
c.gridy++;
}

private void addCalculatorButtons()
{
for (CalculatorType calculatorType : CalculatorType.values())
{
final JButton uiButton = new JButton();
final BufferedImage icon = iconManager.getSkillImage(calculatorType.getSkill());
uiButton.addActionListener(e -> openCalculator(calculatorType, uiButton));

uiButton.setIcon(new ImageIcon(icon));
uiButton.setToolTipText(calculatorType.getSkill().getName());
uiButton.setFocusPainted(false);

uiButtonGridConstraints.gridx = uiButtonIndex % 4;
uiButtonGridLayout.setConstraints(uiButton, uiButtonGridConstraints);
uiButtonGrid.add(uiButton);
uiButtonIndex++;
MaterialTab tab = new MaterialTab("", tabGroup, null);
tab.setOpaque(true);
tab.setVerticalAlignment(SwingConstants.CENTER);
tab.setHorizontalAlignment(SwingConstants.CENTER);
tab.setBackground(ColorScheme.DARKER_GRAY_COLOR);
tab.setIcon(new ImageIcon(iconManager.getSkillImage(calculatorType.getSkill(), true)));
tab.setOnSelectEvent(() -> uiCalculator.openCalculator(calculatorType));
tab.addMouseListener(tabHoverListener);

tabGroup.addTab(tab);
}
}

private void openCalculator(CalculatorType calculatorType, JButton button)
{
// Remove highlight from existing button..
if (activeButton != null)
activeButton.setSelected(false);

// Set the new button as selected..
button.setSelected(true);
activeButton = button;

// Invoke the calculator component..
uiCalculator.openCalculator(calculatorType);

// Refresh rendering..
revalidate();
repaint();
}
}
Loading

0 comments on commit 566439e

Please sign in to comment.