From e7001f4b40c5443874092e6fc6bd13799b44c5ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiktor=20Obr=C4=99bski?= Date: Thu, 1 Aug 2024 23:10:26 +0200 Subject: [PATCH] Add keyboard navigation to journal table of contents Jump to previous/next section by ctrl+up/ctrl+down, working only in beta 51.01+ --- docs/gui/journal.rst | 1 + gui/journal.lua | 36 ++++++++++--- internal/journal/table_of_contents.lua | 9 +++- test/gui/journal.lua | 72 ++++++++++++++++++++++++-- 4 files changed, 106 insertions(+), 12 deletions(-) diff --git a/docs/gui/journal.rst b/docs/gui/journal.rst index 81d77d130..ba3619d2e 100644 --- a/docs/gui/journal.rst +++ b/docs/gui/journal.rst @@ -48,6 +48,7 @@ Supported Features - If no text is selected, paste text in the cursor position - Scrolling behaviour for long text build-in - Table of contents (:kbd:`Ctrl` + :kbd:`O`), with headers line prefixed by '#', e.g. '# Fort history', '## Year 1' +- Table of contents navigation: jump to previous/next section by :kbd:`Ctrl` + :kbd:`Up` / :kbd:`Ctrl` + :kbd:`Down` Usage ----- diff --git a/gui/journal.lua b/gui/journal.lua index 58827d487..30d5072ca 100644 --- a/gui/journal.lua +++ b/gui/journal.lua @@ -118,11 +118,31 @@ end function JournalWindow:onInput(keys) if (keys.A_MOVE_N_DOWN) then - print('works N') + local curr_cursor = self.subviews.journal_editor:getCursor() + local section_index, section = self.subviews.table_of_contents_panel:cursorSection( + curr_cursor + ) + + if section.line_cursor == curr_cursor then + self.subviews.table_of_contents_panel:setSelectedSection( + section_index - 1 + ) + self.subviews.table_of_contents_panel:submit() + else + self:onTableOfContentsSubmit(section_index, section) + end + + return false + elseif (keys.A_MOVE_S_DOWN) then + local section_index = self.subviews.table_of_contents_panel:cursorSection( + self.subviews.journal_editor:getCursor() + ) + self.subviews.table_of_contents_panel:setSelectedSection( + section_index + 1 + ) + self.subviews.table_of_contents_panel:submit() + return false - end - if (keys.A_MOVE_S_DOWN) then - print('works S') end return JournalWindow.super.onInput(self, keys) @@ -223,7 +243,7 @@ function JournalWindow:postUpdateLayout() end function JournalWindow:onCursorChange(cursor) - local section_index, cursor_section = self.subviews.table_of_contents_panel:cursorSection( + local section_index = self.subviews.table_of_contents_panel:cursorSection( cursor ) self.subviews.table_of_contents_panel:setSelectedSection(section_index) @@ -241,9 +261,9 @@ function JournalWindow:onTextChange(text) end end -function JournalWindow:onTableOfContentsSubmit(ind, choice) - self.subviews.journal_editor:setCursor(choice.line_cursor) - self.subviews.journal_editor:scrollToCursor(choice.line_cursor) +function JournalWindow:onTableOfContentsSubmit(ind, section) + self.subviews.journal_editor:setCursor(section.line_cursor) + self.subviews.journal_editor:scrollToCursor(section.line_cursor) end JournalScreen = defclass(JournalScreen, gui.ZScreen) diff --git a/internal/journal/table_of_contents.lua b/internal/journal/table_of_contents.lua index eac816b3e..c325d3ca7 100644 --- a/internal/journal/table_of_contents.lua +++ b/internal/journal/table_of_contents.lua @@ -35,7 +35,14 @@ function TableOfContents:cursorSection(cursor) end function TableOfContents:setSelectedSection(section_index) - self.subviews.table_of_contents:setSelected(section_index) + local curr_sel = self.subviews.table_of_contents:getSelected() + if curr_sel ~= section_index then + self.subviews.table_of_contents:setSelected(section_index) + end +end + +function TableOfContents:submit() + return self.subviews.table_of_contents:submit() end function TableOfContents:reload(text) diff --git a/test/gui/journal.lua b/test/gui/journal.lua index f3584fcc1..6e94ef7e4 100644 --- a/test/gui/journal.lua +++ b/test/gui/journal.lua @@ -2954,17 +2954,83 @@ function test.table_of_contents_selection_follows_cursor() text_area:setCursor(300) gui_journal.view:onRender() - print(read_rendered_text(text_area)) - expect.eq(toc:getSelected(), 3) text_area:setCursor(646) gui_journal.view:onRender() - print(read_rendered_text(text_area)) + expect.eq(toc:getSelected(), 6) + + journal:dismiss() +end + +function test.table_of_contents_keyboard_navigation() + local journal, text_area = arrange_empty_journal({ + w=100, + h=50, + allow_layout_restore=false + }) + + local text = table.concat({ + '# Header 1', + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + 'Nulla ut lacus ut tortor semper consectetur.', + '# Header 2', + 'Ut eu orci non nibh hendrerit posuere.', + 'Sed euismod odio eu fringilla bibendum.', + '## Subheader 1', + 'Etiam dignissim diam nec aliquet facilisis.', + 'Integer tristique purus at tellus luctus, vel aliquet sapien sollicitudin.', + '## Subheader 2', + 'Fusce ornare est vitae urna feugiat, vel interdum quam vestibulum.', + '10: Vivamus id felis scelerisque, lobortis diam ut, mollis nisi.', + '### Subsubheader 1', + '# Header 3', + 'Donec quis lectus ac erat placerat eleifend.', + 'Aenean non orci id erat malesuada pharetra.', + 'Nunc in lectus et metus finibus venenatis.', + }, '\n') + + simulate_input_text(text) + + simulate_input_keys('CUSTOM_CTRL_O') + + local toc = journal.subviews.table_of_contents + + text_area:setCursor(5) + gui_journal.view:onRender() + + simulate_input_keys('A_MOVE_N_DOWN') + + expect.eq(toc:getSelected(), 1) + + simulate_input_keys('A_MOVE_N_DOWN') expect.eq(toc:getSelected(), 6) + simulate_input_keys('A_MOVE_N_DOWN') + simulate_input_keys('A_MOVE_N_DOWN') + + expect.eq(toc:getSelected(), 4) + + simulate_input_keys('A_MOVE_S_DOWN') + + expect.eq(toc:getSelected(), 5) + + simulate_input_keys('A_MOVE_S_DOWN') + simulate_input_keys('A_MOVE_S_DOWN') + simulate_input_keys('A_MOVE_S_DOWN') + + expect.eq(toc:getSelected(), 2) + + + text_area:setCursor(250) + gui_journal.view:onRender() + + simulate_input_keys('A_MOVE_N_DOWN') + + expect.eq(toc:getSelected(), 3) + journal:dismiss() end