diff --git a/CMakeLists.txt b/CMakeLists.txt index c57157526..d61376c5c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -119,6 +119,8 @@ add_library(${CORE_WIDGETS_ADDON} SHARED "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtWidgets/QButtonGroup/qbuttongroup_wrap.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtWidgets/QStatusBar/qstatusbar_wrap.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/core/FlexLayout/flexlayout_wrap.cpp" + "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtWidgets/QTextBrowser/qtextbrowser_wrap.cpp" + "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtWidgets/QTextEdit/qtextedit_wrap.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtWidgets/QStandardItemModel/qstandarditemmodel_wrap.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtWidgets/QStandardItem/qstandarditem_wrap.cpp" # Custom widgets (include them for automoc since they contain Q_OBJECT) @@ -177,6 +179,8 @@ add_library(${CORE_WIDGETS_ADDON} SHARED "${PROJECT_SOURCE_DIR}/src/cpp/include/nodegui/QtWidgets/QButtonGroup/nbuttongroup.hpp" "${PROJECT_SOURCE_DIR}/src/cpp/include/nodegui/QtWidgets/QStatusBar/nstatusbar.hpp" "${PROJECT_SOURCE_DIR}/src/cpp/include/nodegui/QtWidgets/QStandardItemModel/nstandarditemmodel.hpp" + "${PROJECT_SOURCE_DIR}/src/cpp/include/nodegui/QtWidgets/QTextBrowser/ntextbrowser.hpp" + "${PROJECT_SOURCE_DIR}/src/cpp/include/nodegui/QtWidgets/QTextEdit/ntextedit.hpp" ) AddCommonConfig(${CORE_WIDGETS_ADDON}) diff --git a/src/cpp/include/nodegui/QtWidgets/QTextBrowser/ntextbrowser.hpp b/src/cpp/include/nodegui/QtWidgets/QTextBrowser/ntextbrowser.hpp new file mode 100644 index 000000000..5da65e15a --- /dev/null +++ b/src/cpp/include/nodegui/QtWidgets/QTextBrowser/ntextbrowser.hpp @@ -0,0 +1,63 @@ +#pragma once + +#include + +#include "Extras/Export/export.h" +#include "QtCore/QUrl/qurl_wrap.h" +#include "QtWidgets/QTextEdit/qtextedit_macro.h" +#include "core/NodeWidget/nodewidget.h" + +class DLL_EXPORT NTextBrowser : public QTextBrowser, public NodeWidget { + Q_OBJECT + NODEWIDGET_IMPLEMENTATIONS(QTextBrowser) + public: + using QTextBrowser::QTextBrowser; // inherit all constructors of QTextBrowser + + void connectSignalsToEventEmitter() { + QTEXTEDIT_SIGNALS + // Qt Connects: Implement all signal connects here + QObject::connect(this, &QTextBrowser::anchorClicked, [=](const QUrl& link) { + Napi::Env env = this->emitOnNode.Env(); + Napi::HandleScope scope(env); + auto instance = QUrlWrap::constructor.New( + {Napi::External::New(env, new QUrl(link))}); + this->emitOnNode.Call( + {Napi::String::New(env, "anchorClicked"), instance}); + }); + QObject::connect( + this, &QTextBrowser::backwardAvailable, [=](bool available) { + Napi::Env env = this->emitOnNode.Env(); + Napi::HandleScope scope(env); + this->emitOnNode.Call({Napi::String::New(env, "backwardAvailable"), + Napi::Boolean::New(env, available)}); + }); + QObject::connect( + this, &QTextBrowser::forwardAvailable, [=](bool available) { + Napi::Env env = this->emitOnNode.Env(); + Napi::HandleScope scope(env); + this->emitOnNode.Call({Napi::String::New(env, "forwardAvailable"), + Napi::Boolean::New(env, available)}); + }); + QObject::connect( + this, QOverload::of(&QTextBrowser::highlighted), + [=](const QString& link) { + Napi::Env env = this->emitOnNode.Env(); + Napi::HandleScope scope(env); + this->emitOnNode.Call({Napi::String::New(env, "highlighted"), + Napi::String::New(env, link.toStdString())}); + }); + QObject::connect(this, &QTextBrowser::historyChanged, [=]() { + Napi::Env env = this->emitOnNode.Env(); + Napi::HandleScope scope(env); + this->emitOnNode.Call({Napi::String::New(env, "historyChanged")}); + }); + QObject::connect(this, &QTextBrowser::sourceChanged, [=](const QUrl& src) { + Napi::Env env = this->emitOnNode.Env(); + Napi::HandleScope scope(env); + auto instance = QUrlWrap::constructor.New( + {Napi::External::New(env, new QUrl(src))}); + this->emitOnNode.Call( + {Napi::String::New(env, "sourceChanged"), instance}); + }); + } +}; diff --git a/src/cpp/include/nodegui/QtWidgets/QTextBrowser/qtextbrowser_wrap.h b/src/cpp/include/nodegui/QtWidgets/QTextBrowser/qtextbrowser_wrap.h new file mode 100644 index 000000000..e72eabddf --- /dev/null +++ b/src/cpp/include/nodegui/QtWidgets/QTextBrowser/qtextbrowser_wrap.h @@ -0,0 +1,35 @@ +#pragma once + +#include + +#include + +#include "Extras/Export/export.h" +#include "QtWidgets/QTextEdit/qtextedit_macro.h" +#include "ntextbrowser.hpp" + +class DLL_EXPORT QTextBrowserWrap : public Napi::ObjectWrap { + QTEXTEDIT_WRAPPED_METHODS_DECLARATION + private: + QPointer instance; + + public: + static Napi::Object init(Napi::Env env, Napi::Object exports); + QTextBrowserWrap(const Napi::CallbackInfo& info); + ~QTextBrowserWrap(); + NTextBrowser* getInternalInstance(); + // class constructor + static Napi::FunctionReference constructor; + // wrapped methods + Napi::Value backwardHistoryCount(const Napi::CallbackInfo& info); + Napi::Value clearHistory(const Napi::CallbackInfo& info); + Napi::Value forwardHistoryCount(const Napi::CallbackInfo& info); + Napi::Value historyTitle(const Napi::CallbackInfo& info); + Napi::Value historyUrl(const Napi::CallbackInfo& info); + Napi::Value isBackwardAvailable(const Napi::CallbackInfo& info); + Napi::Value isForwardAvailable(const Napi::CallbackInfo& info); + Napi::Value backward(const Napi::CallbackInfo& info); + Napi::Value forward(const Napi::CallbackInfo& info); + Napi::Value home(const Napi::CallbackInfo& info); + Napi::Value reload(const Napi::CallbackInfo& info); +}; diff --git a/src/cpp/include/nodegui/QtWidgets/QTextEdit/ntextedit.hpp b/src/cpp/include/nodegui/QtWidgets/QTextEdit/ntextedit.hpp new file mode 100644 index 000000000..3587a0cac --- /dev/null +++ b/src/cpp/include/nodegui/QtWidgets/QTextEdit/ntextedit.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include + +#include "Extras/Export/export.h" +#include "QtWidgets/QTextEdit/qtextedit_macro.h" +#include "core/NodeWidget/nodewidget.h" + +class DLL_EXPORT NTextEdit : public QTextEdit, public NodeWidget { + Q_OBJECT + NODEWIDGET_IMPLEMENTATIONS(QTextEdit) + public: + using QTextEdit::QTextEdit; // inherit all constructors of QTextEdit + + void connectSignalsToEventEmitter() { + QTEXTEDIT_SIGNALS + // Qt Connects: Implement all signal connects here + } +}; diff --git a/src/cpp/include/nodegui/QtWidgets/QTextEdit/qtextedit_macro.h b/src/cpp/include/nodegui/QtWidgets/QTextEdit/qtextedit_macro.h new file mode 100644 index 000000000..eafdf0d4a --- /dev/null +++ b/src/cpp/include/nodegui/QtWidgets/QTextEdit/qtextedit_macro.h @@ -0,0 +1,312 @@ +#pragma once + +#include + +#include "QtGui/QColor/qcolor_wrap.h" +#include "QtGui/QFont/qfont_wrap.h" +#include "QtWidgets/QAbstractScrollArea/qabstractscrollarea_macro.h" + +/* + + This macro adds common QTextEdit exported methods + The exported methods are taken into this macro to avoid writing them in each + and every widget we export. + */ + +#ifndef QTEXTEDIT_WRAPPED_METHODS_DECLARATION +#define QTEXTEDIT_WRAPPED_METHODS_DECLARATION \ + \ + QABSTRACTSCROLLAREA_WRAPPED_METHODS_DECLARATION \ + \ + Napi::Value setAlignment(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + int alignment = info[0].As().Int32Value(); \ + this->instance->setAlignment(static_cast(alignment)); \ + return env.Null(); \ + } \ + Napi::Value alignment(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + Qt::Alignment alignment = this->instance->alignment(); \ + return Napi::Number::New(env, static_cast(alignment)); \ + } \ + Napi::Value canPaste(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + return Napi::Boolean::New(env, this->instance->canPaste()); \ + } \ + Napi::Value ensureCursorVisible(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + this->instance->ensureCursorVisible(); \ + return env.Null(); \ + } \ + Napi::Value setFontFamily(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + std::string family = info[0].As().Utf8Value(); \ + this->instance->setFontFamily(QString::fromUtf8(family.c_str())); \ + return env.Null(); \ + } \ + Napi::Value fontFamily(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + QString family = this->instance->fontFamily(); \ + return Napi::String::New(env, family.toStdString()); \ + } \ + Napi::Value setFontItalic(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + bool italic = info[0].As().Value(); \ + this->instance->setFontItalic(italic); \ + return env.Null(); \ + } \ + Napi::Value fontItalic(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + return Napi::Boolean::New(env, this->instance->fontItalic()); \ + } \ + Napi::Value setFontPointSize(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + double s = info[0].As().DoubleValue(); \ + this->instance->setFontPointSize(s); \ + return env.Null(); \ + } \ + Napi::Value fontPointSize(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + return Napi::Number::New(env, this->instance->fontPointSize()); \ + } \ + Napi::Value setFontUnderline(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + bool underline = info[0].As().Value(); \ + this->instance->setFontUnderline(underline); \ + return env.Null(); \ + } \ + Napi::Value fontUnderline(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + return Napi::Boolean::New(env, this->instance->fontUnderline()); \ + } \ + Napi::Value setFontWeight(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + int weight = info[0].As().Int32Value(); \ + this->instance->setFontWeight(weight); \ + return env.Null(); \ + } \ + Napi::Value fontWeight(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + return Napi::Number::New(env, this->instance->fontWeight()); \ + } \ + Napi::Value append(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + std::string text = info[0].As().Utf8Value(); \ + this->instance->append(QString::fromUtf8(text.c_str())); \ + return env.Null(); \ + } \ + Napi::Value clear(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + this->instance->clear(); \ + return env.Null(); \ + } \ + Napi::Value copy(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + this->instance->copy(); \ + return env.Null(); \ + } \ + Napi::Value cut(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + this->instance->cut(); \ + return env.Null(); \ + } \ + Napi::Value insertHtml(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + std::string text = info[0].As().Utf8Value(); \ + this->instance->insertHtml(QString::fromUtf8(text.c_str())); \ + return env.Null(); \ + } \ + Napi::Value insertPlainText(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + std::string text = info[0].As().Utf8Value(); \ + this->instance->insertPlainText(QString::fromUtf8(text.c_str())); \ + return env.Null(); \ + } \ + Napi::Value paste(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + this->instance->paste(); \ + return env.Null(); \ + } \ + Napi::Value redo(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + this->instance->redo(); \ + return env.Null(); \ + } \ + Napi::Value scrollToAnchor(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + std::string name = info[0].As().Utf8Value(); \ + this->instance->scrollToAnchor(QString::fromUtf8(name.c_str())); \ + return env.Null(); \ + } \ + Napi::Value selectAll(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + this->instance->selectAll(); \ + return env.Null(); \ + } \ + Napi::Value setCurrentFont(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + Napi::Object fontObject = info[0].As(); \ + QFontWrap* fontWrap = Napi::ObjectWrap::Unwrap(fontObject); \ + this->instance->setCurrentFont(*fontWrap->getInternalInstance()); \ + return env.Null(); \ + } \ + Napi::Value currentFont(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + QFont font = this->instance->currentFont(); \ + auto instance = QFontWrap::constructor.New( \ + {Napi::External::New(env, new QFont(font))}); \ + return instance; \ + } \ + Napi::Value setText(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + std::string text = info[0].As().Utf8Value(); \ + this->instance->setText(QString::fromUtf8(text.c_str())); \ + return env.Null(); \ + } \ + Napi::Value setTextBackgroundColor(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + Napi::Object colorObject = info[0].As(); \ + QColorWrap* colorWrap = Napi::ObjectWrap::Unwrap(colorObject); \ + this->instance->setTextBackgroundColor(*colorWrap->getInternalInstance()); \ + return env.Null(); \ + } \ + Napi::Value setTextColor(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + Napi::Object colorObject = info[0].As(); \ + QColorWrap* colorWrap = Napi::ObjectWrap::Unwrap(colorObject); \ + this->instance->setTextColor(*colorWrap->getInternalInstance()); \ + return env.Null(); \ + } \ + Napi::Value undo(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + this->instance->undo(); \ + return env.Null(); \ + } \ + Napi::Value zoomIn(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + int range = info[0].As().Int32Value(); \ + this->instance->zoomIn(range); \ + return env.Null(); \ + } \ + Napi::Value zoomOut(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + int range = info[0].As().Int32Value(); \ + this->instance->zoomOut(range); \ + return env.Null(); \ + } + +#endif // QTEXTEDIT_WRAPPED_METHODS_DECLARATION + +#ifndef QTEXTEDIT_WRAPPED_METHODS_EXPORT_DEFINE +#define QTEXTEDIT_WRAPPED_METHODS_EXPORT_DEFINE(WidgetWrapName) \ + \ + QABSTRACTSCROLLAREA_WRAPPED_METHODS_EXPORT_DEFINE(WidgetWrapName) \ + \ + InstanceMethod("setAlignment", &WidgetWrapName::setAlignment), \ + InstanceMethod("alignment", &WidgetWrapName::alignment), \ + InstanceMethod("canPaste", &WidgetWrapName::canPaste), \ + InstanceMethod("setCurrentFont", &WidgetWrapName::setCurrentFont), \ + InstanceMethod("currentFont", &WidgetWrapName::currentFont), \ + InstanceMethod("ensureCursorVisible", \ + &WidgetWrapName::ensureCursorVisible), \ + InstanceMethod("setFontFamily", &WidgetWrapName::setFontFamily), \ + InstanceMethod("fontFamily", &WidgetWrapName::fontFamily), \ + InstanceMethod("setFontItalic", &WidgetWrapName::setFontItalic), \ + InstanceMethod("fontItalic", &WidgetWrapName::fontItalic), \ + InstanceMethod("setFontPointSize", &WidgetWrapName::setFontPointSize), \ + InstanceMethod("fontPointSize", &WidgetWrapName::fontPointSize), \ + InstanceMethod("setFontUnderline", &WidgetWrapName::setFontUnderline), \ + InstanceMethod("fontUnderline", &WidgetWrapName::fontUnderline), \ + InstanceMethod("setFontWeight", &WidgetWrapName::setFontWeight), \ + InstanceMethod("fontWeight", &WidgetWrapName::fontWeight), \ + InstanceMethod("append", &WidgetWrapName::append), \ + InstanceMethod("clear", &WidgetWrapName::clear), \ + InstanceMethod("copy", &WidgetWrapName::copy), \ + InstanceMethod("cut", &WidgetWrapName::cut), \ + InstanceMethod("insertHtml", &WidgetWrapName::insertHtml), \ + InstanceMethod("insertPlainText", &WidgetWrapName::insertPlainText), \ + InstanceMethod("paste", &WidgetWrapName::paste), \ + InstanceMethod("redo", &WidgetWrapName::redo), \ + InstanceMethod("scrollToAnchor", &WidgetWrapName::scrollToAnchor), \ + InstanceMethod("selectAll", &WidgetWrapName::selectAll), \ + InstanceMethod("setText", &WidgetWrapName::setText), \ + InstanceMethod("setTextBackgroundColor", \ + &WidgetWrapName::setTextBackgroundColor), \ + InstanceMethod("setTextColor", &WidgetWrapName::setTextColor), \ + InstanceMethod("zoomIn", &WidgetWrapName::zoomIn), \ + InstanceMethod("zoomOut", &WidgetWrapName::zoomOut), + +#endif // QTEXTEDIT_WRAPPED_METHODS_EXPORT_DEFINE + +#ifndef QTEXTEDIT_SIGNALS +#define QTEXTEDIT_SIGNALS \ + \ + QABSTRACTSCROLLAREA_SIGNALS \ + \ + QObject::connect(this, &QTextEdit::copyAvailable, [=](bool yes) { \ + Napi::Env env = this->emitOnNode.Env(); \ + Napi::HandleScope scope(env); \ + this->emitOnNode.Call({Napi::String::New(env, "copyAvailable"), \ + Napi::Boolean::New(env, yes)}); \ + }); \ + QObject::connect(this, &QTextEdit::cursorPositionChanged, [=]() { \ + Napi::Env env = this->emitOnNode.Env(); \ + Napi::HandleScope scope(env); \ + this->emitOnNode.Call({Napi::String::New(env, "cursorPositionChanged")}); \ + }); \ + QObject::connect(this, &QTextEdit::redoAvailable, [=](bool available) { \ + Napi::Env env = this->emitOnNode.Env(); \ + Napi::HandleScope scope(env); \ + this->emitOnNode.Call({Napi::String::New(env, "redoAvailable"), \ + Napi::Boolean::New(env, available)}); \ + }); \ + QObject::connect(this, &QTextEdit::selectionChanged, [=]() { \ + Napi::Env env = this->emitOnNode.Env(); \ + Napi::HandleScope scope(env); \ + this->emitOnNode.Call({Napi::String::New(env, "selectionChanged")}); \ + }); \ + QObject::connect(this, &QTextEdit::textChanged, [=]() { \ + Napi::Env env = this->emitOnNode.Env(); \ + Napi::HandleScope scope(env); \ + this->emitOnNode.Call({Napi::String::New(env, "textChanged")}); \ + }); \ + QObject::connect(this, &QTextEdit::undoAvailable, [=](bool available) { \ + Napi::Env env = this->emitOnNode.Env(); \ + Napi::HandleScope scope(env); \ + this->emitOnNode.Call({Napi::String::New(env, "undoAvailable"), \ + Napi::Boolean::New(env, available)}); \ + }); + +#endif // QTEXTEDIT_SIGNALS diff --git a/src/cpp/include/nodegui/QtWidgets/QTextEdit/qtextedit_wrap.h b/src/cpp/include/nodegui/QtWidgets/QTextEdit/qtextedit_wrap.h new file mode 100644 index 000000000..a6173e4f6 --- /dev/null +++ b/src/cpp/include/nodegui/QtWidgets/QTextEdit/qtextedit_wrap.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +#include + +#include "Extras/Export/export.h" +#include "QtWidgets/QTextEdit/qtextedit_macro.h" +#include "ntextedit.hpp" + +class DLL_EXPORT QTextEditWrap : public Napi::ObjectWrap { + QTEXTEDIT_WRAPPED_METHODS_DECLARATION + private: + QPointer instance; + + public: + static Napi::Object init(Napi::Env env, Napi::Object exports); + QTextEditWrap(const Napi::CallbackInfo& info); + ~QTextEditWrap(); + NTextEdit* getInternalInstance(); + // class constructor + static Napi::FunctionReference constructor; + // wrapped methods +}; diff --git a/src/cpp/lib/QtWidgets/QTextBrowser/qtextbrowser_wrap.cpp b/src/cpp/lib/QtWidgets/QTextBrowser/qtextbrowser_wrap.cpp new file mode 100644 index 000000000..3f453f1bd --- /dev/null +++ b/src/cpp/lib/QtWidgets/QTextBrowser/qtextbrowser_wrap.cpp @@ -0,0 +1,153 @@ +#include "QtWidgets/QTextBrowser/qtextbrowser_wrap.h" + +#include + +#include "Extras/Utils/nutils.h" +#include "QtWidgets/QWidget/qwidget_wrap.h" + +Napi::FunctionReference QTextBrowserWrap::constructor; + +Napi::Object QTextBrowserWrap::init(Napi::Env env, Napi::Object exports) { + Napi::HandleScope scope(env); + char CLASSNAME[] = "QTextBrowser"; + Napi::Function func = DefineClass( + env, CLASSNAME, + {InstanceMethod("backwardHistoryCount", + &QTextBrowserWrap::backwardHistoryCount), + InstanceMethod("clearHistory", &QTextBrowserWrap::clearHistory), + InstanceMethod("forwardHistoryCount", + &QTextBrowserWrap::forwardHistoryCount), + InstanceMethod("historyTitle", &QTextBrowserWrap::historyTitle), + InstanceMethod("historyUrl", &QTextBrowserWrap::historyUrl), + InstanceMethod("isBackwardAvailable", + &QTextBrowserWrap::isBackwardAvailable), + InstanceMethod("isForwardAvailable", + &QTextBrowserWrap::isForwardAvailable), + InstanceMethod("backward", &QTextBrowserWrap::backward), + InstanceMethod("forward", &QTextBrowserWrap::forward), + InstanceMethod("home", &QTextBrowserWrap::home), + InstanceMethod("reload", &QTextBrowserWrap::reload), + QTEXTEDIT_WRAPPED_METHODS_EXPORT_DEFINE(QTextBrowserWrap)}); + constructor = Napi::Persistent(func); + exports.Set(CLASSNAME, func); + return exports; +} + +NTextBrowser* QTextBrowserWrap::getInternalInstance() { return this->instance; } + +QTextBrowserWrap::QTextBrowserWrap(const Napi::CallbackInfo& info) + : Napi::ObjectWrap(info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + if (info.Length() == 1) { + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NTextBrowser(parentWidgetWrap->getInternalInstance()); + } else if (info.Length() == 0) { + this->instance = new NTextBrowser(); + } else { + Napi::TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + } + this->rawData = extrautils::configureQWidget( + this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), + true); +} + +QTextBrowserWrap::~QTextBrowserWrap() { + extrautils::safeDelete(this->instance); +} + +Napi::Value QTextBrowserWrap::backwardHistoryCount( + const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + return Napi::Number::New(env, this->instance->backwardHistoryCount()); +} + +Napi::Value QTextBrowserWrap::clearHistory(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + this->instance->clearHistory(); + return env.Null(); +} + +Napi::Value QTextBrowserWrap::forwardHistoryCount( + const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + return Napi::Number::New(env, this->instance->forwardHistoryCount()); +} + +Napi::Value QTextBrowserWrap::historyTitle(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + int i = info[0].As().Int32Value(); + QString title = this->instance->historyTitle(i); + return Napi::String::New(env, title.toStdString()); +} + +Napi::Value QTextBrowserWrap::historyUrl(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + int i = info[0].As().Int32Value(); + QUrl url = this->instance->historyUrl(i); + auto instance = QUrlWrap::constructor.New( + {Napi::External::New(env, new QUrl(url))}); + return instance; +} + +Napi::Value QTextBrowserWrap::isBackwardAvailable( + const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + return Napi::Boolean::New(env, this->instance->isBackwardAvailable()); +} + +Napi::Value QTextBrowserWrap::isForwardAvailable( + const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + return Napi::Boolean::New(env, this->instance->isForwardAvailable()); +} + +Napi::Value QTextBrowserWrap::backward(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + this->instance->backward(); + return env.Null(); +} + +Napi::Value QTextBrowserWrap::forward(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + this->instance->forward(); + return env.Null(); +} + +Napi::Value QTextBrowserWrap::home(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + this->instance->home(); + return env.Null(); +} + +Napi::Value QTextBrowserWrap::reload(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + this->instance->reload(); + return env.Null(); +} diff --git a/src/cpp/lib/QtWidgets/QTextEdit/qtextedit_wrap.cpp b/src/cpp/lib/QtWidgets/QTextEdit/qtextedit_wrap.cpp new file mode 100644 index 000000000..38868c93a --- /dev/null +++ b/src/cpp/lib/QtWidgets/QTextEdit/qtextedit_wrap.cpp @@ -0,0 +1,43 @@ +#include "QtWidgets/QTextEdit/qtextedit_wrap.h" + +#include + +#include "Extras/Utils/nutils.h" +#include "QtWidgets/QWidget/qwidget_wrap.h" + +Napi::FunctionReference QTextEditWrap::constructor; + +Napi::Object QTextEditWrap::init(Napi::Env env, Napi::Object exports) { + Napi::HandleScope scope(env); + char CLASSNAME[] = "QTextEdit"; + Napi::Function func = DefineClass( + env, CLASSNAME, {QTEXTEDIT_WRAPPED_METHODS_EXPORT_DEFINE(QTextEditWrap)}); + constructor = Napi::Persistent(func); + exports.Set(CLASSNAME, func); + return exports; +} + +NTextEdit* QTextEditWrap::getInternalInstance() { return this->instance; } + +QTextEditWrap::QTextEditWrap(const Napi::CallbackInfo& info) + : Napi::ObjectWrap(info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + if (info.Length() == 1) { + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NTextEdit(parentWidgetWrap->getInternalInstance()); + } else if (info.Length() == 0) { + this->instance = new NTextEdit(); + } else { + Napi::TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + } + this->rawData = extrautils::configureQWidget( + this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), + true); +} + +QTextEditWrap::~QTextEditWrap() { extrautils::safeDelete(this->instance); } diff --git a/src/cpp/main.cpp b/src/cpp/main.cpp index b208769fe..f0bf4f872 100644 --- a/src/cpp/main.cpp +++ b/src/cpp/main.cpp @@ -78,6 +78,8 @@ #include "QtWidgets/QTableView/qtableview_wrap.h" #include "QtWidgets/QTableWidget/qtablewidget_wrap.h" #include "QtWidgets/QTableWidgetItem/qtablewidgetitem_wrap.h" +#include "QtWidgets/QTextBrowser/qtextbrowser_wrap.h" +#include "QtWidgets/QTextEdit/qtextedit_wrap.h" #include "QtWidgets/QTimeEdit/qtimeedit_wrap.h" #include "QtWidgets/QToolButton/qtoolbutton_wrap.h" #include "QtWidgets/QTreeWidget/qtreewidget_wrap.h" @@ -170,6 +172,8 @@ Napi::Object Main(Napi::Env env, Napi::Object exports) { QMessageBoxWrap::init(env, exports); QInputDialogWrap::init(env, exports); QSliderWrap::init(env, exports); + QTextBrowserWrap::init(env, exports); + QTextEditWrap::init(env, exports); QTimeEditWrap::init(env, exports); QButtonGroupWrap::init(env, exports); QStatusBarWrap::init(env, exports); diff --git a/src/demo.ts b/src/demo.ts index 07677383e..d04feb7d7 100644 --- a/src/demo.ts +++ b/src/demo.ts @@ -1,6 +1,5 @@ import { QFileDialog, DialogCode, FileMode } from './index'; - const fileDialog = new QFileDialog(); fileDialog.setFileMode(FileMode.AnyFile); fileDialog.setNameFilter('All files (*.*)'); diff --git a/src/index.ts b/src/index.ts index cb7fe868a..b9f50414e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -101,6 +101,14 @@ export { QGroupBox, QGroupBoxSignals } from './lib/QtWidgets/QGroupBox'; export { QStatusBar, QStatusBarSignals } from './lib/QtWidgets/QStatusBar'; export { QStandardItemModel, QStandardItemModelSignals } from './lib/QtWidgets/QStandardItemModel'; export { QStandardItem } from './lib/QtWidgets/QStandardItem'; +export { QTextBrowser, QTextBrowserSignals } from './lib/QtWidgets/QTextBrowser'; +export { + QTextEdit, + QTextEditSignals, + AutoFormattingFlag, + QTextEditLineWrapMode, + WrapMode, +} from './lib/QtWidgets/QTextEdit'; // Core export { QDate } from './lib/QtCore/QDate'; export { QDateTime } from './lib/QtCore/QDateTime'; diff --git a/src/lib/QtEnums/index.ts b/src/lib/QtEnums/index.ts index 5124dcda6..17ef56a37 100644 --- a/src/lib/QtEnums/index.ts +++ b/src/lib/QtEnums/index.ts @@ -88,4 +88,4 @@ export { WindowModality } from './WindowModality'; export { WindowState } from './WindowState'; export { WindowType } from './WindowType'; export { PenStyle } from './PenStyle'; -export { DialogCode } from './DialogCode'; \ No newline at end of file +export { DialogCode } from './DialogCode'; diff --git a/src/lib/QtWidgets/QTextBrowser.ts b/src/lib/QtWidgets/QTextBrowser.ts new file mode 100644 index 000000000..35a10ae3e --- /dev/null +++ b/src/lib/QtWidgets/QTextBrowser.ts @@ -0,0 +1,100 @@ +import addon from '../utils/addon'; +import { NodeWidget } from './QWidget'; +import { NativeElement } from '../core/Component'; +import { QUrl } from '../QtCore/QUrl'; +import { NodeTextEdit, QTextEditSignals } from './QTextEdit'; + +/** + +> Create and control text browser. + +* **This class is a JS wrapper around Qt's [QTextBrowser class](https://doc.qt.io/qt-5/qtextbrowser.html)** + +A `QTextBrowser` provides ability to add and manipulate native text browser widgets. + +### Example + +```javascript +const { QTextBrowser } = require("@nodegui/nodegui"); + +const textBrowser = new QTextBrowser(); +``` + + */ +export class QTextBrowser extends NodeTextEdit { + native: NativeElement; + constructor(); + constructor(parent: NodeWidget); + constructor(parent?: NodeWidget) { + let native; + if (parent) { + native = new addon.QTextBrowser(parent.native); + } else { + native = new addon.QTextBrowser(); + } + super(native); + this.native = native; + parent && this.setNodeParent(parent); + } + setOpenExternalLinks(open: boolean): void { + this.setProperty('openExternalLinks', open); + } + openExternalLinks(): boolean { + return this.property('openExternalLinks').toBool(); + } + setOpenLinks(open: boolean): void { + this.setProperty('openLinks', open); + } + openLinks(): boolean { + return this.property('openLinks').toBool(); + } + setSource(name: QUrl): void { + this.setProperty('source', name.native); + } + source(): QUrl { + const name = this.property('source'); + return QUrl.fromQVariant(name); + } + backwardHistoryCount(): number { + return this.native.backwardHistoryCount(); + } + clearHistory(): void { + this.native.clearHistory(); + } + forwardHistoryCount(): number { + return this.native.forwardHistoryCount(); + } + historyTitle(i: number): string { + return this.native.historyTitle(i); + } + historyUrl(): QUrl { + return new QUrl(this.native.historyUrl()); + } + isBackwardAvailable(): boolean { + return this.native.isBackwardAvailable(); + } + isForwardAvailable(): boolean { + return this.native.isForwardAvailable(); + } + backward(): void { + this.native.backward(); + } + forward(): void { + this.native.forward(); + } + home(): void { + this.native.home(); + } + reload(): void { + this.native.reload(); + } +} + +export interface QTextBrowserSignals extends QTextEditSignals { + anchorClicked: (link: QUrl) => void; + backwardAvailable: (available: boolean) => void; + forwardAvailable: (available: boolean) => void; + highlighted: (link: string) => void; + historyChanged: () => void; + sourceChanged: (src: QUrl) => void; +} diff --git a/src/lib/QtWidgets/QTextEdit.ts b/src/lib/QtWidgets/QTextEdit.ts new file mode 100644 index 000000000..e014bdb51 --- /dev/null +++ b/src/lib/QtWidgets/QTextEdit.ts @@ -0,0 +1,266 @@ +import addon from '../utils/addon'; +import { NodeWidget } from './QWidget'; +import { NativeElement } from '../core/Component'; +import { QAbstractScrollArea, QAbstractScrollAreaSignals } from './QAbstractScrollArea'; +import { AlignmentFlag, TextInteractionFlag } from '../QtEnums'; +import { QFont } from '../QtGui/QFont'; +import { QColor } from '../QtGui/QColor'; + +/** + +> Create and control editable text field. + +* **This class is a JS wrapper around Qt's [QTextEdit class](https://doc.qt.io/qt-5/qtextedit.html)** + +A `QTextEdit` provides ability to add and manipulate native editable text field widgets. + +### Example + +```javascript +const { QTextEdit } = require("@nodegui/nodegui"); + +const textEdit = new QTextEdit(); +``` + + */ +export abstract class NodeTextEdit extends QAbstractScrollArea { + setAcceptRichText(accept: boolean): void { + this.setProperty('acceptRichText', accept); + } + acceptRichText(): boolean { + return this.property('acceptRichText').toBool(); + } + setAutoFormatting(features: AutoFormattingFlag): void { + this.setProperty('autoFormatting', features); + } + autoFormatting(): AutoFormattingFlag { + return this.property('autoFormatting').toInt(); + } + setCursorWidth(width: number): void { + this.setProperty('cursorWidth', width); + } + cursorWidth(): number { + return this.property('cursorWidth').toInt(); + } + setDocumentTitle(title: string): void { + this.setProperty('documentTitle', title); + } + documentTitle(): string { + return this.property('documentTitle').toString(); + } + setHtml(text: string): void { + this.setProperty('html', text); + } + toHtml(): string { + return this.property('html').toString(); + } + setLineWrapColumnOrWidth(w: number): void { + this.setProperty('lineWrapColumnOrWidth', w); + } + lineWrapColumnOrWidth(): number { + return this.property('lineWrapColumnOrWidth').toInt(); + } + setLineWrapMode(mode: QTextEditLineWrapMode): void { + this.setProperty('lineWrapMode', mode); + } + lineWrapMode(): QTextEditLineWrapMode { + return this.property('lineWrapMode').toInt(); + } + setOverwriteMode(overwrite: boolean): void { + this.setProperty('overwriteMode', overwrite); + } + overwriteMode(): boolean { + return this.property('overwriteMode').toBool(); + } + setPlaceholderText(placeholderText: string): void { + this.setProperty('placeholderText', placeholderText); + } + placeholderText(): string { + return this.property('placeholderText').toString(); + } + setPlainText(text: string): void { + this.setProperty('plainText', text); + } + toPlainText(): string { + return this.property('plainText').toString(); + } + setReadOnly(ro: boolean): void { + this.setProperty('readOnly', ro); + } + isReadOnly(): boolean { + return this.property('readOnly').toBool(); + } + setTabChangesFocus(b: boolean): void { + this.setProperty('tabChangesFocus', b); + } + tabChangesFocus(): boolean { + return this.property('tabChangesFocus').toBool(); + } + setTabStopDistance(distance: number): void { + this.setProperty('tabStopDistance', distance); + } + tabStopDistance(): number { + return this.property('tabStopDistance').toDouble(); + } + setTextInteractionFlags(flags: TextInteractionFlag): void { + this.setProperty('textInteractionFlags', flags); + } + textInteractionFlags(): TextInteractionFlag { + return this.property('textInteractionFlags').toInt(); + } + setUndoRedoEnabled(enable: boolean): void { + this.setProperty('undoRedoEnabled', enable); + } + isUndoRedoEnabled(): boolean { + return this.property('undoRedoEnabled').toBool(); + } + setWordWrapMode(policy: WrapMode): void { + this.setProperty('wordWrapMode', policy); + } + wordWrapMode(): WrapMode { + return this.property('wordWrapMode').toInt(); + } + setAlignment(alignment: AlignmentFlag): void { + this.native.setAlignment(alignment); + } + alignment(): AlignmentFlag { + return this.native.alignment(); + } + canPaste(): boolean { + return this.native.canPaste(); + } + setCurrentFont(f: QFont): void { + this.native.setCurrentFont(f.native); + } + currentFont(): QFont { + return new QFont(this.native.currentFont()); + } + ensureCursorVisible(): void { + this.native.ensureCursorVisible(); + } + setFontFamily(family: string): void { + this.native.setFontFamily(family); + } + fontFamily(): string { + return this.native.fontFamily(); + } + setFontItalic(italic: boolean): void { + this.native.setFontItalic(italic); + } + fontItalic(): boolean { + return this.native.fontItalic(); + } + setFontPointSize(s: number): void { + this.native.setFontPointSize(s); + } + fontPointSize(): number { + return this.native.fontPointSize(); + } + setFontUnderline(underline: boolean): void { + this.native.setFontUnderline(underline); + } + fontUnderline(): boolean { + return this.native.fontUnderline(); + } + setFontWeight(weight: number): void { + this.native.setFontWeight(weight); + } + fontWeight(): number { + return this.native.fontWeight(); + } + append(text: string): void { + this.native.append(text); + } + clear(): void { + this.native.clear(); + } + copy(): void { + this.native.copy(); + } + cut(): void { + this.native.cut(); + } + insertHtml(text: string): void { + this.native.insertHtml(text); + } + insertPlainText(text: string): void { + this.native.insertPlainText(text); + } + paste(): void { + this.native.paste(); + } + redo(): void { + this.native.redo(); + } + scrollToAnchor(name: string): void { + this.native.scrollToAnchor(name); + } + selectAll(): void { + this.native.selectAll(); + } + setText(text: string): void { + this.native.setText(text); + } + setTextBackgroundColor(color: QColor): void { + this.native.setTextBackgroundColor(color.native); + } + setTextColor(color: QColor): void { + this.native.setTextColor(color.native); + } + undo(): void { + this.native.undo(); + } + zommIn(range = 1): void { + this.native.zoomIn(range); + } + zoomOut(range = 1): void { + this.native.zoomOut(range); + } +} + +export enum AutoFormattingFlag { + AutoNone = 0, + AutoBulletList = 0x00000001, + AutoAll = 0xffffffff, +} + +export enum QTextEditLineWrapMode { + NoWrap, + WidgetWidth, + FixedPixelWidth, + FixedColumnWidth, +} + +export enum WrapMode { + NoWrap, + WordWrap, + ManualWrap, + WrapAnywhere, + WrapAtWordBoundaryOrAnywhere, +} + +export class QTextEdit extends NodeTextEdit { + native: NativeElement; + constructor(); + constructor(parent: NodeWidget); + constructor(parent?: NodeWidget) { + let native; + if (parent) { + native = new addon.QTextEdit(parent.native); + } else { + native = new addon.QTextEdit(); + } + super(native); + this.native = native; + parent && this.setNodeParent(parent); + } +} + +export interface QTextEditSignals extends QAbstractScrollAreaSignals { + copyAvailable: (yes: boolean) => void; + cursorPositionChanged: () => void; + redoAvailable: (available: boolean) => void; + selectionChanged: () => void; + textChanged: () => void; + undoAvailable: (available: boolean) => void; +}