diff --git a/.gitignore b/.gitignore
index e198ae035..6042ba7e9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,6 +59,7 @@ ui_*.py
source/canvaspreviewframe.py
source/carla_config.py
source/digitalpeakmeter.py
+source/draggablegraphicsview.py
source/ledbutton.py
source/paramspinbox.py
source/pianoroll.py
diff --git a/Makefile b/Makefile
index 1baeca407..855e75f8a 100644
--- a/Makefile
+++ b/Makefile
@@ -266,6 +266,7 @@ RES = \
bin/resources/carla_widgets.py \
bin/resources/canvaspreviewframe.py \
bin/resources/digitalpeakmeter.py \
+ bin/resources/draggablegraphicsview.py \
bin/resources/externalui.py \
bin/resources/ledbutton.py \
bin/resources/paramspinbox.py \
@@ -354,6 +355,7 @@ endif
WIDGETS = \
source/canvaspreviewframe.py \
source/digitalpeakmeter.py \
+ source/draggablegraphicsview.py \
source/ledbutton.py \
source/paramspinbox.py \
source/pianoroll.py \
@@ -628,6 +630,7 @@ endif
$(LINK) $(DATADIR)/carla/carla_widgets.py $(DESTDIR)$(DATADIR)/carla/resources
$(LINK) $(DATADIR)/carla/canvaspreviewframe.py $(DESTDIR)$(DATADIR)/carla/resources
$(LINK) $(DATADIR)/carla/digitalpeakmeter.py $(DESTDIR)$(DATADIR)/carla/resources
+ $(LINK) $(DATADIR)/carla/draggablegraphicsview.py $(DESTDIR)$(DATADIR)/carla/resources
$(LINK) $(DATADIR)/carla/externalui.py $(DESTDIR)$(DATADIR)/carla/resources
$(LINK) $(DATADIR)/carla/ledbutton.py $(DESTDIR)$(DATADIR)/carla/resources
$(LINK) $(DATADIR)/carla/paramspinbox.py $(DESTDIR)$(DATADIR)/carla/resources
diff --git a/resources/ui/carla_host.ui b/resources/ui/carla_host.ui
index 90b0ca378..610e46b56 100644
--- a/resources/ui/carla_host.ui
+++ b/resources/ui/carla_host.ui
@@ -127,7 +127,7 @@
1
-
-
+
-
@@ -864,6 +864,11 @@
QListWidget
+
+ DraggableGraphicsView
+ QGraphicsView
+
+
diff --git a/source/widgets/draggablegraphicsview.py b/source/widgets/draggablegraphicsview.py
new file mode 100644
index 000000000..74f6bd86e
--- /dev/null
+++ b/source/widgets/draggablegraphicsview.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+# Middle-click draggable QGraphicsView
+# Copyright (C) 2016 Filipe Coelho
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# For a full copy of the GNU General Public License see the doc/GPL.txt file.
+
+# ------------------------------------------------------------------------------------------------------------
+# Imports (Config)
+
+from carla_config import *
+
+# ------------------------------------------------------------------------------------------------------------
+# Imports (Global)
+
+if config_UseQt5:
+ from PyQt5.QtCore import Qt
+ from PyQt5.QtGui import QCursor
+ from PyQt5.QtWidgets import QGraphicsView, QMouseEvent
+else:
+ from PyQt4.QtCore import Qt
+ from PyQt4.QtGui import QCursor, QGraphicsView, QMouseEvent
+
+# ------------------------------------------------------------------------------------------------------------
+# Widget Class
+
+class DraggableGraphicsView(QGraphicsView):
+ def __init__(self, parent):
+ QGraphicsView.__init__(self, parent)
+
+ self.fPanning = False
+
+ def mousePressEvent(self, event):
+ if event.button() == Qt.MiddleButton:
+ self.fPanning = True
+ self.setDragMode(QGraphicsView.ScrollHandDrag)
+ event = QMouseEvent(event.type(), event.pos(), Qt.LeftButton, Qt.LeftButton, event.modifiers())
+
+ QGraphicsView.mousePressEvent(self, event)
+
+ def mouseReleaseEvent(self, event):
+ if self.fPanning:
+ self.fPanning = False
+ self.setDragMode(QGraphicsView.NoDrag)
+ self.setCursor(QCursor(Qt.ArrowCursor))
+
+ QGraphicsView.mouseReleaseEvent(self, event)