2022-09-03 22:13:22 +01:00
|
|
|
Menu_background_color = {r=0.6, g=0.8, b=0.6}
|
|
|
|
Menu_border_color = {r=0.6, g=0.7, b=0.6}
|
|
|
|
Menu_command_color = {r=0.2, g=0.2, b=0.2}
|
|
|
|
Menu_highlight_color = {r=0.5, g=0.7, b=0.3}
|
|
|
|
|
|
|
|
function source.draw_menu_bar()
|
|
|
|
if App.run_tests then return end -- disable in tests
|
|
|
|
App.color(Menu_background_color)
|
|
|
|
love.graphics.rectangle('fill', 0,0, App.screen.width, Menu_status_bar_height)
|
|
|
|
App.color(Menu_border_color)
|
|
|
|
love.graphics.rectangle('line', 0,0, App.screen.width, Menu_status_bar_height)
|
|
|
|
App.color(Menu_command_color)
|
|
|
|
Menu_cursor = 5
|
|
|
|
if Show_file_navigator then
|
|
|
|
source.draw_file_navigator()
|
|
|
|
return
|
|
|
|
end
|
|
|
|
add_hotkey_to_menu('ctrl+e: run')
|
|
|
|
if Focus == 'edit' then
|
|
|
|
add_hotkey_to_menu('ctrl+g: switch file')
|
|
|
|
if Show_log_browser_side then
|
|
|
|
add_hotkey_to_menu('ctrl+l: hide log browser')
|
|
|
|
else
|
|
|
|
add_hotkey_to_menu('ctrl+l: show log browser')
|
|
|
|
end
|
2022-12-05 23:26:38 +00:00
|
|
|
add_hotkey_to_menu('ctrl+k: clear logs')
|
2022-09-03 22:13:22 +01:00
|
|
|
if Editor_state.expanded then
|
2022-09-07 02:39:46 +01:00
|
|
|
add_hotkey_to_menu('alt+b: collapse debug prints')
|
2022-09-03 22:13:22 +01:00
|
|
|
else
|
2022-09-07 02:39:46 +01:00
|
|
|
add_hotkey_to_menu('alt+b: expand debug prints')
|
2022-09-03 22:13:22 +01:00
|
|
|
end
|
2022-09-07 02:39:46 +01:00
|
|
|
add_hotkey_to_menu('alt+d: create/edit debug print')
|
2022-09-03 22:13:22 +01:00
|
|
|
add_hotkey_to_menu('ctrl+f: find in file')
|
|
|
|
add_hotkey_to_menu('alt+left alt+right: prev/next word')
|
|
|
|
elseif Focus == 'log_browser' then
|
|
|
|
-- nothing yet
|
|
|
|
else
|
|
|
|
assert(false, 'unknown focus "'..Focus..'"')
|
|
|
|
end
|
|
|
|
add_hotkey_to_menu('ctrl+z ctrl+y: undo/redo')
|
|
|
|
add_hotkey_to_menu('ctrl+x ctrl+c ctrl+v: cut/copy/paste')
|
|
|
|
add_hotkey_to_menu('ctrl+= ctrl+- ctrl+0: zoom')
|
|
|
|
end
|
|
|
|
|
|
|
|
function add_hotkey_to_menu(s)
|
2023-04-01 22:48:59 +01:00
|
|
|
local width = App.width(s)
|
2022-11-06 17:17:02 +00:00
|
|
|
if Menu_cursor > App.screen.width - 30 then
|
2022-09-03 22:13:22 +01:00
|
|
|
return
|
|
|
|
end
|
|
|
|
App.color(Menu_command_color)
|
2023-04-01 22:48:59 +01:00
|
|
|
App.screen.print(s, Menu_cursor,5)
|
2022-09-03 22:13:22 +01:00
|
|
|
Menu_cursor = Menu_cursor + width + 30
|
|
|
|
end
|
|
|
|
|
|
|
|
function source.draw_file_navigator()
|
2022-09-18 09:53:36 +01:00
|
|
|
App.color(Menu_command_color)
|
2023-04-01 22:48:59 +01:00
|
|
|
App.screen.print(File_navigation.filter, 5, 5)
|
|
|
|
draw_cursor(5 + App.width(File_navigation.filter), 5)
|
2022-09-18 07:53:57 +01:00
|
|
|
if File_navigation.num_lines == nil then
|
2022-09-18 09:11:23 +01:00
|
|
|
File_navigation.num_lines = source.num_lines_for_file_navigator(File_navigation.candidates)
|
2022-09-18 07:53:57 +01:00
|
|
|
end
|
|
|
|
App.color(Menu_background_color)
|
2022-09-18 09:11:23 +01:00
|
|
|
love.graphics.rectangle('fill', 0,Menu_status_bar_height, App.screen.width, File_navigation.num_lines * Editor_state.line_height + --[[highlight padding]] 2)
|
2022-09-18 07:53:57 +01:00
|
|
|
local x,y = 5, Menu_status_bar_height
|
2022-09-18 07:43:14 +01:00
|
|
|
for i,filename in ipairs(File_navigation.candidates) do
|
2022-09-18 07:53:57 +01:00
|
|
|
x,y = add_file_to_menu(x,y, filename, i == File_navigation.index)
|
2022-09-18 07:05:08 +01:00
|
|
|
if Menu_cursor >= App.screen.width - 5 then
|
|
|
|
break
|
|
|
|
end
|
2022-09-03 22:13:22 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-09-18 09:53:36 +01:00
|
|
|
function draw_cursor(x, y)
|
|
|
|
-- blink every 0.5s
|
|
|
|
if math.floor(Cursor_time*2)%2 == 0 then
|
|
|
|
App.color(Cursor_color)
|
|
|
|
love.graphics.rectangle('fill', x,y, 3,Editor_state.line_height)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function source.file_navigator_candidates()
|
|
|
|
if File_navigation.filter == '' then
|
|
|
|
return File_navigation.all_candidates
|
|
|
|
end
|
|
|
|
local result = {}
|
|
|
|
for _,filename in ipairs(File_navigation.all_candidates) do
|
|
|
|
if starts_with(filename, File_navigation.filter) then
|
|
|
|
table.insert(result, filename)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return result
|
|
|
|
end
|
|
|
|
|
2022-09-18 09:11:23 +01:00
|
|
|
function source.num_lines_for_file_navigator(candidates)
|
2022-09-18 07:53:57 +01:00
|
|
|
local result = 1
|
|
|
|
local x = 5
|
2022-09-18 09:11:23 +01:00
|
|
|
for i,filename in ipairs(candidates) do
|
2023-04-01 22:48:59 +01:00
|
|
|
local width = App.width(filename)
|
2022-09-18 08:01:14 +01:00
|
|
|
if x + width > App.screen.width - 5 then
|
|
|
|
result = result+1
|
|
|
|
x = 5 + width
|
|
|
|
else
|
|
|
|
x = x + width + 30
|
|
|
|
end
|
2022-09-18 07:53:57 +01:00
|
|
|
end
|
|
|
|
return result
|
|
|
|
end
|
|
|
|
|
|
|
|
function add_file_to_menu(x,y, s, cursor_highlight)
|
2023-04-01 22:48:59 +01:00
|
|
|
local width = App.width(s)
|
2022-09-18 07:53:57 +01:00
|
|
|
if x + width > App.screen.width - 5 then
|
|
|
|
y = y + Editor_state.line_height
|
|
|
|
x = 5
|
|
|
|
end
|
2022-09-18 09:26:20 +01:00
|
|
|
local color = Menu_background_color
|
2022-09-03 22:13:22 +01:00
|
|
|
if cursor_highlight then
|
2022-09-18 09:26:20 +01:00
|
|
|
color = Menu_highlight_color
|
2022-09-03 22:13:22 +01:00
|
|
|
end
|
2023-10-17 06:53:26 +01:00
|
|
|
button(Editor_state, 'menu', {x=x-5, y=y-2, w=width+5*2, h=Editor_state.line_height+2*2, bg=color,
|
2022-09-18 09:26:20 +01:00
|
|
|
onpress1 = function()
|
2022-09-19 08:35:10 +01:00
|
|
|
navigate_to_file(s)
|
2022-09-18 09:26:20 +01:00
|
|
|
end
|
|
|
|
})
|
2022-09-03 22:13:22 +01:00
|
|
|
App.color(Menu_command_color)
|
2023-04-01 22:48:59 +01:00
|
|
|
App.screen.print(s, x,y)
|
2022-09-18 07:53:57 +01:00
|
|
|
x = x + width + 30
|
|
|
|
return x,y
|
2022-09-03 22:13:22 +01:00
|
|
|
end
|
|
|
|
|
2022-09-19 08:35:10 +01:00
|
|
|
function navigate_to_file(s)
|
2022-09-19 08:37:08 +01:00
|
|
|
move_candidate_to_front(s)
|
2023-09-15 21:33:26 +01:00
|
|
|
source.switch_to_file(s..'.lua')
|
2023-09-15 21:36:27 +01:00
|
|
|
love.window.setTitle('lines.love - source - '..Editor_state.filename)
|
2022-09-19 08:35:10 +01:00
|
|
|
reset_file_navigator()
|
|
|
|
end
|
|
|
|
|
2022-09-19 08:37:08 +01:00
|
|
|
function move_candidate_to_front(s)
|
|
|
|
local index = array.find(File_navigation.all_candidates, s)
|
|
|
|
assert(index)
|
|
|
|
table.remove(File_navigation.all_candidates, index)
|
|
|
|
table.insert(File_navigation.all_candidates, 1, s)
|
|
|
|
end
|
|
|
|
|
2022-09-19 08:35:10 +01:00
|
|
|
function reset_file_navigator()
|
|
|
|
Show_file_navigator = false
|
|
|
|
File_navigation.index = 1
|
|
|
|
File_navigation.filter = ''
|
|
|
|
File_navigation.candidates = File_navigation.all_candidates
|
|
|
|
end
|
|
|
|
|
2022-12-24 01:16:19 +00:00
|
|
|
function keychord_press_on_file_navigator(chord, key)
|
2022-09-18 08:37:20 +01:00
|
|
|
log(2, 'file navigator: '..chord)
|
2022-09-18 09:11:23 +01:00
|
|
|
log(2, {name='file_navigator_state', files=File_navigation.candidates, index=File_navigation.index})
|
2022-09-03 22:13:22 +01:00
|
|
|
if chord == 'escape' then
|
2022-09-19 08:35:10 +01:00
|
|
|
reset_file_navigator()
|
2022-09-03 22:13:22 +01:00
|
|
|
elseif chord == 'return' then
|
2022-09-19 08:35:10 +01:00
|
|
|
navigate_to_file(File_navigation.candidates[File_navigation.index])
|
2022-09-18 09:53:36 +01:00
|
|
|
elseif chord == 'backspace' then
|
|
|
|
local len = utf8.len(File_navigation.filter)
|
|
|
|
local byte_offset = Text.offset(File_navigation.filter, len)
|
|
|
|
File_navigation.filter = string.sub(File_navigation.filter, 1, byte_offset-1)
|
|
|
|
File_navigation.index = 1
|
|
|
|
File_navigation.candidates = source.file_navigator_candidates()
|
2022-09-03 22:13:22 +01:00
|
|
|
elseif chord == 'left' then
|
|
|
|
if File_navigation.index > 1 then
|
|
|
|
File_navigation.index = File_navigation.index-1
|
|
|
|
end
|
|
|
|
elseif chord == 'right' then
|
|
|
|
if File_navigation.index < #File_navigation.candidates then
|
|
|
|
File_navigation.index = File_navigation.index+1
|
|
|
|
end
|
2022-09-18 08:37:20 +01:00
|
|
|
elseif chord == 'down' then
|
|
|
|
file_navigator_down()
|
|
|
|
elseif chord == 'up' then
|
|
|
|
file_navigator_up()
|
2022-09-03 22:13:22 +01:00
|
|
|
end
|
|
|
|
end
|
2022-09-18 08:37:20 +01:00
|
|
|
|
2022-09-18 09:11:23 +01:00
|
|
|
function log_render.file_navigator_state(o, x,y, w)
|
|
|
|
-- duplicate structure of source.draw_file_navigator
|
|
|
|
local num_lines = source.num_lines_for_file_navigator(o.files)
|
|
|
|
local h = num_lines * Editor_state.line_height
|
|
|
|
App.color(Menu_background_color)
|
|
|
|
love.graphics.rectangle('fill', x,y, w,h)
|
|
|
|
-- compute the x,y,width of the current index (in offsets from top left)
|
|
|
|
local x2,y2 = 0,0
|
|
|
|
local width = 0
|
|
|
|
for i,filename in ipairs(o.files) do
|
2023-04-01 22:48:59 +01:00
|
|
|
width = App.width(filename)
|
2022-09-18 09:11:23 +01:00
|
|
|
if x2 + width > App.screen.width - 5 then
|
|
|
|
y2 = y2 + Editor_state.line_height
|
|
|
|
x2 = 0
|
|
|
|
end
|
|
|
|
if i == o.index then
|
|
|
|
break
|
|
|
|
end
|
|
|
|
x2 = x2 + width + 30
|
|
|
|
end
|
|
|
|
-- figure out how much of the menu to display
|
|
|
|
local menu_xmin = math.max(0, x2-w/2)
|
|
|
|
local menu_xmax = math.min(App.screen.width, x2+w/2)
|
|
|
|
-- now selectively print out entries
|
|
|
|
local x3,y3 = 0,y -- x3 is relative, y3 is absolute
|
|
|
|
local width = 0
|
|
|
|
for i,filename in ipairs(o.files) do
|
2023-04-01 22:48:59 +01:00
|
|
|
width = App.width(filename)
|
2022-09-18 09:11:23 +01:00
|
|
|
if x3 + width > App.screen.width - 5 then
|
|
|
|
y3 = y3 + Editor_state.line_height
|
|
|
|
x3 = 0
|
|
|
|
end
|
|
|
|
if i == o.index then
|
|
|
|
App.color(Menu_highlight_color)
|
|
|
|
love.graphics.rectangle('fill', x + x3-menu_xmin - 5, y3-2, width+5*2, Editor_state.line_height+2*2)
|
|
|
|
end
|
|
|
|
if x3 >= menu_xmin and x3 + width < menu_xmax then
|
|
|
|
App.color(Menu_command_color)
|
2023-04-01 22:48:59 +01:00
|
|
|
App.screen.print(filename, x + x3-menu_xmin, y3)
|
2022-09-18 09:11:23 +01:00
|
|
|
end
|
|
|
|
x3 = x3 + width + 30
|
|
|
|
end
|
|
|
|
--
|
|
|
|
return h+20
|
|
|
|
end
|
|
|
|
|
2022-09-18 08:37:20 +01:00
|
|
|
function file_navigator_up()
|
|
|
|
local y, x, width = file_coord(File_navigation.index)
|
|
|
|
local index = file_index(y-Editor_state.line_height, x, width)
|
|
|
|
if index then
|
|
|
|
File_navigation.index = index
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function file_navigator_down()
|
|
|
|
local y, x, width = file_coord(File_navigation.index)
|
|
|
|
local index = file_index(y+Editor_state.line_height, x, width)
|
|
|
|
if index then
|
|
|
|
File_navigation.index = index
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function file_coord(index)
|
|
|
|
local y,x = Menu_status_bar_height, 5
|
|
|
|
for i,filename in ipairs(File_navigation.candidates) do
|
2023-04-01 22:48:59 +01:00
|
|
|
local width = App.width(filename)
|
2022-09-18 08:37:20 +01:00
|
|
|
if x + width > App.screen.width - 5 then
|
|
|
|
y = y + Editor_state.line_height
|
|
|
|
x = 5
|
|
|
|
end
|
|
|
|
if i == index then
|
|
|
|
return y, x, width
|
|
|
|
end
|
|
|
|
x = x + width + 30
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function file_index(fy, fx, fwidth)
|
|
|
|
log_start('file index')
|
|
|
|
log(2, ('for %d %d %d'):format(fy, fx, fwidth))
|
|
|
|
local y,x = Menu_status_bar_height, 5
|
|
|
|
local best_guess, best_guess_x, best_guess_width
|
|
|
|
for i,filename in ipairs(File_navigation.candidates) do
|
2023-04-01 22:48:59 +01:00
|
|
|
local width = App.width(filename)
|
2022-09-18 08:37:20 +01:00
|
|
|
if x + width > App.screen.width - 5 then
|
|
|
|
y = y + Editor_state.line_height
|
|
|
|
x = 5
|
|
|
|
end
|
|
|
|
if y == fy then
|
|
|
|
log(2, ('%d: correct row; considering %d %s %d %d'):format(y, i, filename, x, width))
|
|
|
|
if best_guess == nil then
|
|
|
|
log(2, 'nil')
|
|
|
|
best_guess = i
|
|
|
|
best_guess_x = x
|
|
|
|
best_guess_width = width
|
|
|
|
elseif math.abs(fx + fwidth/2 - x - width/2) < math.abs(fx + fwidth/2 - best_guess_x - best_guess_width/2) then
|
|
|
|
best_guess = i
|
|
|
|
best_guess_x = x
|
|
|
|
best_guess_width = width
|
|
|
|
end
|
|
|
|
log(2, ('best guess now %d %s %d %d'):format(best_guess, File_navigation.candidates[best_guess], best_guess_x, best_guess_width))
|
|
|
|
end
|
|
|
|
x = x + width + 30
|
|
|
|
end
|
|
|
|
log_end('file index')
|
|
|
|
return best_guess
|
|
|
|
end
|
2022-09-18 09:53:36 +01:00
|
|
|
|
2022-12-24 01:16:19 +00:00
|
|
|
function text_input_on_file_navigator(t)
|
2022-09-18 09:53:36 +01:00
|
|
|
File_navigation.filter = File_navigation.filter..t
|
|
|
|
File_navigation.candidates = source.file_navigator_candidates()
|
|
|
|
end
|