예제 #1
0
 def layout(self):
     top_height = self.TOP_HEIGHT
     bottom_height = self.BOTTOM_HEIGHT
     # add a title label at the top
     if ((self.scene()) and (not self.title_proxy)):
         title_view = view.NameLabel(self.unit)
         self.title_proxy = self.scene().addWidget(title_view)
         self.title_proxy.setParentItem(self)
     r = self.boundingRect()
     r.adjust(1, 1, -1, -1)
     if (self.title_proxy):
         title_view = self.title_proxy.widget()
         title_view.setFixedWidth(r.width() - (2 * top_height))
         title_height = title_view.geometry().height()
         self.title_proxy.setPos(
             QPointF(top_height, (top_height - title_height) / 2.0))
     # make a button to delete the unit
     if (self.allow_delete):
         if ((self.scene()) and (not self._delete_button)):
             self._delete_button = DeleteButton(self)
             self._delete_button.clicked.connect(self.on_delete)
         if (self._delete_button):
             self._delete_button.setRect(
                 QRectF(r.right() - top_height, r.top(), top_height,
                        top_height))
     elif (self._delete_button):
         self._delete_button.destroy()
         self._delete_button = None
     # make a button to add to the unit
     if (self.allow_add):
         if ((self.scene()) and (not self._add_button)):
             self._add_button = AddButton(self)
             self._add_button.clicked.connect(self.on_add)
         if (self._add_button):
             self._add_button.setRect(
                 QRectF(r.left(),
                        r.bottom() - bottom_height, bottom_height,
                        bottom_height))
     elif (self._add_button):
         self._add_button.destroy()
         self._add_button = None
     # make a button to drag the unit
     if ((self.scene()) and (not self._drag_button)):
         self._drag_button = DragButton(self, self.unit)
     if (self._drag_button):
         self._drag_button.setRect(
             QRectF(r.left(), r.top(), top_height, top_height))
     # make a button to resize the unit
     if ((self.allow_resize_width) or (self.allow_resize_height)):
         if ((self.scene()) and (not self._resize_button)):
             self._resize_button = ResizeButton(
                 self,
                 target=self.unit,
                 horizontal=self.allow_resize_width,
                 vertical=self.allow_resize_height)
             self._resize_button.resize.connect(self.on_resize)
         if (self._resize_button):
             self._resize_button.setRect(
                 QRectF(r.right() - bottom_height,
                        r.bottom() - bottom_height, bottom_height,
                        bottom_height))
     elif (self._resize_button):
         self._resize_button.resize.disconnect(self.on_resize)
         self._resize_button.destroy()
         self._resize_button = None
     # position the content, if any
     m = self.MARGIN
     content_pos = QPointF(m, m + top_height)
     content_height = 0.0
     if (self._content):
         self._content.setPos(content_pos)
         content_height = self._content.boundingRect().height()
     # position inputs and outputs left and right of the content
     io_rect = QRectF(0.0, content_pos.y(), r.width(), content_height)
     if (self._input_layout):
         self._input_layout.setRect(io_rect)
     if (self._output_layout):
         self._output_layout.setRect(io_rect)
예제 #2
0
 def layout(self):
   top_height = self.TOP_HEIGHT
   bottom_height = self.BOTTOM_HEIGHT
   # add a title label at the top
   if ((self.scene()) and (not self.title_proxy)):
     title_view = view.NameLabel(self.unit)
     self.title_proxy = self.scene().addWidget(title_view)
     self.title_proxy.setParentItem(self)
   r = self.boundingRect()
   r.adjust(1, 1, -1, -1)
   if (self.title_proxy):
     title_view = self.title_proxy.widget()
     title_view.setFixedWidth(r.width() - (2 * top_height))
     title_height = title_view.geometry().height()
     self.title_proxy.setPos(
       QPointF(top_height, (top_height - title_height) / 2.0))
   # make a button to delete the unit
   if (self.allow_delete):
     if ((self.scene()) and (not self._delete_button)):
       self._delete_button = DeleteButton(self)
       self._delete_button.clicked.connect(self.on_delete)
     if (self._delete_button):
       self._delete_button.setRect(
         QRectF(r.right() - top_height, r.top(), top_height, top_height))
   elif (self._delete_button):
     self._delete_button.destroy()
     self._delete_button = None
   # make a button to add to the unit
   if (self.allow_add):
     if ((self.scene()) and (not self._add_button)):
       self._add_button = AddButton(self)
       self._add_button.clicked.connect(self.on_add)
     if (self._add_button):
       self._add_button.setRect(
         QRectF(r.left(), r.bottom() - bottom_height, 
                bottom_height, bottom_height))
   elif (self._add_button):
     self._add_button.destroy()
     self._add_button = None
   # make a button to drag the unit
   if ((self.scene()) and (not self._drag_button)):
     self._drag_button = DragButton(self, self.unit)
   if (self._drag_button):
     self._drag_button.setRect(
       QRectF(r.left(), r.top(), top_height, top_height))
   # make a button to resize the unit
   if ((self.allow_resize_width) or (self.allow_resize_height)):
     if ((self.scene()) and (not self._resize_button)):
       self._resize_button = ResizeButton(self, 
         target=self.unit,
         horizontal=self.allow_resize_width, 
         vertical=self.allow_resize_height)
       self._resize_button.resize.connect(self.on_resize)
     if (self._resize_button):
       self._resize_button.setRect(
         QRectF(r.right() - bottom_height, r.bottom() - bottom_height, 
                bottom_height, bottom_height))
   elif (self._resize_button):
     self._resize_button.resize.disconnect(self.on_resize)
     self._resize_button.destroy()
     self._resize_button = None
   # position the content, if any
   m = self.MARGIN
   content_pos = QPointF(m, m + top_height)
   content_height = 0.0
   if (self._content):
     self._content.setPos(content_pos)
     content_height = self._content.boundingRect().height()
   # position inputs and outputs left and right of the content
   io_rect = QRectF(0.0, content_pos.y(), 
                    r.width(), content_height)
   if (self._input_layout):
     self._input_layout.setRect(io_rect)
   if (self._output_layout):
     self._output_layout.setRect(io_rect)
예제 #3
0
class UnitView(view.Selectable, view.ModelView):
    # define a mapping from unit classes to specific view classes
    _unit_class_to_view_class = dict()
    # the margin to leave around the content
    MARGIN = 10.0
    # the height of the bar at the top, containing the title and buttons
    TOP_HEIGHT = 24.0
    # the height of the bar at the bottom, containing the add and resize buttons
    BOTTOM_HEIGHT = 24.0

    def __init__(self, *args, **kwargs):
        view.ModelView.__init__(self, *args, **kwargs)
        view.Selectable.__init__(self)
        self.title_proxy = None
        self._size = QSizeF(60.0, 40.0)
        self._content = None
        self._input_layout = None
        self._output_layout = None
        self.allow_delete = True
        self._delete_button = None
        self._drag_button = None
        self.allow_resize_width = False
        self.allow_resize_height = False
        self._resize_button = None
        self.allow_add = False
        self._add_button = None
        # editing the title may change the width of the unit
        self.unit.name_changed.connect(self.on_name_changed)
        # show a normal cursor to override the workspace cursor
        self.setCursor(Qt.ArrowCursor)

    def destroy(self):
        if (self._resize_button):
            self._resize_button.resize.disconnect(self.on_resize)
        self.unit.name_changed.disconnect(self.on_name_changed)
        # removing the content will change the unit view's geometry briefly
        self.prepareGeometryChange()
        view.ModelView.destroy(self)

    @property
    def unit(self):
        return (self._model)

    # return whether the unit view is being moved or resized
    @property
    def moving(self):
        return (((self._drag_button) and (self._drag_button.dragging))
                or ((self._resize_button) and (self._resize_button.dragging)))

    # register a class for use as a unit view
    @classmethod
    def register_unit_view(cls, unit_class, view_class):
        cls._unit_class_to_view_class[unit_class] = view_class

    # get an appropriate view for a unit
    @classmethod
    def view_for_unit(cls, unit):
        unit_class = unit.__class__
        if (unit_class in cls._unit_class_to_view_class):
            view_class = cls._unit_class_to_view_class[unit_class]
            return (view_class(unit))
        return (UnitView(unit))

    # handle the user wanting to remove the unit
    def on_delete(self):
        document_view = self.parentItemWithAttribute('document')
        if (document_view):
            document = document_view.document
            inputs = ()
            outputs = ()
            if (self._input_layout is not None):
                inputs = self._input_layout.items
            if (self._output_layout is not None):
                outputs = self._output_layout.items
            document.remove_unit(self.unit, inputs=inputs, outputs=outputs)

    # handle the user wanting to add to the unit (this will have different
    #  behaviors depending on the type of unit)
    def on_add(self):
        pass

    # get the size of the content (override for independent sizing)
    def content_size(self):
        return (self._content.boundingRect().size())

    # manage the rect to keep it centered on the content size
    def rect(self):
        r = view.ModelView.rect(self)
        if (self._content):
            m = self.MARGIN
            content_size = self.content_size()
            w = content_size.width() + (m * 2)
            h = content_size.height() + (m * 2)
            h += self.TOP_HEIGHT
            if ((self.allow_resize_width) or (self.allow_resize_height)
                    or (self.allow_add)):
                h += self.BOTTOM_HEIGHT
            r.setWidth(w)
            r.setHeight(h)
        # make sure there's enough space for the title
        top_width = (2 * self.TOP_HEIGHT)
        if (self.title_proxy):
            title_view = self.title_proxy.widget()
            tr = title_view.minimumSizeHint()
            top_width += tr.width()
        r.setWidth(max(r.width(), top_width))
        return (r)

    def setRect(self, rect):
        posChanged = ((rect.x() != self.pos().x())
                      or (rect.y() != self.pos().y()))
        if (posChanged):
            self.prepareGeometryChange()
            self.setPos(rect.x(), rect.y())

    def on_name_changed(self):
        self.prepareGeometryChange()
        self.layout()

    def on_resize(self, event, width, height):
        delta_width = width - self.unit.width
        delta_height = height - self.unit.height
        if (event.modifiers() == Qt.ShiftModifier):
            delta_x = delta_width / 2.0
            delta_y = delta_height / 2.0
            workspace_view = self.parentItemWithAttribute('units')
            if (workspace_view is not None):
                for other_unit in workspace_view.units:
                    if ((other_unit is not self.unit)
                            and (not isinstance(other_unit, unit.GroupUnit))):
                        if (other_unit.x < self.unit.x):
                            other_unit.x -= delta_x
                        elif (other_unit.x > self.unit.x):
                            other_unit.x += delta_x
                        if (other_unit.y < self.unit.y):
                            other_unit.y -= delta_y
                        elif (other_unit.y > self.unit.y):
                            other_unit.y += delta_y

    def layout(self):
        top_height = self.TOP_HEIGHT
        bottom_height = self.BOTTOM_HEIGHT
        # add a title label at the top
        if ((self.scene()) and (not self.title_proxy)):
            title_view = view.NameLabel(self.unit)
            self.title_proxy = self.scene().addWidget(title_view)
            self.title_proxy.setParentItem(self)
        r = self.boundingRect()
        r.adjust(1, 1, -1, -1)
        if (self.title_proxy):
            title_view = self.title_proxy.widget()
            title_view.setFixedWidth(r.width() - (2 * top_height))
            title_height = title_view.geometry().height()
            self.title_proxy.setPos(
                QPointF(top_height, (top_height - title_height) / 2.0))
        # make a button to delete the unit
        if (self.allow_delete):
            if ((self.scene()) and (not self._delete_button)):
                self._delete_button = DeleteButton(self)
                self._delete_button.clicked.connect(self.on_delete)
            if (self._delete_button):
                self._delete_button.setRect(
                    QRectF(r.right() - top_height, r.top(), top_height,
                           top_height))
        elif (self._delete_button):
            self._delete_button.destroy()
            self._delete_button = None
        # make a button to add to the unit
        if (self.allow_add):
            if ((self.scene()) and (not self._add_button)):
                self._add_button = AddButton(self)
                self._add_button.clicked.connect(self.on_add)
            if (self._add_button):
                self._add_button.setRect(
                    QRectF(r.left(),
                           r.bottom() - bottom_height, bottom_height,
                           bottom_height))
        elif (self._add_button):
            self._add_button.destroy()
            self._add_button = None
        # make a button to drag the unit
        if ((self.scene()) and (not self._drag_button)):
            self._drag_button = DragButton(self, self.unit)
        if (self._drag_button):
            self._drag_button.setRect(
                QRectF(r.left(), r.top(), top_height, top_height))
        # make a button to resize the unit
        if ((self.allow_resize_width) or (self.allow_resize_height)):
            if ((self.scene()) and (not self._resize_button)):
                self._resize_button = ResizeButton(
                    self,
                    target=self.unit,
                    horizontal=self.allow_resize_width,
                    vertical=self.allow_resize_height)
                self._resize_button.resize.connect(self.on_resize)
            if (self._resize_button):
                self._resize_button.setRect(
                    QRectF(r.right() - bottom_height,
                           r.bottom() - bottom_height, bottom_height,
                           bottom_height))
        elif (self._resize_button):
            self._resize_button.resize.disconnect(self.on_resize)
            self._resize_button.destroy()
            self._resize_button = None
        # position the content, if any
        m = self.MARGIN
        content_pos = QPointF(m, m + top_height)
        content_height = 0.0
        if (self._content):
            self._content.setPos(content_pos)
            content_height = self._content.boundingRect().height()
        # position inputs and outputs left and right of the content
        io_rect = QRectF(0.0, content_pos.y(), r.width(), content_height)
        if (self._input_layout):
            self._input_layout.setRect(io_rect)
        if (self._output_layout):
            self._output_layout.setRect(io_rect)

    # draw a box enclosing the content and title
    def _paint(self, qp):
        pen = self.pen()
        pen.setWidth(2.0)
        qp.setPen(pen)
        if (self.unit.selected):
            qp.setBrush(self.brush(0.30))
        elif (self.unit.hue is not None):
            color = QColor()
            color.setHsvF(self.unit.hue, 1.0, 1.0, 0.30)
            qp.setBrush(QBrush(color))
        else:
            qp.setBrush(self.brush(0.15))
        r = self.boundingRect()
        r.adjust(1, 1, -1, -1)
        qp.drawRoundedRect(r, 4.0, 4.0)
예제 #4
0
class UnitView(view.Selectable, view.ModelView):
  # define a mapping from unit classes to specific view classes
  _unit_class_to_view_class = dict()
  # the margin to leave around the content
  MARGIN = 10.0
  # the height of the bar at the top, containing the title and buttons
  TOP_HEIGHT = 24.0
  # the height of the bar at the bottom, containing the add and resize buttons
  BOTTOM_HEIGHT = 24.0
  def __init__(self, *args, **kwargs):
    view.ModelView.__init__(self, *args, **kwargs)
    view.Selectable.__init__(self)
    self.title_proxy = None
    self._size = QSizeF(60.0, 40.0)
    self._content = None
    self._input_layout = None
    self._output_layout = None
    self.allow_delete = True
    self._delete_button = None
    self._drag_button = None
    self.allow_resize_width = False
    self.allow_resize_height = False
    self._resize_button = None
    self.allow_add = False
    self._add_button = None
    # editing the title may change the width of the unit
    self.unit.name_changed.connect(self.on_name_changed)
    # show a normal cursor to override the workspace cursor
    self.setCursor(Qt.ArrowCursor)
  def destroy(self):
    if (self._resize_button):
      self._resize_button.resize.disconnect(self.on_resize)
    self.unit.name_changed.disconnect(self.on_name_changed)
    # removing the content will change the unit view's geometry briefly
    self.prepareGeometryChange()
    view.ModelView.destroy(self)  
  @property
  def unit(self):
    return(self._model)
  # return whether the unit view is being moved or resized
  @property
  def moving(self):
    return(((self._drag_button) and (self._drag_button.dragging)) or
           ((self._resize_button) and (self._resize_button.dragging)))
  # register a class for use as a unit view
  @classmethod
  def register_unit_view(cls, unit_class, view_class):
    cls._unit_class_to_view_class[unit_class] = view_class
  # get an appropriate view for a unit
  @classmethod
  def view_for_unit(cls, unit):
    unit_class = unit.__class__
    if (unit_class in cls._unit_class_to_view_class):
      view_class = cls._unit_class_to_view_class[unit_class]
      return(view_class(unit))
    return(UnitView(unit))
  # handle the user wanting to remove the unit
  def on_delete(self):
    document_view = self.parentItemWithAttribute('document')
    if (document_view):
      document = document_view.document
      inputs = ()
      outputs = ()
      if (self._input_layout is not None):
        inputs = self._input_layout.items
      if (self._output_layout is not None):
        outputs = self._output_layout.items
      document.remove_unit(self.unit, inputs=inputs, outputs=outputs)
  # handle the user wanting to add to the unit (this will have different 
  #  behaviors depending on the type of unit)
  def on_add(self):
    pass
  # get the size of the content (override for independent sizing)
  def content_size(self):
    return(self._content.boundingRect().size())
  # manage the rect to keep it centered on the content size
  def rect(self):
    r = view.ModelView.rect(self)
    if (self._content):
      m = self.MARGIN
      content_size = self.content_size()
      w = content_size.width() + (m * 2)
      h = content_size.height() + (m * 2)
      h += self.TOP_HEIGHT
      if ((self.allow_resize_width) or (self.allow_resize_height) or 
          (self.allow_add)):
        h += self.BOTTOM_HEIGHT
      r.setWidth(w)
      r.setHeight(h)
    # make sure there's enough space for the title
    top_width = (2 * self.TOP_HEIGHT)
    if (self.title_proxy):
      title_view = self.title_proxy.widget()
      tr = title_view.minimumSizeHint()
      top_width += tr.width()
    r.setWidth(max(r.width(), top_width))
    return(r)
  def setRect(self, rect):
    posChanged = ((rect.x() != self.pos().x()) or
                  (rect.y() != self.pos().y()))
    if (posChanged):
      self.prepareGeometryChange()
      self.setPos(rect.x(), rect.y())
  def on_name_changed(self):
    self.prepareGeometryChange()
    self.layout()
  def on_resize(self, event, width, height):
    delta_width = width - self.unit.width
    delta_height = height - self.unit.height
    if (event.modifiers() == Qt.ShiftModifier):
      delta_x = delta_width / 2.0
      delta_y = delta_height / 2.0
      workspace_view = self.parentItemWithAttribute('units')
      if (workspace_view is not None):
        for other_unit in workspace_view.units:
          if ((other_unit is not self.unit) and 
              (not isinstance(other_unit, unit.GroupUnit))):
            if (other_unit.x < self.unit.x):
              other_unit.x -= delta_x
            elif (other_unit.x > self.unit.x):
              other_unit.x += delta_x
            if (other_unit.y < self.unit.y):
              other_unit.y -= delta_y
            elif (other_unit.y > self.unit.y):
              other_unit.y += delta_y
  def layout(self):
    top_height = self.TOP_HEIGHT
    bottom_height = self.BOTTOM_HEIGHT
    # add a title label at the top
    if ((self.scene()) and (not self.title_proxy)):
      title_view = view.NameLabel(self.unit)
      self.title_proxy = self.scene().addWidget(title_view)
      self.title_proxy.setParentItem(self)
    r = self.boundingRect()
    r.adjust(1, 1, -1, -1)
    if (self.title_proxy):
      title_view = self.title_proxy.widget()
      title_view.setFixedWidth(r.width() - (2 * top_height))
      title_height = title_view.geometry().height()
      self.title_proxy.setPos(
        QPointF(top_height, (top_height - title_height) / 2.0))
    # make a button to delete the unit
    if (self.allow_delete):
      if ((self.scene()) and (not self._delete_button)):
        self._delete_button = DeleteButton(self)
        self._delete_button.clicked.connect(self.on_delete)
      if (self._delete_button):
        self._delete_button.setRect(
          QRectF(r.right() - top_height, r.top(), top_height, top_height))
    elif (self._delete_button):
      self._delete_button.destroy()
      self._delete_button = None
    # make a button to add to the unit
    if (self.allow_add):
      if ((self.scene()) and (not self._add_button)):
        self._add_button = AddButton(self)
        self._add_button.clicked.connect(self.on_add)
      if (self._add_button):
        self._add_button.setRect(
          QRectF(r.left(), r.bottom() - bottom_height, 
                 bottom_height, bottom_height))
    elif (self._add_button):
      self._add_button.destroy()
      self._add_button = None
    # make a button to drag the unit
    if ((self.scene()) and (not self._drag_button)):
      self._drag_button = DragButton(self, self.unit)
    if (self._drag_button):
      self._drag_button.setRect(
        QRectF(r.left(), r.top(), top_height, top_height))
    # make a button to resize the unit
    if ((self.allow_resize_width) or (self.allow_resize_height)):
      if ((self.scene()) and (not self._resize_button)):
        self._resize_button = ResizeButton(self, 
          target=self.unit,
          horizontal=self.allow_resize_width, 
          vertical=self.allow_resize_height)
        self._resize_button.resize.connect(self.on_resize)
      if (self._resize_button):
        self._resize_button.setRect(
          QRectF(r.right() - bottom_height, r.bottom() - bottom_height, 
                 bottom_height, bottom_height))
    elif (self._resize_button):
      self._resize_button.resize.disconnect(self.on_resize)
      self._resize_button.destroy()
      self._resize_button = None
    # position the content, if any
    m = self.MARGIN
    content_pos = QPointF(m, m + top_height)
    content_height = 0.0
    if (self._content):
      self._content.setPos(content_pos)
      content_height = self._content.boundingRect().height()
    # position inputs and outputs left and right of the content
    io_rect = QRectF(0.0, content_pos.y(), 
                     r.width(), content_height)
    if (self._input_layout):
      self._input_layout.setRect(io_rect)
    if (self._output_layout):
      self._output_layout.setRect(io_rect)
  # draw a box enclosing the content and title
  def _paint(self, qp):
    pen = self.pen()
    pen.setWidth(2.0)
    qp.setPen(pen)
    if (self.unit.selected):
      qp.setBrush(self.brush(0.30))
    elif (self.unit.hue is not None):
      color = QColor()
      color.setHsvF(self.unit.hue, 1.0, 1.0, 0.30)
      qp.setBrush(QBrush(color))
    else:
      qp.setBrush(self.brush(0.15))
    r = self.boundingRect()
    r.adjust(1, 1, -1, -1)
    qp.drawRoundedRect(r, 4.0, 4.0)