Collection of tools useful for audio production
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

356 lines
11KB

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # Imports (Global)
  4. from PyQt4.QtCore import Qt, QTimer, SIGNAL
  5. from PyQt4.QtGui import QAbstractSpinBox, QComboBox, QCursor, QDialog, QInputDialog, QMenu, QPainter, QProgressBar, QValidator
  6. from PyQt4.QtGui import QStyleFactory
  7. from math import isnan
  8. # Imports (Custom)
  9. import ui_inputdialog_value
  10. def fix_value(value, minimum, maximum):
  11. if (isnan(value)):
  12. print("Parameter is NaN! - %f" % (value))
  13. return minimum
  14. elif (value < minimum):
  15. print("Parameter too low! - %f/%f" % (value, minimum))
  16. return minimum
  17. elif (value > maximum):
  18. print("Parameter too high! - %f/%f" % (value, maximum))
  19. return maximum
  20. else:
  21. return value
  22. QPlastiqueStyle = QStyleFactory.create("Plastique")
  23. # Custom InputDialog with Scale Points support
  24. class CustomInputDialog(QDialog, ui_inputdialog_value.Ui_Dialog):
  25. def __init__(self, parent=None, label="", current=0, minimum=0, maximum=0, step=0, scalepoints=None):
  26. super(CustomInputDialog, self).__init__(parent)
  27. self.setupUi(self)
  28. self.label.setText(label)
  29. self.doubleSpinBox.setMinimum(minimum)
  30. self.doubleSpinBox.setMaximum(maximum)
  31. self.doubleSpinBox.setValue(current)
  32. self.doubleSpinBox.setSingleStep(step)
  33. self.ret_value = current
  34. if (scalepoints == None):
  35. self.groupBox.setVisible(False)
  36. self.resize(200, 0)
  37. else:
  38. text = "<table>"
  39. for scalepoint in scalepoints:
  40. text += "<tr><td align='right'>%s</td><td align='left'> - %s</td></tr>" % (str(scalepoint['value']), scalepoint['label'])
  41. text += "</table>"
  42. self.textBrowser.setText(text)
  43. self.resize(200, 300)
  44. self.connect(self, SIGNAL("accepted()"), self.setReturnValue)
  45. def setReturnValue(self):
  46. self.ret_value = self.doubleSpinBox.value()
  47. # Progress-Bar used for ParamSpinBox
  48. class ParamProgressBar(QProgressBar):
  49. def __init__(self, parent=None):
  50. super(ParamProgressBar, self).__init__(parent)
  51. self._minimum = 0.0
  52. self._maximum = 1.0
  53. self._step_small = 0.0
  54. self._rvalue = 0.0
  55. self._label = ""
  56. self._pre_label = " "
  57. self._left_click_down = False
  58. self.setMinimum(0)
  59. self.setMaximum(1000)
  60. self.setValue(0)
  61. self.setFormat("(none)")
  62. def set_minimum(self, value):
  63. self._minimum = value
  64. def set_maximum(self, value):
  65. self._maximum = value
  66. def set_value(self, value):
  67. self._rvalue = value
  68. vper = (value-self._minimum)/(self._maximum-self._minimum)
  69. self.setValue(vper*1000)
  70. def set_label(self, label):
  71. self._label = label.strip()
  72. if (self._label == "(coef)"):
  73. self._label = ""
  74. self._pre_label = "*"
  75. self.update()
  76. def handleMouseEventPos(self, pos):
  77. xper = float(pos.x())/self.width()
  78. value = xper*(self._maximum-self._minimum)+self._minimum
  79. if (value < self._minimum):
  80. value = self._minimum
  81. elif (value > self._maximum):
  82. value = self._maximum
  83. self.emit(SIGNAL("valueChangedFromBar(double)"), value)
  84. def mousePressEvent(self, event):
  85. if (event.button() == Qt.LeftButton):
  86. self.handleMouseEventPos(event.pos())
  87. self._left_click_down = True
  88. else:
  89. self._left_click_down = False
  90. return QProgressBar.mousePressEvent(self, event)
  91. def mouseMoveEvent(self, event):
  92. if (self._left_click_down):
  93. self.handleMouseEventPos(event.pos())
  94. return QProgressBar.mouseMoveEvent(self, event)
  95. def mouseReleaseEvent(self, event):
  96. self._left_click_down = False
  97. return QProgressBar.mouseReleaseEvent(self, event)
  98. def paintEvent(self, event):
  99. self.setFormat("%s %f %s" % (self._pre_label, self._rvalue, self._label))
  100. return QProgressBar.paintEvent(self, event)
  101. # Special SpinBox used for parameters
  102. class ParamSpinBox(QAbstractSpinBox):
  103. def __init__(self, parent=None):
  104. super(ParamSpinBox, self).__init__(parent)
  105. self._minimum = 0.0
  106. self._maximum = 1.0
  107. self._default = 0.0
  108. self._value = None
  109. self._step = 0.0
  110. self._step_small = 0.0
  111. self._step_large = 0.0
  112. self._read_only = False
  113. self._scalepoints = None
  114. self._have_scalepoints = False
  115. self.bar = ParamProgressBar(self)
  116. self.bar.setContextMenuPolicy(Qt.NoContextMenu)
  117. self.bar.show()
  118. self.lineEdit().setVisible(False)
  119. self.connect(self.bar, SIGNAL("valueChangedFromBar(double)"), self.handleValueChangedFromBar)
  120. self.connect(self, SIGNAL("customContextMenuRequested(QPoint)"), self.showCustomMenu)
  121. QTimer.singleShot(0, self.updateBarGeometry)
  122. def force_plastique_style(self):
  123. self.setStyle(QPlastiqueStyle)
  124. def set_minimum(self, value):
  125. self._minimum = value
  126. self.bar.set_minimum(value)
  127. def set_maximum(self, value):
  128. self._maximum = value
  129. self.bar.set_maximum(value)
  130. def set_default(self, value):
  131. value = fix_value(value, self._minimum, self._maximum)
  132. self._default = value
  133. def set_value(self, value, send=True):
  134. value = fix_value(value, self._minimum, self._maximum)
  135. if (self._value != value):
  136. self._value = value
  137. self.bar.set_value(value)
  138. if (self._have_scalepoints):
  139. self.set_scalepoint_value(value)
  140. if (send):
  141. self.emit(SIGNAL("valueChanged(double)"), value)
  142. self.update()
  143. return True
  144. else:
  145. return False
  146. def set_step(self, value):
  147. if (value == 0.0):
  148. self._step = 0.01
  149. else:
  150. self._step = value
  151. def set_step_small(self, value):
  152. if (value == 0.0):
  153. self._step_small = 0.001
  154. else:
  155. self._step_small = value
  156. def set_step_large(self, value):
  157. if (value == 0.0):
  158. self._step_large = 0.1
  159. else:
  160. self._step_large = value
  161. def set_label(self, label):
  162. self.bar.set_label(label)
  163. def set_read_only(self, yesno):
  164. self.setButtonSymbols(QAbstractSpinBox.UpDownArrows if (yesno) else QAbstractSpinBox.NoButtons)
  165. self._read_only = yesno
  166. self.setReadOnly(yesno)
  167. def set_scalepoints(self, scalepoints, use_scalepoints):
  168. if (len(scalepoints) > 0):
  169. self._scalepoints = scalepoints
  170. self._have_scalepoints = use_scalepoints
  171. if (use_scalepoints):
  172. # Hide ProgressBar and create a ComboBox
  173. self.bar.close()
  174. self.box = QComboBox(self)
  175. self.box.setContextMenuPolicy(Qt.NoContextMenu)
  176. self.box.show()
  177. self.updateBarGeometry()
  178. for scalepoint in scalepoints:
  179. self.box.addItem("%f - %s" % (scalepoint['value'], scalepoint['label']))
  180. self.set_scalepoint_value(self._value)
  181. self.connect(self.box, SIGNAL("currentIndexChanged(QString)"), self.handleValueChangedFromBox)
  182. else:
  183. self._scalepoints = None
  184. def set_scalepoint_value(self, value):
  185. value = self.get_nearest_scalepoint(value)
  186. for i in range(self.box.count()):
  187. if (float(self.box.itemText(i).split(" - ", 1)[0]) == value):
  188. self.box.setCurrentIndex(i)
  189. break
  190. def get_nearest_scalepoint(self, real_value):
  191. final_value = 0.0
  192. for i in range(len(self._scalepoints)):
  193. scale_value = self._scalepoints[i]['value']
  194. if (i == 0):
  195. final_value = scale_value
  196. else:
  197. srange1 = abs(real_value-scale_value)
  198. srange2 = abs(real_value-final_value)
  199. if (srange2 > srange1):
  200. final_value = scale_value
  201. return final_value
  202. def handleValueChangedFromBar(self, value):
  203. if (self._read_only): return
  204. step = int(0.5+((value-self._minimum)/self._step))
  205. real_value = self._minimum+(step*self._step)
  206. self.set_value(real_value)
  207. def handleValueChangedFromBox(self, box_text):
  208. if (self._read_only): return
  209. value = float(box_text.split(" - ", 1)[0])
  210. last_scale_value = self._scalepoints[len(self._scalepoints)-1]['value']
  211. if (value == last_scale_value):
  212. value = self._maximum
  213. self.set_value(value)
  214. def showCustomMenu(self, pos):
  215. menu = QMenu(self)
  216. act_x_reset = menu.addAction(self.tr("Reset (%f)" % (self._default)))
  217. menu.addSeparator()
  218. act_x_copy = menu.addAction(self.tr("Copy (%f)"% (self._value)))
  219. if (False and not self._read_only):
  220. act_x_paste = menu.addAction(self.tr("Paste (%s)" % ("TODO")))
  221. else:
  222. act_x_paste = menu.addAction(self.tr("Paste"))
  223. act_x_paste.setEnabled(False)
  224. menu.addSeparator()
  225. act_x_set = menu.addAction(self.tr("Set value..."))
  226. if (self._read_only):
  227. act_x_reset.setEnabled(False)
  228. act_x_paste.setEnabled(False)
  229. act_x_set.setEnabled(False)
  230. # TODO - NOT IMPLEMENTED YET
  231. act_x_copy.setEnabled(False)
  232. act_x_sel = menu.exec_(QCursor.pos())
  233. if (act_x_sel == act_x_set):
  234. dialog = CustomInputDialog(self, self.parent().label.text(), self._value, self._minimum, self._maximum, self._step, self._scalepoints)
  235. if (dialog.exec_()):
  236. value = dialog.ret_value
  237. self.set_value(value)
  238. elif (act_x_sel == act_x_copy):
  239. pass
  240. elif (act_x_sel == act_x_paste):
  241. pass
  242. elif (act_x_sel == act_x_reset):
  243. self.set_value(self._default)
  244. def stepBy(self, steps):
  245. if (steps == 0):
  246. return
  247. value = self._value+(steps*self._step)
  248. if (value < self._minimum):
  249. value = self._minimum
  250. elif (value > self._maximum):
  251. value = self._maximum
  252. self.set_value(value)
  253. def stepEnabled(self):
  254. if (self._read_only):
  255. return QAbstractSpinBox.StepNone
  256. elif (self._value <= self._minimum):
  257. return QAbstractSpinBox.StepUpEnabled
  258. elif (self._value >= self._maximum):
  259. return QAbstractSpinBox.StepDownEnabled
  260. else:
  261. return QAbstractSpinBox.StepUpEnabled|QAbstractSpinBox.StepDownEnabled
  262. def updateAll(self):
  263. self.update()
  264. self.bar.update()
  265. if (self._have_scalepoints):
  266. self.box.update()
  267. def updateBarGeometry(self):
  268. self.bar.setGeometry(self.lineEdit().geometry())
  269. if (self._have_scalepoints):
  270. self.box.setGeometry(self.lineEdit().geometry())
  271. def resizeEvent(self, event):
  272. QTimer.singleShot(0, self.updateBarGeometry)
  273. return QAbstractSpinBox.resizeEvent(self, event)