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.

156 lines
5.5KB

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