def __init__(self, universe=None):
        super(UniverseItem, self).__init__()
        self.setAcceptDrops(True)
        self._universe = universe

        self.underlying_pixmap_item = QGraphicsPixmapItem()
        self.underlying_pixmap_item.setPixmap(QPixmap(":/images/universe.png"))
class IconGraphicsWidget(QGraphicsWidget):
    """
    This class is responsible for visualization of icon with text
    """

    def __init__(self, path_to_image):
        super(IconGraphicsWidget, self).__init__()
        self.initialize(path_to_image)

    def initialize(self, path_to_image):
        self.underlying_pixmap_item = QGraphicsPixmapItem()
        self.underlying_pixmap_item.setPixmap(QPixmap(path_to_image))

        self.image_width = self.underlying_pixmap_item.pixmap().width()
        self.image_height = self.underlying_pixmap_item.pixmap().height()

        self.text = "Default text"

        self.horizontal_margin = 10
        self.vertical_margin = 20
        self.distance_to_text = 10
        bounding_rectangle_width = 2*self.horizontal_margin + self.image_width
        bounding_rectangle_height = 2*self.vertical_margin + self.image_height + self.distance_to_text

        self.bounding_rectangle = QRectF(0, 0, bounding_rectangle_width, bounding_rectangle_height)

    def paint(self, painter, option, widget=None):
        assert isinstance(painter, QPainter)

        painter.setBrush(Qt.white)
        painter.drawRoundedRect(self.bounding_rectangle, 5, 5)

        # Painting QPixmapItem element with it's own renderer
        transform = painter.transform()
        painter.translate(self.horizontal_margin, self.vertical_margin)
        self.underlying_pixmap_item.paint(painter, option, widget)
        painter.setTransform(transform)

        painter.drawText(QRectF(self.horizontal_margin,
                                self.bounding_rectangle.height() - self.vertical_margin,
                                self.image_width,
                                painter.fontMetrics().height()
                                ), self.text)

    def boundingRect(self):
        return self.bounding_rectangle

    def sizeHint(self, which, constraint=QSizeF()):
        return QSizeF(self.bounding_rectangle.width(), self.bounding_rectangle.height())

    def shape(self):
        path = QPainterPath()
        path.addRoundedRect(self.bounding_rectangle, 5, 5)
        return path

    def setText(self, text):
        self.text = text
        self.update()
    def initialize(self, path_to_image):
        self.underlying_pixmap_item = QGraphicsPixmapItem()
        self.underlying_pixmap_item.setPixmap(QPixmap(path_to_image))

        self.image_width = self.underlying_pixmap_item.pixmap().width()
        self.image_height = self.underlying_pixmap_item.pixmap().height()

        self.text = "Default text"

        self.horizontal_margin = 10
        self.vertical_margin = 20
        self.distance_to_text = 10
        bounding_rectangle_width = 2*self.horizontal_margin + self.image_width
        bounding_rectangle_height = 2*self.vertical_margin + self.image_height + self.distance_to_text

        self.bounding_rectangle = QRectF(0, 0, bounding_rectangle_width, bounding_rectangle_height)
class UniverseItem(ClickableGraphicsWidget):
    """
    This item represents universe object at the scene
    where universe is configured.
    """

    matter_added = Signal(QGraphicsItem, name="matter_added")
    atom_added = Signal(QGraphicsItem, name="atom_added")
    radial_force_added = Signal(QGraphicsItem, name="radial_force_added")
    expression_based_force_added = Signal(QGraphicsItem, name="expression_based_force_added")
    bitmap_force_added = Signal(QGraphicsItem, name="bitmap_force_added")
    natural_law_added = Signal(QGraphicsItem, name="natural_law_added")
    agent_added = Signal(QGraphicsItem, name="agent_added")
    sensor_added = Signal(QGraphicsItem, name="sensor_added")

    def __init__(self, universe=None):
        super(UniverseItem, self).__init__()
        self.setAcceptDrops(True)
        self._universe = universe

        self.underlying_pixmap_item = QGraphicsPixmapItem()
        self.underlying_pixmap_item.setPixmap(QPixmap(":/images/universe.png"))

    def dragEnterEvent(self, event):
        print "UniverseItem::dragEnterEvent"
        if event.mimeData().hasText() and event.mimeData().text() in ["Matter", "Atom", "RadialForce",
                                                                      "ExpressionBasedForce", "BitmapForce",
                                                                      "NaturalLaw", "Agent", "Sensor"]:
            event.setAccepted(True)
            self.update()
        else:
            event.setAccepted(False)

    def dragLeaveEvent(self, event):
        """

        :param event:
        :type event: QGraphicsSceneDragDropEvent
        :return:
        """
        print "UniverseItem::dragLeaveEvent"
        print event.pos()
        self.update()

    def dropEvent(self, event):
        print "UniverseItem::dropEvent"
        if event.mimeData().hasText() and event.mimeData().text() == "Matter":
            matter = self._universe.create_matter()
            matter_item = MatterItem(matter)
            self.matter_added.emit(matter_item)
        elif event.mimeData().hasText() and event.mimeData().text() == "Atom":
            atom = self._universe.create_atom()
            atom_item = AtomItem(atom)
            self.atom_added.emit(atom_item)
        elif event.mimeData().hasText() and event.mimeData().text() == "RadialForce":
            radial_force = self._universe.create_radial_force({"min_x": 0,
                                                               "max_x": 10,
                                                               "min_y": -10,
                                                               "max_y": 10,
                                                               "degree": 3,
                                                               "ys": [3, 3, 3, 2]
                                                               }
                                                              )
            radial_force_item = RadialForceItem(radial_force)
            self.radial_force_added.emit(radial_force_item)
        elif event.mimeData().hasText() and event.mimeData().text() == "ExpressionBasedForce":
            expression_based_force = self._universe.create_expression_based_force("0.0")
            expression_based_force_item = ExpressionBasedForceItem(expression_based_force)
            self.expression_based_force_added.emit(expression_based_force_item)
        elif event.mimeData().hasText() and event.mimeData().text() == "BitmapForce":
            bitmap_force = self._universe.create_bitmap_force()
            bitmap_force_item = BitmapForceItem(bitmap_force)
            self.bitmap_force_added.emit(bitmap_force_item)
        elif event.mimeData().hasText() and event.mimeData().text() == "NaturalLaw":
            natural_law = self._universe.create_natural_law()
            natural_law_item = NaturalLawItem(natural_law)
            self.natural_law_added.emit(natural_law_item)
        elif event.mimeData().hasText() and event.mimeData().text() == "Agent":
            agent = self._universe.create_agent()
            agent_item = AgentItem(agent)
            self.agent_added.emit(agent_item)
        elif event.mimeData().hasText() and event.mimeData().text() == "Sensor":
            sensor = self._universe.create_sensor()
            sensor_item = SensorItem(sensor)
            self.sensor_added.emit(sensor_item)

        self.update()

    def paint(self, painter, option, widget=None):
        """
        :type painter: QPainter
        :type option: QStyleOptionGraphicsItem
        :type widget: QWidget
        :return:
        """
        self.underlying_pixmap_item.paint(painter, option, widget)

    def boundingRect(self):
        return self.underlying_pixmap_item.boundingRect()

    def shape(self):
        return self.underlying_pixmap_item.shape()

    @property
    def universe(self):
        return self._universe

    @universe.setter
    def universe(self, universe):
        self._universe = universe