Adds text measuring support for button and label
This commit is contained in:
parent
ac0a544565
commit
695d1df039
7
examples/calculator/README.md
Normal file
7
examples/calculator/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
# Calculator app
|
||||
|
||||
This example showcases how to build a basic mac calculator clone.
|
||||
|
||||
The app should look like this:
|
||||
|
||||

|
||||
BIN
examples/calculator/calculator.png
Normal file
BIN
examples/calculator/calculator.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 300 KiB |
119
examples/calculator/index.ts
Normal file
119
examples/calculator/index.ts
Normal file
@ -0,0 +1,119 @@
|
||||
import { QMainWindow } from "../../src/lib/QtWidgets/QMainWindow";
|
||||
import { QWidget } from "../../src/lib/QtGui/QWidget";
|
||||
import { FlexLayout } from "../../src/lib/core/FlexLayout";
|
||||
import { QPushButton } from "../../src/lib/QtWidgets/QPushButton";
|
||||
import { QLabel } from "../../src/lib/QtWidgets/QLabel";
|
||||
|
||||
const globals = global as any;
|
||||
|
||||
// Main Window
|
||||
const win = new QMainWindow();
|
||||
|
||||
win.resize(400, 600);
|
||||
|
||||
const getButton = (
|
||||
label: string,
|
||||
value: number | string,
|
||||
type: "value" | "command"
|
||||
) => {
|
||||
const button = new QPushButton();
|
||||
button.setText(label);
|
||||
return {
|
||||
ui: button,
|
||||
value,
|
||||
type
|
||||
};
|
||||
};
|
||||
|
||||
// Top Row
|
||||
const row0 = new QWidget();
|
||||
win.setCentralWidget(row0);
|
||||
|
||||
row0.setStyleSheet(`
|
||||
qproperty-flex: 1;
|
||||
`);
|
||||
const btnClear = getButton("AC", "AC", "command");
|
||||
const resultText = new QLabel();
|
||||
resultText.setText(0);
|
||||
|
||||
const row0Layout = new FlexLayout();
|
||||
row0Layout.setFlexNode(row0.getFlexNode());
|
||||
|
||||
row0Layout.addWidget(btnClear.ui, btnClear.ui.getFlexNode());
|
||||
row0Layout.addWidget(resultText, resultText.getFlexNode());
|
||||
row0.setLayout(row0Layout);
|
||||
|
||||
// // First Row
|
||||
// const btn7 = getButton("7", 7, "value");
|
||||
// const btn8 = getButton("8", 8, "value");
|
||||
// const btn9 = getButton("9", 9, "value");
|
||||
// const btnDivide = getButton("/", "/", "command");
|
||||
// const row1 = new QWidget();
|
||||
// const row1Layout = new FlexLayout();
|
||||
// row1.setLayout(row1Layout);
|
||||
// row1Layout.setFlexNode(row1.getFlexNode());
|
||||
// row1Layout.addWidget(btn7.ui, btn7.ui.getFlexNode());
|
||||
// row1Layout.addWidget(btn8.ui, btn8.ui.getFlexNode());
|
||||
// row1Layout.addWidget(btn9.ui, btn9.ui.getFlexNode());
|
||||
// row1Layout.addWidget(btnDivide.ui, btnDivide.ui.getFlexNode());
|
||||
|
||||
// // Second Row
|
||||
// const btn4 = getButton("4", 4, "value");
|
||||
// const btn5 = getButton("5", 5, "value");
|
||||
// const btn6 = getButton("6", 6, "value");
|
||||
// const btnMultiply = getButton("x", "*", "command");
|
||||
// const row2 = new QWidget();
|
||||
// const row2Layout = new FlexLayout();
|
||||
// row2.setLayout(row2Layout);
|
||||
// row2Layout.setFlexNode(row2.getFlexNode());
|
||||
// row2Layout.addWidget(btn4.ui, btn4.ui.getFlexNode());
|
||||
// row2Layout.addWidget(btn5.ui, btn5.ui.getFlexNode());
|
||||
// row2Layout.addWidget(btn6.ui, btn6.ui.getFlexNode());
|
||||
// row2Layout.addWidget(btnMultiply.ui, btnMultiply.ui.getFlexNode());
|
||||
|
||||
// // Third Row
|
||||
// const btn1 = getButton("1", 1, "value");
|
||||
// const btn2 = getButton("2", 2, "value");
|
||||
// const btn3 = getButton("3", 3, "value");
|
||||
// const btnMinus = getButton("-", "-", "command");
|
||||
// const row3 = new QWidget();
|
||||
// const row3Layout = new FlexLayout();
|
||||
// row3.setLayout(row3Layout);
|
||||
// row3Layout.setFlexNode(row3.getFlexNode());
|
||||
// row3Layout.addWidget(btn1.ui, btn1.ui.getFlexNode());
|
||||
// row3Layout.addWidget(btn2.ui, btn2.ui.getFlexNode());
|
||||
// row3Layout.addWidget(btn3.ui, btn3.ui.getFlexNode());
|
||||
// row3Layout.addWidget(btnMinus.ui, btnMinus.ui.getFlexNode());
|
||||
|
||||
// // Fourth Row
|
||||
// const btn0 = getButton("0", 0, "value");
|
||||
// const btnDot = getButton(".", ".", "command");
|
||||
// const btnEquals = getButton("=", "=", "command");
|
||||
// const btnPlus = getButton("+", "+", "command");
|
||||
// const row4 = new QWidget();
|
||||
// const row4Layout = new FlexLayout();
|
||||
// row4.setLayout(row4Layout);
|
||||
// row4Layout.setFlexNode(row4.getFlexNode());
|
||||
// row4Layout.addWidget(btn0.ui, btn0.ui.getFlexNode());
|
||||
// row4Layout.addWidget(btnDot.ui, btnDot.ui.getFlexNode());
|
||||
// row4Layout.addWidget(btnEquals.ui, btnEquals.ui.getFlexNode());
|
||||
// row4Layout.addWidget(btnPlus.ui, btnPlus.ui.getFlexNode());
|
||||
|
||||
// Root view
|
||||
// const rootView = new QWidget();
|
||||
// rootView.setStyleSheet(
|
||||
// `
|
||||
// qproperty-flex: 1;
|
||||
// `
|
||||
// );
|
||||
// const rootViewFlexLayout = new FlexLayout();
|
||||
// rootViewFlexLayout.setFlexNode(rootView.getFlexNode());
|
||||
// rootView.setLayout(rootViewFlexLayout);
|
||||
// rootViewFlexLayout.addWidget(row0, row0.getFlexNode());
|
||||
// rootViewFlexLayout.addWidget(row1, row1.getFlexNode());
|
||||
// rootViewFlexLayout.addWidget(row2, row2.getFlexNode());
|
||||
// rootViewFlexLayout.addWidget(row3, row3.getFlexNode());
|
||||
|
||||
win.show();
|
||||
|
||||
globals.win = win; //to keep gc from collecting ui widgets
|
||||
@ -15,6 +15,7 @@
|
||||
"typescript": "^3.4.5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "npm run build:addon&&npm run build:lib",
|
||||
"build:lib": "tsc",
|
||||
"build:addon": "node-gyp -j 8 build",
|
||||
"rebuild:addon": "node-gyp -j 8 rebuild",
|
||||
|
||||
@ -1,8 +1,26 @@
|
||||
#include "utils.h"
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <QWidget>
|
||||
#include "deps/spdlog/spdlog.h"
|
||||
|
||||
void extrautils::noop(){}
|
||||
|
||||
void extrautils::throwTypeError(Napi::Env env, std::string errorMessage){
|
||||
Napi::TypeError::New(env, errorMessage.c_str()).ThrowAsJavaScriptException();
|
||||
}
|
||||
|
||||
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();
|
||||
if(widget){
|
||||
QSize size = widget->sizeHint();
|
||||
return YGSize{
|
||||
.height = static_cast<float>(size.height()),
|
||||
.width = static_cast<float>(size.width())
|
||||
};
|
||||
}
|
||||
}
|
||||
return YGSize{ .height = 0, .width = 0 };
|
||||
}
|
||||
@ -1,11 +1,11 @@
|
||||
#ifndef EXTRAUTILS_WRAP_H
|
||||
#define EXTRAUTILS_WRAP_H
|
||||
#pragma once
|
||||
|
||||
#include <napi.h>
|
||||
#include "src/cpp/core/FlexLayout/flexlayout.h"
|
||||
|
||||
namespace extrautils {
|
||||
void noop();
|
||||
void throwTypeError(Napi::Env env, std::string errorMessage);
|
||||
YGSize measureQtWidget (YGNodeRef node, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -39,6 +39,8 @@ QLabelWrap::QLabelWrap(const Napi::CallbackInfo& info): Napi::ObjectWrap<QLabelW
|
||||
}else {
|
||||
extrautils::throwTypeError(env, "Wrong number of arguments");
|
||||
}
|
||||
// Adds measure function on yoga node so that widget size is calculated based on its text also.
|
||||
YGNodeSetMeasureFunc(this->instance->getFlexNode(), &extrautils::measureQtWidget);
|
||||
}
|
||||
|
||||
QLabelWrap::~QLabelWrap() {
|
||||
|
||||
@ -21,7 +21,7 @@ class QLabelWrap : public Napi::ObjectWrap<QLabelWrap>{
|
||||
Napi::Value text(const Napi::CallbackInfo &info);
|
||||
|
||||
QWIDGET_WRAPPED_METHODS_DECLARATION
|
||||
YOGAWIDGET_WRAPPED_METHODS_DECLARATION
|
||||
YOGAWIDGET_WRAPPED_METHODS_DECLARATION
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -35,6 +35,8 @@ QPushButtonWrap::QPushButtonWrap(const Napi::CallbackInfo& info): Napi::ObjectWr
|
||||
}else {
|
||||
extrautils::throwTypeError(env, "Wrong number of arguments");
|
||||
}
|
||||
// Adds measure function on yoga node so that widget size is calculated based on its text also.
|
||||
YGNodeSetMeasureFunc(this->instance->getFlexNode(), &extrautils::measureQtWidget);
|
||||
}
|
||||
|
||||
QPushButtonWrap::~QPushButtonWrap() {
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include "npushbutton.h"
|
||||
#include "src/cpp/QtGui/QWidget/qwidget_macro.h"
|
||||
#include "src/cpp/core/YogaWidget/yogawidget_macro.h"
|
||||
#include "src/cpp/Extras/Utils/utils.h"
|
||||
|
||||
class QPushButtonWrap : public Napi::ObjectWrap<QPushButtonWrap> {
|
||||
private:
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#include <QWidget>
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
FlexLayout::NodeContext *FlexLayout::getNodeContext(YGNodeRef node) const
|
||||
FlexLayout::NodeContext *FlexLayout::getNodeContext(YGNodeRef node)
|
||||
{
|
||||
if(!node){
|
||||
return nullptr;
|
||||
@ -122,6 +122,7 @@ void FlexLayout::setGeometry(const QRect &rect)
|
||||
QWidget* childWidget = childLayoutItem->widget();
|
||||
if(childWidget){
|
||||
childWidget->setGeometry(childRect);
|
||||
spdlog::info("Object: {}, rect: w:{}, h:{}, l:{}, t:{}",childWidget->metaObject()->className(),width,height,left,top);
|
||||
}else {
|
||||
childLayoutItem->setGeometry(childRect);
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
#ifndef FLEXLAYOUT_H
|
||||
#define FLEXLAYOUT_H
|
||||
#pragma once
|
||||
|
||||
#include "deps/yoga/YGNode.h"
|
||||
#include <QLayout>
|
||||
@ -25,6 +24,7 @@ class FlexLayout: public QLayout
|
||||
{
|
||||
private:
|
||||
YGNodeRef node;
|
||||
public:
|
||||
struct NodeContext
|
||||
{
|
||||
NodeContext(QLayoutItem *i) {
|
||||
@ -32,9 +32,6 @@ private:
|
||||
}
|
||||
QLayoutItem *item;
|
||||
};
|
||||
NodeContext* getNodeContext(YGNodeRef node) const;
|
||||
|
||||
public:
|
||||
FlexLayout(QWidget* parentWidget=nullptr, YGNodeRef parentNode=nullptr);
|
||||
~FlexLayout() override;
|
||||
QSize sizeHint() const override;
|
||||
@ -45,6 +42,6 @@ public:
|
||||
void addWidget(QWidget* childWidget, YGNodeRef childNode);
|
||||
void setGeometry(const QRect &rect) override;
|
||||
void setFlexNode(YGNodeRef parentNode);
|
||||
static NodeContext* getNodeContext(YGNodeRef node);
|
||||
};
|
||||
|
||||
#endif // FLEXLAYOUT_H
|
||||
|
||||
Loading…
Reference in New Issue
Block a user