diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerMouseListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerMouseListener.java index 611c4390a9..b62dc512d5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerMouseListener.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerMouseListener.java @@ -88,7 +88,8 @@ public class ScreenMarkerMouseListener extends MouseListener if (SwingUtilities.isLeftMouseButton(event) && plugin.isCreatingScreenMarker()) { - plugin.finishCreation(false); + /* Set the creation panel as "ready" (because the marker area as been drawn) */ + plugin.completeSelection(); } event.consume(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerOverlay.java index 10c65d8da0..b0321fd29a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerOverlay.java @@ -43,15 +43,10 @@ public class ScreenMarkerOverlay extends Overlay ScreenMarkerOverlay(ScreenMarker marker) { this.marker = marker; + this.screenMarkerRenderable = new ScreenMarkerRenderable(); setPosition(OverlayPosition.DETACHED); setLayer(OverlayLayer.ALWAYS_ON_TOP); setPriority(OverlayPriority.HIGH); - - screenMarkerRenderable = new ScreenMarkerRenderable(); - screenMarkerRenderable.setBorderThickness(marker.getBorderThickness()); - screenMarkerRenderable.setColor(marker.getColor()); - screenMarkerRenderable.setFill(marker.getFill()); - screenMarkerRenderable.setStroke(new BasicStroke(marker.getBorderThickness())); } @Override @@ -68,6 +63,10 @@ public class ScreenMarkerOverlay extends Overlay return null; } + screenMarkerRenderable.setBorderThickness(marker.getBorderThickness()); + screenMarkerRenderable.setColor(marker.getColor()); + screenMarkerRenderable.setFill(marker.getFill()); + screenMarkerRenderable.setStroke(new BasicStroke(marker.getBorderThickness())); screenMarkerRenderable.setPreferredSize(getPreferredSize()); return screenMarkerRenderable.render(graphics); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerPlugin.java index 2f5632adee..cc1b2803f3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerPlugin.java @@ -1,6 +1,7 @@ /* * Copyright (c) 2018, Kamiel, * Copyright (c) 2018, Adam + * Copyright (c) 2018, Psikoi * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,7 +27,6 @@ package net.runelite.client.plugins.screenmarkers; import com.google.common.base.Strings; -import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; @@ -67,8 +67,8 @@ public class ScreenMarkerPlugin extends Plugin private static final String DEFAULT_MARKER_NAME = "Marker"; private static final Dimension DEFAULT_SIZE = new Dimension(2, 2); - @Inject - private EventBus eventBus; + @Getter + private final List screenMarkers = new ArrayList<>(); @Inject private ConfigManager configManager; @@ -89,9 +89,6 @@ public class ScreenMarkerPlugin extends Plugin private ScreenMarkerPluginPanel pluginPanel; private NavigationButton navigationButton; - @Getter - private final List screenMarkers = new ArrayList<>(); - @Getter(AccessLevel.PACKAGE) private ScreenMarker currentMarker; @@ -125,6 +122,7 @@ public class ScreenMarkerPlugin extends Plugin navigationButton = NavigationButton.builder() .tooltip(PLUGIN_NAME) .icon(icon) + .priority(5) .panel(pluginPanel) .build(); @@ -189,9 +187,6 @@ public class ScreenMarkerPlugin extends Plugin { if (!aborted) { - setMouseListenerEnabled(false); - pluginPanel.setCreationEnabled(false); - final ScreenMarkerOverlay screenMarkerOverlay = new ScreenMarkerOverlay(currentMarker); screenMarkerOverlay.setPreferredLocation(overlay.getBounds().getLocation()); screenMarkerOverlay.setPreferredSize(overlay.getBounds().getSize()); @@ -205,6 +200,15 @@ public class ScreenMarkerPlugin extends Plugin creatingScreenMarker = false; currentMarker = null; + setMouseListenerEnabled(false); + + pluginPanel.setCreation(false); + } + + /* The marker area has been drawn, inform the user and unlock the confirm button */ + public void completeSelection() + { + pluginPanel.getCreationPanel().unlockConfirm(); } public void deleteMarker(final ScreenMarkerOverlay marker) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerCreationPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerCreationPanel.java new file mode 100644 index 0000000000..6385fa3163 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerCreationPanel.java @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2018, 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.screenmarkers.ui; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.GridLayout; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.IOException; +import javax.imageio.ImageIO; +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.border.EmptyBorder; +import net.runelite.client.plugins.screenmarkers.ScreenMarkerPlugin; +import net.runelite.client.ui.ColorScheme; +import net.runelite.client.ui.FontManager; +import net.runelite.client.ui.components.shadowlabel.JShadowedLabel; + +public class ScreenMarkerCreationPanel extends JPanel +{ + private static final ImageIcon CONFIRM_ICON; + private static final ImageIcon CONFIRM_HOVER_ICON; + private static final ImageIcon CONFIRM_LOCKED_ICON; + private static final ImageIcon CANCEL_ICON; + private static final ImageIcon CANCEL_HOVER_ICON; + + private final JShadowedLabel instructionsLabel = new JShadowedLabel(); + private final JLabel confirmLabel = new JLabel(); + private boolean lockedConfirm = true; + + static + { + try + { + synchronized (ImageIO.class) + { + CONFIRM_ICON = new ImageIcon(ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("confirm_icon.png"))); + CONFIRM_HOVER_ICON = new ImageIcon(ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("confirm_hover_icon.png"))); + CONFIRM_LOCKED_ICON = new ImageIcon(ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("confirm_locked_icon.png"))); + CANCEL_ICON = new ImageIcon(ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("cancel_icon.png"))); + CANCEL_HOVER_ICON = new ImageIcon(ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("cancel_hover_icon.png"))); + } + } + catch (IOException e) + { + throw new RuntimeException(e); + } + } + + ScreenMarkerCreationPanel(ScreenMarkerPlugin plugin) + { + setBackground(ColorScheme.DARKER_GRAY_COLOR); + setBorder(new EmptyBorder(8, 8, 8, 8)); + setLayout(new BorderLayout()); + + instructionsLabel.setFont(FontManager.getRunescapeSmallFont()); + instructionsLabel.setForeground(Color.WHITE); + + JPanel actionsContainer = new JPanel(new GridLayout(1, 2, 8, 0)); + actionsContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR); + + confirmLabel.setIcon(CONFIRM_LOCKED_ICON); + confirmLabel.setToolTipText("Confirm and save"); + confirmLabel.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent mouseEvent) + { + /* If the confirm button is not locked */ + if (!lockedConfirm) + { + plugin.finishCreation(false); + } + } + + @Override + public void mouseEntered(MouseEvent mouseEvent) + { + confirmLabel.setIcon(lockedConfirm ? CONFIRM_LOCKED_ICON : CONFIRM_HOVER_ICON); + } + + @Override + public void mouseExited(MouseEvent mouseEvent) + { + confirmLabel.setIcon(lockedConfirm ? CONFIRM_LOCKED_ICON : CONFIRM_ICON); + } + }); + + JLabel cancelLabel = new JLabel(CANCEL_ICON); + cancelLabel.setToolTipText("Cancel"); + cancelLabel.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent mouseEvent) + { + plugin.finishCreation(true); + } + + @Override + public void mouseEntered(MouseEvent mouseEvent) + { + cancelLabel.setIcon(CANCEL_HOVER_ICON); + } + + @Override + public void mouseExited(MouseEvent mouseEvent) + { + cancelLabel.setIcon(CANCEL_ICON); + } + }); + + actionsContainer.add(confirmLabel); + actionsContainer.add(cancelLabel); + + add(instructionsLabel, BorderLayout.CENTER); + add(actionsContainer, BorderLayout.EAST); + } + + /* Unlocks the confirm button */ + public void unlockConfirm() + { + this.confirmLabel.setIcon(CONFIRM_ICON); + this.lockedConfirm = false; + instructionsLabel.setText("Confirm or cancel to finish."); + } + + /* Locks the confirm button */ + public void lockConfirm() + { + this.confirmLabel.setIcon(CONFIRM_LOCKED_ICON); + this.lockedConfirm = true; + instructionsLabel.setText("Drag in-game to draw"); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java index 13b62aceae..5a297299a3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2018, Kamiel, + * Copyright (c) 2018, Psikoi * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,55 +25,395 @@ */ package net.runelite.client.plugins.screenmarkers.ui; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; import java.awt.FlowLayout; -import java.awt.GridLayout; -import javax.swing.JButton; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.image.BufferedImage; +import java.io.IOException; +import javax.imageio.ImageIO; +import javax.swing.ImageIcon; +import javax.swing.JColorChooser; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JOptionPane; import javax.swing.JPanel; -import javax.swing.JToggleButton; +import javax.swing.JSpinner; +import javax.swing.SpinnerModel; +import javax.swing.SpinnerNumberModel; +import javax.swing.border.EmptyBorder; +import javax.swing.border.MatteBorder; import net.runelite.client.plugins.screenmarkers.ScreenMarkerOverlay; import net.runelite.client.plugins.screenmarkers.ScreenMarkerPlugin; -import net.runelite.client.ui.components.shadowlabel.JShadowedLabel; +import net.runelite.client.ui.ColorScheme; +import net.runelite.client.util.SwingUtil; class ScreenMarkerPanel extends JPanel { - private static final String DELETE_TEXT = "Delete"; - private static final String HIDE_TEXT = "Hide"; - private static final String SHOW_TEXT = "Show"; + private static final int DEFAULT_FILL_OPACITY = 75; + + private static final ImageIcon BORDER_COLOR_ICON; + private static final ImageIcon BORDER_COLOR_HOVER_ICON; + private static final ImageIcon NO_BORDER_COLOR_ICON; + private static final ImageIcon NO_BORDER_COLOR_HOVER_ICON; + + private static final ImageIcon FILL_COLOR_ICON; + private static final ImageIcon FILL_COLOR_HOVER_ICON; + private static final ImageIcon NO_FILL_COLOR_ICON; + private static final ImageIcon NO_FILL_COLOR_HOVER_ICON; + + private static final ImageIcon FULL_OPACITY_ICON; + private static final ImageIcon OPACITY_HOVER_ICON; + private static final ImageIcon NO_OPACITY_ICON; + + private static final ImageIcon VISIBLE_ICON; + private static final ImageIcon VISIBLE_HOVER_ICON; + private static final ImageIcon INVISIBLE_ICON; + private static final ImageIcon INVISIBLE_HOVER_ICON; + + private static final ImageIcon DELETE_ICON; + private static final ImageIcon DELETE_HOVER_ICON; private final ScreenMarkerPlugin plugin; private final ScreenMarkerOverlay marker; - private JToggleButton visibleToggle; + + private final JLabel borderColorIndicator = new JLabel(); + private final JLabel fillColorIndicator = new JLabel(); + private final JLabel opacityIndicator = new JLabel(); + private final JLabel visibilityLabel = new JLabel(); + private final JLabel deleteLabel = new JLabel(); + + private final SpinnerModel spinnerModel = new SpinnerNumberModel(5, 0, Integer.MAX_VALUE, 1); + private final JSpinner thicknessSpinner = new JSpinner(spinnerModel); + + private boolean visible; + + static + { + try + { + synchronized (ImageIO.class) + { + BufferedImage borderImg = ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("border_color_icon.png")); + BORDER_COLOR_ICON = new ImageIcon(borderImg); + BORDER_COLOR_HOVER_ICON = new ImageIcon(SwingUtil.grayscaleOffset(borderImg, -100)); + + BufferedImage noBorderImg = ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("no_border_color_icon.png")); + NO_BORDER_COLOR_ICON = new ImageIcon(noBorderImg); + NO_BORDER_COLOR_HOVER_ICON = new ImageIcon(SwingUtil.grayscaleOffset(noBorderImg, -100)); + + BufferedImage fillImg = ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("fill_color_icon.png")); + FILL_COLOR_ICON = new ImageIcon(fillImg); + FILL_COLOR_HOVER_ICON = new ImageIcon(SwingUtil.grayscaleOffset(fillImg, -100)); + + BufferedImage noFillImg = ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("no_fill_color_icon.png")); + NO_FILL_COLOR_ICON = new ImageIcon(noFillImg); + NO_FILL_COLOR_HOVER_ICON = new ImageIcon(SwingUtil.grayscaleOffset(noFillImg, -100)); + + BufferedImage opacityImg = ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("opacity_icon.png")); + FULL_OPACITY_ICON = new ImageIcon(opacityImg); + OPACITY_HOVER_ICON = new ImageIcon(SwingUtil.grayscaleOffset(opacityImg, -100)); + NO_OPACITY_ICON = new ImageIcon(SwingUtil.grayscaleOffset(opacityImg, -150)); + + BufferedImage visibleImg = ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("visible_icon.png")); + VISIBLE_ICON = new ImageIcon(visibleImg); + VISIBLE_HOVER_ICON = new ImageIcon(SwingUtil.grayscaleOffset(visibleImg, -100)); + + BufferedImage invisibleImg = ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("invisible_icon.png")); + INVISIBLE_ICON = new ImageIcon(invisibleImg); + INVISIBLE_HOVER_ICON = new ImageIcon(SwingUtil.grayscaleOffset(invisibleImg, -100)); + + BufferedImage deleteImg = ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("delete_icon.png")); + DELETE_ICON = new ImageIcon(deleteImg); + DELETE_HOVER_ICON = new ImageIcon(SwingUtil.grayscaleOffset(deleteImg, -100)); + } + } + catch (IOException e) + { + throw new RuntimeException(e); + } + } ScreenMarkerPanel(ScreenMarkerPlugin plugin, ScreenMarkerOverlay marker) { this.plugin = plugin; this.marker = marker; - construct(); - } + this.visible = marker.getMarker().isVisible(); - private void construct() - { - setLayout(new GridLayout(0, 1, 0, 3)); - JPanel container = new JPanel(new FlowLayout()); + setLayout(new BorderLayout()); + setBackground(ColorScheme.DARKER_GRAY_COLOR); - JButton deleteButton = new JButton(DELETE_TEXT); - deleteButton.addActionListener(l -> plugin.deleteMarker(marker)); + JPanel bottomContainer = new JPanel(new BorderLayout()); + bottomContainer.setBorder(new EmptyBorder(8, 0, 8, 0)); + bottomContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR); - boolean selected = !marker.getMarker().isVisible(); - visibleToggle = new JToggleButton(selected ? SHOW_TEXT : HIDE_TEXT, selected); - visibleToggle.setFocusable(false); - visibleToggle.addActionListener(l -> + JPanel leftActions = new JPanel(new FlowLayout(FlowLayout.LEFT, 8, 0)); + leftActions.setBackground(ColorScheme.DARKER_GRAY_COLOR); + + borderColorIndicator.setToolTipText("Edit border color"); + borderColorIndicator.addMouseListener(new MouseAdapter() { - boolean visible = !visibleToggle.isSelected(); - marker.getMarker().setVisible(visible); - visibleToggle.setText(visible ? HIDE_TEXT : SHOW_TEXT); - plugin.updateConfig(); + @Override + public void mousePressed(MouseEvent mouseEvent) + { + openBorderColorPicker(); + } + + @Override + public void mouseEntered(MouseEvent mouseEvent) + { + borderColorIndicator.setIcon(marker.getMarker().getBorderThickness() == 0 ? NO_BORDER_COLOR_HOVER_ICON : BORDER_COLOR_HOVER_ICON); + } + + @Override + public void mouseExited(MouseEvent mouseEvent) + { + borderColorIndicator.setIcon(marker.getMarker().getBorderThickness() == 0 ? NO_BORDER_COLOR_ICON : BORDER_COLOR_ICON); + } }); - container.add(new JShadowedLabel(marker.getName())); - container.add(visibleToggle); - container.add(deleteButton); + fillColorIndicator.setToolTipText("Edit fill color"); + fillColorIndicator.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent mouseEvent) + { + openFillColorPicker(); + } - add(container); + @Override + public void mouseEntered(MouseEvent mouseEvent) + { + fillColorIndicator.setIcon(marker.getMarker().getFill().getAlpha() == 0 ? NO_FILL_COLOR_HOVER_ICON : FILL_COLOR_HOVER_ICON); + } + + @Override + public void mouseExited(MouseEvent mouseEvent) + { + fillColorIndicator.setIcon(marker.getMarker().getFill().getAlpha() == 0 ? NO_FILL_COLOR_ICON : FILL_COLOR_ICON); + } + }); + + thicknessSpinner.setValue(marker.getMarker().getBorderThickness()); + thicknessSpinner.setPreferredSize(new Dimension(50, 20)); + thicknessSpinner.addChangeListener(ce -> updateThickness(true)); + + opacityIndicator.setToolTipText("Toggle background transparency"); + opacityIndicator.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent mouseEvent) + { + final Color fill = marker.getMarker().getFill(); + + if (fill.getAlpha() == 0) + { + marker.getMarker().setFill(new Color(fill.getRed(), fill.getGreen(), fill.getBlue(), DEFAULT_FILL_OPACITY)); + } + else + { + marker.getMarker().setFill(new Color(fill.getRed(), fill.getGreen(), fill.getBlue(), 0)); + } + + updateFill(); + plugin.updateConfig(); + } + + @Override + public void mouseEntered(MouseEvent mouseEvent) + { + opacityIndicator.setIcon(OPACITY_HOVER_ICON); + } + + @Override + public void mouseExited(MouseEvent mouseEvent) + { + opacityIndicator.setIcon(marker.getMarker().getFill().getAlpha() == 0 ? NO_OPACITY_ICON : FULL_OPACITY_ICON); + } + }); + + leftActions.add(borderColorIndicator); + leftActions.add(fillColorIndicator); + leftActions.add(opacityIndicator); + leftActions.add(thicknessSpinner); + + JPanel rightActions = new JPanel(new FlowLayout(FlowLayout.RIGHT, 8, 0)); + rightActions.setBackground(ColorScheme.DARKER_GRAY_COLOR); + + visibilityLabel.setToolTipText(visible ? "Hide screen marker" : "Show screen marker"); + visibilityLabel.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent mouseEvent) + { + visible = !visible; + marker.getMarker().setVisible(visible); + plugin.updateConfig(); + updateVisibility(); + } + + @Override + public void mouseEntered(MouseEvent mouseEvent) + { + visibilityLabel.setIcon(visible ? VISIBLE_HOVER_ICON : INVISIBLE_HOVER_ICON); + } + + @Override + public void mouseExited(MouseEvent mouseEvent) + { + updateVisibility(); + } + }); + + deleteLabel.setIcon(DELETE_ICON); + deleteLabel.setToolTipText("Delete screen marker"); + deleteLabel.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent mouseEvent) + { + int confirm = JOptionPane.showConfirmDialog(null, + "Are you sure you want to permanenely delete this screen marker?", + "Warning", JOptionPane.OK_CANCEL_OPTION); + + if (confirm == 0) + { + plugin.deleteMarker(marker); + } + } + + @Override + public void mouseEntered(MouseEvent mouseEvent) + { + deleteLabel.setIcon(DELETE_HOVER_ICON); + } + + @Override + public void mouseExited(MouseEvent mouseEvent) + { + deleteLabel.setIcon(DELETE_ICON); + } + }); + + rightActions.add(visibilityLabel); + rightActions.add(deleteLabel); + + bottomContainer.add(leftActions, BorderLayout.WEST); + bottomContainer.add(rightActions, BorderLayout.EAST); + + add(bottomContainer, BorderLayout.CENTER); + + updateVisibility(); + updateFill(); + updateBorder(); + updateBorder(); + + } + + /* Updates the thickness without saving on config */ + private void updateThickness(boolean save) + { + marker.getMarker().setBorderThickness((Integer) thicknessSpinner.getValue()); + updateBorder(); + if (save) + { + plugin.updateConfig(); + } + } + + private void updateVisibility() + { + visibilityLabel.setIcon(visible ? VISIBLE_ICON : INVISIBLE_ICON); + } + + private void updateFill() + { + final boolean isFullyTransparent = marker.getMarker().getFill().getAlpha() == 0; + + if (isFullyTransparent) + { + fillColorIndicator.setBorder(null); + } + else + { + Color color = marker.getMarker().getFill(); + Color fullColor = new Color(color.getRed(), color.getGreen(), color.getBlue()); + fillColorIndicator.setBorder(new MatteBorder(0, 0, 3, 0, fullColor)); + } + + fillColorIndicator.setIcon(isFullyTransparent ? NO_FILL_COLOR_ICON : FILL_COLOR_ICON); + opacityIndicator.setIcon(isFullyTransparent ? NO_OPACITY_ICON : FULL_OPACITY_ICON); + } + + private void updateBorder() + { + if (marker.getMarker().getBorderThickness() == 0) + { + borderColorIndicator.setBorder(null); + } + else + { + Color color = marker.getMarker().getColor(); + borderColorIndicator.setBorder(new MatteBorder(0, 0, 3, 0, color)); + } + + borderColorIndicator.setIcon(marker.getMarker().getBorderThickness() == 0 ? NO_BORDER_COLOR_ICON : BORDER_COLOR_ICON); + } + + private void openFillColorPicker() + { + final JFrame parent = new JFrame(); + JColorChooser jColorChooser = new JColorChooser(marker.getMarker().getFill()); + + jColorChooser.getSelectionModel().addChangeListener(e1 -> + { + Color chosen = jColorChooser.getColor(); + marker.getMarker().setFill(new Color(chosen.getRed(), chosen.getGreen(), chosen.getBlue(), DEFAULT_FILL_OPACITY)); + updateFill(); + }); + + parent.addWindowListener(new WindowAdapter() + { + @Override + public void windowClosing(WindowEvent e) + { + plugin.updateConfig(); + } + }); + + parent.add(jColorChooser); + parent.pack(); + parent.setLocationRelativeTo(null); + parent.setVisible(true); + } + + private void openBorderColorPicker() + { + final JFrame parent = new JFrame(); + JColorChooser jColorChooser = new JColorChooser(marker.getMarker().getColor()); + + jColorChooser.getSelectionModel().addChangeListener(e1 -> + { + marker.getMarker().setColor(jColorChooser.getColor()); + updateBorder(); + }); + + parent.addWindowListener(new WindowAdapter() + { + @Override + public void windowClosing(WindowEvent e) + { + plugin.updateConfig(); + } + }); + + parent.add(jColorChooser); + parent.pack(); + parent.setLocationRelativeTo(null); + parent.setVisible(true); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPluginPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPluginPanel.java index eb844e3f4b..9dca4e8d11 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPluginPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPluginPanel.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2018, Kamiel, + * Copyright (c) 2018, Psikoi * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,84 +29,147 @@ import com.google.inject.Inject; import com.google.inject.Singleton; import java.awt.BorderLayout; import java.awt.Color; -import java.awt.Component; -import java.awt.GridLayout; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import javax.swing.JButton; -import javax.swing.JColorChooser; -import javax.swing.JFormattedTextField; -import javax.swing.JFrame; +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.IOException; +import javax.imageio.ImageIO; +import javax.swing.Box; +import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JPanel; -import javax.swing.JSpinner; -import javax.swing.SpinnerModel; -import javax.swing.SpinnerNumberModel; +import javax.swing.border.EmptyBorder; import lombok.Getter; import net.runelite.client.plugins.screenmarkers.ScreenMarkerOverlay; import net.runelite.client.plugins.screenmarkers.ScreenMarkerPlugin; +import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.PluginPanel; -import net.runelite.client.ui.components.shadowlabel.JShadowedLabel; +import net.runelite.client.ui.components.PluginErrorPanel; @Singleton public class ScreenMarkerPluginPanel extends PluginPanel { - private static final String TITLE = "Screen Markers"; - private static final Color DEFAULT_COLOR = Color.BLUE; - private static final int DEFAULT_BORDER_THICKNESS = 5; - private static final int DEFAULT_FILL_OPACITY = 75; - private static final String COLOR_PICKER_TITLE = "Choose a color.."; - private static final String COLOR_TEXT = "Color"; - private static final String FILL_TEXT = "Fill"; - private static final String NEW_TEXT = "New"; - private static final String CANCEL_TEXT = "Cancel"; - private static final Color CANCEL_BUTTON_COLOR = Color.RED.darker(); + private static final ImageIcon ADD_ICON; + private static final ImageIcon ADD_HOVER_ICON; + + private static final Color DEFAULT_BORDER_COLOR = Color.GREEN; + private static final Color DEFAULT_FILL_COLOR = new Color(0, 255, 0, 0); + + private static final int DEFAULT_BORDER_THICKNESS = 3; + + private final JLabel addMarker = new JLabel(ADD_ICON); + private final JLabel title = new JLabel(); + private final PluginErrorPanel noMarkersPanel = new PluginErrorPanel(); @Inject private ScreenMarkerPlugin plugin; - private JButton markerButton; + @Getter + private Color selectedColor = DEFAULT_BORDER_COLOR; @Getter - private Color selectedColor = DEFAULT_COLOR; - - @Getter - private Color selectedFillColor = new Color(DEFAULT_COLOR.getRed(), DEFAULT_COLOR.getGreen(), DEFAULT_COLOR.getBlue(), DEFAULT_FILL_OPACITY); + private Color selectedFillColor = DEFAULT_FILL_COLOR; @Getter private int selectedBorderThickness = DEFAULT_BORDER_THICKNESS; - private boolean creationEnabled = false; + @Getter + private ScreenMarkerCreationPanel creationPanel; + + static + { + try + { + synchronized (ImageIO.class) + { + ADD_ICON = new ImageIcon(ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("add_icon.png"))); + ADD_HOVER_ICON = new ImageIcon(ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("add_hover_icon.png"))); + } + } + catch (IOException e) + { + throw new RuntimeException(e); + } + } public void init() { setLayout(new BorderLayout()); - JPanel northPanel = new JPanel(new GridLayout(0, 2, 0, 3)); + setBorder(new EmptyBorder(10, 10, 10, 10)); - markerButton = new JButton(NEW_TEXT); - markerButton.setFocusable(false); - markerButton.addActionListener(l -> startOrCancelCreation()); + JPanel northPanel = new JPanel(new BorderLayout()); + northPanel.setBorder(new EmptyBorder(1, 0, 10, 0)); - northPanel.add(new JShadowedLabel(TITLE)); - northPanel.add(new JLabel()); - northPanel.add(new JShadowedLabel("Border size:")); - northPanel.add(createBorderThicknessSpinner()); - northPanel.add(new JShadowedLabel("Border color:")); - northPanel.add(createBorderColorButton()); - northPanel.add(new JShadowedLabel("Fill color:")); - northPanel.add(createFillColorButton()); + title.setText("Screen Markers"); + title.setForeground(Color.WHITE); - northPanel.add(markerButton); + northPanel.add(title, BorderLayout.WEST); + northPanel.add(addMarker, BorderLayout.EAST); - JPanel centerPanel = new JPanel(); - JPanel markerView = new JPanel(new GridLayout(0, 1, 0, 3)); + JPanel centerPanel = new JPanel(new BorderLayout()); + centerPanel.setBackground(ColorScheme.DARK_GRAY_COLOR); + + JPanel markerView = new JPanel(new GridBagLayout()); + markerView.setBackground(ColorScheme.DARK_GRAY_COLOR); + + GridBagConstraints constraints = new GridBagConstraints(); + constraints.fill = GridBagConstraints.HORIZONTAL; + constraints.weightx = 1; + constraints.gridx = 0; + constraints.gridy = 0; for (final ScreenMarkerOverlay marker : plugin.getScreenMarkers()) { - markerView.add(new ScreenMarkerPanel(plugin, marker)); + markerView.add(new ScreenMarkerPanel(plugin, marker), constraints); + constraints.gridy++; + + markerView.add(Box.createRigidArea(new Dimension(0, 10)), constraints); + constraints.gridy++; } - centerPanel.add(markerView, BorderLayout.NORTH); + noMarkersPanel.setContent("Screen Markers", "Highlight a region on your screen."); + noMarkersPanel.setVisible(false); + + if (plugin.getScreenMarkers().isEmpty()) + { + noMarkersPanel.setVisible(true); + title.setVisible(false); + } + + markerView.add(noMarkersPanel, constraints); + constraints.gridy++; + + creationPanel = new ScreenMarkerCreationPanel(plugin); + creationPanel.setVisible(false); + + markerView.add(creationPanel, constraints); + constraints.gridy++; + + addMarker.setToolTipText("Add new screen marker"); + addMarker.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent mouseEvent) + { + setCreation(true); + } + + @Override + public void mouseEntered(MouseEvent mouseEvent) + { + addMarker.setIcon(ADD_HOVER_ICON); + } + + @Override + public void mouseExited(MouseEvent mouseEvent) + { + addMarker.setIcon(ADD_ICON); + } + }); + + centerPanel.add(markerView, BorderLayout.CENTER); add(northPanel, BorderLayout.NORTH); add(centerPanel, BorderLayout.CENTER); @@ -119,93 +183,28 @@ public class ScreenMarkerPluginPanel extends PluginPanel init(); } - private void startOrCancelCreation() + /* Enables/Disables new marker creation mode */ + public void setCreation(boolean on) { - creationEnabled = !creationEnabled; - plugin.setMouseListenerEnabled(creationEnabled); - setMarkerButtonState(creationEnabled); - } - - public void setCreationEnabled(boolean creationEnabled) - { - this.creationEnabled = creationEnabled; - setMarkerButtonState(creationEnabled); - } - - private void setMarkerButtonState(boolean selected) - { - markerButton.setSelected(selected); - markerButton.setText(selected ? CANCEL_TEXT : NEW_TEXT); - markerButton.setBackground(selected ? CANCEL_BUTTON_COLOR : null); - } - - private JSpinner createBorderThicknessSpinner() - { - SpinnerModel model = new SpinnerNumberModel(selectedBorderThickness, 0, Integer.MAX_VALUE, 1); - JSpinner spinner = new JSpinner(model); - Component editor = spinner.getEditor(); - JFormattedTextField spinnerTextField = ((JSpinner.DefaultEditor) editor).getTextField(); - spinnerTextField.setColumns(5); - spinner.addChangeListener(ce -> selectedBorderThickness = (Integer) spinner.getValue()); - return spinner; - } - - private JButton createBorderColorButton() - { - JButton colorPicker = new JButton(COLOR_TEXT); - colorPicker.setFocusable(false); - colorPicker.setBackground(selectedColor); - colorPicker.addActionListener(e -> + if (on) { - final JFrame parent = new JFrame(COLOR_PICKER_TITLE); - JColorChooser jColorChooser = new JColorChooser(selectedColor); - jColorChooser.getSelectionModel().addChangeListener(e1 -> colorPicker.setBackground(jColorChooser.getColor())); - - parent.addWindowListener(new WindowAdapter() - { - @Override - public void windowClosing(WindowEvent e) - { - selectedColor = jColorChooser.getColor(); - } - }); - - parent.add(jColorChooser); - parent.pack(); - parent.setLocationRelativeTo(null); - parent.setVisible(true); - }); - - return colorPicker; - } - - private JButton createFillColorButton() - { - JButton colorPicker = new JButton(FILL_TEXT); - colorPicker.setFocusable(false); - colorPicker.setBackground(selectedFillColor); - colorPicker.addActionListener(e -> + noMarkersPanel.setVisible(false); + title.setVisible(true); + } + else { - final JFrame parent = new JFrame(COLOR_PICKER_TITLE); - JColorChooser jColorChooser = new JColorChooser(selectedFillColor); - jColorChooser.getSelectionModel().addChangeListener(e1 -> colorPicker.setBackground(jColorChooser.getColor())); + boolean empty = plugin.getScreenMarkers().isEmpty(); + noMarkersPanel.setVisible(empty); + title.setVisible(!empty); + } - parent.addWindowListener(new WindowAdapter() - { - @Override - public void windowClosing(WindowEvent e) - { - Color color = jColorChooser.getColor(); - selectedFillColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), DEFAULT_FILL_OPACITY); - } - }); + creationPanel.setVisible(on); + addMarker.setVisible(!on); - parent.add(jColorChooser); - parent.pack(); - parent.setLocationRelativeTo(null); - parent.setVisible(true); - }); - - return colorPicker; + if (on) + { + creationPanel.lockConfirm(); + plugin.setMouseListenerEnabled(true); + } } } diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/add_hover_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/add_hover_icon.png new file mode 100644 index 0000000000..9eb7fe3baa Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/add_hover_icon.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/add_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/add_icon.png new file mode 100644 index 0000000000..b6e47f792f Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/add_icon.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/border_color_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/border_color_icon.png new file mode 100644 index 0000000000..4cfc549d35 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/border_color_icon.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/cancel_hover_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/cancel_hover_icon.png new file mode 100644 index 0000000000..d1ddc4ef67 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/cancel_hover_icon.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/cancel_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/cancel_icon.png new file mode 100644 index 0000000000..ff07283662 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/cancel_icon.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/confirm_hover_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/confirm_hover_icon.png new file mode 100644 index 0000000000..e5b7199658 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/confirm_hover_icon.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/confirm_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/confirm_icon.png new file mode 100644 index 0000000000..976540916e Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/confirm_icon.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/confirm_locked_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/confirm_locked_icon.png new file mode 100644 index 0000000000..d6300bc3e9 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/confirm_locked_icon.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/delete_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/delete_icon.png new file mode 100644 index 0000000000..5240ab13a4 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/delete_icon.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/fill_color_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/fill_color_icon.png new file mode 100644 index 0000000000..5c209a576a Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/fill_color_icon.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/invisible_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/invisible_icon.png new file mode 100644 index 0000000000..c67cf93ded Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/invisible_icon.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/no_border_color_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/no_border_color_icon.png new file mode 100644 index 0000000000..deeebaf3f7 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/no_border_color_icon.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/no_fill_color_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/no_fill_color_icon.png new file mode 100644 index 0000000000..2e2fda5d16 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/no_fill_color_icon.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/opacity_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/opacity_icon.png new file mode 100644 index 0000000000..12c76765f2 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/opacity_icon.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/visible_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/visible_icon.png new file mode 100644 index 0000000000..68b74af697 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/visible_icon.png differ