File: ui.lua

package info (click to toggle)
widelands 2%3A1.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 684,084 kB
  • sloc: cpp: 196,737; ansic: 19,395; python: 8,515; sh: 1,734; xml: 700; makefile: 46; lisp: 25
file content (271 lines) | stat: -rw-r--r-- 8,583 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
include "scripting/coroutine.lua"

-- RST
-- .. _ui.lua:
--
-- ui.lua
-- ---------------
--
-- This script contains UI related functions like for moving the mouse or the
-- view or clicking on fields and UI elements.
--
-- .. Note::
--    Do not use any of these functions for multiplayer scenarios or winconditions,
--    because a game will likely desync then.
--
-- To make these functions available include this file at the beginning
-- of a script via:
--
-- .. code-block:: lua
--
--    include "scripting/ui.lua"
--

-- Sleep until we are done animating.
function _await_animation(return_immediate)
   if return_immediate then return end
   local mv = wl.ui.MapView()
   while mv.is_animating do
      sleep(41)
   end
end

-- RST
-- .. function:: scroll_to_map_pixel(map_pixel[, return_immediate = false])
--
--    .. versionchanged:: 1.2.1
--       Added parameter ``return_immediate``.
--
--    Make a nice moving transition to center on the 'map_pixel', which is a table
--    that must contain 'x' and 'y' keys. The function will return as soon as
--    the transition is completed. Usually this function is useful when
--    scrolling back after using :meth:`scroll_to_field` or
--    :meth:`wait_for_roadbuilding_and_scroll`. The return value of these
--    functions can be passed to ``scroll_to_map_pixel`` to move back to the
--    previous location.
--
--    :arg map_pixel: pixels to focus on.
--    :type map_pixel: :class:`table`
--    :arg return_immediate: Whether to return from the function call immediately, even if the transition is still ongoing.
--    :type return_immediate: :class:`boolean`
--
--    Example:
--
--    .. code-block:: lua
--
--       include "scripting/ui.lua"
--       include "scripting/messages.lua"
--
--       local rocks_field = wl.Game().map:get_field(12, 34)
--
--       -- scroll to 'rocks_field'; 'prior_location' will be the position from where we are scrolling from
--       local prior_location = scroll_to_field(rocks_field)
--       campaign_message_box({title= "New observation",
--                             body = "We have found some rocks!",
--                             position = "top"})
--       -- after clicking 'OK' scroll back
--       scroll_to_map_pixel(prior_location)
--

function scroll_to_map_pixel(map_pixel, return_immediate)
   _await_animation(return_immediate)
   wl.ui.MapView():scroll_to_map_pixel(map_pixel.x, map_pixel.y)
   _await_animation(return_immediate)
end

-- RST
-- .. function:: scroll_to_field(field[, return_immediate = false])
--
--    .. versionchanged:: 1.2.1
--       Added parameter ``return_immediate``.
--
--    Make a nice moving transition to center the 'field' on screen. The
--    function will return as soon as the transition is completed.
--
--    :arg field: Field to center the view on
--    :type field: :class:`wl.map.Field`
--    :arg return_immediate: Whether to return from the function call immediately, even if the transition is still ongoing.
--    :type return_immediate: :class:`boolean`
--
--    :returns: the prior center map pixel of the MapView as a table containing
--       'x' and 'y' keys.
--
function scroll_to_field(field, return_immediate)
   _await_animation(return_immediate)
   local mv = wl.ui.MapView()
   local center_map_pixel = mv.center_map_pixel
   mv:scroll_to_field(field)
   _await_animation(return_immediate)
   return center_map_pixel
end

-- RST
-- .. function:: mouse_to_pixel(x, y[, return_immediate = false])
--
--    .. versionchanged:: 1.2.1
--       Added parameter ``return_immediate``.
--
--    Make a nice moving transition for the mouse to the given pixels relative
--    to the top left corner of the screen. The function will return as soon as
--    the transition is completed.
--
--    :arg x: x position to move the mouse to
--    :type x: :class:`integer`
--    :arg y: y position to move the mouse to
--    :type y: :class:`integer`
--    :arg return_immediate: Whether to return from the function call immediately, even if the transition is still ongoing.
--    :type return_immediate: :class:`boolean`
--
function mouse_to_pixel(x, y, return_immediate)
   _await_animation(return_immediate)
   wl.ui.MapView():mouse_to_pixel(math.floor(x), math.floor(y))
   _await_animation(return_immediate)
end

-- RST
-- .. function:: mouse_to_field(field[, return_immediate = false])
--
--    .. versionchanged:: 1.2.1
--       Added parameter ``return_immediate``.
--
--    Move the mouse on the given field. Makes sure that the field is inside
--    the current view area by scrolling the view if necessary. The function
--    will return as soon as the transition is completed.
--
--    :arg field: Field to mouse to
--    :type field: :class:`wl.map.Field`
--    :arg return_immediate: Whether to return from the function call immediately, even if the transition is still ongoing.
--    :type return_immediate: :class:`boolean`
--
function mouse_to_field(field, return_immediate)
   _await_animation(return_immediate)
   local mv = wl.ui.MapView()
   if not mv:is_visible(field) then
      scroll_to_field(field)
      mouse_to_field(field)
      return
   end

   mv:mouse_to_field(field)
   _await_animation(return_immediate)
end

-- RST
-- .. function:: mouse_to_panel(panel[, return_immediate = false])
--
--    .. versionchanged:: 1.2.1
--       Added parameter ``return_immediate``.
--
--    Move the mouse to the center of the given ui element. The function will
--    return as soon as the transition is completed.
--
--    :arg panel: Panel to mouse to
--    :type panel: :class:`wl.ui.Panel`
--    :arg return_immediate: Whether to return from the function call immediately, even if the transition is still ongoing.
--    :type return_immediate: :class:`boolean`
--
function mouse_to_panel(panel, return_immediate)
   _await_animation(return_immediate)
   local x, y = wl.ui.MapView():get_descendant_position(panel)
   mouse_to_pixel(x + panel.width / 2, y + panel.height / 2)
end

-- RST
-- .. function:: click_building(player, building_name)
--
--    Click on the first building of type 'building_name' owned by 'player'.
--
--    :arg player: Player to search building for.
--    :type player: :class:`wl.game.Player`
--    :arg building_name: Building name to look for.
--    :type building_name: :class:`string`
--
--    :returns: :const:`true` if a building was clicked
--
function click_building(player, building_name)
   local building = player:get_buildings(building_name)[1]
   mouse_to_field(building.fields[1])
   wl.ui.MapView():click(building.fields[1])
   return true
end

-- RST
-- .. function:: click_button(name)
--
--    Searches through all open windows for a button named 'name' and, if
--    found, clicks it.
--
--    This function is used only by the testsuite.
--
--    :arg name: Name of the button to click.
--    :type name: :class:`string`
--
--    :returns: :const:`true` if a button was clicked
--
function click_button(name)
   -- Most buttons are not meant to be clicked by any thread other than the main thread.
   -- If this button opens a window, its initialization may take several seconds.
   -- Since only the testsuite uses this functionality, we can wait.
   sleep(5000)

   for button_name, button in pairs(wl.ui.MapView().buttons) do
      if button_name == name then
         button:click()
         sleep(5000)
         return true
      end
   end

   for window_name, window in pairs(wl.ui.MapView().windows) do
      for button_name, button in pairs(window.buttons) do
         if button_name == name then
            button:click()
            sleep(5000)
            return true
         end
      end
   end
   return false
end

-- RST
-- .. function:: close_windows()
--
--    Closes all open windows.
--
function close_windows()
   for k,v in pairs(wl.ui.MapView().windows) do
      v:close()
   end
end


-- RST
-- .. function:: wait_for_roadbuilding()
--
--    Sleeps while player is in roadbuilding mode.
--
function wait_for_roadbuilding()
   if wl.Game().type == "singleplayer" then
      _await_animation()
      while (wl.ui.MapView().is_building_road) do sleep(2000) end
   end
end


-- RST
-- .. function:: wait_for_roadbuilding_and_scroll(field)
--
--    Sleeps while player is in roadbuilding mode, then calls
--    :meth:`scroll_to_field(field) <scroll_to_field>`.
--
--    :arg field: Field to scroll to
--    :type field: :class:`wl.map.Field`
--
--    :returns: The return value of `scroll_to_field`.

function wait_for_roadbuilding_and_scroll(field)
   _await_animation()
   wait_for_roadbuilding()
   return scroll_to_field(field)
end