| 
							- #!/usr/bin/env python3
 - # -*- coding: utf-8 -*-
 - 
 - # QGraphicsEmbedScene class, based on Qt3D C++ code
 - # Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 - # Copyright (C) 2014 Filipe Coelho <falktx@falktx.com>
 - #
 - # 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 pyqtSignal, pyqtSlot, qRound, Qt, QPoint, QPointF, QRectF, QSize
 -     from PyQt5.QtGui import QPainter
 -     from PyQt5.QtOpenGL import QGLFramebufferObject, QGLFramebufferObjectFormat
 -     from PyQt5.QtWidgets import QApplication, QEvent, QGraphicsItem, QGraphicsScene
 - else:
 -     from PyQt4.QtCore import pyqtSignal, pyqtSlot, qRound, Qt, QEvent, QObject, QPoint, QPointF, QRectF, QSize
 -     from PyQt4.QtOpenGL import QGLFramebufferObject, QGLFramebufferObjectFormat
 -     from PyQt4.QtGui import QApplication, QPainter, QGraphicsItem, QGraphicsScene
 - 
 - # ------------------------------------------------------------------------------------------------------------
 - 
 - # Returns the next power of two that is greater than or
 - # equal to @a value.  The @a value must be positive or the
 - # result is undefined.
 - #
 - # This is a convenience function for use with GL texture
 - # handling code.
 - 
 - def nextPowerOfTwo(value):
 -     value -= 1
 -     value |= value >> 1
 -     value |= value >> 2
 -     value |= value >> 4
 -     value |= value >> 8
 -     value |= value >> 16
 -     value += 1
 -     return value
 - 
 - # ------------------------------------------------------------------------------------------------------------
 - # Widget Class
 - 
 - class QGraphicsEmbedScene(QGraphicsScene):
 -     def __init__(self, parent):
 -         QGraphicsScene.__init__(self, parent)
 - 
 -         self.dirty = True
 -         self.fbo = None
 - 
 -         self.format = QGLFramebufferObjectFormat()
 -         self.format.setAttachment(QGLFramebufferObject.CombinedDepthStencil)
 - 
 -         self.pressedPos = QPoint()
 - 
 -         self.changed.connect(self.slot_update)
 -         self.sceneRectChanged.connect(self.slot_update)
 - 
 -     def format(self):
 -         return self.format
 - 
 -     def setFormat(self, format):
 -         self.format = format
 - 
 -     def renderToTexture(self, levelOfDetail = 1.0):
 -         # Determine the fbo size we will need.
 -         size = (self.sceneRect().size() * levelOfDetail).toSize()
 -         fboSize = nextPowerOfTwo(size)
 -         if fboSize.isEmpty():
 -             fboSize = QSize(16, 16)
 - 
 -         # Create or re-create the fbo.
 -         if self.fbo is None or self.fbo.size() != fboSize:
 -             #del self.fbo
 -             self.fbo = QGLFramebufferObject(fboSize, self.format)
 -             if not self.fbo.isValid():
 -                 #del self.fbo
 -                 self.fbo = None
 -                 return 0
 -             self.dirty = True
 - 
 -         # Return the previous texture contents if the scene hasn't changed.
 -         if self.fbo is not None and not self.dirty:
 -             return self.fbo.texture()
 - 
 -         # Render the scene into the fbo, scaling the QPainter's view
 -         # transform up to the power-of-two fbo size.
 -         painter = QPainter(self.fbo)
 -         painter.setWindow(0, 0, size.width(), size.height())
 -         painter.setViewport(0, 0, fboSize.width(), fboSize.height())
 -         self.render(painter)
 -         painter.end()
 -         self.dirty = False
 -         return self.fbo.texture()
 - 
 -     def deliverEvent(self, event, texCoord):
 -         # Map the texture co-ordinate into "screen" co-ordinates.
 -         # Mouse move and release events can extend beyond the boundaries
 -         # of the scene, for "click and drag off-screen" operations.
 -         # Mouse press and double-click events need to be constrained.
 -         bounds = self.sceneRect()
 -         screenX = qRound(texCoord.x() * bounds.width())
 -         screenY = qRound((1.0 - texCoord.y()) * bounds.height())
 -         if event.type() in (QEvent.GraphicsSceneMousePress,
 -                             QEvent.GraphicsSceneMouseDoubleClick,
 -                             QEvent.MouseButtonPress,
 -                             QEvent.MouseButtonDblClick):
 -             if screenX < 0:
 -                 screenX = 0
 -             elif screenX >= bounds.width():
 -                 screenX = qRound(bounds.width() - 1)
 -             if screenY < 0:
 -                 screenY = 0
 -             elif screenY >= bounds.height():
 -                 screenY = qRound(bounds.height() - 1)
 -             self.pressedPos = QPoint(screenX, screenY)
 - 
 -         # Convert the event and deliver it to the scene.
 -         eventType = event.type()
 - 
 -         if eventType in (QEvent.GraphicsSceneMouseMove,
 -                          QEvent.GraphicsSceneMousePress,
 -                          QEvent.GraphicsSceneMouseRelease,
 -                          QEvent.GraphicsSceneMouseDoubleClick):
 -             pass
 -             #QGraphicsSceneMouseEvent *ev =
 -                 #static_cast<QGraphicsSceneMouseEvent *>(event)
 -             #QGraphicsSceneMouseEvent e(ev->type())
 -             #e.setPos(QPointF(screenX, screenY))
 -             #e.setScenePos(QPointF(screenX + bounds.x(), screenY + bounds.y()))
 -             #e.setScreenPos(QPoint(screenX, screenY))
 -             #e.setButtonDownScreenPos(ev->button(), d->pressedPos)
 -             #e.setButtonDownScenePos
 -                 #(ev->button(), QPointF(d->pressedPos.x() + bounds.x(),
 -                                       #d->pressedPos.y() + bounds.y()))
 -             #e.setButtons(ev->buttons())
 -             #e.setButton(ev->button())
 -             #e.setModifiers(ev->modifiers())
 -             #e.setAccepted(false)
 -             #QApplication::sendEvent(this, &e)
 - 
 -         elif eventType == QEvent.GraphicsSceneWheel:
 -             pass
 -             #QGraphicsSceneWheelEvent *ev =
 -                 #static_cast<QGraphicsSceneWheelEvent *>(event)
 -             #QGraphicsSceneWheelEvent e(QEvent::GraphicsSceneWheel)
 -             #e.setPos(QPointF(screenX, screenY))
 -             #e.setScenePos(QPointF(screenX + bounds.x(), screenY + bounds.y()))
 -             #e.setScreenPos(QPoint(screenX, screenY))
 -             #e.setButtons(ev->buttons())
 -             #e.setModifiers(ev->modifiers())
 -             #e.setDelta(ev->delta())
 -             #e.setOrientation(ev->orientation())
 -             #e.setAccepted(false)
 -             #QApplication::sendEvent(this, &e)
 - 
 -         elif eventType in (QEvent.MouseButtonPress,
 -                            QEvent.MouseButtonRelease,
 -                            QEvent.MouseButtonDblClick,
 -                            QEvent.MouseMove):
 -             pass
 -             #QMouseEvent *ev = static_cast<QMouseEvent *>(event)
 -             #QEvent::Type type
 -             #if (ev->type() == QEvent::MouseButtonPress)
 -                 #type = QEvent::GraphicsSceneMousePress
 -             #else if (ev->type() == QEvent::MouseButtonRelease)
 -                 #type = QEvent::GraphicsSceneMouseRelease
 -             #else if (ev->type() == QEvent::MouseButtonDblClick)
 -                 #type = QEvent::GraphicsSceneMouseDoubleClick
 -             #else
 -                 #type = QEvent::GraphicsSceneMouseMove
 -             #QGraphicsSceneMouseEvent e(type)
 -             #e.setPos(QPointF(screenX, screenY))
 -             #e.setScenePos(QPointF(screenX + bounds.x(), screenY + bounds.y()))
 -             #e.setScreenPos(QPoint(screenX, screenY))
 -             #e.setButtonDownScreenPos(ev->button(), d->pressedPos)
 -             #e.setButtonDownScenePos
 -                 #(ev->button(), QPointF(d->pressedPos.x() + bounds.x(),
 -                                       #d->pressedPos.y() + bounds.y()))
 -             #e.setButtons(ev->buttons())
 -             #e.setButton(ev->button())
 -             #e.setModifiers(ev->modifiers())
 -             #e.setAccepted(false)
 -             #QApplication::sendEvent(this, &e)
 - 
 -         elif eventType == QEvent.Wheel:
 -             pass
 -             #QWheelEvent *ev = static_cast<QWheelEvent *>(event)
 -             #QGraphicsSceneWheelEvent e(QEvent::GraphicsSceneWheel)
 -             #e.setPos(QPointF(screenX, screenY))
 -             #e.setScenePos(QPointF(screenX + bounds.x(), screenY + bounds.y()))
 -             #e.setScreenPos(QPoint(screenX, screenY))
 -             #e.setButtons(ev->buttons())
 -             #e.setModifiers(ev->modifiers())
 -             #e.setDelta(ev->delta())
 -             #e.setOrientation(ev->orientation())
 -             #e.setAccepted(false)
 -             #QApplication::sendEvent(this, &e)
 - 
 -         #else:
 -             # Send the event directly without any conversion.
 -             # Typically used for keyboard, focus, and enter/leave events.
 -             #QApplication.sendEvent(self, event)
 - 
 -         QApplication.sendEvent(self, event)
 - 
 -     def drawBackground(self, painter, rect):
 -         if self.backgroundBrush().style() == Qt.NoBrush:
 -             # Fill the fbo with the transparent color as there won't
 -             # be a window or graphics item drawing a previous background.
 -             painter.save()
 -             painter.setCompositionMode(QPainter.CompositionMode_Source)
 -             painter.fillRect(rect, Qt.transparent)
 -             painter.restore()
 -         else:
 -             QGraphicsScene.drawBackground(painter, rect)
 - 
 -     @pyqtSlot()
 -     def slot_update(self):
 -         self.dirty = True
 - 
 - # ------------------------------------------------------------------------------------------------------------
 - # PatchScene compatible class
 - 
 - # object types
 - CanvasBoxType           = QGraphicsItem.UserType + 1
 - CanvasIconType          = QGraphicsItem.UserType + 2
 - CanvasPortType          = QGraphicsItem.UserType + 3
 - CanvasLineType          = QGraphicsItem.UserType + 4
 - CanvasBezierLineType    = QGraphicsItem.UserType + 5
 - CanvasLineMovType       = QGraphicsItem.UserType + 6
 - CanvasBezierLineMovType = QGraphicsItem.UserType + 7
 - 
 - class PatchScene3D(QGraphicsEmbedScene):
 -     scaleChanged    = pyqtSignal(float)
 -     sceneGroupMoved = pyqtSignal(int, int, QPointF)
 -     pluginSelected  = pyqtSignal(list)
 - 
 -     def __init__(self, parent, view):
 -         QGraphicsEmbedScene.__init__(self, parent)
 - 
 -         self.m_ctrl_down = False
 -         self.m_mouse_down_init = False
 -         self.m_mouse_rubberband = False
 - 
 -         self.addRubberBand()
 - 
 -         self.m_view = view
 -         #if not self.m_view:
 -             #qFatal("PatchCanvas::PatchScene() - invalid view")
 - 
 -         self.selectionChanged.connect(self.slot_selectionChanged)
 - 
 -     def addRubberBand(self):
 -         self.m_rubberband = self.addRect(QRectF(0, 0, 0, 0))
 -         self.m_rubberband.setZValue(-1)
 -         self.m_rubberband.hide()
 -         self.m_rubberband_selection = False
 -         self.m_rubberband_orig_point = QPointF(0, 0)
 - 
 -     def clear(self):
 -         QGraphicsEmbedScene.clear(self)
 - 
 -         # Re-add rubberband, that just got deleted
 -         self.addRubberBand()
 - 
 -     def fixScaleFactor(self):
 -         pass
 - 
 -     def updateTheme(self):
 -         pass
 - 
 -     def zoom_fit(self):
 -         pass
 - 
 -     def zoom_in(self):
 -         pass
 - 
 -     def zoom_out(self):
 -         pass
 - 
 -     def zoom_reset(self):
 -         pass
 - 
 -     @pyqtSlot()
 -     def slot_selectionChanged(self):
 -         items_list = self.selectedItems()
 - 
 -         if len(items_list) == 0:
 -             self.pluginSelected.emit([])
 -             return
 - 
 -         plugin_list = []
 - 
 -         for item in items_list:
 -             if item and item.isVisible():
 -                 group_item = None
 - 
 -                 if item.type() == CanvasBoxType:
 -                     group_item = item
 -                 elif item.type() == CanvasPortType:
 -                     group_item = item.parentItem()
 -                 #elif item.type() in (CanvasLineType, CanvasBezierLineType, CanvasLineMovType, CanvasBezierLineMovType):
 -                     #plugin_list = []
 -                     #break
 - 
 -                 if group_item is not None and group_item.m_plugin_id >= 0:
 -                     plugin_list.append(group_item.m_plugin_id)
 - 
 -         self.pluginSelected.emit(plugin_list)
 
 
  |