Permalink
Browse files

Command line widget and Qt/Lua connection improvements

  • Loading branch information...
feragon committed Jun 3, 2016
1 parent 9eebd52 commit 61be5810065c20abca52d65dc0e6d28a134262b9
View
@@ -1,8 +1,9 @@
#include "luaqobject.h"
#include <iostream>
#include "widgets/clicommand.h"
LuaQObject::LuaQObject(QObject* object):
_object(object)
_object(object),
_valid(false)
{
//Connect QObject destroyed() signal
const int destroySignalId = _object->metaObject()->indexOfSignal("destroyed()");
@@ -11,34 +12,52 @@ LuaQObject::LuaQObject(QObject* object):
LuaQObject::~LuaQObject() {
_object = 0;
}
bool LuaQObject::connect(int signalId, LuaIntf::LuaRef slot) {
_signalId = signalId;
if(slot.isFunction()) {
_slotId = 1;
if(QMetaObject::connect(_object, signalId, this, this->metaObject()->methodCount() + _slotId)) {
_slotFunction = slot;
return true;
_slotFunction = slot;
_valid = true;
}
}
else {
std::cerr << "Given slot is not a function" << std::endl;
}
return false;
return _valid;
}
int LuaQObject::qt_metacall(QMetaObject::Call c, int id, void **a)
{
id = QObject::qt_metacall(c, id, a);
if(id == _slotId && _slotFunction) {
_slotFunction();
if(id == 0) {
_valid = false;
}
else if(id == _slotId) {
if(_slotFunction) {
LuaIntf::LuaState s = _slotFunction.state();
auto parameters = _object->metaObject()->method(_signalId).parameterTypes();
unsigned int i = 0;
_slotFunction.pushToStack();
for (auto parameter : parameters) {
i++;
pushArg(s, QMetaType::type(parameter.constData()), a[i]);
}
s.call(i, 0);
}
return -1;
}
return -1;
return id;
}
std::string LuaQObject::objectName(QObject* object) {
@@ -55,7 +74,7 @@ std::string LuaQObject::objectName() {
}
QObject* LuaQObject::findChild(QObject* object, std::string name) {
for(auto *child : object->children()) {
for(auto child : object->children()) {
if(objectName(child) == name) {
return child;
}
@@ -72,4 +91,62 @@ QObject* LuaQObject::findChild(std::string name) {
}
return 0;
}
void LuaQObject::pushArg(LuaIntf::LuaState s, int const type, void const* arg) {
switch (type)
{
case QMetaType::Void:
s.push(nullptr);
break;
case QMetaType::Bool:
s.push(*(bool*)arg);
break;
case QMetaType::Int:
s.push(*(int*)arg);
break;
case QMetaType::UInt:
s.push(*(unsigned int*)arg);
break;
case QMetaType::Long:
s.push(*(long*)arg);
break;
case QMetaType::LongLong:
s.push(*(long long*)arg);
break;
case QMetaType::Short:
s.push(*(short*)arg);
break;
case QMetaType::Char:
s.push(*(char*)arg);
break;
case QMetaType::ULong:
s.push(*(unsigned long*)arg);
break;
case QMetaType::ULongLong:
s.push(*(unsigned long long*)arg);
break;
case QMetaType::UShort:
s.push(*(unsigned short*)arg);
break;
case QMetaType::UChar:
s.push(*(unsigned char*)arg);
break;
case QMetaType::Double:
s.push(*(double*)arg);
break;
case QMetaType::Float:
s.push(*(float*)arg);
break;
case QMetaType::QString:
s.push(reinterpret_cast<const QString*>(arg));
break;
default:
s.push(nullptr);
break;
}
}
bool LuaQObject::valid() {
return _valid;
}
View
@@ -14,28 +14,30 @@ extern "C"
class LuaQObject : public QObject {
public:
LuaQObject(QObject *object);
LuaQObject(QObject* object);
~LuaQObject();
bool connect(int signalId, LuaIntf::LuaRef slot);
void pushArg(LuaIntf::LuaState s, int const type, void const* arg);
std::string objectName();
static std::string objectName(QObject* object);
QObject* findChild(std::string name);
static QObject* findChild(QObject* object, std::string name);
bool valid();
int qt_metacall(QMetaObject::Call c, int id, void **a);
private:
QObject* _object;
int _slotId;
int _signalId;
LuaIntf::LuaRef _slotFunction;
bool _valid;
};
using LuaQObject_SPtr = std::shared_ptr<LuaQObject>;
View
@@ -23,7 +23,7 @@ void addQtBaseBindings(lua_State *L) {
.addFunction("findChild", [](QObject* object, std::string name) {
return LuaQObject::findChild(object, name);
})
.addStaticFunction("tr", &QObject::tr)
.addStaticFunction("tr", &QObject::tr, LUA_ARGS(const char*, LuaIntf::_opt<const char*>, LuaIntf::_opt<int>))
.endClass()
.beginExtendClass<QWidget, QObject>("QWidget")
@@ -145,10 +145,7 @@ void addLCBindings(lua_State *L) {
.beginModule("lc")
.beginExtendClass<CadMdiChild, QWidget>("CadMdiChild")
.addFactory([]() {
CadMdiChild* child = new CadMdiChild;
return child;
})
.addConstructor(LUA_SP(std::shared_ptr<CadMdiChild>), LUA_ARGS())
.addFunction("cursor", &CadMdiChild::cursor)
.addFunction("document", &CadMdiChild::document)
.addProperty("id", &CadMdiChild::id, &CadMdiChild::setId)
@@ -171,7 +168,8 @@ void addLCBindings(lua_State *L) {
.endClass()
.beginClass<LuaInterface>("LuaInterface")
.addFunction("luaConnect", &LuaInterface::qtConnect)
.addFunction("luaConnect", &LuaInterface::luaConnect)
.addFunction("connect", &LuaInterface::qtConnect)
.endClass()
.beginExtendClass<LuaScript, QDockWidget>("LuaScript")
@@ -182,6 +180,12 @@ void addLCBindings(lua_State *L) {
.addFunction("autoScale", &LCViewer::DocumentCanvas::autoScale)
.endClass()
.beginExtendClass<CliCommand, QDockWidget>("CliCommand")
.addConstructor(LUA_SP(std::shared_ptr<CliCommand>), LUA_ARGS(QWidget*))
.addFunction("addCommand", &CliCommand::addCommand)
.addFunction("focus", &CliCommand::focus)
.addFunction("write", &CliCommand::write, LUA_ARGS(const char*))
.endClass()
.endModule();
}
View
@@ -26,6 +26,7 @@ extern "C"
#include "documentcanvas.h"
#include "lcadviewer.h"
#include "widgets/luascript.h"
#include "widgets/clicommand.h"
#include "luainterface.h"
#include "luaqobject.h"
View
@@ -29,8 +29,8 @@ void LuaInterface::initLua() {
std::cout << out << std::endl;
}
bool LuaInterface::qtConnect(
QObject *sender,
bool LuaInterface::luaConnect(
QObject* sender,
std::string signalName,
LuaIntf::LuaRef slot)
{
@@ -40,9 +40,14 @@ bool LuaInterface::qtConnect(
std::cout << "No such signal " << signalName << std::endl;
}
else {
LuaQObject_SPtr lqo(new LuaQObject(sender));
auto lqo = std::make_shared<LuaQObject>(sender);
_luaQObjects.push_back(lqo);
return lqo->connect(signalId, slot);
auto connected = lqo->connect(signalId, slot);
cleanInvalidQObject();
return connected;
}
return false;
@@ -58,4 +63,28 @@ std::shared_ptr<QWidget> LuaInterface::loadUiFile(const char* fileName) {
file.close();
return widget;
}
}
void LuaInterface::cleanInvalidQObject() {
_luaQObjects.erase(std::remove_if(_luaQObjects.begin(),
_luaQObjects.end(),
[](LuaQObject_SPtr lqo){
return !lqo->valid();
}),
_luaQObjects.end());
}
bool LuaInterface::qtConnect(QObject *sender, std::string signalName, QObject *receiver, std::string slotName) {
int signalId = sender->metaObject()->indexOfSignal(signalName.c_str());
if(signalId < 0) {
std::cout << "No such signal " << signalName << std::endl;
}
int slotId = receiver->metaObject()->indexOfSlot(slotName.c_str());
if(slotId < 0) {
std::cout << "No such slot " << signalName << std::endl;
}
return QMetaObject::connect(sender, signalId, receiver, slotId);
}
View
@@ -30,12 +30,19 @@ class LuaInterface {
void initLua();
bool qtConnect(
QObject *sender,
bool luaConnect(
QObject* sender,
std::string signalName,
LuaIntf::LuaRef slot
);
bool qtConnect(QObject* sender,
std::string signalName,
QObject* receiver,
std::string slotName);
void cleanInvalidQObject();
static std::shared_ptr<QWidget> loadUiFile(const char* fileName);
private:
Oops, something went wrong.

0 comments on commit 61be581

Please sign in to comment.