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.

155 lines
5.3KB

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # Middle-click draggable QGraphicsView
  4. # Copyright (C) 2016-2020 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 PyQt5.QtCore import Qt, QEvent, QTimer
  20. from PyQt5.QtGui import QCursor, QMouseEvent
  21. from PyQt5.QtWidgets import QGraphicsView
  22. # ------------------------------------------------------------------------------------------------------------
  23. # Imports (Custom Stuff)
  24. from carla_shared import *
  25. # ------------------------------------------------------------------------------------------------------------
  26. # Widget Class
  27. class DraggableGraphicsView(QGraphicsView):
  28. def __init__(self, parent):
  29. QGraphicsView.__init__(self, parent)
  30. self.fPanning = False
  31. try:
  32. self.fMiddleButton = Qt.MiddleButton
  33. except:
  34. self.fMiddleButton = Qt.MidButton
  35. exts = gCarla.utils.get_supported_file_extensions()
  36. self.fSupportedExtensions = tuple(("." + i) for i in exts)
  37. self.fWasLastDragValid = False
  38. self.setAcceptDrops(True)
  39. # --------------------------------------------------------------------------------------------------------
  40. def isDragUrlValid(self, filename):
  41. lfilename = filename.lower()
  42. if os.path.isdir(filename):
  43. #if os.path.exists(os.path.join(filename, "manifest.ttl")):
  44. #return True
  45. if MACOS and lfilename.endswith(".vst"):
  46. return True
  47. elif lfilename.endswith(".vst3") and ".vst3" in self.fSupportedExtensions:
  48. return True
  49. elif os.path.isfile(filename):
  50. if lfilename.endswith(self.fSupportedExtensions):
  51. return True
  52. return False
  53. # --------------------------------------------------------------------------------------------------------
  54. def dragEnterEvent(self, event):
  55. urls = event.mimeData().urls()
  56. for url in urls:
  57. if self.isDragUrlValid(url.toLocalFile()):
  58. self.fWasLastDragValid = True
  59. event.acceptProposedAction()
  60. return
  61. self.fWasLastDragValid = False
  62. QGraphicsView.dragEnterEvent(self, event)
  63. def dragMoveEvent(self, event):
  64. if not self.fWasLastDragValid:
  65. QGraphicsView.dragMoveEvent(self, event)
  66. return
  67. event.acceptProposedAction()
  68. def dragLeaveEvent(self, event):
  69. self.fWasLastDragValid = False
  70. QGraphicsView.dragLeaveEvent(self, event)
  71. # --------------------------------------------------------------------------------------------------------
  72. def dropEvent(self, event):
  73. event.acceptProposedAction()
  74. urls = event.mimeData().urls()
  75. if len(urls) == 0:
  76. return
  77. for url in urls:
  78. filename = url.toLocalFile()
  79. if not gCarla.gui.host.load_file(filename):
  80. CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"),
  81. self.tr("Failed to load file"),
  82. gCarla.gui.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok)
  83. # --------------------------------------------------------------------------------------------------------
  84. def mousePressEvent(self, event):
  85. if event.button() == self.fMiddleButton and not (event.modifiers() & Qt.ControlModifier):
  86. buttons = event.buttons()
  87. buttons &= ~self.fMiddleButton
  88. buttons |= Qt.LeftButton
  89. timestamp = event.timestamp()
  90. self.fPanning = True
  91. self.setDragMode(QGraphicsView.ScrollHandDrag)
  92. else:
  93. timestamp = None
  94. QGraphicsView.mousePressEvent(self, event)
  95. if timestamp is None:
  96. return
  97. event = QMouseEvent(QEvent.MouseButtonPress,
  98. event.localPos(), event.windowPos(), event.screenPos(),
  99. Qt.LeftButton, Qt.LeftButton,
  100. Qt.NoModifier,
  101. Qt.MouseEventSynthesizedByApplication)
  102. event.setTimestamp(timestamp)
  103. QGraphicsView.mousePressEvent(self, event)
  104. def mouseReleaseEvent(self, event):
  105. QGraphicsView.mouseReleaseEvent(self, event)
  106. if event.button() == self.fMiddleButton and self.fPanning:
  107. self.fPanning = False
  108. self.setDragMode(QGraphicsView.NoDrag)
  109. self.setCursor(QCursor(Qt.ArrowCursor))
  110. def wheelEvent(self, event):
  111. if event.buttons() & self.fMiddleButton:
  112. event.ignore()
  113. return
  114. QGraphicsView.wheelEvent(self, event)
  115. # --------------------------------------------------------------------------------------------------------