Template repo for tiny cross-platform apps that can be modified on phone, tablet or computer.
1local json = require 'json'
2
3require('test')
4
5OS = love.system.getOS()
6
7-- some global names accessible to Carousel
8require 'app'
9
10local I = {} -- for file-local helpers, so I can refer to them before defining them
11
12edit = require 'edit' -- available to app
13local keychord = require 'keychord'
14live = require 'live' -- available to app
15
16Current_time = 0
17Error_message = ''
18Error_count = 0
19
20local I = {}
21
22function love.load(arg, unfiltered_arg)
23 Arg, Unfiltered_arg = arg, unfiltered_arg
24 -- TODO: LÖVE version check should probably be outside edit
25 if not edit.is_this_love_version_supported() then
26 unsupported_version_screen_until_keypress()
27 end
28
29 run_tests()
30
31 love.keyboard.setKeyRepeat(true)
32
33 love.graphics.setBackgroundColor(1,1,1)
34 love.graphics.setFont(love.graphics.newFont(20))
35
36 OS = love.system.getOS()
37
38 live.load()
39
40 edit.load()
41
42 -- remember settings across restarts
43 local settings = I.load_settings()
44--? print(settings.x, settings.y)
45 local screen_width, screen_height = I.adjust_window(settings)
46
47 if on.initialize then on.initialize(arg, unfiltered_arg) end
48end
49
50function unsupported_version_screen_until_keypress()
51 local error_message = ("This app hasn't been tested with LÖVE version %s; please use version %s if you run into errors. Press a key to continue."):format(edit.love_version(), edit.preferred_love_version())
52 print(error_message)
53 while true do
54 love.graphics.origin()
55 love.graphics.clear(0,0,1)
56 love.graphics.setColor(1,1,1)
57 love.graphics.printf(error_message, 40,40, 400)
58 love.graphics.present()
59 if love.event then
60 love.event.pump()
61 for name, a,b,c,d,e,f in love.event.poll() do
62 if name == 'quit' then
63 if not love.quit or not love.quit() then
64 os.exit(1)
65 end
66 elseif name == 'keypressed' then
67 return
68 end
69 end
70 end
71 love.timer.sleep(0.01)
72 end
73end
74
75function I.adjust_window(settings)
76 -- adjust dimensions and make resizable
77 local screen_width, screen_height, flags = love.window.getMode()
78 if settings then
79 screen_width, screen_height = settings.width, settings.height
80 end
81 flags.resizable = true
82 local has_text_input = love.keyboard.hasTextInput()
83 I.set_window_mode(screen_width, screen_height, flags)
84 if OS == 'iOS' then
85 -- iOS recreates the window on setMode
86 -- readd some properties of the window
87 -- https://github.com/love2d/love/issues/1959
88 love.keyboard.setTextInput(has_text_input)
89 love.keyboard.setKeyRepeat(true)
90 end
91 -- adjust position
92 if settings then
93 if OS == 'Linux' then
94 -- HACK: love.window.setPosition doesn't quite seem to do what is asked of it on Linux.
95 -- This line is currently tuned just for Kartik's computer.
96 love.window.setPosition(settings.x-1, settings.y-35, settings.displayindex)
97 else
98 love.window.setPosition(settings.x, settings.y, settings.displayindex)
99 end
100 end
101 return screen_width, screen_height
102end
103
104function I.set_window_mode(w, h, flags)
105 -- Hack. On Linux with LÖVE 12, I've observed love.window.setMode go awry.
106 -- Guidance from LÖVE folks (https://github.com/love2d/love/issues/2214)
107 -- is that everything should be working with density-independent units
108 -- most of the time, but on some platforms love.window.setMode doesn't do
109 -- so. In that case, make sure to pass in values in raw pixel units to it.
110 local w1 = love.window.getMode()
111 local w2 = love.graphics.getDimensions()
112 if w1 ~= w2 then
113 w, h = love.window.toPixels(w, h)
114 end
115 love.window.setMode(w, h, flags)
116end
117
118function love.resize(w,h)
119 if on.resize then on.resize(w,h) end
120end
121
122function love.draw()
123 if on.draw then on.draw() end
124end
125
126function love.mousepressed(x,y, mouse_button, is_touch, presses)
127 if on.mouse_press then on.mouse_press(x,y, mouse_button, is_touch, presses) end
128end
129
130function love.mousemoved(x,y, dx,dy, is_touch)
131 if on.mouse_move then on.mouse_move(x,y, dx,dy, is_touch) end
132end
133
134function love.mousereleased(x,y, mouse_button, is_touch, presses)
135 if on.mouse_release then on.mouse_release(x,y, mouse_button, is_touch, presses) end
136end
137
138function love.mousemoved(x,y, dx,dy, is_touch)
139 if on.mouse_move then on.mouse_move(x,y, dx,dy, is_touch) end
140end
141
142function love.touchpressed(id, x,y, dx,dy, pressure)
143 if Mode == 'error' then return end
144 if on.touch_press then on.touch_press(id, x,y, dx,dy, pressure) end
145end
146
147function love.touchreleased(id, x,y, dx,dy, pressure)
148 if Mode == 'error' then return end
149 if on.touch_release then on.touch_release(id, x,y, dx,dy, pressure) end
150end
151
152function love.touchmoved(id, x,y, dx,dy, pressure)
153 if Mode == 'error' then return end
154 if on.touch_move then on.touch_move(id, x,y, dx,dy, pressure) end
155end
156
157function love.wheelmoved(dx,dy)
158 if on.mouse_wheel_move then on.mouse_wheel_move(dx,dy) end
159end
160
161function love.keypressed(key, scancode, is_repeat)
162 local chord = keychord.collect_keypress(key)
163 if chord == nil then return end
164 if OS == 'iOS' then
165 -- magic. iOS is prone to losing textinput events.
166 -- https://github.com/love2d/love/issues/1959
167 love.keyboard.setTextInput(true)
168 love.keyboard.setKeyRepeat(true)
169 end
170 if on.keychord_press then on.keychord_press(chord, key, scancode, is_repeat) end
171end
172
173function love.textinput(t)
174 if on.text_input then on.text_input(t) end
175end
176
177function love.keyreleased(key, scancode)
178 if on.key_release then on.key_release(key, scancode) end
179end
180
181function love.update(dt)
182 Current_time = Current_time + dt
183 live.update(dt)
184 edit.update_all(dt)
185 if on.update then on.update(dt) end
186end
187
188function love.quit()
189 if on.quit then on.quit() end
190 save_settings()
191end
192
193function restart()
194 if on.quit then on.quit() end
195 save_settings()
196 I.load_settings()
197 if on.initialize then on.initialize(Arg, Unfiltered_arg) end
198end
199
200function love.mousefocus(in_focus)
201 if on.mouse_focus then on.mouse_focus(in_focus) end
202end
203
204function love.focus(in_focus)
205 if in_focus then
206 love.graphics.setBackgroundColor(1,1,1)
207 else
208 love.graphics.setBackgroundColor(0.8,0.8,0.8)
209 end
210 if on.focus then on.focus(in_focus) end
211end
212
213function I.load_settings()
214 if not love.filesystem.getInfo('config') then return nil end
215 local contents = love.filesystem.read('config')
216 if #contents == 0 then return nil end
217 local settings = json.decode(contents)
218 if on.load_settings then on.load_settings(settings.app) end
219 return settings
220end
221
222function save_settings() -- available to app
223 local settings = {}
224 if on.save_settings then settings.app = on.save_settings() end
225 settings.x, settings.y, settings.displayindex = love.window.getPosition()
226 settings.width, settings.height = love.graphics.getDimensions()
227 love.filesystem.write('config', json.encode(settings))
228end