From 46531f7665bcd02d22594c144eb6e4f59f4c7fdb Mon Sep 17 00:00:00 2001 From: Ron Young Date: Sat, 23 Feb 2019 16:51:33 -0600 Subject: [PATCH] RuneliteColorPicker: add support for recent colors --- .../components/colorpicker/RecentColors.java | 133 ++++++++++++++++++ .../colorpicker/RuneliteColorPicker.java | 29 +++- 2 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/ui/components/colorpicker/RecentColors.java diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/colorpicker/RecentColors.java b/runelite-client/src/main/java/net/runelite/client/ui/components/colorpicker/RecentColors.java new file mode 100644 index 0000000000..fcb69a3198 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/colorpicker/RecentColors.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2019, Ron Young + * 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.colorpicker; + +import com.google.common.collect.EvictingQueue; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.function.Consumer; +import javax.swing.JPanel; +import net.runelite.client.config.ConfigManager; +import static net.runelite.client.ui.components.colorpicker.RuneliteColorPicker.CONFIG_GROUP; +import net.runelite.client.util.ColorUtil; +import net.runelite.client.util.Text; + +final class RecentColors +{ + private static final String CONFIG_KEY = "recentColors"; + private static final int MAX = 16; + private static final int BOX_SIZE = 16; + + private final EvictingQueue recentColors = EvictingQueue.create(MAX); + private final ConfigManager configManager; + + RecentColors(final ConfigManager configManager) + { + this.configManager = configManager; + } + + private void load() + { + String str = configManager.getConfiguration(CONFIG_GROUP, CONFIG_KEY); + if (str != null) + { + recentColors.addAll(Text.fromCSV(str)); + } + } + + void add(final String color) + { + if (ColorUtil.fromString(color) == null) + { + return; + } + + recentColors.remove(color); + recentColors.add(color); + + configManager.setConfiguration(CONFIG_GROUP, CONFIG_KEY, Text.toCSV(recentColors)); + } + + JPanel build(final Consumer consumer, final boolean alphaHidden) + { + load(); + + JPanel container = new JPanel(new GridBagLayout()); + + GridBagConstraints cx = new GridBagConstraints(); + cx.insets = new Insets(0, 1, 4, 2); + cx.gridy = 0; + cx.gridx = 0; + cx.anchor = GridBagConstraints.WEST; + + for (String s : recentColors) + { + if (cx.gridx == MAX / 2) + { + cx.gridy++; + cx.gridx = 0; + } + + // Make sure the last element stays in line with all of the others + if (container.getComponentCount() == recentColors.size() - 1) + { + cx.weightx = 1; + cx.gridwidth = MAX / 2 - cx.gridx; + } + + container.add(createBox(ColorUtil.fromString(s), consumer, alphaHidden), cx); + cx.gridx++; + } + + return container; + } + + private static JPanel createBox(final Color color, final Consumer consumer, final boolean alphaHidden) + { + final JPanel box = new JPanel(); + String hex = alphaHidden ? ColorUtil.colorToHexCode(color) : ColorUtil.colorToAlphaHexCode(color); + + box.setBackground(color); + box.setOpaque(true); + box.setPreferredSize(new Dimension(BOX_SIZE, BOX_SIZE)); + box.setToolTipText("#" + hex.toUpperCase()); + box.addMouseListener(new MouseAdapter() + { + @Override + public void mouseClicked(MouseEvent e) + { + consumer.accept(color); + } + }); + + return box; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/colorpicker/RuneliteColorPicker.java b/runelite-client/src/main/java/net/runelite/client/ui/components/colorpicker/RuneliteColorPicker.java index b7b5b0de21..653d31ecf8 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/components/colorpicker/RuneliteColorPicker.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/colorpicker/RuneliteColorPicker.java @@ -63,6 +63,8 @@ import org.pushingpixels.substance.internal.SubstanceSynapse; public class RuneliteColorPicker extends JDialog { + static final String CONFIG_GROUP = "colorpicker"; + private final static int FRAME_WIDTH = 400; private final static int FRAME_HEIGHT = 380; private final static int TONE_PANEL_SIZE = 160; @@ -97,6 +99,9 @@ public class RuneliteColorPicker extends JDialog super(parent, "RuneLite Color Picker - " + title, ModalityType.MODELESS); this.selectedColor = previousColor; + this.alphaHidden = alphaHidden; + + RecentColors recentColors = new RecentColors(configManager); setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); setResizable(false); @@ -118,7 +123,6 @@ public class RuneliteColorPicker extends JDialog rightPanel.setLayout(new GridBagLayout()); GridBagConstraints cx = new GridBagConstraints(); - cx.insets = new Insets(0, 0, 0, 0); JLabel old = new JLabel("Previous"); old.setHorizontalAlignment(JLabel.CENTER); @@ -149,11 +153,26 @@ public class RuneliteColorPicker extends JDialog hexContainer.add(hexInput, cx); cx.fill = GridBagConstraints.BOTH; - cx.gridwidth = GridBagConstraints.RELATIVE; cx.weightx = 1; cx.weighty = 1; cx.gridy = 0; cx.gridx = 0; + + JPanel recentColorsContainer = recentColors.build(c -> + { + if (!alphaHidden) + { + alphaSlider.update(c.getAlpha()); + } + + colorChange(c); + updatePanels(); + }, alphaHidden); + + rightPanel.add(recentColorsContainer, cx); + + cx.gridwidth = GridBagConstraints.RELATIVE; + cx.gridy++; rightPanel.add(old, cx); cx.gridx++; @@ -185,7 +204,6 @@ public class RuneliteColorPicker extends JDialog slidersContainer.add(blueSlider); slidersContainer.add(alphaSlider); - this.alphaHidden = alphaHidden; if (alphaHidden) { alphaSlider.setVisible(false); @@ -285,6 +303,11 @@ public class RuneliteColorPicker extends JDialog onClose.accept(selectedColor); } + if (!Objects.equals(previousColor, selectedColor)) + { + recentColors.add(selectedColor.getRGB() + ""); + } + RuneliteColorPicker cp = colorPickerManager.getCurrentPicker(); if (Objects.equals(cp, RuneliteColorPicker.this)) {