summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Bugaev <bugaevc@gmail.com>2019-10-02 22:44:05 +0300
committerAndreas Kling <awesomekling@gmail.com>2019-10-03 08:23:54 +0200
commit395e4210ef97dd5d8a9348f5304a525e4c288259 (patch)
tree20e6289e86327381607da84efb6fddf5a8e86cde
parentafdc5688ec90a58591e359e794d07eff18baa0a6 (diff)
downloadserenity-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.cpp33
-rw-r--r--Applications/Help/History.h22
-rw-r--r--Applications/Help/Makefile7
-rw-r--r--Applications/Help/main.cpp90
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"));