Cleanup top-level directory.

main
Ben Niemann 2021-11-22 04:35:14 +01:00
parent b2ea8b14bf
commit 50d6be3954
31 changed files with 35 additions and 1149 deletions

2
.gitignore vendored
View File

@ -5,6 +5,6 @@
/.lock-waf*
/build/
/result
/src/.lock-waf_linux_build
/flatpy/flatpy.egg-info/
/flatpy/.env/
/playground/

136
Node.qml
View File

@ -1,136 +0,0 @@
import QtQuick 2.12
//import QtQuick.Controls 2.12
import QtGraphicalEffects 1.15
Item {
id: node
default property alias children: body.children;
property QtObject d
property var fontSize: 14
x: d.rect.x
y: d.rect.y
z: d.active ? 1 : 0
width: d.rect.width
height: d.rect.height
// Swallow all unhandled click events anywhere in the node.
MouseArea {
anchors.fill: parent
onPressed: {
d.active = true;
}
}
Rectangle {
id: frame
anchors.fill: parent
color: "#eeeeee"
border { width: 1; color: d.active ? "#666666" : "#cccccc" }
// The title bar
Rectangle {
id: header
height: fontSize + 8
anchors {
top: parent.top
left: parent.left
right: parent.right
topMargin: 1
leftMargin: 1
rightMargin: 1
}
color: "#aaaaff"
// Drag the node by clicking the title bar.
MouseArea {
id: dragArea
anchors.fill: parent
drag.threshold: 0
cursorShape: Qt.OpenHandCursor
property var cx: 0
property var cy: 0
onPressed: {
d.active = true;
cx = mouse.x;
cy = mouse.y;
}
onPositionChanged: {
d.rect = Qt.rect(
Math.floor(d.rect.x + mouse.x - cx),
Math.floor(d.rect.y + mouse.y - cy),
d.rect.width, d.rect.height);
}
}
Item {
anchors.fill: parent
anchors.leftMargin: 4
anchors.rightMargin: 4
clip: true
Text {
text: d.title
color: "#000000"
font.pixelSize: fontSize
}
}
}
Item {
id: body
anchors {
top: header.bottom
bottom: parent.bottom
left: parent.left
right: parent.right
margins: 3
}
}
// Make the node resizable.
Rectangle {
width: 20
height: 20
anchors {
right: parent.right
bottom: parent.bottom
rightMargin: 1
bottomMargin: 1
}
color: "#aaaaff"
MouseArea {
anchors.fill: parent
drag.threshold: 0
cursorShape: Qt.SizeFDiagCursor
property var cx: 0
property var cy: 0
onPressed: {
d.active = true;
cx = mouse.x;
cy = mouse.y;
}
onPositionChanged: {
d.rect = Qt.rect(
d.rect.x, d.rect.y,
Math.max(Math.floor(d.rect.width + mouse.x - cx), 50),
Math.max(Math.floor(d.rect.height + mouse.y - cy), 50));
}
}
}
}
DropShadow {
visible: d.active
anchors.fill: parent
horizontalOffset: 1
verticalOffset: 1
radius: 12.0
samples: 17
color: "#806666aa"
source: frame
}
}

View File

@ -2,6 +2,9 @@
set -e
ROOT="$(realpath "$(dirname "$0")/..")"
cd "$ROOT"
./waf build
# This is suboptimal, but necessary, so it doesn't import the modules from the src directory. But

8
bin/pytest Executable file
View File

@ -0,0 +1,8 @@
#!/bin/bash
set -e
ROOT="$(realpath "$(dirname "$0")/..")"
cd "${ROOT}/build"
pytest -c../etc/pytest.ini "$@"

15
bin/update-waf Executable file
View File

@ -0,0 +1,15 @@
#!/bin/bash
set -e
VERSION=2.0.22
ROOT="$(realpath "$(dirname "$0")/..")"
mkdir -p build
cd "${ROOT}/build"
rm -fr waf-*
wget https://waf.io/waf-${VERSION}.tar.bz2
tar xjf waf-${VERSION}.tar.bz2
cd waf-${VERSION}
python3 ./waf-light --tools=gccdeps configure build
cp waf ../../

View File

@ -44,8 +44,8 @@ let
# overrides to include work with qtquickcontrols, ...). Let's filter it (and possibly other
# packages) out and install them directly from nixpkgs (see PYTHONPATH below).
requirements = let
req-runtime = lib.strings.splitString "\n" (builtins.readFile ./requirements.txt);
req-dev = lib.strings.splitString "\n" (builtins.readFile ./requirements-dev.txt);
req-runtime = lib.strings.splitString "\n" (builtins.readFile ./etc/requirements.txt);
req-dev = lib.strings.splitString "\n" (builtins.readFile ./etc/requirements-dev.txt);
req-all = req-runtime ++ (lib.lists.optionals withTests req-dev);
blacklist = [ "pyside2" ];
is_blacklisted = l: builtins.any (pkg: !isNull (builtins.match (pkg + "=.*") l)) blacklist;

View File

@ -3,4 +3,4 @@ import os.path
def pytest_configure(config):
plugin = config.pluginmanager.getplugin('mypy')
plugin.mypy_argv.append(
'--config-file=' + os.path.join(os.path.dirname(__file__), 'mypy.ini'))
'--config-file=' + os.path.join(os.path.dirname(__file__), '..', '..', 'etc', 'mypy.ini'))

View File

@ -24,6 +24,8 @@ def build(ctx):
ctx.py_module('logging.py')
ctx.cy_module('logsink.pyx', use=['noisicaa-core'])
ctx.py_test('conftest.py')
ctx.recurse('core')
ctx.recurse('engine')
ctx.recurse('model')

View File

@ -1,116 +0,0 @@
# @begin:license
#
# Copyright (c) 2015-2019, Benjamin Niemann <pink@odahoda.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# @end:license
import asyncio
import os.path
import subprocess
import sys
import traceback
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'build', 'src'))
import flatbuffers # type: ignore
import grpc.aio # type: ignore
from noisicaa.core.status import Error
import noisicaa.engine.server
from noisicaa.engine import engine_notification_generated as engine_notification_fb
from noisicaa.engine import backend_settings_generated as backend_settings_fb
from noisicaa.engine import server_generated as server_fb
from noisicaa.engine import server_grpc_fb
SOCKET = "unix:/tmp/noisicaa-playground"
def make_empty_message():
builder = flatbuffers.Builder(100)
builder.Finish(server_fb.CreateEmptyMessage(builder))
return bytes(builder.Output())
def check_status_response(response):
if not response.ok:
raise Error(response.msg.decode('utf-8'))
async def listener(stub):
async for response_dat in stub.GetNotifications(make_empty_message()):
response = engine_notification_fb.EngineNotification(response_dat)
if response.msg_type == engine_notification_fb.EngineNotificationPayload.block_stats:
block_stats = engine_notification_fb.BlockStats(response.msg)
print("load=%.2f%%" % (100.0 * block_stats.load))
else:
print(response.msg_type)
print("notifications done")
async def main():
meter = subprocess.Popen(["meterbridge", "-t", "sco", "-n", "noisicaa-meter", "foo", "foo"])
await asyncio.sleep(1)
server = noisicaa.engine.server.Server()
server.start(SOCKET)
try:
channel = grpc.aio.insecure_channel(SOCKET)
stub = server_grpc_fb.EngineServiceStub(channel)
listener_task = asyncio.create_task(listener(stub))
builder = flatbuffers.Builder(1024)
request_offset = backend_settings_fb.CreateBackendSettings(
builder,
name='jack',
connect_ports=['noisicaa-meter:meter_1', 'noisicaa-meter:meter_2'])
builder.Finish(request_offset)
request_dat = bytes(builder.Output())
response_dat = await stub.SetBackend(request_dat)
response = server_fb.StatusResponse(response_dat)
check_status_response(response)
builder = flatbuffers.Builder(1024)
request_offset = server_fb.CreateStartEngineRequest(builder)
builder.Finish(request_offset)
request_dat = bytes(builder.Output())
response_dat = await stub.StartEngine(request_dat)
response = server_fb.StatusResponse(response_dat)
check_status_response(response)
await asyncio.sleep(3)
response_dat = await stub.StopEngine(make_empty_message())
response = server_fb.StatusResponse(response_dat)
check_status_response(response)
await listener_task
except Exception: # pylint: disable=broad-except
traceback.print_exc()
finally:
server.stop()
meter.terminate()
meter.wait()
return 0
if __name__ == '__main__':
loop = asyncio.get_event_loop()
rc = loop.run_until_complete(main())
sys.exit(rc)

5
pytest
View File

@ -1,5 +0,0 @@
#!/bin/bash
set -e
cd build
pytest -c../pytest.ini "$@"

View File

View File

@ -1,112 +0,0 @@
#include "beziercurve.h"
#include <QtQuick/qsgnode.h>
#include <QtQuick/qsgflatcolormaterial.h>
BezierCurve::BezierCurve(QQuickItem *parent)
: QQuickItem(parent)
, m_p1(0, 0)
, m_p2(1, 0)
, m_p3(0, 1)
, m_p4(1, 1)
, m_segmentCount(256)
{
setFlag(ItemHasContents, true);
}
BezierCurve::~BezierCurve()
{
}
void BezierCurve::setP1(const QPointF &p)
{
if (p == m_p1)
return;
m_p1 = p;
emit p1Changed(p);
update();
}
void BezierCurve::setP2(const QPointF &p)
{
if (p == m_p2)
return;
m_p2 = p;
emit p2Changed(p);
update();
}
void BezierCurve::setP3(const QPointF &p)
{
if (p == m_p3)
return;
m_p3 = p;
emit p3Changed(p);
update();
}
void BezierCurve::setP4(const QPointF &p)
{
if (p == m_p4)
return;
m_p4 = p;
emit p4Changed(p);
update();
}
void BezierCurve::setSegmentCount(int count)
{
if (m_segmentCount == count)
return;
m_segmentCount = count;
emit segmentCountChanged(count);
update();
}
QSGNode *BezierCurve::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
QSGGeometryNode *node = nullptr;
QSGGeometry *geometry = nullptr;
if (!oldNode) {
node = new QSGGeometryNode;
geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), m_segmentCount);
geometry->setLineWidth(4);
geometry->setDrawingMode(QSGGeometry::DrawLineStrip);
node->setGeometry(geometry);
node->setFlag(QSGNode::OwnsGeometry);
QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
material->setColor(QColor(60, 60, 60));
node->setMaterial(material);
node->setFlag(QSGNode::OwnsMaterial);
} else {
node = static_cast<QSGGeometryNode *>(oldNode);
geometry = node->geometry();
geometry->allocate(m_segmentCount);
}
QSizeF itemSize = size();
QSGGeometry::Point2D *vertices = geometry->vertexDataAsPoint2D();
for (int i = 0; i < m_segmentCount; ++i) {
qreal t = i / qreal(m_segmentCount - 1);
qreal invt = 1 - t;
QPointF pos = invt * invt * invt * m_p1
+ 3 * invt * invt * t * m_p2
+ 3 * invt * t * t * m_p3
+ t * t * t * m_p4;
float x = pos.x() * itemSize.width();
float y = pos.y() * itemSize.height();
vertices[i].set(x, y);
}
node->markDirty(QSGNode::DirtyGeometry);
return node;
}

View File

@ -1,112 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the demonstration applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef BEZIERCURVE_H
#define BEZIERCURVE_H
//! [1]
#include <QtQuick/QQuickItem>
class BezierCurve : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(QPointF p1 READ p1 WRITE setP1 NOTIFY p1Changed)
Q_PROPERTY(QPointF p2 READ p2 WRITE setP2 NOTIFY p2Changed)
Q_PROPERTY(QPointF p3 READ p3 WRITE setP3 NOTIFY p3Changed)
Q_PROPERTY(QPointF p4 READ p4 WRITE setP4 NOTIFY p4Changed)
Q_PROPERTY(int segmentCount READ segmentCount WRITE setSegmentCount NOTIFY segmentCountChanged)
//! [3]
QML_ELEMENT
//! [3]
public:
BezierCurve(QQuickItem *parent = 0);
~BezierCurve();
//! [2]
QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
//! [2]
QPointF p1() const { return m_p1; }
QPointF p2() const { return m_p2; }
QPointF p3() const { return m_p3; }
QPointF p4() const { return m_p4; }
int segmentCount() const { return m_segmentCount; }
void setP1(const QPointF &p);
void setP2(const QPointF &p);
void setP3(const QPointF &p);
void setP4(const QPointF &p);
void setSegmentCount(int count);
signals:
void p1Changed(const QPointF &p);
void p2Changed(const QPointF &p);
void p3Changed(const QPointF &p);
void p4Changed(const QPointF &p);
void segmentCountChanged(int count);
private:
QPointF m_p1;
QPointF m_p2;
QPointF m_p3;
QPointF m_p4;
int m_segmentCount;
};
//! [1]
#endif

View File

@ -1,5 +0,0 @@
<RCC>
<qresource prefix="/scenegraph/customgeometry">
<file>main.qml</file>
</qresource>
</RCC>

View File

@ -1,73 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the demonstration applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtGui>
#include <QtQuick>
#include "beziercurve.h"
//! [1]
int main(int argc, char **argv)
{
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
qmlRegisterType<BezierCurve>("CustomGeometry", 1, 0, "BezierCurve");
QQuickView view;
QSurfaceFormat format = view.format();
format.setSamples(16);
view.setFormat(format);
view.setSource(QUrl("qrc:///scenegraph/customgeometry/main.qml"));
view.show();
return app.exec();
}
//! [1]

View File

@ -1,85 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the demonstration applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
//! [1]
import QtQuick 2.0
import CustomGeometry 1.0
//! [1] //! [2]
Item {
width: 300
height: 200
BezierCurve {
id: line
anchors.fill: parent
anchors.margins: 20
//! [2] //! [3]
property real t
SequentialAnimation on t {
NumberAnimation { to: 1; duration: 2000; easing.type: Easing.InOutQuad }
NumberAnimation { to: 0; duration: 2000; easing.type: Easing.InOutQuad }
loops: Animation.Infinite
}
p2: Qt.point(t, 1 - t)
p3: Qt.point(1 - t, t)
}
//! [3] //! [4]
Text {
anchors.bottom: line.bottom
x: 20
width: parent.width - 40
wrapMode: Text.WordWrap
text: "This curve is a custom scene graph item, implemented using GL_LINE_STRIP"
}
}
//! [4]

View File

@ -1,5 +0,0 @@
from . cimport registry
def registerTypes():
registry.registerTypes()

View File

@ -1,63 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the demonstration applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtGui>
#include <QtQuick>
#include "beziercurve.h"
namespace noisicaa {
void registerTypes() {
qmlRegisterType<BezierCurve>("Noisicaa", 1, 0, "BezierCurve");
}
}

View File

@ -1,6 +0,0 @@
namespace noisicaa {
void registerTypes();
}

View File

@ -1,4 +0,0 @@
cdef extern from "q/registry.h" namespace "noisicaa" nogil:
void registerTypes()

View File

@ -1,18 +0,0 @@
def build(ctx):
ctx.shlib(
features = 'qt5 cxx cxxshlib',
uselib = 'QT5CORE QT5GUI QT5QUICK',
source = [
'beziercurve.cpp',
'registry.cpp',
],
moc = [
'beziercurve.h',
],
target = 'noisicaa-qml-extensions',
)
ctx.py_module('__init__.py')
ctx.cy_module('qml_extensions.pyx', use=['noisicaa-qml-extensions'])

309
quick.py
View File

@ -1,309 +0,0 @@
from pprint import pprint
import os.path
import random
import sys
import time
from PySide2.QtCore import Qt
from PySide2 import QtCore
from PySide2 import QtGui
from PySide2 import QtQuick
from PySide2 import QtQml
sys.path.insert(0, 'build')
from q import qml_extensions
a = QtGui.QGuiApplication([])
view = QtQuick.QQuickView()
view.setResizeMode(QtQuick.QQuickView.SizeRootObjectToView)
format = QtGui.QSurfaceFormat(view.format())
format.setSamples(16)
view.setFormat(format)
qml_extensions.registerTypes()
class Node(QtCore.QObject):
def __init__(self, title):
super().__init__()
self.__title = title
self.__rect = QtCore.QRectF()
self.__active = False
self.setRect(QtCore.QRectF(random.randint(100, 1000), random.randint(100, 800), random.randint(100, 200), random.randint(100, 200)))
def getTitle(self):
return self.__title
def setTitle(self, t):
self.__title = t
self.titleChanged.emit(t)
titleChanged = QtCore.Signal(str)
title = QtCore.Property(str, fget=getTitle, fset=setTitle, notify=titleChanged)
def getRect(self):
return self.__rect
def setRect(self, r):
self.__rect = r
self.rectChanged.emit(r)
rectChanged = QtCore.Signal(QtCore.QRectF)
rect = QtCore.Property(QtCore.QRectF, fget=getRect, fset=setRect, notify=rectChanged)
def isActive(self):
return self.__active
def setActive(self, v):
self.__active = v
if self.__active:
for n in nodes:
if n is not self:
n.active = False
self.activeChanged.emit(v)
activeChanged = QtCore.Signal(bool)
active = QtCore.Property(bool, fget=isActive, fset=setActive, notify=activeChanged)
class Connection(QtCore.QObject):
def __init__(self, n1, n2):
super().__init__()
self.__p1 = QtCore.QPointF()
self.__p2 = QtCore.QPointF()
self.__n1 = n1
self.__updateP1(n1.rect)
self.__n1.rectChanged.connect(self.__updateP1)
self.__n2 = n2
self.__updateP2(n2.rect)
self.__n2.rectChanged.connect(self.__updateP2)
def __updateP1(self, r):
self.setP1(QtCore.QPointF(r.right(), (r.bottom() + r.top()) // 2))
def __updateP2(self, r):
self.setP2(QtCore.QPointF(r.left(), (r.bottom() + r.top()) // 2))
def getP1(self):
return self.__p1
def setP1(self, r):
self.__p1 = r
self.p1Changed.emit(r)
p1Changed = QtCore.Signal(QtCore.QPointF)
p1 = QtCore.Property(QtCore.QPointF, fget=getP1, fset=setP1, notify=p1Changed)
def getP2(self):
return self.__p2
def setP2(self, r):
self.__p2 = r
self.p2Changed.emit(r)
p2Changed = QtCore.Signal(QtCore.QPointF)
p2 = QtCore.Property(QtCore.QPointF, fget=getP2, fset=setP2, notify=p2Changed)
my_model = QtCore.QStringListModel()
my_model.setStringList(["foo", "bar"])
view.rootContext().setContextProperty("strings",my_model)
# nodes = [
# Node("n%d" % i) for i in range(1000)
# ]
class ObjectList(QtCore.QAbstractListModel):
def __init__(self):
super().__init__()
self.__list = []
def __iter__(self):
yield from self.__list
def __len__(self):
return len(self.__list)
def __getitem__(self, idx):
return self.__list[idx]
def rowCount(self, parent=QtCore.QModelIndex()):
return len(self.__list)
def data(self, index, role=Qt.DisplayRole):
if role != Qt.DisplayRole:
return None
if not index.isValid():
return None
if index.row() < 0 or index.row() >= len(self.__list):
return None
return self.__list[index.row()]
def insertObject(self, row, obj):
self.beginInsertRows(QtCore.QModelIndex(), row, row)
self.__list.insert(row, obj)
self.endInsertRows()
nodes = ObjectList()
view.rootContext().setContextProperty("nodes", nodes)
connections = ObjectList()
view.rootContext().setContextProperty("connections", connections)
node_idx = 0
def add_node():
global node_idx
node = Node('n{}'.format(node_idx))
nodes.insertObject(len(nodes), node)
if nodes.rowCount() > 2:
for i in range(random.randint(1, nodes.rowCount() // 2)):
connections.insertObject(len(connections), Connection(nodes[random.randint(0, nodes.rowCount() - 2)], node))
node_idx += 1
insert_timer = QtCore.QTimer(a)
insert_timer.timeout.connect(add_node)
insert_timer.start(200)
frames = []
next_update = time.time()
def swapped():
frames.append(time.perf_counter_ns())
if len(frames) > 10:
frames.pop(0)
global next_update
if len(frames) > 2 and time.time() >= next_update:
ns_per_frame = (frames[-1] - frames[0]) / (len(frames) - 1)
fps = 1e9 / ns_per_frame
view.rootContext().setContextProperty("fps", '%.2f fps' % fps)
next_update = time.time() + 0.5
view.frameSwapped.connect(swapped)
view.rootContext().setContextProperty("fps", '')
# class Connection(QtQuick.QQuickItem):
# def __init__(self, parent=None):
# super().__init__(parent)
# self.setFlag(QtQuick.QQuickItem.ItemHasContents, True)
# self.__p1 = QtCore.QPointF(0, 0)
# self.__p2 = QtCore.QPointF(20, 0)
# self.__p3 = QtCore.QPointF(80, 90)
# self.__p4 = QtCore.QPointF(100, 100)
# self.__segmentCount = 20
# def updatePaintNode(self, oldNode: QtQuick.QSGNode, data: QtQuick.QQuickItem.UpdatePaintNodeData):
# node = None # type: QtQuick.QSGGeometryNode
# geometry = None # type: QtQuick.QSGGeometry
# if oldNode is None:
# node = QtQuick.QSGGeometryNode()
# geometry = QtQuick.QSGGeometry(QtQuick.QSGGeometry.defaultAttributes_Point2D(), self.__segmentCount)
# geometry.setLineWidth(2)
# geometry.setDrawingMode(QtQuick.QSGGeometry.DrawLineStrip)
# node.setGeometry(geometry)
# node.setFlag(QtQuick.QSGNode.OwnsGeometry)
# # material = QtQuick.QSGFlatColorMaterial()
# # material.setColor(QtGui.QColor(255, 0, 0))
# # node.setMaterial(material)
# # node.setFlag(QtQuick.QSGNode.OwnsMaterial)
# else:
# node = oldNode
# geometry = node.geometry()
# geometry.allocate(self.__segmentCount)
# # QSizeF itemSize = size();
# # QSGGeometry::Point2D *vertices = geometry->vertexDataAsPoint2D();
# # for (int i = 0; i < m_segmentCount; ++i) {
# # qreal t = i / qreal(m_segmentCount - 1);
# # qreal invt = 1 - t;
# # QPointF pos = invt * invt * invt * m_p1
# # + 3 * invt * invt * t * m_p2
# # + 3 * invt * t * t * m_p3
# # + t * t * t * m_p4;
# # float x = pos.x() * itemSize.width();
# # float y = pos.y() * itemSize.height();
# # vertices[i].set(x, y);
# # }
# node.markDirty(QtQuick.QSGNode.DirtyGeometry)
# return node
# QtQml.qmlRegisterType(Connection, 'Noisicaa', 1, 0, 'Connection')
qml = '''\
import QtQuick 2.12
import QtQuick.Controls 2.12
Page {
width: parent != null ? parent.width : 640
height: parent != null ? parent.height : 480
header: Label {
//color: "#15af15"
text: qsTr("Where do people use Qt?")
//font.pointSize: 17
//font.bold: true
//font.family: "Arial"
renderType: Text.NativeRendering
horizontalAlignment: Text.AlignHCenter
padding: 10
}
Rectangle {
id: root
width: parent.width
height: parent.height
Image {
id: image
fillMode: Image.PreserveAspectFit
anchors.centerIn: root
source: "./logo.png"
opacity: 0.5
}
ListView {
id: view
anchors.fill: root
anchors.margins: 25
model: myModel
delegate: Text {
anchors.leftMargin: 50
//font.pointSize: 15
horizontalAlignment: Text.AlignHCenter
text: display
}
}
}
NumberAnimation {
id: anim
running: true
target: view
property: "contentY"
duration: 500
}
}
'''
# https://forum.qt.io/topic/64046/can-you-create-qml-from-a-string-byte-array/6
# comp = QtQml.QQmlComponent(view.engine())
# comp.setData(qml.encode('utf-8'), QtCore.QUrl.fromLocalFile(__file__))
# item = comp.create()
# item.setParentItem(view.contentItem())
qml_file = os.path.join(os.path.dirname(__file__),"view.qml")
view.setSource(QtCore.QUrl.fromLocalFile(os.path.abspath(qml_file)))
#Show the window
if view.status() == QtQuick.QQuickView.Error:
sys.exit(-1)
view.show()
a.exec_()
view.hide()
del view

View File

@ -1,90 +0,0 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import Noisicaa 1.0
Rectangle {
width: 1600
height: 1200
color: "#aaffaa"
Rectangle {
color: "#ffffff"
border { width: 1; color: "#aaaaaa" }
anchors {
fill: parent
margins: 10
}
MouseArea {
anchors.fill: parent
onPressed: {
for (var i = 0 ; i < nodes.rowCount() ; ++i ) {
var node = nodes.data(nodes.index(i, 0));
node.active = false;
}
}
onWheel: {
if (wheel.angleDelta.y > 0) {
canvas.x = Math.floor(wheel.x + (canvas.x - wheel.x) * 1.2);
canvas.y = Math.floor(wheel.y + (canvas.y - wheel.y) * 1.2);
canvas.scale *= 1.2;
} else {
canvas.x = Math.floor(wheel.x + (canvas.x - wheel.x) / 1.2);
canvas.y = Math.floor(wheel.y + (canvas.y - wheel.y) / 1.2);
canvas.scale /= 1.2;
}
}
drag.target: canvas
}
Item {
anchors.margins: 1
anchors.fill: parent
clip: true
Item {
id: canvas
Repeater {
model: connections
BezierCurve {
property QtObject d: display
x: d.p1.x
y: d.p1.y
width: d.p2.x - d.p1.x
height: d.p2.y - d.p1.y
p2: Qt.point(0.3, 0)
p3: Qt.point(0.7, 1)
}
}
Repeater {
model: nodes
Node {
d: display
Rectangle {
anchors.fill: parent
color: "#ff8888"
border { width: 1; color: "#000000" }
}
}
}
}
}
Text {
anchors {
right: parent.right
top: parent.top
rightMargin: 10
topMargin: 5
}
text: fps
}
}
}

View File

@ -318,15 +318,15 @@ def run_tests(ctx):
argv = [
ctx.env.PYTEST[0],
'-c', os.path.join(ctx.top_dir, 'pytest.ini'),
'-c', os.path.join(ctx.top_dir, 'etc', 'pytest.ini'),
'-v',
]
if ctx.options.test:
argv += ['-k', ctx.options.test]
if ctx.options.test_lint:
argv += ['--mypy', '--pylint', '--pylint-rcfile=' + os.path.join(ctx.top_dir, 'pylintrc')]
argv += ['--mypy', '--pylint', '--pylint-rcfile=' + os.path.join(ctx.top_dir, 'etc', 'pylintrc')]
if ctx.env.ENABLE_COVERAGE:
argv += ['--cov=noisicaa', '--cov-config=' + os.path.join(ctx.top_dir, 'coveragerc'), '--cov-report=']
argv += ['--cov=noisicaa', '--cov-config=' + os.path.join(ctx.top_dir, 'etc', 'coveragerc'), '--cov-report=']
kw = {
'cwd': ctx.out_dir,
}
@ -362,11 +362,8 @@ def build(ctx):
ctx.recurse('bin')
ctx.recurse('data')
ctx.recurse('noisicaa')
ctx.recurse('q')
if ctx.cmd == 'test':
with ctx.group(ctx.GRP_BUILD_TESTS):
ctx.py_module('conftest.py')
ctx.add_pre_fun(clear_coverage_data)
ctx.add_post_fun(run_tests)