Add ICU message format support
[chromium-blink-merge.git] / tools / site_compare / drivers / win32 / mouse.py
blob0096af987cabafb9bdafafef9ec34f46d0080a2c
1 #!/usr/bin/env python
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """SiteCompare module for simulating mouse input.
8 This module contains functions that can be used to simulate a user
9 navigating using a pointing device. This includes mouse movement,
10 clicking with any button, and dragging.
11 """
13 import time # for sleep
15 import win32api # for mouse_event
16 import win32con # Windows constants
17 import win32gui # for window functions
20 def ScreenToMouse(pt):
21 """Convert a value in screen coordinates to mouse coordinates.
23 Mouse coordinates are specified as a percentage of screen dimensions,
24 normalized to 16 bits. 0 represents the far left/top of the screen,
25 65535 represents the far right/bottom. This function assumes that
26 the size of the screen is fixed at module load time and does not change
28 Args:
29 pt: the point of the coords to convert
31 Returns:
32 the converted point
33 """
35 # Initialize the screen dimensions on first execution. Note that this
36 # function assumes that the screen dimensions do not change during run.
37 if not ScreenToMouse._SCREEN_DIMENSIONS:
38 desktop = win32gui.GetClientRect(win32gui.GetDesktopWindow())
39 ScreenToMouse._SCREEN_DIMENSIONS = (desktop[2], desktop[3])
41 return ((65535 * pt[0]) / ScreenToMouse._SCREEN_DIMENSIONS[0],
42 (65535 * pt[1]) / ScreenToMouse._SCREEN_DIMENSIONS[1])
44 ScreenToMouse._SCREEN_DIMENSIONS = None
47 def PressButton(down, button='left'):
48 """Simulate a mouse button press or release at the current mouse location.
50 Args:
51 down: whether the button is pressed or released
52 button: which button is pressed
54 Returns:
55 None
56 """
58 # Put the mouse_event flags in a convenient dictionary by button
59 flags = {
60 'left': (win32con.MOUSEEVENTF_LEFTUP, win32con.MOUSEEVENTF_LEFTDOWN),
61 'middle': (win32con.MOUSEEVENTF_MIDDLEUP, win32con.MOUSEEVENTF_MIDDLEDOWN),
62 'right': (win32con.MOUSEEVENTF_RIGHTUP, win32con.MOUSEEVENTF_RIGHTDOWN)
65 # hit the button
66 win32api.mouse_event(flags[button][down], 0, 0)
69 def ClickButton(button='left', click_time=0):
70 """Press and release a mouse button at the current mouse location.
72 Args:
73 button: which button to click
74 click_time: duration between press and release
76 Returns:
77 None
78 """
79 PressButton(True, button)
80 time.sleep(click_time)
81 PressButton(False, button)
84 def DoubleClickButton(button='left', click_time=0, time_between_clicks=0):
85 """Double-click a mouse button at the current mouse location.
87 Args:
88 button: which button to click
89 click_time: duration between press and release
90 time_between_clicks: time to pause between clicks
92 Returns:
93 None
94 """
95 ClickButton(button, click_time)
96 time.sleep(time_between_clicks)
97 ClickButton(button, click_time)
100 def MoveToLocation(pos, duration=0, tick=0.01):
101 """Move the mouse cursor to a specified location, taking the specified time.
103 Args:
104 pos: position (in screen coordinates) to move to
105 duration: amount of time the move should take
106 tick: amount of time between successive moves of the mouse
108 Returns:
109 None
111 # calculate the number of moves to reach the destination
112 num_steps = (duration/tick)+1
114 # get the current and final mouse position in mouse coords
115 current_location = ScreenToMouse(win32gui.GetCursorPos())
116 end_location = ScreenToMouse(pos)
118 # Calculate the step size
119 step_size = ((end_location[0]-current_location[0])/num_steps,
120 (end_location[1]-current_location[1])/num_steps)
121 step = 0
123 while step < num_steps:
124 # Move the mouse one step
125 current_location = (current_location[0]+step_size[0],
126 current_location[1]+step_size[1])
128 # Coerce the coords to int to avoid a warning from pywin32
129 win32api.mouse_event(
130 win32con.MOUSEEVENTF_MOVE|win32con.MOUSEEVENTF_ABSOLUTE,
131 int(current_location[0]), int(current_location[1]))
133 step += 1
134 time.sleep(tick)
137 def ClickAtLocation(pos, button='left', click_time=0):
138 """Simulate a mouse click in a particular location, in screen coordinates.
140 Args:
141 pos: position in screen coordinates (x,y)
142 button: which button to click
143 click_time: duration of the click
145 Returns:
146 None
148 MoveToLocation(pos)
149 ClickButton(button, click_time)
152 def ClickInWindow(hwnd, offset=None, button='left', click_time=0):
153 """Simulate a user mouse click in the center of a window.
155 Args:
156 hwnd: handle of the window to click in
157 offset: where to click, defaults to dead center
158 button: which button to click
159 click_time: duration of the click
161 Returns:
162 Nothing
165 rect = win32gui.GetClientRect(hwnd)
166 if offset is None: offset = (rect[2]/2, rect[3]/2)
168 # get the screen coordinates of the window's center
169 pos = win32gui.ClientToScreen(hwnd, offset)
171 ClickAtLocation(pos, button, click_time)
174 def DoubleClickInWindow(
175 hwnd, offset=None, button='left', click_time=0, time_between_clicks=0.1):
176 """Simulate a user mouse double click in the center of a window.
178 Args:
179 hwnd: handle of the window to click in
180 offset: where to click, defaults to dead center
181 button: which button to click
182 click_time: duration of the clicks
183 time_between_clicks: length of time to pause between clicks
185 Returns:
186 Nothing
188 ClickInWindow(hwnd, offset, button, click_time)
189 time.sleep(time_between_clicks)
190 ClickInWindow(hwnd, offset, button, click_time)
193 def main():
194 # We're being invoked rather than imported. Let's do some tests
196 screen_size = win32gui.GetClientRect(win32gui.GetDesktopWindow())
197 screen_size = (screen_size[2], screen_size[3])
199 # move the mouse (instantly) to the upper right corner
200 MoveToLocation((screen_size[0], 0))
202 # move the mouse (over five seconds) to the lower left corner
203 MoveToLocation((0, screen_size[1]), 5)
205 # click the left mouse button. This will open up the Start menu
206 # if the taskbar is at the bottom
208 ClickButton()
210 # wait a bit, then click the right button to open the context menu
211 time.sleep(3)
212 ClickButton('right')
214 # move the mouse away and then click the left button to dismiss the
215 # context menu
216 MoveToLocation((screen_size[0]/2, screen_size[1]/2), 3)
217 MoveToLocation((0, 0), 3)
218 ClickButton()
221 if __name__ == "__main__":
222 sys.exit(main())