From 48e51ef6b4fedf92f36d52c01647ca45ad50625f Mon Sep 17 00:00:00 2001 From: bubblobill Date: Tue, 4 Aug 2026 03:11:31 +0800 Subject: [PATCH] Icon housekeeping: Some blank SVG icons containing FlatIconColors. Added missing Icons.WARNING Added Icons.ACTION_EDIT_IN_EDITOR Plus generic directional triangle icons. New class TextFieldEditorWithPopup.java Implemented in TokenPropertiesManagementPanel Usual i18n keys added/changed --- .../TextFieldEditorButtonTableCellEditor.java | 71 --- .../swing/TextFieldEditorWithPopup.java | 514 ++++++++++++++++++ .../TokenPropertiesManagementPanel.java | 4 +- .../dialog/MacroButtonDialogView.form | 12 +- .../dialog/MacroEditorDialog.java | 5 + .../maptool/client/ui/theme/Icons.java | 6 + .../client/ui/theme/RessourceManager.java | 6 + .../icons/rod_takehara/edit/EditExternal.svg | 23 + .../maptool/client/image/blank_icon.svg | 64 +++ .../maptool/client/image/blank_icon_thin.svg | 64 +++ .../client/image/blank_icon_thinnest.svg | 64 +++ .../client/image/triangle_blue_down.svg | 52 ++ .../client/image/triangle_blue_left.svg | 52 ++ .../client/image/triangle_blue_right.svg | 52 ++ .../maptool/client/image/triangle_blue_up.svg | 52 ++ .../rptools/maptool/language/i18n.properties | 17 +- 16 files changed, 976 insertions(+), 82 deletions(-) delete mode 100644 src/main/java/net/rptools/maptool/client/swing/TextFieldEditorButtonTableCellEditor.java create mode 100644 src/main/java/net/rptools/maptool/client/swing/TextFieldEditorWithPopup.java create mode 100644 src/main/resources/net/rptools/maptool/client/icons/rod_takehara/edit/EditExternal.svg create mode 100644 src/main/resources/net/rptools/maptool/client/image/blank_icon.svg create mode 100644 src/main/resources/net/rptools/maptool/client/image/blank_icon_thin.svg create mode 100644 src/main/resources/net/rptools/maptool/client/image/blank_icon_thinnest.svg create mode 100644 src/main/resources/net/rptools/maptool/client/image/triangle_blue_down.svg create mode 100644 src/main/resources/net/rptools/maptool/client/image/triangle_blue_left.svg create mode 100644 src/main/resources/net/rptools/maptool/client/image/triangle_blue_right.svg create mode 100644 src/main/resources/net/rptools/maptool/client/image/triangle_blue_up.svg diff --git a/src/main/java/net/rptools/maptool/client/swing/TextFieldEditorButtonTableCellEditor.java b/src/main/java/net/rptools/maptool/client/swing/TextFieldEditorButtonTableCellEditor.java deleted file mode 100644 index 67a85cc9fc..0000000000 --- a/src/main/java/net/rptools/maptool/client/swing/TextFieldEditorButtonTableCellEditor.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This software Copyright by the RPTools.net development team, and - * licensed under the Affero GPL Version 3 or, at your option, any later - * version. - * - * MapTool Source Code is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU Affero General Public - * License * along with this source Code. If not, please visit - * and specifically the Affero license - * text at . - */ -package net.rptools.maptool.client.swing; - -import java.awt.*; -import javax.swing.*; -import javax.swing.table.TableCellEditor; -import net.rptools.maptool.client.ui.macrobuttons.dialog.MacroEditorDialog; -import net.rptools.maptool.language.I18N; - -/** - * Class that implements a Table Cell editor that allows editing either through text box or macro - * dialog if the user clicks on the "..." button. - */ -public class TextFieldEditorButtonTableCellEditor extends AbstractCellEditor - implements TableCellEditor { - - /** - * The text field that is displayed so that the user can edit the contents without opening editor - */ - private JTextField textField = new JTextField(); - - /** The button that opens the editor dialog. */ - private JPanel panel = new JPanel(new GridBagLayout()); - - /** Creates a new TextFieldEditorButtonTableCellEditor. */ - public TextFieldEditorButtonTableCellEditor() { - textField.addActionListener(l -> fireEditingStopped()); - panel.add(textField); - JButton button = new JButton("..."); - button.addActionListener( - l -> - MacroEditorDialog.createModalDialog( - c -> { - if (c != null) { - textField.setText(c); - fireEditingStopped(); - } else { - fireEditingCanceled(); - } - }) - .show( - I18N.getText("campaignProperties.macroEditDialog.default.title"), - textField.getText())); - panel.add(button); - } - - @Override - public Component getTableCellEditorComponent( - JTable table, Object value, boolean isSelected, int row, int column) { - textField.setText(value == null ? "" : value.toString()); - return panel; - } - - @Override - public Object getCellEditorValue() { - return textField.getText(); - } -} diff --git a/src/main/java/net/rptools/maptool/client/swing/TextFieldEditorWithPopup.java b/src/main/java/net/rptools/maptool/client/swing/TextFieldEditorWithPopup.java new file mode 100644 index 0000000000..ac2be3a92c --- /dev/null +++ b/src/main/java/net/rptools/maptool/client/swing/TextFieldEditorWithPopup.java @@ -0,0 +1,514 @@ +/* + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. + * + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . + */ +package net.rptools.maptool.client.swing; + +import com.formdev.flatlaf.FlatIconColors; +import com.formdev.flatlaf.extras.FlatSVGIcon; +import com.formdev.flatlaf.extras.components.FlatButton; +import com.formdev.flatlaf.extras.components.FlatTextField; +import com.jidesoft.swing.PartialLineBorder; +import com.jidesoft.swing.PartialSide; +import java.awt.*; +import java.awt.event.*; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.SimpleBooleanProperty; +import javax.accessibility.*; +import javax.swing.*; +import net.rptools.maptool.client.ui.macrobuttons.dialog.MacroEditorDialog; +import net.rptools.maptool.client.ui.theme.Icons; +import net.rptools.maptool.client.ui.theme.RessourceManager; +import net.rptools.maptool.language.I18N; + +/** + * + * + *

A component containing a JTextField with a pop-up text area.

+ * + *

Features

+ * + *
    + *
  • A button within the text field to open the text in a larger (modal) {@link + * MacroEditorDialog} + *
  • [Optional] A label placed before the text field + *
  • [Optional] A button to collapse/hide the text field to save space, e.g. for use in a + * toolbar + *
  • Method to open the text field in a {@link GenericDialog} + *
  • Method to get the text field as a {@link DefaultCellEditor} + *
+ * + *

The {@link #textField} is used as a delegate for values and should be used as the access point + * for most things, e.g. + * + *

+ *     TextFieldEditorWithPopup tf = new TextFieldEditorWithPopup();
+ *     tf.getTextField().addActionListener(myListener);
+ * 
+ */ +@SuppressWarnings("unused") +public class TextFieldEditorWithPopup extends Box implements Accessible { + private static final Icon EDIT_ICON = RessourceManager.getSmallIcon(Icons.ACTION_EDIT_IN_EDITOR); + private static final FlatSVGIcon RIGHT_TRIANGLE = + ((FlatSVGIcon) RessourceManager.getSmallIcon(Icons.TRIANGLE_RIGHT)).derive(0.4f); + private static final FlatSVGIcon LEFT_TRIANGLE = + ((FlatSVGIcon) RessourceManager.getSmallIcon(Icons.TRIANGLE_LEFT)).derive(0.4f); + + private static final String EDITOR_ACCESSIBLE_NAME_KEY = "textEditorWithPopup.accessibleName"; + private static final String EDITOR_ACCESSIBLE_DESCRIPTION_KEY = + "textEditorWithPopup.accessibleDescription"; + private static final String EDITOR_BUTTON_ACCESSIBLE_NAME_KEY = + "textEditorWithPopup.openEditorButton.accessibleName"; + private static final String EDITOR_BUTTON_ACCESSIBLE_DESCRIPTION_KEY = + "textEditorWithPopup.openEditorButton.accessibleDescription"; + private static final String COLLAPSE_BUTTON_ACCESSIBLE_NAME_KEY = + "textEditorWithPopup.collapseToggleButton.accessibleName"; + private static final String COLLAPSE_BUTTON_ACCESSIBLE_DESCRIPTION_KEY = + "textEditorWithPopup.collapseToggleButton.accessibleDescription"; + private static final Color OPEN_EDITOR_BUTTON_BG = + UIManager.getDefaults().getColor("ToolBar.background"); + private static final Color BUTTON_BORDER_COLOUR = + UIManager.getDefaults().getColor("Button.borderColor"); + private static final Color BUTTON_HIGHLIGHT = + UIManager.getDefaults().getColor(FlatIconColors.ACTIONS_YELLOW.key); + + /** Text field displayed for editing. Contains {@link #openEditorButton} at the tail end. */ + private final FlatTextField textField = new FlatTextField(); + + /** + * Label to show if required. Appears before the {@link #textField} and {@link #collapseButton} + */ + private final JLabel label = new JLabel(); + + /** Button inside the {@link #textField} that opens the external editor. */ + private final JButton openEditorButton = new JButton(EDIT_ICON); + + /** + * Toggle button for collapsing/hiding the text editor. Sits between the {@link #label} and {@link + * #textField}. Selected == collapsed + */ + private final JToggleButton collapseButton = new JToggleButton(); + + /** Collapsed state; true = text field hidden, false = text area visible */ + private final BooleanProperty collapsible = new SimpleBooleanProperty(false); + + /** Collapsed state; true = text field hidden, false = text area visible */ + private final BooleanProperty collapsed = new SimpleBooleanProperty(false); + + /** Label visibility */ + private final BooleanProperty showLabel = new SimpleBooleanProperty(false); + + /** Used as the title in the external editor pop-up */ + private String externalEditorTitle = I18N.getMessage("Label.editor"); + + private ActionListener openEditorActionListener = + l -> + MacroEditorDialog.createModalDialog( + c -> { + if (c != null) { + setValue(c); + } + }) + .show(getExternalEditorTitle(), getValue()); + + { + initLabel(); + initPropertyChangeListeners(); + initTextField(); + initOpenEditorButton(); + initAccessibility(); + initCollapseButton(); + } + + /** Creates a new TextFieldEditorWithPopup. */ + public TextFieldEditorWithPopup(String text) { + this(); + setValue(text); + } + + /** Creates a new TextFieldEditorWithPopup. */ + public TextFieldEditorWithPopup() { + super(BoxLayout.LINE_AXIS); + super.getAccessibleContext().setAccessibleName(I18N.getMessage(EDITOR_ACCESSIBLE_NAME_KEY)); + super.getAccessibleContext() + .setAccessibleDescription(I18N.getMessage(EDITOR_ACCESSIBLE_DESCRIPTION_KEY)); + setFocusCycleRoot(false); + setFocusable(false); + setRequestFocusEnabled(false); + add(label); + add(collapseButton); + add(textField); + invalidate(); + setVisible(true); + } + + /** set up the collapse button */ + private void initCollapseButton() { + collapseButton.setFocusable(true); + collapseButton.setFocusTraversalKeysEnabled(true); + collapseButton.setRequestFocusEnabled(true); + collapseButton.addPropertyChangeListener(evt -> System.out.println(evt.getPropertyName())); + // appearance - no background or border unless focussed + collapseButton.addFocusListener( + new FocusListener() { + @Override + public void focusGained(FocusEvent e) { + collapseButton.setContentAreaFilled(true); + } + + @Override + public void focusLost(FocusEvent e) { + collapseButton.setContentAreaFilled(false); + } + }); + collapseButton.setIcon(LEFT_TRIANGLE); // collapse + collapseButton.setSelectedIcon(RIGHT_TRIANGLE); // expand + collapseButton.putClientProperty("JButton.buttonType", FlatButton.ButtonType.borderless); + collapseButton.setBackground(BUTTON_HIGHLIGHT); + collapseButton.setContentAreaFilled(false); + collapseButton.setSelected(true); + collapseButton.setVisible(false); + // update property with state + collapseButton.addActionListener(e -> setCollapsed(collapseButton.isSelected())); + } + + /** set accessibility bits */ + private void initAccessibility() { + openEditorButton + .getAccessibleContext() + .setAccessibleName(I18N.getMessage(EDITOR_BUTTON_ACCESSIBLE_NAME_KEY)); + openEditorButton + .getAccessibleContext() + .setAccessibleDescription(I18N.getMessage(EDITOR_BUTTON_ACCESSIBLE_DESCRIPTION_KEY)); + openEditorButton.setToolTipText(I18N.getMessage(EDITOR_BUTTON_ACCESSIBLE_DESCRIPTION_KEY)); + collapseButton + .getAccessibleContext() + .setAccessibleName(I18N.getMessage(COLLAPSE_BUTTON_ACCESSIBLE_NAME_KEY)); + collapseButton + .getAccessibleContext() + .setAccessibleDescription(I18N.getMessage(COLLAPSE_BUTTON_ACCESSIBLE_DESCRIPTION_KEY)); + collapseButton.setToolTipText(I18N.getMessage(COLLAPSE_BUTTON_ACCESSIBLE_DESCRIPTION_KEY)); + } + + /** add listeners for values that influence layout */ + private void initPropertyChangeListeners() { + collapsible.addListener((observable, oldValue, newValue) -> revalidate()); + collapsed.addListener((observable, oldValue, newValue) -> revalidate()); + showLabel.addListener((observable, oldValue, newValue) -> revalidate()); + } + + private void initLabel() { + label.setBorder(BorderFactory.createEmptyBorder(0, 6, 0, 3)); + label.setVisible(false); + label.setFocusable(false); + label.setLabelFor(this); + } + + /** adds openEditor button and listeners to keep enabled state aligned */ + private void initTextField() { + textField.setFocusable(true); + textField.setFocusTraversalKeysEnabled(true); + textField.setRequestFocusEnabled(true); + // Put the external editor button inside the text field + textField.setTrailingComponent(openEditorButton); + // keep external editor button enabled state the same as the text field + textField.addPropertyChangeListener( + "editable", evt -> openEditorButton.setEnabled((Boolean) evt.getNewValue())); + textField.addPropertyChangeListener( + "enabled", evt -> openEditorButton.setEnabled((Boolean) evt.getNewValue())); + } + + /** + * set up the openEditor button appearance and action. FlatTextField does a bad job of + * differentiating the trailing button or making its focus obvious. + */ + private void initOpenEditorButton() { + openEditorButton.addFocusListener( + new FocusListener() { + @Override + public void focusGained(FocusEvent e) { + openEditorButton.setBackground(BUTTON_HIGHLIGHT); + } + + @Override + public void focusLost(FocusEvent e) { + openEditorButton.setBackground(OPEN_EDITOR_BUTTON_BG); + } + }); + openEditorButton.setFocusable(true); + openEditorButton.setFocusTraversalKeysEnabled(true); + openEditorButton.setRequestFocusEnabled(true); + openEditorButton.setOpaque(true); + openEditorButton.setBorder(new PartialLineBorder(BUTTON_BORDER_COLOUR, 1, PartialSide.WEST)); + // tends to inherit the caret cursor so we reset it + openEditorButton.setCursor(Cursor.getDefaultCursor()); + // assign the action to open the external editor + openEditorButton.addActionListener(openEditorActionListener); + } + + /** + * @return text value from the {@link #textField} + */ + public String getValue() { + return textField.getText(); + } + + /** + * @param text value for the {@link #textField} + */ + public void setValue(String text) { + textField.setText(text); + } + + /** + * Enable/Disable the collapsible functionality + * + * @param value enabled + */ + public void setCollapsible(boolean value) { + collapsible.set(value); + } + + /** + * Sets the collapsed state + * + * @param value collapsed + * @see #collapsed + */ + public void setCollapsed(boolean value) { + collapsed.set(value); + if (collapseButton.isSelected() != value) { + collapseButton.setSelected(value); + } + revalidate(); + } + + /** + * @return Value for {@link #externalEditorTitle} + */ + public String getExternalEditorTitle() { + return externalEditorTitle; + } + + /** + * Value for {@link #externalEditorTitle} + * + * @param title to use + */ + public void setExternalEditorTitle(String title) { + externalEditorTitle = title; + } + + /** + * Sets the text on the {@link #openEditorButton} using the i18n lookup key + * + * @param text for label + */ + public void setOpenEditorButtonText(String text) { + openEditorButton.setText(text); + invalidate(); + } + + /** + * Sets the text on the {@link #openEditorButton} + * + * @param i18nKey to lookup + */ + public void setOpenEditorButtonTextKey(String i18nKey) { + setOpenEditorButtonText(I18N.getMessage(i18nKey)); + } + + /** + * Set the tooltip on the {@link #openEditorButton} using the i18n lookup key + * + * @param i18nKey to lookup + * @see #openEditorButton + */ + public void setOpenEditorButtonTooltipTextKey(String i18nKey) { + openEditorButton.setToolTipText(I18N.getMessage(i18nKey)); + } + + /** + * Set the tooltip on the {@link #openEditorButton} + * + * @param text to display as tooltip + */ + public void setOpenEditorButtonTooltipText(String text) { + openEditorButton.setToolTipText(text); + } + + /** + * Change the icon on the {@link #openEditorButton}. Removes any text in the button, so do it + * before {@link #setOpenEditorButtonText}/{@link #setOpenEditorButtonTextKey} + * + * @param icon to use + */ + public void setOpenEditorButtonIcon(Icon icon) { + openEditorButton.setIcon(icon); + if (!openEditorButton.getText().isBlank()) { + openEditorButton.setText(null); + } + revalidate(); + } + + /** + * Replace the listener that opens the external editor. + * + * @param openEditorActionListener the replacement + */ + public void setOpenEditorActionListener(ActionListener openEditorActionListener) { + openEditorButton.removeActionListener(this.openEditorActionListener); + this.openEditorActionListener = openEditorActionListener; + openEditorButton.addActionListener(this.openEditorActionListener); + } + + /** + * @return The {@link #label} component + */ + public JLabel getLabel() { + return label; + } + + /** + * @return The {@link #collapseButton} + */ + public JToggleButton getCollapseButton() { + return collapseButton; + } + + /** + * @return The {@link #openEditorButton} + */ + public JButton getOpenEditorButton() { + return openEditorButton; + } + + /** + * @return The {@link #textField} + */ + public JTextField getTextField() { + return textField; + } + + /** + * Sets the icon on the label preceding the text field + * + * @param icon to use + */ + public void setLabelIcon(Icon icon) { + label.setIcon(icon); + setShowLabel(true); + invalidate(); + } + + /** + * @return visibility of {@link #label} component + */ + public boolean isShowLabel() { + return showLabel.get(); + } + + /** + * Sets the label as visible. This is set to true automatically when the label is assigned text or + * an icon. + * + * @param value visible state of the label + */ + public void setShowLabel(boolean value) { + showLabel.set(value); + revalidate(); + } + + /** + * Sets the text on the label preceding the text field + * + * @param text for label + */ + public void setLabelText(String text) { + label.setText(text); + setShowLabel(true); + super.getAccessibleContext().setAccessibleName(text); + invalidate(); + } + + /** + * Sets the text on the label preceding the text field using the i18n lookup key. + * + * @param i18nKey to lookup + */ + public void setLabelTextKey(String i18nKey) { + setLabelText(I18N.getMessage(i18nKey)); + } + + /** + * Sets the tooltip text on the label preceding the text field. + * + * @param text for tooltip + */ + public void setLabelTooltipText(String text) { + label.setToolTipText(text); + super.getAccessibleContext().setAccessibleDescription(text); + } + + /** + * Sets the tooltip text on the label preceding the text field using the i18n lookup key. + * + * @param i18nKey to lookup + */ + public void setLabelTooltipTextKey(String i18nKey) { + setLabelTooltipText(I18N.getMessage(i18nKey)); + } + + /** + * Applies enabled state to JTextField + * + * @param enabled true if this component should be enabled, false otherwise + */ + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + textField.setEnabled(enabled); + } + + /** + * Opens the component in a {@link GenericDialog} + * + * @param title shown in the JDialog + */ + public void openInDialog(String title) { + new GenericDialogFactory() + .setDialogTitle(title) + .setCloseOperation(WindowConstants.DISPOSE_ON_CLOSE) + .addButton(ButtonKind.CLOSE) + .setContent(this) + .display(); + } + + /** + * For use in tables, trees, etc. + * + * @return a new {@link DefaultCellEditor} with the text field as the editor component + */ + public DefaultCellEditor getAsCellEditor() { + return new DefaultCellEditor(textField); + } + + /** sets various component visibilities before calling super method */ + @Override + public void revalidate() { + label.setVisible(showLabel.get()); + collapseButton.setVisible(collapsible.get()); + textField.setVisible(!collapsed.get()); + super.revalidate(); + } +} diff --git a/src/main/java/net/rptools/maptool/client/ui/campaignproperties/TokenPropertiesManagementPanel.java b/src/main/java/net/rptools/maptool/client/ui/campaignproperties/TokenPropertiesManagementPanel.java index ff41626f4f..c58168f6f0 100644 --- a/src/main/java/net/rptools/maptool/client/ui/campaignproperties/TokenPropertiesManagementPanel.java +++ b/src/main/java/net/rptools/maptool/client/ui/campaignproperties/TokenPropertiesManagementPanel.java @@ -28,7 +28,7 @@ import net.rptools.maptool.client.MapTool; import net.rptools.maptool.client.swing.AbeillePanel; import net.rptools.maptool.client.swing.TableCellRendererDecorator; -import net.rptools.maptool.client.swing.TextFieldEditorButtonTableCellEditor; +import net.rptools.maptool.client.swing.TextFieldEditorWithPopup; import net.rptools.maptool.client.ui.campaignproperties.TokenPropertiesTableModel.LargeEditableText; import net.rptools.maptool.client.ui.sheet.stats.StatSheetComboBoxRenderer; import net.rptools.maptool.client.ui.theme.Icons; @@ -374,7 +374,7 @@ public void initPropertyTable() { var propertyTable = getTokenPropertiesTable(); propertyTable.setModel(new TokenPropertiesTableModel()); propertyTable.setDefaultEditor( - LargeEditableText.class, new TextFieldEditorButtonTableCellEditor()); + LargeEditableText.class, new TextFieldEditorWithPopup().getAsCellEditor()); propertyTable .getSelectionModel() .addListSelectionListener( diff --git a/src/main/java/net/rptools/maptool/client/ui/macrobuttons/dialog/MacroButtonDialogView.form b/src/main/java/net/rptools/maptool/client/ui/macrobuttons/dialog/MacroButtonDialogView.form index 402a2efcf5..5bc9d2ac74 100644 --- a/src/main/java/net/rptools/maptool/client/ui/macrobuttons/dialog/MacroButtonDialogView.form +++ b/src/main/java/net/rptools/maptool/client/ui/macrobuttons/dialog/MacroButtonDialogView.form @@ -3,7 +3,7 @@ - + @@ -22,7 +22,7 @@ - + @@ -67,7 +67,7 @@ - + @@ -339,9 +339,9 @@ - - - + + + 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 ee5d87c8b0..aa4d7b4acf 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 @@ -24,6 +24,7 @@ import java.io.IOException; import java.util.*; import java.util.function.Consumer; +import javax.accessibility.AccessibleContext; import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.swing.*; @@ -962,4 +963,8 @@ private JCheckBox getCompareCommandCheckBox() { } // End comparison customization + + public AccessibleContext getAccessibleContext() { + return macroEditorRSyntaxTextArea.getAccessibleContext(); + } } diff --git a/src/main/java/net/rptools/maptool/client/ui/theme/Icons.java b/src/main/java/net/rptools/maptool/client/ui/theme/Icons.java index ba1de77a8e..ee2ba022a9 100644 --- a/src/main/java/net/rptools/maptool/client/ui/theme/Icons.java +++ b/src/main/java/net/rptools/maptool/client/ui/theme/Icons.java @@ -21,6 +21,7 @@ public enum Icons { ACTION_DELETE, ACTION_ACCEPT, ACTION_EDIT, + ACTION_EDIT_IN_EDITOR, ACTION_EXPORT, ACTION_IMPORT, ACTION_NEW, @@ -42,6 +43,10 @@ public enum Icons { ADD_RESSOURCE_LOCAL, ADD_RESSOURCE_RPTOOLS, ADD_RESSOURCE_WEB, + TRIANGLE_DOWN, + TRIANGLE_LEFT, + TRIANGLE_RIGHT, + TRIANGLE_UP, ASSETPANEL_HEROLABS, ASSETPANEL_HEROLABS_FOLDER, ASSETPANEL_PDF, @@ -195,6 +200,7 @@ public enum Icons { TOOLBAR_VOLUME_ON, TOOLBAR_ZONE, TOOLBAR_ZONE_NOT_VISIBLE, + WARNING, WINDOW_CAMPAIGN_MACROS, WINDOW_CHAT, WINDOW_CONNECTIONS, diff --git a/src/main/java/net/rptools/maptool/client/ui/theme/RessourceManager.java b/src/main/java/net/rptools/maptool/client/ui/theme/RessourceManager.java index 224f154866..8f98750d95 100644 --- a/src/main/java/net/rptools/maptool/client/ui/theme/RessourceManager.java +++ b/src/main/java/net/rptools/maptool/client/ui/theme/RessourceManager.java @@ -64,6 +64,10 @@ public class RessourceManager { put(Icons.ADD_RESSOURCE_LOCAL, IMAGE_DIR + "folder.png"); put(Icons.ADD_RESSOURCE_RPTOOLS, IMAGE_DIR + "rptools_icon.png"); put(Icons.ADD_RESSOURCE_WEB, IMAGE_DIR + "download.png"); + put(Icons.TRIANGLE_DOWN, IMAGE_DIR + "triangle_blue_down.svg"); + put(Icons.TRIANGLE_LEFT, IMAGE_DIR + "triangle_blue_left.svg"); + put(Icons.TRIANGLE_RIGHT, IMAGE_DIR + "triangle_blue_right.svg"); + put(Icons.TRIANGLE_UP, IMAGE_DIR + "triangle_blue_up.svg"); put(Icons.ASSETPANEL_HEROLABS, IMAGE_DIR + "hero-lab-icon.png"); put(Icons.ASSETPANEL_HEROLABS_FOLDER, IMAGE_DIR + "hero_lab_folder.png"); put(Icons.ASSETPANEL_PDF, IMAGE_DIR + "pdf_icon.png"); @@ -227,6 +231,7 @@ public class RessourceManager { put(Icons.TOOLBAR_VOLUME_ON, IMAGE_DIR + "audio/volume.png"); put(Icons.TOOLBAR_ZONE, IMAGE_DIR + "tool/btn-world.png"); put(Icons.TOOLBAR_ZONE_NOT_VISIBLE, IMAGE_DIR + "notvisible.png"); + put(Icons.WARNING, IMAGE_DIR + "warning.svg"); put(Icons.WINDOW_CAMPAIGN_MACROS, IMAGE_DIR + "campaign_panel.png"); put(Icons.WINDOW_CHAT, IMAGE_DIR + "application.png"); put(Icons.WINDOW_CONNECTIONS, IMAGE_DIR + "computer.png"); @@ -304,6 +309,7 @@ public class RessourceManager { put(Icons.ACTION_DELETE, ROD_ICONS + "edit/Delete.svg"); put(Icons.ACTION_ACCEPT, ROD_ICONS + "edit/Accept.svg"); put(Icons.ACTION_EDIT, ROD_ICONS + "edit/Edit.svg"); + put(Icons.ACTION_EDIT_IN_EDITOR, ROD_ICONS + "edit/EditExternal.svg"); put(Icons.ACTION_EXPORT, ROD_ICONS + "edit/Export.svg"); put(Icons.ACTION_IMPORT, ROD_ICONS + "edit/Import.svg"); put(Icons.ACTION_NEW, ROD_ICONS + "edit/New.svg"); diff --git a/src/main/resources/net/rptools/maptool/client/icons/rod_takehara/edit/EditExternal.svg b/src/main/resources/net/rptools/maptool/client/icons/rod_takehara/edit/EditExternal.svg new file mode 100644 index 0000000000..05480b212d --- /dev/null +++ b/src/main/resources/net/rptools/maptool/client/icons/rod_takehara/edit/EditExternal.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/net/rptools/maptool/client/image/blank_icon.svg b/src/main/resources/net/rptools/maptool/client/image/blank_icon.svg new file mode 100644 index 0000000000..dfb0177dcc --- /dev/null +++ b/src/main/resources/net/rptools/maptool/client/image/blank_icon.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/net/rptools/maptool/client/image/blank_icon_thin.svg b/src/main/resources/net/rptools/maptool/client/image/blank_icon_thin.svg new file mode 100644 index 0000000000..c5d69dd2f1 --- /dev/null +++ b/src/main/resources/net/rptools/maptool/client/image/blank_icon_thin.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/net/rptools/maptool/client/image/blank_icon_thinnest.svg b/src/main/resources/net/rptools/maptool/client/image/blank_icon_thinnest.svg new file mode 100644 index 0000000000..12219f77c2 --- /dev/null +++ b/src/main/resources/net/rptools/maptool/client/image/blank_icon_thinnest.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/net/rptools/maptool/client/image/triangle_blue_down.svg b/src/main/resources/net/rptools/maptool/client/image/triangle_blue_down.svg new file mode 100644 index 0000000000..c353b2eab2 --- /dev/null +++ b/src/main/resources/net/rptools/maptool/client/image/triangle_blue_down.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/net/rptools/maptool/client/image/triangle_blue_left.svg b/src/main/resources/net/rptools/maptool/client/image/triangle_blue_left.svg new file mode 100644 index 0000000000..540ce680b7 --- /dev/null +++ b/src/main/resources/net/rptools/maptool/client/image/triangle_blue_left.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/net/rptools/maptool/client/image/triangle_blue_right.svg b/src/main/resources/net/rptools/maptool/client/image/triangle_blue_right.svg new file mode 100644 index 0000000000..41659e1a98 --- /dev/null +++ b/src/main/resources/net/rptools/maptool/client/image/triangle_blue_right.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/net/rptools/maptool/client/image/triangle_blue_up.svg b/src/main/resources/net/rptools/maptool/client/image/triangle_blue_up.svg new file mode 100644 index 0000000000..74d1690427 --- /dev/null +++ b/src/main/resources/net/rptools/maptool/client/image/triangle_blue_up.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/net/rptools/maptool/language/i18n.properties b/src/main/resources/net/rptools/maptool/language/i18n.properties index 7ca803a223..367e52bc81 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n.properties @@ -255,6 +255,8 @@ Default.campaign.halos.category.generic = Generic Default.campaign.halos.category.coloredCircle = ~Colored Circle Default.campaign.halos.category.coloredGrid = ~Colored Grid +#noun +Label.editor = Editor Label.footprint = Footprint Label.lights = Vision Label.type = Type @@ -342,7 +344,7 @@ Label.visibility = Visibility Label.pathfilename = Path/Filename: Label.allowURIAccess = Allow URI Access Label.rotation = Rotation -#Scale as in ratio +#Noun. Scale as in ratio Label.scale = Scale Label.snapToGrid = Snap-to-Grid Label.textType = Text Type @@ -1057,7 +1059,7 @@ ServerDialog.option.reveal.move.tooltip = Allows tokens to automatically reveal ServerDialog.option.vision.individual = Use Individual Views ServerDialog.option.vision.individual.tooltip = Players do not share vision. ServerDialog.option.fow.individual = Use Individual FOW -ServerDialog.option.fow.individual.tooltip = Each token has it's own FOW. +ServerDialog.option.fow.individual.tooltip = Each token has it''s own FOW. ServerDialog.option.impersonate = Allow Players to Impersonate any token ServerDialog.option.impersonate.tooltip = Gives players the ability to impersonate any character as if they had GM status. ServerDialog.option.macros = Players Receive Campaign Macros @@ -1732,7 +1734,6 @@ component.label.macro.minWidth = Min Width component.label.macro.sortPrefix = Sort Prefix component.label.macro.toolTip = Tooltip component.tab.macro.details = Details -component.tab.macro.editor = Editor component.tab.macro.options = Options component.tooltip.macro.allowPlayerEdits = Select this to allow players to edit this macro. component.tooltip.macro.applyToSelected = Check here to run this macro against the currently selected tokens. Uncheck to run this macro outside of the context of any selected tokens. If this macro references one or more token properties, it should be checked. @@ -1903,6 +1904,13 @@ help.header.description = Description impersonate.description = Speak as if you were something/one else. impersonate.mustOwn = Only {0}''s owners can impersonate or run macros on it. +textEditorWithPopup.accessibleName = Text field with external editor +textEditorWithPopup.accessibleDescription = Text field with a button to open an external editor in a pop-up +textEditorWithPopup.openEditorButton.accessibleName = Editor Button +textEditorWithPopup.openEditorButton.accessibleDescription = Open in editor +textEditorWithPopup.collapseToggleButton.accessibleName = Collapse Button +textEditorWithPopup.collapseToggleButton.accessibleDescription = Show/Hide the text field + initPanel.addAll = Add All initPanel.addPCs = Add PCs initPanel.center = Center On Map @@ -2727,6 +2735,8 @@ panel.DrawExplorer.opacity = opacity({0}%) panel.DrawExplorer.eraser = CUT: {0} # DrawExplorer panel panel.DrawExplorer.Unknown.Shape = Unknown Shape +# The editor dockable frame +panel.Editor = Editor panel.Global = Global panel.Global.description = Dockable window showing macros stored on the local computer. panel.Impersonate = Impersonate @@ -2904,6 +2914,7 @@ token.popup.menu.auras.clearOwner = Clear Owner Auras Only token.popup.menu.snap = Snap to grid token.popup.menu.visible = Visible to players token.popup.menu.impersonate = Impersonate +token.popup.menu.impersonateStop = Stop Impersonating token.popup.menu.move = Move token.popup.menu.move.path = Show Path token.popup.menu.move.revertlast = Revert Last Move