root/trunk/libffado/support/mixer-qt4/ffado/widgets/ntompanner.py

Revision 1695, 5.6 kB (checked in by arnonym, 14 years ago)

stupid error(s)...

Line 
1 #
2 # Copyright (C) 2009 by Arnold Krille
3 #
4 # This file is part of FFADO
5 # FFADO = Free Firewire (pro-)audio drivers for linux
6 #
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 2 of the License, or
10 # (at your option) version 3 of the License.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 #
20
21 from PyQt4 import QtGui, QtCore, Qt
22 import dbus, math, numpy
23
24 import logging
25 log = logging.getLogger("widgets")
26
27 percentage = 0.3
28 circlerect = QtCore.QRectF(-percentage/2, -percentage/2, percentage, percentage)
29
30 class PannerSource(QtGui.QGraphicsEllipseItem):
31     def __init__(self, number, parent):
32         QtGui.QGraphicsEllipseItem.__init__(self)
33         self.setRect(circlerect)
34
35         self.number = number
36         self.parent = parent
37
38         self.setBrush(QtGui.QColor(255, 0, 0))
39         self.setPen(QtGui.QPen(Qt.Qt.NoPen))
40
41         self.setFlags(QtGui.QGraphicsItem.ItemIsMovable | QtGui.QGraphicsItem.ItemIsFocusable)
42
43     def focusInEvent(self, ev):
44         QtGui.QGraphicsEllipseItem.focusInEvent(self, ev)
45
46     def itemChange(self, change, value):
47         if change == QtGui.QGraphicsItem.ItemPositionChange:
48             value = self.parent.nearestSink(value.toPointF())
49         if change == QtGui.QGraphicsItem.ItemPositionHasChanged:
50             self.parent.sourcePositionChanged(self.number)
51         return QtGui.QGraphicsEllipseItem.itemChange(self, change, value)
52
53 class N2MPanner(QtGui.QFrame):
54     def __init__(self, parent):
55         QtGui.QFrame.__init__(self, parent)
56
57         layout = QtGui.QGridLayout(self)
58         self.setLayout(layout)
59
60         self.view = QtGui.QGraphicsView(self)
61         layout.addWidget(self.view, 0, 0)
62
63         self.scene = QtGui.QGraphicsScene(QtCore.QRectF(-1, -1, 2, 2), self)
64         self.view.setScene(self.scene)
65
66         self.scene.addEllipse( QtCore.QRectF(-1,-1,2,2), QtGui.QPen(self.palette().color(QtGui.QPalette.Window).darker() ) ).setZValue(-1)
67
68         self.pen = QtGui.QPen(self.palette().color(QtGui.QPalette.Window).darker())
69         #pen.setWidthF(0.01)
70
71         self.sources = []
72         self.sinks = []
73         self.values = numpy.array(numpy.float)
74         #print self.values.flags
75         #print self.values
76
77         #self.updateGeometry()
78         QtCore.QTimer.singleShot(10, self.resizeEvent)
79
80     def setNumberOfSinks(self, sinknr):
81         #print "N2MPanner.setNumberOfSinks( %i )" % sinknr
82         while len(self.sinks) > sinknr:
83             self.sinks[-1].setParentItem(None)
84             del self.sinks[-1]
85         while len(self.sinks) < sinknr:
86             c = self.scene.addEllipse(circlerect, self.pen)
87             c.setZValue(1)
88             self.sinks.append(c)
89         #print "N2MPanner.setNumberOfSinks() new size %i" % len(self.sinks)
90         for i in range(sinknr):
91             degree = 2*math.pi/sinknr * i
92             self.sinks[i].setPos(math.cos(degree), math.sin(degree))
93         self.update()
94         self.values.resize((len(self.sources), len(self.sinks)))
95         self.sourcePositionChanged(range(len(self.sources)))
96
97     def setNumberOfSources(self, sourcenr):
98         #print "N2MPanner.setNumberOfSources( %i )" % sourcenr
99         while len(self.sources) > sourcenr:
100             self.sources[-1].setParentItem(None)
101             del self.sources[-1]
102         while len(self.sources) < sourcenr:
103             s = PannerSource(len(self.sources), self)
104             self.scene.addItem(s)
105             self.sources.append(s)
106         #print "N2MPanner.setNumberOfSources() new size %i" % len(self.sources)
107         self.values.resize((len(self.sources), len(self.sinks)))
108         self.sourcePositionChanged(range(len(self.sources)))
109
110     def distance(self, p1, p2):
111         return math.sqrt( math.pow(p1.x()-p2.x(), 2) + math.pow(p1.y()-p2.y(), 2) )
112
113     def sourcePositionChanged(self, number):
114         if not isinstance(number, list):
115             number = [number]
116         #print "N2MPanner.sourcePositionChanged( %s )" % str(number)
117         for i in number:
118             for sink in self.sinks:
119                 j = self.sinks.index(sink)
120                 self.values[i,j] = self.distance(self.sources[i].pos(), sink.pos())
121                 #print " distance to sink(%g, %g) is %g" % (sink.x(), sink.y(), self.distance(self.sources[number].pos(), sink.pos()))
122         #print self.values
123         self.emit(QtCore.SIGNAL("valuesChanged"))
124
125     def nearestSink(self, point):
126         for sink in self.sinks:
127             if sink.contains(sink.mapFromParent(point)):
128                 return sink.pos()
129         return point
130
131     def resizeEvent(self, event=None):
132         self.view.fitInView(QtCore.QRectF(-1.2, -1.2, 2.4, 2.4), Qt.Qt.KeepAspectRatio)
133
134
135 if __name__ == "__main__":
136
137     import sys
138
139     app = QtGui.QApplication(sys.argv)
140
141     w = QtGui.QWidget(None)
142     l = QtGui.QVBoxLayout(w)
143
144     s1 = QtGui.QSpinBox(w)
145     s1.setRange(1,10)
146     l.addWidget(s1)
147
148     s2 = QtGui.QSpinBox(w)
149     s2.setRange(1,10)
150     l.addWidget(s2)
151
152     p = N2MPanner(w)
153     p.setNumberOfSinks(1)
154     p.setNumberOfSources(1)
155     QtCore.QObject.connect(s1, QtCore.SIGNAL("valueChanged(int)"), p.setNumberOfSinks)
156     QtCore.QObject.connect(s2, QtCore.SIGNAL("valueChanged(int)"), p.setNumberOfSources)
157     l.addWidget(p)
158
159     w.show()
160
161     app.exec_()
162
163
164 #
165 # vim: et ts=4 sw=4
Note: See TracBrowser for help on using the browser.