Пример #1
0
    def add_square(self, pos, size, col='black', thickness=None):
        """Draw a square.

        Args:
            pos (QPoint): square position
            size (QSize): square size
            col (str): square colour
            thickness (float): line thickness
        """
        from psyhive import qt

        _pos = qt.get_p(pos)
        _size = qt.get_size(size)
        _rect = QtCore.QRect(_pos, _size)

        _brush = QtGui.QBrush(qt.HColor(0, 0, 0, 0))
        _col = qt.get_col(col)
        _pen = QtGui.QPen(_col)
        if thickness:
            _pen.setWidthF(thickness)

        _pnt = qt.HPainter()
        _pnt.begin(self)
        _pnt.setPen(_pen)
        _pnt.setBrush(_brush)
        _pnt.drawRect(_rect)
        _pnt.end()

        return _rect
Пример #2
0
    def _callback__PlaySeq(self):

        _work = get_single(self.ui.Work.selected_data(), catch=True)
        if not _work:
            return
        _c_work = self.c_works[_work]
        _viewables = [
            _out for _out in _c_work.find_outputs()
            if _out.format in ['mov', 'jpg']
        ]

        if len(_viewables) == 1:
            _viewable = get_single(_viewables)
            _seq = get_single(_viewable.find_files())
            _seq.view()
            return

        _menu = qt.HMenu(self.ui.PlaySeq)
        for _viewable in _viewables:
            _seq = get_single(_viewable.find_files())
            _menu.add_action('View ' + _viewable.output_type,
                             func=_seq.view,
                             icon=icons.EMOJI.find('Blue Circle'))
        _pos = qt.get_p(self.ui.PlaySeq.size() / 2)
        _menu.exec_(self.ui.PlaySeq.mapToGlobal(_pos))
Пример #3
0
    def add_polygon(self, pts, col, outline='black', thickness=1.0):
        """Draw a polygon on this pixmap.

        Args:
            pts (QPointF list): polygon points
            col (QColor): fill colour
            outline (str|None): outline colour (if any)
            thickness (float): line thickness
        """
        from psyhive import qt

        if outline:
            _pen = QtGui.QPen(outline)
            _pen.setCapStyle(Qt.RoundCap)
            if thickness:
                _pen.setWidthF(thickness)
        else:
            _pen = QtGui.QPen()
            _pen.setStyle(Qt.NoPen)

        _col = qt.get_col(col)
        _brush = QtGui.QBrush(_col)
        _poly = QtGui.QPolygonF()
        for _pt in pts:
            _pt = qt.get_p(_pt)
            _poly.append(_pt)

        _pnt = HPainter()
        _pnt.begin(self)
        _pnt.setBrush(_brush)
        _pnt.setPen(_pen)
        _pnt.drawPolygon(_poly)
        _pnt.end()
Пример #4
0
    def add_circle(self,
                   pos,
                   col='black',
                   radius=10,
                   thickness=None,
                   operation=None,
                   pen=None):
        """Draw a circle on this pixmap.

        Args:
            pos (QPoint): centre point
            col (str): line colour
            radius (int): circle radius
            thickness (float): line thickness
            operation (str): compositing operation
            pen (QPen): override pen
        """
        from psyhive import qt

        _pos = qt.get_p(pos)
        _col = qt.get_col(col)
        _pen = pen or QtGui.QPen(_col)
        if thickness:
            _pen.setWidthF(thickness)
        _rect = QtCore.QRect(_pos.x() - radius,
                             _pos.y() - radius, radius * 2, radius * 2)

        _pnt = HPainter()
        _pnt.begin(self)
        _pnt.set_operation(operation)
        _pnt.setPen(_pen)
        _pnt.drawArc(_rect, 0, 360 * 16)
        _pnt.end()

        return _rect
Пример #5
0
def read_input(msg="Enter input:",
               title="Input dialog",
               default=None,
               type_=str,
               width=300,
               required=False,
               parent=None):
    """Show an input dialog requesting the user enter data.

    Args:
        msg (str): dialog message
        title (str): dialog title
        default (any): default value for dialog
        type_ (type): type of data to receive
        width (int): dialog width
        required (bool): whether data is required
        parent (QDialog): parent dialog

    Returns:
        (any): entered data of requested type
    """
    from psyhive import qt
    _locals = locals()
    _args = [parent] if parent else []

    # Get pos
    _pos = None
    if parent:
        _pos = parent.get_c()

    if type_ is str:
        _default = default or ''
        _dialog = QtWidgets.QInputDialog(*_args)
        _dialog.setInputMode(QtWidgets.QInputDialog.TextInput)
        _dialog.setWindowTitle(title)
        _dialog.setLabelText(msg)
        _dialog.setTextValue(_default)
        _dialog.resize(width, 100)
        if _pos:
            _dialog.move(_pos - qt.get_p(_dialog.size()) / 2)
        _responded = _dialog.exec_()
        _result = str(_dialog.textValue())
    elif type_ is int:
        _default = default or 1
        _result, _responded = QtWidgets.QInputDialog.getInt(
            None, title, msg, _default)
    else:
        raise ValueError('Unhandled type: {}'.format(type_.__name__))

    if _responded in [0, False]:
        raise DialogCancelled

    if required and not _result:
        notify_warning(
            'This dialog requires information to be entered.\n\nPlease enter '
            'some text or press cancel to exit.')
        _result = read_input(**_locals)
        return _result

    return _result
Пример #6
0
    def get_c(self):
        """Get centre point of this pixmap.

        Returns:
            (QPoint): centre
        """
        from psyhive import qt
        return qt.get_p(self.size()) / 2
Пример #7
0
    def get_c(self):
        """Get interface centre.

        Returns:
            (QPoint): centre
        """
        from psyhive import qt
        return self.pos() + qt.get_p(self.size() / 2)
Пример #8
0
def _get_rect(anchor, pos, size):
    """Get rect for the given pos/size and anchor position.

    Args:
        anchor (str): anchor point
        pos (QPoint): anchor position
        size (QSize): rect size

    Returns:
        (QRect): rectangle
    """
    from psyhive import qt

    _size = qt.get_size(size)
    _pos = qt.get_p(pos)
    if anchor == 'C':
        _root = _pos - qt.get_p(_size) / 2
    elif anchor == 'L':
        _root = _pos - qt.get_p(0, _size.height() / 2)
    elif anchor == 'R':
        _root = _pos - qt.get_p(_size.width(), _size.height() / 2)
    elif anchor == 'T':
        _root = _pos - qt.get_p(_size.width() / 2, 0)
    elif anchor == 'TL':
        _root = _pos
    elif anchor == 'TR':
        _root = _pos - qt.get_p(_size.width(), 0)
    elif anchor == 'BL':
        _root = _pos - qt.get_p(0, _size.height())
    else:
        raise ValueError(anchor)

    return QtCore.QRect(_root, _size)
Пример #9
0
    def add_line(self,
                 pt1,
                 pt2,
                 col='black',
                 thickness=None,
                 operation=None,
                 pen=None,
                 verbose=0):
        """Draw a straight line on this pixmap.

        Args:
            pt1 (QPoint): start point
            pt2 (QPoint): end point
            col (str): line colour
            thickness (float): line thickness
            operation (str): compositing operation
            pen (QPen): override pen (ignores all other pen attrs)
            verbose (int): print process data
        """
        from psyhive import qt

        _pt1 = qt.get_p(pt1)
        _pt2 = qt.get_p(pt2)

        # Get pen
        if pen:
            _pen = pen
        else:
            _col = qt.get_col(col)
            _pen = QtGui.QPen(_col)
            _pen.setCapStyle(Qt.RoundCap)
            _pen.setJoinStyle(Qt.RoundJoin)
            if thickness:
                _pen.setWidthF(thickness)

            lprint("COL", _col, verbose=verbose)

        _pnt = HPainter()
        _pnt.begin(self)
        _pnt.setPen(_pen)
        _pnt.set_operation(operation)
        _pnt.drawLine(_pt1.x(), _pt1.y(), _pt2.x(), _pt2.y())
        _pnt.end()
Пример #10
0
    def add_dot(self,
                pos,
                col='black',
                radius=1.0,
                outline=None,
                thickness=None,
                operation=None,
                render_hint=None):
        """Draw a circle on this pixmap.

        Args:
            pos (QPoint): centre point
            col (str): dot colour
            radius (float): dot radius
            outline (QPen): apply outline pen
            thickness (float): line thickness
            operation (str): compositing operation
            render_hint (RenderHint): add render hint
        """
        from psyhive import qt

        _pos = qt.get_p(pos)
        _col = qt.get_col(col)
        _brush = QtGui.QBrush(_col)

        # Set outline
        if thickness:
            _pen = QtGui.QPen(qt.get_col('Black'))
            _pen.setWidthF(thickness)
        elif not outline:
            _pen = QtGui.QPen(_col)
            _pen.setStyle(Qt.NoPen)
        elif isinstance(outline, QtGui.QPen):
            _pen = outline
        elif isinstance(outline, six.string_types):
            _out_col = qt.get_col(outline)
            _pen = QtGui.QPen(_out_col)
        else:
            raise ValueError(outline)

        _pnt = HPainter()
        _pnt.begin(self)
        _pnt.setBrush(_brush)
        _pnt.setPen(_pen)
        if render_hint:
            _pnt.setRenderHint(render_hint)
        _pnt.set_operation(operation)
        _pnt.drawEllipse(_pos.x() - radius,
                         _pos.y() - radius, radius * 2, radius * 2)
        _pnt.end()
Пример #11
0
    def add_path(self, pts, col='black', thickness=None, pen=None):
        """Draw a path on this pixmap.

        Args:
            pts (QPoint list): list of points in path
            col (str): path colour
            thickness (float): line thickness
            pen (QPen): override pen (ignores all other pen attrs)
        """
        from psyhive import qt

        # Set pen
        if pen:
            _pen = pen
        else:
            _col = qt.get_col(col)
            _pen = pen or QtGui.QPen(_col)
            _pen.setCapStyle(Qt.RoundCap)
            if thickness:
                _pen.setWidthF(thickness)

        _brush = QtGui.QBrush()
        _brush.setStyle(Qt.NoBrush)

        # Make path object
        _path = QtGui.QPainterPath()
        _path.moveTo(qt.get_p(pts[0]))
        for _pt in pts[1:]:
            _path.lineTo(qt.get_p(_pt))

        _pnt = HPainter()
        _pnt.begin(self)
        _pnt.setPen(_pen)
        _pnt.setBrush(_brush)
        _pnt.drawPath(_path)
        _pnt.end()
Пример #12
0
    def add_overlay(self,
                    pix,
                    pos=None,
                    anchor='TL',
                    operation=None,
                    resize=None):
        """Add overlay to this pixmap.

        Args:
            pix (QPixmap|str): image to overlay
            pos (QPoint|tuple): position of overlay
            anchor (str): anchor position
            operation (str): overlay mode
            resize (int|QSize): apply resize to overlay

        Returns:
            (QRect): rectangle that was drawn
        """
        from psyhive import qt

        _pix = qt.get_pixmap(pix)
        if resize:
            _pix = _pix.resize(resize)
        _pos = qt.get_p(pos) if pos else QtCore.QPoint()

        # Set offset
        if anchor == 'C':
            _pos = _pos - qt.get_p([_pix.width() / 2, _pix.height() / 2])
        elif anchor == 'BL':
            _pos = _pos - qt.get_p([0, _pix.height()])
        elif anchor == 'BR':
            _pos = _pos - qt.get_p([_pix.width(), _pix.height()])
        elif anchor == 'TL':
            pass
        elif anchor == 'TR':
            _pos = _pos - qt.get_p([_pix.width(), 0])
        elif anchor == 'T':
            _pos = _pos - qt.get_p([_pix.width() / 2, 0])
        else:
            raise ValueError(anchor)

        _pnt = HPainter()
        _pnt.begin(self)
        _pnt.set_operation(operation)
        _pnt.drawPixmap(_pos.x(), _pos.y(), _pix)
        _pnt.end()

        return QtCore.QRect(_pos, _pix.size())
Пример #13
0
def multi_select(
        items, msg='Select items:', title="Select", multi=True,
        default=None, select='Select', width=None, pos=None,
        parent=None, labels=None):
    """Raise a dialog requesting selection from a list of items.

    Args:
        items (list): list of objects to display
        msg (str): message for dialog
        title (str): dialog title
        multi (bool): allow multiple selection (default is True)
        default (any): default value
        select (str): label for select button
        width (int): override dialog width
        pos (QPoint): position for dialog
        parent (QDialog): parent dialog
        labels (str list): list of display names for items
            (length must match item list length)
    """
    from psyhive import qt
    global _DIALOG

    if not items:
        raise RuntimeError('No items')
    get_application()

    # Raise dialog
    _DIALOG = _MultiSelectDialog(
        items=items, multi=multi, msg=msg, select=select, title=title,
        width=width, default=default, parent=parent, labels=labels)
    if pos:
        _pos = pos - qt.get_p(_DIALOG.size()/2)
        _DIALOG.move(_pos)
    _DIALOG.exec_()
    if _DIALOG and _DIALOG.result is None:
        raise qt.DialogCancelled

    return _DIALOG and _DIALOG.result
Пример #14
0
def _add_psyhive_btn(label, icon, cmd, tooltip, add_dots=True, verbose=0):
    """Add styled button to PsyHive shelf.

    Args:
        label (str): button label
        icon (str): button icon name
        cmd (fn): button command
        tooltip (str): button tooltip
        add_dots (bool): add speckled dots to button background
        verbose (int): print process data

    Returns:
        (str): button element
    """
    global _BUTTON_IDX

    # Set name/tmp_file
    lprint('ADDING', label, verbose=verbose)
    _name = 'PsyHive_' + label
    for _find, _replace in [('/', ''), (' ', ''), ('\n', '')]:
        _name = _name.replace(_find, _replace)
    _tmp_file = '{}/pixmaps/{}.png'.format(tempfile.gettempdir(), _name)
    _rand = str_to_seed(_name)
    lprint(' - NAME', _name, verbose=verbose)

    # Get colour
    _cols = ['RoyalBlue', 'CornflowerBlue', 'DodgerBlue']
    _col_name = _rand.choice(_cols)
    _col = qt.get_col(_col_name)
    lprint(' - COL NAME', _col_name, verbose=verbose)

    # Draw base
    _pix = qt.HPixmap(32, 32)
    _pix.fill('Transparent')
    _col = _col.whiten(0.3)
    _pix.add_rounded_rect(pos=(0, 0),
                          size=(32, 32),
                          col=_col,
                          outline=None,
                          bevel=4)
    _col = _col.whiten(0.3)
    _pix.add_rounded_rect(pos=(2, 2), size=(28, 28), col=_col, outline=None)
    if add_dots:
        for _ in range(8):
            if _rand.random() > 0.3:
                _pos = qt.get_p([int(33 * _rand.random()) for _ in range(2)])
                _rad = ValueRange('2-6').rand(random_=_rand)
                _alpha = ValueRange('80-100').rand(random_=_rand)
                _col = QtGui.QColor(255, 255, 255, _alpha)
                _pix.add_dot(pos=_pos, radius=_rad, col=_col)

    # Add icon
    if icon:
        _pix.add_overlay(icon, pos=qt.get_p(15, 2), resize=12, anchor='T')

    # Add text
    _lines = label.split('\n')
    for _jdx, _line in enumerate(_lines):
        _r_jdx = len(_lines) - _jdx - 1
        _pix.add_text(_line,
                      pos=qt.get_p(16, 31 - _r_jdx * 7),
                      font=_get_btn_font(),
                      anchor='B')

    _pix.save_as(_tmp_file, force=True)

    lprint(' - TMP FILE', _tmp_file, verbose=verbose)

    _btn = ui.add_shelf_button(_name,
                               image=_tmp_file,
                               command=cmd,
                               parent='PsyHive',
                               annotation=tooltip)
    lprint(verbose=verbose)

    _BUTTON_IDX += 1

    return _btn
Пример #15
0
    def add_text(self,
                 text,
                 pos=(0, 0),
                 anchor='TL',
                 col='white',
                 font=None,
                 size=None,
                 verbose=0):
        """Write text to the image.

        Args:
            text (str): text to add
            pos (tuple|QPoint): text position
            anchor (str): text anchor
            col (str|QColor): text colour
            font (QFont): text font
            size (int): apply font size
            verbose (int): print process data
        """
        from psyhive.qt import get_p, get_col
        lprint("Adding text", text, verbose=verbose)
        _window = self.window()
        _pos = get_p(pos)
        _x, _y = _pos.x(), _pos.y()
        _w, _h = _window.width(), _window.height()

        if anchor == 'BL':
            _rect = QtCore.QRect(_x, 0, _w - _x, _y)
            _align = Qt.AlignLeft | Qt.AlignBottom
        elif anchor == 'BR':
            _rect = QtCore.QRect(0, 0, _x, _y)
            _align = Qt.AlignRight | Qt.AlignBottom
        elif anchor == 'B':
            _rect = QtCore.QRect(0, 0, 2 * _x, _y)
            _align = Qt.AlignHCenter | Qt.AlignBottom
        elif anchor == 'C':
            _rect = QtCore.QRect(0, 0, 2 * _x, 2 * _y)
            _align = Qt.AlignHCenter | Qt.AlignVCenter
        elif anchor == 'L':
            _rect = QtCore.QRect(_x, 0, _w, 2 * _y)
            _align = Qt.AlignVCenter | Qt.AlignLeft
        elif anchor == 'R':
            _rect = QtCore.QRect(0, 0, _x, 2 * _y)
            _align = Qt.AlignRight | Qt.AlignVCenter
        elif anchor in ('T', 'TC'):
            _rect = QtCore.QRect(0, _y, 2 * _x, _h)
            _align = Qt.AlignHCenter | Qt.AlignTop
        elif anchor == 'TL':
            _rect = QtCore.QRect(_x, _y, _w, _h)
            _align = Qt.AlignLeft | Qt.AlignTop
        elif anchor == 'TR':
            _rect = QtCore.QRect(0, _y, _x, _h - _y)
            _align = Qt.AlignRight | Qt.AlignTop
        else:
            raise ValueError('Unhandled anchor: %s' % anchor)

        if font:
            self.setFont(font)
        elif size is not None:
            _font = QtGui.QFont()
            _font.setPointSize(size)
            self.setFont(_font)

        # Draw text
        self.setPen(get_col(col or 'white'))
        self.drawText(_rect, _align, text)