From be26c55db7cc312451cf11e629ca1f4aaa60981f Mon Sep 17 00:00:00 2001 From: Adam Keenan Date: Fri, 2 Jun 2023 21:09:10 -0400 Subject: [PATCH] feat: Clone and drag to reorder --- .../runelite/watchdog/AlertManager.java | 20 ++++-- .../runelite/watchdog/WatchdogPanel.java | 29 +++++--- .../runelite/watchdog/alerts/Alert.java | 5 ++ .../runelite/watchdog/ui/AlertListItem.java | 68 +++++++++++------- .../runelite/watchdog/ui/UpDownArrows.java | 51 ------------- .../panels/MessageNotificationPanel.java | 2 +- .../panels/NotificationPanel.java | 39 ++++------ .../panels/OverheadNotificationPanel.java | 2 +- .../panels/OverlayNotificationPanel.java | 2 +- .../panels/ScreenFlashNotificationPanel.java | 2 +- .../panels/SoundEffectNotificationPanel.java | 2 +- .../panels/SoundNotificationPanel.java | 2 +- .../panels/TextToSpeechNotificationPanel.java | 2 +- .../watchdog/ui/panels/AlertPanel.java | 3 +- .../ui/panels/NotificationsPanel.java | 50 ++++++++----- .../watchdog/ui/panels/PanelUtils.java | 5 ++ .../runelite/watchdog/delete_icon.png | Bin 300 -> 0 bytes .../runelite/watchdog/mdi_drag-vertical.png | Bin 0 -> 185 bytes .../runelite/watchdog/mdi_import.png | Bin 0 -> 215 bytes .../runelite/watchdog/version.properties | 8 +-- 20 files changed, 147 insertions(+), 145 deletions(-) delete mode 100644 src/main/java/com/adamk33n3r/runelite/watchdog/ui/UpDownArrows.java delete mode 100644 src/main/resources/com/adamk33n3r/runelite/watchdog/delete_icon.png create mode 100644 src/main/resources/com/adamk33n3r/runelite/watchdog/mdi_drag-vertical.png create mode 100644 src/main/resources/com/adamk33n3r/runelite/watchdog/mdi_import.png diff --git a/src/main/java/com/adamk33n3r/runelite/watchdog/AlertManager.java b/src/main/java/com/adamk33n3r/runelite/watchdog/AlertManager.java index f4722c1..4210920 100644 --- a/src/main/java/com/adamk33n3r/runelite/watchdog/AlertManager.java +++ b/src/main/java/com/adamk33n3r/runelite/watchdog/AlertManager.java @@ -45,9 +45,11 @@ public class AlertManager { @Named("watchdog.pluginVersion") private String pluginVersion; - private static final Type ALERT_LIST_TYPE; + public static final Type ALERT_TYPE; + public static final Type ALERT_LIST_TYPE; static { + ALERT_TYPE = new TypeToken() {}.getType(); ALERT_LIST_TYPE = new TypeToken>() {}.getType(); } @@ -97,6 +99,19 @@ public void removeAlert(Alert alert) { SwingUtilities.invokeLater(this.watchdogPanel::rebuild); } + public void cloneAlert(Alert alert) { + String json = this.gson.toJson(alert, ALERT_TYPE); + Alert clonedAlert = this.gson.fromJson(json, ALERT_TYPE); + clonedAlert.setName(clonedAlert.getName() + " Clone"); + this.addAlert(clonedAlert); + } + + public void moveAlertTo(Alert alert, int pos) { + this.alerts.remove(alert); + this.alerts.add(pos, alert); + this.saveAlerts(); + } + public void moveAlertToTop(Alert alert) { this.alerts.remove(alert); this.alerts.add(0, alert); @@ -135,8 +150,6 @@ public void moveAlertDown(Alert alert) { this.saveAlerts(); } - public void moveNotificationUp(Alert alert, Notification notification) {} - public void loadAlerts() { final String json = this.configManager.getConfiguration(WatchdogConfig.CONFIG_GROUP_NAME, WatchdogConfig.ALERTS); this.importAlerts(json, false, false); @@ -243,5 +256,4 @@ private void handleUpgrades() { this.saveAlerts(); } } - } diff --git a/src/main/java/com/adamk33n3r/runelite/watchdog/WatchdogPanel.java b/src/main/java/com/adamk33n3r/runelite/watchdog/WatchdogPanel.java index ba3fa90..3cd90ec 100644 --- a/src/main/java/com/adamk33n3r/runelite/watchdog/WatchdogPanel.java +++ b/src/main/java/com/adamk33n3r/runelite/watchdog/WatchdogPanel.java @@ -12,9 +12,9 @@ import net.runelite.client.plugins.config.ConfigPlugin; import net.runelite.client.plugins.info.InfoPanel; import net.runelite.client.plugins.timetracking.TimeTrackingPlugin; -import net.runelite.client.ui.DynamicGridLayout; import net.runelite.client.ui.MultiplexingPluginPanel; import net.runelite.client.ui.PluginPanel; +import net.runelite.client.ui.components.DragAndDropReorderPane; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.LinkBrowser; @@ -29,10 +29,10 @@ import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JMenuItem; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; +import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.border.EmptyBorder; import java.awt.BorderLayout; @@ -44,8 +44,6 @@ import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.util.Arrays; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; @Slf4j public class WatchdogPanel extends PluginPanel { @@ -90,6 +88,8 @@ public class WatchdogPanel extends PluginPanel { public static final ImageIcon KOFI_ICON_HOVER; public static final ImageIcon CONFIG_ICON; public static final ImageIcon CONFIG_ICON_HOVER; + public static final ImageIcon EXPORT_ICON = new ImageIcon(ImageUtil.loadImageResource(ConfigPlugin.class, "mdi_export.png")); + public static final ImageIcon IMPORT_ICON = new ImageIcon(ImageUtil.loadImageResource(WatchdogPanel.class, "mdi_import.png")); static { final BufferedImage addIcon = ImageUtil.loadImageResource(TimeTrackingPlugin.class, "add_icon.png"); @@ -185,23 +185,32 @@ public void rebuild() { this.add(topPanel, BorderLayout.NORTH); + DragAndDropReorderPane dragAndDropReorderPane = new DragAndDropReorderPane(); + dragAndDropReorderPane.addDragListener((c) -> { + int pos = dragAndDropReorderPane.getPosition(c); + AlertListItem alertListItem = (AlertListItem) c; +// log.debug("drag listener: " + alertListItem.getAlert().getName() + " to " + pos); + alertManager.moveAlertTo(alertListItem.getAlert(), pos); + }); JPanel alertPanel = new JPanel(new BorderLayout()); - JPanel alertWrapperWrapper = new JPanel(new DynamicGridLayout(0, 1, 3, 3)); - alertPanel.add(alertWrapperWrapper, BorderLayout.NORTH); + alertPanel.add(dragAndDropReorderPane, BorderLayout.NORTH); + for (Alert alert : this.alertManager.getAlerts()) { - AlertListItem alertListItem = new AlertListItem(this, this.alertManager, alert); - alertWrapperWrapper.add(alertListItem); + AlertListItem alertListItem = new AlertListItem(this, this.alertManager, alert, dragAndDropReorderPane); + dragAndDropReorderPane.add(alertListItem); } this.add(new JScrollPane(alertPanel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER), BorderLayout.CENTER); JPanel importExportGroup = new JPanel(new GridLayout(1, 2, 5, 0)); - JButton importButton = new JButton("Import"); + JButton importButton = new JButton("Import", IMPORT_ICON); + importButton.setHorizontalTextPosition(SwingConstants.LEFT); importButton.addActionListener(ev -> { ImportExportDialog importExportDialog = new ImportExportDialog(SwingUtilities.getWindowAncestor(this)); importExportDialog.setVisible(true); }); importExportGroup.add(importButton); - JButton exportButton = new JButton("Export"); + JButton exportButton = new JButton("Export", EXPORT_ICON); + exportButton.setHorizontalTextPosition(SwingConstants.LEFT); exportButton.addActionListener(ev -> { ImportExportDialog importExportDialog = new ImportExportDialog(SwingUtilities.getWindowAncestor(this), WatchdogPlugin.getInstance().getConfig().alerts()); importExportDialog.setVisible(true); diff --git a/src/main/java/com/adamk33n3r/runelite/watchdog/alerts/Alert.java b/src/main/java/com/adamk33n3r/runelite/watchdog/alerts/Alert.java index 42a60b8..5f2f5ac 100644 --- a/src/main/java/com/adamk33n3r/runelite/watchdog/alerts/Alert.java +++ b/src/main/java/com/adamk33n3r/runelite/watchdog/alerts/Alert.java @@ -35,6 +35,11 @@ public TriggerType getType() { .orElse(null); } + public void moveNotificationTo(Notification notification, int pos) { + this.notifications.remove(notification); + this.notifications.add(pos, notification); + } + public void moveNotificationToTop(Notification notification) { this.notifications.remove(notification); this.notifications.add(0, notification); diff --git a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/AlertListItem.java b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/AlertListItem.java index 1c7b890..5262371 100644 --- a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/AlertListItem.java +++ b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/AlertListItem.java @@ -5,31 +5,57 @@ import com.adamk33n3r.runelite.watchdog.alerts.Alert; import com.adamk33n3r.runelite.watchdog.ui.panels.PanelUtils; +import net.runelite.client.plugins.config.ConfigPlugin; import net.runelite.client.ui.DynamicGridLayout; import net.runelite.client.ui.PluginPanel; +import net.runelite.client.ui.components.MouseDragEventForwarder; import net.runelite.client.util.ImageUtil; +import net.runelite.client.util.SwingUtil; + +import lombok.Getter; import javax.swing.ImageIcon; import javax.swing.JButton; +import javax.swing.JComponent; import javax.swing.JOptionPane; import javax.swing.JPanel; +import javax.swing.border.EmptyBorder; import java.awt.BorderLayout; import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.awt.image.BufferedImage; public class AlertListItem extends JPanel { - public static final ImageIcon DELETE_ICON; public static final ImageIcon DELETE_ICON_HOVER; + public static final ImageIcon CLONE_ICON = new ImageIcon(ImageUtil.loadImageResource(ConfigPlugin.class, "mdi_content-duplicate.png")); + public static final ImageIcon DELETE_ICON = new ImageIcon(ImageUtil.loadImageResource(ConfigPlugin.class, "mdi_delete.png")); + public static final ImageIcon DRAG_VERT = new ImageIcon(ImageUtil.loadImageResource(WatchdogPanel.class, "mdi_drag-vertical.png")); static { - final BufferedImage deleteImg = ImageUtil.resizeCanvas(ImageUtil.loadImageResource(WatchdogPanel.class, "delete_icon.png"), 10, 10); - DELETE_ICON = new ImageIcon(deleteImg); - DELETE_ICON_HOVER = new ImageIcon(ImageUtil.luminanceOffset(deleteImg, -80)); + DELETE_ICON_HOVER = new ImageIcon(ImageUtil.luminanceOffset(DELETE_ICON.getImage(), -80)); } - public AlertListItem(WatchdogPanel panel, AlertManager alertManager, Alert alert) { + + private static final int ROW_HEIGHT = 30; + private static final int PADDING = 2; + + @Getter + private final Alert alert; + + public AlertListItem(WatchdogPanel panel, AlertManager alertManager, Alert alert, JComponent parent) { + this.alert = alert; + this.setLayout(new BorderLayout(5, 0)); - this.setPreferredSize(new Dimension(PluginPanel.PANEL_WIDTH, 30)); + this.setBorder(new EmptyBorder(PADDING, 0, PADDING, 0)); + this.setPreferredSize(new Dimension(PluginPanel.PANEL_WIDTH, ROW_HEIGHT + PADDING * 2)); + + + JPanel frontGroup = new JPanel(new DynamicGridLayout(1, 0, 3, 0)); + + JButton dragHandle = new JButton(DRAG_VERT); + SwingUtil.removeButtonDecorations(dragHandle); + dragHandle.setPreferredSize(new Dimension(8, 16)); + MouseDragEventForwarder mouseDragEventForwarder = new MouseDragEventForwarder(parent); + dragHandle.addMouseListener(mouseDragEventForwarder); + dragHandle.addMouseMotionListener(mouseDragEventForwarder); + frontGroup.add(dragHandle); ToggleButton toggleButton = new ToggleButton(); toggleButton.setSelected(alert.isEnabled()); @@ -37,7 +63,10 @@ public AlertListItem(WatchdogPanel panel, AlertManager alertManager, Alert alert alert.setEnabled(toggleButton.isSelected()); alertManager.saveAlerts(); }); - this.add(toggleButton, BorderLayout.LINE_START); + toggleButton.setOpaque(false); + frontGroup.add(toggleButton); + + this.add(frontGroup, BorderLayout.LINE_START); final JButton alertButton = new JButton(alert.getName()); alertButton.setToolTipText(alert.getName()); @@ -49,24 +78,11 @@ public AlertListItem(WatchdogPanel panel, AlertManager alertManager, Alert alert final JPanel actionButtons = new JPanel(new DynamicGridLayout(1, 0, 0, 0)); this.add(actionButtons, BorderLayout.LINE_END); - UpDownArrows upDownArrows = new UpDownArrows("Move Alert up (hold shift for top)", (btn, modifiers) -> { - if ((modifiers & ActionEvent.SHIFT_MASK) != 0) { - alertManager.moveAlertToTop(alert); - } else { - alertManager.moveAlertUp(alert); - } - panel.rebuild(); - }, "Move Alert down (hold shift for bottom)", (btn, modifiers) -> { - if ((modifiers & ActionEvent.SHIFT_MASK) != 0) { - alertManager.moveAlertToBottom(alert); - } else { - alertManager.moveAlertDown(alert); - } - panel.rebuild(); - }, true); - actionButtons.add(upDownArrows); + actionButtons.add(PanelUtils.createActionButton(CLONE_ICON, CLONE_ICON, "Clone Alert", (btn, modifiers) -> { + alertManager.cloneAlert(alert); + })); - final JButton deleteButton = PanelUtils.createActionButton(DELETE_ICON, DELETE_ICON_HOVER, "Delete Alert", (btn, modifiers) -> { + final JButton deleteButton = PanelUtils.createActionButton(DELETE_ICON, DELETE_ICON, "Delete Alert", (btn, modifiers) -> { int result = JOptionPane.showConfirmDialog(this, "Are you sure you want to delete the " + alert.getName() + " alert?", "Delete?", JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE); if (result == JOptionPane.YES_OPTION) { alertManager.removeAlert(alert); diff --git a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/UpDownArrows.java b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/UpDownArrows.java deleted file mode 100644 index 7ada68d..0000000 --- a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/UpDownArrows.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.adamk33n3r.runelite.watchdog.ui; - -import com.adamk33n3r.runelite.watchdog.ui.panels.PanelUtils; - -import net.runelite.client.plugins.loottracker.LootTrackerPlugin; -import net.runelite.client.util.ImageUtil; - -import javax.swing.ImageIcon; -import javax.swing.JButton; -import javax.swing.JPanel; -import java.awt.Dimension; -import java.awt.GridLayout; -import java.awt.image.BufferedImage; - -public class UpDownArrows extends JPanel { - private static final ImageIcon UP_CHEVRON_ICON; - private static final ImageIcon UP_CHEVRON_ICON_HOVER; - private static final ImageIcon DOWN_CHEVRON_ICON; - private static final ImageIcon DOWN_CHEVRON_ICON_HOVER; - private static final Dimension BTN_DIMENSION = new Dimension(10, 10); - - static { - final BufferedImage downArrowImg = ImageUtil.loadImageResource(LootTrackerPlugin.class, "expanded.png"); - BufferedImage upArrowImg = ImageUtil.flipImage(downArrowImg, false, true); - UP_CHEVRON_ICON = new ImageIcon(upArrowImg); - UP_CHEVRON_ICON_HOVER = new ImageIcon(ImageUtil.luminanceOffset(upArrowImg, -80)); - DOWN_CHEVRON_ICON = new ImageIcon(downArrowImg); - DOWN_CHEVRON_ICON_HOVER = new ImageIcon(ImageUtil.luminanceOffset(downArrowImg, -80)); - } - - public UpDownArrows(String upTooltip, PanelUtils.ButtonClickListener onUp, String downTooltip, PanelUtils.ButtonClickListener onDown) { - this(upTooltip, onUp, downTooltip, onDown, false); - } - - public UpDownArrows(String upTooltip, PanelUtils.ButtonClickListener onUp, String downTooltip, PanelUtils.ButtonClickListener onDown, boolean horizontal) { - if (horizontal) { - this.setLayout(new GridLayout(1, 2, 0, 0)); - this.setPreferredSize(new Dimension(30, 10)); - } else { - this.setLayout(new GridLayout(2, 1, 0, 0)); - this.setPreferredSize(new Dimension(16, 16)); - } - - final JButton upButton = PanelUtils.createActionButton(UP_CHEVRON_ICON, UP_CHEVRON_ICON_HOVER, upTooltip, onUp); - upButton.setPreferredSize(BTN_DIMENSION); - this.add(upButton); - final JButton downButton = PanelUtils.createActionButton(DOWN_CHEVRON_ICON, DOWN_CHEVRON_ICON_HOVER, downTooltip, onDown); - downButton.setPreferredSize(BTN_DIMENSION); - this.add(downButton); - } -} diff --git a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/MessageNotificationPanel.java b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/MessageNotificationPanel.java index c628539..3106726 100644 --- a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/MessageNotificationPanel.java +++ b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/MessageNotificationPanel.java @@ -12,7 +12,7 @@ import java.awt.event.FocusListener; public class MessageNotificationPanel extends NotificationPanel { - public MessageNotificationPanel(MessageNotification notification, NotificationsPanel parentPanel, Runnable onChangeListener, PanelUtils.ButtonClickListener onRemove) { + public MessageNotificationPanel(MessageNotification notification, NotificationsPanel parentPanel, Runnable onChangeListener, PanelUtils.OnRemove onRemove) { super(notification, parentPanel, onChangeListener, onRemove); FlatTextArea flatTextArea = new FlatTextArea("Enter your message...", true); diff --git a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/NotificationPanel.java b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/NotificationPanel.java index 45b9a65..0cc0ab8 100644 --- a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/NotificationPanel.java +++ b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/NotificationPanel.java @@ -4,13 +4,15 @@ import com.adamk33n3r.runelite.watchdog.notifications.Notification; import com.adamk33n3r.runelite.watchdog.ui.AlertListItem; import com.adamk33n3r.runelite.watchdog.ui.StretchedStackedLayout; -import com.adamk33n3r.runelite.watchdog.ui.UpDownArrows; import com.adamk33n3r.runelite.watchdog.ui.panels.NotificationsPanel; import com.adamk33n3r.runelite.watchdog.ui.panels.PanelUtils; import net.runelite.client.ui.ColorScheme; +import net.runelite.client.ui.components.MouseDragEventForwarder; import net.runelite.client.util.ImageUtil; +import lombok.Getter; + import javax.swing.BorderFactory; import javax.swing.ImageIcon; import javax.swing.JButton; @@ -21,7 +23,6 @@ import javax.swing.border.EmptyBorder; import java.awt.BorderLayout; import java.awt.FlowLayout; -import java.awt.event.ActionEvent; import java.awt.image.BufferedImage; public abstract class NotificationPanel extends JPanel { @@ -63,13 +64,17 @@ public abstract class NotificationPanel extends JPanel { CLOCK_ICON = new ImageIcon(ImageUtil.luminanceOffset(clockIcon, -80)); } + @Getter + protected Notification notification; protected JPanel settings = new JPanel(new StretchedStackedLayout(3, 3)); private static final Border NAME_BOTTOM_BORDER = new CompoundBorder( BorderFactory.createMatteBorder(0, 0, 1, 0, ColorScheme.DARK_GRAY_COLOR), BorderFactory.createMatteBorder(5, 10, 5, 0, ColorScheme.DARKER_GRAY_COLOR)); - public NotificationPanel(Notification notification, NotificationsPanel parentPanel, Runnable onChangeListener, PanelUtils.ButtonClickListener onRemove) { + public NotificationPanel(Notification notification, NotificationsPanel parentPanel, Runnable onChangeListener, PanelUtils.OnRemove onRemove) { + this.notification = notification; + this.setLayout(new BorderLayout()); this.setBorder(new EmptyBorder(3, 0, 0, 0)); JPanel container = new JPanel(new StretchedStackedLayout(3, 3)); @@ -88,32 +93,18 @@ public NotificationPanel(Notification notification, NotificationsPanel parentPan nameLabel.setToolTipText(notificationType.getTooltip()); nameWrapper.add(nameLabel, BorderLayout.WEST); + MouseDragEventForwarder mouseDragEventForwarder = new MouseDragEventForwarder(parentPanel.getNotificationContainer()); + nameWrapper.addMouseListener(mouseDragEventForwarder); + nameWrapper.addMouseMotionListener(mouseDragEventForwarder); + nameLabel.addMouseListener(mouseDragEventForwarder); + nameLabel.addMouseMotionListener(mouseDragEventForwarder); + // Right buttons JPanel rightActions = new JPanel(new FlowLayout(FlowLayout.RIGHT, 6, 0)); rightActions.setBorder(new EmptyBorder(4, 0, 0, 0)); rightActions.setBackground(ColorScheme.DARKER_GRAY_COLOR); nameWrapper.add(rightActions, BorderLayout.EAST); - - UpDownArrows upDownArrows = new UpDownArrows("Move Notification up (hold shift for top)", (btn, modifiers) -> { - if ((modifiers & ActionEvent.SHIFT_MASK) != 0) { - notification.getAlert().moveNotificationToTop(notification); - } else { - notification.getAlert().moveNotificationUp(notification); - } - onChangeListener.run(); - parentPanel.rebuild(); - }, "Move Notification down (hold shift for bottom)", (btn, modifiers) -> { - if ((modifiers & ActionEvent.SHIFT_MASK) != 0) { - notification.getAlert().moveNotificationToBottom(notification); - } else { - notification.getAlert().moveNotificationDown(notification); - } - onChangeListener.run(); - parentPanel.rebuild(); - }, true); - rightActions.add(upDownArrows); - JButton focusBtn = PanelUtils.createToggleActionButton( FOREGROUND_ICON, FOREGROUND_ICON_HOVER, @@ -139,7 +130,7 @@ public NotificationPanel(Notification notification, NotificationsPanel parentPan AlertListItem.DELETE_ICON, AlertListItem.DELETE_ICON_HOVER, "Remove this notification", - onRemove); + (btn, modifiers) -> onRemove.elementRemoved(this)); rightActions.add(deleteBtn); this.settings.setBorder(new EmptyBorder(5, 10, 5, 10)); diff --git a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/OverheadNotificationPanel.java b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/OverheadNotificationPanel.java index 228e048..d2a8bbb 100644 --- a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/OverheadNotificationPanel.java +++ b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/OverheadNotificationPanel.java @@ -7,7 +7,7 @@ import javax.swing.JSpinner; public class OverheadNotificationPanel extends MessageNotificationPanel { - public OverheadNotificationPanel(Overhead notification, NotificationsPanel parentPanel, Runnable onChangeListener, PanelUtils.ButtonClickListener onRemove) { + public OverheadNotificationPanel(Overhead notification, NotificationsPanel parentPanel, Runnable onChangeListener, PanelUtils.OnRemove onRemove) { super(notification, parentPanel, onChangeListener, onRemove); JSpinner displayTime = PanelUtils.createSpinner(notification.getDisplayTime(), 1, 99, 1, val -> { diff --git a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/OverlayNotificationPanel.java b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/OverlayNotificationPanel.java index 46576ca..d5a8c7b 100644 --- a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/OverlayNotificationPanel.java +++ b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/OverlayNotificationPanel.java @@ -14,7 +14,7 @@ public class OverlayNotificationPanel extends MessageNotificationPanel { private JPanel displayTime; - public OverlayNotificationPanel(Overlay notification, NotificationsPanel parentPanel, ColorPickerManager colorPickerManager, Runnable onChangeListener, PanelUtils.ButtonClickListener onRemove) { + public OverlayNotificationPanel(Overlay notification, NotificationsPanel parentPanel, ColorPickerManager colorPickerManager, Runnable onChangeListener, PanelUtils.OnRemove onRemove) { super(notification, parentPanel, onChangeListener, onRemove); ColorJButton colorPicker = PanelUtils.createColorPicker( diff --git a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/ScreenFlashNotificationPanel.java b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/ScreenFlashNotificationPanel.java index 40b55dc..24e106f 100644 --- a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/ScreenFlashNotificationPanel.java +++ b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/ScreenFlashNotificationPanel.java @@ -15,7 +15,7 @@ import java.util.Arrays; public class ScreenFlashNotificationPanel extends NotificationPanel { - public ScreenFlashNotificationPanel(ScreenFlash screenFlash, NotificationsPanel parentPanel, ColorPickerManager colorPickerManager, Runnable onChangeListener, PanelUtils.ButtonClickListener onRemove) { + public ScreenFlashNotificationPanel(ScreenFlash screenFlash, NotificationsPanel parentPanel, ColorPickerManager colorPickerManager, Runnable onChangeListener, PanelUtils.OnRemove onRemove) { super(screenFlash, parentPanel, onChangeListener, onRemove); ColorJButton colorPickerBtn = PanelUtils.createColorPicker( diff --git a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/SoundEffectNotificationPanel.java b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/SoundEffectNotificationPanel.java index 2812169..cf99e59 100644 --- a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/SoundEffectNotificationPanel.java +++ b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/SoundEffectNotificationPanel.java @@ -13,7 +13,7 @@ public class SoundEffectNotificationPanel extends NotificationPanel { - public SoundEffectNotificationPanel(SoundEffect soundEffect, NotificationsPanel parentPanel, Runnable onChangeListener, PanelUtils.ButtonClickListener onRemove) { + public SoundEffectNotificationPanel(SoundEffect soundEffect, NotificationsPanel parentPanel, Runnable onChangeListener, PanelUtils.OnRemove onRemove) { super(soundEffect, parentPanel, onChangeListener, onRemove); JRichTextPane richTextPane = new JRichTextPane(); diff --git a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/SoundNotificationPanel.java b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/SoundNotificationPanel.java index b16d5bf..4a9517a 100644 --- a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/SoundNotificationPanel.java +++ b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/SoundNotificationPanel.java @@ -15,7 +15,7 @@ public class SoundNotificationPanel extends NotificationPanel { - public SoundNotificationPanel(Sound sound, NotificationsPanel parentPanel, Runnable onChangeListener, PanelUtils.ButtonClickListener onRemove) { + public SoundNotificationPanel(Sound sound, NotificationsPanel parentPanel, Runnable onChangeListener, PanelUtils.OnRemove onRemove) { super(sound, parentPanel, onChangeListener, onRemove); String[] supportedExtensions = Arrays.stream(AudioSystem.getAudioFileTypes()).map(AudioFileFormat.Type::getExtension).toArray(String[]::new); diff --git a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/TextToSpeechNotificationPanel.java b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/TextToSpeechNotificationPanel.java index 4008f40..cca0417 100644 --- a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/TextToSpeechNotificationPanel.java +++ b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/notifications/panels/TextToSpeechNotificationPanel.java @@ -35,7 +35,7 @@ public class TextToSpeechNotificationPanel extends NotificationPanel { SPEED_ICON = new ImageIcon(ImageUtil.luminanceOffset(speedImg, -80)); } - public TextToSpeechNotificationPanel(TextToSpeech notification, NotificationsPanel parentPanel, Runnable onChangeListener, PanelUtils.ButtonClickListener onRemove) { + public TextToSpeechNotificationPanel(TextToSpeech notification, NotificationsPanel parentPanel, Runnable onChangeListener, PanelUtils.OnRemove onRemove) { super(notification, parentPanel, onChangeListener, onRemove); if (!WatchdogPlugin.getInstance().getConfig().ttsEnabled()) { diff --git a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/panels/AlertPanel.java b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/panels/AlertPanel.java index dc5d3d7..f63e0d4 100644 --- a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/panels/AlertPanel.java +++ b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/panels/AlertPanel.java @@ -32,6 +32,7 @@ import java.util.function.Consumer; import java.util.function.Supplier; +import static com.adamk33n3r.runelite.watchdog.AlertManager.ALERT_LIST_TYPE; import static com.adamk33n3r.runelite.watchdog.ui.notifications.panels.NotificationPanel.TEST_ICON; import static com.adamk33n3r.runelite.watchdog.ui.notifications.panels.NotificationPanel.TEST_ICON_HOVER; @@ -107,7 +108,7 @@ private AlertPanel(MultiplexingPluginPanel muxer, Alert alert) { (btn, modifiers) -> { ImportExportDialog importExportDialog = new ImportExportDialog( SwingUtilities.getWindowAncestor(this), - this.alertManager.getGson().toJson(new Alert[] { alert }) + this.alertManager.getGson().toJson(new Alert[] { alert }, ALERT_LIST_TYPE) ); importExportDialog.setVisible(true); } diff --git a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/panels/NotificationsPanel.java b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/panels/NotificationsPanel.java index 8f7c1e2..1e9a00e 100644 --- a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/panels/NotificationsPanel.java +++ b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/panels/NotificationsPanel.java @@ -14,8 +14,10 @@ import com.adamk33n3r.runelite.watchdog.notifications.SoundEffect; import com.adamk33n3r.runelite.watchdog.notifications.TextToSpeech; import com.adamk33n3r.runelite.watchdog.notifications.TrayNotification; +import com.adamk33n3r.runelite.watchdog.ui.AlertListItem; import com.adamk33n3r.runelite.watchdog.ui.dropdownbutton.DropDownButtonFactory; import com.adamk33n3r.runelite.watchdog.ui.notifications.panels.MessageNotificationPanel; +import com.adamk33n3r.runelite.watchdog.ui.notifications.panels.NotificationPanel; import com.adamk33n3r.runelite.watchdog.ui.notifications.panels.OverheadNotificationPanel; import com.adamk33n3r.runelite.watchdog.ui.notifications.panels.OverlayNotificationPanel; import com.adamk33n3r.runelite.watchdog.ui.notifications.panels.ScreenFlashNotificationPanel; @@ -24,9 +26,11 @@ import com.adamk33n3r.runelite.watchdog.ui.notifications.panels.TextToSpeechNotificationPanel; import net.runelite.client.ui.DynamicGridLayout; +import net.runelite.client.ui.components.DragAndDropReorderPane; import net.runelite.client.ui.components.colorpicker.ColorPickerManager; import com.google.inject.Injector; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import javax.inject.Inject; @@ -51,12 +55,21 @@ public class NotificationsPanel extends JPanel { @Inject private AlertManager alertManager; - private final JPanel notificationContainer; + @Getter + private final DragAndDropReorderPane notificationContainer; public NotificationsPanel(Alert alert) { this.alert = alert; this.setLayout(new DynamicGridLayout(0, 1, 3, 3)); - this.notificationContainer = new JPanel(new DynamicGridLayout(0, 1, 3, 3)); + this.notificationContainer = new DragAndDropReorderPane(); + this.notificationContainer.addDragListener((c) -> { + int pos = this.notificationContainer.getPosition(c); + NotificationPanel notificationPanel = (NotificationPanel) c; + Notification notification = notificationPanel.getNotification(); +// log.debug("drag listener: " + notification.getType().getName() + " to " + pos); + notification.getAlert().moveNotificationTo(notification, pos); + this.alertManager.saveAlerts(); + }); JPopupMenu popupMenu = new JPopupMenu(); ActionListener actionListener = e -> { @@ -97,34 +110,35 @@ public void rebuild() { } private void addPanel(Notification notification) { - JPanel notificationPanel = new JPanel(new DynamicGridLayout(0, 1, 3, 3)); - this.notificationContainer.add(notificationPanel); - - PanelUtils.ButtonClickListener removeNotification = (btn, modifiers) -> { + PanelUtils.OnRemove removeNotification = (removedPanel) -> { this.alert.getNotifications().remove(notification); - this.notificationContainer.remove(notificationPanel); + this.notificationContainer.remove(removedPanel); this.notificationContainer.revalidate(); this.alertManager.saveAlerts(); }; - if (notification instanceof GameMessage) - notificationPanel.add(new MessageNotificationPanel((GameMessage)notification, this, this.alertManager::saveAlerts, removeNotification)); - else if (notification instanceof TextToSpeech) - notificationPanel.add(new TextToSpeechNotificationPanel((TextToSpeech) notification, this, this.alertManager::saveAlerts, removeNotification)); + NotificationPanel notificationPanel = null; + if (notification instanceof GameMessage) { + notificationPanel = new MessageNotificationPanel((GameMessage) notification, this, this.alertManager::saveAlerts, removeNotification); + } else if (notification instanceof TextToSpeech) + notificationPanel = new TextToSpeechNotificationPanel((TextToSpeech) notification, this, this.alertManager::saveAlerts, removeNotification); else if (notification instanceof Sound) - notificationPanel.add(new SoundNotificationPanel((Sound)notification, this, this.alertManager::saveAlerts, removeNotification)); + notificationPanel = new SoundNotificationPanel((Sound)notification, this, this.alertManager::saveAlerts, removeNotification); else if (notification instanceof SoundEffect) - notificationPanel.add(new SoundEffectNotificationPanel((SoundEffect)notification, this, this.alertManager::saveAlerts, removeNotification)); + notificationPanel = new SoundEffectNotificationPanel((SoundEffect)notification, this, this.alertManager::saveAlerts, removeNotification); else if (notification instanceof TrayNotification) - notificationPanel.add(new MessageNotificationPanel((TrayNotification)notification, this, this.alertManager::saveAlerts, removeNotification)); + notificationPanel = new MessageNotificationPanel((TrayNotification)notification, this, this.alertManager::saveAlerts, removeNotification); else if (notification instanceof ScreenFlash) - notificationPanel.add(new ScreenFlashNotificationPanel((ScreenFlash) notification, this, this.colorPickerManager, this.alertManager::saveAlerts, removeNotification)); + notificationPanel = new ScreenFlashNotificationPanel((ScreenFlash) notification, this, this.colorPickerManager, this.alertManager::saveAlerts, removeNotification); else if (notification instanceof Overhead) - notificationPanel.add(new OverheadNotificationPanel((Overhead) notification, this, this.alertManager::saveAlerts, removeNotification)); + notificationPanel = new OverheadNotificationPanel((Overhead) notification, this, this.alertManager::saveAlerts, removeNotification); else if (notification instanceof Overlay) - notificationPanel.add(new OverlayNotificationPanel((Overlay) notification, this, this.colorPickerManager, this.alertManager::saveAlerts, removeNotification)); + notificationPanel = new OverlayNotificationPanel((Overlay) notification, this, this.colorPickerManager, this.alertManager::saveAlerts, removeNotification); else if (notification instanceof NotificationEvent) - notificationPanel.add(new MessageNotificationPanel((NotificationEvent) notification, this, this.alertManager::saveAlerts, removeNotification)); + notificationPanel = new MessageNotificationPanel((NotificationEvent) notification, this, this.alertManager::saveAlerts, removeNotification); + + if (notificationPanel != null) + this.notificationContainer.add(notificationPanel); } private Notification createNotification(NotificationType notificationType) { diff --git a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/panels/PanelUtils.java b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/panels/PanelUtils.java index bfe8de4..e71bcca 100644 --- a/src/main/java/com/adamk33n3r/runelite/watchdog/ui/panels/PanelUtils.java +++ b/src/main/java/com/adamk33n3r/runelite/watchdog/ui/panels/PanelUtils.java @@ -14,6 +14,7 @@ import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; +import javax.swing.JComponent; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JOptionPane; @@ -155,6 +156,10 @@ public interface ButtonClickListener { void clickPerformed(JButton button, int modifiers); } + public interface OnRemove { + void elementRemoved(JComponent removed); + } + public static JButton createToggleActionButton(ImageIcon onIcon, ImageIcon onRolloverIcon, ImageIcon offIcon, ImageIcon offRolloverIcon, String onTooltip, String offTooltip, boolean initialValue, ButtonClickListener listener) { JButton actionButton = createActionButton(offIcon, offRolloverIcon, offTooltip, (btn, modifiers) -> { btn.setSelected(!btn.isSelected()); diff --git a/src/main/resources/com/adamk33n3r/runelite/watchdog/delete_icon.png b/src/main/resources/com/adamk33n3r/runelite/watchdog/delete_icon.png deleted file mode 100644 index cb6699689158b44346ec359e97a09273e0565671..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 300 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p>QL70(Y)*K0-;6YCp#}EtuwUd3h4jD+ebf*i%lq}_bU(YBW zx~ExM@V(-Z%K5^I$JBm&PVks9)6Dl4U%leeEmO-bUAm@IvSja;jiS#~4thr2T&GaX zu6A3n=aT80Dd&Ppg>BLu%1gd5IGs76=&o8+&JSyjlYsTNPna?C@ z`Laeh;omo2U7K$^D&H)g8n?Y+!G2b*OXck=6265RZfAEDOYk@w`eBZv&D_Nt{E6k? sJfHE2%r~;X9Qf-=derS-t%*CBJ6yY#XPaE+1A2zR)78&qol`;+037UYwEzGB diff --git a/src/main/resources/com/adamk33n3r/runelite/watchdog/mdi_drag-vertical.png b/src/main/resources/com/adamk33n3r/runelite/watchdog/mdi_drag-vertical.png new file mode 100644 index 0000000000000000000000000000000000000000..49a3d19af5da75f4e710b5d36e19ee4ef62565bd GIT binary patch literal 185 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|ialK%LoEE0 zQx*sq1g)6QxSVl&-rZm4Pn>wcvFXA8|Nnnqy>ey4s-u|)-rn9W8xawq*TD1R^Yi}3 zRjXbx=B!h_#!wp?dbL?a(qW@`2X9PGBgdy=#w!czOifJ-8Wu4p@y=MVY}qr1NsL!M i9Llg#FcQ%`*UR8D%}bDb;p{4)^$eb_elF{r5}E)q#z=Jl literal 0 HcmV?d00001 diff --git a/src/main/resources/com/adamk33n3r/runelite/watchdog/mdi_import.png b/src/main/resources/com/adamk33n3r/runelite/watchdog/mdi_import.png new file mode 100644 index 0000000000000000000000000000000000000000..6487ae0d3ed249cf8fe426c1ef4a3d806f766971 GIT binary patch literal 215 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPHF4e$wZ1=6=~-+uV;A&|UrX$1m=DQ$u$Pr7Z@3Yw#i&L+Hz$n&?p8^S3j3^P6