001 package nl.cwi.sen1.tide.tool.srcviewer; 002 003 //{{{ imports 004 005 import java.awt.BorderLayout; 006 import java.awt.Color; 007 import java.awt.Component; 008 import java.awt.Container; 009 import java.awt.Dimension; 010 import java.awt.Font; 011 import java.awt.FontMetrics; 012 import java.awt.Graphics; 013 import java.awt.Point; 014 import java.awt.Rectangle; 015 import java.awt.event.ActionEvent; 016 import java.awt.event.ActionListener; 017 import java.net.URL; 018 019 import javax.swing.Icon; 020 import javax.swing.ImageIcon; 021 import javax.swing.JComponent; 022 import javax.swing.JPanel; 023 import javax.swing.JPopupMenu; 024 025 import nl.cwi.sen1.tide.tool.ToolManager; 026 import nl.cwi.sen1.tide.tool.ruleinspector.RuleInspector; 027 import nl.cwi.sen1.tide.tool.ruleinspector.RuleInspectorFactory; 028 import nl.cwi.sen1.tide.tool.support.DebugProcess; 029 import nl.cwi.sen1.tide.tool.support.DebugProcessListener; 030 import nl.cwi.sen1.tide.tool.support.Expr; 031 import nl.cwi.sen1.tide.tool.support.ExprFormat; 032 import nl.cwi.sen1.tide.tool.support.Port; 033 import nl.cwi.sen1.tide.tool.support.ProcessStatusChangeListener; 034 import nl.cwi.sen1.tide.tool.support.Rule; 035 036 //}}} 037 038 class ValuePopup 039 extends JPanel 040 implements DebugProcessListener, ProcessStatusChangeListener, ActionListener { 041 //{{{ Constants 042 043 public final static int ICON_SIZE = 14; 044 045 private final static String TAG_UPDATE = "vp-update"; 046 047 /* 048 * private final static Color COLOR_BACK_CLEAN= new Color(0xFF,0xCC,0xCC); 049 * private final static Color COLOR_BACK_DIRTY= new Color(0xFF,0x99,0x99); 050 */ 051 private final static Color COLOR_BACK_CLEAN = new Color(0xEE, 0xEE, 0x00); 052 private final static Color COLOR_BACK_DIRTY = new Color(0xCC, 0xCC, 0x00); 053 private final static Color COLOR_BORDER = new Color(0x00, 0x00, 0x00); 054 055 private final static String ITEM_EDIT_RULE = "Edit Rule"; 056 private final static String ITEM_VIEW_VARIABLE = "View Variable"; 057 058 //}}} 059 060 //{{{ Attributes 061 062 private static int next_id = 0; 063 064 private int id; 065 private ToolManager manager; 066 private SourceFileViewer viewer; 067 068 private String tag_update; 069 070 private DebugProcess process; 071 private Rule updateRule; 072 private Expr expr; 073 private String label; 074 private ExprFormat format; 075 076 private boolean uptodate; 077 078 private String content; 079 private Font font; 080 private FontMetrics metrics; 081 private Icon closeIcon; 082 083 private int drag_trans_x; 084 private int drag_trans_y; 085 086 private JPopupMenu menu; 087 088 //}}} 089 090 //{{{ public ValuePopup(manager, viewer, process, expr, label, initial) 091 092 public ValuePopup( 093 ToolManager manager, 094 SourceFileViewer viewer, 095 DebugProcess process, 096 Expr expr, 097 String label, 098 Expr initial_value, 099 ExprFormat fmt) { 100 this.id = next_id++; 101 this.manager = manager; 102 this.viewer = viewer; 103 this.process = process; 104 this.expr = expr; 105 this.label = label; 106 this.format = fmt; 107 108 tag_update = TAG_UPDATE + "-" + id; 109 110 uptodate = true; 111 112 process.addDebugProcessListener(this); 113 process.addProcessStatusChangeListener(this); 114 115 closeIcon = loadIcon("mini-close.gif"); 116 117 content = label + "=" + format.format(initial_value); 118 119 setLayout(new BorderLayout()); 120 121 setBackground(new Color(0xFF, 0xFF, 0x00)); 122 this.setOpaque(true); 123 setDoubleBuffered(true); 124 font = new Font("Helvetica", Font.BOLD, 12); 125 metrics = getFontMetrics(font); 126 127 setSize(getPreferredSize()); 128 129 process.requestRuleCreation( 130 Port.makeStopped(), 131 Expr.makeTrue(), 132 expr, 133 tag_update, 134 true); 135 136 //{{{ Create menu 137 138 menu = new JPopupMenu("Variable " + label); 139 menu.add(ITEM_EDIT_RULE).addActionListener(this); 140 menu.add(ITEM_VIEW_VARIABLE).addActionListener(this); 141 142 //}}} 143 } 144 145 //}}} 146 //{{{ public Rule getUpdateRule() 147 148 public Rule getUpdateRule() { 149 return updateRule; 150 } 151 152 //}}} 153 //{{{ private loadIcon(String name) 154 155 private Icon loadIcon(String name) { 156 URL url = getClass().getResource("/resources/images/" + name); 157 return new ImageIcon(url); 158 } 159 160 //}}} 161 //{{{ public Dimension getPreferredSize() 162 163 public Dimension getPreferredSize() { 164 return new Dimension( 165 ICON_SIZE + 4 + metrics.stringWidth(content), 166 Math.max( 167 ICON_SIZE + 4, 168 2 + metrics.getMaxAscent() + metrics.getMaxDescent())); 169 } 170 171 //}}} 172 //{{{ public void paint(Graphics g) 173 174 public void paint(Graphics g) { 175 int width = getSize().width; 176 int height = getSize().height; 177 178 g.setFont(font); 179 g.setColor(uptodate ? COLOR_BACK_CLEAN : COLOR_BACK_DIRTY); 180 g.fillRect(0, 0, width, height); 181 g.setColor(COLOR_BORDER); 182 g.drawRect(0, 0, width - 1, height - 1); 183 g.setColor(Color.black); 184 185 closeIcon.paintIcon(this, g, 0, (height - ICON_SIZE) / 2); 186 g.drawString( 187 content, 188 ICON_SIZE + 3, 189 (height - metrics.getHeight()) / 2 + metrics.getMaxAscent() + 1); 190 } 191 192 //}}} 193 //{{{ public void show(JComponent invoker, int x, int y) 194 195 public void show(JComponent invoker, int x, int y) { 196 Point p = new Point(x, y); 197 //SwingUtilities.convertPointFromScreen(p,invoker.getRootPane().getLayeredPane()); 198 this.setBounds(p.x, p.y, getSize().width, getSize().height); 199 /* 200 * invoker.getRootPane().getLayeredPane().add(this, 201 * JLayeredPane.POPUP_LAYER,0); 202 */ 203 invoker.add(this); 204 setVisible(true); 205 invoker.repaint(p.x, p.y, getSize().width, getSize().height); 206 } 207 208 //}}} 209 //{{{ public void remove() 210 211 public void remove() { 212 Container parent = getParent(); 213 Rectangle r = this.getBounds(); 214 if (parent != null) { 215 parent.remove(this); 216 parent.repaint(r.x, r.y, r.width, r.height); 217 } 218 } 219 220 //}}} 221 //{{{ public void startDragging(int start_x, int start_y) 222 223 public void startDragging(int start_x, int start_y) { 224 drag_trans_x = getX() - start_x; 225 drag_trans_y = getY() - start_y; 226 } 227 228 //}}} 229 //{{{ public int getDragTransX() 230 231 public int getDragTransX() { 232 return drag_trans_x; 233 } 234 235 //}}} 236 //{{{ public int getDragTransY() 237 238 public int getDragTransY() { 239 return drag_trans_y; 240 } 241 242 //}}} 243 244 //{{{ public void closePopup() 245 246 public void closePopup() { 247 process.removeProcessStatusChangeListener(this); 248 process.removeDebugProcessListener(this); 249 } 250 251 //}}} 252 //{{{ public void updateValue() 253 254 public void updateValue() { 255 process.requestEvaluation(expr, tag_update); 256 } 257 258 //}}} 259 //{{{ public void showMenu(Component parent, int x, int y) 260 261 public void showMenu(Component parent, int x, int y) { 262 menu.show(parent, x, y); 263 } 264 265 //}}} 266 267 //{{{ public void actionPerformed(ActionEvent event) 268 269 public void actionPerformed(ActionEvent event) { 270 if (event.getActionCommand().equals(ITEM_EDIT_RULE)) { 271 String toolName = RuleInspectorFactory.NAME; 272 RuleInspector inspector = 273 (RuleInspector) manager.launchProcessTool(toolName, process); 274 inspector.editRule(updateRule); 275 } else if (event.getActionCommand().equals(ITEM_VIEW_VARIABLE)) {} 276 } 277 278 //}}} 279 280 //{{{ public void processStatusChanged(DebugProcess process) 281 282 public void processStatusChanged(DebugProcess process) { 283 if (process.isRunning()) { 284 uptodate = false; 285 repaint(); 286 } 287 } 288 289 //}}} 290 291 //{{{ private void updateValue(Expr value) 292 293 private void updateValue(Expr value) { 294 content = label + "=" + format.format(value); 295 uptodate = process.isStopped(); 296 setSize(getPreferredSize()); 297 repaint(); 298 } 299 300 //}}} 301 302 //{{{ public void ruleCreated(DebugProcess process, Rule rule) 303 304 public void ruleCreated(DebugProcess process, Rule rule) { 305 if (rule.getTag().equals(tag_update)) { 306 updateRule = rule; 307 } 308 } 309 310 //}}} 311 //{{{ public void ruleDeleted(DebugProcess process, Rule rule) 312 313 public void ruleDeleted(DebugProcess process, Rule rule) { 314 if (rule == updateRule) { 315 viewer.removeValuePopup(this); 316 } 317 } 318 319 //}}} 320 //{{{ public void ruleModified(DebugProcess process, Rule rule) 321 322 public void ruleModified(DebugProcess process, Rule rule) { 323 } 324 325 //}}} 326 //{{{ public void ruleTriggered(DebugProcess process, Rule rule, Expr 327 // value) 328 329 public void ruleTriggered(DebugProcess process, Rule rule, Expr value) { 330 if (rule == updateRule) { 331 updateValue(value); 332 } 333 } 334 335 //}}} 336 //{{{ public void evaluationResult(process, expr, value, tag) 337 338 public void evaluationResult(DebugProcess process, Expr expr, Expr value, String tag) { 339 if (tag.equals(tag_update)) { 340 updateValue(value); 341 } 342 } 343 344 //}}} 345 //{{{ public void selectRule(DebugProcess process, Rule rule) 346 347 public void selectRule(DebugProcess process, Rule rule) {} 348 349 //}}} 350 }