diff options
Diffstat (limited to 'PySide/QtCore')
-rw-r--r-- | PySide/QtCore/CMakeLists.txt | 4 | ||||
-rw-r--r-- | PySide/QtCore/glue/qeasingcurve_glue.cpp | 120 | ||||
-rw-r--r-- | PySide/QtCore/glue/qeasingcurve_glue.h | 27 | ||||
-rw-r--r-- | PySide/QtCore/typesystem_core.xml | 32 |
4 files changed, 174 insertions, 9 deletions
diff --git a/PySide/QtCore/CMakeLists.txt b/PySide/QtCore/CMakeLists.txt index e0a82c64d..df05bf652 100644 --- a/PySide/QtCore/CMakeLists.txt +++ b/PySide/QtCore/CMakeLists.txt @@ -1,5 +1,7 @@ project(QtCore) +set(QtCore_gluecode "${CMAKE_CURRENT_SOURCE_DIR}/glue/qeasingcurve_glue.cpp") + if (${QT_VERSION_MAJOR} EQUAL 4 AND ${QT_VERSION_MINOR} LESS 6) set (QtCore_46_SRC ) else() @@ -153,4 +155,4 @@ create_pyside_module(QtCore "" QtCore_typesystem_path QtCore_SRC - "") + QtCore_gluecode) diff --git a/PySide/QtCore/glue/qeasingcurve_glue.cpp b/PySide/QtCore/glue/qeasingcurve_glue.cpp new file mode 100644 index 000000000..705220481 --- /dev/null +++ b/PySide/QtCore/glue/qeasingcurve_glue.cpp @@ -0,0 +1,120 @@ +#include <Python.h> +#include <shiboken.h> +#include <pysideweakref.h> +#include <QEasingCurve> + +#include "glue/qeasingcurve_glue.h" + +#define __ECF_ATT_NAME__ "__ecf__" +#define MAX_CUSTOM_FUNCTIONS 10 + +static void deleteData(void* data); + +struct CustomFunctionsData +{ + static CustomFunctionsData m_list[MAX_CUSTOM_FUNCTIONS]; + + PySideEasingCurveFunctor* m_obj; + QEasingCurve::EasingFunction m_func; +}; + +CustomFunctionsData CustomFunctionsData::m_list[MAX_CUSTOM_FUNCTIONS]; + +template<int N> +struct CustomFunctions +{ + static void init() + { + CustomFunctionsData data; + data.m_obj = 0; + data.m_func = &CustomFunctions<N>::callback; + CustomFunctionsData::m_list[N] = data; + + CustomFunctions<N-1>::init(); + } + + static qreal callback(qreal v) + { + return (*CustomFunctionsData::m_list[N].m_obj)(v); + } +}; + +template<> +struct CustomFunctions<0> +{ + static void init() + { + CustomFunctionsData data; + data.m_obj = 0; + data.m_func = &CustomFunctions<0>::callback; + CustomFunctionsData::m_list[0] = data; + } + + static qreal callback(qreal v) + { + return (*CustomFunctionsData::m_list[0].m_obj)(v); + } +}; + +void deleteData(void* data) +{ + delete (PySideEasingCurveFunctor*)(data); +} + +void PySideEasingCurveFunctor::init() +{ + CustomFunctions<MAX_CUSTOM_FUNCTIONS>::init(); +} + +QEasingCurve::EasingFunction PySideEasingCurveFunctor::createCustomFuntion(PyObject* parent, PyObject* pyFunc) +{ + for(int i=0; i < MAX_CUSTOM_FUNCTIONS; i++) { + CustomFunctionsData& data = CustomFunctionsData::m_list[i]; + if (data.m_obj == 0) { + data.m_obj = new PySideEasingCurveFunctor(i, parent, pyFunc); + return data.m_func; + } + } + //PyErr_Format(PyExc_RuntimeError, "PySide only supports %d custom functions simultaneously.", MAX_CUSTOM_FUNCTIONS); + return 0; +} + +PySideEasingCurveFunctor::~PySideEasingCurveFunctor() +{ + + CustomFunctionsData::m_list[m_index].m_obj = 0; + PyObject_SetAttrString(m_parent, __ECF_ATT_NAME__, Py_None); +} + +qreal PySideEasingCurveFunctor::operator()(qreal progress) +{ + Shiboken::GilState state; + PyObject* args = Py_BuildValue("(f)", progress); + PyObject* result = PyObject_CallObject(m_func, args); + qreal cppResult = 0.0; + if (result) { + cppResult = Shiboken::Converter<qreal>::toCpp(result); + Py_DECREF(result); + } + Py_DECREF(args); + return cppResult; +} + +PyObject* PySideEasingCurveFunctor::callable() +{ + Py_INCREF(m_func); + return m_func; +} + +PyObject* PySideEasingCurveFunctor::callable(PyObject* parent) +{ + return PyObject_GetAttrString(parent, __ECF_ATT_NAME__); +} + +PySideEasingCurveFunctor::PySideEasingCurveFunctor(int index, PyObject* parent, PyObject* pyFunc) + : m_parent(parent), m_func(pyFunc), m_index(index) +{ + PyObject_SetAttrString(m_parent, __ECF_ATT_NAME__, m_func); + PySide::WeakRef::create(m_parent, deleteData, this); +} + diff --git a/PySide/QtCore/glue/qeasingcurve_glue.h b/PySide/QtCore/glue/qeasingcurve_glue.h new file mode 100644 index 000000000..282e4391d --- /dev/null +++ b/PySide/QtCore/glue/qeasingcurve_glue.h @@ -0,0 +1,27 @@ +#ifndef __QEASINGCURVE_GLUE__ +#define __QEASINGCURVE_GLUE__ + +#include <Python.h> +#include <QEasingCurve> + +class PySideEasingCurveFunctor +{ + public: + static void init(); + static QEasingCurve::EasingFunction createCustomFuntion(PyObject* parent, PyObject* pyFunc); + + qreal operator()(qreal progress); + + PyObject* callable(); //Return New reference + static PyObject* callable(PyObject* parent); //Return New reference + + ~PySideEasingCurveFunctor(); + private: + PyObject* m_parent; + PyObject* m_func; + int m_index; + + PySideEasingCurveFunctor(int index, PyObject* parent, PyObject *pyFunc); +}; + +#endif diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml index 37c246b93..2f16cbe56 100644 --- a/PySide/QtCore/typesystem_core.xml +++ b/PySide/QtCore/typesystem_core.xml @@ -84,6 +84,7 @@ <enum-type name="QtValidLicenseForDeclarativeModule" /> <!-- From Qt4.6 ^^^ --> + <enum-type name="QtMsgType"/> <primitive-type name="qint8"/> @@ -2971,16 +2972,31 @@ </modify-function> </object-type> - <!-- FIXME: setCustomType() actually takes a pointer to function type - (EasingFunction), but for some reason apiextractor thinks it is a float/double: - http://bugs.pyside.org/show_bug.cgi?id=201 - Se also bug: - http://bugs.pyside.org/show_bug.cgi?id=725 - --> - <rejection class="QEasingCurve" function-name="setCustomType" /> + <!-- We will use inject code to implement the function below --> + <rejection class="QEasingCurve" function-name="setCustomType" /> + <rejection class="QEasingCurve" function-name="customType" /> <value-type name="QEasingCurve" since="4.6"> + <extra-includes> + <include file-name="pysideweakref.h" location="global"/> + <include file-name="glue/qeasingcurve_glue.h" location="local"/> + </extra-includes> + <inject-code> + PySideEasingCurveFunctor::init(); + </inject-code> <enum-type name="Type" /> - <modify-function signature="customType() const" remove="all"/> + <add-function signature="setCustomType(PyObject*)"> + <inject-code> + QEasingCurve::EasingFunction func = PySideEasingCurveFunctor::createCustomFuntion(%PYSELF, %PYARG_1); + if (func) + %CPPSELF.%FUNCTION_NAME(func); + </inject-code> + </add-function> + <add-function signature="customType()" return-type="PyObject"> + <inject-code> + //%FUNCTION_NAME() + %PYARG_0 = PySideEasingCurveFunctor::callable(%PYSELF); + </inject-code> + </add-function> </value-type> <object-type name="QEventTransition" since="4.6"> |