Links are working!
parent
3b6b72a36e
commit
1841bebc93
66
src/draw.cc
66
src/draw.cc
|
@ -1,5 +1,6 @@
|
|||
#include "draw.h"
|
||||
#include "node.h"
|
||||
#include "mainwindow.h"
|
||||
#include <gdk/gdkthreads.h>
|
||||
#include <iostream>
|
||||
#define PANGO_SCALE_XXX_LARGE ((double)1.98)
|
||||
|
@ -11,8 +12,9 @@ struct DispatchData
|
|||
std::string url;
|
||||
};
|
||||
|
||||
Draw::Draw()
|
||||
: buffer(Glib::unwrap(this->get_buffer())),
|
||||
Draw::Draw(MainWindow &mainWindow)
|
||||
: mainWindow(mainWindow),
|
||||
buffer(Glib::unwrap(this->get_buffer())),
|
||||
fontSize(10 * PANGO_SCALE),
|
||||
fontFamily("Ubuntu Monospace"),
|
||||
headingLevel(0),
|
||||
|
@ -63,6 +65,62 @@ Draw::Draw()
|
|||
heading5.set_weight(Pango::WEIGHT_BOLD);
|
||||
heading6.set_size(fontSize * PANGO_SCALE_MEDIUM);
|
||||
heading6.set_weight(Pango::WEIGHT_BOLD);
|
||||
|
||||
// Click event
|
||||
signal_event_after().connect(sigc::mem_fun(this, &Draw::event_after));
|
||||
}
|
||||
|
||||
/**
|
||||
* Links can be activated by clicking or touching the screen.
|
||||
*/
|
||||
void Draw::event_after(GdkEvent *ev)
|
||||
{
|
||||
gdouble ex, ey;
|
||||
Gtk::TextBuffer::iterator iter;
|
||||
int x, y;
|
||||
|
||||
if (ev->type == GDK_BUTTON_RELEASE)
|
||||
{
|
||||
GdkEventButton *event;
|
||||
event = (GdkEventButton *)ev;
|
||||
if (event->button != GDK_BUTTON_PRIMARY)
|
||||
return;
|
||||
ex = event->x;
|
||||
ey = event->y;
|
||||
}
|
||||
else if (ev->type == GDK_TOUCH_END)
|
||||
{
|
||||
GdkEventTouch *event;
|
||||
event = (GdkEventTouch *)ev;
|
||||
ex = event->x;
|
||||
ey = event->y;
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
// Get the textview coordinates and retrieve an iterator
|
||||
window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_WIDGET, ex, ey, x, y);
|
||||
get_iter_at_location(iter, x, y);
|
||||
// Find the links
|
||||
followLink(iter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for links
|
||||
*/
|
||||
void Draw::followLink(Gtk::TextBuffer::iterator &iter)
|
||||
{
|
||||
auto tags = iter.get_tags();
|
||||
for (auto const &tag : tags)
|
||||
{
|
||||
char *url = static_cast<char *>(tag->get_data("url"));
|
||||
if (url != 0 && (strlen(url) > 0))
|
||||
{
|
||||
// Get the URL
|
||||
mainWindow.doRequest(url, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Draw::showMessage(const std::string &message, const std::string &detailed_info)
|
||||
|
@ -81,7 +139,8 @@ void Draw::showStartPage()
|
|||
this->clear();
|
||||
|
||||
insertHeading1("Welcome to the Decentralized Web (DWeb)");
|
||||
insertText("For the test example, go to: ipfs://QmQzhn6hEfbYdCfwzYFsSt3eWpubVKA1dNqsgUwci5vHwq");
|
||||
insertText("See also the: ");
|
||||
insertLink("Example page on IPFS", "ipfs://QmQzhn6hEfbYdCfwzYFsSt3eWpubVKA1dNqsgUwci5vHwq");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -298,7 +357,6 @@ void Draw::processNode(cmark_node *node, cmark_event_type ev_type)
|
|||
// URL
|
||||
else if (isLink)
|
||||
{
|
||||
std::cout << "Text: " << text << "With link: " << linkURL << std::endl;
|
||||
insertLink(text, linkURL);
|
||||
linkURL = "";
|
||||
}
|
||||
|
|
10
src/draw.h
10
src/draw.h
|
@ -5,17 +5,24 @@
|
|||
#include <pangomm/layout.h>
|
||||
#include <cmark-gfm.h>
|
||||
|
||||
class MainWindow;
|
||||
struct DispatchData;
|
||||
|
||||
class Draw : public Gtk::TextView
|
||||
{
|
||||
public:
|
||||
Draw();
|
||||
Draw(MainWindow &mainWindow);
|
||||
void showMessage(const std::string &message, const std::string &detailed_info = "");
|
||||
void showStartPage();
|
||||
void processDocument(cmark_node *root_node);
|
||||
|
||||
protected:
|
||||
// Signals
|
||||
void event_after(GdkEvent *ev);
|
||||
|
||||
private:
|
||||
void followLink(Gtk::TextBuffer::iterator &iter);
|
||||
|
||||
void processNode(cmark_node *node, cmark_event_type ev_type);
|
||||
// Helper functions for inserting text
|
||||
void insertText(const std::string &text);
|
||||
|
@ -37,6 +44,7 @@ private:
|
|||
static gboolean clearIdle(GtkTextBuffer *textBuffer);
|
||||
static std::string const intToRoman(int num);
|
||||
|
||||
MainWindow &mainWindow;
|
||||
GtkTextBuffer *buffer;
|
||||
int fontSize;
|
||||
std::string fontFamily;
|
||||
|
|
|
@ -12,6 +12,7 @@ MainWindow::MainWindow()
|
|||
: m_vbox(Gtk::ORIENTATION_VERTICAL, 0),
|
||||
m_hbox_bar(Gtk::ORIENTATION_HORIZONTAL, 0),
|
||||
m_requestThread(nullptr),
|
||||
m_draw(*this),
|
||||
requestPath(""),
|
||||
finalRequestPath(""),
|
||||
currentContent("")
|
||||
|
@ -29,7 +30,7 @@ MainWindow::MainWindow()
|
|||
m_about.signal_response().connect(sigc::mem_fun(m_about, &About::hide_about)); /*!< Close about dialog */
|
||||
m_refreshButton.signal_clicked().connect(sigc::mem_fun(this, &MainWindow::refresh)); /*!< Button for reloading the page */
|
||||
m_homeButton.signal_clicked().connect(sigc::mem_fun(this, &MainWindow::go_home)); /*!< Button for home page */
|
||||
m_inputField.signal_activate().connect(sigc::mem_fun(this, &MainWindow::input_activate)); /*!< User pressed enter in the input */
|
||||
m_addressBar.signal_activate().connect(sigc::mem_fun(this, &MainWindow::address_bar_activate)); /*!< User pressed enter the address bar */
|
||||
|
||||
m_vbox.pack_start(m_menu, false, false, 0);
|
||||
|
||||
|
@ -59,7 +60,7 @@ MainWindow::MainWindow()
|
|||
m_hbox_bar.pack_start(m_forwardButton, false, false, 0);
|
||||
m_hbox_bar.pack_start(m_refreshButton, false, false, 0);
|
||||
m_hbox_bar.pack_start(m_homeButton, false, false, 0);
|
||||
m_hbox_bar.pack_start(m_inputField, true, true, 8);
|
||||
m_hbox_bar.pack_start(m_addressBar, true, true, 8);
|
||||
m_vbox.pack_start(m_hbox_bar, false, false, 6);
|
||||
|
||||
// Browser text drawing area
|
||||
|
@ -71,7 +72,7 @@ MainWindow::MainWindow()
|
|||
show_all_children();
|
||||
|
||||
// Grap focus to input field by default
|
||||
m_inputField.grab_focus();
|
||||
m_addressBar.grab_focus();
|
||||
|
||||
// Show start page by default
|
||||
// Load test.md file on start-up
|
||||
|
@ -79,23 +80,11 @@ MainWindow::MainWindow()
|
|||
//go_home();
|
||||
}
|
||||
|
||||
void MainWindow::go_home()
|
||||
{
|
||||
this->requestPath = "";
|
||||
this->finalRequestPath = "";
|
||||
this->currentContent = "";
|
||||
this->m_inputField.set_text("");
|
||||
m_draw.showStartPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger when user input text in address bar
|
||||
* Fetch document from disk or IPFS, using threading
|
||||
*/
|
||||
void MainWindow::input_activate()
|
||||
void MainWindow::doRequest(const std::string &path, bool setAddressBar)
|
||||
{
|
||||
// QmQzhn6hEfbYdCfwzYFsSt3eWpubVKA1dNqsgUwci5vHwq
|
||||
|
||||
// Stop running thread (if applicable)
|
||||
if (m_requestThread)
|
||||
{
|
||||
if (m_requestThread->joinable())
|
||||
|
@ -107,8 +96,28 @@ void MainWindow::input_activate()
|
|||
}
|
||||
}
|
||||
|
||||
if (m_requestThread == nullptr)
|
||||
m_requestThread = new std::thread(&MainWindow::doRequest, this, m_inputField.get_text());
|
||||
if (m_requestThread == nullptr) {
|
||||
if (setAddressBar)
|
||||
m_addressBar.set_text(path);
|
||||
m_requestThread = new std::thread(&MainWindow::processRequest, this, path);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::go_home()
|
||||
{
|
||||
this->requestPath = "";
|
||||
this->finalRequestPath = "";
|
||||
this->currentContent = "";
|
||||
this->m_addressBar.set_text("");
|
||||
m_draw.showStartPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger when user input text in address bar
|
||||
*/
|
||||
void MainWindow::address_bar_activate()
|
||||
{
|
||||
doRequest(m_addressBar.get_text());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -116,15 +125,14 @@ void MainWindow::input_activate()
|
|||
*/
|
||||
void MainWindow::refresh()
|
||||
{
|
||||
if (m_requestThread == nullptr)
|
||||
m_requestThread = new std::thread(&MainWindow::doRequest, this, "");
|
||||
doRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file from disk or IPFS network, from the provided path,
|
||||
* parse the content, and display the document
|
||||
*/
|
||||
void MainWindow::doRequest(const std::string &path)
|
||||
void MainWindow::processRequest(const std::string &path)
|
||||
{
|
||||
currentContent = "";
|
||||
if (!path.empty())
|
||||
|
@ -166,7 +174,7 @@ void MainWindow::doRequest(const std::string &path)
|
|||
}
|
||||
|
||||
/**
|
||||
* Helper method for doRequest(),
|
||||
* Helper method for processRequest(),
|
||||
* Display markdown file from IPFS network.
|
||||
*/
|
||||
void MainWindow::fetchFromIPFS()
|
||||
|
@ -189,7 +197,7 @@ void MainWindow::fetchFromIPFS()
|
|||
}
|
||||
|
||||
/**
|
||||
* Helper method for doRequest(),
|
||||
* Helper method for processRequest(),
|
||||
* Display markdown file from disk.
|
||||
*/
|
||||
void MainWindow::openFromDisk()
|
||||
|
|
|
@ -18,12 +18,13 @@ class MainWindow : public Gtk::Window
|
|||
{
|
||||
public:
|
||||
MainWindow();
|
||||
void doRequest(const std::string &path= std::string(), bool setAddressBar = false);
|
||||
|
||||
protected:
|
||||
// Signal handlers:
|
||||
// Our new improved on_button_clicked(). (see below)
|
||||
void go_home();
|
||||
void input_activate();
|
||||
void address_bar_activate();
|
||||
void refresh();
|
||||
void on_button_clicked(Glib::ustring data);
|
||||
void show_about();
|
||||
|
@ -38,7 +39,7 @@ protected:
|
|||
Gtk::Button m_forwardButton;
|
||||
Gtk::Button m_refreshButton;
|
||||
Gtk::Button m_homeButton;
|
||||
Gtk::Entry m_inputField;
|
||||
Gtk::Entry m_addressBar;
|
||||
Gtk::Image backIcon;
|
||||
Gtk::Image forwardIcon;
|
||||
Gtk::Image refreshIcon;
|
||||
|
@ -55,7 +56,7 @@ private:
|
|||
std::string finalRequestPath;
|
||||
std::string currentContent;
|
||||
|
||||
void doRequest(const std::string &path);
|
||||
void processRequest(const std::string &path);
|
||||
void fetchFromIPFS();
|
||||
void openFromDisk();
|
||||
};
|
||||
|
|
34
test.md
34
test.md
|
@ -1,2 +1,34 @@
|
|||
Hello *World*, What a **happy** day!
|
||||
blabla.
|
||||
[test](ipfs://QmQzhn6hEfbYdCfwzYFsSt3eWpubVKA1dNqsgUwci5vHwq)
|
||||
|
||||
[test](ipfs://blablabalba)
|
||||
# Heading 1
|
||||
|
||||
## Heading 2
|
||||
|
||||
### Heading 3
|
||||
|
||||
***New*** paragraph.
|
||||
New line.
|
||||
|
||||
* list 1
|
||||
* list 2
|
||||
* list 3
|
||||
* list 3.1
|
||||
* list 3.2
|
||||
* list 4
|
||||
|
||||
1. first
|
||||
2. second
|
||||
3. third
|
||||
1. 1st
|
||||
2. 2nd
|
||||
3. grappig
|
||||
4. he
|
||||
4. four
|
||||
|
||||
Extra text.
|
||||
|
||||
----------
|
||||
|
||||
Dit is een nieuwe test.
|
Loading…
Reference in New Issue