From 22c376e4bdc5d10bb9df0dbffe149677b52405f7 Mon Sep 17 00:00:00 2001 From: rbbi <31489752+rbbi@users.noreply.github.com> Date: Tue, 18 Sep 2018 06:57:32 +0100 Subject: [PATCH] Change skill calc checkboxes to radio buttons (#4373) Fixes #2935 --- .../skillcalculator/BonusCheckBox.java | 38 ++++++++ .../skillcalculator/SkillCalculator.java | 89 +++++++++++++++---- 2 files changed, 109 insertions(+), 18 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/BonusCheckBox.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/BonusCheckBox.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/BonusCheckBox.java new file mode 100644 index 0000000000..6402cee7ea --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/BonusCheckBox.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018, Robbie McLeod + * 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.skillcalculator; + +import javax.swing.JCheckBox; +import lombok.Getter; +import lombok.Setter; +import net.runelite.client.plugins.skillcalculator.beans.SkillDataBonus; + +class BonusCheckBox extends JCheckBox +{ + @Getter + @Setter + private SkillDataBonus bonus; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculator.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculator.java index ad9560ae78..bb910164df 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculator.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculator.java @@ -67,6 +67,7 @@ class SkillCalculator extends JPanel private UICombinedActionSlot combinedActionSlot = new UICombinedActionSlot(); private ArrayList combinedActionSlots = new ArrayList<>(); + private final List bonusCheckBoxes = new ArrayList<>(); private int currentLevel = 1; private int currentXP = Experience.getXpForLevel(currentLevel); @@ -151,10 +152,15 @@ class SkillCalculator extends JPanel double xp = 0; for (UIActionSlot slot : combinedActionSlots) + { xp += slot.getValue(); + } if (neededXP > 0) + { + assert xp != 0; actionCount = (int) Math.ceil(neededXP / xp); + } combinedActionSlot.setText(formatXPActionString(xp, actionCount, "exp - ")); } @@ -162,7 +168,9 @@ class SkillCalculator extends JPanel private void clearCombinedSlots() { for (UIActionSlot slot : combinedActionSlots) + { slot.setSelected(false); + } combinedActionSlots.clear(); } @@ -173,29 +181,66 @@ class SkillCalculator extends JPanel { for (SkillDataBonus bonus : skillData.getBonuses()) { - JPanel uiOption = new JPanel(new BorderLayout()); - JLabel uiLabel = new JLabel(bonus.getName()); - JCheckBox uiCheckbox = new JCheckBox(); + JPanel checkboxPanel = buildCheckboxPanel(bonus); - 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.getValue())); - uiCheckbox.setBackground(ColorScheme.MEDIUM_GRAY_COLOR); - - uiOption.add(uiLabel, BorderLayout.WEST); - uiOption.add(uiCheckbox, BorderLayout.EAST); - - add(uiOption); + add(checkboxPanel); add(Box.createRigidArea(new Dimension(0, 5))); } } } + private JPanel buildCheckboxPanel(SkillDataBonus bonus) + { + JPanel uiOption = new JPanel(new BorderLayout()); + JLabel uiLabel = new JLabel(bonus.getName()); + BonusCheckBox uiCheckbox = new BonusCheckBox(); + + 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(event -> adjustCheckboxes(uiCheckbox)); + + uiCheckbox.setBackground(ColorScheme.MEDIUM_GRAY_COLOR); + + uiOption.add(uiLabel, BorderLayout.WEST); + uiOption.add(uiCheckbox, BorderLayout.EAST); + + uiCheckbox.setBonus(bonus); + bonusCheckBoxes.add(uiCheckbox); + + return uiOption; + } + + private void adjustCheckboxes(BonusCheckBox target) + { + adjustAllExcept(target); + adjustXPBonus(target.isSelected(), target.getBonus().getValue()); + } + + /** + * Adjusts and deselects all other checkboxes + * contained within {@link SkillCalculator#bonusCheckBoxes} + * except the checkbox provided as the parameter + * + * @param except The checkbox to keep unchanged + */ + private void adjustAllExcept(JCheckBox except) + { + bonusCheckBoxes.stream() + .filter(checkbox -> checkbox != except) + .filter(JCheckBox::isSelected) + .forEach(otherSelectedCheckbox -> + { + otherSelectedCheckbox.setSelected(false); + adjustXPBonus(false, + otherSelectedCheckbox.getBonus().getValue()); + }); + } + private void renderActionSlots() { // Wipe the list of references to the slot components. @@ -214,12 +259,18 @@ class SkillCalculator extends JPanel public void mousePressed(MouseEvent e) { if (!e.isShiftDown()) + { clearCombinedSlots(); + } if (slot.isSelected()) + { combinedActionSlots.remove(slot); + } else + { combinedActionSlots.add(slot); + } slot.setSelected(!slot.isSelected()); updateCombinedAction(); @@ -242,7 +293,9 @@ class SkillCalculator extends JPanel double xp = (action.isIgnoreBonus()) ? action.getXp() : action.getXp() * xpFactor; if (neededXP > 0) + { actionCount = (int) Math.ceil(neededXP / xp); + } slot.setText("Lvl. " + action.getLevel() + " (" + formatXPActionString(xp, actionCount, "exp) - ")); slot.setAvailable(currentLevel >= action.getLevel()); @@ -316,4 +369,4 @@ class SkillCalculator extends JPanel { return Math.min(MAX_XP, Math.max(0, input)); } -} \ No newline at end of file +}