Skip to content

Commit

Permalink
Command line widget and Qt/Lua connection improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
feragon committed Jun 3, 2016
1 parent 9eebd52 commit 61be581
Show file tree
Hide file tree
Showing 11 changed files with 297 additions and 51 deletions.
99 changes: 88 additions & 11 deletions lcUI/lua/luaqobject.cpp
@@ -1,8 +1,9 @@
#include "luaqobject.h" #include "luaqobject.h"
#include <iostream> #include <iostream>

#include "widgets/clicommand.h"
LuaQObject::LuaQObject(QObject* object): LuaQObject::LuaQObject(QObject* object):
_object(object) _object(object),
_valid(false)
{ {
//Connect QObject destroyed() signal //Connect QObject destroyed() signal
const int destroySignalId = _object->metaObject()->indexOfSignal("destroyed()"); const int destroySignalId = _object->metaObject()->indexOfSignal("destroyed()");
Expand All @@ -11,34 +12,52 @@ LuaQObject::LuaQObject(QObject* object):


LuaQObject::~LuaQObject() { LuaQObject::~LuaQObject() {
_object = 0; _object = 0;

} }


bool LuaQObject::connect(int signalId, LuaIntf::LuaRef slot) { bool LuaQObject::connect(int signalId, LuaIntf::LuaRef slot) {
_signalId = signalId;
if(slot.isFunction()) { if(slot.isFunction()) {
_slotId = 1; _slotId = 1;


if(QMetaObject::connect(_object, signalId, this, this->metaObject()->methodCount() + _slotId)) { if(QMetaObject::connect(_object, signalId, this, this->metaObject()->methodCount() + _slotId)) {
_slotFunction = slot; _slotFunction = slot;

_valid = true;
return true;
} }
} }
else { else {
std::cerr << "Given slot is not a function" << std::endl; 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) int LuaQObject::qt_metacall(QMetaObject::Call c, int id, void **a)
{ {

id = QObject::qt_metacall(c, id, 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) { std::string LuaQObject::objectName(QObject* object) {
Expand All @@ -55,7 +74,7 @@ std::string LuaQObject::objectName() {
} }


QObject* LuaQObject::findChild(QObject* object, std::string name) { QObject* LuaQObject::findChild(QObject* object, std::string name) {
for(auto *child : object->children()) { for(auto child : object->children()) {
if(objectName(child) == name) { if(objectName(child) == name) {
return child; return child;
} }
Expand All @@ -72,4 +91,62 @@ QObject* LuaQObject::findChild(std::string name) {
} }


return 0; 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;
} }
14 changes: 8 additions & 6 deletions lcUI/lua/luaqobject.h
Expand Up @@ -14,28 +14,30 @@ extern "C"


class LuaQObject : public QObject { class LuaQObject : public QObject {
public: public:
LuaQObject(QObject *object); LuaQObject(QObject* object);
~LuaQObject(); ~LuaQObject();


bool connect(int signalId, LuaIntf::LuaRef slot); bool connect(int signalId, LuaIntf::LuaRef slot);
void pushArg(LuaIntf::LuaState s, int const type, void const* arg);


std::string objectName(); std::string objectName();
static std::string objectName(QObject* object); static std::string objectName(QObject* object);

QObject* findChild(std::string name); QObject* findChild(std::string name);
static QObject* findChild(QObject* object, std::string name); static QObject* findChild(QObject* object, std::string name);


bool valid();


int qt_metacall(QMetaObject::Call c, int id, void **a); int qt_metacall(QMetaObject::Call c, int id, void **a);


private: private:

QObject* _object; QObject* _object;




int _slotId; int _slotId;
int _signalId;
LuaIntf::LuaRef _slotFunction; LuaIntf::LuaRef _slotFunction;

bool _valid;
}; };


using LuaQObject_SPtr = std::shared_ptr<LuaQObject>; using LuaQObject_SPtr = std::shared_ptr<LuaQObject>;
Expand Down
16 changes: 10 additions & 6 deletions lcUI/lua/qtbridge.cpp
Expand Up @@ -23,7 +23,7 @@ void addQtBaseBindings(lua_State *L) {
.addFunction("findChild", [](QObject* object, std::string name) { .addFunction("findChild", [](QObject* object, std::string name) {
return LuaQObject::findChild(object, 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() .endClass()


.beginExtendClass<QWidget, QObject>("QWidget") .beginExtendClass<QWidget, QObject>("QWidget")
Expand Down Expand Up @@ -145,10 +145,7 @@ void addLCBindings(lua_State *L) {


.beginModule("lc") .beginModule("lc")
.beginExtendClass<CadMdiChild, QWidget>("CadMdiChild") .beginExtendClass<CadMdiChild, QWidget>("CadMdiChild")
.addFactory([]() { .addConstructor(LUA_SP(std::shared_ptr<CadMdiChild>), LUA_ARGS())
CadMdiChild* child = new CadMdiChild;
return child;
})
.addFunction("cursor", &CadMdiChild::cursor) .addFunction("cursor", &CadMdiChild::cursor)
.addFunction("document", &CadMdiChild::document) .addFunction("document", &CadMdiChild::document)
.addProperty("id", &CadMdiChild::id, &CadMdiChild::setId) .addProperty("id", &CadMdiChild::id, &CadMdiChild::setId)
Expand All @@ -171,7 +168,8 @@ void addLCBindings(lua_State *L) {
.endClass() .endClass()


.beginClass<LuaInterface>("LuaInterface") .beginClass<LuaInterface>("LuaInterface")
.addFunction("luaConnect", &LuaInterface::qtConnect) .addFunction("luaConnect", &LuaInterface::luaConnect)
.addFunction("connect", &LuaInterface::qtConnect)
.endClass() .endClass()


.beginExtendClass<LuaScript, QDockWidget>("LuaScript") .beginExtendClass<LuaScript, QDockWidget>("LuaScript")
Expand All @@ -182,6 +180,12 @@ void addLCBindings(lua_State *L) {
.addFunction("autoScale", &LCViewer::DocumentCanvas::autoScale) .addFunction("autoScale", &LCViewer::DocumentCanvas::autoScale)
.endClass() .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(); .endModule();
} }
1 change: 1 addition & 0 deletions lcUI/lua/qtbridge.h
Expand Up @@ -26,6 +26,7 @@ extern "C"
#include "documentcanvas.h" #include "documentcanvas.h"
#include "lcadviewer.h" #include "lcadviewer.h"
#include "widgets/luascript.h" #include "widgets/luascript.h"
#include "widgets/clicommand.h"


#include "luainterface.h" #include "luainterface.h"
#include "luaqobject.h" #include "luaqobject.h"
Expand Down
39 changes: 34 additions & 5 deletions lcUI/luainterface.cpp
Expand Up @@ -29,8 +29,8 @@ void LuaInterface::initLua() {
std::cout << out << std::endl; std::cout << out << std::endl;
} }


bool LuaInterface::qtConnect( bool LuaInterface::luaConnect(
QObject *sender, QObject* sender,
std::string signalName, std::string signalName,
LuaIntf::LuaRef slot) LuaIntf::LuaRef slot)
{ {
Expand All @@ -40,9 +40,14 @@ bool LuaInterface::qtConnect(
std::cout << "No such signal " << signalName << std::endl; std::cout << "No such signal " << signalName << std::endl;
} }
else { else {
LuaQObject_SPtr lqo(new LuaQObject(sender)); auto lqo = std::make_shared<LuaQObject>(sender);
_luaQObjects.push_back(lqo); _luaQObjects.push_back(lqo);
return lqo->connect(signalId, slot);
auto connected = lqo->connect(signalId, slot);

cleanInvalidQObject();

return connected;
} }


return false; return false;
Expand All @@ -58,4 +63,28 @@ std::shared_ptr<QWidget> LuaInterface::loadUiFile(const char* fileName) {
file.close(); file.close();


return widget; 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);
}

11 changes: 9 additions & 2 deletions lcUI/luainterface.h
Expand Up @@ -30,12 +30,19 @@ class LuaInterface {


void initLua(); void initLua();


bool qtConnect( bool luaConnect(
QObject *sender, QObject* sender,
std::string signalName, std::string signalName,
LuaIntf::LuaRef slot 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); static std::shared_ptr<QWidget> loadUiFile(const char* fileName);


private: private:
Expand Down

0 comments on commit 61be581

Please sign in to comment.