From 2e2e50643cdbee43139f8886eacbbb644d08e7e1 Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Sat, 26 Jul 2025 21:44:21 -0700 Subject: [PATCH 01/14] Clear marker list before updating --- .../java/net/rptools/maptool/client/ui/zone/ZoneViewModel.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/net/rptools/maptool/client/ui/zone/ZoneViewModel.java b/src/main/java/net/rptools/maptool/client/ui/zone/ZoneViewModel.java index ef9d816e1c..c34861d170 100644 --- a/src/main/java/net/rptools/maptool/client/ui/zone/ZoneViewModel.java +++ b/src/main/java/net/rptools/maptool/client/ui/zone/ZoneViewModel.java @@ -385,6 +385,8 @@ private void updateTokenPositions() { } private void updateMarkerPositions() { + markerList.clear(); + for (var list : tokenPositionsByLayer.values()) { for (var tokenPosition : list) { var token = tokenPosition.token(); From 22afb49866dc16fcd6e88e0b7dcf94166e2690f4 Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Sat, 26 Jul 2025 21:52:42 -0700 Subject: [PATCH 02/14] Document which fields are updated (and thus need to be cleared) by each update method in ZoneViewModel --- .../maptool/client/ui/zone/ZoneViewModel.java | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/rptools/maptool/client/ui/zone/ZoneViewModel.java b/src/main/java/net/rptools/maptool/client/ui/zone/ZoneViewModel.java index c34861d170..1b8f184b50 100644 --- a/src/main/java/net/rptools/maptool/client/ui/zone/ZoneViewModel.java +++ b/src/main/java/net/rptools/maptool/client/ui/zone/ZoneViewModel.java @@ -261,15 +261,16 @@ public void update() { updateLightPosition(); } + // What follows are "systems". + + /** Updates {@link #isUsingGdxRenderer}. */ private void updateIsUsingGdxRenderer() { isUsingGdxRenderer = MapTool.getFrame().getGdxPanel().isVisible(); } - // What follows are "systems". - /** - * If the zone is not already loaded, updates the loading status and emits {@link ZoneLoaded} if - * it becomes loaded. + * If the zone is not already loaded, updates the {@link #loadingProgress} and emits {@link + * ZoneLoaded} if it becomes loaded. */ private void updateIsLoading() { if (loadingProgress == null) { @@ -324,6 +325,7 @@ private void updateIsLoading() { } } + /** Updates {@link #zoneScale} and {@link #viewport}. */ private void updateViewport() { var renderer = MapTool.getFrame().getZoneRenderer(this.zone); if (renderer == null) { @@ -338,10 +340,12 @@ private void updateViewport() { viewport.setFrame(zoneScale.toWorldSpace(screenBounds)); } + /** Updates {@link #visibleArea} based on {@link #playerView}. */ private void updateVisibleArea() { visibleArea = zoneView.getVisibleArea(playerView); } + /** Updates {@link #selectedTokenList}. */ private void updateSelectedTokensList() { selectedTokenList.clear(); @@ -353,6 +357,7 @@ private void updateSelectedTokensList() { } } + /** Updates {@link #playerView}. */ private void updatePlayerView() { playerView = makePlayerView(MapTool.getPlayer().getEffectiveRole(), true); } @@ -384,6 +389,7 @@ private void updateTokenPositions() { } } + /** Updates {@link #markerList} based on {@link #tokenPositionsByLayer}. */ private void updateMarkerPositions() { markerList.clear(); @@ -399,6 +405,7 @@ private void updateMarkerPositions() { } } + /** Updates {@link #tokenStackMap} based on {@link #tokenPositionsByLayer}. */ private void updateTokenStacks() { tokenStackMap.clear(); var tokenPositions = tokenPositionsByLayer.get(Zone.Layer.TOKEN); @@ -434,6 +441,10 @@ private void updateTokenStacks() { } } + /** + * Updates {@link #onScreenTokens} and {@link #visibleTokensByLayer} based on {@link + * #tokenPositionsByLayer}, {@link #viewport}, {@link #playerView}, and {@link #visibleArea}. + */ private void updateVisibleTokens() { double scale = 1; var renderer = MapTool.getFrame().getZoneRenderer(this.zone); @@ -474,6 +485,7 @@ private void updateVisibleTokens() { } } + /** Updates {@link #movingTokens}. */ private void updateMovingTokens() { movingTokens.clear(); @@ -487,6 +499,10 @@ private void updateMovingTokens() { } } + /** + * Updates {@link #lightPositions} based on {@link #playerView}, {@link #tokenPositions}, and + * {@link #onScreenTokens}. + */ private void updateLightPosition() { lightPositions.clear(); From 8cbd6ee188008c40882f5f00a1b4bdb888d0d954 Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Tue, 5 Aug 2025 07:03:45 -0700 Subject: [PATCH 03/14] Do not show token popup menu while dragging map _Fix applies to both PointerTool and StampTool_ When releasing the mouse, we grab the current drag state before it gets cleared, so that we know whether the user was dragging the map. This is in lieu of a more comprehensive change to `PointerTool` and `StampTool` that would isolate different user actions to ensure this kind of thing can't happen. --- .../java/net/rptools/maptool/client/tool/PointerTool.java | 5 +++-- src/main/java/net/rptools/maptool/client/tool/StampTool.java | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/rptools/maptool/client/tool/PointerTool.java b/src/main/java/net/rptools/maptool/client/tool/PointerTool.java index 654961d98f..b2bb1f0970 100644 --- a/src/main/java/net/rptools/maptool/client/tool/PointerTool.java +++ b/src/main/java/net/rptools/maptool/client/tool/PointerTool.java @@ -478,6 +478,8 @@ public void mousePressed(MouseEvent e) { @Override public void mouseReleased(MouseEvent e) { + final boolean isDraggingMap = isDraggingMap(); + super.mouseReleased(e); mouseButtonDown = false; @@ -563,7 +565,7 @@ public void mouseReleased(MouseEvent e) { } // POPUP MENU - if (SwingUtilities.isRightMouseButton(e) && tokenDragOp == null && !isDraggingMap()) { + if (SwingUtilities.isRightMouseButton(e) && tokenDragOp == null && !isDraggingMap) { final var selectionModel = renderer.getSelectionModel(); if (tokenUnderMouse != null && !selectionModel.isSelected(tokenUnderMouse.getId())) { if (!SwingUtil.isShiftDown(e)) { @@ -585,7 +587,6 @@ public void mouseReleased(MouseEvent e) { return; } } - super.mouseReleased(e); } // // diff --git a/src/main/java/net/rptools/maptool/client/tool/StampTool.java b/src/main/java/net/rptools/maptool/client/tool/StampTool.java index af3dbe5f4f..15c81e10ff 100644 --- a/src/main/java/net/rptools/maptool/client/tool/StampTool.java +++ b/src/main/java/net/rptools/maptool/client/tool/StampTool.java @@ -377,6 +377,8 @@ public void mousePressed(MouseEvent e) { @Override public void mouseReleased(MouseEvent e) { + final boolean isDraggingMap = isDraggingMap(); + super.mouseReleased(e); if (isShowingTokenStackPopup) { @@ -446,7 +448,7 @@ public void mouseReleased(MouseEvent e) { return; } // POPUP MENU - if (SwingUtilities.isRightMouseButton(e) && tokenDragOp == null && !isDraggingMap()) { + if (SwingUtilities.isRightMouseButton(e) && tokenDragOp == null && !isDraggingMap) { final var selectionModel = renderer.getSelectionModel(); if (tokenUnderMouse != null && !selectionModel.isSelected(tokenUnderMouse.getId())) { if (!SwingUtil.isShiftDown(e)) { @@ -469,7 +471,6 @@ public void mouseReleased(MouseEvent e) { return; } } - super.mouseReleased(e); } // // From 190f78657df4d7948556b27985e81813b6443de7 Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Wed, 13 Aug 2025 15:40:21 -0700 Subject: [PATCH 04/14] Calculate selected token list on demand This is more wasteful, but is identical to 1.17 behaviour and avoids the possibility of stale selection data in case the zone has not been rerendered after a selection chnage. --- .../maptool/client/ui/zone/ZoneViewModel.java | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/src/main/java/net/rptools/maptool/client/ui/zone/ZoneViewModel.java b/src/main/java/net/rptools/maptool/client/ui/zone/ZoneViewModel.java index 1b8f184b50..ba41fb54f6 100644 --- a/src/main/java/net/rptools/maptool/client/ui/zone/ZoneViewModel.java +++ b/src/main/java/net/rptools/maptool/client/ui/zone/ZoneViewModel.java @@ -108,7 +108,6 @@ public static TokenPosition fromToken(Token token, Zone zone) { private final Rectangle2D viewport = new Rectangle2D.Double(); private Area visibleArea = new Area(); - private final List selectedTokenList = new ArrayList<>(); private final Set movingTokens = new HashSet<>(); private final Map tokenPositions = new HashMap<>(); @@ -222,7 +221,14 @@ public Map> getTokenStackMap() { } public List getSelectedTokenList() { - return Collections.unmodifiableList(selectedTokenList); + var tokens = new ArrayList(); + for (GUID g : selectionModel.getSelectedTokenIds()) { + final var token = zone.getToken(g); + if (token != null) { + tokens.add(token); + } + } + return tokens; } public Set getVisibleTokens(Zone.Layer layer) { @@ -252,7 +258,6 @@ public void update() { updateViewport(); updatePlayerView(); updateVisibleArea(); - updateSelectedTokensList(); updateMovingTokens(); updateTokenPositions(); updateMarkerPositions(); @@ -345,18 +350,6 @@ private void updateVisibleArea() { visibleArea = zoneView.getVisibleArea(playerView); } - /** Updates {@link #selectedTokenList}. */ - private void updateSelectedTokensList() { - selectedTokenList.clear(); - - for (GUID g : selectionModel.getSelectedTokenIds()) { - final var token = zone.getToken(g); - if (token != null) { - selectedTokenList.add(token); - } - } - } - /** Updates {@link #playerView}. */ private void updatePlayerView() { playerView = makePlayerView(MapTool.getPlayer().getEffectiveRole(), true); From c24b1661743a1ec2b62919a8f953cfbec3ca98fb Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Thu, 28 Aug 2025 08:27:52 -0700 Subject: [PATCH 05/14] Remove redundant application of token opacity `TokenRenderer` applies the token opacity, so callers do not need to pass it in. They should only pass additional opacity, such as that used to indicate a dragged token. --- .../maptool/client/ui/zone/renderer/ZoneRenderer.java | 8 +++----- .../ui/zone/renderer/tokenRender/TokenRenderer.java | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/rptools/maptool/client/ui/zone/renderer/ZoneRenderer.java b/src/main/java/net/rptools/maptool/client/ui/zone/renderer/ZoneRenderer.java index e54a3095b1..95a320724b 100644 --- a/src/main/java/net/rptools/maptool/client/ui/zone/renderer/ZoneRenderer.java +++ b/src/main/java/net/rptools/maptool/client/ui/zone/renderer/ZoneRenderer.java @@ -1815,11 +1815,9 @@ protected void renderTokens( // Render Halo haloRenderer.renderHalo(tokenG, token, position); - // Calculate alpha Transparency from token and use opacity to indicate that token is moving - float opacity = token.getTokenOpacity(); - if (viewModel.isTokenMoving(token.getId())) { - opacity = opacity / 2.0f; - } + // Use opacity to indicate that token is moving + float opacity = viewModel.isTokenMoving(token.getId()) ? 0.5f : 1f; + // Finally render the token image timer.start("token-list-7"); // Clipping is handled in the isTokenInNeedOfClipping() call far above. diff --git a/src/main/java/net/rptools/maptool/client/ui/zone/renderer/tokenRender/TokenRenderer.java b/src/main/java/net/rptools/maptool/client/ui/zone/renderer/tokenRender/TokenRenderer.java index 1558e6996f..f1497a8a98 100644 --- a/src/main/java/net/rptools/maptool/client/ui/zone/renderer/tokenRender/TokenRenderer.java +++ b/src/main/java/net/rptools/maptool/client/ui/zone/renderer/tokenRender/TokenRenderer.java @@ -47,7 +47,7 @@ public TokenRenderer(RenderHelper renderHelper, Zone zone) { this.zone = zone; } - public void renderToken(Token token, TokenPosition position, Graphics2D g2d, float opacity) { + public void renderToken(Token token, TokenPosition position, Graphics2D g2d, float extraOpacity) { var timer = CodeTimer.get(); timer.increment("TokenRenderer-renderToken"); timer.start("TokenRenderer-renderToken"); @@ -60,7 +60,7 @@ public void renderToken(Token token, TokenPosition position, Graphics2D g2d, flo timer.start("TokenRenderer-paintTokenImage"); renderHelper.render( - g2d, worldG -> paintTokenImage(worldG, position, opacity * token.getTokenOpacity())); + g2d, worldG -> paintTokenImage(worldG, position, extraOpacity * token.getTokenOpacity())); timer.stop("TokenRenderer-paintTokenImage"); timer.stop("TokenRenderer-renderToken"); } From 6fa926d7cea2970a47c0d883aa50852c54f2c10b Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Wed, 3 Sep 2025 07:57:08 -0700 Subject: [PATCH 06/14] Respect the lack of macro button when editing campaign properties All the modifications of `MacroButtonProperties` still have to be gated behind a null check since campaign properties do not have `MacroButtonProperties`. --- .../dialog/MacroEditorDialog.java | 229 +++++++++--------- 1 file changed, 115 insertions(+), 114 deletions(-) diff --git a/src/main/java/net/rptools/maptool/client/ui/macrobuttons/dialog/MacroEditorDialog.java b/src/main/java/net/rptools/maptool/client/ui/macrobuttons/dialog/MacroEditorDialog.java index fa9e538699..229aa356d6 100644 --- a/src/main/java/net/rptools/maptool/client/ui/macrobuttons/dialog/MacroEditorDialog.java +++ b/src/main/java/net/rptools/maptool/client/ui/macrobuttons/dialog/MacroEditorDialog.java @@ -374,6 +374,11 @@ public void show(MacroButton button) { } public void show(MacroButtonProperties mbp) { + if (mbp == null) { + MapTool.showError(I18N.getText("msg.error.macro.buttonPropsAreNull")); + return; + } + String id = mbp.getMacroUUID(); if (openMacroList.contains(id)) { return; @@ -382,11 +387,6 @@ public void show(MacroButtonProperties mbp) { updateOpenMacroList(true); this.isTokenMacro = properties.getToken() != null; - if (properties == null) { - MapTool.showError(I18N.getText("msg.error.macro.buttonPropsAreNull")); - return; - } - oldHashCode = properties.hashCodeForComparison(); boolean playerCanEdit = !MapTool.getPlayer().isGM() && properties.getAllowPlayerEdits(); boolean onGlobalPanel = properties.getSaveLocation().equals("Global"); @@ -742,125 +742,126 @@ protected void executeAction() { private void save(boolean closeDialog) { callback.accept(getCommandTextArea().getText()); - String hotKey = getHotKeyCombo().getSelectedItem().toString(); - properties.setHotKey(hotKey); - properties.setColorKey(getColorComboBox().getSelectedItem().toString()); - properties.setLabel(getLabelTextField().getText()); - properties.setGroup(getGroupTextField().getText()); - properties.setSortby(getSortbyTextField().getText()); - properties.setCommand(getCommandTextArea().getText()); - properties.setAutoExecute(getAutoExecuteCheckBox().isSelected()); - properties.setIncludeLabel(getIncludeLabelCheckBox().isSelected()); - properties.setApplyToTokens(getApplyToTokensCheckBox().isSelected()); - properties.setFontColorKey(getFontColorComboBox().getSelectedItem().toString()); - properties.setFontSize(getFontSizeComboBox().getSelectedItem().toString()); - properties.setMinWidth(getMinWidthTextField().getText()); - properties.setMaxWidth(getMaxWidthTextField().getText()); - properties.setCompareGroup(getCompareGroupCheckBox().isSelected()); - properties.setCompareSortPrefix(getCompareSortPrefixCheckBox().isSelected()); - properties.setCompareCommand(getCompareCommandCheckBox().isSelected()); - properties.setCompareIncludeLabel(getCompareIncludeLabelCheckBox().isSelected()); - properties.setCompareAutoExecute(getCompareAutoExecuteCheckBox().isSelected()); - properties.setCompareApplyToSelectedTokens( - getCompareApplyToSelectedTokensCheckBox().isSelected()); - properties.setAllowPlayerEdits(getAllowPlayerEditsCheckBox().isSelected()); - properties.setToolTip(getToolTipTextField().getText()); - properties.setDisplayHotKey(getDisplayHotkeyCheckBox().isSelected()); - - properties.save(); - - if (button != null) { - - button.getHotKeyManager().assignKeyStroke(hotKey); - button.setColor(getColorComboBox().getSelectedItem().toString()); - button.setText(this.button.getButtonText()); - - if (button.getPanelClass().equals("SelectionPanel")) { - if (MapTool.getFrame() - .getSelectionPanel() - .getCommonMacros() - .contains(button.getProperties())) { - boolean changeAllowPlayerEdits = false; - boolean endingAllowPlayerEdits = false; - if (startingAllowPlayerEdits) { - if (!properties.getAllowPlayerEdits()) { - boolean confirmDisallowPlayerEdits = - MapTool.confirm(I18N.getText("confirm.macro.disallowPlayerEdits")); - if (confirmDisallowPlayerEdits) { - changeAllowPlayerEdits = true; - endingAllowPlayerEdits = false; - } else { - properties.setAllowPlayerEdits(true); + if (properties != null) { + String hotKey = getHotKeyCombo().getSelectedItem().toString(); + properties.setHotKey(hotKey); + properties.setColorKey(getColorComboBox().getSelectedItem().toString()); + properties.setLabel(getLabelTextField().getText()); + properties.setGroup(getGroupTextField().getText()); + properties.setSortby(getSortbyTextField().getText()); + properties.setCommand(getCommandTextArea().getText()); + properties.setAutoExecute(getAutoExecuteCheckBox().isSelected()); + properties.setIncludeLabel(getIncludeLabelCheckBox().isSelected()); + properties.setApplyToTokens(getApplyToTokensCheckBox().isSelected()); + properties.setFontColorKey(getFontColorComboBox().getSelectedItem().toString()); + properties.setFontSize(getFontSizeComboBox().getSelectedItem().toString()); + properties.setMinWidth(getMinWidthTextField().getText()); + properties.setMaxWidth(getMaxWidthTextField().getText()); + properties.setCompareGroup(getCompareGroupCheckBox().isSelected()); + properties.setCompareSortPrefix(getCompareSortPrefixCheckBox().isSelected()); + properties.setCompareCommand(getCompareCommandCheckBox().isSelected()); + properties.setCompareIncludeLabel(getCompareIncludeLabelCheckBox().isSelected()); + properties.setCompareAutoExecute(getCompareAutoExecuteCheckBox().isSelected()); + properties.setCompareApplyToSelectedTokens( + getCompareApplyToSelectedTokensCheckBox().isSelected()); + properties.setAllowPlayerEdits(getAllowPlayerEditsCheckBox().isSelected()); + properties.setToolTip(getToolTipTextField().getText()); + properties.setDisplayHotKey(getDisplayHotkeyCheckBox().isSelected()); + + properties.save(); + + if (button != null) { + button.getHotKeyManager().assignKeyStroke(hotKey); + button.setColor(getColorComboBox().getSelectedItem().toString()); + button.setText(this.button.getButtonText()); + + if (button.getPanelClass().equals("SelectionPanel")) { + if (MapTool.getFrame() + .getSelectionPanel() + .getCommonMacros() + .contains(button.getProperties())) { + boolean changeAllowPlayerEdits = false; + boolean endingAllowPlayerEdits = false; + if (startingAllowPlayerEdits) { + if (!properties.getAllowPlayerEdits()) { + boolean confirmDisallowPlayerEdits = + MapTool.confirm(I18N.getText("confirm.macro.disallowPlayerEdits")); + if (confirmDisallowPlayerEdits) { + changeAllowPlayerEdits = true; + endingAllowPlayerEdits = false; + } else { + properties.setAllowPlayerEdits(true); + } } - } - } else { - if (properties.getAllowPlayerEdits()) { - boolean confirmAllowPlayerEdits = - MapTool.confirm(I18N.getText("confirm.macro.allowPlayerEdits")); - if (confirmAllowPlayerEdits) { - changeAllowPlayerEdits = true; - endingAllowPlayerEdits = true; - } else { - properties.setAllowPlayerEdits(false); + } else { + if (properties.getAllowPlayerEdits()) { + boolean confirmAllowPlayerEdits = + MapTool.confirm(I18N.getText("confirm.macro.allowPlayerEdits")); + if (confirmAllowPlayerEdits) { + changeAllowPlayerEdits = true; + endingAllowPlayerEdits = true; + } else { + properties.setAllowPlayerEdits(false); + } } } - } - boolean trusted = true; - for (Token nextToken : - MapTool.getFrame().getCurrentZoneRenderer().getSelectedTokensList()) { - trusted = AppUtil.playerOwns(nextToken); - boolean isGM = MapTool.getPlayer().isGM(); - for (MacroButtonProperties nextMacro : nextToken.getMacroList(trusted)) { - if (isGM || nextMacro.getApplyToTokens()) { - if (nextMacro.hashCodeForComparison() == oldHashCode) { - nextMacro.setLabel(properties.getLabel()); - if (properties.getCompareGroup() && startingCompareGroup) { - nextMacro.setGroup(properties.getGroup()); - } - if (properties.getCompareSortPrefix() && startingCompareSortPrefix) { - nextMacro.setSortby(properties.getSortby()); - } - if (properties.getCompareCommand() && startingCompareCommand) { - nextMacro.setCommand(properties.getCommand()); - } - if (properties.getCompareAutoExecute() && startingCompareAutoExecute) { - nextMacro.setAutoExecute(properties.getAutoExecute()); - } - if (properties.getCompareIncludeLabel() && startingCompareIncludeLabel) { - nextMacro.setIncludeLabel(properties.getIncludeLabel()); + boolean trusted = true; + for (Token nextToken : + MapTool.getFrame().getCurrentZoneRenderer().getSelectedTokensList()) { + trusted = AppUtil.playerOwns(nextToken); + boolean isGM = MapTool.getPlayer().isGM(); + for (MacroButtonProperties nextMacro : nextToken.getMacroList(trusted)) { + if (isGM || nextMacro.getApplyToTokens()) { + if (nextMacro.hashCodeForComparison() == oldHashCode) { + nextMacro.setLabel(properties.getLabel()); + if (properties.getCompareGroup() && startingCompareGroup) { + nextMacro.setGroup(properties.getGroup()); + } + if (properties.getCompareSortPrefix() && startingCompareSortPrefix) { + nextMacro.setSortby(properties.getSortby()); + } + if (properties.getCompareCommand() && startingCompareCommand) { + nextMacro.setCommand(properties.getCommand()); + } + if (properties.getCompareAutoExecute() && startingCompareAutoExecute) { + nextMacro.setAutoExecute(properties.getAutoExecute()); + } + if (properties.getCompareIncludeLabel() && startingCompareIncludeLabel) { + nextMacro.setIncludeLabel(properties.getIncludeLabel()); + } + if (properties.getCompareApplyToSelectedTokens() + && startingCompareApplyToSelectedTokens) { + nextMacro.setApplyToTokens(properties.getApplyToTokens()); + } + if (changeAllowPlayerEdits) { + nextMacro.setAllowPlayerEdits(endingAllowPlayerEdits); + } + nextMacro.setCompareGroup(properties.getCompareGroup()); + nextMacro.setCompareSortPrefix(properties.getCompareSortPrefix()); + nextMacro.setCompareCommand(properties.getCompareCommand()); + nextMacro.setCompareAutoExecute(properties.getCompareAutoExecute()); + nextMacro.setCompareIncludeLabel(properties.getCompareIncludeLabel()); + nextMacro.setCompareApplyToSelectedTokens( + properties.getCompareApplyToSelectedTokens()); + nextMacro.save(); } - if (properties.getCompareApplyToSelectedTokens() - && startingCompareApplyToSelectedTokens) { - nextMacro.setApplyToTokens(properties.getApplyToTokens()); - } - if (changeAllowPlayerEdits) { - nextMacro.setAllowPlayerEdits(endingAllowPlayerEdits); - } - nextMacro.setCompareGroup(properties.getCompareGroup()); - nextMacro.setCompareSortPrefix(properties.getCompareSortPrefix()); - nextMacro.setCompareCommand(properties.getCompareCommand()); - nextMacro.setCompareAutoExecute(properties.getCompareAutoExecute()); - nextMacro.setCompareIncludeLabel(properties.getCompareIncludeLabel()); - nextMacro.setCompareApplyToSelectedTokens( - properties.getCompareApplyToSelectedTokens()); - nextMacro.save(); } } } } + MapTool.getFrame().getSelectionPanel().reset(); + } + if (button.getPanelClass().equals("CampaignPanel")) { + MapTool.serverCommand() + .updateCampaignMacros(MapTool.getCampaign().getMacroButtonPropertiesArray()); + MapTool.getFrame().getCampaignPanel().reset(); } - MapTool.getFrame().getSelectionPanel().reset(); - } - if (button.getPanelClass().equals("CampaignPanel")) { - MapTool.serverCommand() - .updateCampaignMacros(MapTool.getCampaign().getMacroButtonPropertiesArray()); - MapTool.getFrame().getCampaignPanel().reset(); - } - if (button.getPanelClass().equals("GmPanel")) { - MapTool.serverCommand() - .updateGmMacros(MapTool.getCampaign().getGmMacroButtonPropertiesArray()); - MapTool.getFrame().getGmPanel().reset(); + if (button.getPanelClass().equals("GmPanel")) { + MapTool.serverCommand() + .updateGmMacros(MapTool.getCampaign().getGmMacroButtonPropertiesArray()); + MapTool.getFrame().getGmPanel().reset(); + } } } From 4e01ffb66f7a761f1e6c74bb9ec5e65c82e63a4c Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Wed, 3 Sep 2025 08:07:13 -0700 Subject: [PATCH 07/14] Privatize MacroEditorDialog fields and remove commented code --- .../dialog/MacroEditorDialog.java | 36 ++++++------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/src/main/java/net/rptools/maptool/client/ui/macrobuttons/dialog/MacroEditorDialog.java b/src/main/java/net/rptools/maptool/client/ui/macrobuttons/dialog/MacroEditorDialog.java index 229aa356d6..5ef620a266 100644 --- a/src/main/java/net/rptools/maptool/client/ui/macrobuttons/dialog/MacroEditorDialog.java +++ b/src/main/java/net/rptools/maptool/client/ui/macrobuttons/dialog/MacroEditorDialog.java @@ -78,17 +78,17 @@ public class MacroEditorDialog extends JDialog implements SearchListener { private static final long serialVersionUID = 8228617911117087993L; private static final Logger log = LogManager.getLogger(MacroEditorDialog.class); private final AbeillePanel panel; - MacroButton button; - MacroButtonProperties properties; - boolean isTokenMacro = false; - int oldHashCode = 0; - Boolean startingCompareGroup; - Boolean startingCompareSortPrefix; - Boolean startingCompareCommand; - Boolean startingCompareIncludeLabel; - Boolean startingCompareAutoExecute; - Boolean startingCompareApplyToSelectedTokens; - Boolean startingAllowPlayerEdits; + private MacroButton button; + private MacroButtonProperties properties; + private boolean isTokenMacro = false; + private int oldHashCode = 0; + private Boolean startingCompareGroup; + private Boolean startingCompareSortPrefix; + private Boolean startingCompareCommand; + private Boolean startingCompareIncludeLabel; + private Boolean startingCompareAutoExecute; + private Boolean startingCompareApplyToSelectedTokens; + private Boolean startingAllowPlayerEdits; private final RSyntaxTextArea macroEditorRSyntaxTextArea = new RSyntaxTextArea(2, 2); private CollapsibleSectionPanel csp; @@ -726,20 +726,6 @@ protected void executeAction() { } } - // Jamz: maybe later... - // public void rememberLastWindowLocation() { - // Dimension windowSize = this.getSize(); - // - // int x = outerWindow.getLocation().x + (outerSize.width - innerSize.width) - // / 2; - // int y = outerWindow.getLocation().y + (outerSize.height - - // innerSize.height) / 2; - // - // Jamz: For multiple monitor's, x & y can be negative values... - // innerWindow.setLocation(x < 0 ? 0 : x, y < 0 ? 0 : y); - // innerWindow.setLocation(x, y); - // } - private void save(boolean closeDialog) { callback.accept(getCommandTextArea().getText()); if (properties != null) { From 2c5b36d6c6149b22dc14f875250b4012d8e246de Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Wed, 3 Sep 2025 08:40:25 -0700 Subject: [PATCH 08/14] In HTMLContent, all raw HTML strings do not have bridge or base URL The associated `HtmlDocument` constructor no longer has `isJavaBridgeInjected` or `isBaseUrlInjected` parameters since these have to be `false`. --- .../maptool/client/ui/htmlframe/HTMLContent.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/rptools/maptool/client/ui/htmlframe/HTMLContent.java b/src/main/java/net/rptools/maptool/client/ui/htmlframe/HTMLContent.java index 53dd269644..91bbb6fb98 100644 --- a/src/main/java/net/rptools/maptool/client/ui/htmlframe/HTMLContent.java +++ b/src/main/java/net/rptools/maptool/client/ui/htmlframe/HTMLContent.java @@ -141,9 +141,8 @@ private record HtmlDocumentContent( document.outputSettings().charset(StandardCharsets.US_ASCII); } - public HtmlDocumentContent( - String str, boolean isJavaBridgeInjected, boolean isBaseUrlInjected) { - this(Jsoup.parse(str), isJavaBridgeInjected, isBaseUrlInjected); + public HtmlDocumentContent(String str) { + this(Jsoup.parse(str), false, false); } public String str() { @@ -176,7 +175,7 @@ private HTMLContent(Content content) { * @return an HTMLContent object */ public static HTMLContent htmlFromString(@Nonnull String html) { - return new HTMLContent(new HtmlDocumentContent(html, false, false)); + return new HTMLContent(new HtmlDocumentContent(html)); } /** @@ -333,7 +332,7 @@ public HTMLContent fetchContent() throws IOException { var assetType = Asset.Type.fromMediaType(mediaType); if (assetType == Asset.Type.HTML) { - return new HTMLContent(new HtmlDocumentContent(html, false, false)); + return new HTMLContent(new HtmlDocumentContent(html)); } return new HTMLContent(new StringContent(html)); } @@ -343,7 +342,7 @@ public HTMLContent fetchContent() throws IOException { if (asset != null) { if (asset.isStringAsset()) { if (asset.getType() == Asset.Type.HTML) { - return new HTMLContent(new HtmlDocumentContent(asset.getDataAsString(), false, false)); + return new HTMLContent(new HtmlDocumentContent(asset.getDataAsString())); } return new HTMLContent(new StringContent(asset.getDataAsString())); } else { From 4a71a923a2c0921c8fe2b8a58fe5eeb49c0cd527 Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Wed, 3 Sep 2025 08:40:46 -0700 Subject: [PATCH 09/14] Fixup the HTML when constructing `HtmlDocument` This make `cachelib` be consistently applied to HTML5 content again. --- .../net/rptools/maptool/client/ui/htmlframe/HTMLContent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/rptools/maptool/client/ui/htmlframe/HTMLContent.java b/src/main/java/net/rptools/maptool/client/ui/htmlframe/HTMLContent.java index 91bbb6fb98..0ba0913ff0 100644 --- a/src/main/java/net/rptools/maptool/client/ui/htmlframe/HTMLContent.java +++ b/src/main/java/net/rptools/maptool/client/ui/htmlframe/HTMLContent.java @@ -142,7 +142,7 @@ private record HtmlDocumentContent( } public HtmlDocumentContent(String str) { - this(Jsoup.parse(str), false, false); + this(Jsoup.parse(HTMLPanelInterface.fixHTML(str)), false, false); } public String str() { From 155bf29cfa81f0162013a734122f822a5a0a9bfe Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Wed, 10 Sep 2025 10:36:51 -0700 Subject: [PATCH 10/14] Apply correct clipping --- .../rptools/maptool/client/ui/zone/renderer/ZoneRenderer.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/rptools/maptool/client/ui/zone/renderer/ZoneRenderer.java b/src/main/java/net/rptools/maptool/client/ui/zone/renderer/ZoneRenderer.java index 95a320724b..d294f3f230 100644 --- a/src/main/java/net/rptools/maptool/client/ui/zone/renderer/ZoneRenderer.java +++ b/src/main/java/net/rptools/maptool/client/ui/zone/renderer/ZoneRenderer.java @@ -1782,10 +1782,12 @@ protected void renderTokens( if (isTokenInNeedOfClipping(token, position.transformedBounds(), isGMView)) { tokenG = (Graphics2D) clippedG.create(); if (token.getShape() == Token.TokenShape.FIGURE || token.isAlwaysVisible()) { + Area cellVisibleArea = new Area(visibleScreenArea); Area cb = zone.getGrid() .getTokenCellArea(zoneScale.toScreenSpace(position.transformedBounds())); - tokenG.clip(cb); + cellVisibleArea.intersect(cb); + tokenG.clip(cellVisibleArea); } } else { tokenG = (Graphics2D) g.create(); From 76011ee59c05d65be37faeff8a640b614cc0f7cb Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Mon, 15 Sep 2025 20:31:39 -0700 Subject: [PATCH 11/14] Fix FacingArrowRenderer-preCheck timer --- .../tokenRender/FacingArrowRenderer.java | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/main/java/net/rptools/maptool/client/ui/zone/renderer/tokenRender/FacingArrowRenderer.java b/src/main/java/net/rptools/maptool/client/ui/zone/renderer/tokenRender/FacingArrowRenderer.java index 5b0aeef38f..fb28e0e6b3 100644 --- a/src/main/java/net/rptools/maptool/client/ui/zone/renderer/tokenRender/FacingArrowRenderer.java +++ b/src/main/java/net/rptools/maptool/client/ui/zone/renderer/tokenRender/FacingArrowRenderer.java @@ -68,19 +68,22 @@ public void paintArrow(Graphics2D tokenG, TokenPosition position) { var tokenShape = token.getShape(); timer.start("FacingArrowRenderer-preCheck"); - if (!token.hasFacing()) { - return; - } - final var forceFacing = AppPreferences.forceFacingArrow.get(); - if (!forceFacing) { - if (TokenShape.TOP_DOWN.equals(tokenShape)) { + try { + if (!token.hasFacing()) { return; } - if (TokenShape.FIGURE.equals(tokenShape) && token.getHasImageTable()) { - return; + final var forceFacing = AppPreferences.forceFacingArrow.get(); + if (!forceFacing) { + if (TokenShape.TOP_DOWN.equals(tokenShape)) { + return; + } + if (TokenShape.FIGURE.equals(tokenShape) && token.getHasImageTable()) { + return; + } } + } finally { + timer.stop("FacingArrowRenderer-preCheck"); } - timer.stop("FacingArrowRenderer-preCheck"); timer.start("FacingArrowRenderer-render"); renderHelper.render( From 6db85d6c6c1fe2faf584a164fe3add78d0617cbb Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Mon, 15 Sep 2025 20:32:28 -0700 Subject: [PATCH 12/14] Fix renderFog-hardFow timer --- .../rptools/maptool/client/ui/zone/renderer/FogRenderer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/rptools/maptool/client/ui/zone/renderer/FogRenderer.java b/src/main/java/net/rptools/maptool/client/ui/zone/renderer/FogRenderer.java index 154200c656..10f4e17e7e 100644 --- a/src/main/java/net/rptools/maptool/client/ui/zone/renderer/FogRenderer.java +++ b/src/main/java/net/rptools/maptool/client/ui/zone/renderer/FogRenderer.java @@ -95,7 +95,7 @@ private void renderWorld(Graphics2D worldG, PlayerView view) { worldG.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, view.isGMView() ? .6f : 1f)); var bounds = originalClip.getBounds(); worldG.fillRect(bounds.x, bounds.y, bounds.width, bounds.height); - timer.start("renderFog-hardFow"); + timer.stop("renderFog-hardFow"); timer.start("renderFog-softFow"); if (!softFogArea.isEmpty()) { From 5b4fb0f77ce34da735baaa7d966298c087046f5d Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Mon, 15 Sep 2025 20:33:05 -0700 Subject: [PATCH 13/14] ZoneRenderer should not check GDX panel visibility directly --- .../rptools/maptool/client/ui/zone/renderer/ZoneRenderer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/rptools/maptool/client/ui/zone/renderer/ZoneRenderer.java b/src/main/java/net/rptools/maptool/client/ui/zone/renderer/ZoneRenderer.java index 95a320724b..fab7b6ee50 100644 --- a/src/main/java/net/rptools/maptool/client/ui/zone/renderer/ZoneRenderer.java +++ b/src/main/java/net/rptools/maptool/client/ui/zone/renderer/ZoneRenderer.java @@ -714,7 +714,7 @@ public void paintComponent(Graphics g) { timer -> { timer.setThreshold(10); - if (!MapTool.getFrame().getGdxPanel().isVisible()) { + if (!viewModel.isUsingGdxRenderer()) { timer.start("paintComponent"); Graphics2D g2d = (Graphics2D) g; From 5498bda5e1350f98e001f1be854003b4a1202c01 Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Mon, 15 Sep 2025 20:35:11 -0700 Subject: [PATCH 14/14] Remove LibGDX renderer --- .../maptool/client/DeveloperOptions.java | 6 --- .../maptool/client/ui/MapToolFrame.java | 39 ------------------- .../maptool/client/ui/ToolbarPanel.java | 17 -------- .../maptool/client/ui/zone/ZoneViewModel.java | 2 +- 4 files changed, 1 insertion(+), 63 deletions(-) diff --git a/src/main/java/net/rptools/maptool/client/DeveloperOptions.java b/src/main/java/net/rptools/maptool/client/DeveloperOptions.java index 485faaa312..298f965911 100644 --- a/src/main/java/net/rptools/maptool/client/DeveloperOptions.java +++ b/src/main/java/net/rptools/maptool/client/DeveloperOptions.java @@ -55,12 +55,6 @@ public static final class Toggle { "Preferences.developer.debugTokenDragging.label", "Preferences.developer.debugTokenDragging.tooltip", false); - public static final Preference EnableLibGdxRendererToggleButton = - store.defineBoolean( - "enableLibGDXRendererToggleButton", - "Preferences.developer.enableLibGDXRendererToggleButton.label", - "Preferences.developer.enableLibGDXRendererToggleButton.tooltip", - false); public static List> getOptions() { return store.getDefinedPreferences().stream() diff --git a/src/main/java/net/rptools/maptool/client/ui/MapToolFrame.java b/src/main/java/net/rptools/maptool/client/ui/MapToolFrame.java index 2def723e30..096f799622 100644 --- a/src/main/java/net/rptools/maptool/client/ui/MapToolFrame.java +++ b/src/main/java/net/rptools/maptool/client/ui/MapToolFrame.java @@ -14,13 +14,10 @@ */ package net.rptools.maptool.client.ui; -import com.badlogic.gdx.backends.jogamp.JoglAwtApplicationConfiguration; -import com.badlogic.gdx.backends.jogamp.JoglSwingCanvas; import com.google.common.eventbus.Subscribe; import com.jidesoft.docking.DefaultDockableHolder; import com.jidesoft.docking.DockableFrame; import com.jidesoft.docking.DockingManager; -import com.jogamp.opengl.awt.GLJPanel; import java.awt.*; import java.awt.event.*; import java.awt.image.BufferedImage; @@ -96,7 +93,6 @@ import net.rptools.maptool.client.ui.zone.PointerOverlay; import net.rptools.maptool.client.ui.zone.PointerToolOverlay; import net.rptools.maptool.client.ui.zone.ZoneMiniMapPanel; -import net.rptools.maptool.client.ui.zone.gdx.GdxRenderer; import net.rptools.maptool.client.ui.zone.renderer.ZoneRenderer; import net.rptools.maptool.events.MapToolEventBus; import net.rptools.maptool.language.I18N; @@ -159,8 +155,6 @@ public class MapToolFrame extends DefaultDockableHolder implements WindowListene /** Contains the zoneRenderer, as well as all overlays. */ private final JPanel zoneRendererPanel; - private GLJPanel gdxPanel; - private JPanel currentRenderPanel; /** Contains the overlays that should be displayed in front of everything else. */ @@ -416,11 +410,9 @@ public MapToolFrame(JMenuBar menuBar) { zoneRendererPanel = new JPanel(new PositionalLayout(5)); zoneRendererPanel.setBackground(Color.black); currentRenderPanel = zoneRendererPanel; - initGdx(); zoneRendererPanel.add(getChatTypingPanel(), PositionalLayout.Position.NW); zoneRendererPanel.add(getChatActionLabel(), PositionalLayout.Position.SW); - zoneRendererPanel.add(gdxPanel, PositionalLayout.Position.CENTER); commandPanel = new CommandPanel(); @@ -472,37 +464,6 @@ public MapToolFrame(JMenuBar menuBar) { setChatTypingLabelColor(AppPreferences.chatNotificationColor.get()); } - private void initGdx() { - var config = new JoglAwtApplicationConfiguration(); - // config.foregroundFPS = 300; - // config.backgroundFPS = 10; - // config.title = "maptool"; - // config.width = 640; - // config.height = 480; - // config.samples = 1; - // var config = new LwjglApplicationConfiguration(); - config.foregroundFPS = 10000; - config.vSyncEnabled = false; - - var joglSwingCanvas = new JoglSwingCanvas(GdxRenderer.getInstance(), config); - // var joglSwingCanvas = new LwjglAWTCanvas(GdxRenderer.getInstance(), config); - - gdxPanel = joglSwingCanvas.getGLCanvas(); - gdxPanel.setVisible(false); - gdxPanel.setOpaque(false); - // gdxPanel.setLayout(new PositionalLayout(5)); - } - - public void switchRenderers() { - var isVisible = gdxPanel.isVisible(); - gdxPanel.setVisible(!isVisible); - // currentRenderer.setVisible(isVisible); - } - - public GLJPanel getGdxPanel() { - return gdxPanel; - } - public ChatNotificationTimers getChatNotificationTimers() { return chatTyperTimers; } diff --git a/src/main/java/net/rptools/maptool/client/ui/ToolbarPanel.java b/src/main/java/net/rptools/maptool/client/ui/ToolbarPanel.java index bcaf4b7184..76d6874b42 100644 --- a/src/main/java/net/rptools/maptool/client/ui/ToolbarPanel.java +++ b/src/main/java/net/rptools/maptool/client/ui/ToolbarPanel.java @@ -18,7 +18,6 @@ import java.util.Enumeration; import java.util.Hashtable; import javax.swing.*; -import net.rptools.maptool.client.DeveloperOptions; import net.rptools.maptool.client.MapTool; import net.rptools.maptool.client.functions.MediaPlayerAdapter; import net.rptools.maptool.client.swing.SwingUtil; @@ -167,8 +166,6 @@ public ToolbarPanel(Toolbox tbox) { tokenSelectionButtonAll.setSelected(true); // Jamz: End panel - add(createGdxButton(Icons.TOOLBAR_LIBGDX)); - // the "Select Map" button mapselect = createZoneSelectionButton(); add(mapselect); @@ -541,20 +538,6 @@ private JToggleButton createMuteButton( return button; } - private JToggleButton createGdxButton(final Icons icon) { - final JToggleButton button = new JToggleButton(); - button.addActionListener( - e -> { - MapTool.getFrame().switchRenderers(); - }); - - button.setIcon(RessourceManager.getBigIcon(icon)); - button.setVisible(DeveloperOptions.Toggle.EnableLibGdxRendererToggleButton.get()); - DeveloperOptions.Toggle.EnableLibGdxRendererToggleButton.onChange(button::setVisible); - - return button; - } - private JToggleButton createTokenSelectionButton( final Icons icon, final Icons offIcon, String tooltip, TokenSelection tokenSelection) { final JToggleButton button = new JToggleButton(); diff --git a/src/main/java/net/rptools/maptool/client/ui/zone/ZoneViewModel.java b/src/main/java/net/rptools/maptool/client/ui/zone/ZoneViewModel.java index ba41fb54f6..4264417601 100644 --- a/src/main/java/net/rptools/maptool/client/ui/zone/ZoneViewModel.java +++ b/src/main/java/net/rptools/maptool/client/ui/zone/ZoneViewModel.java @@ -270,7 +270,7 @@ public void update() { /** Updates {@link #isUsingGdxRenderer}. */ private void updateIsUsingGdxRenderer() { - isUsingGdxRenderer = MapTool.getFrame().getGdxPanel().isVisible(); + isUsingGdxRenderer = false; } /**