Audio plugin host https://kx.studio/carla
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.

paramspinbox.py 18KB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
Frontend widget enhancements (#767) * optimization: MainWindow resize event (no more issue #148) minimap: Brightness-aware shading on side gaps * CarlaStyle: more careful rounded corner drawing Rounded rectangles have transparent corners even with opaque colors. During compositing colors from several such objects are mixed, producing unexpected artifacts. Also outer contour must have bigger rounding - values for inner/outer rects are spreaded to be around of original 2.0px, to preserve original look. * CarlaStyle: better separator color Create separator color from softened text color. * paramspinbox: Keep scrollbar size closer to outer frame Unless QStyle allowes any widget style, or it is entries and scrollbars provide essential way to control or read frame parameters, scrollbar is still set a bit smaller to counter theme-side deviations between scrollbar and spinbox visible height while real height is equal. * CarlaStyle: better light shade * CarlaStyle: fix visible spinbox height regression When spinbox is in one row with scrollbar or entry field, all vertically expanding, spinbox look a bit lower. * CarlaStyle: completed spinbox buttons light border * CarlaStyle: fixed spinbox button rects, better borderwidth balance Integer button rectangles now produce pixel-aligned non-overlaping, still centered rectangles. SpinBox border width is reduced to minimum, right enough to keep entry widget corners out of outer rounded border parts. * CarlaStyle: constification (SpinBox drawing) * CarlaStyle: spinbox drawing fixes Rely to correct buttons rectangles, handle correctly both even and odd spinbox heights. Disappeared buttons highlight glitch, appeared when moving mouse one button to another. * CarlaStyle, SpinBox: contrast highlight margin between buttons * CarlaStyle spinbox: more careful buttons highlight * CarlaStyle, spinbox: better arrows placement * paramspinbox: Hide scrollbar border * CarlaStyle: nicer rounded corners in deep-dark colors (less radius deviation) * CarlaStyle CT_ToolButton: took less space than combobox in same layout As in designer, carla_host.ui has plus/minus buttons size 25x24, with height equal to adjacent combobox. It seems, system carla style already got fix.
6 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
Frontend widget enhancements (#767) * optimization: MainWindow resize event (no more issue #148) minimap: Brightness-aware shading on side gaps * CarlaStyle: more careful rounded corner drawing Rounded rectangles have transparent corners even with opaque colors. During compositing colors from several such objects are mixed, producing unexpected artifacts. Also outer contour must have bigger rounding - values for inner/outer rects are spreaded to be around of original 2.0px, to preserve original look. * CarlaStyle: better separator color Create separator color from softened text color. * paramspinbox: Keep scrollbar size closer to outer frame Unless QStyle allowes any widget style, or it is entries and scrollbars provide essential way to control or read frame parameters, scrollbar is still set a bit smaller to counter theme-side deviations between scrollbar and spinbox visible height while real height is equal. * CarlaStyle: better light shade * CarlaStyle: fix visible spinbox height regression When spinbox is in one row with scrollbar or entry field, all vertically expanding, spinbox look a bit lower. * CarlaStyle: completed spinbox buttons light border * CarlaStyle: fixed spinbox button rects, better borderwidth balance Integer button rectangles now produce pixel-aligned non-overlaping, still centered rectangles. SpinBox border width is reduced to minimum, right enough to keep entry widget corners out of outer rounded border parts. * CarlaStyle: constification (SpinBox drawing) * CarlaStyle: spinbox drawing fixes Rely to correct buttons rectangles, handle correctly both even and odd spinbox heights. Disappeared buttons highlight glitch, appeared when moving mouse one button to another. * CarlaStyle, SpinBox: contrast highlight margin between buttons * CarlaStyle spinbox: more careful buttons highlight * CarlaStyle, spinbox: better arrows placement * paramspinbox: Hide scrollbar border * CarlaStyle: nicer rounded corners in deep-dark colors (less radius deviation) * CarlaStyle CT_ToolButton: took less space than combobox in same layout As in designer, carla_host.ui has plus/minus buttons size 25x24, with height equal to adjacent combobox. It seems, system carla style already got fix.
6 years ago
Frontend widget enhancements (#767) * optimization: MainWindow resize event (no more issue #148) minimap: Brightness-aware shading on side gaps * CarlaStyle: more careful rounded corner drawing Rounded rectangles have transparent corners even with opaque colors. During compositing colors from several such objects are mixed, producing unexpected artifacts. Also outer contour must have bigger rounding - values for inner/outer rects are spreaded to be around of original 2.0px, to preserve original look. * CarlaStyle: better separator color Create separator color from softened text color. * paramspinbox: Keep scrollbar size closer to outer frame Unless QStyle allowes any widget style, or it is entries and scrollbars provide essential way to control or read frame parameters, scrollbar is still set a bit smaller to counter theme-side deviations between scrollbar and spinbox visible height while real height is equal. * CarlaStyle: better light shade * CarlaStyle: fix visible spinbox height regression When spinbox is in one row with scrollbar or entry field, all vertically expanding, spinbox look a bit lower. * CarlaStyle: completed spinbox buttons light border * CarlaStyle: fixed spinbox button rects, better borderwidth balance Integer button rectangles now produce pixel-aligned non-overlaping, still centered rectangles. SpinBox border width is reduced to minimum, right enough to keep entry widget corners out of outer rounded border parts. * CarlaStyle: constification (SpinBox drawing) * CarlaStyle: spinbox drawing fixes Rely to correct buttons rectangles, handle correctly both even and odd spinbox heights. Disappeared buttons highlight glitch, appeared when moving mouse one button to another. * CarlaStyle, SpinBox: contrast highlight margin between buttons * CarlaStyle spinbox: more careful buttons highlight * CarlaStyle, spinbox: better arrows placement * paramspinbox: Hide scrollbar border * CarlaStyle: nicer rounded corners in deep-dark colors (less radius deviation) * CarlaStyle CT_ToolButton: took less space than combobox in same layout As in designer, carla_host.ui has plus/minus buttons size 25x24, with height equal to adjacent combobox. It seems, system carla style already got fix.
6 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # Parameter SpinBox, a custom Qt widget
  4. # Copyright (C) 2011-2019 Filipe Coelho <falktx@falktx.com>
  5. #
  6. # This program is free software; you can redistribute it and/or
  7. # modify it under the terms of the GNU General Public License as
  8. # published by the Free Software Foundation; either version 2 of
  9. # the License, or any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # For a full copy of the GNU General Public License see the doc/GPL.txt file.
  17. # ------------------------------------------------------------------------------------------------------------
  18. # Imports (Global)
  19. from math import isnan, modf
  20. from random import random
  21. from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QTimer
  22. from PyQt5.QtGui import QCursor, QPalette
  23. from PyQt5.QtWidgets import QAbstractSpinBox, QApplication, QComboBox, QDialog, QMenu, QProgressBar
  24. # ------------------------------------------------------------------------------------------------------------
  25. # Imports (Custom)
  26. import ui_inputdialog_value
  27. # ------------------------------------------------------------------------------------------------------------
  28. # Get a fixed value within min/max bounds
  29. def geFixedValue(name, value, minimum, maximum):
  30. if isnan(value):
  31. print("Parameter '%s' is NaN! - %f" % (name, value))
  32. return minimum
  33. if value < minimum:
  34. print("Parameter '%s' too low! - %f/%f" % (name, value, minimum))
  35. return minimum
  36. if value > maximum:
  37. print("Parameter '%s' too high! - %f/%f" % (name, value, maximum))
  38. return maximum
  39. return value
  40. # ------------------------------------------------------------------------------------------------------------
  41. # Custom InputDialog with Scale Points support
  42. class CustomInputDialog(QDialog):
  43. def __init__(self, parent, label, current, minimum, maximum, step, stepSmall, scalePoints):
  44. QDialog.__init__(self, parent)
  45. self.ui = ui_inputdialog_value.Ui_Dialog()
  46. self.ui.setupUi(self)
  47. # calculate num decimals from stepSmall
  48. if stepSmall >= 1.0:
  49. decimals = 0
  50. elif step >= 1.0:
  51. decimals = 2
  52. else:
  53. decfrac, decwhole = modf(stepSmall)
  54. if "000" in str(decfrac):
  55. decfrac = round(decfrac, str(decfrac).find("000"))
  56. else:
  57. decfrac = round(decfrac, 12)
  58. decimals = abs(len(str(decfrac))-len(str(decwhole))-1)
  59. self.ui.label.setText(label)
  60. self.ui.doubleSpinBox.setDecimals(decimals)
  61. self.ui.doubleSpinBox.setRange(minimum, maximum)
  62. self.ui.doubleSpinBox.setSingleStep(step)
  63. self.ui.doubleSpinBox.setValue(current)
  64. if not scalePoints:
  65. self.ui.groupBox.setVisible(False)
  66. self.resize(200, 0)
  67. else:
  68. text = "<table>"
  69. for scalePoint in scalePoints:
  70. text += "<tr><td align='right'>%f</td><td align='left'> - %s</td></tr>" % (scalePoint['value'], scalePoint['label'])
  71. text += "</table>"
  72. self.ui.textBrowser.setText(text)
  73. self.resize(200, 300)
  74. self.fRetValue = current
  75. self.accepted.connect(self.slot_setReturnValue)
  76. def returnValue(self):
  77. return self.fRetValue
  78. @pyqtSlot()
  79. def slot_setReturnValue(self):
  80. self.fRetValue = self.ui.doubleSpinBox.value()
  81. def done(self, r):
  82. QDialog.done(self, r)
  83. self.close()
  84. # ------------------------------------------------------------------------------------------------------------
  85. # ProgressBar used for ParamSpinBox
  86. class ParamProgressBar(QProgressBar):
  87. # signals
  88. dragStateChanged = pyqtSignal(bool)
  89. valueChanged = pyqtSignal(float)
  90. def __init__(self, parent):
  91. QProgressBar.__init__(self, parent)
  92. self.fLeftClickDown = False
  93. self.fIsInteger = False
  94. self.fIsReadOnly = False
  95. self.fMinimum = 0.0
  96. self.fMaximum = 1.0
  97. self.fInitiated = False
  98. self.fRealValue = 0.0
  99. self.fLastPaintedValue = None
  100. self.fCurrentPaintedText = ""
  101. self.fLabel = ""
  102. self.fName = ""
  103. self.fPreLabel = " "
  104. self.fTextCall = None
  105. self.fValueCall = None
  106. self.setFormat("(none)")
  107. # Fake internal value, 10'000 precision
  108. QProgressBar.setMinimum(self, 0)
  109. QProgressBar.setMaximum(self, 10000)
  110. QProgressBar.setValue(self, 0)
  111. def setMinimum(self, value):
  112. self.fMinimum = value
  113. def setMaximum(self, value):
  114. self.fMaximum = value
  115. def setValue(self, value):
  116. if self.fRealValue == value and self.fInitiated:
  117. return False
  118. self.fInitiated = True
  119. self.fRealValue = value
  120. div = float(self.fMaximum - self.fMinimum)
  121. if div == 0.0:
  122. print("Parameter '%s' division by 0 prevented (value:%f, min:%f, max:%f)" % (self.fName, value, self.fMaximum, self.fMinimum))
  123. vper = 1.0
  124. else:
  125. vper = float(value - self.fMinimum) / div
  126. if vper < 0.0:
  127. vper = 0.0
  128. elif vper > 1.0:
  129. vper = 1.0
  130. if self.fValueCall is not None:
  131. self.fValueCall(value)
  132. QProgressBar.setValue(self, int(vper * 10000))
  133. return True
  134. def setLabel(self, label):
  135. self.fLabel = label.strip()
  136. if self.fLabel == "(coef)":
  137. self.fLabel = ""
  138. self.fPreLabel = "*"
  139. # force refresh of text value
  140. self.fLastPaintedValue = None
  141. self.update()
  142. def setName(self, name):
  143. self.fName = name
  144. def setReadOnly(self, yesNo):
  145. self.fIsReadOnly = yesNo
  146. def setTextCall(self, textCall):
  147. self.fTextCall = textCall
  148. def setValueCall(self, valueCall):
  149. self.fValueCall = valueCall
  150. def handleMouseEventPos(self, pos):
  151. if self.fIsReadOnly:
  152. return
  153. xper = float(pos.x()) / float(self.width())
  154. value = xper * (self.fMaximum - self.fMinimum) + self.fMinimum
  155. if self.fIsInteger:
  156. value = round(value)
  157. if value < self.fMinimum:
  158. value = self.fMinimum
  159. elif value > self.fMaximum:
  160. value = self.fMaximum
  161. if self.setValue(value):
  162. self.valueChanged.emit(value)
  163. def mousePressEvent(self, event):
  164. if self.fIsReadOnly:
  165. return
  166. if event.button() == Qt.LeftButton:
  167. self.handleMouseEventPos(event.pos())
  168. self.fLeftClickDown = True
  169. self.dragStateChanged.emit(True)
  170. else:
  171. self.fLeftClickDown = False
  172. QProgressBar.mousePressEvent(self, event)
  173. def mouseMoveEvent(self, event):
  174. if self.fIsReadOnly:
  175. return
  176. if self.fLeftClickDown:
  177. self.handleMouseEventPos(event.pos())
  178. QProgressBar.mouseMoveEvent(self, event)
  179. def mouseReleaseEvent(self, event):
  180. if self.fIsReadOnly:
  181. return
  182. self.fLeftClickDown = False
  183. self.dragStateChanged.emit(False)
  184. QProgressBar.mouseReleaseEvent(self, event)
  185. def paintEvent(self, event):
  186. if self.fTextCall is not None:
  187. if self.fLastPaintedValue != self.fRealValue:
  188. self.fLastPaintedValue = self.fRealValue
  189. self.fCurrentPaintedText = self.fTextCall()
  190. self.setFormat("%s %s %s" % (self.fPreLabel, self.fCurrentPaintedText, self.fLabel))
  191. elif self.fIsInteger:
  192. self.setFormat("%s %i %s" % (self.fPreLabel, int(self.fRealValue), self.fLabel))
  193. else:
  194. self.setFormat("%s %f %s" % (self.fPreLabel, self.fRealValue, self.fLabel))
  195. QProgressBar.paintEvent(self, event)
  196. # ------------------------------------------------------------------------------------------------------------
  197. # Special SpinBox used for parameters
  198. class ParamSpinBox(QAbstractSpinBox):
  199. # signals
  200. valueChanged = pyqtSignal(float)
  201. def __init__(self, parent):
  202. QAbstractSpinBox.__init__(self, parent)
  203. self.fName = ""
  204. self.fMinimum = 0.0
  205. self.fMaximum = 1.0
  206. self.fDefault = 0.0
  207. self.fValue = None
  208. self.fStep = 0.01
  209. self.fStepSmall = 0.0001
  210. self.fStepLarge = 0.1
  211. self.fIsReadOnly = False
  212. self.fScalePoints = None
  213. self.fUseScalePoints = False
  214. self.fBar = ParamProgressBar(self)
  215. self.fBar.setContextMenuPolicy(Qt.NoContextMenu)
  216. #self.fBar.show()
  217. barPalette = self.fBar.palette()
  218. barPalette.setColor(QPalette.Window, Qt.transparent)
  219. self.fBar.setPalette(barPalette)
  220. self.fBox = None
  221. self.lineEdit().hide()
  222. self.customContextMenuRequested.connect(self.slot_showCustomMenu)
  223. self.fBar.valueChanged.connect(self.slot_progressBarValueChanged)
  224. self.dragStateChanged = self.fBar.dragStateChanged
  225. QTimer.singleShot(0, self.slot_updateProgressBarGeometry)
  226. def setDefault(self, value):
  227. value = geFixedValue(self.fName, value, self.fMinimum, self.fMaximum)
  228. self.fDefault = value
  229. def setMinimum(self, value):
  230. self.fMinimum = value
  231. self.fBar.setMinimum(value)
  232. def setMaximum(self, value):
  233. self.fMaximum = value
  234. self.fBar.setMaximum(value)
  235. def setValue(self, value):
  236. if not self.fIsReadOnly:
  237. value = geFixedValue(self.fName, value, self.fMinimum, self.fMaximum)
  238. if self.fBar.fIsInteger:
  239. value = round(value)
  240. if self.fValue == value:
  241. return False
  242. self.fValue = value
  243. self.fBar.setValue(value)
  244. if self.fUseScalePoints:
  245. self._setScalePointValue(value)
  246. self.valueChanged.emit(value)
  247. self.update()
  248. return True
  249. def setStep(self, value):
  250. if value == 0.0:
  251. self.fStep = 0.001
  252. else:
  253. self.fStep = value
  254. if self.fStepSmall > value:
  255. self.fStepSmall = value
  256. if self.fStepLarge < value:
  257. self.fStepLarge = value
  258. self.fBar.fIsInteger = bool(self.fStepSmall == 1.0)
  259. def setStepSmall(self, value):
  260. if value == 0.0:
  261. self.fStepSmall = 0.0001
  262. elif value > self.fStep:
  263. self.fStepSmall = self.fStep
  264. else:
  265. self.fStepSmall = value
  266. self.fBar.fIsInteger = bool(self.fStepSmall == 1.0)
  267. def setStepLarge(self, value):
  268. if value == 0.0:
  269. self.fStepLarge = 0.1
  270. elif value < self.fStep:
  271. self.fStepLarge = self.fStep
  272. else:
  273. self.fStepLarge = value
  274. def setLabel(self, label):
  275. self.fBar.setLabel(label)
  276. def setName(self, name):
  277. self.fName = name
  278. self.fBar.setName(name)
  279. def setTextCallback(self, textCall):
  280. self.fBar.setTextCall(textCall)
  281. def setValueCallback(self, valueCall):
  282. self.fBar.setValueCall(valueCall)
  283. def setReadOnly(self, yesNo):
  284. self.fIsReadOnly = yesNo
  285. self.fBar.setReadOnly(yesNo)
  286. self.setButtonSymbols(QAbstractSpinBox.UpDownArrows if yesNo else QAbstractSpinBox.NoButtons)
  287. QAbstractSpinBox.setReadOnly(self, yesNo)
  288. # FIXME use change event
  289. def setEnabled(self, yesNo):
  290. self.fBar.setEnabled(yesNo)
  291. QAbstractSpinBox.setEnabled(self, yesNo)
  292. def setScalePoints(self, scalePoints, useScalePoints):
  293. if len(scalePoints) == 0:
  294. self.fScalePoints = None
  295. self.fUseScalePoints = False
  296. return
  297. self.fScalePoints = scalePoints
  298. self.fUseScalePoints = useScalePoints
  299. if not useScalePoints:
  300. return
  301. # Hide ProgressBar and create a ComboBox
  302. self.fBar.close()
  303. self.fBox = QComboBox(self)
  304. self.fBox.setContextMenuPolicy(Qt.NoContextMenu)
  305. #self.fBox.show()
  306. self.slot_updateProgressBarGeometry()
  307. # Add items, sorted
  308. boxItemValues = []
  309. for scalePoint in scalePoints:
  310. value = scalePoint['value']
  311. if self.fStep == 1.0:
  312. label = "%i - %s" % (int(value), scalePoint['label'])
  313. else:
  314. label = "%f - %s" % (value, scalePoint['label'])
  315. if len(boxItemValues) == 0:
  316. self.fBox.addItem(label)
  317. boxItemValues.append(value)
  318. else:
  319. if value < boxItemValues[0]:
  320. self.fBox.insertItem(0, label)
  321. boxItemValues.insert(0, value)
  322. elif value > boxItemValues[-1]:
  323. self.fBox.addItem(label)
  324. boxItemValues.append(value)
  325. else:
  326. for index in range(len(boxItemValues)):
  327. if value >= boxItemValues[index]:
  328. self.fBox.insertItem(index+1, label)
  329. boxItemValues.insert(index+1, value)
  330. break
  331. if self.fValue is not None:
  332. self._setScalePointValue(self.fValue)
  333. self.fBox.currentIndexChanged['QString'].connect(self.slot_comboBoxIndexChanged)
  334. def stepBy(self, steps):
  335. if steps == 0 or self.fValue is None:
  336. return
  337. value = self.fValue + (self.fStep * steps)
  338. if value < self.fMinimum:
  339. value = self.fMinimum
  340. elif value > self.fMaximum:
  341. value = self.fMaximum
  342. self.setValue(value)
  343. def stepEnabled(self):
  344. if self.fIsReadOnly or self.fValue is None:
  345. return QAbstractSpinBox.StepNone
  346. if self.fValue <= self.fMinimum:
  347. return QAbstractSpinBox.StepUpEnabled
  348. if self.fValue >= self.fMaximum:
  349. return QAbstractSpinBox.StepDownEnabled
  350. return (QAbstractSpinBox.StepUpEnabled | QAbstractSpinBox.StepDownEnabled)
  351. def updateAll(self):
  352. self.update()
  353. self.fBar.update()
  354. if self.fBox is not None:
  355. self.fBox.update()
  356. def resizeEvent(self, event):
  357. QAbstractSpinBox.resizeEvent(self, event)
  358. self.slot_updateProgressBarGeometry()
  359. @pyqtSlot(str)
  360. def slot_comboBoxIndexChanged(self, boxText):
  361. if self.fIsReadOnly:
  362. return
  363. value = float(boxText.split(" - ", 1)[0])
  364. lastScaleValue = self.fScalePoints[-1]['value']
  365. if value == lastScaleValue:
  366. value = self.fMaximum
  367. self.setValue(value)
  368. @pyqtSlot(float)
  369. def slot_progressBarValueChanged(self, value):
  370. if self.fIsReadOnly:
  371. return
  372. if value <= self.fMinimum:
  373. realValue = self.fMinimum
  374. elif value >= self.fMaximum:
  375. realValue = self.fMaximum
  376. else:
  377. curStep = int((value - self.fMinimum) / self.fStep + 0.5)
  378. realValue = self.fMinimum + (self.fStep * curStep)
  379. if realValue < self.fMinimum:
  380. realValue = self.fMinimum
  381. elif realValue > self.fMaximum:
  382. realValue = self.fMaximum
  383. self.setValue(realValue)
  384. @pyqtSlot()
  385. def slot_showCustomMenu(self):
  386. clipboard = QApplication.instance().clipboard()
  387. pasteText = clipboard.text()
  388. pasteValue = None
  389. if pasteText:
  390. try:
  391. pasteValue = float(pasteText)
  392. except:
  393. pass
  394. menu = QMenu(self)
  395. actReset = menu.addAction(self.tr("Reset (%f)" % self.fDefault))
  396. actRandom = menu.addAction(self.tr("Random"))
  397. menu.addSeparator()
  398. actCopy = menu.addAction(self.tr("Copy (%f)" % self.fValue))
  399. if pasteValue is None:
  400. actPaste = menu.addAction(self.tr("Paste"))
  401. actPaste.setEnabled(False)
  402. else:
  403. actPaste = menu.addAction(self.tr("Paste (%f)" % pasteValue))
  404. menu.addSeparator()
  405. actSet = menu.addAction(self.tr("Set value..."))
  406. if self.fIsReadOnly:
  407. actReset.setEnabled(False)
  408. actRandom.setEnabled(False)
  409. actPaste.setEnabled(False)
  410. actSet.setEnabled(False)
  411. actSel = menu.exec_(QCursor.pos())
  412. if actSel == actReset:
  413. self.setValue(self.fDefault)
  414. elif actSel == actRandom:
  415. value = random() * (self.fMaximum - self.fMinimum) + self.fMinimum
  416. self.setValue(value)
  417. elif actSel == actCopy:
  418. clipboard.setText("%f" % self.fValue)
  419. elif actSel == actPaste:
  420. self.setValue(pasteValue)
  421. elif actSel == actSet:
  422. dialog = CustomInputDialog(self, self.fName, self.fValue, self.fMinimum, self.fMaximum,
  423. self.fStep, self.fStepSmall, self.fScalePoints)
  424. if dialog.exec_():
  425. value = dialog.returnValue()
  426. self.setValue(value)
  427. @pyqtSlot()
  428. def slot_updateProgressBarGeometry(self):
  429. geometry = self.lineEdit().geometry()
  430. dx = geometry.x()-1
  431. dy = geometry.y()-1
  432. geometry.adjust(-dx, -dy, dx, dy)
  433. self.fBar.setGeometry(geometry)
  434. if self.fUseScalePoints:
  435. self.fBox.setGeometry(geometry)
  436. def _getNearestScalePoint(self, realValue):
  437. finalValue = 0.0
  438. for i in range(len(self.fScalePoints)):
  439. scaleValue = self.fScalePoints[i]["value"]
  440. if i == 0:
  441. finalValue = scaleValue
  442. else:
  443. srange1 = abs(realValue - scaleValue)
  444. srange2 = abs(realValue - finalValue)
  445. if srange2 > srange1:
  446. finalValue = scaleValue
  447. return finalValue
  448. def _setScalePointValue(self, value):
  449. value = self._getNearestScalePoint(value)
  450. for i in range(self.fBox.count()):
  451. if float(self.fBox.itemText(i).split(" - ", 1)[0]) == value:
  452. self.fBox.setCurrentIndex(i)
  453. break