1 /*
   2  * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package org.jemmy.input;
  24 
  25 import org.jemmy.Rectangle;
  26 import org.jemmy.Point;
  27 import java.util.Arrays;
  28 import org.jemmy.action.Action;
  29 import org.jemmy.control.Wrap;
  30 import org.jemmy.env.Environment;
  31 import org.jemmy.env.Timeout;
  32 import org.jemmy.interfaces.Modifier;
  33 import org.jemmy.interfaces.Mouse;
  34 import static org.jemmy.interfaces.Mouse.CLICK;
  35 import org.jemmy.interfaces.Showable;
  36 
  37 /**
  38  *
  39  * @author shura
  40  */
  41 public class MouseImpl implements Mouse {
  42 
  43     private Wrap<?> target;
  44     private RobotDriver robotDriver;
  45     private boolean detached = false;
  46 
  47     static {
  48         if (Environment.getEnvironment().getTimeout(CLICK) == null) {
  49             Environment.getEnvironment().setTimeout(MouseImpl.CLICK);
  50         }
  51     }
  52 
  53     /**
  54      *
  55      * @param target
  56      */
  57     public MouseImpl(Wrap<?> target) {
  58         this.target = target;
  59         this.robotDriver = new RobotDriver(new Timeout("", 10));
  60     }
  61 
  62     public Mouse detached() {
  63         this.detached = true;
  64         return this;
  65     }
  66 
  67     private void runAction(Action action) {
  68         if (detached) {
  69             target.getEnvironment().getExecutor().executeDetached(target.getEnvironment(), false, action);
  70         } else {
  71             target.getEnvironment().getExecutor().execute(target.getEnvironment(), false, action);
  72         }
  73     }
  74 
  75     /**
  76      *
  77      */
  78     @Override
  79     public void press() {
  80         press(MouseButtons.BUTTON1);
  81     }
  82 
  83     /**
  84      *
  85      * @param button
  86      */
  87     @Override
  88     public void press(MouseButton button) {
  89         press(button, new Modifier[]{});
  90     }
  91 
  92      /**
  93      *
  94      * @param button
  95      * @param modifiers
  96      */
  97     @Override
  98     public void press(final MouseButton button, final Modifier... modifiers) {
  99         runAction(new Action() {
 100 
 101             public void run(Object... parameters) {
 102                 robotDriver.pressMouse(button, modifiers);
 103             }
 104 
 105             @Override
 106             public String toString() {
 107                 return "pressing mouse button " + button + " with " + modifiers + " modifiers";
 108             }
 109         });
 110     }
 111 
 112     /**
 113      *
 114      */
 115     public void release() {
 116         release(MouseButtons.BUTTON1);
 117     }
 118 
 119     /**
 120      *
 121      * @param button
 122      */
 123     @Override
 124     public void release(MouseButton button) {
 125         release(button, new Modifier[]{});
 126     }
 127 
 128     /**
 129      *
 130      * @param button
 131      * @param modifiers
 132      */
 133     @Override
 134     public void release(final MouseButton button, final Modifier... modifiers) {
 135         runAction(new Action() {
 136 
 137             public void run(Object... parameters) {
 138                 robotDriver.releaseMouse(button, modifiers);
 139             }
 140 
 141             @Override
 142             public String toString() {
 143                 return "releasing mouse button " + button + " with " + modifiers + " modifiers";
 144             }
 145         });
 146     }
 147 
 148     /**
 149      *
 150      */
 151     public void move() {
 152         move(target.getClickPoint());
 153     }
 154 
 155     /**
 156      *
 157      * @param p
 158      */
 159     public void move(final Point p) {
 160         runAction(new Action() {
 161 
 162             public void run(Object... parameters) {
 163                 robotDriver.moveMouse(getAbsolute(target, p));
 164             }
 165 
 166             @Override
 167             public String toString() {
 168                 return "moving mouse to " + p;
 169             }
 170         });
 171     }
 172 
 173     /**
 174      *
 175      */
 176     public void click() {
 177         this.click(1);
 178     }
 179 
 180     /**
 181      *
 182      * @param count
 183      */
 184     public void click(int count) {
 185         this.click(count, null);
 186     }
 187 
 188     /**
 189      *
 190      * @param count
 191      * @param p Point to click, if null {@linkplain Wrap#getClickPoint()
 192      * Wrap.getClickPoint()} method is invoked to get the point to click.
 193      */
 194     public void click(int count, Point p) {
 195         this.click(count, p, MouseButtons.BUTTON1);
 196     }
 197 
 198     /**
 199      *
 200      * @param count
 201      * @param p Point to click, if null {@linkplain Wrap#getClickPoint()
 202      * Wrap.getClickPoint()} method is invoked to get the point to click.
 203      * @param button
 204      */
 205     @Override
 206     public void click(int count, Point p, MouseButton button) {
 207         click(count, p, button, new Modifier[] {});
 208     }
 209 
 210     /**
 211      *
 212      * @param count
 213      * @param p Point to click, if null {@linkplain Wrap#getClickPoint()
 214      * Wrap.getClickPoint()} method is invoked to get the point to click.
 215      * @param button
 216      * @param modifiers
 217      */
 218     @Override
 219     public void click(final int count, final Point p, final MouseButton button, final Modifier... modifiers) {
 220         runAction(new Action() {
 221 
 222             public void run(Object... parameters) {
 223                 if (target.is(Showable.class)) {
 224                     target.as(Showable.class).shower().show();
 225                 }
 226                 robotDriver.clickMouse(getAbsolute(target,
 227                         p == null ? target.getClickPoint() : p),
 228                         count, button, target.getEnvironment().getTimeout(CLICK), modifiers);
 229             }
 230 
 231             @Override
 232             public String toString() {
 233                 return "clicking " + button + " mouse button " + count + " times at " + p + " with " + Arrays.toString(modifiers) + " modifiers";
 234             }
 235         });
 236     }
 237 
 238     static Point getAbsolute(Wrap<?> target, Point p) {
 239         Rectangle screenBounds = target.getScreenBounds();
 240         return new Point(p.x + screenBounds.x, p.y + screenBounds.y);
 241     }
 242 
 243     private void turn(final Point p, final int amount, final Modifier... modifiers) {
 244         runAction(new Action() {
 245 
 246             public void run(Object... parameters) {
 247                 if (target.is(Showable.class)) {
 248                     target.as(Showable.class).shower().show();
 249                 }
 250                 robotDriver.turnWheel(getAbsolute(target,
 251                         p == null ? target.getClickPoint() : p),
 252                         amount, modifiers);
 253             }
 254 
 255             @Override
 256             public String toString() {
 257                 return "turning wheel to " + amount + " with " + Arrays.toString(modifiers) + " modifiers";
 258             }
 259         });
 260     }
 261 
 262     public void turnWheel(Point point, final int amount, Modifier... modifiers) {
 263         turn(point, amount, modifiers);
 264     }
 265 
 266     public void turnWheel(Point point, final int amount) {
 267         turn(point, amount, new Modifier[]{});
 268     }
 269 
 270     public void turnWheel(final int amount) {
 271         turn(null, amount, new Modifier[]{});
 272     }
 273 }