001    package nl.cwi.sen1.util;
002    
003    import java.awt.event.InputEvent;
004    import java.awt.event.MouseEvent;
005    
006    import javax.swing.event.MouseInputAdapter;
007    
008    import nl.cwi.sen1.configapi.Factory;
009    import nl.cwi.sen1.configapi.types.Event;
010    import nl.cwi.sen1.configapi.types.KeyModifierList;
011    import nl.cwi.sen1.configapi.types.VirtualButton;
012    import toolbus.AbstractTool;
013    import aterm.ATerm;
014    import aterm.pure.PureFactory;
015    
016    /**
017     * This is a generic MouseAdapter useful for any MetaStudio component that needs
018     * to send mouse events to the ToolBus. It has some magic: if the component is a
019     * subclass of JTextComponent it also stores the correct caret position, next to
020     * the other details of a MouseEvent (x,y) pos. These can be used for later
021     * inspection when the ToolBus scripts might ask for further details.
022     * 
023     * @author jurgenv
024     * 
025     */
026    public class MouseAdapter extends MouseInputAdapter {
027            private Factory factory;
028    
029            private AbstractTool bridge;
030    
031            private ATerm id;
032    
033            private Event event;
034            
035            static private MouseEvent popupEvent;
036    
037            public void setId(ATerm id) {
038                    this.id = id;
039            }
040            
041            public MouseAdapter(ATerm id, AbstractTool bridge, Event event) {
042                    this.factory = Factory.getInstance((PureFactory) id.getFactory());
043                    this.bridge = bridge;
044                    this.id = id;
045                    this.event = event;
046            }
047    
048            public void mousePressed(MouseEvent e) {
049                    if (event.isEqual(convert(e))) {
050                            ATerm msg = factory.getPureFactory().make(
051                                            "mouse-event(<term>,<term>)",
052                                            this.id, this.event.toTerm());
053                            bridge.postEvent(msg);
054                    }
055            }
056    
057            public void mouseReleased(MouseEvent e) {
058                    if (e.isPopupTrigger()) {
059                      mousePressed(e);
060                    }
061            }
062    
063            static public MouseEvent getPreviousPopupEvent() {
064                    return popupEvent;
065            }
066            
067            private Event convert(MouseEvent e) {
068                    if (e.isPopupTrigger()) {
069                            popupEvent = e;
070                            return factory.makeEvent_Popup();
071                    }
072                    int mask = e.getModifiers();
073                    return factory.makeEvent_Click(modifiers(mask), button(mask));
074            }
075    
076            private KeyModifierList modifiers(int modifiers) {
077                    KeyModifierList mods = factory.makeKeyModifierList();
078    
079                    if ((modifiers & InputEvent.CTRL_DOWN_MASK) != 0) {
080                            mods.insert(factory.makeKeyModifier_M_CTRL());
081                    }
082                    if ((modifiers & InputEvent.ALT_DOWN_MASK) != 0) {
083                            mods.insert(factory.makeKeyModifier_M_CTRL());
084                    }
085                    if ((modifiers & InputEvent.SHIFT_DOWN_MASK) != 0) {
086                            mods.insert(factory.makeKeyModifier_M_CTRL());
087                    }
088    
089                    return mods;
090            }
091    
092            private VirtualButton button(int modifiers) {
093                    if ((modifiers & InputEvent.BUTTON1_DOWN_MASK) != 0) {
094                            return factory.makeVirtualButton_BUTTON1();
095                    }
096                    if ((modifiers & InputEvent.BUTTON2_DOWN_MASK) != 0) {
097                            return factory.makeVirtualButton_BUTTON2();
098                    }
099                    if ((modifiers & InputEvent.BUTTON3_DOWN_MASK) != 0) {
100                            return factory.makeVirtualButton_BUTTON3();
101                    }
102                    return factory.makeVirtualButton_NOBUTTON();
103            }
104    }