autogui 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +20 -0
- data/LICENSE +29 -0
- data/README.md +431 -0
- data/bin/autogui +19 -0
- data/docs/api.md +186 -0
- data/docs/guide.md +243 -0
- data/docs/publishing.md +90 -0
- data/examples/hello.rb +20 -0
- data/examples/locate_demo.rb +16 -0
- data/lib/autogui/exceptions.rb +9 -0
- data/lib/autogui/geometry.rb +98 -0
- data/lib/autogui/image.rb +344 -0
- data/lib/autogui/keys.rb +50 -0
- data/lib/autogui/message_box.rb +125 -0
- data/lib/autogui/platform/darwin.rb +185 -0
- data/lib/autogui/platform/linux.rb +172 -0
- data/lib/autogui/platform/windows.rb +400 -0
- data/lib/autogui/platform.rb +41 -0
- data/lib/autogui/run.rb +168 -0
- data/lib/autogui/screenshot.rb +95 -0
- data/lib/autogui/tween.rb +254 -0
- data/lib/autogui/version.rb +5 -0
- data/lib/autogui/window.rb +170 -0
- data/lib/autogui.rb +738 -0
- metadata +90 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AutoGUI
|
|
4
|
+
module Tween
|
|
5
|
+
module_function
|
|
6
|
+
|
|
7
|
+
def check(n)
|
|
8
|
+
n = n.to_f
|
|
9
|
+
unless n.between?(0.0, 1.0)
|
|
10
|
+
raise AutoGUIException, "Argument must be between 0.0 and 1.0."
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
n
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def linear(n)
|
|
17
|
+
check(n)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def easeInQuad(n)
|
|
21
|
+
n = check(n)
|
|
22
|
+
n * n
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def easeOutQuad(n)
|
|
26
|
+
n = check(n)
|
|
27
|
+
-n * (n - 2)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def easeInOutQuad(n)
|
|
31
|
+
n = check(n)
|
|
32
|
+
if n < 0.5
|
|
33
|
+
2 * n * n
|
|
34
|
+
else
|
|
35
|
+
n = n * 2 - 1
|
|
36
|
+
-0.5 * (n * (n - 2) - 1)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def easeInCubic(n)
|
|
41
|
+
n = check(n)
|
|
42
|
+
n**3
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def easeOutCubic(n)
|
|
46
|
+
n = check(n)
|
|
47
|
+
n -= 1
|
|
48
|
+
n**3 + 1
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def easeInOutCubic(n)
|
|
52
|
+
n = check(n)
|
|
53
|
+
n *= 2
|
|
54
|
+
if n < 1
|
|
55
|
+
0.5 * n**3
|
|
56
|
+
else
|
|
57
|
+
n -= 2
|
|
58
|
+
0.5 * (n**3 + 2)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def easeInQuart(n)
|
|
63
|
+
n = check(n)
|
|
64
|
+
n**4
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def easeOutQuart(n)
|
|
68
|
+
n = check(n)
|
|
69
|
+
n -= 1
|
|
70
|
+
-(n**4 - 1)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def easeInOutQuart(n)
|
|
74
|
+
n = check(n)
|
|
75
|
+
n *= 2
|
|
76
|
+
if n < 1
|
|
77
|
+
0.5 * n**4
|
|
78
|
+
else
|
|
79
|
+
n -= 2
|
|
80
|
+
-0.5 * (n**4 - 2)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def easeInQuint(n)
|
|
85
|
+
n = check(n)
|
|
86
|
+
n**5
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def easeOutQuint(n)
|
|
90
|
+
n = check(n)
|
|
91
|
+
n -= 1
|
|
92
|
+
n**5 + 1
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def easeInOutQuint(n)
|
|
96
|
+
n = check(n)
|
|
97
|
+
n *= 2
|
|
98
|
+
if n < 1
|
|
99
|
+
0.5 * n**5
|
|
100
|
+
else
|
|
101
|
+
n -= 2
|
|
102
|
+
0.5 * (n**5 + 2)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def easeInSine(n)
|
|
107
|
+
n = check(n)
|
|
108
|
+
-Math.cos(n * Math::PI / 2) + 1
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def easeOutSine(n)
|
|
112
|
+
n = check(n)
|
|
113
|
+
Math.sin(n * Math::PI / 2)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def easeInOutSine(n)
|
|
117
|
+
n = check(n)
|
|
118
|
+
-0.5 * (Math.cos(Math::PI * n) - 1)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def easeInExpo(n)
|
|
122
|
+
n = check(n)
|
|
123
|
+
n == 0 ? 0 : 2**(10 * (n - 1))
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def easeOutExpo(n)
|
|
127
|
+
n = check(n)
|
|
128
|
+
n == 1 ? 1 : -(2**(-10 * n)) + 1
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def easeInOutExpo(n)
|
|
132
|
+
n = check(n)
|
|
133
|
+
return 0 if n.zero?
|
|
134
|
+
return 1 if n == 1
|
|
135
|
+
|
|
136
|
+
n *= 2
|
|
137
|
+
if n < 1
|
|
138
|
+
0.5 * (2**(10 * (n - 1)))
|
|
139
|
+
else
|
|
140
|
+
0.5 * (-(2**(-10 * (n - 1))) + 2)
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def easeInCirc(n)
|
|
145
|
+
n = check(n)
|
|
146
|
+
-(Math.sqrt(1 - n * n) - 1)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def easeOutCirc(n)
|
|
150
|
+
n = check(n)
|
|
151
|
+
n -= 1
|
|
152
|
+
Math.sqrt(1 - n * n)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def easeInOutCirc(n)
|
|
156
|
+
n = check(n)
|
|
157
|
+
n *= 2
|
|
158
|
+
if n < 1
|
|
159
|
+
-0.5 * (Math.sqrt(1 - n * n) - 1)
|
|
160
|
+
else
|
|
161
|
+
n -= 2
|
|
162
|
+
0.5 * (Math.sqrt(1 - n * n) + 1)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def easeInElastic(n, amplitude = 1, period = 0.3)
|
|
167
|
+
n = check(n)
|
|
168
|
+
return 0 if n.zero?
|
|
169
|
+
return 1 if n == 1
|
|
170
|
+
|
|
171
|
+
s = period / (2 * Math::PI) * Math.asin(1.0 / amplitude)
|
|
172
|
+
n -= 1
|
|
173
|
+
-(amplitude * (2**(10 * n)) * Math.sin((n - s) * (2 * Math::PI) / period))
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def easeOutElastic(n, amplitude = 1, period = 0.3)
|
|
177
|
+
n = check(n)
|
|
178
|
+
return 0 if n.zero?
|
|
179
|
+
return 1 if n == 1
|
|
180
|
+
|
|
181
|
+
s = period / (2 * Math::PI) * Math.asin(1.0 / amplitude)
|
|
182
|
+
amplitude * (2**(-10 * n)) * Math.sin((n - s) * (2 * Math::PI) / period) + 1
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def easeInOutElastic(n, amplitude = 1, period = 0.45)
|
|
186
|
+
n = check(n)
|
|
187
|
+
return 0 if n.zero?
|
|
188
|
+
return 1 if n == 1
|
|
189
|
+
|
|
190
|
+
s = period / (2 * Math::PI) * Math.asin(1.0 / amplitude)
|
|
191
|
+
n *= 2
|
|
192
|
+
if n < 1
|
|
193
|
+
n -= 1
|
|
194
|
+
-0.5 * (amplitude * (2**(10 * n)) * Math.sin((n - s) * (2 * Math::PI) / period))
|
|
195
|
+
else
|
|
196
|
+
n -= 1
|
|
197
|
+
amplitude * (2**(-10 * n)) * Math.sin((n - s) * (2 * Math::PI) / period) * 0.5 + 1
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def easeInBack(n, s = 1.70158)
|
|
202
|
+
n = check(n)
|
|
203
|
+
n * n * ((s + 1) * n - s)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def easeOutBack(n, s = 1.70158)
|
|
207
|
+
n = check(n)
|
|
208
|
+
n -= 1
|
|
209
|
+
n * n * ((s + 1) * n + s) + 1
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def easeInOutBack(n, s = 1.70158)
|
|
213
|
+
n = check(n)
|
|
214
|
+
s *= 1.525
|
|
215
|
+
n *= 2
|
|
216
|
+
if n < 1
|
|
217
|
+
0.5 * (n * n * ((s + 1) * n - s))
|
|
218
|
+
else
|
|
219
|
+
n -= 2
|
|
220
|
+
0.5 * (n * n * ((s + 1) * n + s) + 2)
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def easeInBounce(n)
|
|
225
|
+
n = check(n)
|
|
226
|
+
1 - easeOutBounce(1 - n)
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def easeOutBounce(n)
|
|
230
|
+
n = check(n)
|
|
231
|
+
if n < 1 / 2.75
|
|
232
|
+
7.5625 * n * n
|
|
233
|
+
elsif n < 2 / 2.75
|
|
234
|
+
n -= 1.5 / 2.75
|
|
235
|
+
7.5625 * n * n + 0.75
|
|
236
|
+
elsif n < 2.5 / 2.75
|
|
237
|
+
n -= 2.25 / 2.75
|
|
238
|
+
7.5625 * n * n + 0.9375
|
|
239
|
+
else
|
|
240
|
+
n -= 2.625 / 2.75
|
|
241
|
+
7.5625 * n * n + 0.984375
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def easeInOutBounce(n)
|
|
246
|
+
n = check(n)
|
|
247
|
+
if n < 0.5
|
|
248
|
+
easeInBounce(n * 2) * 0.5
|
|
249
|
+
else
|
|
250
|
+
easeOutBounce(n * 2 - 1) * 0.5 + 0.5
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
end
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AutoGUI
|
|
4
|
+
class Window
|
|
5
|
+
SW_HIDE = 0
|
|
6
|
+
SW_SHOWNORMAL = 1
|
|
7
|
+
SW_SHOWMINIMIZED = 2
|
|
8
|
+
SW_SHOWMAXIMIZED = 3
|
|
9
|
+
SW_RESTORE = 9
|
|
10
|
+
|
|
11
|
+
attr_reader :hwnd
|
|
12
|
+
|
|
13
|
+
def initialize(hwnd)
|
|
14
|
+
@hwnd = hwnd
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def title
|
|
18
|
+
Platform.current.window_title(@hwnd)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def box
|
|
22
|
+
left, top, width, height = Platform.current.window_rect(@hwnd)
|
|
23
|
+
Box.new(left, top, width, height)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def left
|
|
27
|
+
box.left
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def top
|
|
31
|
+
box.top
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def width
|
|
35
|
+
box.width
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def height
|
|
39
|
+
box.height
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def right
|
|
43
|
+
left + width
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def bottom
|
|
47
|
+
top + height
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def visible?
|
|
51
|
+
Platform.current.window_visible?(@hwnd)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def minimized?
|
|
55
|
+
Platform.current.window_minimized?(@hwnd)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def maximized?
|
|
59
|
+
Platform.current.window_maximized?(@hwnd)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def activate
|
|
63
|
+
Platform.current.activate_window(@hwnd)
|
|
64
|
+
self
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def minimize
|
|
68
|
+
Platform.current.show_window(@hwnd, SW_SHOWMINIMIZED)
|
|
69
|
+
self
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def maximize
|
|
73
|
+
Platform.current.show_window(@hwnd, SW_SHOWMAXIMIZED)
|
|
74
|
+
self
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def restore
|
|
78
|
+
Platform.current.show_window(@hwnd, SW_RESTORE)
|
|
79
|
+
self
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def hide
|
|
83
|
+
Platform.current.show_window(@hwnd, SW_HIDE)
|
|
84
|
+
self
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def close
|
|
88
|
+
Platform.current.close_window(@hwnd)
|
|
89
|
+
self
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def moveTo(x, y)
|
|
93
|
+
Platform.current.move_window(@hwnd, x.to_i, y.to_i, width, height)
|
|
94
|
+
self
|
|
95
|
+
end
|
|
96
|
+
alias move_to moveTo
|
|
97
|
+
|
|
98
|
+
def resizeTo(w, h)
|
|
99
|
+
Platform.current.move_window(@hwnd, left, top, w.to_i, h.to_i)
|
|
100
|
+
self
|
|
101
|
+
end
|
|
102
|
+
alias resize_to resizeTo
|
|
103
|
+
|
|
104
|
+
def to_s
|
|
105
|
+
"Window(title=#{title.inspect}, box=#{box})"
|
|
106
|
+
end
|
|
107
|
+
alias inspect to_s
|
|
108
|
+
|
|
109
|
+
def ==(other)
|
|
110
|
+
other.is_a?(Window) && other.hwnd.to_i == @hwnd.to_i
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
module WindowFunctions
|
|
115
|
+
module_function
|
|
116
|
+
|
|
117
|
+
def getAllWindows
|
|
118
|
+
windows = []
|
|
119
|
+
return windows unless Platform.current.respond_to?(:each_hwnd)
|
|
120
|
+
|
|
121
|
+
Platform.current.each_hwnd do |hwnd|
|
|
122
|
+
next unless Platform.current.window_visible?(hwnd)
|
|
123
|
+
|
|
124
|
+
title = Platform.current.window_title(hwnd)
|
|
125
|
+
next if title.nil? || title.empty?
|
|
126
|
+
|
|
127
|
+
windows << Window.new(hwnd)
|
|
128
|
+
end
|
|
129
|
+
windows
|
|
130
|
+
end
|
|
131
|
+
alias get_all_windows getAllWindows
|
|
132
|
+
|
|
133
|
+
def getAllTitles
|
|
134
|
+
getAllWindows.map(&:title)
|
|
135
|
+
end
|
|
136
|
+
alias get_all_titles getAllTitles
|
|
137
|
+
|
|
138
|
+
def getWindowsWithTitle(title)
|
|
139
|
+
re = title.is_a?(Regexp) ? title : /#{Regexp.escape(title.to_s)}/i
|
|
140
|
+
getAllWindows.select { |w| w.title.match?(re) }
|
|
141
|
+
end
|
|
142
|
+
alias get_windows_with_title getWindowsWithTitle
|
|
143
|
+
|
|
144
|
+
def getWindowsAt(x, y)
|
|
145
|
+
getAllWindows.select do |w|
|
|
146
|
+
b = w.box
|
|
147
|
+
x >= b.left && x < b.left + b.width && y >= b.top && y < b.top + b.height
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
alias get_windows_at getWindowsAt
|
|
151
|
+
|
|
152
|
+
def getActiveWindow
|
|
153
|
+
return nil unless Platform.current.respond_to?(:GetForegroundWindow)
|
|
154
|
+
|
|
155
|
+
hwnd = Platform.current.GetForegroundWindow()
|
|
156
|
+
return nil unless Platform.current.valid_window?(hwnd)
|
|
157
|
+
|
|
158
|
+
Window.new(hwnd)
|
|
159
|
+
rescue StandardError
|
|
160
|
+
nil
|
|
161
|
+
end
|
|
162
|
+
alias get_active_window getActiveWindow
|
|
163
|
+
|
|
164
|
+
def getActiveWindowTitle
|
|
165
|
+
w = getActiveWindow
|
|
166
|
+
w&.title
|
|
167
|
+
end
|
|
168
|
+
alias get_active_window_title getActiveWindowTitle
|
|
169
|
+
end
|
|
170
|
+
end
|