mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
Expand effect engine & ui update (#445)
* update
* update
* update
* .
* .
* .
* update
* .
* .
* .
* .
* update
* .
* update
* .
* update
* update
* update
* update
* update
* update
* .
* update
* update
* update
* .
* .
* .
* Revert "."
This reverts commit 4dd6404b32
.
* update
* .
* .
* .
* .
* .
* .
* .
* .
* .
* .
* .
* ...
* .
* .
* .
* .
* .
* .
* .
* .
* .
* update
* update
* update
* remove svg and pic
* colorpicker imgs to base64 to prevent delayed load if not cached
* fix json2python func
* update swirl with rgba
* add double swirl, tune default val in schema, update explanation
* adjust swirl.py
* FileObserver for config checks with timer as fallback (#4)
This commit is contained in:
@@ -26,17 +26,25 @@ PyMethodDef Effect::effectMethods[] = {
|
||||
{"setImage" , Effect::wrapSetImage , METH_VARARGS, "Set a new image to process and determine new led colors."},
|
||||
{"abort" , Effect::wrapAbort , METH_NOARGS, "Check if the effect should abort execution."},
|
||||
{"imageShow" , Effect::wrapImageShow , METH_VARARGS, "set current effect image to hyperion core."},
|
||||
{"imageCanonicalGradient", Effect::wrapImageCanonicalGradient, METH_VARARGS, ""},
|
||||
{"imageLinearGradient" , Effect::wrapImageLinearGradient , METH_VARARGS, ""},
|
||||
{"imageConicalGradient" , Effect::wrapImageConicalGradient , METH_VARARGS, ""},
|
||||
{"imageRadialGradient" , Effect::wrapImageRadialGradient , METH_VARARGS, ""},
|
||||
{"imageSolidFill" , Effect::wrapImageSolidFill , METH_VARARGS, ""},
|
||||
{"imageDrawLine" , Effect::wrapImageDrawLine , METH_VARARGS, ""},
|
||||
{"imageDrawPoint" , Effect::wrapImageDrawPoint , METH_VARARGS, ""},
|
||||
{"imageDrawRect" , Effect::wrapImageDrawRect , METH_VARARGS, ""},
|
||||
{"imageDrawPolygon" , Effect::wrapImageDrawPolygon , METH_VARARGS, ""},
|
||||
{"imageDrawPie" , Effect::wrapImageDrawPie , METH_VARARGS, ""},
|
||||
{"imageSetPixel" , Effect::wrapImageSetPixel , METH_VARARGS, "set pixel color of image"},
|
||||
{"imageGetPixel" , Effect::wrapImageGetPixel , METH_VARARGS, "get pixel color of image"},
|
||||
{"imageSave" , Effect::wrapImageSave , METH_NOARGS, "adds a new background image"},
|
||||
{"imageMinSize" , Effect::wrapImageMinSize , METH_VARARGS, "sets minimal dimension of background image"},
|
||||
{"imageMinSize" , Effect::wrapImageMinSize , METH_VARARGS, "sets minimal dimension of background image"},
|
||||
{"imageWidth" , Effect::wrapImageWidth , METH_NOARGS, "gets image width"},
|
||||
{"imageHeight" , Effect::wrapImageHeight , METH_NOARGS, "gets image height"},
|
||||
{"imageCRotate" , Effect::wrapImageCRotate , METH_VARARGS, "rotate the coordinate system by given angle"},
|
||||
{"imageCOffset" , Effect::wrapImageCOffset , METH_VARARGS, "Add offset to the coordinate system"},
|
||||
{"imageCShear" , Effect::wrapImageCShear , METH_VARARGS, "Shear of coordinate system by the given horizontal/vertical axis"},
|
||||
{"imageResetT" , Effect::wrapImageResetT , METH_NOARGS, "Resets all coords modifications (rotate,offset,shear)"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
@@ -224,6 +232,7 @@ PyObject *Effect::json2python(const QJsonValue &jsonData) const
|
||||
for (QJsonArray::iterator i = arrayData.begin(); i != arrayData.end(); ++i, ++index)
|
||||
{
|
||||
PyObject * obj = json2python(*i);
|
||||
Py_INCREF(obj);
|
||||
PyList_SetItem(list, index, obj);
|
||||
Py_XDECREF(obj);
|
||||
}
|
||||
@@ -452,8 +461,76 @@ PyObject* Effect::wrapImageShow(PyObject *self, PyObject *args)
|
||||
return Py_BuildValue("");
|
||||
}
|
||||
|
||||
PyObject* Effect::wrapImageLinearGradient(PyObject *self, PyObject *args)
|
||||
{
|
||||
Effect * effect = getEffect();
|
||||
|
||||
PyObject* Effect::wrapImageCanonicalGradient(PyObject *self, PyObject *args)
|
||||
int argCount = PyTuple_Size(args);
|
||||
PyObject * bytearray = nullptr;
|
||||
int startRX = 0;
|
||||
int startRY = 0;
|
||||
int startX = 0;
|
||||
int startY = 0;
|
||||
int endX, width = effect->_imageSize.width();
|
||||
int endY, height = effect->_imageSize.height();
|
||||
int spread = 0;
|
||||
|
||||
bool argsOK = false;
|
||||
|
||||
if ( argCount == 10 && PyArg_ParseTuple(args, "iiiiiiiiOi", &startRX, &startRY, &width, &height, &startX, &startY, &endX, &endY, &bytearray, &spread) )
|
||||
{
|
||||
argsOK = true;
|
||||
}
|
||||
if ( argCount == 6 && PyArg_ParseTuple(args, "iiiiOi", &startX, &startY, &endX, &endY, &bytearray, &spread) )
|
||||
{
|
||||
argsOK = true;
|
||||
}
|
||||
|
||||
if (argsOK)
|
||||
{
|
||||
if (PyByteArray_Check(bytearray))
|
||||
{
|
||||
const int length = PyByteArray_Size(bytearray);
|
||||
const unsigned arrayItemLength = 5;
|
||||
if (length % arrayItemLength == 0)
|
||||
{
|
||||
QRect myQRect(startRX,startRY,width,height);
|
||||
QLinearGradient gradient(QPoint(startX,startY), QPoint(endX,endY));
|
||||
char * data = PyByteArray_AS_STRING(bytearray);
|
||||
|
||||
for (int idx=0; idx<length; idx+=arrayItemLength)
|
||||
{
|
||||
gradient.setColorAt(
|
||||
((uint8_t)data[idx])/255.0,
|
||||
QColor(
|
||||
(uint8_t)(data[idx+1]),
|
||||
(uint8_t)(data[idx+2]),
|
||||
(uint8_t)(data[idx+3]),
|
||||
(uint8_t)(data[idx+4])
|
||||
));
|
||||
}
|
||||
|
||||
gradient.setSpread(static_cast<QGradient::Spread>(spread));
|
||||
effect->_painter->fillRect(myQRect, gradient);
|
||||
|
||||
return Py_BuildValue("");
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "Length of bytearray argument should multiple of 5");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "No bytearray properly defined");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* Effect::wrapImageConicalGradient(PyObject *self, PyObject *args)
|
||||
{
|
||||
Effect * effect = getEffect();
|
||||
|
||||
@@ -527,30 +604,30 @@ PyObject* Effect::wrapImageRadialGradient(PyObject *self, PyObject *args)
|
||||
|
||||
int argCount = PyTuple_Size(args);
|
||||
PyObject * bytearray = nullptr;
|
||||
int centerX, centerY, radius, focalX, focalY, focalRadius;
|
||||
int centerX, centerY, radius, focalX, focalY, focalRadius, spread;
|
||||
int startX = 0;
|
||||
int startY = 0;
|
||||
int width = effect->_imageSize.width();
|
||||
int height = effect->_imageSize.height();
|
||||
|
||||
bool argsOK = false;
|
||||
|
||||
if ( argCount == 11 && PyArg_ParseTuple(args, "iiiiiiiiiiO", &startX, &startY, &width, &height, ¢erX, ¢erY, &radius, &focalX, &focalY, &focalRadius, &bytearray) )
|
||||
|
||||
if ( argCount == 12 && PyArg_ParseTuple(args, "iiiiiiiiiiOi", &startX, &startY, &width, &height, ¢erX, ¢erY, &radius, &focalX, &focalY, &focalRadius, &bytearray, &spread) )
|
||||
{
|
||||
argsOK = true;
|
||||
}
|
||||
if ( argCount == 8 && PyArg_ParseTuple(args, "iiiiiiiO", &startX, &startY, &width, &height, ¢erX, ¢erY, &radius, &bytearray) )
|
||||
}
|
||||
if ( argCount == 9 && PyArg_ParseTuple(args, "iiiiiiiOi", &startX, &startY, &width, &height, ¢erX, ¢erY, &radius, &bytearray, &spread) )
|
||||
{
|
||||
argsOK = true;
|
||||
focalX = centerX;
|
||||
focalY = centerY;
|
||||
focalRadius = radius;
|
||||
}
|
||||
if ( argCount == 7 && PyArg_ParseTuple(args, "iiiiiiO", ¢erX, ¢erY, &radius, &focalX, &focalY, &focalRadius, &bytearray) )
|
||||
if ( argCount == 8 && PyArg_ParseTuple(args, "iiiiiiOi", ¢erX, ¢erY, &radius, &focalX, &focalY, &focalRadius, &bytearray, &spread) )
|
||||
{
|
||||
argsOK = true;
|
||||
}
|
||||
if ( argCount == 4 && PyArg_ParseTuple(args, "iiiO", ¢erX, ¢erY, &radius, &bytearray) )
|
||||
if ( argCount == 5 && PyArg_ParseTuple(args, "iiiOi", ¢erX, ¢erY, &radius, &bytearray, &spread) )
|
||||
{
|
||||
argsOK = true;
|
||||
focalX = centerX;
|
||||
@@ -581,7 +658,7 @@ PyObject* Effect::wrapImageRadialGradient(PyObject *self, PyObject *args)
|
||||
));
|
||||
}
|
||||
|
||||
//gradient.setSpread(QGradient::ReflectSpread);
|
||||
gradient.setSpread(static_cast<QGradient::Spread>(spread));
|
||||
effect->_painter->fillRect(myQRect, gradient);
|
||||
|
||||
return Py_BuildValue("");
|
||||
@@ -601,6 +678,160 @@ PyObject* Effect::wrapImageRadialGradient(PyObject *self, PyObject *args)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* Effect::wrapImageDrawPolygon(PyObject *self, PyObject *args)
|
||||
{
|
||||
Effect * effect = getEffect();
|
||||
PyObject * bytearray = nullptr;
|
||||
|
||||
int argCount = PyTuple_Size(args);
|
||||
int r, g, b;
|
||||
int a = 255;
|
||||
|
||||
bool argsOK = false;
|
||||
|
||||
if ( argCount == 5 && PyArg_ParseTuple(args, "Oiiii", &bytearray, &r, &g, &b, &a) )
|
||||
{
|
||||
argsOK = true;
|
||||
}
|
||||
if ( argCount == 4 && PyArg_ParseTuple(args, "Oiii", &bytearray, &r, &g, &b) )
|
||||
{
|
||||
argsOK = true;
|
||||
}
|
||||
|
||||
if (argsOK)
|
||||
{
|
||||
if (PyByteArray_Check(bytearray))
|
||||
{
|
||||
int length = PyByteArray_Size(bytearray);
|
||||
if (length % 2 == 0)
|
||||
{
|
||||
QVector <QPoint> points;
|
||||
char * data = PyByteArray_AS_STRING(bytearray);
|
||||
|
||||
for (int idx=0; idx<length; idx+=2)
|
||||
{
|
||||
points.append(QPoint((int)(data[idx]),(int)(data[idx+1])));
|
||||
}
|
||||
|
||||
QPainter * painter = effect->_painter;
|
||||
QPen oldPen = painter->pen();
|
||||
QPen newPen(QColor(r,g,b,a));
|
||||
painter->setPen(newPen);
|
||||
painter->setBrush(QBrush(QColor(r,g,b,a), Qt::SolidPattern));
|
||||
painter->drawPolygon(points);
|
||||
painter->setPen(oldPen);
|
||||
return Py_BuildValue("");
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "Length of bytearray argument should multiple of 2");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "Argument 1 is not a bytearray");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* Effect::wrapImageDrawPie(PyObject *self, PyObject *args)
|
||||
{
|
||||
Effect * effect = getEffect();
|
||||
PyObject * bytearray = nullptr;
|
||||
|
||||
QString brush;
|
||||
int argCount = PyTuple_Size(args);
|
||||
int radius, centerX, centerY;
|
||||
int startAngle = 0;
|
||||
int spanAngle = 360;
|
||||
int r = 0;
|
||||
int g = 0;
|
||||
int b = 0;
|
||||
int a = 255;
|
||||
|
||||
bool argsOK = false;
|
||||
|
||||
if ( argCount == 9 && PyArg_ParseTuple(args, "iiiiiiiii", ¢erX, ¢erY, &radius, &startAngle, &spanAngle, &r, &g, &b, &a) )
|
||||
{
|
||||
argsOK = true;
|
||||
}
|
||||
if ( argCount == 8 && PyArg_ParseTuple(args, "iiiiiiii", ¢erX, ¢erY, &radius, &startAngle, &spanAngle, &r, &g, &b) )
|
||||
{
|
||||
argsOK = true;
|
||||
}
|
||||
if ( argCount == 7 && PyArg_ParseTuple(args, "iiiiisO", ¢erX, ¢erY, &radius, &startAngle, &spanAngle, &brush, &bytearray) )
|
||||
{
|
||||
argsOK = true;
|
||||
}
|
||||
if ( argCount == 5 && PyArg_ParseTuple(args, "iiisO", ¢erX, ¢erY, &radius, &brush, &bytearray) )
|
||||
{
|
||||
argsOK = true;
|
||||
}
|
||||
|
||||
if (argsOK)
|
||||
{
|
||||
QPainter * painter = effect->_painter;
|
||||
startAngle = std::max(std::min(startAngle,360),0);
|
||||
spanAngle = std::max(std::min(spanAngle,360),-360);
|
||||
|
||||
if( argCount == 7 || argCount == 5 )
|
||||
{
|
||||
a = 0;
|
||||
if (PyByteArray_Check(bytearray))
|
||||
{
|
||||
int length = PyByteArray_Size(bytearray);
|
||||
if (length % 5 == 0)
|
||||
{
|
||||
|
||||
QConicalGradient gradient(QPoint(centerX,centerY), startAngle);
|
||||
|
||||
|
||||
char * data = PyByteArray_AS_STRING(bytearray);
|
||||
|
||||
for (int idx=0; idx<length; idx+=5)
|
||||
{
|
||||
gradient.setColorAt(
|
||||
((uint8_t)data[idx])/255.0,
|
||||
QColor(
|
||||
(uint8_t)(data[idx+1]),
|
||||
(uint8_t)(data[idx+2]),
|
||||
(uint8_t)(data[idx+3]),
|
||||
(uint8_t)(data[idx+4])
|
||||
));
|
||||
}
|
||||
painter->setBrush(gradient);
|
||||
|
||||
return Py_BuildValue("");
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "Length of bytearray argument should multiple of 5");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "Last argument is not a bytearray");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
painter->setBrush(QBrush(QColor(r,g,b,a), Qt::SolidPattern));
|
||||
}
|
||||
QPen oldPen = painter->pen();
|
||||
QPen newPen(QColor(r,g,b,a));
|
||||
painter->setPen(newPen);
|
||||
painter->drawPie(centerX - radius, centerY - radius, centerX + radius, centerY + radius, startAngle * 16, spanAngle * 16);
|
||||
painter->setPen(oldPen);
|
||||
return Py_BuildValue("");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* Effect::wrapImageSolidFill(PyObject *self, PyObject *args)
|
||||
{
|
||||
Effect * effect = getEffect();
|
||||
@@ -682,6 +913,40 @@ PyObject* Effect::wrapImageDrawLine(PyObject *self, PyObject *args)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* Effect::wrapImageDrawPoint(PyObject *self, PyObject *args)
|
||||
{
|
||||
Effect * effect = getEffect();
|
||||
|
||||
int argCount = PyTuple_Size(args);
|
||||
int r, g, b, x, y;
|
||||
int a = 255;
|
||||
int thick = 1;
|
||||
|
||||
bool argsOK = false;
|
||||
|
||||
if ( argCount == 7 && PyArg_ParseTuple(args, "iiiiiii", &x, &y, &thick, &r, &g, &b, &a) )
|
||||
{
|
||||
argsOK = true;
|
||||
}
|
||||
if ( argCount == 6 && PyArg_ParseTuple(args, "iiiiii", &x, &y, &thick, &r, &g, &b) )
|
||||
{
|
||||
argsOK = true;
|
||||
}
|
||||
|
||||
if (argsOK)
|
||||
{
|
||||
QPainter * painter = effect->_painter;
|
||||
QPen oldPen = painter->pen();
|
||||
QPen newPen(QColor(r,g,b,a));
|
||||
newPen.setWidth(thick);
|
||||
painter->setPen(newPen);
|
||||
painter->drawPoint(x, y);
|
||||
painter->setPen(oldPen);
|
||||
|
||||
return Py_BuildValue("");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* Effect::wrapImageDrawRect(PyObject *self, PyObject *args)
|
||||
{
|
||||
@@ -801,6 +1066,62 @@ PyObject* Effect::wrapImageHeight(PyObject *self, PyObject *args)
|
||||
return Py_BuildValue("i", effect->_imageSize.height());
|
||||
}
|
||||
|
||||
PyObject* Effect::wrapImageCRotate(PyObject *self, PyObject *args)
|
||||
{
|
||||
Effect * effect = getEffect();
|
||||
|
||||
int argCount = PyTuple_Size(args);
|
||||
int angle;
|
||||
|
||||
if ( argCount == 1 && PyArg_ParseTuple(args, "i", &angle ) )
|
||||
{
|
||||
angle = std::max(std::min(angle,360),0);
|
||||
effect->_painter->rotate(angle);
|
||||
return Py_BuildValue("");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* Effect::wrapImageCOffset(PyObject *self, PyObject *args)
|
||||
{
|
||||
Effect * effect = getEffect();
|
||||
|
||||
int offsetX = 0;
|
||||
int offsetY = 0;
|
||||
int argCount = PyTuple_Size(args);
|
||||
|
||||
if ( argCount == 2 )
|
||||
{
|
||||
PyArg_ParseTuple(args, "ii", &offsetX, &offsetY );
|
||||
}
|
||||
|
||||
effect->_painter->translate(QPoint(offsetX,offsetY));
|
||||
return Py_BuildValue("");
|
||||
}
|
||||
|
||||
PyObject* Effect::wrapImageCShear(PyObject *self, PyObject *args)
|
||||
{
|
||||
Effect * effect = getEffect();
|
||||
|
||||
int sh,sv;
|
||||
int argCount = PyTuple_Size(args);
|
||||
|
||||
if ( argCount == 2 && PyArg_ParseTuple(args, "ii", &sh, &sv ))
|
||||
{
|
||||
effect->_painter->shear(sh,sv);
|
||||
return Py_BuildValue("");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* Effect::wrapImageResetT(PyObject *self, PyObject *args)
|
||||
{
|
||||
Effect * effect = getEffect();
|
||||
|
||||
effect->_painter->resetTransform();
|
||||
return Py_BuildValue("");
|
||||
}
|
||||
|
||||
Effect * Effect::getEffect()
|
||||
{
|
||||
// extract the module from the runtime
|
||||
|
Reference in New Issue
Block a user