11 -- delegate most business logic to a layer that can be reused by other projects
15 -- called both in tests and real run
16 function App
.initialize_globals()
17 -- tests currently mostly clear their own state
22 -- for hysteresis in a few places
23 Last_resize_time
= App
.getTime()
24 Last_focus_time
= App
.getTime() -- https://love2d.org/forums/viewtopic.php?p=249700
27 -- called only for real run
28 function App
.initialize(arg
)
29 love
.keyboard
.setTextInput(true) -- bring up keyboard on touch screen
30 love
.keyboard
.setKeyRepeat(true)
32 love
.graphics
.setBackgroundColor(1,1,1)
34 if love
.filesystem
.getInfo('config') then
37 initialize_default_settings()
41 Editor_state
.filename
= arg
[1]
42 load_from_disk(Editor_state
)
43 Text
.redraw_all(Editor_state
)
44 Editor_state
.screen_top1
= {line
=1, pos
=1}
45 Editor_state
.cursor1
= {line
=1, pos
=1}
46 edit
.fixup_cursor(Editor_state
)
48 load_from_disk(Editor_state
)
49 Text
.redraw_all(Editor_state
)
50 if Editor_state
.cursor1
.line
> #Editor_state
.lines
or Editor_state
.lines
[Editor_state
.cursor1
.line
].mode
~= 'text' then
51 edit
.fixup_cursor(Editor_state
)
54 love
.window
.setTitle('lines.love - '..Editor_state
.filename
)
57 print('ignoring commandline args after '..arg
[1])
60 if rawget(_G
, 'jit') then
66 function load_settings()
67 local settings
= json
.decode(love
.filesystem
.read('config'))
68 love
.graphics
.setFont(love
.graphics
.newFont(settings
.font_height
))
69 -- maximize window to determine maximum allowable dimensions
70 App
.screen
.width
, App
.screen
.height
, App
.screen
.flags
= love
.window
.getMode()
71 -- set up desired window dimensions
72 love
.window
.setPosition(settings
.x
, settings
.y
, settings
.displayindex
)
73 App
.screen
.flags
.resizable
= true
74 App
.screen
.flags
.minwidth
= math
.min(App
.screen
.width
, 200)
75 App
.screen
.flags
.minheight
= math
.min(App
.screen
.width
, 200)
76 App
.screen
.width
, App
.screen
.height
= settings
.width
, settings
.height
77 love
.window
.setMode(App
.screen
.width
, App
.screen
.height
, App
.screen
.flags
)
78 Editor_state
= edit
.initialize_state(Margin_top
, Margin_left
, App
.screen
.width
-Margin_right
, settings
.font_height
, math
.floor(settings
.font_height
*1.3))
79 Editor_state
.filename
= settings
.filename
80 Editor_state
.screen_top1
= settings
.screen_top
81 Editor_state
.cursor1
= settings
.cursor
84 function initialize_default_settings()
85 local font_height
= 20
86 love
.graphics
.setFont(love
.graphics
.newFont(font_height
))
87 local em
= App
.newText(love
.graphics
.getFont(), 'm')
88 initialize_window_geometry(App
.width(em
))
89 Editor_state
= edit
.initialize_state(Margin_top
, Margin_left
, App
.screen
.width
-Margin_right
)
90 Editor_state
.font_height
= font_height
91 Editor_state
.line_height
= math
.floor(font_height
*1.3)
95 function initialize_window_geometry(em_width
)
97 love
.window
.setMode(0, 0) -- maximize
98 App
.screen
.width
, App
.screen
.height
, App
.screen
.flags
= love
.window
.getMode()
99 -- shrink height slightly to account for window decoration
100 App
.screen
.height
= App
.screen
.height
-100
101 App
.screen
.width
= 40*em_width
102 App
.screen
.flags
.resizable
= true
103 App
.screen
.flags
.minwidth
= math
.min(App
.screen
.width
, 200)
104 App
.screen
.flags
.minheight
= math
.min(App
.screen
.width
, 200)
105 love
.window
.setMode(App
.screen
.width
, App
.screen
.height
, App
.screen
.flags
)
108 function App
.resize(w
, h
)
109 --? print(("Window resized to width: %d and height: %d."):format(w, h))
110 App
.screen
.width
, App
.screen
.height
= w
, h
111 Text
.redraw_all(Editor_state
)
112 Editor_state
.selection1
= {} -- no support for shift drag while we're resizing
113 Editor_state
.right
= App
.screen
.width
-Margin_right
114 Editor_state
.width
= Editor_state
.right
-Editor_state
.left
115 Text
.tweak_screen_top_and_cursor(Editor_state
, Editor_state
.left
, Editor_state
.right
)
116 Last_resize_time
= App
.getTime()
119 function App
.filedropped(file
)
120 -- first make sure to save edits on any existing file
121 if Editor_state
.next_save
then
122 save_to_disk(Editor_state
)
124 -- clear the slate for the new file
125 App
.initialize_globals() -- in particular, forget all undo history
126 Editor_state
.filename
= file
:getFilename()
128 Editor_state
.lines
= load_from_file(file
)
130 edit
.fixup_cursor(Editor_state
)
131 love
.window
.setTitle('lines.love - '..Editor_state
.filename
)
136 edit
.draw(Editor_state
)
139 function App
.update(dt
)
140 Cursor_time
= Cursor_time
+ dt
141 -- some hysteresis while resizing
142 if App
.getTime() < Last_resize_time
+ 0.1 then
145 edit
.update(Editor_state
, dt
)
149 edit
.quit(Editor_state
)
150 -- save some important settings
151 local x
,y
,displayindex
= love
.window
.getPosition()
152 local filename
= Editor_state
.filename
153 if filename
:sub(1,1) ~= '/' then
154 filename
= love
.filesystem
.getWorkingDirectory()..'/'..filename
-- '/' should work even on Windows
157 x
=x
, y
=y
, displayindex
=displayindex
,
158 width
=App
.screen
.width
, height
=App
.screen
.height
,
159 font_height
=Editor_state
.font_height
,
161 screen_top
=Editor_state
.screen_top1
, cursor
=Editor_state
.cursor1
}
162 love
.filesystem
.write('config', json
.encode(settings
))
165 function App
.mousepressed(x
,y
, mouse_button
)
166 Cursor_time
= 0 -- ensure cursor is visible immediately after it moves
167 return edit
.mouse_pressed(Editor_state
, x
,y
, mouse_button
)
170 function App
.mousereleased(x
,y
, mouse_button
)
171 Cursor_time
= 0 -- ensure cursor is visible immediately after it moves
172 return edit
.mouse_released(Editor_state
, x
,y
, mouse_button
)
175 function App
.focus(in_focus
)
177 Last_focus_time
= App
.getTime()
181 function App
.textinput(t
)
182 -- ignore events for some time after window in focus
183 if App
.getTime() < Last_focus_time
+ 0.01 then
186 Cursor_time
= 0 -- ensure cursor is visible immediately after it moves
187 return edit
.textinput(Editor_state
, t
)
190 function App
.keychord_pressed(chord
, key
)
191 -- ignore events for some time after window in focus
192 if App
.getTime() < Last_focus_time
+ 0.01 then
195 Cursor_time
= 0 -- ensure cursor is visible immediately after it moves
196 return edit
.keychord_pressed(Editor_state
, chord
, key
)
199 function App
.keyreleased(key
, scancode
)
200 -- ignore events for some time after window in focus
201 if App
.getTime() < Last_focus_time
+ 0.01 then
204 Cursor_time
= 0 -- ensure cursor is visible immediately after it moves
205 return edit
.key_released(Editor_state
, key
, scancode
)