run.lua 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. run = {}
  2. Editor_state = {}
  3. -- called both in tests and real run
  4. function run.initialize_globals()
  5. -- tests currently mostly clear their own state
  6. -- blinking cursor
  7. Cursor_time = 0
  8. end
  9. -- called only for real run
  10. function run.initialize(arg)
  11. log_new('run')
  12. if Settings then
  13. run.load_settings()
  14. else
  15. run.initialize_default_settings()
  16. end
  17. if #arg > 0 and Editor_state.filename ~= absolutize(arg[1]) then
  18. Editor_state.filename = arg[1]
  19. load_from_disk(Editor_state)
  20. Text.redraw_all(Editor_state)
  21. Editor_state.screen_top1 = {line=1, pos=1}
  22. Editor_state.cursor1 = {line=1, pos=1}
  23. else
  24. load_from_disk(Editor_state)
  25. Text.redraw_all(Editor_state)
  26. end
  27. edit.check_locs(Editor_state)
  28. -- keep a few blank lines around: https://merveilles.town/@akkartik/110084833821965708
  29. love.window.setTitle('view.love - '..Editor_state.filename)
  30. if #arg > 1 then
  31. print('ignoring commandline args after '..arg[1])
  32. end
  33. if rawget(_G, 'jit') then
  34. jit.off()
  35. jit.flush()
  36. end
  37. end
  38. function print_and_log(s)
  39. print(s)
  40. log(3, s)
  41. end
  42. function run.load_settings()
  43. local font = love.graphics.newFont(Settings.font_height)
  44. -- set up desired window dimensions and make window resizable
  45. _, _, App.screen.flags = App.screen.size()
  46. App.screen.flags.resizable = true
  47. App.screen.width, App.screen.height = Settings.width, Settings.height
  48. App.screen.resize(App.screen.width, App.screen.height, App.screen.flags)
  49. run.set_window_position_from_settings(Settings)
  50. Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width-Margin_right, font, Settings.font_height, math.floor(Settings.font_height*1.3))
  51. Editor_state.filename = Settings.filename
  52. Editor_state.screen_top1 = Settings.screen_top
  53. Editor_state.cursor1 = Settings.cursor
  54. end
  55. function run.set_window_position_from_settings(settings)
  56. local os = love.system.getOS()
  57. if os == 'Linux' then
  58. -- love.window.setPosition doesn't quite seem to do what is asked of it on Linux.
  59. App.screen.move(settings.x, settings.y-37, settings.displayindex)
  60. else
  61. App.screen.move(settings.x, settings.y, settings.displayindex)
  62. end
  63. end
  64. function run.initialize_default_settings()
  65. local font_height = 20
  66. local font = love.graphics.newFont(font_height)
  67. run.initialize_window_geometry()
  68. Editor_state = edit.initialize_state(Margin_top, Margin_left, App.screen.width-Margin_right, font, font_height, math.floor(font_height*1.3))
  69. Settings = run.settings()
  70. end
  71. function run.initialize_window_geometry()
  72. -- Initialize window width/height and make window resizable.
  73. --
  74. -- I get tempted to have opinions about window dimensions here, but they're
  75. -- non-portable:
  76. -- - maximizing doesn't work on mobile and messes things up
  77. -- - maximizing keeps the title bar on screen in Linux, but off screen on
  78. -- Windows. And there's no way to get the height of the title bar.
  79. -- It seems more robust to just follow LÖVE's default window size until
  80. -- someone overrides it.
  81. App.screen.width, App.screen.height, App.screen.flags = App.screen.size()
  82. App.screen.flags.resizable = true
  83. App.screen.resize(App.screen.width, App.screen.height, App.screen.flags)
  84. end
  85. function run.resize(w, h)
  86. --? print(("Window resized to width: %d and height: %d."):format(w, h))
  87. App.screen.width, App.screen.height = w, h
  88. Text.redraw_all(Editor_state)
  89. Editor_state.selection1 = {} -- no support for shift drag while we're resizing
  90. Editor_state.right = App.screen.width-Margin_right
  91. Editor_state.width = Editor_state.right-Editor_state.left
  92. Text.tweak_screen_top_and_cursor(Editor_state, Editor_state.left, Editor_state.right)
  93. end
  94. function run.file_drop(file)
  95. -- first make sure to save edits on any existing file
  96. if Editor_state.next_save then
  97. save_to_disk(Editor_state)
  98. end
  99. -- clear the slate for the new file
  100. App.initialize_globals()
  101. Editor_state.filename = file:getFilename()
  102. file:open('r')
  103. Editor_state.lines = load_from_file(file)
  104. file:close()
  105. Text.redraw_all(Editor_state)
  106. Editor_state.screen_top1 = {line=1, pos=1}
  107. Editor_state.cursor1 = {line=1, pos=1}
  108. -- keep a few blank lines around: https://merveilles.town/@akkartik/110084833821965708
  109. love.window.setTitle('view.love - '..Editor_state.filename)
  110. end
  111. function run.draw()
  112. edit.draw(Editor_state)
  113. end
  114. function run.update(dt)
  115. Cursor_time = Cursor_time + dt
  116. edit.update(Editor_state, dt)
  117. end
  118. function run.quit()
  119. edit.quit(Editor_state)
  120. end
  121. function run.settings()
  122. if Settings == nil then Settings = {} end
  123. Settings.x, Settings.y, Settings.displayindex = App.screen.position()
  124. return {
  125. x=Settings.x, y=Settings.y, displayindex=Settings.displayindex,
  126. width=App.screen.width, height=App.screen.height,
  127. font_height=Editor_state.font_height,
  128. filename=absolutize(Editor_state.filename),
  129. screen_top=Editor_state.screen_top1, cursor=Editor_state.cursor1
  130. }
  131. end
  132. function absolutize(path)
  133. if is_relative_path(path) then
  134. return App.current_dir..path
  135. end
  136. return path
  137. end
  138. function run.mouse_press(x,y, mouse_button)
  139. Cursor_time = 0 -- ensure cursor is visible immediately after it moves
  140. love.keyboard.setTextInput(true) -- bring up keyboard on touch screen
  141. return edit.mouse_press(Editor_state, x,y, mouse_button)
  142. end
  143. function run.mouse_release(x,y, mouse_button)
  144. Cursor_time = 0 -- ensure cursor is visible immediately after it moves
  145. return edit.mouse_release(Editor_state, x,y, mouse_button)
  146. end
  147. function run.mouse_wheel_move(dx,dy)
  148. Cursor_time = 0 -- ensure cursor is visible immediately after it moves
  149. return edit.mouse_wheel_move(Editor_state, dx,dy)
  150. end
  151. function run.text_input(t)
  152. Cursor_time = 0 -- ensure cursor is visible immediately after it moves
  153. return edit.text_input(Editor_state, t)
  154. end
  155. function run.keychord_press(chord, key)
  156. Cursor_time = 0 -- ensure cursor is visible immediately after it moves
  157. return edit.keychord_press(Editor_state, chord, key)
  158. end
  159. function run.key_release(key, scancode)
  160. Cursor_time = 0 -- ensure cursor is visible immediately after it moves
  161. return edit.key_release(Editor_state, key, scancode)
  162. end
  163. function width(s)
  164. return love.graphics.getFont():getWidth(s)
  165. end