diff --git a/src/main/java/net/rptools/maptool/client/functions/TokenBarFunction.java b/src/main/java/net/rptools/maptool/client/functions/TokenBarFunction.java index eb02dde8c1..f4a272e3b0 100644 --- a/src/main/java/net/rptools/maptool/client/functions/TokenBarFunction.java +++ b/src/main/java/net/rptools/maptool/client/functions/TokenBarFunction.java @@ -38,6 +38,9 @@ private TokenBarFunction() { /** singleton instance of this function */ private static final TokenBarFunction instance = new TokenBarFunction(); + /** Suffix added to the bar name to store the hidden value of the bar */ + public static final String hidenBarSuffix = "StoredValue"; + /** * @return singleton instance */ @@ -84,7 +87,10 @@ public Object childEvaluate( * @return A {@link BigDecimal} value, or an empty string "" if bar is not visible */ public static Object getValue(Token token, String bar) { - Object value = token.getState(bar); + Object value = token.getState(bar + hidenBarSuffix); + if (value == null) { + value = token.getState(bar); + } return value != null ? value : ""; } @@ -95,8 +101,19 @@ public static Object getValue(Token token, String bar) { * @return The {@link BigDecimal} value that was actually set. */ public static Object setValue(Token token, String bar, Object value) { + Object valueShown = token.getState(bar); BigDecimal val = getBigDecimalValue(value); - MapTool.serverCommand().updateTokenProperty(token, Token.Update.setState, bar, val); + if (valueShown != null) { + // If the bar is visible, set both the visual value of the bar and the stored value + MapTool.serverCommand().updateTokenProperty(token, Token.Update.setState, bar, val); + MapTool.serverCommand() + .updateTokenProperty(token, Token.Update.setState, bar + hidenBarSuffix, val); + } else { + // If the bar is not visible, only set the stored value + MapTool.serverCommand() + .updateTokenProperty(token, Token.Update.setState, bar + hidenBarSuffix, val); + } + return val; } @@ -116,7 +133,34 @@ public static BigDecimal isVisible(Token token, String bar) { * @return If the bar visible or not */ public static BigDecimal setVisible(Token token, String bar, boolean show) { - MapTool.serverCommand().updateTokenProperty(token, Token.Update.setState, bar, show); + Object valueShown = token.getState(bar); + Object valueHidden = token.getState(bar + hidenBarSuffix); + if (show) { + if (valueHidden != null) { + // if we want to show the bar, and we have a hidden value, restore it + MapTool.serverCommand() + .updateTokenProperty( + token, Token.Update.setState, bar, getBigDecimalValue(valueHidden)); + } else { + if (valueShown == null) { + // if we want to show the bar, and we don't have a hidden value, and no shown value, set + // both to true/1.0 + // This check is to avoid messing with old tokens that does not have a hidden value. + MapTool.serverCommand().updateTokenProperty(token, Token.Update.setState, bar, true); + MapTool.serverCommand() + .updateTokenProperty(token, Token.Update.setState, bar + hidenBarSuffix, true); + } + } + } else { + if (valueShown != null) { + // if we want to hide the bar, and we have a shown value, store it and hide the bar + MapTool.serverCommand() + .updateTokenProperty( + token, Token.Update.setState, bar + hidenBarSuffix, getBigDecimalValue(valueShown)); + MapTool.serverCommand().updateTokenProperty(token, Token.Update.setState, bar, false); + } + } + return show ? BigDecimal.ONE : BigDecimal.ZERO; } diff --git a/src/main/java/net/rptools/maptool/client/ui/TokenPopupMenu.java b/src/main/java/net/rptools/maptool/client/ui/TokenPopupMenu.java index d9629e66a4..7cdf13c2f2 100644 --- a/src/main/java/net/rptools/maptool/client/ui/TokenPopupMenu.java +++ b/src/main/java/net/rptools/maptool/client/ui/TokenPopupMenu.java @@ -691,14 +691,23 @@ public void actionPerformed(ActionEvent e) { hide.setSelected(true); slider.setEnabled(false); slider.setValue(100); + Object hiddenValue = getTokenUnderMouse().getState(name + TokenBarFunction.hidenBarSuffix); + if (hiddenValue != null) { + slider.setValue( + (int) (TokenBarFunction.getBigDecimalValue(hiddenValue).doubleValue() * 100)); + } else { + slider.setValue(100); + } } else { hide.setSelected(false); slider.setEnabled(true); - slider.setValue( - (int) - (TokenBarFunction.getBigDecimalValue(getTokenUnderMouse().getState(name)) - .doubleValue() - * 100)); + Object hiddenValue = getTokenUnderMouse().getState(name + TokenBarFunction.hidenBarSuffix); + if (hiddenValue != null) { + slider.setValue( + (int) (TokenBarFunction.getBigDecimalValue(hiddenValue).doubleValue() * 100)); + } else { + slider.setValue(100); + } } JPanel barPanel = new JPanel(new MigLayout("wrap 2")); @@ -721,6 +730,9 @@ public void actionPerformed(ActionEvent e) { Token token = zone.getToken(tokenGUID); BigDecimal val = hide.isSelected() ? null : new BigDecimal(slider.getValue() / 100.0); token.setState(name, val); + if (val != null) { + token.setState(name + TokenBarFunction.hidenBarSuffix, val); + } MapTool.serverCommand().putToken(zone.getId(), token); } } diff --git a/src/main/java/net/rptools/maptool/client/ui/campaignproperties/TokenBarController.java b/src/main/java/net/rptools/maptool/client/ui/campaignproperties/TokenBarController.java index 67d1218a72..e3c9fa22fd 100644 --- a/src/main/java/net/rptools/maptool/client/ui/campaignproperties/TokenBarController.java +++ b/src/main/java/net/rptools/maptool/client/ui/campaignproperties/TokenBarController.java @@ -42,6 +42,7 @@ import net.rptools.lib.MD5Key; import net.rptools.maptool.client.AppConstants; import net.rptools.maptool.client.AppPreferences; +import net.rptools.maptool.client.functions.TokenBarFunction; import net.rptools.maptool.client.swing.AbeillePanel; import net.rptools.maptool.client.swing.ColorWell; import net.rptools.maptool.client.ui.PreviewPanelFileChooser; @@ -530,8 +531,20 @@ public void changedUpdate(DocumentEvent e) { boolean hasImages = false; BarTokenOverlay selectedBar = (BarTokenOverlay) formPanel.getList(BARS).getSelectedValue(); boolean hasUniqueUpdateName = false; + var namesToCheck = new ArrayList(); + // We need to check for both the name and the name with the hidden value suffix + if (selectedBar != null) { + for (String name : getNames()) { + namesToCheck.add(name + TokenBarFunction.hidenBarSuffix); + namesToCheck.add(name); + if (name.endsWith(TokenBarFunction.hidenBarSuffix)) { + namesToCheck.add( + name.substring(0, name.length() - TokenBarFunction.hidenBarSuffix.length())); + } + } + } if (selectedBar != null) - hasUniqueUpdateName = selectedBar.getName().equals(text) || !getNames().contains(text); + hasUniqueUpdateName = selectedBar.getName().equals(text) || !namesToCheck.contains(text); if (size > 0 && imageCount == size) { hasImages = true; } else if (size < 0 && imageCount == increments && increments > 0) { @@ -541,7 +554,7 @@ public void changedUpdate(DocumentEvent e) { } // endif formPanel .getButton(ADD) - .setEnabled(hasName && !getNames().contains(text) && hasImages && hasShow); + .setEnabled(hasName && !namesToCheck.contains(text) && hasImages && hasShow); formPanel .getButton(UPDATE) .setEnabled(hasName && hasUniqueUpdateName && selectedBar != null && hasShow && hasImages); diff --git a/src/main/java/net/rptools/maptool/client/ui/campaignproperties/TokenStatesController.java b/src/main/java/net/rptools/maptool/client/ui/campaignproperties/TokenStatesController.java index 6c4351fc8a..18487d2822 100644 --- a/src/main/java/net/rptools/maptool/client/ui/campaignproperties/TokenStatesController.java +++ b/src/main/java/net/rptools/maptool/client/ui/campaignproperties/TokenStatesController.java @@ -31,6 +31,7 @@ import net.rptools.lib.StringUtil; import net.rptools.maptool.client.AppConstants; import net.rptools.maptool.client.AppPreferences; +import net.rptools.maptool.client.functions.TokenBarFunction; import net.rptools.maptool.client.swing.AbeillePanel; import net.rptools.maptool.client.swing.ColorWell; import net.rptools.maptool.client.ui.PreviewPanelFileChooser; @@ -454,12 +455,24 @@ public void changedUpdate(DocumentEvent e) { || formPanel.getCheckBox(SHOW_OTHERS).isSelected(); BooleanTokenOverlay selectedState = (BooleanTokenOverlay) formPanel.getList(STATES).getSelectedValue(); + var namesToCheck = new ArrayList(); + // We need to check for both the name and the name with the hidden value suffix + if (selectedState != null) { + for (String name : getNames()) { + namesToCheck.add(name + TokenBarFunction.hidenBarSuffix); + namesToCheck.add(name); + if (name.endsWith(TokenBarFunction.hidenBarSuffix)) { + namesToCheck.add( + name.substring(0, name.length() - TokenBarFunction.hidenBarSuffix.length())); + } + } + } boolean hasUniqueUpdateName = false; if (selectedState != null) - hasUniqueUpdateName = selectedState.getName().equals(text) || !getNames().contains(text); + hasUniqueUpdateName = selectedState.getName().equals(text) || !namesToCheck.contains(text); formPanel .getButton(ADD) - .setEnabled(hasName && !getNames().contains(text) && hasImage && hasShow); + .setEnabled(hasName && !namesToCheck.contains(text) && hasImage && hasShow); formPanel .getButton(UPDATE) .setEnabled(hasName && hasUniqueUpdateName && selectedState != null && hasShow); diff --git a/src/main/java/net/rptools/maptool/client/ui/token/dialog/edit/EditTokenDialog.java b/src/main/java/net/rptools/maptool/client/ui/token/dialog/edit/EditTokenDialog.java index 3d51a1f7aa..e41bd33b6c 100644 --- a/src/main/java/net/rptools/maptool/client/ui/token/dialog/edit/EditTokenDialog.java +++ b/src/main/java/net/rptools/maptool/client/ui/token/dialog/edit/EditTokenDialog.java @@ -346,7 +346,13 @@ public void bind(final Token token) { if (token.getState(bar.getName()) == null) { cb.setSelected(true); bar.setEnabled(false); - bar.setValue(100); + Object hiddenValue = token.getState(bar.getName() + TokenBarFunction.hidenBarSuffix); + if (hiddenValue != null) { + bar.setValue( + (int) (TokenBarFunction.getBigDecimalValue(hiddenValue).doubleValue() * 100)); + } else { + bar.setValue(100); + } } else { cb.setSelected(false); bar.setEnabled(true); @@ -878,6 +884,9 @@ public boolean commit() { BigDecimal value = cb.isSelected() ? null : new BigDecimal(bar.getValue()).divide(new BigDecimal(100)); token.setState(bar.getName(), value); + if (value != null) { + token.setState(bar.getName() + TokenBarFunction.hidenBarSuffix, value); + } bar.setValue( (int) (TokenBarFunction.getBigDecimalValue(token.getState(bar.getName())).doubleValue()