From e4f43c8501f1395f89579d3b3998a54ad7c9b41d Mon Sep 17 00:00:00 2001 From: Melroy van den Berg Date: Mon, 16 Nov 2020 05:46:05 +0100 Subject: [PATCH] Working PoC with QGraphicsScene/View and QGraphicsTextItem --- .vscode/settings.json | 4 +++- README.md | 2 ++ src/CMakeLists.txt | 2 ++ src/main.cc | 19 +++++++++++++++--- src/mainwindow.cc | 45 ++++++++++++++++++++++++++++++++++++++++-- src/mainwindow.h | 9 ++++++++- src/markdown-render.cc | 38 +++++++++-------------------------- src/markdown-render.h | 3 --- src/scene.cc | 7 +++++++ src/scene.h | 17 ++++++++++++++++ 10 files changed, 107 insertions(+), 39 deletions(-) create mode 100644 src/scene.cc create mode 100644 src/scene.h diff --git a/.vscode/settings.json b/.vscode/settings.json index 7ba37f8..92c33e8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -64,6 +64,8 @@ "cinttypes": "cpp", "typeinfo": "cpp", "variant": "cpp", - "bit": "cpp" + "bit": "cpp", + "qsizepolicy": "cpp", + "qgraphicsscene": "cpp" } } \ No newline at end of file diff --git a/README.md b/README.md index 8892130..baa9649 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,8 @@ The GUI-toolkit or 2D/3D engine used displaying the content is not yet decided. We can also still change the language of the source code (iso markdown). Atleast no HTML and JavaScript anymore, content is king after all. +For the development environment I'm using VSCodium with `C/C++`, `Cmake` and `Cmake Tools` extensions installed. + ### GUIs #### Qt diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4686a25..3a447e7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -30,6 +30,8 @@ set(SOURCES markdown-render.h mainwindow.cc mainwindow.h + scene.h + scene.cc ) if(ANDROID) diff --git a/src/main.cc b/src/main.cc index bc2275a..016b9ac 100644 --- a/src/main.cc +++ b/src/main.cc @@ -2,20 +2,33 @@ #include "markdown-render.h" #include "mainwindow.h" +#include #include #include #include int main(int argc, char *argv[]) { - MarkdownRender md; + MarkdownRender mdRender; - QString output = QString::fromStdString(md.renderDemoFile()); + std::string exePath = std::filesystem::current_path().string(); + std::string htmlOutput, myOutput = ""; + std::string filePath = exePath.append("/../../test.md"); + printf("Path: %s\n", filePath.c_str()); + + cmark_node *root_node = mdRender.parseFile(filePath); + if (root_node != NULL) { + htmlOutput = mdRender.renderHTML(root_node); + myOutput = mdRender.renderMyLayout(root_node); + + cmark_node_free(root_node); + } QApplication app(argc, argv); MainWindow window; - window.setOutput(output); + window.setOutputToTextEdit(QString::fromStdString(htmlOutput)); + window.drawOutputToScene(QString::fromStdString(myOutput)); window.show(); return app.exec(); } diff --git a/src/mainwindow.cc b/src/mainwindow.cc index b659b35..bb5b4a1 100644 --- a/src/mainwindow.cc +++ b/src/mainwindow.cc @@ -1,4 +1,5 @@ #include "mainwindow.h" +#include "scene.h" #include #include @@ -6,6 +7,9 @@ #include #include #include +#include +#include +#include MainWindow::MainWindow() { @@ -13,7 +17,8 @@ MainWindow::MainWindow() setWindowTitle("Browser"); QMenu *fileMenu = new QMenu("File"); - fileMenu->addAction("New"); + fileMenu->addAction("Open..."); + fileMenu->addAction("New..."); fileMenu->addAction("Exit"); menuBar()->addMenu(fileMenu); @@ -23,6 +28,13 @@ MainWindow::MainWindow() QVBoxLayout *layout = new QVBoxLayout(centralWidget); layout->setContentsMargins(5, 5, 5, 5); + scene = new Scene(); + scene->setSceneRect(QRectF(0, 0, 200, 180)); + view = new QGraphicsView(scene); + //view->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + view->setAlignment(Qt::Alignment::enum_type::AlignLeft); + layout->addWidget(view); + // We will not use TextEdit, it does only support HTML (and markdown, but we don't want to use the built-in parser). // Instead, we can try QPainter in Qt or use a 2D engine (using ttf, glyphs atlas, render bitmap text). textEdit = new QTextEdit(); @@ -30,7 +42,36 @@ MainWindow::MainWindow() layout->addWidget(textEdit); } -void MainWindow::setOutput(const QString& text) +/** + * Can be used for resizing the scene +void MainWindow::resizeEvent(QResizeEvent *) { + QRectF bounds = scene->itemsBoundingRect(); + bounds.setWidth(bounds.width()*0.9); // to tighten-up margins + bounds.setHeight(bounds.height()*0.9); // same as above + view->fitInView(bounds, Qt::KeepAspectRatio); + view->centerOn(0, 0); +}*/ + +/** + * Example of adding text (plaintext or html) to text edit + */ +void MainWindow::setOutputToTextEdit(const QString& text) { textEdit->setHtml(text); } + +// TODO: Create a new Render class for converting AST and render it to the scene, by calculating the positions, etc. +// So the input parameter will be a root node, render the right Qt objects with their positions and settings, and drop in on the scene. +// Basically cmark parse and Qt are comming togther. +void MainWindow::drawOutputToScene(const QString& text) +{ + QGraphicsTextItem *textItem = new QGraphicsTextItem(text); + QFont font; + font.setBold(true); + font.setFamily("Open Sans"); // Arial + textItem->setFont(font); + textItem->setPos(10, 40); + textItem->setTextWidth(200); + + scene->addItem(textItem); +} diff --git a/src/mainwindow.h b/src/mainwindow.h index 808164b..b641fe0 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -6,6 +6,8 @@ QT_BEGIN_NAMESPACE class QAction; class QTextEdit; +class QGraphicsView; +class Scene; QT_END_NAMESPACE class MainWindow : public QMainWindow @@ -14,13 +16,18 @@ class MainWindow : public QMainWindow public: MainWindow(); - void setOutput(const QString& text); + void setOutputToTextEdit(const QString& text); + void drawOutputToScene(const QString& text); //private slots: // void newFile(); private: + QGraphicsView *view; + Scene *scene; QTextEdit *textEdit; + + // void resizeEvent(QResizeEvent *); }; #endif \ No newline at end of file diff --git a/src/markdown-render.cc b/src/markdown-render.cc index d93f2b8..d77319a 100644 --- a/src/markdown-render.cc +++ b/src/markdown-render.cc @@ -1,6 +1,5 @@ #include "markdown-render.h" -#include #include #include #include @@ -19,36 +18,8 @@ static inline void outc(cmark_renderer *renderer, cmark_node *node, } MarkdownRender::MarkdownRender(): - exePath(std::filesystem::current_path().string()), options(CMARK_OPT_DEFAULT) {} -/** - * Helper wrapper for testing/demo - */ -std::string const MarkdownRender::renderDemoFile() -{ - std::string output = ""; - std::string filePath = exePath.append("/../../test.md"); - printf("Path: %s\n", filePath.c_str()); - - cmark_node *root_node = parseFile(filePath); - if (root_node != NULL) { - output = renderHTML(root_node); - //output = renderMyLayout(root_node); - - cmark_node_free(root_node); - } - return output; -} - -/** - * This is a function that will make enabling extensions easier - */ -void MarkdownRender::addMarkdownExtension(cmark_parser *parser, const char *extName) { - cmark_syntax_extension *ext = cmark_find_syntax_extension(extName); - if ( ext ) - cmark_parser_attach_syntax_extension(parser, ext); -} /** * Parse markdown by file path @@ -90,6 +61,15 @@ std::string const MarkdownRender::renderMyLayout(cmark_node *node) return std::string(renderLayout(node, options, 0, NULL)); } +/** + * This is a function that will make enabling extensions easier + */ +void MarkdownRender::addMarkdownExtension(cmark_parser *parser, const char *extName) { + cmark_syntax_extension *ext = cmark_find_syntax_extension(extName); + if ( ext ) + cmark_parser_attach_syntax_extension(parser, ext); +} + char *MarkdownRender::renderLayout(cmark_node *root, int options, int width, cmark_llist *extensions) { return cmark_render(cmark_node_mem(root), root, options, width, outc, renderNode); diff --git a/src/markdown-render.h b/src/markdown-render.h index 754d9b6..e38a7ce 100644 --- a/src/markdown-render.h +++ b/src/markdown-render.h @@ -13,10 +13,7 @@ public: std::string const renderHTML(cmark_node *node); std::string const renderMyLayout(cmark_node *node); - std::string const renderDemoFile(); // As an example - private: - std::string exePath; int options; void addMarkdownExtension(cmark_parser *parser, const char *extName); diff --git a/src/scene.cc b/src/scene.cc new file mode 100644 index 0000000..df4cf4c --- /dev/null +++ b/src/scene.cc @@ -0,0 +1,7 @@ +#include "scene.h" + +Scene::Scene(QObject *parent) + : QGraphicsScene(parent) +{ + +} \ No newline at end of file diff --git a/src/scene.h b/src/scene.h new file mode 100644 index 0000000..215757e --- /dev/null +++ b/src/scene.h @@ -0,0 +1,17 @@ +#ifndef SCENE_H +#define SCENE_H + +#include + +class Scene : public QGraphicsScene +{ + Q_OBJECT + +public: + explicit Scene(QObject *parent = 0); + +private: + +}; + +#endif \ No newline at end of file