diff options
author | Sergey Bugaev <bugaevc@gmail.com> | 2019-10-02 22:44:05 +0300 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-10-03 08:23:54 +0200 |
commit | 395e4210ef97dd5d8a9348f5304a525e4c288259 (patch) | |
tree | 20e6289e86327381607da84efb6fddf5a8e86cde | |
parent | afdc5688ec90a58591e359e794d07eff18baa0a6 (diff) | |
download | serenity-395e4210ef97dd5d8a9348f5304a525e4c288259.zip |
Help: Follow clicked links
This also adds a toolbar and a menu which allow you to
navigate back and forth through history ^)
-rw-r--r-- | Applications/Help/History.cpp | 33 | ||||
-rw-r--r-- | Applications/Help/History.h | 22 | ||||
-rw-r--r-- | Applications/Help/Makefile | 7 | ||||
-rw-r--r-- | Applications/Help/main.cpp | 90 |
4 files changed, 145 insertions, 7 deletions
diff --git a/Applications/Help/History.cpp b/Applications/Help/History.cpp new file mode 100644 index 0000000000..89822bdbbb --- /dev/null +++ b/Applications/Help/History.cpp @@ -0,0 +1,33 @@ +#include "History.h" + +void History::push(const StringView& history_item) +{ + m_items.shrink(m_current_history_item + 1); + m_items.append(history_item); + m_current_history_item++; +} + +String History::current() +{ + if (m_current_history_item == -1) + return {}; + return m_items[m_current_history_item]; +} + +void History::go_back() +{ + ASSERT(can_go_back()); + m_current_history_item--; +} + +void History::go_forward() +{ + ASSERT(can_go_forward()); + m_current_history_item++; +} + +void History::clear() +{ + m_items = {}; + m_current_history_item = -1; +} diff --git a/Applications/Help/History.h b/Applications/Help/History.h new file mode 100644 index 0000000000..1c83b35d35 --- /dev/null +++ b/Applications/Help/History.h @@ -0,0 +1,22 @@ +#pragma once + +#include <AK/String.h> +#include <AK/Vector.h> + +class History final { +public: + void push(const StringView& history_item); + String current(); + + void go_back(); + void go_forward(); + + bool can_go_back() { return m_current_history_item > 0; } + bool can_go_forward() { return m_current_history_item + 1 < m_items.size(); } + + void clear(); + +private: + Vector<String> m_items; + int m_current_history_item { -1 }; +}; diff --git a/Applications/Help/Makefile b/Applications/Help/Makefile index b85c197770..36b372dd7c 100644 --- a/Applications/Help/Makefile +++ b/Applications/Help/Makefile @@ -1,9 +1,10 @@ include ../../Makefile.common OBJS = \ - ManualModel.o \ - ManualSectionNode.o \ - ManualPageNode.o \ + ManualModel.o \ + ManualSectionNode.o \ + ManualPageNode.o \ + History.o \ main.o APP = Help diff --git a/Applications/Help/main.cpp b/Applications/Help/main.cpp index dd20b51205..8030b5fdd3 100644 --- a/Applications/Help/main.cpp +++ b/Applications/Help/main.cpp @@ -1,10 +1,17 @@ +#include "History.h" #include "ManualModel.h" #include <LibCore/CFile.h> #include <LibDraw/PNGLoader.h> +#include <LibGUI/GAboutDialog.h> +#include <LibGUI/GAction.h> #include <LibGUI/GApplication.h> +#include <LibGUI/GBoxLayout.h> +#include <LibGUI/GMenu.h> +#include <LibGUI/GMenuBar.h> #include <LibGUI/GMessageBox.h> #include <LibGUI/GSplitter.h> #include <LibGUI/GTextEditor.h> +#include <LibGUI/GToolBar.h> #include <LibGUI/GTreeView.h> #include <LibGUI/GWindow.h> #include <LibHTML/HtmlView.h> @@ -12,6 +19,7 @@ #include <LibHTML/Parser/CSSParser.h> #include <LibHTML/Parser/HTMLParser.h> #include <LibMarkdown/MDDocument.h> +#include <libgen.h> int main(int argc, char* argv[]) { @@ -21,7 +29,13 @@ int main(int argc, char* argv[]) window->set_title("Help"); window->set_rect(300, 200, 570, 500); - auto splitter = GSplitter::construct(Orientation::Horizontal, nullptr); + auto widget = GWidget::construct(); + widget->set_layout(make<GBoxLayout>(Orientation::Vertical)); + widget->layout()->set_spacing(0); + + auto toolbar = GToolBar::construct(widget); + + auto splitter = GSplitter::construct(Orientation::Horizontal, widget); auto model = ManualModel::create(); @@ -36,8 +50,17 @@ int main(int argc, char* argv[]) String css = default_stylesheet_source; auto sheet = parse_css(css); - tree_view->on_selection_change = [&] { - String path = model->page_path(tree_view->selection().first()); + History history; + + RefPtr<GAction> go_back_action; + RefPtr<GAction> go_forward_action; + + auto update_actions = [&]() { + go_back_action->set_enabled(history.can_go_back()); + go_forward_action->set_enabled(history.can_go_forward()); + }; + + auto open_page = [&](String path) { if (path.is_null()) { html_view->set_document(nullptr); return; @@ -70,7 +93,66 @@ int main(int argc, char* argv[]) window->set_title(String::format("Help: %s", page_and_section.characters())); }; - window->set_main_widget(splitter); + tree_view->on_selection_change = [&] { + String path = model->page_path(tree_view->selection().first()); + if (path.is_null()) { + html_view->set_document(nullptr); + return; + } + history.push(path); + update_actions(); + open_page(path); + }; + + html_view->on_link_click = [&](const String& href) { + char* current_path = strdup(history.current().characters()); + char* dir_path = dirname(current_path); + char* path = realpath(String::format("%s/%s", dir_path, href.characters()).characters(), nullptr); + free(current_path); + history.push(path); + update_actions(); + open_page(path); + free(path); + }; + + go_back_action = GAction::create("Go Back", { Mod_Alt, Key_Left }, GraphicsBitmap::load_from_file("/res/icons/16x16/go-back.png"), [&](const GAction&) { + history.go_back(); + update_actions(); + open_page(history.current()); + }); + + go_forward_action = GAction::create("Go Forward", { Mod_Alt, Key_Right }, GraphicsBitmap::load_from_file("/res/icons/16x16/go-forward.png"), [&](const GAction&) { + history.go_forward(); + update_actions(); + open_page(history.current()); + }); + + go_back_action->set_enabled(false); + go_forward_action->set_enabled(false); + + toolbar->add_action(*go_back_action); + toolbar->add_action(*go_forward_action); + + auto menubar = make<GMenuBar>(); + + auto app_menu = make<GMenu>("Help"); + app_menu->add_action(GAction::create("About", [&](const GAction&) { + GAboutDialog::show("Help", load_png("/res/icons/16x16/book.png"), window); + })); + app_menu->add_separator(); + app_menu->add_action(GCommonActions::make_quit_action([](auto&) { + GApplication::the().quit(0); + })); + menubar->add_menu(move(app_menu)); + + auto go_menu = make<GMenu>("Go"); + go_menu->add_action(*go_back_action); + go_menu->add_action(*go_forward_action); + menubar->add_menu(move(go_menu)); + + app.set_menubar(move(menubar)); + + window->set_main_widget(widget); window->show(); window->set_icon(load_png("/res/icons/16x16/book.png")); |