001package org.vishia.gral.awt;
002
003import java.awt.Color;
004import java.awt.Component;
005import java.awt.Dimension;
006import java.awt.Point;
007import java.awt.Rectangle;
008import java.awt.event.MouseEvent;
009import java.awt.event.MouseListener;
010import java.awt.event.MouseMotionListener;
011
012import org.vishia.gral.base.GralMouseWidgetAction_ifc;
013import org.vishia.gral.base.GralWidget;
014import org.vishia.gral.base.GralMng;
015import org.vishia.gral.ifc.GralRectangle;
016import org.vishia.gral.ifc.GralUserAction;
017import org.vishia.gral.ifc.GralWidget_ifc;
018import org.vishia.util.KeyCode;
019
020/**Common used {@link MouseListener} for all gral widgets.
021 * 
022 * @author Hartmut Schorrig
023 *
024 */
025public class AwtGralMouseListener
026{
027  /**This class implements a MouseListener which does not call a user method.
028   * Only the information about the clicked widget are stored in the GralMng
029   * and the Gral designer is supported.
030   * 
031   */
032  public static class MouseListenerNoAction implements MouseListener
033  {
034
035    
036    public MouseListenerNoAction()
037    {
038    }
039
040    int xDown, yDown;
041    
042    /**The mouse-down action save some informations about the widget.
043     * It may be overridden by an derived class, then this method should be invoked within.
044     */
045    @Override public void mousePressed(MouseEvent ev)
046    {
047      AwtWidget widget = (AwtWidget)ev.getComponent();
048      Object oInfo = widget.getData();
049      if(oInfo instanceof GralWidget){
050        GralWidget widgetInfo = (GralWidget)oInfo;
051        GralMng guiMng = widgetInfo.gralMng();
052        try{
053          if(widgetInfo ==null || widgetInfo.getDataPath() ==null || !widgetInfo.getDataPath().equals("widgetInfo")){
054            guiMng.setLastClickedWidget(widgetInfo );
055          }
056          if(guiMng.bDesignMode){
057            GralRectangle rr = new GralRectangle(ev.getX(), ev.getY(), 0, 0);
058            if(ev.getButton() == 1){ //left
059              xDown = ev.getX(); yDown = ev.getY();
060              guiMng.pressedLeftMouseDownForDesign(widgetInfo, rr);  
061            } else if(ev.getButton() == 3){ //right
062              //guiMng.pressedRightMouseDownForDesign(widgetInfo, rr);
063            }
064          }
065        } catch(Exception exc){ guiMng.writeLog(0, exc); }
066
067    }
068      
069    }
070
071    /**The mouse up is left empty. It may be overridden by an derived class. */
072    @Override public void mouseReleased(MouseEvent ev)
073    { AwtWidget widget = (AwtWidget)ev.getComponent();
074      Object oInfo = widget.getData();
075      if(oInfo instanceof GralWidget){
076        GralWidget widgetInfo = (GralWidget)oInfo;
077        GralMng guiMng = widgetInfo.gralMng();
078        try{
079          GralWidget widgd = (GralWidget)oInfo;
080          int dx = ev.getX() - xDown, dy = ev.getY() - yDown;
081          if(dx < 10 && dx > -10 && dy < 10 && dy > -10){
082            GralWidget_ifc.ActionChange action = widgd.getActionChange(GralWidget_ifc.ActionChangeWhen.onMouse1Up); 
083            if(action !=null){
084              Object[] args = action.args();
085              if(args == null){ action.action().exec(KeyCode.mouse1Up, widgd, new Integer(ev.getX()), new Integer(ev.getY())); }
086              else { 
087                //additional 2 arguments: copy in one args2.
088                Object[] args2 = new Object[args.length +2];
089                System.arraycopy(args, 0, args2, 0, args.length);
090                args2[args.length] = new Integer(ev.getX());
091                args2[args.length+1] = new Integer(ev.getY());
092                action.action().exec(KeyCode.mouse1Up, widgd, args2); 
093              }
094            }
095          } else if(guiMng.bDesignMode && ev.getButton() == 1){
096            boolean bCopy = (ev.getModifiers() & 99999) !=0;
097            GralRectangle rr = new GralRectangle(ev.getX(), ev.getY(), 0, 0);
098            guiMng.releaseLeftMouseForDesign(widgd, rr, bCopy);  
099          }
100          //widgd.redraw();
101        } catch(Exception exc){ guiMng.writeLog(0, exc); }
102        
103      }
104      
105    }
106    
107    
108
109    /**The mouse doubleclick is left empty. It may be overridden by an derived class. */
110       @Override
111    public void mouseClicked(MouseEvent e)
112    {
113      // TODO Auto-generated method stub
114      
115    }
116
117    @Override
118    public void mouseEntered(MouseEvent e)
119    {
120      // TODO Auto-generated method stub
121      
122    }
123
124    @Override
125    public void mouseExited(MouseEvent e)
126    {
127      // TODO Auto-generated method stub
128      
129    }
130      
131
132    
133  }
134 
135
136  
137  
138  
139  
140  public static class MouseListenerGralAction extends MouseListenerNoAction
141  implements MouseListener
142  {
143    
144    /**Positions saved on mouse press, to detect whether the mouse-release occurs in the pressed area.
145     * If the mouse-position is shifted outside the area of the widget, the mouse-release-user-action
146     * is not executed.
147     */
148    private int xMousePress, yMousePress;
149    
150    private Color backgroundWhilePressed;
151    
152    /**Used in the implementation level for the paint routine. Therefore it is package private.
153     */
154    protected boolean isPressed;
155    
156    
157    
158    protected final GralMouseWidgetAction_ifc mouseWidgetAction;
159    
160    
161    /**Constructor.
162     * @param guiMng The Gui-manager
163     * @param userCmdGui The users method for the action. 
164     * @param sCmdPress command string provided as first parameter on mouse button press.
165     * @param sCmdRelease
166     * @param sCmdDoubleClick
167     */
168    public MouseListenerGralAction(GralMouseWidgetAction_ifc mouseWidgetAction)
169    { super();
170      this.mouseWidgetAction = mouseWidgetAction;
171    }
172    
173    
174
175    @Override
176    public void mouseClicked(MouseEvent ev) {
177      xMousePress = ev.getX();
178      yMousePress = ev.getY();
179      AwtWidget widget = (AwtWidget)ev.getComponent();
180      GralWidget widgg = (GralWidget)widget.getData();
181      GralWidget_ifc.ActionChange action = widgg.getActionChange(GralWidget_ifc.ActionChangeWhen.onMouse1Double); 
182      if(action !=null){
183        Object[] args = action.args();
184        if(args == null){ action.action().exec(KeyCode.mouse1Double, widgg, new Integer(ev.getX()), new Integer(ev.getY())); }
185        else { 
186          //additional 2 arguments: copy in one args2.
187          Object[] args2 = new Object[args.length +2];
188          System.arraycopy(args, 0, args2, 0, args.length);
189          args2[args.length] = new Integer(ev.getX());
190          args2[args.length+1] = new Integer(ev.getY());
191          action.action().exec(KeyCode.mouse1Double, widgg, args2); 
192        }
193      }
194    }
195
196    @Override public void mousePressed(MouseEvent e) {
197      super.mousePressed(e);
198      isPressed = true;
199      xMousePress = e.getX();
200      yMousePress = e.getY();
201      Component widget = e.getComponent();
202      AwtWidget widgetAwt = (AwtWidget)widget;
203      widget.addMouseMotionListener(mouseMoveListener);
204      Object oData = widgetAwt.getData();
205      GralWidget widgg = (GralWidget)oData;  //maybe null
206      Dimension size = widget.getSize();
207      try{ 
208        final int keyCode;
209        switch(e.getButton()){ 
210          case 1: keyCode = KeyCode.mouse1Down; break; 
211          case 2: keyCode = KeyCode.mouse2Down; break;
212          case 3: keyCode = KeyCode.mouse3Down; break;
213          default: keyCode = KeyCode.mouse3Down; break;  //other key
214        }
215        if(mouseWidgetAction !=null){
216          switch(e.getButton()){ 
217            case 1: mouseWidgetAction.mouse1Down(keyCode, xMousePress, yMousePress, size.width, size.height, widgg); break;
218            case 2: mouseWidgetAction.mouse2Down(keyCode, xMousePress, yMousePress, size.width, size.height, widgg); break;
219          }  
220        }
221        GralWidget_ifc.ActionChange action = widgg.getActionChange(null); 
222        if(action !=null){
223          Object[] args = action.args();
224          if(args == null){ action.action().exec(keyCode, widgg, new Integer(e.getX()), new Integer(e.getY())); }
225          else { 
226            //additional 2 arguments: copy in one args2.
227            Object[] args2 = new Object[args.length +2];
228            System.arraycopy(args, 0, args2, 0, args.length);
229            args2[args.length] = new Integer(e.getX());
230            args2[args.length+1] = new Integer(e.getY());
231            action.action().exec(keyCode, widgg, args2); 
232          }
233        }
234      } catch(Exception exc){ System.err.printf("AwtGralMouseListener - any exception while mouse down; %s\n", exc.getMessage()); }
235    }
236
237    
238    
239    
240    @Override public void mouseReleased(MouseEvent e) {
241      //set the background color to the originally value again if it was changed.
242      super.mouseReleased(e);
243      if(isPressed){
244        Component widget = e.getComponent();
245        AwtWidget widgetAwt = (AwtWidget)widget;
246        Dimension size = widget.getSize();
247        GralWidget widgg = (GralWidget)widgetAwt.getData();
248        widget.removeMouseMotionListener(mouseMoveListener);
249        isPressed = false;
250        final int keyCode;
251        GralWidget_ifc.ActionChangeWhen whenAction;
252        switch(e.getButton()){ 
253          case 1: keyCode = KeyCode.mouse1Up; whenAction = GralWidget_ifc.ActionChangeWhen.onMouse1Up; break; 
254          case 2: keyCode = KeyCode.mouse2Up; whenAction = GralWidget_ifc.ActionChangeWhen.onMouse2Up; break;
255          case 3: keyCode = KeyCode.mouse3Up; whenAction = null; break;
256          default: keyCode = KeyCode.mouse3Up; whenAction = null; break;  //other key
257        }
258        if(mouseWidgetAction !=null){
259          switch(e.getButton()){ 
260            case 1: mouseWidgetAction.mouse1Up(keyCode, e.getX(), e.getY(), size.width, size.height, widgg); break;
261            case 2: mouseWidgetAction.mouse2Up(keyCode, e.getX(), e.getY(), size.width, size.height, widgg); break;
262          }  
263        }
264        backgroundWhilePressed = null;
265        try{ 
266          GralWidget_ifc.ActionChange action = widgg.getActionChange(whenAction); 
267          if(action !=null){
268            Object[] args = action.args();
269            if(args == null){ action.action().exec(keyCode, widgg); }
270            else { action.action().exec(keyCode, widgg, args); }
271          }
272        } catch(Exception exc){ System.err.printf("SwtGralMouseListener - any exception while mouse down; %s\n", exc.getMessage()); }
273        //widgg.repaint();
274      }
275    }
276
277    protected MouseMotionListener mouseMoveListener = new MouseMotionListener()
278    {
279
280      @Override public void mouseMoved(MouseEvent e)
281      {
282      }//method mouseMoved
283
284      @Override
285      public void mouseDragged(MouseEvent e)
286      {
287        if(e.getComponent() instanceof AwtWidget){
288          Component widget = e.getComponent();
289          AwtWidget widgetAwt = (AwtWidget)widget;
290          Rectangle size = widget.getBounds();
291          if(mouseWidgetAction !=null){
292            if(!mouseWidgetAction.mouseMoved(e.getX(), e.getY(), size.x, size.y)){
293              isPressed = false;
294              widget.removeMouseMotionListener(mouseMoveListener);
295            }
296            mouseWidgetAction.mouseMoved(e.getX(), e.getY(), size.x, size.y);
297            //mouseWidgetAction.removeMouseCursorFromWidgetWhilePressed();
298          }
299        } 
300      }//method mouseDragged
301    };
302    
303
304  }
305
306
307  
308  
309}