Working PoC with QGraphicsScene/View and QGraphicsTextItem

master
Melroy van den Berg 2020-11-16 05:46:05 +01:00
parent a893d416ab
commit e4f43c8501
10 changed files with 107 additions and 39 deletions

View File

@ -64,6 +64,8 @@
"cinttypes": "cpp",
"typeinfo": "cpp",
"variant": "cpp",
"bit": "cpp"
"bit": "cpp",
"qsizepolicy": "cpp",
"qgraphicsscene": "cpp"
}
}

View File

@ -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

View File

@ -30,6 +30,8 @@ set(SOURCES
markdown-render.h
mainwindow.cc
mainwindow.h
scene.h
scene.cc
)
if(ANDROID)

View File

@ -2,20 +2,33 @@
#include "markdown-render.h"
#include "mainwindow.h"
#include <filesystem>
#include <QApplication>
#include <QTextDocument>
#include <QString>
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();
}

View File

@ -1,4 +1,5 @@
#include "mainwindow.h"
#include "scene.h"
#include <QVBoxLayout>
#include <QMenuBar>
@ -6,6 +7,9 @@
#include <QWidget>
#include <QTextEdit>
#include <QSizePolicy>
#include <QGraphicsView>
#include <QRectF>
#include <QGraphicsTextItem>
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);
}

View File

@ -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

View File

@ -1,6 +1,5 @@
#include "markdown-render.h"
#include <filesystem>
#include <string>
#include <cmark-gfm-core-extensions.h>
#include <time.h>
@ -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);

View File

@ -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);

7
src/scene.cc Normal file
View File

@ -0,0 +1,7 @@
#include "scene.h"
Scene::Scene(QObject *parent)
: QGraphicsScene(parent)
{
}

17
src/scene.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef SCENE_H
#define SCENE_H
#include <QGraphicsScene>
class Scene : public QGraphicsScene
{
Q_OBJECT
public:
explicit Scene(QObject *parent = 0);
private:
};
#endif