682 lines
24 KiB
Python
682 lines
24 KiB
Python
#!/usr/bin/env python3
|
|
# Qtvcp Joypad widget
|
|
#
|
|
# Copyright (c) 2021 Jim Sloot <persei802@gmail.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
|
|
# (at your option) 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.
|
|
###############################################################################
|
|
import sys
|
|
import enum
|
|
from qtpy import QtCore, QtGui, QtWidgets
|
|
from qtpy.QtCore import Qt, QPoint, QPointF, QRect, QRectF, QSize, QSizeF, QEvent
|
|
try:
|
|
from qtpy.QtCore import QEnum
|
|
except ImportError:
|
|
try:
|
|
from qtpy.QtCore import Q_ENUM as QEnum
|
|
except ImportError:
|
|
# before Qt 5.10
|
|
from qtpy.QtCore import Q_ENUMS as QEnum
|
|
from qtpy.QtGui import QPainter, QPainterPath, QPen, QBrush, QColor, QFont, QPixmap, QRadialGradient
|
|
|
|
import hal
|
|
from qtvcp.widgets.widget_baseclass import _HalWidgetBase
|
|
|
|
class IndicatorPosition(enum.IntEnum):
|
|
NONE = 0
|
|
LEFT = 1
|
|
RIGHT = 2
|
|
CENTER = 3
|
|
TOP = 4
|
|
BOTTOM = 5
|
|
LEFTRIGHT = 6
|
|
TOPBOTTOM = 7
|
|
|
|
class JoyPad(QtWidgets.QWidget):
|
|
IndicatorPosition = IndicatorPosition
|
|
QEnum(IndicatorPosition)
|
|
|
|
joy_btn_pressed = QtCore.Signal(str)
|
|
joy_btn_released = QtCore.Signal(str)
|
|
joy_l_pressed = QtCore.Signal(bool)
|
|
joy_l_released = QtCore.Signal(bool)
|
|
joy_r_pressed = QtCore.Signal(bool)
|
|
joy_r_released = QtCore.Signal(bool)
|
|
joy_c_pressed = QtCore.Signal(bool)
|
|
joy_c_released = QtCore.Signal(bool)
|
|
joy_t_pressed = QtCore.Signal(bool)
|
|
joy_t_released = QtCore.Signal(bool)
|
|
joy_b_pressed = QtCore.Signal(bool)
|
|
joy_b_released = QtCore.Signal(bool)
|
|
def __init__(self, parent=None):
|
|
super(JoyPad, self).__init__(parent)
|
|
self.rect1 = QRectF()
|
|
self.rect2 = QRectF()
|
|
self.left_image = None
|
|
self.right_image = None
|
|
self.top_image = None
|
|
self.bottom_image = None
|
|
self.center_image = None
|
|
self._dummyPixmap = QtGui.QPixmap()
|
|
self._font = QFont('Lato Heavy', 20)
|
|
self._text_color = QColor('white')
|
|
self._textL = ''
|
|
self._textR = ''
|
|
self._textC = ''
|
|
self._textT = ''
|
|
self._textB = ''
|
|
self.colorState = False
|
|
self._true_color = QColor('lawngreen')
|
|
self._false_color = QColor('gray')
|
|
self.highlight_color = self._false_color
|
|
self._highlightPosition = IndicatorPosition.NONE
|
|
self.highlight_left = False
|
|
self.highlight_right = False
|
|
self.highlight_top = False
|
|
self.highlight_bottom = False
|
|
self.highlight_center = False
|
|
self.last_active_btn = None
|
|
self.setMouseTracking(True)
|
|
self.setToolTipDuration(2000)
|
|
self.installEventFilter(self)
|
|
self.btn_names = {'L': 'left', 'R': 'right', 'T': 'top', 'B': 'bottom', 'C': 'center'}
|
|
self.tooltips = {'L': '', 'R': '', 'T': '', 'B': '', 'C': ''}
|
|
self.axis_list = ('X', 'Y', 'Z', 'A')
|
|
|
|
def eventFilter(self, obj, event):
|
|
if obj is self and self.isEnabled():
|
|
if event.type() == QEvent.MouseButtonPress:
|
|
if event.button() == Qt.RightButton:
|
|
event.ignore()
|
|
else:
|
|
pos = event.localPos()
|
|
active_btn = self.get_active_btn(pos)
|
|
self.last_active_btn = active_btn
|
|
if active_btn is not None:
|
|
self._pressedOutput(active_btn)
|
|
elif event.type() == QEvent.MouseButtonRelease:
|
|
if event.button() == Qt.RightButton:
|
|
event.ignore()
|
|
elif self.last_active_btn is not None:
|
|
self._releasedOutput(self.last_active_btn)
|
|
elif event.type() == QEvent.MouseMove:
|
|
pos = event.pos()
|
|
active_btn = self.get_active_btn(pos)
|
|
if active_btn is not None:
|
|
self.setToolTip(self.tooltips[active_btn])
|
|
return super(JoyPad, self).eventFilter(obj, event)
|
|
|
|
def _pressedOutput(self, btncode):
|
|
self.joy_btn_pressed.emit(btncode)
|
|
self['joy_{}_pressed'.format(btncode.lower())].emit(True)
|
|
|
|
def _releasedOutput(self, btncode):
|
|
self.joy_btn_released.emit(btncode)
|
|
self['joy_{}_released'.format(btncode.lower())].emit(False)
|
|
|
|
def get_active_btn(self, pos):
|
|
if self.center_path.contains(pos): return 'C'
|
|
elif self.left_path.contains(pos): return 'L'
|
|
elif self.right_path.contains(pos): return 'R'
|
|
elif self.bottom_path.contains(pos): return 'B'
|
|
elif self.top_path.contains(pos): return 'T'
|
|
return None
|
|
|
|
def paintEvent(self, event):
|
|
painter = QPainter(self)
|
|
painter.setRenderHint(painter.Antialiasing)
|
|
w = min(event.rect().width(), event.rect().height())
|
|
self.rect1.setSize(QSizeF(w * 0.4, w * 0.4))
|
|
self.rect2.setSize(QSizeF(w * 0.9, w * 0.9))
|
|
self.create_paths(painter, event)
|
|
self.draw_painter_paths(painter, event)
|
|
self.draw_icons(painter, event)
|
|
self.draw_highlight(painter, event)
|
|
painter.end()
|
|
|
|
def create_paths(self, qp, event):
|
|
self.left_path = QPainterPath()
|
|
self.right_path = QPainterPath()
|
|
self.bottom_path = QPainterPath()
|
|
self.top_path = QPainterPath()
|
|
self.center_path = QPainterPath()
|
|
center = event.rect().center()
|
|
self.rect1.moveCenter(center)
|
|
self.rect2.moveCenter(center)
|
|
left_start = QPointF(self.rect1.topLeft())
|
|
right_start = QPointF(self.rect1.bottomRight())
|
|
bottom_start = QPointF(self.rect1.bottomLeft())
|
|
top_start = QPointF(self.rect1.topRight())
|
|
path = (self.right_path, self.top_path, self.left_path, self.bottom_path)
|
|
start = (right_start, top_start, left_start, bottom_start)
|
|
angle = -45
|
|
for i in range(4):
|
|
path[i].moveTo(start[i])
|
|
path[i].arcTo(self.rect1, angle, 90)
|
|
path[i].arcTo(self.rect2, angle + 90, -90)
|
|
path[i].closeSubpath()
|
|
angle += 90
|
|
cap = QRectF()
|
|
cap.setSize(QSizeF(self.rect1.width()*0.8, self.rect1.height()*0.8))
|
|
cap.moveCenter(center)
|
|
self.center_path.addEllipse(cap)
|
|
|
|
def draw_painter_paths(self, qp, event):
|
|
w = min(event.rect().width(), event.rect().height())
|
|
center = event.rect().center()
|
|
fp = QPoint(int(center.x() - w/4), int(center.y() - w/4))
|
|
bg = QRadialGradient(center, w/2, fp)
|
|
bg.setColorAt(0, QColor(180, 180, 180))
|
|
bg.setColorAt(1, QColor(40, 40, 40))
|
|
qp.setBrush(QBrush(bg))
|
|
qp.setPen(QPen(QColor(Qt.black), 4))
|
|
qp.drawPath(self.left_path)
|
|
qp.drawPath(self.right_path)
|
|
qp.drawPath(self.top_path)
|
|
qp.drawPath(self.bottom_path)
|
|
qp.drawPath(self.center_path)
|
|
|
|
def draw_icons(self, qp, event):
|
|
rect = QRect()
|
|
rect.setSize(QSize(int(self.rect1.width() * 0.4), int(self.rect1.height() * 0.4)))
|
|
center = event.rect().center()
|
|
qp.setPen(QPen(self._text_color, 2))
|
|
qp.setFont(self._font)
|
|
# left button
|
|
rect.moveCenter(QPoint(int(center.x() - self.rect2.width()/3), center.y()))
|
|
if isinstance(self.left_image, QPixmap):
|
|
pix = self.left_image
|
|
qp.drawPixmap(rect, pix, pix.rect())
|
|
elif isinstance(self.left_image, str):
|
|
qp.drawText(rect, Qt.AlignCenter, self.left_image)
|
|
# right button
|
|
rect.moveCenter(QPoint(int(center.x() + self.rect2.width()/3), center.y()))
|
|
if isinstance(self.right_image, QPixmap):
|
|
pix = self.right_image
|
|
qp.drawPixmap(rect, pix, pix.rect())
|
|
elif isinstance(self.right_image, str):
|
|
qp.drawText(rect, Qt.AlignCenter, self.right_image)
|
|
# bottom button
|
|
rect.moveCenter(QPoint(center.x(), int(center.y() + self.rect2.width()/3)))
|
|
if isinstance(self.bottom_image, QPixmap):
|
|
pix = self.bottom_image
|
|
qp.drawPixmap(rect, pix, pix.rect())
|
|
elif isinstance(self.bottom_image, str):
|
|
qp.drawText(rect, Qt.AlignCenter, self.bottom_image)
|
|
# top button
|
|
rect.moveCenter(QPoint(center.x(), int(center.y() - self.rect2.width()/3)))
|
|
if isinstance(self.top_image, QPixmap):
|
|
pix = self.top_image
|
|
qp.drawPixmap(rect, pix, pix.rect())
|
|
elif isinstance(self.top_image, str):
|
|
qp.drawText(rect, Qt.AlignCenter, self.top_image)
|
|
# center button
|
|
rect.moveCenter(QPoint(center.x(), center.y()))
|
|
if isinstance(self.center_image, QPixmap):
|
|
pix = self.center_image
|
|
qp.drawPixmap(rect, pix, pix.rect())
|
|
elif isinstance(self.center_image, str):
|
|
qp.drawText(rect, Qt.AlignCenter, self.center_image)
|
|
|
|
def draw_highlight(self, qp, event):
|
|
rect = QRectF()
|
|
rect.setSize(self.rect1.size() * 0.9)
|
|
center = event.rect().center()
|
|
rect.moveCenter(center)
|
|
pen_width = self.rect1.width() * 0.08
|
|
qp.setPen(QPen(self.highlight_color, pen_width, cap = Qt.FlatCap))
|
|
if self.highlight_center is True:
|
|
qp.drawArc(rect, 0, 5760)
|
|
else:
|
|
if self.highlight_right is True:
|
|
qp.drawArc(rect, -45 * 16, 90 * 16)
|
|
if self.highlight_left is True:
|
|
qp.drawArc(rect, 135 * 16, 90 * 16)
|
|
if self.highlight_top is True:
|
|
qp.drawArc(rect, 45 * 16, 90 * 16)
|
|
if self.highlight_bottom is True:
|
|
qp.drawArc(rect, 225 * 16, 90 * 16)
|
|
|
|
def reset_highlight(self):
|
|
self.highlight_left = False
|
|
self.highlight_right = False
|
|
self.highlight_top = False
|
|
self.highlight_bottom = False
|
|
self.highlight_center = False
|
|
|
|
def set_highlight(self, btn, state=True):
|
|
if type(btn) == int:
|
|
if btn == IndicatorPosition.LEFT:
|
|
btn ='L'
|
|
elif btn == IndicatorPosition.RIGHT:
|
|
btn ='R'
|
|
elif btn == IndicatorPosition.CENTER:
|
|
btn ='C'
|
|
elif btn == IndicatorPosition.TOP:
|
|
btn ='T'
|
|
elif btn == IndicatorPosition.BOTTOM:
|
|
btn ='B'
|
|
elif btn == IndicatorPosition.LEFTRIGHT:
|
|
btn ='X'
|
|
elif btn == IndicatorPosition.TOPBOTTOM:
|
|
btn ='Z'
|
|
elif btn == IndicatorPosition.NONE:
|
|
self.reset_highlight()
|
|
return
|
|
else:
|
|
print ('undefined position:{}'.format(btn))
|
|
return
|
|
if btn not in self.axis_list and btn not in self.btn_names.keys(): return
|
|
if btn == 'X' or btn == 'A':
|
|
self.highlight_left = state
|
|
self.highlight_right = state
|
|
elif btn == 'Y' or btn == 'Z':
|
|
self.highlight_top = state
|
|
self.highlight_bottom = state
|
|
else:
|
|
name = self.btn_names[btn]
|
|
self['highlight_' + name] = state
|
|
self.update()
|
|
|
|
def set_button_icon(self, btn, path):
|
|
self.set_icon(btn, 'image', path)
|
|
def set_button_text(self, btn, text):
|
|
self.set_icon(btn, 'text', text)
|
|
|
|
def set_icon(self, btn, kind, data):
|
|
if btn not in self.btn_names.keys(): return
|
|
name = self.btn_names[btn]
|
|
if kind == 'image':
|
|
if data is None:
|
|
self[name + "_image"] = None
|
|
else:
|
|
self[name + "_image"] = QPixmap(data)
|
|
elif kind == 'text':
|
|
self[name + "_image"] = data
|
|
else: return
|
|
self.update()
|
|
|
|
def set_tooltip(self, btn, tip):
|
|
if btn in self.btn_names.keys():
|
|
self.tooltips[btn] = tip
|
|
|
|
def setLight(self, data):
|
|
if data:
|
|
self.highlight_color = self._true_color
|
|
else:
|
|
self.highlight_color = self._false_color
|
|
self.update()
|
|
|
|
def set_HighlightPosition(self, position):
|
|
self._highlightPosition = position
|
|
self.reset_highlight()
|
|
self.set_highlight(position, True)
|
|
self.update()
|
|
|
|
def get_HighlightPosition(self):
|
|
return self._highlightPosition
|
|
|
|
def reset_HighlightPosition(self):
|
|
self._highlightPosition = IndicatorPosition.NONE
|
|
self.reset_highlight()
|
|
self.update()
|
|
|
|
highlightPosition = QtCore.Property(IndicatorPosition,
|
|
get_HighlightPosition, set_HighlightPosition, reset_HighlightPosition)
|
|
|
|
@QtCore.Slot()
|
|
def set_colorStateTrue(self):
|
|
self.setLight(True)
|
|
@QtCore.Slot()
|
|
def set_colorStateFalse(self):
|
|
self.setLight(False)
|
|
|
|
@QtCore.Slot(bool)
|
|
def set_colorState(self, state):
|
|
self.colorState = bool(state)
|
|
self.setLight(state)
|
|
|
|
def get_colorState(self):
|
|
return self.colorState
|
|
|
|
def reset_colorState(self):
|
|
self.colorState = False
|
|
self.setLight(False)
|
|
|
|
setColorState = QtCore.Property(bool, get_colorState, set_colorState, reset_colorState)
|
|
|
|
def setLeftImagePath(self, data):
|
|
if data.isNull():
|
|
data = None
|
|
self.set_icon('L', 'image', data)
|
|
def getLeftImagePath(self):
|
|
if isinstance(self.left_image, QPixmap):
|
|
self.left_image
|
|
else:
|
|
return self._dummyPixmap
|
|
def resetLeftImagePath(self):
|
|
pass
|
|
|
|
def setRightImagePath(self, data):
|
|
if data.isNull():
|
|
data = None
|
|
self.set_icon('R', 'image', data)
|
|
def getRightImagePath(self):
|
|
return self._dummyPixmap
|
|
def resetRightImagePath(self):
|
|
pass
|
|
|
|
def setCenterImagePath(self, data):
|
|
if data.isNull():
|
|
data = None
|
|
self.set_icon('C', 'image', data)
|
|
def getCenterImagePath(self):
|
|
return self._dummyPixmap
|
|
def resetCenterImagePath(self):
|
|
pass
|
|
|
|
def setTopImagePath(self, data):
|
|
if data.isNull():
|
|
data = None
|
|
self.set_icon('T', 'image', data)
|
|
def getTopImagePath(self):
|
|
return self._dummyPixmap
|
|
def resetTopImagePath(self):
|
|
pass
|
|
|
|
def setBottomImagePath(self, data):
|
|
if data.isNull():
|
|
data = None
|
|
self.set_icon('B', 'image', data)
|
|
def getBottomImagePath(self):
|
|
return self._dummyPixmap
|
|
def resetBottomImagePath(self):
|
|
pass
|
|
|
|
left_image_path = QtCore.Property(QPixmap, getLeftImagePath, setLeftImagePath, resetLeftImagePath)
|
|
right_image_path = QtCore.Property(QPixmap, getRightImagePath, setRightImagePath, resetRightImagePath)
|
|
center_image_path = QtCore.Property(QPixmap, getCenterImagePath, setCenterImagePath, resetCenterImagePath)
|
|
top_image_path = QtCore.Property(QPixmap, getTopImagePath, setTopImagePath, resetTopImagePath)
|
|
bottom_image_path = QtCore.Property(QPixmap, getBottomImagePath, setBottomImagePath, resetBottomImagePath)
|
|
|
|
|
|
def getFont(self):
|
|
return self._font
|
|
def setFont(self, value):
|
|
self._font = value
|
|
def resetFont(self):
|
|
self._font = QFont('Lato Heavy', 20)
|
|
button_font = QtCore.Property(QFont, getFont, setFont, resetFont)
|
|
|
|
def setLeftText(self, data):
|
|
self._textL = data
|
|
if not data.strip():
|
|
data = None
|
|
self.set_icon('L', 'text', data)
|
|
def getLeftText(self):
|
|
return self._textL
|
|
def resetLeftText(self):
|
|
self._textL = ''
|
|
self.set_icon('L', 'text', '')
|
|
|
|
def setRightText(self, data):
|
|
self._textR = data
|
|
if not data.strip():
|
|
data = None
|
|
self.set_icon('R', 'text', data)
|
|
def getRightText(self):
|
|
return self._textR
|
|
def resetRightText(self):
|
|
self._textR = ''
|
|
self.set_icon('R', 'text', '')
|
|
|
|
def setCenterText(self, data):
|
|
self._textC = data
|
|
if not data.strip():
|
|
data = None
|
|
self.set_icon('C', 'text', data)
|
|
def getCenterText(self):
|
|
return self._textC
|
|
def resetCenterText(self):
|
|
self._textC = ''
|
|
self.set_icon('C', 'text', '')
|
|
|
|
def setTopText(self, data):
|
|
self._textT = data
|
|
if not data.strip():
|
|
data = None
|
|
self.set_icon('T', 'text', data)
|
|
def getTopText(self):
|
|
return self._textT
|
|
def resetTopText(self):
|
|
self._textT = ''
|
|
self.set_icon('T', 'text', '')
|
|
|
|
def setBottomText(self, data):
|
|
self._textB = data
|
|
if not data.strip():
|
|
data = None
|
|
self.set_icon('B', 'text', data)
|
|
def getBottomText(self):
|
|
return self._textB
|
|
def resetBottomText(self):
|
|
self._textB = ''
|
|
self.set_icon('B', 'text', '')
|
|
|
|
left_text = QtCore.Property(str, getLeftText, setLeftText, resetLeftText)
|
|
right_text = QtCore.Property(str, getRightText, setRightText, resetRightText)
|
|
center_text = QtCore.Property(str, getCenterText, setCenterText, resetCenterText)
|
|
top_text = QtCore.Property(str, getTopText, setTopText, resetTopText)
|
|
bottom_text = QtCore.Property(str, getBottomText, setBottomText, resetBottomText)
|
|
|
|
@QtCore.Slot(QColor)
|
|
def set_true_color(self, color):
|
|
self._true_color = color
|
|
self.setLight(self.colorState)
|
|
@QtCore.Slot(str)
|
|
def set_true_color(self, color):
|
|
self._true_color = QColor(color)
|
|
self.setLight(self.colorState)
|
|
|
|
def get_true_color(self):
|
|
return self._true_color
|
|
|
|
def reset_true_color(self):
|
|
self._true_color = QColor('lawngreen')
|
|
self.setLight(self.colorState)
|
|
|
|
@QtCore.Slot(QColor)
|
|
def set_false_color(self, color):
|
|
self._false_color = color
|
|
self.setLight(self.colorState)
|
|
@QtCore.Slot(str)
|
|
def set_false_color(self, color):
|
|
self._false_color = QColor(color)
|
|
self.setLight(self.colorState)
|
|
|
|
def get_false_color(self):
|
|
return self._false_color
|
|
|
|
def reset_false_color(self):
|
|
self._false_color = QColor('gray')
|
|
self.setLight(self.colorState)
|
|
|
|
def set_text_color(self, color):
|
|
self._text_color = QColor(color)
|
|
self.update()
|
|
def get_text_color(self):
|
|
return self._text_color
|
|
def reset_text_color(self):
|
|
self._text_color = QColor('white')
|
|
self.update()
|
|
|
|
true_color = QtCore.Property(QColor, get_true_color, set_true_color, reset_true_color)
|
|
false_color = QtCore.Property(QColor, get_false_color, set_false_color, reset_false_color)
|
|
text_color = QtCore.Property(QColor, get_text_color, set_text_color, reset_text_color)
|
|
|
|
@QtCore.Slot(str)
|
|
def btn_pressed(self, btn):
|
|
print("Button pressed", btn)
|
|
|
|
@QtCore.Slot(str)
|
|
def btn_released(self, btn):
|
|
print("Button released", btn)
|
|
|
|
# required code for object indexing
|
|
def __getitem__(self, item):
|
|
return getattr(self, item)
|
|
|
|
def __setitem__(self, item, value):
|
|
return setattr(self, item, value)
|
|
|
|
class HALPinType(enum.IntEnum):
|
|
NONE = 0
|
|
BIT = hal.HAL_BIT
|
|
S32 = hal.HAL_S32
|
|
FLOAT = hal.HAL_FLOAT
|
|
|
|
class HALPad(JoyPad, _HalWidgetBase):
|
|
HALPinType = HALPinType
|
|
QEnum(HALPinType)
|
|
|
|
# older version of pyqt5 need this as well as QEnum
|
|
NONE = 0
|
|
BIT = hal.HAL_BIT
|
|
S32 = hal.HAL_S32
|
|
FLOAT = hal.HAL_FLOAT
|
|
|
|
def __init__(self, parent=None):
|
|
super(HALPad, self).__init__(parent)
|
|
self._pin_name = ''
|
|
self._pin_type = HALPinType.BIT
|
|
|
|
self._trueOutputR = 1.0
|
|
self._trueOutputL = 1.0
|
|
self._trueOutputC = 1.0
|
|
self._trueOutputT = 1.0
|
|
self._trueOutputB = 1.0
|
|
self._falseOutput = 0.0
|
|
|
|
self._true_color = QColor('lawngreen')
|
|
self._false_color = QColor('red')
|
|
|
|
# we want center active for an indicator light
|
|
self.setProperty('highlightPosition',IndicatorPosition.CENTER)
|
|
self.setLight(False)
|
|
|
|
def _hal_init(self):
|
|
if self._pin_name == '':
|
|
pname = self.HAL_NAME_
|
|
else:
|
|
pname = self._pin_name
|
|
if not self._pin_type == HALPinType.NONE:
|
|
ptype = self._pin_type
|
|
self.halPinR = self.HAL_GCOMP_.newpin(pname + '.right', ptype, hal.HAL_OUT)
|
|
self.halPinL = self.HAL_GCOMP_.newpin(pname + '.left', ptype, hal.HAL_OUT)
|
|
self.halPinT = self.HAL_GCOMP_.newpin(pname + '.top', ptype, hal.HAL_OUT)
|
|
self.halPinB = self.HAL_GCOMP_.newpin(pname + '.bottom', ptype, hal.HAL_OUT)
|
|
self.halPinC = self.HAL_GCOMP_.newpin(pname + '.center', ptype, hal.HAL_OUT)
|
|
if not self._highlightPosition == IndicatorPosition.NONE:
|
|
self.halPinLightCenter = self.HAL_GCOMP_.newpin(pname + '.light.center', hal.HAL_BIT, hal.HAL_IN)
|
|
self.halPinLightCenter.value_changed.connect(lambda data: self.setLight(data))
|
|
|
|
def _pressedOutput(self, btncode):
|
|
self.joy_btn_pressed.emit(btncode)
|
|
self['joy_{}_pressed'.format(btncode.lower())].emit(True)
|
|
|
|
if self._pin_type == HALPinType.BIT:
|
|
data = True
|
|
elif self._pin_type == HALPinType.FLOAT:
|
|
data = float(self['_trueOutput{}'.format(btncode)])
|
|
elif self._pin_type == HALPinType.S32:
|
|
data = int(self['_trueOutput{}'.format(btncode)])
|
|
else:
|
|
return
|
|
try:
|
|
self['halPin{}'.format(btncode)].set(data)
|
|
except:
|
|
pass
|
|
|
|
def _releasedOutput(self, btncode):
|
|
self.joy_btn_released.emit(btncode)
|
|
self['joy_{}_released'.format(btncode.lower())].emit(False)
|
|
|
|
if self._pin_type == HALPinType.BIT:
|
|
data = False
|
|
elif self._pin_type == HALPinType.FLOAT:
|
|
data = float(self._falseOutput)
|
|
elif self._pin_type == HALPinType.S32:
|
|
data = int(self._falseOutput)
|
|
else:
|
|
return
|
|
try:
|
|
self['halPin{}'.format(btncode)].set(data)
|
|
except:
|
|
pass
|
|
|
|
def setPinTrueOutput(self, btn, data):
|
|
btncode = self.btn_names[btn.lower()]
|
|
self['_trueOutput{}'.format(btncode)] = data
|
|
|
|
#########################################################################
|
|
# This is how designer can interact with our widget properties.
|
|
# designer will show the Property properties in the editor
|
|
# it will use the get set and reset calls to do those actions
|
|
########################################################################
|
|
|
|
def set_pin_name(self, value):
|
|
self._pin_name = value
|
|
def get_pin_name(self):
|
|
return self._pin_name
|
|
def reset_pin_name(self):
|
|
self._pin_name = ''
|
|
|
|
def set_pin_type(self, value):
|
|
self._pin_type = value
|
|
print(value)
|
|
def get_pin_type(self):
|
|
return self._pin_type
|
|
def reset_pin_type(self):
|
|
self._pin_type = HALPinType.BIT
|
|
|
|
# designer will show these properties in this order:
|
|
pin_type = QtCore.Property(HALPinType, get_pin_type, set_pin_type, reset_pin_type)
|
|
pin_name = QtCore.Property(str, get_pin_name, set_pin_name, reset_pin_name)
|
|
|
|
#############################
|
|
# Testing #
|
|
#############################
|
|
if __name__ == "__main__":
|
|
import sys
|
|
from qtpy.QtWidgets import QWidget
|
|
app = QtWidgets.QApplication(sys.argv)
|
|
w = QWidget()
|
|
w.setGeometry(100, 100, 600, 400)
|
|
w.setWindowTitle('JoyPad')
|
|
joy = JoyPad()
|
|
joy.set_icon('L', 'text', 'X-')
|
|
joy.set_icon('R', 'text', 'X+')
|
|
joy.set_icon('T', 'text', 'Y+')
|
|
joy.set_icon('B', 'text', 'Y-')
|
|
joy.set_icon('C', 'image', 'stop.png')
|
|
joy.set_tooltip('T', 'This is the top button')
|
|
joy.set_tooltip('C', 'This is the center button')
|
|
joy.set_false_color('red')
|
|
joy.set_highlight('T', True)
|
|
joy.joy_btn_pressed.connect(joy.btn_pressed)
|
|
joy.joy_btn_released.connect(joy.btn_released)
|
|
layout = QtWidgets.QVBoxLayout()
|
|
layout.addWidget(joy)
|
|
w.setLayout(layout)
|
|
w.show()
|
|
sys.exit( app.exec() )
|
|
|