diff options
-rw-r--r-- | app.lua | 4 | ||||
-rw-r--r-- | commands.lua | 223 | ||||
-rw-r--r-- | log_browser.lua | 9 | ||||
-rw-r--r-- | main.lua | 1 | ||||
-rw-r--r-- | run.lua | 1 | ||||
-rw-r--r-- | source.lua | 15 | ||||
-rw-r--r-- | source_edit.lua | 4 | ||||
-rw-r--r-- | source_text.lua | 6 |
8 files changed, 235 insertions, 28 deletions
diff --git a/app.lua b/app.lua index 994f0c7..62ecd38 100644 --- a/app.lua +++ b/app.lua @@ -194,6 +194,10 @@ function App.color(color) love.graphics.setColor(color.r, color.g, color.b, color.a) end +function colortable(app_color) + return {app_color.r, app_color.g, app_color.b, app_color.a} +end + App.time = 1 function App.getTime() return App.time diff --git a/commands.lua b/commands.lua index be9c9bf..583d1ef 100644 --- a/commands.lua +++ b/commands.lua @@ -42,52 +42,120 @@ function source.draw_menu_bar() end function add_hotkey_to_menu(s) - if Text_cache[s] == nil then - Text_cache[s] = App.newText(love.graphics.getFont(), s) - end - local width = App.width(Text_cache[s]) + local s_text = to_text(s) + local width = App.width(s_text) if Menu_cursor + width > App.screen.width - 5 then return end App.color(Menu_command_color) - App.screen.draw(Text_cache[s], Menu_cursor,5) + App.screen.draw(s_text, Menu_cursor,5) Menu_cursor = Menu_cursor + width + 30 end function source.draw_file_navigator() - for i,file in ipairs(File_navigation.candidates) do - if file == 'source' then + App.color(Menu_command_color) + local filter_text = to_text(File_navigation.filter) + App.screen.draw(filter_text, 5, 5) + draw_cursor(5 + App.width(filter_text), 5) + if File_navigation.num_lines == nil then + File_navigation.num_lines = source.num_lines_for_file_navigator(File_navigation.candidates) + end + App.color(Menu_background_color) + love.graphics.rectangle('fill', 0,Menu_status_bar_height, App.screen.width, File_navigation.num_lines * Editor_state.line_height + --[[highlight padding]] 2) + local x,y = 5, Menu_status_bar_height + for i,filename in ipairs(File_navigation.candidates) do + if filename == 'source' then App.color(Menu_border_color) love.graphics.line(Menu_cursor-10,2, Menu_cursor-10,Menu_status_bar_height-2) end - add_file_to_menu(file, i == File_navigation.index) + x,y = add_file_to_menu(x,y, filename, i == File_navigation.index) + if Menu_cursor >= App.screen.width - 5 then + break + end end end -function add_file_to_menu(s, cursor_highlight) - if Text_cache[s] == nil then - Text_cache[s] = App.newText(love.graphics.getFont(), s) +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 - local width = App.width(Text_cache[s]) - if Menu_cursor + width > App.screen.width - 5 then - return +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 + +function source.num_lines_for_file_navigator(candidates) + local result = 1 + local x = 5 + for i,filename in ipairs(candidates) do + local width = App.width(to_text(filename)) + if x + width > App.screen.width - 5 then + result = result+1 + x = 5 + width + else + x = x + width + 30 + end + end + return result +end + +function add_file_to_menu(x,y, s, cursor_highlight) + local s_text = to_text(s) + local width = App.width(s_text) + if x + width > App.screen.width - 5 then + y = y + Editor_state.line_height + x = 5 + end + local color = Menu_background_color if cursor_highlight then - App.color(Menu_highlight_color) - love.graphics.rectangle('fill', Menu_cursor-5,5-2, App.width(Text_cache[s])+5*2,Editor_state.line_height+2*2) + color = Menu_highlight_color end + button(Editor_state, 'menu', {x=x-5, y=y-2, w=width+5*2, h=Editor_state.line_height+2*2, color=colortable(color), + onpress1 = function() + local candidate = guess_source(s..'.lua') + source.switch_to_file(candidate) + Show_file_navigator = false + end + }) App.color(Menu_command_color) - App.screen.draw(Text_cache[s], Menu_cursor,5) - Menu_cursor = Menu_cursor + width + 30 + App.screen.draw(s_text, x,y) + x = x + width + 30 + return x,y end function keychord_pressed_on_file_navigator(chord, key) + log(2, 'file navigator: '..chord) + log(2, {name='file_navigator_state', files=File_navigation.candidates, index=File_navigation.index}) if chord == 'escape' then Show_file_navigator = false + File_navigation.index = 1 + File_navigation.filter = '' + File_navigation.candidates = File_navigation.all_candidates elseif chord == 'return' then local candidate = guess_source(File_navigation.candidates[File_navigation.index]..'.lua') source.switch_to_file(candidate) Show_file_navigator = false + File_navigation.index = 1 + File_navigation.filter = '' + File_navigation.candidates = File_navigation.all_candidates + 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() elseif chord == 'left' then if File_navigation.index > 1 then File_navigation.index = File_navigation.index-1 @@ -96,5 +164,124 @@ function keychord_pressed_on_file_navigator(chord, key) if File_navigation.index < #File_navigation.candidates then File_navigation.index = File_navigation.index+1 end + elseif chord == 'down' then + file_navigator_down() + elseif chord == 'up' then + file_navigator_up() end end + +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 + local filename_text = to_text(filename) + width = App.width(filename_text) + 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 + local filename_text = to_text(filename) + width = App.width(filename_text) + 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) + App.screen.draw(filename_text, x + x3-menu_xmin, y3) + end + x3 = x3 + width + 30 + end + -- + return h+20 +end + +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 + local width = App.width(to_text(filename)) + 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 + local width = App.width(to_text(filename)) + 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 + +function textinput_on_file_navigator(t) + File_navigation.filter = File_navigation.filter..t + File_navigation.candidates = source.file_navigator_candidates() +end diff --git a/log_browser.lua b/log_browser.lua index f65117f..91f02eb 100644 --- a/log_browser.lua +++ b/log_browser.lua @@ -27,7 +27,14 @@ log_browser = {} function log_browser.parse(State) for _,line in ipairs(State.lines) do if line.data ~= '' then - line.filename, line.line_number, line.data = line.data:match('%[string "([^:]*)"%]:([^:]*):%s*(.*)') + local rest + line.filename, line.line_number, rest = line.data:match('%[string "([^:]*)"%]:([^:]*):%s*(.*)') + if line.filename == nil then + line.filename, line.line_number, rest = line.data:match('([^:]*):([^:]*):%s*(.*)') + end + if rest then + line.data = rest + end line.filename = guess_source(line.filename) line.line_number = tonumber(line.line_number) if line.data:sub(1,1) == '{' then diff --git a/main.lua b/main.lua index 8e926c8..87b867f 100644 --- a/main.lua +++ b/main.lua @@ -26,6 +26,7 @@ load_file_from_source_or_save_directory('log.lua') -- but some files we want to only load sometimes function App.load() + log_new('session') if love.filesystem.getInfo('config') then Settings = json.decode(love.filesystem.read('config')) Current_app = Settings.current_app diff --git a/run.lua b/run.lua index e395978..8d03aa2 100644 --- a/run.lua +++ b/run.lua @@ -15,6 +15,7 @@ end -- called only for real run function run.initialize(arg) + log_new('run') love.keyboard.setTextInput(true) -- bring up keyboard on touch screen love.keyboard.setKeyRepeat(true) diff --git a/source.lua b/source.lua index a259494..c763994 100644 --- a/source.lua +++ b/source.lua @@ -1,4 +1,5 @@ source = {} +log_render = {} Editor_state = {} @@ -10,7 +11,7 @@ function source.initialize_globals() Focus = 'edit' Show_file_navigator = false File_navigation = { - candidates = { + all_candidates = { 'run', 'run_tests', 'log', @@ -43,7 +44,9 @@ function source.initialize_globals() 'json', }, index = 1, + filter = '', } + File_navigation.candidates = File_navigation.all_candidates -- modified with filter Menu_status_bar_height = 5 + --[[line height in tests]] 15 + 5 @@ -56,6 +59,7 @@ end -- called only for real run function source.initialize() + log_new('source') love.keyboard.setTextInput(true) -- bring up keyboard on touch screen love.keyboard.setKeyRepeat(true) @@ -219,8 +223,7 @@ function source.switch_to_file(filename) end function source.draw() - source.draw_menu_bar() - edit.draw(Editor_state) + edit.draw(Editor_state, --[[hide cursor?]] Show_file_navigator) if Show_log_browser_side then -- divider App.color(Divider_color) @@ -228,6 +231,7 @@ function source.draw() -- log_browser.draw(Log_browser_state) end + source.draw_menu_bar() end function source.update(dt) @@ -304,6 +308,10 @@ end function source.textinput(t) Cursor_time = 0 -- ensure cursor is visible immediately after it moves + if Show_file_navigator then + textinput_on_file_navigator(t) + return + end if Focus == 'edit' then return edit.textinput(Editor_state, t) else @@ -341,7 +349,6 @@ function source.keychord_pressed(chord, key) end if chord == 'C-g' then Show_file_navigator = true - File_navigation.index = 1 return end if Focus == 'edit' then diff --git a/source_edit.lua b/source_edit.lua index c17ce26..4f55083 100644 --- a/source_edit.lua +++ b/source_edit.lua @@ -124,7 +124,7 @@ function edit.fixup_cursor(State) end end -function edit.draw(State) +function edit.draw(State, hide_cursor) State.button_handlers = {} App.color(Text_color) if #State.lines ~= #State.line_cache then @@ -170,7 +170,7 @@ function edit.draw(State) end, }) end - y, State.screen_bottom1.pos, State.screen_bottom1.posB = Text.draw(State, line_index, y, startpos, startposB) + y, State.screen_bottom1.pos, State.screen_bottom1.posB = Text.draw(State, line_index, y, startpos, startposB, hide_cursor) y = y + State.line_height --? print('=> y', y) elseif line.mode == 'drawing' then diff --git a/source_text.lua b/source_text.lua index 5959fd5..3e70343 100644 --- a/source_text.lua +++ b/source_text.lua @@ -4,7 +4,7 @@ AB_padding = 20 -- space in pixels between A side and B side -- draw a line starting from startpos to screen at y between State.left and State.right -- return the final y, and pos,posB of start of final screen line drawn -function Text.draw(State, line_index, y, startpos, startposB) +function Text.draw(State, line_index, y, startpos, startposB, hide_cursor) local line = State.lines[line_index] local line_cache = State.line_cache[line_index] line_cache.starty = y @@ -18,7 +18,7 @@ function Text.draw(State, line_index, y, startpos, startposB) return y, screen_line_starting_pos end if Focus == 'edit' and State.cursor1.pos then - if State.search_term == nil then + if not hide_cursor and not State.search_term then if line_index == State.cursor1.line and State.cursor1.pos == pos then Text.draw_cursor(State, x, y) end @@ -64,7 +64,7 @@ function Text.draw(State, line_index, y, startpos, startposB) --? if line_index == 8 then print('a') end if Focus == 'edit' and State.cursor1.posB then --? if line_index == 8 then print('b') end - if State.search_term == nil then + if not hide_cursor and not State.search_term then --? if line_index == 8 then print('c', State.cursor1.line, State.cursor1.posB, line_index, pos) end if line_index == State.cursor1.line and State.cursor1.posB == pos then Text.draw_cursor(State, x, y) |