diff options
author | Oriko <oriko1010@protonmail.com> | 2020-03-12 16:36:58 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-03-12 19:04:59 +0100 |
commit | bacd3dd57ac54759b50b61ce80c727e86be9c054 (patch) | |
tree | 95314e054b02cd6a584fb41453f45a7ecb381ec7 | |
parent | 6d89f48dd8c0a57e241a69a5db3a7ceeed8ce108 (diff) | |
download | serenity-bacd3dd57ac54759b50b61ce80c727e86be9c054.zip |
HackStudio: Underline header links
-rw-r--r-- | DevTools/HackStudio/Editor.cpp | 65 | ||||
-rw-r--r-- | DevTools/HackStudio/Editor.h | 5 |
2 files changed, 66 insertions, 4 deletions
diff --git a/DevTools/HackStudio/Editor.cpp b/DevTools/HackStudio/Editor.cpp index c183d117b9..abbf06a3a8 100644 --- a/DevTools/HackStudio/Editor.cpp +++ b/DevTools/HackStudio/Editor.cpp @@ -31,8 +31,10 @@ #include <LibCore/DirIterator.h> #include <LibCore/File.h> #include <LibGUI/Application.h> +#include <LibGUI/CppLexer.h> #include <LibGUI/Painter.h> #include <LibGUI/ScrollBar.h> +#include <LibGUI/SyntaxHighlighter.h> #include <LibGUI/Window.h> #include <LibMarkdown/MDDocument.h> #include <LibWeb/DOM/ElementFactory.h> @@ -92,6 +94,8 @@ void Editor::paint_event(GUI::PaintEvent& event) if (horizontal_scrollbar().is_visible()) rect.set_height(rect.height() - horizontal_scrollbar().height()); painter.draw_rect(rect, palette().selection()); + + window()->set_override_cursor(m_hovering_link && m_holding_ctrl ? GUI::StandardCursor::Hand : GUI::StandardCursor::IBeam); } } @@ -176,11 +180,22 @@ void Editor::mousemove_event(GUI::MouseEvent& event) auto text_position = text_position_at(event.position()); if (!text_position.is_valid()) { - GUI::Application::the().hide_tooltip(); + m_documentation_tooltip_window->hide(); return; } + bool hide_tooltip = true; + bool is_over_header = false; + for (auto& span : document().spans()) { + if (span.range.contains(m_previous_text_position) && !span.range.contains(text_position)) { + auto token = static_cast<GUI::CppToken::Type>(reinterpret_cast<size_t>(span.data)); + if (token == GUI::CppToken::Type::IncludePath && span.is_underlined) { + span.is_underlined = false; + wrapper().editor().update(); + } + } + if (span.range.contains(text_position)) { auto adjusted_range = span.range; adjusted_range.end().set_column(adjusted_range.end().column() + 1); @@ -188,15 +203,37 @@ void Editor::mousemove_event(GUI::MouseEvent& event) #ifdef EDITOR_DEBUG dbg() << "Hovering: " << adjusted_range << " \"" << hovered_span_text << "\""; #endif - show_documentation_tooltip_if_available(hovered_span_text, event.position().translated(screen_relative_rect().location())); - return; + + auto token = static_cast<GUI::CppToken::Type>(reinterpret_cast<size_t>(span.data)); + if (token == GUI::CppToken::Type::IncludePath) { + is_over_header = true; + bool was_underlined = span.is_underlined; + span.is_underlined = event.modifiers() & Mod_Ctrl; + if (span.is_underlined != was_underlined) { + wrapper().editor().update(); + } + } else if (token == GUI::CppToken::Type::Identifier) { + show_documentation_tooltip_if_available(hovered_span_text, event.position().translated(screen_relative_rect().location())); + hide_tooltip = false; + } } } - GUI::Application::the().hide_tooltip(); + + m_previous_text_position = text_position; + if (hide_tooltip) + m_documentation_tooltip_window->hide(); + + m_hovering_link = is_over_header && (event.modifiers() & Mod_Ctrl); } void Editor::mousedown_event(GUI::MouseEvent& event) { + auto highlighter = wrapper().editor().syntax_highlighter(); + if (!highlighter || highlighter->language() != GUI::SyntaxLanguage::Cpp) { + GUI::TextEditor::mousedown_event(event); + return; + } + if (!(event.modifiers() & Mod_Ctrl)) { GUI::TextEditor::mousedown_event(event); return; @@ -210,6 +247,12 @@ void Editor::mousedown_event(GUI::MouseEvent& event) for (auto& span : document().spans()) { if (span.range.contains(text_position)) { + auto token = static_cast<GUI::CppToken::Type>(reinterpret_cast<size_t>(span.data)); + if (token != GUI::CppToken::Type::IncludePath) { + GUI::TextEditor::mousedown_event(event); + return; + } + auto adjusted_range = span.range; adjusted_range.end().set_column(adjusted_range.end().column() + 1); auto span_text = document().text_in_range(adjusted_range); @@ -225,6 +268,20 @@ void Editor::mousedown_event(GUI::MouseEvent& event) GUI::TextEditor::mousedown_event(event); } +void Editor::keydown_event(GUI::KeyEvent& event) +{ + if (event.key() == Key_Control) + m_holding_ctrl = true; + GUI::TextEditor::keydown_event(event); +} + +void Editor::keyup_event(GUI::KeyEvent& event) +{ + if (event.key() == Key_Control) + m_holding_ctrl = false; + GUI::TextEditor::keyup_event(event); +} + static HashMap<String, String>& include_paths() { static HashMap<String, String> paths; diff --git a/DevTools/HackStudio/Editor.h b/DevTools/HackStudio/Editor.h index c02d7d01e6..b3c159f400 100644 --- a/DevTools/HackStudio/Editor.h +++ b/DevTools/HackStudio/Editor.h @@ -48,6 +48,8 @@ private: virtual void paint_event(GUI::PaintEvent&) override; virtual void mousemove_event(GUI::MouseEvent&) override; virtual void mousedown_event(GUI::MouseEvent&) override; + virtual void keydown_event(GUI::KeyEvent&) override; + virtual void keyup_event(GUI::KeyEvent&) override; void show_documentation_tooltip_if_available(const String&, const Gfx::Point& screen_location); void navigate_to_include_if_available(String); @@ -57,4 +59,7 @@ private: RefPtr<GUI::Window> m_documentation_tooltip_window; RefPtr<Web::HtmlView> m_documentation_html_view; String m_last_parsed_token; + GUI::TextPosition m_previous_text_position { 0, 0 }; + bool m_hovering_link { false }; + bool m_holding_ctrl { false }; }; |