001package jmri.jmrit.display; 002 003import java.awt.event.ActionEvent; 004import java.util.HashMap; 005import java.util.Map; 006 007import javax.annotation.CheckForNull; 008import javax.annotation.Nonnull; 009import javax.swing.AbstractAction; 010import javax.swing.JPopupMenu; 011 012import jmri.jmrit.catalog.NamedIcon; 013import jmri.jmrit.logixng.LogixNG; 014import jmri.util.swing.JmriMouseEvent; 015 016/** 017 * An icon that executes a LogixNG when clicked on. 018 * 019 * @author Daniel Bergqvist (C) 2023 020 */ 021public class LogixNGIcon extends PositionableLabel { 022 023 public static final IdentityManager IDENTITY_MANAGER = new IdentityManager(); 024 025 private final int _identity; 026 private NamedIcon _originalIcon = new NamedIcon("resources/icons/logixng/logixng_icon.gif", "resources/icons/logixng/logixng_icon.gif"); 027 private String _originalText = Bundle.getMessage("LogixNGIcon_Text"); 028 029 public LogixNGIcon(String s, @Nonnull Editor editor) { 030 super(s, editor); 031 _identity = IDENTITY_MANAGER.getIdentity(this); 032 _originalText = s; 033 } 034 035 public LogixNGIcon(int identity, String s, @Nonnull Editor editor) { 036 super(s, editor); 037 _identity = IDENTITY_MANAGER.getIdentity(identity, this); 038 _originalText = s; 039 } 040 041 public LogixNGIcon(@CheckForNull NamedIcon s, @Nonnull Editor editor) { 042 super(s, editor); 043 _identity = IDENTITY_MANAGER.getIdentity(this); 044 _originalIcon = _namedIcon; 045 } 046 047 public LogixNGIcon(int identity, @CheckForNull NamedIcon s, @Nonnull Editor editor) { 048 super(s, editor); 049 _identity = IDENTITY_MANAGER.getIdentity(identity, this); 050 _originalIcon = _namedIcon; 051 052 // Please retain the line below. It's used to create the resources/icons/logixng/logixng_icon.gif icon 053 // createLogixNGIconImage(); 054 } 055 056 @Override 057 @Nonnull 058 public String getTypeString() { 059 return Bundle.getMessage("PositionableType_LogixNGIcon"); 060 } 061 062 public int getIdentity() { 063 return _identity; 064 } 065 066 @Override 067 protected void editIcon() { 068 super.editIcon(); 069 // If the icon is changed, we must remember that in case the user 070 // switches between icon -> text -> icon 071 _originalIcon = _namedIcon; 072 } 073 074 @Override 075 public void doMousePressed(JmriMouseEvent e) { 076 log.debug("doMousePressed"); 077 if (!e.isMetaDown() && !e.isAltDown()) { 078 executeLogixNG(); 079 } 080 super.doMousePressed(e); 081 } 082/* 083 @Override 084 public void doMouseReleased(JmriMouseEvent e) { 085 log.debug("doMouseReleased"); 086 if (!e.isMetaDown() && !e.isAltDown()) { 087 executeLogixNG(); 088 } 089 super.doMouseReleased(e); 090 } 091 092 @Override 093 public void doMouseClicked(JmriMouseEvent e) { 094 if (true && !true) { 095 // this button responds to clicks 096 if (!e.isMetaDown() && !e.isAltDown()) { 097 try { 098 if (getSensor().getKnownState() == jmri.Sensor.INACTIVE) { 099 getSensor().setKnownState(jmri.Sensor.ACTIVE); 100 } else { 101 getSensor().setKnownState(jmri.Sensor.INACTIVE); 102 } 103 } catch (jmri.JmriException reason) { 104 log.warn("Exception flipping sensor", reason); 105 } 106 } 107 } 108 super.doMouseClicked(e); 109 } 110*/ 111 public void executeLogixNG() { 112 LogixNG logixNG = getLogixNG(); 113 114 if (logixNG != null) { 115 for (int i=0; i < logixNG.getNumConditionalNGs(); i++) { 116 logixNG.getConditionalNG(i).execute(); 117 } 118 } 119 } 120 121 private void changeLogixNGIconType() { 122 _unRotatedText = null; 123 if (isIcon()) { 124 _icon = false; 125 _text = true; 126 setText(_originalText); 127 setIcon(null); 128 setOpaque(true); 129 } else if (isText()) { 130 _icon = true; 131 if (getText() != null) { 132 _originalText = getText(); 133 } 134 _text = false; 135 setText(null); 136 setUnRotatedText(null); 137 setOpaque(false); 138 setIcon(_originalIcon); 139 } 140 int deg = getDegrees(); 141 rotate(deg); 142 } 143 144 /** 145 * Pop-up just displays the sensor name. 146 * 147 * @param popup the menu to display 148 * @return always true 149 */ 150 @Override 151 public boolean showPopUp(JPopupMenu popup) { 152 if (isEditable()) { 153 if (isIcon()) { 154 popup.add(new AbstractAction(Bundle.getMessage("ChangeToText")) { 155 @Override 156 public void actionPerformed(ActionEvent e) { 157 changeLogixNGIconType(); 158 } 159 }); 160 } else { 161 popup.add(new AbstractAction(Bundle.getMessage("ChangeToIcon")) { 162 @Override 163 public void actionPerformed(ActionEvent e) { 164 changeLogixNGIconType(); 165 } 166 }); 167 } 168 } 169 return true; 170 } 171 172 173/* 174 // Please retain this commented method. It's used to create the resources/icons/logixng/logixng_icon.gif icon 175 176 private void createLogixNGIconImage() { 177 178 try { 179 int width = 90, height = 39; 180 181 // TYPE_INT_ARGB specifies the image format: 8-bit RGBA packed into integer pixels 182 java.awt.image.BufferedImage bi = new java.awt.image.BufferedImage(width, height, java.awt.image.BufferedImage.TYPE_INT_ARGB); 183 184 java.awt.Graphics2D ig2 = bi.createGraphics(); 185 186 ig2.setColor(java.awt.Color.WHITE); 187 ig2.fillRect(0, 0, width-1, height-1); 188 ig2.setColor(java.awt.Color.BLACK); 189 ig2.drawRect(0, 0, width-1, height-1); 190 191 java.awt.Font font = new java.awt.Font("Verdana", java.awt.Font.BOLD, 15); 192 ig2.setFont(font); 193 ig2.setPaint(java.awt.Color.black); 194 195 // Draw string twice to get more bold 196 ig2.drawString("LogixNG", 11, 24); 197 ig2.drawString("LogixNG", 12, 24); 198 199 javax.imageio.ImageIO.write(bi, "gif", new java.io.File(jmri.util.FileUtil.getExternalFilename("resources/icons/logixng/logixng_icon.gif"))); 200 } catch (java.io.IOException ie) { 201 throw new RuntimeException(ie); 202 } 203 } 204*/ 205 206 207 public static class IdentityManager { 208 209 Map<Integer, LogixNGIcon> _identities = new HashMap<>(); 210 int _lastIdentity = -1; 211 212 private IdentityManager() { 213 // Private constructor to keep it as a singleton 214 } 215 216 public int getIdentity(LogixNGIcon logixNGIcon) { 217 _lastIdentity++; 218 _identities.put(_lastIdentity, logixNGIcon); 219 return _lastIdentity; 220 } 221 222 public int getIdentity(int identity, LogixNGIcon logixNGIcon) { 223 if (_identities.containsKey(identity)) { 224 log.error("Identity {} already exists", identity); 225 return getIdentity(logixNGIcon); 226 } 227 _identities.put(identity, logixNGIcon); 228 if (identity > _lastIdentity) { 229 _lastIdentity = identity; 230 } 231 return identity; 232 } 233 234 public LogixNGIcon getLogixNGIcon(int identity) { 235 return _identities.get(identity); 236 } 237 238 } 239 240 241 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogixNGIcon.class); 242}