Adds dynamic content support for flex layout. (#199)
* layout performance fix * adjust size, webdefaults * Add flexlayout owner to the context * revert * reorders setlayout and setflexnode * add defaults * fix mainwindow rootNode * properties to methods * Adds defaultsAdds flexutils measurewidget * introduce configure for all types of nodes. * lint fix * Revams flexlayout to handle dynamic content * Adds dynamic layout support for flex layout. * lint fix * fix few code updates
This commit is contained in:
parent
1c1cea7a3b
commit
edcdbb510e
@ -15,6 +15,7 @@ add_library(${CORE_WIDGETS_ADDON} SHARED
|
||||
"${PROJECT_SOURCE_DIR}/src/cpp/main.cpp"
|
||||
# core internals
|
||||
"${PROJECT_SOURCE_DIR}/src/cpp/lib/Extras/Utils/nutils.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/src/cpp/lib/core/FlexLayout/flexutils.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/src/cpp/lib/core/FlexLayout/flexlayout.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/src/cpp/lib/core/FlexLayout/flexitem.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/src/cpp/lib/core/YogaWidget/nodestyle.cpp"
|
||||
|
||||
@ -6,16 +6,16 @@
|
||||
#include <QVariant>
|
||||
|
||||
#include "core/FlexLayout/flexlayout.h"
|
||||
|
||||
#include "core/FlexLayout/flexutils.h"
|
||||
namespace extrautils {
|
||||
YGSize measureQtWidget(YGNodeRef node, float width, YGMeasureMode widthMode,
|
||||
float height, YGMeasureMode heightMode);
|
||||
|
||||
QVariant* convertToQVariant(Napi::Env& env, Napi::Value& value);
|
||||
|
||||
bool isNapiValueInt(Napi::Env& env, Napi::Value& num);
|
||||
|
||||
std::string getNapiObjectClassName(Napi::Object& object);
|
||||
void* configureQWidget(QWidget* widget, YGNodeRef node,
|
||||
bool isLeafNode = false);
|
||||
void* configureQObject(QObject* object);
|
||||
void* configureComponent(void* component);
|
||||
|
||||
template <typename T>
|
||||
void safeDelete(QPointer<T>& component) {
|
||||
|
||||
@ -25,6 +25,5 @@ class QMouseEventWrap : public Napi::ObjectWrap<QMouseEventWrap> {
|
||||
Napi::Value globalX(const Napi::CallbackInfo& info);
|
||||
Napi::Value globalY(const Napi::CallbackInfo& info);
|
||||
|
||||
|
||||
COMPONENT_WRAPPED_METHODS_DECLARATION
|
||||
};
|
||||
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <napi.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <QPointer>
|
||||
|
||||
@ -13,6 +12,7 @@ class QLabelWrap : public Napi::ObjectWrap<QLabelWrap> {
|
||||
QPointer<NLabel> instance;
|
||||
|
||||
public:
|
||||
QWIDGET_WRAPPED_METHODS_DECLARATION
|
||||
static Napi::Object init(Napi::Env env, Napi::Object exports);
|
||||
QLabelWrap(const Napi::CallbackInfo& info);
|
||||
~QLabelWrap();
|
||||
@ -26,6 +26,4 @@ class QLabelWrap : public Napi::ObjectWrap<QLabelWrap> {
|
||||
Napi::Value text(const Napi::CallbackInfo& info);
|
||||
Napi::Value setPixmap(const Napi::CallbackInfo& info);
|
||||
Napi::Value setOpenExternalLinks(const Napi::CallbackInfo& info);
|
||||
|
||||
QWIDGET_WRAPPED_METHODS_DECLARATION
|
||||
};
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
class QScrollAreaWrap : public Napi::ObjectWrap<QScrollAreaWrap> {
|
||||
private:
|
||||
QPointer<NScrollArea> instance;
|
||||
YGNodeRef scrollNode;
|
||||
|
||||
public:
|
||||
static Napi::Object init(Napi::Env env, Napi::Object exports);
|
||||
|
||||
@ -262,6 +262,12 @@
|
||||
this->instance->setWindowFlag(static_cast<Qt::WindowType>(windowType), \
|
||||
switchOn); \
|
||||
return env.Null(); \
|
||||
} \
|
||||
Napi::Value adjustSize(const Napi::CallbackInfo& info) { \
|
||||
Napi::Env env = info.Env(); \
|
||||
Napi::HandleScope scope(env); \
|
||||
this->instance->adjustSize(); \
|
||||
return env.Null(); \
|
||||
}
|
||||
|
||||
#endif // QWIDGET_WRAPPED_METHODS_DECLARATION
|
||||
@ -302,6 +308,7 @@
|
||||
InstanceMethod("testAttribute", &WidgetWrapName::testAttribute), \
|
||||
InstanceMethod("setWindowOpacity", &WidgetWrapName::setWindowOpacity), \
|
||||
InstanceMethod("windowOpacity", &WidgetWrapName::windowOpacity), \
|
||||
InstanceMethod("setWindowFlag", &WidgetWrapName::setWindowFlag),
|
||||
InstanceMethod("setWindowFlag", &WidgetWrapName::setWindowFlag), \
|
||||
InstanceMethod("adjustSize", &WidgetWrapName::adjustSize),
|
||||
|
||||
#endif // QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE
|
||||
|
||||
@ -21,13 +21,9 @@ YGNodeNew(); FlexLayout * flayout = new FlexLayout(container,root);
|
||||
class FlexLayout : public QLayout, public EventWidget {
|
||||
private:
|
||||
YGNodeRef node;
|
||||
YGNodeRef getRootNode(YGNodeRef node);
|
||||
YGNodeRef getRootNode(YGNodeRef node) const;
|
||||
|
||||
public:
|
||||
struct NodeContext {
|
||||
NodeContext(QLayoutItem *i) { item = i; }
|
||||
QLayoutItem *item;
|
||||
};
|
||||
FlexLayout(QWidget *parentWidget = nullptr, YGNodeRef parentNode = nullptr);
|
||||
~FlexLayout() override;
|
||||
QSize sizeHint() const override;
|
||||
@ -41,7 +37,6 @@ class FlexLayout : public QLayout, public EventWidget {
|
||||
void removeWidget(QWidget *childWidget, YGNodeRef childNode);
|
||||
void setGeometry(const QRect &rect) override;
|
||||
void setFlexNode(YGNodeRef parentNode);
|
||||
static NodeContext *getNodeContext(YGNodeRef node);
|
||||
|
||||
EVENTWIDGET_IMPLEMENTATIONS(FlexLayout)
|
||||
};
|
||||
|
||||
27
src/cpp/include/nodegui/core/FlexLayout/flexutils.h
Normal file
27
src/cpp/include/nodegui/core/FlexLayout/flexutils.h
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <QLayoutItem>
|
||||
#include <QWidget>
|
||||
|
||||
#include "deps/yoga/YGNode.h"
|
||||
|
||||
class FlexNodeContext {
|
||||
void* _widget;
|
||||
QLayoutItem* _layoutItem;
|
||||
|
||||
public:
|
||||
FlexNodeContext(void* widget);
|
||||
QWidget* widget();
|
||||
QLayoutItem* layoutItem();
|
||||
void setLayoutItem(QLayoutItem* item);
|
||||
};
|
||||
namespace flexutils {
|
||||
YGSize measureQtWidget(YGNodeRef node, float width, YGMeasureMode widthMode,
|
||||
float height, YGMeasureMode heightMode);
|
||||
const QRect getFlexNodeGeometry(YGNodeRef node);
|
||||
void setFlexNodeGeometry(YGNodeRef node, const QRect& geometry);
|
||||
FlexNodeContext* getFlexNodeContext(YGNodeRef node);
|
||||
void configureFlexNode(QWidget* widget, YGNodeRef node,
|
||||
bool isLeafNode = false);
|
||||
|
||||
} // namespace flexutils
|
||||
@ -5,28 +5,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "core/Component/component_wrap.h"
|
||||
|
||||
YGSize extrautils::measureQtWidget(YGNodeRef node, float width,
|
||||
YGMeasureMode widthMode, float height,
|
||||
YGMeasureMode heightMode) {
|
||||
FlexLayout::NodeContext* ctx = FlexLayout::getNodeContext(node);
|
||||
if (ctx) {
|
||||
QLayoutItem* childLayoutItem = ctx->item;
|
||||
QWidget* widget = childLayoutItem->widget();
|
||||
float width = 0.0;
|
||||
float height = 0.0;
|
||||
if (widget) {
|
||||
QSize size = widget->sizeHint();
|
||||
width = static_cast<float>(size.width());
|
||||
height = static_cast<float>(size.height());
|
||||
return YGSize{
|
||||
width,
|
||||
height,
|
||||
};
|
||||
}
|
||||
}
|
||||
return YGSize{width, height};
|
||||
}
|
||||
#include "core/FlexLayout/flexutils.h"
|
||||
|
||||
bool extrautils::isNapiValueInt(Napi::Env& env, Napi::Value& num) {
|
||||
return env.Global()
|
||||
@ -96,3 +75,13 @@ QVariant* extrautils::convertToQVariant(Napi::Env& env, Napi::Value& value) {
|
||||
return new QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
void* extrautils::configureComponent(void* component) { return component; }
|
||||
void* extrautils::configureQObject(QObject* object) {
|
||||
return configureComponent(object);
|
||||
}
|
||||
void* extrautils::configureQWidget(QWidget* widget, YGNodeRef node,
|
||||
bool isLeafNode) {
|
||||
flexutils::configureFlexNode(widget, node, isLeafNode);
|
||||
return configureQObject(widget);
|
||||
}
|
||||
@ -37,5 +37,5 @@ QObjectWrap::QObjectWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
this->rawData = extrautils::configureQObject(this->getInternalInstance());
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ QSizeWrap::QSizeWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
this->rawData = extrautils::configureComponent(this->getInternalInstance());
|
||||
}
|
||||
|
||||
QSizeWrap::~QSizeWrap() { this->instance.reset(); }
|
||||
|
||||
@ -32,7 +32,7 @@ QVariantWrap::QVariantWrap(const Napi::CallbackInfo& info)
|
||||
} else {
|
||||
this->instance = QSharedPointer<QVariant>(new QVariant());
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
this->rawData = extrautils::configureComponent(this->getInternalInstance());
|
||||
}
|
||||
|
||||
Napi::Value QVariantWrap::toString(const Napi::CallbackInfo& info) {
|
||||
|
||||
@ -41,7 +41,7 @@ QApplicationWrap::QApplicationWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
this->rawData = extrautils::configureComponent(this->getInternalInstance());
|
||||
}
|
||||
QApplicationWrap::~QApplicationWrap() {
|
||||
if (this->_wasManuallyCreated) {
|
||||
|
||||
@ -29,7 +29,7 @@ QClipboardWrap::QClipboardWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Incorrect initialization of QClipboardWrap")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
this->rawData = extrautils::configureComponent(this->getInternalInstance());
|
||||
}
|
||||
|
||||
QClipboard* QClipboardWrap::getInternalInstance() { return this->instance; }
|
||||
|
||||
@ -33,7 +33,7 @@ QCursorWrap::QCursorWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
this->rawData = extrautils::configureComponent(this->getInternalInstance());
|
||||
}
|
||||
|
||||
QCursorWrap::~QCursorWrap() { this->instance.reset(); }
|
||||
|
||||
@ -36,7 +36,7 @@ QKeyEventWrap::QKeyEventWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
this->rawData = extrautils::configureComponent(this->getInternalInstance());
|
||||
}
|
||||
|
||||
QKeyEventWrap::~QKeyEventWrap() {
|
||||
|
||||
@ -9,15 +9,15 @@ Napi::FunctionReference QMouseEventWrap::constructor;
|
||||
Napi::Object QMouseEventWrap::init(Napi::Env env, Napi::Object exports) {
|
||||
Napi::HandleScope scope(env);
|
||||
char CLASSNAME[] = "QMouseEvent";
|
||||
Napi::Function func = DefineClass(
|
||||
env, CLASSNAME,
|
||||
{InstanceMethod("button", &QMouseEventWrap::button),
|
||||
InstanceMethod("x", &QMouseEventWrap::x),
|
||||
InstanceMethod("y", &QMouseEventWrap::y),
|
||||
InstanceMethod("globalX", &QMouseEventWrap::globalX),
|
||||
InstanceMethod("globalY", &QMouseEventWrap::globalY),
|
||||
Napi::Function func =
|
||||
DefineClass(env, CLASSNAME,
|
||||
{InstanceMethod("button", &QMouseEventWrap::button),
|
||||
InstanceMethod("x", &QMouseEventWrap::x),
|
||||
InstanceMethod("y", &QMouseEventWrap::y),
|
||||
InstanceMethod("globalX", &QMouseEventWrap::globalX),
|
||||
InstanceMethod("globalY", &QMouseEventWrap::globalY),
|
||||
|
||||
COMPONENT_WRAPPED_METHODS_EXPORT_DEFINE});
|
||||
COMPONENT_WRAPPED_METHODS_EXPORT_DEFINE});
|
||||
constructor = Napi::Persistent(func);
|
||||
exports.Set(CLASSNAME, func);
|
||||
return exports;
|
||||
@ -37,7 +37,7 @@ QMouseEventWrap::QMouseEventWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
this->rawData = extrautils::configureComponent(this->getInternalInstance());
|
||||
}
|
||||
|
||||
QMouseEventWrap::~QMouseEventWrap() {
|
||||
|
||||
@ -34,7 +34,7 @@ QIconWrap::QIconWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
this->rawData = extrautils::configureComponent(this->getInternalInstance());
|
||||
}
|
||||
|
||||
QIconWrap::~QIconWrap() { this->instance.reset(); }
|
||||
|
||||
@ -32,7 +32,7 @@ QKeySequenceWrap::QKeySequenceWrap(const Napi::CallbackInfo &info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
this->rawData = extrautils::configureComponent(this->getInternalInstance());
|
||||
}
|
||||
|
||||
QKeySequenceWrap::~QKeySequenceWrap() { this->instance.reset(); }
|
||||
|
||||
@ -41,7 +41,7 @@ QPixmapWrap::QPixmapWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
this->rawData = extrautils::configureComponent(this->getInternalInstance());
|
||||
}
|
||||
|
||||
QPixmapWrap::~QPixmapWrap() { this->instance.reset(); }
|
||||
|
||||
@ -50,7 +50,7 @@ QActionWrap::QActionWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
this->rawData = extrautils::configureQObject(this->getInternalInstance());
|
||||
}
|
||||
|
||||
QActionWrap::~QActionWrap() { extrautils::safeDelete(this->instance); }
|
||||
|
||||
@ -39,11 +39,9 @@ QCheckBoxWrap::QCheckBoxWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
// Adds measure function on yoga node so that widget size is calculated based
|
||||
// on its text also.
|
||||
YGNodeSetMeasureFunc(this->instance->getFlexNode(),
|
||||
&extrautils::measureQtWidget);
|
||||
this->rawData = extrautils::configureQWidget(
|
||||
this->getInternalInstance(), this->getInternalInstance()->getFlexNode(),
|
||||
true);
|
||||
}
|
||||
|
||||
QCheckBoxWrap::~QCheckBoxWrap() { extrautils::safeDelete(this->instance); }
|
||||
|
||||
@ -43,11 +43,10 @@ QDialWrap::QDialWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
// Adds measure function on yoga node so that widget size is calculated based
|
||||
// on its own size.
|
||||
YGNodeSetMeasureFunc(this->instance->getFlexNode(),
|
||||
&extrautils::measureQtWidget);
|
||||
|
||||
this->rawData = extrautils::configureQWidget(
|
||||
this->getInternalInstance(), this->getInternalInstance()->getFlexNode(),
|
||||
true);
|
||||
}
|
||||
|
||||
QDialWrap::~QDialWrap() { extrautils::safeDelete(this->instance); }
|
||||
|
||||
@ -37,7 +37,7 @@ QGridLayoutWrap::QGridLayoutWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
this->rawData = extrautils::configureQObject(this->getInternalInstance());
|
||||
}
|
||||
|
||||
Napi::Value QGridLayoutWrap::addWidget(const Napi::CallbackInfo& info) {
|
||||
|
||||
@ -45,11 +45,10 @@ QLabelWrap::QLabelWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
// Adds measure function on yoga node so that widget size is calculated based
|
||||
// on its text also.
|
||||
YGNodeSetMeasureFunc(this->instance->getFlexNode(),
|
||||
&extrautils::measureQtWidget);
|
||||
auto flexNode = this->getInternalInstance()->getFlexNode();
|
||||
YGNodeSetNodeType(flexNode, YGNodeType::YGNodeTypeText);
|
||||
this->rawData =
|
||||
extrautils::configureQWidget(this->getInternalInstance(), flexNode, true);
|
||||
}
|
||||
|
||||
Napi::Value QLabelWrap::setWordWrap(const Napi::CallbackInfo& info) {
|
||||
|
||||
@ -43,11 +43,9 @@ QLineEditWrap::QLineEditWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
// Adds measure function on yoga node so that widget size is calculated based
|
||||
// on its text also.
|
||||
YGNodeSetMeasureFunc(this->instance->getFlexNode(),
|
||||
&extrautils::measureQtWidget);
|
||||
this->rawData = extrautils::configureQWidget(
|
||||
this->getInternalInstance(), this->getInternalInstance()->getFlexNode(),
|
||||
true);
|
||||
}
|
||||
|
||||
QLineEditWrap::~QLineEditWrap() { extrautils::safeDelete(this->instance); }
|
||||
|
||||
@ -46,7 +46,8 @@ QMainWindowWrap::QMainWindowWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
this->rawData = extrautils::configureQWidget(
|
||||
this->getInternalInstance(), this->getInternalInstance()->getFlexNode());
|
||||
}
|
||||
|
||||
Napi::Value QMainWindowWrap::setCentralWidget(const Napi::CallbackInfo& info) {
|
||||
@ -54,16 +55,13 @@ Napi::Value QMainWindowWrap::setCentralWidget(const Napi::CallbackInfo& info) {
|
||||
Napi::HandleScope scope(env);
|
||||
|
||||
Napi::Object widgetObject = info[0].As<Napi::Object>();
|
||||
Napi::External<YGNode> centralWidgetFlexNode =
|
||||
info[1].As<Napi::External<YGNode>>();
|
||||
QWidgetWrap* centralWidget =
|
||||
Napi::ObjectWrap<QWidgetWrap>::Unwrap(widgetObject);
|
||||
|
||||
Napi::External<YGNode> flexNodeObject = info[1].As<Napi::External<YGNode>>();
|
||||
YGNodeRef flexNodeRef = flexNodeObject.Data();
|
||||
|
||||
YGNodeRef node = this->instance->getFlexNode();
|
||||
YGNodeInsertChild(node, flexNodeRef, 0);
|
||||
YGNodeInsertChild(this->instance->getFlexNode(), centralWidgetFlexNode.Data(),
|
||||
0);
|
||||
this->instance->setCentralWidget(centralWidget->getInternalInstance());
|
||||
|
||||
return env.Null();
|
||||
}
|
||||
|
||||
|
||||
@ -40,11 +40,9 @@ QMenuWrap::QMenuWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
// Adds measure function on yoga node so that widget size is calculated based
|
||||
// on its text also.
|
||||
YGNodeSetMeasureFunc(this->instance->getFlexNode(),
|
||||
&extrautils::measureQtWidget);
|
||||
this->rawData = extrautils::configureQWidget(
|
||||
this->getInternalInstance(), this->getInternalInstance()->getFlexNode(),
|
||||
true);
|
||||
}
|
||||
|
||||
QMenuWrap::~QMenuWrap() { extrautils::safeDelete(this->instance); }
|
||||
|
||||
@ -45,11 +45,8 @@ QMenuBarWrap::QMenuBarWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
// Adds measure function on yoga node so that widget size is calculated based
|
||||
// on its text also.
|
||||
YGNodeSetMeasureFunc(this->instance->getFlexNode(),
|
||||
&extrautils::measureQtWidget);
|
||||
this->rawData = extrautils::configureQWidget(
|
||||
this->getInternalInstance(), this->getInternalInstance()->getFlexNode());
|
||||
}
|
||||
|
||||
QMenuBarWrap::~QMenuBarWrap() { extrautils::safeDelete(this->instance); }
|
||||
|
||||
@ -52,11 +52,9 @@ QPlainTextEditWrap::QPlainTextEditWrap(const Napi::CallbackInfo &info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
// Adds measure function on yoga node so that widget size is calculated based
|
||||
// on its text also.
|
||||
YGNodeSetMeasureFunc(this->instance->getFlexNode(),
|
||||
&extrautils::measureQtWidget);
|
||||
this->rawData = extrautils::configureQWidget(
|
||||
this->getInternalInstance(), this->getInternalInstance()->getFlexNode(),
|
||||
true);
|
||||
}
|
||||
|
||||
QPlainTextEditWrap::~QPlainTextEditWrap() {
|
||||
|
||||
@ -42,11 +42,9 @@ QProgressBarWrap::QProgressBarWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
// Adds measure function on yoga node so that widget size is calculated based
|
||||
// on its own size.
|
||||
YGNodeSetMeasureFunc(this->instance->getFlexNode(),
|
||||
&extrautils::measureQtWidget);
|
||||
this->rawData = extrautils::configureQWidget(
|
||||
this->getInternalInstance(), this->getInternalInstance()->getFlexNode(),
|
||||
true);
|
||||
}
|
||||
|
||||
QProgressBarWrap::~QProgressBarWrap() {
|
||||
|
||||
@ -38,10 +38,9 @@ QPushButtonWrap::QPushButtonWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
// Adds measure function on yoga node so that widget size is calculated based
|
||||
// on its text also.
|
||||
YGNodeSetMeasureFunc(this->instance->getFlexNode(),
|
||||
&extrautils::measureQtWidget);
|
||||
this->rawData = extrautils::configureQWidget(
|
||||
this->getInternalInstance(), this->getInternalInstance()->getFlexNode(),
|
||||
true);
|
||||
}
|
||||
|
||||
QPushButtonWrap::~QPushButtonWrap() { extrautils::safeDelete(this->instance); }
|
||||
|
||||
@ -38,11 +38,9 @@ QRadioButtonWrap::QRadioButtonWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
// Adds measure function on yoga node so that widget size is calculated based
|
||||
// on its own size.
|
||||
YGNodeSetMeasureFunc(this->instance->getFlexNode(),
|
||||
&extrautils::measureQtWidget);
|
||||
this->rawData = extrautils::configureQWidget(
|
||||
this->getInternalInstance(), this->getInternalInstance()->getFlexNode(),
|
||||
true);
|
||||
}
|
||||
|
||||
QRadioButtonWrap::~QRadioButtonWrap() {
|
||||
|
||||
@ -40,11 +40,14 @@ QScrollAreaWrap::QScrollAreaWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
// Adds measure function on yoga node so that widget size is calculated based
|
||||
// on its own size.
|
||||
YGNodeSetMeasureFunc(this->instance->getFlexNode(),
|
||||
&extrautils::measureQtWidget);
|
||||
this->scrollNode = YGNodeNew();
|
||||
YGConfigSetUseWebDefaults(this->scrollNode->getConfig(), true);
|
||||
FlexNodeContext* scrollNodeCtx = new FlexNodeContext(this->instance);
|
||||
YGNodeSetContext(this->scrollNode, scrollNodeCtx);
|
||||
|
||||
this->rawData = extrautils::configureQWidget(
|
||||
this->getInternalInstance(), this->getInternalInstance()->getFlexNode(),
|
||||
true);
|
||||
}
|
||||
|
||||
QScrollAreaWrap::~QScrollAreaWrap() { extrautils::safeDelete(this->instance); }
|
||||
@ -53,8 +56,11 @@ Napi::Value QScrollAreaWrap::setWidget(const Napi::CallbackInfo& info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::HandleScope scope(env);
|
||||
Napi::Object contentWidget = info[0].As<Napi::Object>();
|
||||
Napi::External<YGNode> centralWidgetFlexNode =
|
||||
info[1].As<Napi::External<YGNode>>();
|
||||
QWidgetWrap* contentWidgetWrap =
|
||||
Napi::ObjectWrap<QWidgetWrap>::Unwrap(contentWidget);
|
||||
YGNodeInsertChild(this->scrollNode, centralWidgetFlexNode.Data(), 0);
|
||||
this->instance->setWidget(contentWidgetWrap->getInternalInstance());
|
||||
return env.Null();
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ QShortcutWrap::QShortcutWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
this->rawData = extrautils::configureQObject(this->getInternalInstance());
|
||||
}
|
||||
|
||||
QShortcutWrap::~QShortcutWrap() { extrautils::safeDelete(this->instance); }
|
||||
|
||||
@ -45,11 +45,9 @@ QSpinBoxWrap::QSpinBoxWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
// Adds measure function on yoga node so that widget size is calculated based
|
||||
// on its text also.
|
||||
YGNodeSetMeasureFunc(this->instance->getFlexNode(),
|
||||
&extrautils::measureQtWidget);
|
||||
this->rawData = extrautils::configureQWidget(
|
||||
this->getInternalInstance(), this->getInternalInstance()->getFlexNode(),
|
||||
true);
|
||||
}
|
||||
|
||||
QSpinBoxWrap::~QSpinBoxWrap() { extrautils::safeDelete(this->instance); }
|
||||
|
||||
@ -48,7 +48,7 @@ QSystemTrayIconWrap::QSystemTrayIconWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
this->rawData = extrautils::configureQObject(this->getInternalInstance());
|
||||
}
|
||||
|
||||
QSystemTrayIconWrap::~QSystemTrayIconWrap() {
|
||||
|
||||
@ -47,11 +47,9 @@ QTabWidgetWrap::QTabWidgetWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
// Adds measure function on yoga node so that widget size is calculated based
|
||||
// on its text also.
|
||||
YGNodeSetMeasureFunc(this->instance->getFlexNode(),
|
||||
&extrautils::measureQtWidget);
|
||||
this->rawData = extrautils::configureQWidget(
|
||||
this->getInternalInstance(), this->getInternalInstance()->getFlexNode(),
|
||||
true);
|
||||
}
|
||||
|
||||
Napi::Value QTabWidgetWrap::addTab(const Napi::CallbackInfo& info) {
|
||||
|
||||
@ -39,5 +39,7 @@ QWidgetWrap::QWidgetWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
this->rawData = extrautils::configureQWidget(
|
||||
this->getInternalInstance(), this->getInternalInstance()->getFlexNode(),
|
||||
false);
|
||||
}
|
||||
|
||||
@ -1,10 +1,20 @@
|
||||
#include "core/FlexLayout/flexitem.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "core/FlexLayout/flexutils.h"
|
||||
|
||||
FlexItem::FlexItem() {
|
||||
this->node = YGNodeNew();
|
||||
// YGConfigSetUseWebDefaults(this->node->getConfig(),true);
|
||||
YGConfigSetUseWebDefaults(this->node->getConfig(), true);
|
||||
}
|
||||
|
||||
YGNodeRef FlexItem::getFlexNode() const { return this->node; }
|
||||
|
||||
FlexItem::~FlexItem() { YGNodeFree(this->node); }
|
||||
FlexItem::~FlexItem() {
|
||||
FlexNodeContext* ctx = flexutils::getFlexNodeContext(this->node);
|
||||
if (ctx != nullptr) {
|
||||
delete ctx;
|
||||
};
|
||||
YGNodeFree(this->node);
|
||||
}
|
||||
|
||||
@ -1,19 +1,11 @@
|
||||
#include "core/FlexLayout/flexlayout.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QWidget>
|
||||
|
||||
#include "core/FlexLayout/flexitem.h"
|
||||
#include "core/FlexLayout/flexutils.h"
|
||||
#include "core/YogaWidget/yogawidget.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
FlexLayout::NodeContext* FlexLayout::getNodeContext(YGNodeRef node) {
|
||||
if (!node) {
|
||||
return nullptr;
|
||||
}
|
||||
void* childContext = YGNodeGetContext(node);
|
||||
NodeContext* ctx = static_cast<NodeContext*>(
|
||||
childContext); // because we are managing this at all times
|
||||
return ctx;
|
||||
}
|
||||
|
||||
FlexLayout::FlexLayout(QWidget* parentWidget, YGNodeRef parentNode)
|
||||
: QLayout(parentWidget) {
|
||||
@ -27,99 +19,44 @@ FlexLayout::~FlexLayout() {
|
||||
const uint32_t childCount = YGNodeGetChildCount(this->node);
|
||||
for (uint32_t i = 0; i < childCount; i++) {
|
||||
const YGNodeRef oldChild = YGNodeGetChild(this->node, i);
|
||||
NodeContext* ctx = getNodeContext(oldChild);
|
||||
if (ctx) {
|
||||
delete ctx->item;
|
||||
FlexNodeContext* childCtx = flexutils::getFlexNodeContext(oldChild);
|
||||
|
||||
if (childCtx->layoutItem()) {
|
||||
delete childCtx->layoutItem();
|
||||
childCtx->setLayoutItem(nullptr);
|
||||
}
|
||||
}
|
||||
YGNodeRemoveAllChildren(this->node);
|
||||
}
|
||||
|
||||
QSize FlexLayout::sizeHint() const {
|
||||
if (!this->node) {
|
||||
return QSize(0, 0);
|
||||
}
|
||||
int width = static_cast<uint>(YGNodeLayoutGetWidth(this->node));
|
||||
int height = static_cast<uint>(YGNodeLayoutGetHeight(this->node));
|
||||
return QSize(width, height);
|
||||
}
|
||||
|
||||
void FlexLayout::addItem(QLayoutItem* item) {
|
||||
// Noop: We already have addWidget doing all the hard work.
|
||||
}
|
||||
|
||||
QLayoutItem* FlexLayout::itemAt(int index) const {
|
||||
if (!this->node) {
|
||||
return nullptr;
|
||||
}
|
||||
// spdlog::info("flexlayout: itemAt {}",index);
|
||||
YGNodeRef childNode = YGNodeGetChild(this->node, static_cast<uint>(index));
|
||||
NodeContext* ctx = getNodeContext(childNode);
|
||||
if (!ctx) {
|
||||
return nullptr;
|
||||
}
|
||||
return ctx->item;
|
||||
}
|
||||
|
||||
QLayoutItem* FlexLayout::takeAt(int index) {
|
||||
YGNodeRef childNode = YGNodeGetChild(this->node, static_cast<uint>(index));
|
||||
NodeContext* ctx = getNodeContext(childNode);
|
||||
QLayoutItem* childLayoutItem = ctx->item;
|
||||
YGNodeRemoveChild(this->node, childNode);
|
||||
spdlog::info("flexlayout: takeAt ", index);
|
||||
delete ctx;
|
||||
return childLayoutItem;
|
||||
}
|
||||
|
||||
int FlexLayout::count() const {
|
||||
if (!this->node) {
|
||||
return 0;
|
||||
}
|
||||
float childCount = YGNodeGetChildCount(this->node);
|
||||
spdlog::info("flexlayout: count {}", childCount);
|
||||
return static_cast<uint>(childCount);
|
||||
return;
|
||||
}
|
||||
|
||||
void FlexLayout::addWidget(QWidget* childWidget, YGNodeRef childNode) {
|
||||
if (!this->node) {
|
||||
spdlog::warn(
|
||||
"Flex layout's parent yoga node not set yet. Set it using setFlexNode. "
|
||||
"Child widget will not be added to Flex Layout");
|
||||
qWarning() << "Flex layout's parent yoga node not set yet. Set it using "
|
||||
"setFlexNode. \n"
|
||||
<< "Child widget will not be added to Flex Layout";
|
||||
return;
|
||||
}
|
||||
uint count = YGNodeGetChildCount(this->node);
|
||||
YGNodeInsertChild(this->node, childNode, count);
|
||||
QLayoutItem* layoutItem = new QWidgetItem(childWidget);
|
||||
NodeContext* childContext = new NodeContext(layoutItem);
|
||||
YGNodeSetContext(childNode, static_cast<void*>(childContext));
|
||||
FlexNodeContext* childCtx = flexutils::getFlexNodeContext(childNode);
|
||||
auto layoutitem = new QWidgetItem(childWidget);
|
||||
childCtx->setLayoutItem(layoutitem);
|
||||
QLayout::addWidget(childWidget);
|
||||
this->invalidate();
|
||||
}
|
||||
|
||||
void FlexLayout::removeWidget(QWidget* childWidget, YGNodeRef childNode) {
|
||||
if (!this->node) {
|
||||
spdlog::warn(
|
||||
"Flex layout's parent yoga node not set yet. Set it using setFlexNode. "
|
||||
"childwidget cant be removed");
|
||||
return;
|
||||
}
|
||||
|
||||
NodeContext* ctx = getNodeContext(childNode);
|
||||
if (ctx) {
|
||||
delete ctx->item;
|
||||
}
|
||||
YGNodeRemoveChild(this->node, childNode);
|
||||
QLayout::removeWidget(childWidget);
|
||||
this->invalidate();
|
||||
}
|
||||
|
||||
void FlexLayout::insertChildBefore(QWidget* childWidget,
|
||||
YGNodeRef beforeChildNode,
|
||||
YGNodeRef childNode) {
|
||||
if (!this->node) {
|
||||
spdlog::warn(
|
||||
"Flex layout's parent yoga node not set yet. Set it using setFlexNode. "
|
||||
"childwidget cant be inserted");
|
||||
qWarning() << "Flex layout's parent yoga node not set yet. Set it using "
|
||||
"setFlexNode. \n"
|
||||
<< "childwidget cant be inserted";
|
||||
return;
|
||||
}
|
||||
uint count = YGNodeGetChildCount(this->node);
|
||||
@ -131,14 +68,61 @@ void FlexLayout::insertChildBefore(QWidget* childWidget,
|
||||
}
|
||||
}
|
||||
YGNodeInsertChild(this->node, childNode, indexToInsert);
|
||||
QLayoutItem* layoutItem = new QWidgetItem(childWidget);
|
||||
NodeContext* childContext = new NodeContext(layoutItem);
|
||||
YGNodeSetContext(childNode, static_cast<void*>(childContext));
|
||||
FlexNodeContext* ctx = flexutils::getFlexNodeContext(childNode);
|
||||
ctx->setLayoutItem(new QWidgetItem(childWidget));
|
||||
QLayout::addWidget(childWidget);
|
||||
this->invalidate();
|
||||
}
|
||||
|
||||
YGNodeRef FlexLayout::getRootNode(YGNodeRef node) {
|
||||
QLayoutItem* FlexLayout::itemAt(int index) const {
|
||||
if (!this->node ||
|
||||
index >= static_cast<int>(YGNodeGetChildCount(this->node))) {
|
||||
return nullptr;
|
||||
}
|
||||
YGNodeRef childNode = YGNodeGetChild(this->node, static_cast<uint>(index));
|
||||
FlexNodeContext* childCtx = flexutils::getFlexNodeContext(childNode);
|
||||
return childCtx->layoutItem();
|
||||
}
|
||||
|
||||
QLayoutItem* FlexLayout::takeAt(int index) {
|
||||
if (!this->node ||
|
||||
index >= static_cast<int>(YGNodeGetChildCount(this->node))) {
|
||||
return nullptr;
|
||||
}
|
||||
YGNodeRef childNode = YGNodeGetChild(this->node, static_cast<uint>(index));
|
||||
FlexNodeContext* ctx = flexutils::getFlexNodeContext(childNode);
|
||||
QLayoutItem* childLayoutItem = ctx->layoutItem();
|
||||
ctx->setLayoutItem(nullptr);
|
||||
YGNodeRemoveChild(this->node, childNode);
|
||||
return childLayoutItem;
|
||||
}
|
||||
|
||||
int FlexLayout::count() const {
|
||||
if (!this->node) {
|
||||
return 0;
|
||||
}
|
||||
float childCount = YGNodeGetChildCount(this->node);
|
||||
return static_cast<int>(childCount);
|
||||
}
|
||||
|
||||
void FlexLayout::removeWidget(QWidget* childWidget, YGNodeRef childNode) {
|
||||
if (!this->node) {
|
||||
qWarning() << "Flex layout's parent yoga node not set yet. Set it using "
|
||||
"setFlexNode. "
|
||||
<< "childwidget cant be removed";
|
||||
return;
|
||||
}
|
||||
FlexNodeContext* ctx = flexutils::getFlexNodeContext(childNode);
|
||||
if (ctx->layoutItem()) {
|
||||
delete ctx->layoutItem();
|
||||
ctx->setLayoutItem(nullptr);
|
||||
}
|
||||
YGNodeRemoveChild(this->node, childNode);
|
||||
QLayout::removeWidget(childWidget);
|
||||
this->invalidate();
|
||||
}
|
||||
|
||||
YGNodeRef FlexLayout::getRootNode(YGNodeRef node) const {
|
||||
YGNodeRef parent = node->getOwner();
|
||||
if (!parent) {
|
||||
return node;
|
||||
@ -147,35 +131,37 @@ YGNodeRef FlexLayout::getRootNode(YGNodeRef node) {
|
||||
}
|
||||
}
|
||||
|
||||
QSize FlexLayout::sizeHint() const {
|
||||
QSize totalSize;
|
||||
YGNodeRef parentNode = this->node;
|
||||
YGNodeRef rootNode = getRootNode(parentNode);
|
||||
YGDirection rootDirection = YGNodeStyleGetDirection(rootNode);
|
||||
YGNodeStyleSetMaxHeight(rootNode, QWIDGETSIZE_MAX);
|
||||
YGNodeStyleSetMaxWidth(rootNode, QWIDGETSIZE_MAX);
|
||||
YGNodeCalculateLayout(rootNode, 0, 0, rootDirection);
|
||||
totalSize.rwidth() = YGNodeLayoutGetWidth(this->node);
|
||||
totalSize.rheight() = YGNodeLayoutGetHeight(this->node);
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
void FlexLayout::setGeometry(const QRect& rect) {
|
||||
if (!this->node) {
|
||||
return;
|
||||
}
|
||||
YGNodeRef rootNode = getRootNode(this->node);
|
||||
QWidget* parentWidget = this->parentWidget();
|
||||
QWidget* window = parentWidget->window();
|
||||
YGNodeRef rootNode = FlexLayout::getRootNode(this->node);
|
||||
YGDirection direction = YGNodeStyleGetDirection(rootNode);
|
||||
YGNodeCalculateLayout(rootNode, window->width(), window->height(), direction);
|
||||
YGNodeStyleSetMaxHeight(rootNode, QWIDGETSIZE_MAX);
|
||||
YGNodeStyleSetMaxWidth(rootNode, QWIDGETSIZE_MAX);
|
||||
YGNodeCalculateLayout(rootNode, 0, 0, direction);
|
||||
|
||||
uint count = YGNodeGetChildCount(this->node);
|
||||
|
||||
for (uint i = 0; i < count; ++i) {
|
||||
YGNode* childNode = YGNodeGetChild(this->node, i);
|
||||
int width = static_cast<uint>(YGNodeLayoutGetWidth(childNode));
|
||||
int height = static_cast<uint>(YGNodeLayoutGetHeight(childNode));
|
||||
int left = static_cast<uint>(YGNodeLayoutGetLeft(childNode));
|
||||
int top = static_cast<uint>(YGNodeLayoutGetTop(childNode));
|
||||
|
||||
QRect childRect(left, top, width, height);
|
||||
NodeContext* ctx = getNodeContext(childNode);
|
||||
if (ctx) {
|
||||
QLayoutItem* childLayoutItem = ctx->item;
|
||||
QWidget* childWidget = childLayoutItem->widget();
|
||||
if (childWidget) {
|
||||
childWidget->setGeometry(childRect);
|
||||
} else {
|
||||
childLayoutItem->setGeometry(childRect);
|
||||
}
|
||||
}
|
||||
QRect childRect = flexutils::getFlexNodeGeometry(childNode);
|
||||
FlexNodeContext* ctx = flexutils::getFlexNodeContext(childNode);
|
||||
QLayoutItem* childItem = ctx->layoutItem();
|
||||
childItem->setGeometry(childRect);
|
||||
}
|
||||
QLayout::setGeometry(rect);
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@ FlexLayoutWrap::FlexLayoutWrap(const Napi::CallbackInfo& info)
|
||||
Napi::TypeError::New(env, "Wrong number of arguments")
|
||||
.ThrowAsJavaScriptException();
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
this->rawData = extrautils::configureQObject(this->getInternalInstance());
|
||||
}
|
||||
|
||||
Napi::Value FlexLayoutWrap::addWidget(const Napi::CallbackInfo& info) {
|
||||
|
||||
70
src/cpp/lib/core/FlexLayout/flexutils.cpp
Normal file
70
src/cpp/lib/core/FlexLayout/flexutils.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
#include "core/FlexLayout/flexutils.h"
|
||||
|
||||
FlexNodeContext::FlexNodeContext(void* widget) {
|
||||
this->_widget = widget;
|
||||
this->_layoutItem = nullptr;
|
||||
}
|
||||
|
||||
QWidget* FlexNodeContext::widget() {
|
||||
QWidget* flexNodeWidget = static_cast<QWidget*>(this->_widget);
|
||||
return flexNodeWidget;
|
||||
}
|
||||
|
||||
QLayoutItem* FlexNodeContext::layoutItem() { return this->_layoutItem; }
|
||||
|
||||
void FlexNodeContext::setLayoutItem(QLayoutItem* item) {
|
||||
this->_layoutItem = item;
|
||||
}
|
||||
|
||||
const QRect flexutils::getFlexNodeGeometry(YGNodeRef node) {
|
||||
int width = static_cast<uint>(YGNodeLayoutGetWidth(node));
|
||||
int height = static_cast<uint>(YGNodeLayoutGetHeight(node));
|
||||
int left = static_cast<uint>(YGNodeLayoutGetLeft(node));
|
||||
int top = static_cast<uint>(YGNodeLayoutGetTop(node));
|
||||
const QRect geometry(left, top, width, height);
|
||||
return geometry;
|
||||
}
|
||||
|
||||
void flexutils::setFlexNodeGeometry(YGNodeRef node, const QRect& geometry) {
|
||||
int width = geometry.width();
|
||||
int height = geometry.height();
|
||||
int left = geometry.left();
|
||||
int top = geometry.top();
|
||||
|
||||
YGNodeStyleSetWidth(node, width);
|
||||
YGNodeStyleSetHeight(node, height);
|
||||
YGNodeStyleSetPosition(node, YGEdgeTop, top);
|
||||
YGNodeStyleSetPosition(node, YGEdgeLeft, left);
|
||||
}
|
||||
|
||||
FlexNodeContext* flexutils::getFlexNodeContext(YGNodeRef node) {
|
||||
if (!node) {
|
||||
return nullptr;
|
||||
}
|
||||
void* rawCtx = YGNodeGetContext(node);
|
||||
FlexNodeContext* ctx = static_cast<FlexNodeContext*>(rawCtx);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
YGSize flexutils::measureQtWidget(YGNodeRef node, float _width,
|
||||
YGMeasureMode widthMode, float _height,
|
||||
YGMeasureMode heightMode) {
|
||||
FlexNodeContext* ctx = getFlexNodeContext(node);
|
||||
QWidget* widget = ctx->widget();
|
||||
QSize size = widget->sizeHint();
|
||||
float width = static_cast<float>(size.width());
|
||||
float height = static_cast<float>(size.height());
|
||||
return YGSize{
|
||||
width,
|
||||
height,
|
||||
};
|
||||
}
|
||||
|
||||
void flexutils::configureFlexNode(QWidget* widget, YGNodeRef node,
|
||||
bool isLeafNode) {
|
||||
FlexNodeContext* ctx = new FlexNodeContext(widget);
|
||||
YGNodeSetContext(node, ctx);
|
||||
if (isLeafNode) {
|
||||
YGNodeSetMeasureFunc(node, &flexutils::measureQtWidget);
|
||||
}
|
||||
}
|
||||
87
src/demo.ts
87
src/demo.ts
@ -1,44 +1,51 @@
|
||||
import { QMainWindow } from './index';
|
||||
import { QWidget } from './lib/QtWidgets/QWidget';
|
||||
import { FlexLayout } from './lib/core/FlexLayout';
|
||||
import { QLabel, QLabelEvents } from './lib/QtWidgets/QLabel';
|
||||
import { AlignmentFlag } from './lib/QtEnums';
|
||||
import { QPixmap } from './lib/QtGui/QPixmap';
|
||||
import { QMouseEvent } from './lib/QtGui/QEvent/QMouseEvent';
|
||||
import { QWidget, QScrollArea, QMainWindow, FlexLayout, QLabel } from './index';
|
||||
|
||||
const win = new QMainWindow();
|
||||
const view = new QWidget();
|
||||
view.setLayout(new FlexLayout());
|
||||
view.setStyleSheet(`
|
||||
flex: 1;
|
||||
width: '100%';
|
||||
height: '100%';
|
||||
`);
|
||||
const hello = new QLabel();
|
||||
hello.setText('Hello');
|
||||
hello.setStyleSheet(`
|
||||
border: 1px solid blue;
|
||||
`);
|
||||
const world = new QLabel();
|
||||
world.setText('World');
|
||||
world.addEventListener(QLabelEvents.MouseButtonPress, e => {
|
||||
const event = new QMouseEvent(e);
|
||||
console.log('clicked!', event.x(), event.y());
|
||||
});
|
||||
world.setStyleSheet(`
|
||||
border: 1px solid blue;
|
||||
qproperty-alignment: AlignCenter;
|
||||
`);
|
||||
const pixmap = new QPixmap('/Users/atulr/Project/nodegui/nodegui/extras/assets/kitchen.png');
|
||||
hello.setProperty('pixmap', pixmap);
|
||||
const main = async (): Promise<void> => {
|
||||
const win = new QMainWindow();
|
||||
const scrollArea = new QScrollArea();
|
||||
const center = new QWidget();
|
||||
const label = new QLabel();
|
||||
label.setText(`
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
Hellloooooo
|
||||
`);
|
||||
|
||||
hello.setProperty('alignment', AlignmentFlag.AlignCenter);
|
||||
await scrollArea.setInlineStyle('border: 1px solid yellow;');
|
||||
await center.setInlineStyle(`border: 3px solid blue;`);
|
||||
await label.setInlineStyle(`border: 2px solid green;padding: 10;`);
|
||||
|
||||
if (view.layout) {
|
||||
view.layout.addWidget(hello);
|
||||
view.layout.addWidget(world);
|
||||
}
|
||||
win.setCentralWidget(view);
|
||||
win.show();
|
||||
center.setLayout(new FlexLayout());
|
||||
center.layout?.addWidget(label);
|
||||
scrollArea.setWidget(center);
|
||||
win.setCentralWidget(scrollArea);
|
||||
win.show();
|
||||
(global as any).win = win;
|
||||
};
|
||||
|
||||
(global as any).win = win; // To prevent win from being garbage collected.
|
||||
main();
|
||||
|
||||
@ -7,19 +7,19 @@ export class QKeyEvent {
|
||||
constructor(event: NativeEvent) {
|
||||
this.native = new addon.QKeyEvent(event);
|
||||
}
|
||||
text = (): string => {
|
||||
text(): string {
|
||||
return this.native.text();
|
||||
};
|
||||
key = (): number => {
|
||||
}
|
||||
key(): number {
|
||||
return this.native.key();
|
||||
};
|
||||
modifiers = (): number => {
|
||||
}
|
||||
modifiers(): number {
|
||||
return this.native.modifiers();
|
||||
};
|
||||
count = (): number => {
|
||||
}
|
||||
count(): number {
|
||||
return this.native.count();
|
||||
};
|
||||
isAutoRepeat = (): boolean => {
|
||||
}
|
||||
isAutoRepeat(): boolean {
|
||||
return this.native.isAutoRepeat();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,19 +7,19 @@ export class QMouseEvent {
|
||||
constructor(event: NativeEvent) {
|
||||
this.native = new addon.QMouseEvent(event);
|
||||
}
|
||||
button = (): string => {
|
||||
button(): string {
|
||||
return this.native.button();
|
||||
};
|
||||
x = (): number => {
|
||||
}
|
||||
x(): number {
|
||||
return this.native.x();
|
||||
};
|
||||
y = (): number => {
|
||||
}
|
||||
y(): number {
|
||||
return this.native.y();
|
||||
};
|
||||
globalX = (): number => {
|
||||
}
|
||||
globalX(): number {
|
||||
return this.native.globalX();
|
||||
};
|
||||
globalY = (): number => {
|
||||
}
|
||||
globalY(): number {
|
||||
return this.native.globalY();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@ export class QIcon extends Component {
|
||||
this.native = new addon.QIcon();
|
||||
}
|
||||
}
|
||||
pixmap = (width: number, height: number, mode?: QIconMode, state?: QIconState): QPixmap => {
|
||||
pixmap(width: number, height: number, mode?: QIconMode, state?: QIconState): QPixmap {
|
||||
let nativePixmap;
|
||||
if (mode && state) {
|
||||
nativePixmap = this.native.pixmap(width, height, mode, state);
|
||||
@ -35,12 +35,10 @@ export class QIcon extends Component {
|
||||
nativePixmap = this.native.pixmap(width, height);
|
||||
}
|
||||
return new QPixmap(nativePixmap);
|
||||
};
|
||||
|
||||
}
|
||||
isMask(): boolean {
|
||||
return this.native.isMask();
|
||||
}
|
||||
|
||||
setIsMask(isMask: boolean): void {
|
||||
this.native.setIsMask(isMask);
|
||||
}
|
||||
|
||||
@ -5,9 +5,9 @@ import { NodeObject } from '../QtCore/QObject';
|
||||
export abstract class NodeLayout extends NodeObject {
|
||||
type = 'layout';
|
||||
abstract addWidget(childWidget: NodeWidget, ...args: any[]): void;
|
||||
activate = (): boolean => {
|
||||
activate(): boolean {
|
||||
return this.native.activate();
|
||||
};
|
||||
}
|
||||
invalidate(): void {
|
||||
this.native.invalidate();
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ export class QScrollArea extends QAbstractScrollArea {
|
||||
setWidget(widget: NodeWidget): void {
|
||||
// react:✓, //TODO:getter
|
||||
this.contentWidget = widget;
|
||||
this.native.setWidget(widget.native);
|
||||
this.native.setWidget(widget.native, widget.getFlexNode());
|
||||
}
|
||||
takeWidget(): NodeWidget | null {
|
||||
// react:✓
|
||||
|
||||
@ -126,13 +126,16 @@ export abstract class NodeWidget extends YogaWidget {
|
||||
}
|
||||
setLayout(parentLayout: NodeLayout): void {
|
||||
const flexLayout = parentLayout as FlexLayout;
|
||||
this.native.setLayout(parentLayout.native);
|
||||
if (flexLayout.setFlexNode) {
|
||||
//if flex layout set the flexnode
|
||||
flexLayout.setFlexNode(this.getFlexNode());
|
||||
}
|
||||
this.native.setLayout(parentLayout.native);
|
||||
this.layout = parentLayout;
|
||||
}
|
||||
adjustSize(): void {
|
||||
this.native.adjustSize();
|
||||
}
|
||||
}
|
||||
|
||||
type Rect = {
|
||||
|
||||
@ -3,7 +3,7 @@ import cuid from 'cuid';
|
||||
import nodeguiAutoPrefixer from 'postcss-nodegui-autoprefixer';
|
||||
import { NodeWidget } from '../../QtWidgets/QWidget';
|
||||
export class StyleSheet {
|
||||
static create = async (cssString: string): Promise<string> => {
|
||||
static async create(cssString: string): Promise<string> {
|
||||
const { css } = await postcss([nodeguiAutoPrefixer()])
|
||||
.process(cssString, { from: undefined })
|
||||
.catch(err => {
|
||||
@ -11,7 +11,7 @@ export class StyleSheet {
|
||||
return { css: cssString };
|
||||
});
|
||||
return css;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function prepareInlineStyleSheet(widget: NodeWidget, rawStyle: string): Promise<string> {
|
||||
|
||||
@ -2,7 +2,7 @@ import { NodeObject } from '../QtCore/QObject';
|
||||
|
||||
export type FlexNode = {};
|
||||
export abstract class YogaWidget extends NodeObject {
|
||||
getFlexNode = (): FlexNode => {
|
||||
getFlexNode(): FlexNode {
|
||||
return this.native.getFlexNode();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,5 +3,5 @@
|
||||
1. **Segmentation fault:** Segmentation fault occurs when you access a Pointer that is pointing to an invalid memory address. One major reason for this can be that JS garbage collector would have garbage collected the addon generated value and you try accessing it after a while. This is mostly the case if you see seg fault happening randomly after some time of startup.
|
||||
|
||||
2. **Widget not visible in Flex layout** Widget might have gotten zero height/width. This can occur if yoga was not able to get the default height/width of the widget. Make sure you have implemented
|
||||
`YGNodeSetMeasureFunc(this->instance->getFlexNode(), &extrautils::measureQtWidget);`
|
||||
`YGNodeSetMeasureFunc(this->instance->getFlexNode(), &flexutils::measureQtWidget);`
|
||||
if its a leaf node widget(doesnt contain any children).
|
||||
|
||||
Loading…
Reference in New Issue
Block a user