From 52b67a9393b8eeecfdcef032a3f03c24f8cf1df8 Mon Sep 17 00:00:00 2001 From: bubblobill <45483160+bubblobill@users.noreply.github.com> Date: Wed, 2 Oct 2024 16:05:46 +0800 Subject: [PATCH 1/7] Added ability to set hotkey and displayHotKey macro button properties to metamacro functions. --- .../client/functions/MacroFunctions.java | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/main/java/net/rptools/maptool/client/functions/MacroFunctions.java b/src/main/java/net/rptools/maptool/client/functions/MacroFunctions.java index b0357805fe..052f379765 100644 --- a/src/main/java/net/rptools/maptool/client/functions/MacroFunctions.java +++ b/src/main/java/net/rptools/maptool/client/functions/MacroFunctions.java @@ -355,12 +355,16 @@ public void setMacroProps(MacroButtonProperties mbp, String propString, String d mbp.setAutoExecute(boolVal(value)); } else if ("color".equalsIgnoreCase(key)) { mbp.setColorKey(value); + } else if ("displayHotkey".equalsIgnoreCase(key)) { + mbp.setDisplayHotKey(boolVal(value)); } else if ("fontColor".equalsIgnoreCase(key)) { mbp.setFontColorKey(value); } else if ("fontSize".equalsIgnoreCase(key)) { mbp.setFontSize(value); } else if ("group".equalsIgnoreCase(key)) { mbp.setGroup(value); + } else if ("hotkey".equalsIgnoreCase(key)) { + mbp.setHotKey(value); } else if ("includeLabel".equalsIgnoreCase(key)) { mbp.setIncludeLabel(boolVal(value)); } else if ("sortBy".equalsIgnoreCase(key)) { @@ -1046,20 +1050,22 @@ private ImmutablePair getCampaignMbpByIndexOrLab */ private String macroButtonPropertiesToString(MacroButtonProperties mbp, String delim) { StringBuilder sb = new StringBuilder(); + sb.append("applyToSelected=").append(mbp.getApplyToTokens()).append(delim); sb.append("autoExecute=").append(mbp.getAutoExecute()).append(delim); sb.append("color=").append(mbp.getColorKey()).append(delim); + sb.append("displayHotkey=").append(mbp.getDisplayHotKey()).append(delim); sb.append("fontColor=").append(mbp.getFontColorKey()).append(delim); + sb.append("fontSize=").append(mbp.getFontSize()).append(delim); sb.append("group=").append(mbp.getGroup()).append(delim); + sb.append("hotkey=").append(mbp.getHotKey()).append(delim); sb.append("includeLabel=").append(mbp.getIncludeLabel()).append(delim); - sb.append("sortBy=").append(mbp.getSortby()).append(delim); sb.append("index=").append(mbp.getIndex()).append(delim); sb.append("label=").append(mbp.getLabel()).append(delim); - sb.append("fontSize=").append(mbp.getFontSize()).append(delim); + sb.append("maxWidth=").append(mbp.getMaxWidth()).append(delim); sb.append("minWidth=").append(mbp.getMinWidth()).append(delim); sb.append("playerEditable=").append(mbp.getAllowPlayerEdits()).append(delim); - sb.append("maxWidth=").append(mbp.getMaxWidth()).append(delim); + sb.append("sortBy=").append(mbp.getSortby()).append(delim); sb.append("tooltip=").append(mbp.getToolTip()).append(delim); - sb.append("applyToSelected=").append(mbp.getApplyToTokens()).append(delim); return sb.toString(); } @@ -1091,12 +1097,16 @@ private MacroButtonProperties macroButtonPropertiesFromJSON( mbp.setAutoExecute(boolVal(value)); } else if ("color".equalsIgnoreCase(key)) { mbp.setColorKey(value); + } else if ("displayHotkey".equalsIgnoreCase(key)) { + mbp.setDisplayHotKey(boolVal(value)); } else if ("fontColor".equalsIgnoreCase(key)) { mbp.setFontColorKey(value); } else if ("fontSize".equalsIgnoreCase(key)) { mbp.setFontSize(value); } else if ("group".equalsIgnoreCase(key)) { mbp.setGroup(value); + } else if ("hotkey".equalsIgnoreCase(key)) { + mbp.setHotKey(value); } else if ("includeLabel".equalsIgnoreCase(key)) { mbp.setIncludeLabel(boolVal(value)); } else if ("sortBy".equalsIgnoreCase(key)) { @@ -1184,21 +1194,23 @@ private MacroButtonProperties macroButtonPropertiesFromStringProp( */ private JsonObject macroButtonPropertiesToJSON(MacroButtonProperties mbp) { JsonObject props = new JsonObject(); + props.addProperty("applyToSelected", mbp.getApplyToTokens()); props.addProperty("autoExecute", mbp.getAutoExecute()); props.addProperty("color", mbp.getColorKey()); + props.addProperty("displayHotkey", mbp.getDisplayHotKey()); + props.addProperty("command", mbp.getCommand()); props.addProperty("fontColor", mbp.getFontColorKey()); + props.addProperty("fontSize", mbp.getFontSize()); props.addProperty("group", mbp.getGroup()); + props.addProperty("hotkey", mbp.getHotKey()); props.addProperty("includeLabel", mbp.getIncludeLabel()); - props.addProperty("sortBy", mbp.getSortby()); props.addProperty("index", mbp.getIndex()); props.addProperty("label", mbp.getLabel()); - props.addProperty("fontSize", mbp.getFontSize()); props.addProperty("minWidth", mbp.getMinWidth()); - props.addProperty("playerEditable", mbp.getAllowPlayerEdits()); - props.addProperty("command", mbp.getCommand()); props.addProperty("maxWidth", mbp.getMaxWidth()); + props.addProperty("playerEditable", mbp.getAllowPlayerEdits()); + props.addProperty("sortBy", mbp.getSortby()); props.addProperty("tooltip", mbp.getToolTip()); - props.addProperty("applyToSelected", mbp.getApplyToTokens()); JsonArray compare = new JsonArray(); if (mbp.getCompareGroup()) compare.add("group"); From 710a5e92747380498bc95e87fa21b666adaccdb6 Mon Sep 17 00:00:00 2001 From: bubblobill <45483160+bubblobill@users.noreply.github.com> Date: Wed, 2 Oct 2024 23:31:38 +0800 Subject: [PATCH 2/7] Added function getMacroHotkeys() --- .../client/functions/MacroFunctions.java | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/rptools/maptool/client/functions/MacroFunctions.java b/src/main/java/net/rptools/maptool/client/functions/MacroFunctions.java index 052f379765..042787348d 100644 --- a/src/main/java/net/rptools/maptool/client/functions/MacroFunctions.java +++ b/src/main/java/net/rptools/maptool/client/functions/MacroFunctions.java @@ -18,13 +18,14 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; +import java.util.*; +import javax.swing.*; import net.rptools.lib.MD5Key; import net.rptools.maptool.client.MapTool; import net.rptools.maptool.client.MapToolVariableResolver; import net.rptools.maptool.client.functions.json.JSONMacroFunctions; +import net.rptools.maptool.client.ui.macrobuttons.MacroButtonHotKeyManager; +import net.rptools.maptool.client.ui.macrobuttons.buttons.MacroButton; import net.rptools.maptool.client.ui.macrobuttons.panels.AbstractMacroPanel; import net.rptools.maptool.language.I18N; import net.rptools.maptool.model.MacroButtonProperties; @@ -61,6 +62,7 @@ private MacroFunctions() { "setMacroProps", "getMacros", "getMacroProps", + "getMacroHotkeys", "getMacroIndexes", "getMacroIndices", "getMacroName", @@ -218,7 +220,13 @@ public Object childEvaluate( } else if (functionName.equalsIgnoreCase("getMacroButtonIndex")) { return BigDecimal.valueOf(MapTool.getParser().getMacroButtonIndex()); - + } else if (functionName.equalsIgnoreCase("getMacroHotkeys")) { + FunctionUtil.checkNumberParam(functionName, parameters, 0, 1); + String delim = "json"; + if (!parameters.isEmpty()) { + delim = parameters.getFirst().toString(); + } + return getMacroHotkeys(delim); } else if (functionName.equalsIgnoreCase("getMacroGroup")) { FunctionUtil.checkNumberParam(functionName, parameters, 1, 4); String group = parameters.get(0).toString(); @@ -252,6 +260,30 @@ public Object childEvaluate( throw new ParserException(I18N.getText(KEY_UNKNOWN_MACRO, functionName)); } + private Object getMacroHotkeys(String delim) { + Map keyStrokeMap = MacroButtonHotKeyManager.getKeyStrokeMap(); + JsonObject keyMacroObject = new JsonObject(); + + for (KeyStroke ks : keyStrokeMap.keySet()) { + MacroButton btn = keyStrokeMap.get(ks); + String address = btn.getProperties().getLabel() + "@"; + switch (btn.getPanelClass()) { + case "GlobalPanel", "globalpanel" -> address += "global"; + case "CampaignPanel", "campaignpanel" -> address += "campaign"; + case "GmPanel", "gmpanel" -> address += "gm"; + default -> address += btn.getToken().getName(); + } + keyMacroObject.addProperty(ks.toString(), address); + } + if (delim.equalsIgnoreCase("json")) { + return keyMacroObject; + } else { + return JSONMacroFunctions.getInstance() + .getJsonObjectFunctions() + .toStringProp(keyMacroObject, delim); + } + } + /** * Campaign version of hasMacro(). * From e75d474001cb3ef6e0ab08eb6b8b508b7ca62d7c Mon Sep 17 00:00:00 2001 From: bubblobill <45483160+bubblobill@users.noreply.github.com> Date: Fri, 4 Oct 2024 19:55:57 +0800 Subject: [PATCH 3/7] Added static function to MacroButtonHotKeyManager::isHotkeyAssigned Changed macro functions assigning hotkeys to substitute "none" where the hotkey is already assigned. --- .../rptools/maptool/client/functions/MacroFunctions.java | 6 ++++++ .../client/ui/macrobuttons/MacroButtonHotKeyManager.java | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/rptools/maptool/client/functions/MacroFunctions.java b/src/main/java/net/rptools/maptool/client/functions/MacroFunctions.java index 042787348d..0651ec04cf 100644 --- a/src/main/java/net/rptools/maptool/client/functions/MacroFunctions.java +++ b/src/main/java/net/rptools/maptool/client/functions/MacroFunctions.java @@ -396,6 +396,9 @@ public void setMacroProps(MacroButtonProperties mbp, String propString, String d } else if ("group".equalsIgnoreCase(key)) { mbp.setGroup(value); } else if ("hotkey".equalsIgnoreCase(key)) { + if(MacroButtonHotKeyManager.isHotkeyAssigned(value)) { + value = MacroButtonHotKeyManager.HOTKEYS[0]; + } mbp.setHotKey(value); } else if ("includeLabel".equalsIgnoreCase(key)) { mbp.setIncludeLabel(boolVal(value)); @@ -1138,6 +1141,9 @@ private MacroButtonProperties macroButtonPropertiesFromJSON( } else if ("group".equalsIgnoreCase(key)) { mbp.setGroup(value); } else if ("hotkey".equalsIgnoreCase(key)) { + if(MacroButtonHotKeyManager.isHotkeyAssigned(value)) { + value = MacroButtonHotKeyManager.HOTKEYS[0]; + } mbp.setHotKey(value); } else if ("includeLabel".equalsIgnoreCase(key)) { mbp.setIncludeLabel(boolVal(value)); diff --git a/src/main/java/net/rptools/maptool/client/ui/macrobuttons/MacroButtonHotKeyManager.java b/src/main/java/net/rptools/maptool/client/ui/macrobuttons/MacroButtonHotKeyManager.java index 374afb4f71..af7e7631ae 100644 --- a/src/main/java/net/rptools/maptool/client/ui/macrobuttons/MacroButtonHotKeyManager.java +++ b/src/main/java/net/rptools/maptool/client/ui/macrobuttons/MacroButtonHotKeyManager.java @@ -82,7 +82,9 @@ public class MacroButtonHotKeyManager { private static Map buttonsByKeyStroke = new HashMap(); private MacroButton macroButton; - + public static boolean isHotkeyAssigned(String hotkey){ + return buttonsByKeyStroke.containsKey(hotkey); + } public MacroButtonHotKeyManager(MacroButton macroButton) { this.macroButton = macroButton; } From 2b923447bbc800b28912b8997a7733e07a5f4719 Mon Sep 17 00:00:00 2001 From: bubblobill <45483160+bubblobill@users.noreply.github.com> Date: Fri, 4 Oct 2024 20:01:08 +0800 Subject: [PATCH 4/7] Added static function to MacroButtonHotKeyManager::isHotkeyAssigned le sigh --- .../net/rptools/maptool/client/functions/MacroFunctions.java | 4 ++-- .../client/ui/macrobuttons/MacroButtonHotKeyManager.java | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/rptools/maptool/client/functions/MacroFunctions.java b/src/main/java/net/rptools/maptool/client/functions/MacroFunctions.java index 0651ec04cf..89a9a1011d 100644 --- a/src/main/java/net/rptools/maptool/client/functions/MacroFunctions.java +++ b/src/main/java/net/rptools/maptool/client/functions/MacroFunctions.java @@ -396,7 +396,7 @@ public void setMacroProps(MacroButtonProperties mbp, String propString, String d } else if ("group".equalsIgnoreCase(key)) { mbp.setGroup(value); } else if ("hotkey".equalsIgnoreCase(key)) { - if(MacroButtonHotKeyManager.isHotkeyAssigned(value)) { + if (MacroButtonHotKeyManager.isHotkeyAssigned(value)) { value = MacroButtonHotKeyManager.HOTKEYS[0]; } mbp.setHotKey(value); @@ -1141,7 +1141,7 @@ private MacroButtonProperties macroButtonPropertiesFromJSON( } else if ("group".equalsIgnoreCase(key)) { mbp.setGroup(value); } else if ("hotkey".equalsIgnoreCase(key)) { - if(MacroButtonHotKeyManager.isHotkeyAssigned(value)) { + if (MacroButtonHotKeyManager.isHotkeyAssigned(value)) { value = MacroButtonHotKeyManager.HOTKEYS[0]; } mbp.setHotKey(value); diff --git a/src/main/java/net/rptools/maptool/client/ui/macrobuttons/MacroButtonHotKeyManager.java b/src/main/java/net/rptools/maptool/client/ui/macrobuttons/MacroButtonHotKeyManager.java index af7e7631ae..d2726c70e0 100644 --- a/src/main/java/net/rptools/maptool/client/ui/macrobuttons/MacroButtonHotKeyManager.java +++ b/src/main/java/net/rptools/maptool/client/ui/macrobuttons/MacroButtonHotKeyManager.java @@ -82,9 +82,11 @@ public class MacroButtonHotKeyManager { private static Map buttonsByKeyStroke = new HashMap(); private MacroButton macroButton; - public static boolean isHotkeyAssigned(String hotkey){ + + public static boolean isHotkeyAssigned(String hotkey) { return buttonsByKeyStroke.containsKey(hotkey); } + public MacroButtonHotKeyManager(MacroButton macroButton) { this.macroButton = macroButton; } From 1be39bf0937534e645f36435c21cb5a09d4def34 Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Sun, 6 Oct 2024 16:44:58 -0700 Subject: [PATCH 5/7] Do not show local player in Connections window or status panel --- src/main/java/net/rptools/maptool/client/MapToolClient.java | 4 +++- .../net/rptools/maptool/client/events/PlayerConnected.java | 2 +- .../maptool/client/swing/PlayersLoadingStatusBar.java | 6 +++++- .../client/ui/connections/ClientConnectionPanel.java | 4 ++++ 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/rptools/maptool/client/MapToolClient.java b/src/main/java/net/rptools/maptool/client/MapToolClient.java index 62c3e4a837..4540c9b5d4 100644 --- a/src/main/java/net/rptools/maptool/client/MapToolClient.java +++ b/src/main/java/net/rptools/maptool/client/MapToolClient.java @@ -211,7 +211,9 @@ public List getPlayerList() { public void addPlayer(Player player) { if (!playerList.contains(player)) { playerList.add(player); - new MapToolEventBus().getMainEventBus().post(new PlayerConnected(player)); + new MapToolEventBus() + .getMainEventBus() + .post(new PlayerConnected(player, this.player.equals(player))); playerDatabase.playerSignedIn(player); playerList.sort((arg0, arg1) -> arg0.getName().compareToIgnoreCase(arg1.getName())); diff --git a/src/main/java/net/rptools/maptool/client/events/PlayerConnected.java b/src/main/java/net/rptools/maptool/client/events/PlayerConnected.java index 926daab8de..bedd35f374 100644 --- a/src/main/java/net/rptools/maptool/client/events/PlayerConnected.java +++ b/src/main/java/net/rptools/maptool/client/events/PlayerConnected.java @@ -16,4 +16,4 @@ import net.rptools.maptool.model.player.Player; -public record PlayerConnected(Player player) {} +public record PlayerConnected(Player player, boolean isLocal) {} diff --git a/src/main/java/net/rptools/maptool/client/swing/PlayersLoadingStatusBar.java b/src/main/java/net/rptools/maptool/client/swing/PlayersLoadingStatusBar.java index 7416db36b4..43363c3279 100644 --- a/src/main/java/net/rptools/maptool/client/swing/PlayersLoadingStatusBar.java +++ b/src/main/java/net/rptools/maptool/client/swing/PlayersLoadingStatusBar.java @@ -16,6 +16,7 @@ import com.google.common.eventbus.Subscribe; import java.awt.Dimension; +import java.util.ArrayList; import javax.swing.Icon; import javax.swing.JLabel; import net.rptools.maptool.client.MapTool; @@ -46,7 +47,10 @@ public PlayersLoadingStatusBar() { } private void refreshCount() { - var players = MapTool.getPlayerList(); + var localPlayer = MapTool.getPlayer(); + var players = new ArrayList<>(MapTool.getPlayerList()); + players.remove(localPlayer); + var total = players.size(); var loaded = players.stream().filter(x -> x.getLoaded()).count(); diff --git a/src/main/java/net/rptools/maptool/client/ui/connections/ClientConnectionPanel.java b/src/main/java/net/rptools/maptool/client/ui/connections/ClientConnectionPanel.java index f2a5d95fa1..b930a456bc 100644 --- a/src/main/java/net/rptools/maptool/client/ui/connections/ClientConnectionPanel.java +++ b/src/main/java/net/rptools/maptool/client/ui/connections/ClientConnectionPanel.java @@ -111,6 +111,10 @@ public ClientConnectionPanel() { @Subscribe private void onPlayerConnected(PlayerConnected event) { + if (event.isLocal()) { + return; + } + listModel.addElement(event.player()); } From 109a042b2b4742d5c55017a4f4ecf2e60a01288c Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Sun, 6 Oct 2024 16:50:06 -0700 Subject: [PATCH 6/7] Refactor PlayerLoadingStatusBar to keep its own list of players It already subscribes to the necessary events to keep it up-to-date. Also no more need for the self check. --- .../client/swing/PlayersLoadingStatusBar.java | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/main/java/net/rptools/maptool/client/swing/PlayersLoadingStatusBar.java b/src/main/java/net/rptools/maptool/client/swing/PlayersLoadingStatusBar.java index 43363c3279..a488df70d8 100644 --- a/src/main/java/net/rptools/maptool/client/swing/PlayersLoadingStatusBar.java +++ b/src/main/java/net/rptools/maptool/client/swing/PlayersLoadingStatusBar.java @@ -41,30 +41,21 @@ public class PlayersLoadingStatusBar extends JLabel { loadingIcon = RessourceManager.getSmallIcon(Icons.STATUSBAR_PLAYERS_LOADING); } + private final ArrayList players = new ArrayList<>(); + public PlayersLoadingStatusBar() { refreshCount(); new MapToolEventBus().getMainEventBus().register(this); } private void refreshCount() { - var localPlayer = MapTool.getPlayer(); - var players = new ArrayList<>(MapTool.getPlayerList()); - players.remove(localPlayer); - var total = players.size(); var loaded = players.stream().filter(x -> x.getLoaded()).count(); var sb = new StringBuilder(I18N.getText("ConnectionStatusPanel.playersLoadedZone", loaded, total)); - var self = MapTool.getPlayer(); - for (Player player : players) { - // The Player in the list is a seperate entity to the one from MapTool.getPlayer() - // So it doesn't have the correct status data. - if (player.getName().equals(self.getName())) { - player = self; - } var zone = player.getZoneId() == null ? null : MapTool.getCampaign().getZone(player.getZoneId()); @@ -108,6 +99,11 @@ public Dimension getPreferredSize() { @Subscribe private void onPlayerConnected(PlayerConnected event) { + if (event.isLocal()) { + return; + } + players.add(event.player()); + refreshCount(); } @@ -118,11 +114,13 @@ private void onPlayerStatusChanged(PlayerStatusChanged event) { @Subscribe private void onPlayerDisconnected(PlayerDisconnected event) { + players.remove(event.player()); refreshCount(); } @Subscribe private void onServerDisconnected(ServerDisconnected event) { + players.clear(); refreshCount(); } } From 438c2c7853a5c4c77862ba4f172db26df406670b Mon Sep 17 00:00:00 2001 From: bubblobill <45483160+bubblobill@users.noreply.github.com> Date: Wed, 9 Oct 2024 15:49:37 +0800 Subject: [PATCH 7/7] Could not find a definite point where deleting a macro updated the hotkey list. Added updateKeyStrokes call to both macro deleting methods. --- .../net/rptools/maptool/client/functions/MacroFunctions.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/net/rptools/maptool/client/functions/MacroFunctions.java b/src/main/java/net/rptools/maptool/client/functions/MacroFunctions.java index 89a9a1011d..93a23a1e09 100644 --- a/src/main/java/net/rptools/maptool/client/functions/MacroFunctions.java +++ b/src/main/java/net/rptools/maptool/client/functions/MacroFunctions.java @@ -943,6 +943,7 @@ private String removeMacro(int index, boolean gmPanel) throws ParserException { } AbstractMacroPanel macroPanel = gmPanel ? MapTool.getFrame().getGmPanel() : MapTool.getFrame().getCampaignPanel(); + MapTool.getFrame().updateKeyStrokes(); // ensure hotkeys are updated macroPanel.reset(); return "Removed macro button " + label @@ -970,6 +971,7 @@ private String removeMacro(int index, Token token) throws ParserException { String label = mbp.getLabel(); MapTool.serverCommand().updateTokenProperty(token, Token.Update.deleteMacro, index); + MapTool.getFrame().updateKeyStrokes(); // ensure hotkeys are updated return "Removed macro button " + label + "(index = " + index + ") from " + token.getName(); }