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.JemmyException; 26 import org.jemmy.Point; 27 import org.jemmy.Rectangle; 28 import org.jemmy.Vector; 29 import org.jemmy.env.Timeout; 30 import org.jemmy.action.Action; 31 import org.jemmy.control.Wrap; 32 import org.jemmy.interfaces.Caret; 33 import org.jemmy.interfaces.Drag; 34 import org.jemmy.interfaces.Scroll; 35 36 /** 37 * Performs scrolling by doing d'n'd of a "knob" wrap. To be used for controls 38 * like scroll bars, sliders. 39 * @author shura 40 */ 41 public abstract class KnobDragScrollerImpl implements Caret { 42 43 public static final int MAX_SCROLL_ATTEMPTS = 5; 44 45 Wrap<?> wrap; 46 Scroll scroll; 47 float dragDelta = 1; 48 boolean reverse; 49 50 /** 51 * 52 * @param wrap 53 * @param scroll 54 */ 55 public KnobDragScrollerImpl(Wrap<?> wrap, Scroll scroll) { 56 this.wrap = wrap; 57 this.scroll = scroll; 58 } 59 60 public KnobDragScrollerImpl(Wrap<?> wrap, Scroll scroll, boolean reverse) { 61 this(wrap, scroll); 62 this.reverse = reverse; 63 } 64 65 /** 66 * 67 * @return 68 */ 69 public Wrap<?> getWrap() { 70 return wrap; 71 } 72 73 /** 74 * 75 * @return 76 */ 77 public abstract Vector getScrollVector(); 78 79 /** 80 * 81 * @param dragDelta 82 */ 83 public void setDragDelta(float dragDelta) { 84 this.dragDelta = dragDelta; 85 } 86 87 private void toKnob(Wrap<?> knob, Point inWrap) { 88 inWrap.translate(wrap.getScreenBounds().x, wrap.getScreenBounds().y); 89 inWrap.translate(-knob.getScreenBounds().x, -knob.getScreenBounds().y); 90 } 91 92 private void toWrap(Wrap<?> knob, Point inWrap) { 93 inWrap.translate(knob.getScreenBounds().x, knob.getScreenBounds().y); 94 inWrap.translate(-wrap.getScreenBounds().x, -wrap.getScreenBounds().y); 95 } 96 97 public void to(double value) { 98 scroll.to(value); 99 } 100 101 public void to(final Direction condition) { 102 wrap.getEnvironment().getExecutor().execute(wrap.getEnvironment(), false, new Action() { 103 104 @Override 105 public void run(Object... parameters) { 106 int toOrig; 107 int dragAttempt = 0; 108 Timeout moveTimeout = wrap.getEnvironment().getTimeout(Drag.IN_DRAG_TIMEOUT).clone(); 109 while((toOrig = condition.to()) != 0) { 110 Vector axis = getScrollVector(). 111 multiply(toOrig).setLenght(dragDelta); 112 if (reverse) { 113 axis.multiply(-1); 114 } 115 Vector shift = axis.clone(); 116 Wrap<?> knob = getKnob(); 117 Point orig = new Point(knob.getScreenBounds().getX() + knob.getScreenBounds().getWidth()/2, knob.getScreenBounds().getY() + knob.getScreenBounds().getHeight()/2); 118 knob.mouse().move(knob.toLocal(orig.getLocation())); 119 knob.mouse().press(); 120 wrap.getEnvironment().getTimeout(Drag.BEFORE_DRAG_TIMEOUT).sleep(); 121 try { 122 while (condition.to() == toOrig) { 123 wrap.getEnvironment().getTimeout(Drag.IN_DRAG_TIMEOUT).sleep(); 124 // Rectangle old_pos = knob.getScreenBounds(); 125 knob.mouse().move(knob.toLocal(orig.getLocation().translate(shift))); 126 // if (old_pos.equals(knob.getScreenBounds())) { // TODO: it would be better to check if we achieve maximum position 127 // break; 128 // } 129 if(scroll.position() == scroll.minimum() || scroll.position() == scroll.maximum()) { 130 break; 131 } 132 shift.add(axis); 133 } 134 } finally { 135 wrap.getEnvironment().getTimeout(Drag.BEFORE_DROP_TIMEOUT).sleep(); 136 knob.mouse().release(); 137 } 138 dragAttempt++; 139 if(dragAttempt >= MAX_SCROLL_ATTEMPTS) { 140 //did what we could 141 return; 142 } 143 //slow dow the scrolling 144 moveTimeout.setValue((long) (moveTimeout.getValue() * 1.5)); 145 } 146 } 147 }); 148 } 149 150 /* 151 * Create another class for this perhaps 152 private void initialDrag(double value) { 153 Point hp = getEndPoint(false); 154 Point lp = getEndPoint(true); 155 double xdiff = hp.x - lp.x; 156 double ydiff = hp.y - lp.y; 157 double ratio = value / (scroll.maximum() - scroll.minimum()); 158 Wrap<?> knob = getKnob(); 159 Point p = new Point(xdiff * ratio, ydiff * ratio); 160 toKnob(knob, p); 161 Point clickPoint = knob.getClickPoint(); 162 p.translate(clickPoint.x, clickPoint.y); 163 knob.drag().dnd(clickPoint, knob, p); 164 } 165 * 166 */ 167 /** 168 * 169 * @return 170 */ 171 protected abstract Wrap<?> getKnob(); 172 }