def drawNodes(self, target = None):
     '''draws the graph nodes and prints its coords'''
     if target:
         painter = QPainter(target)
     else:
         painter = QPainter(self.graph_image)
     node_width = 10
     painter.setPen(Qt.NoPen)
     for node in self.graph.nextNode():
         if node in self.graph.highlighted_node:
             if node.data is not None:
                 node_color = self.colorPicker(node)
                 painter.setBrush(QBrush(node_color, Qt.SolidPattern))
         else:
             painter.setBrush(QBrush(Qt.black, Qt.SolidPattern))
         painter.drawEllipse(node.x() - node_width//2,
                             node.y() - node_width//2,
                             node_width,
                             node_width)
         nodeNo = ""
         if node.data is not None and 'number' in node.data.keys():
             nodeNo = str(node.data['number']) + " "
         node_text = QStaticText(nodeNo + str(node))
         painter.setPen(QPen(Qt.black, 1))
         painter.drawStaticText(node.x() - 5, node.y() + 5, node_text)
     painter.end()
    def paintEvent(self, event):
        p = QPainter(self)

        if self.scrollEnabled:
            self.buffer.fill(qRgba(0, 0, 0, 0))
            pb = QPainter(self.buffer)
            pb.setPen(p.pen())
            pb.setFont(p.font())

            x = min(-self.scrollPos, 0) + self.leftMargin
            while x < self.width():
                pb.drawStaticText(
                    QPointF(x,
                            (self.height() - self.wholeTextSize.height()) / 2)
                    + QPoint(2, 2), self.staticText)
                x += self.wholeTextSize.width()

            #Apply Alpha Channel
            pb.setCompositionMode(QPainter.CompositionMode_DestinationIn)
            pb.setClipRect(self.width() - 15, 0, 15, self.height())
            pb.drawImage(0, 0, self.alphaChannel)
            pb.setClipRect(0, 0, 15, self.height())
            #initial situation: don't apply alpha channel in the left half of the image at all; apply it more and more until scrollPos gets positive
            if self.scrollPos < 0:
                pb.setOpacity((max(-8, self.scrollPos) + 8) / 8.0)
            pb.drawImage(0, 0, self.alphaChannel)

            p.drawImage(0, 0, self.buffer)
        else:
            x = (self.width() - self.wholeTextSize.width()) / 2
            y = (self.height() - self.wholeTextSize.height()) / 2
            p.drawStaticText(QPointF(x, y), self.staticText)
Exemple #3
0
 def paintTitle(self, painter: QPainter):
     text = QStaticText(self.title())
     text.setTextWidth(20)
     half_size = QPointF(
         text.size().width() / 2,
         text.size().height() / 2
     )
     painter.drawStaticText(self.pos() - half_size, text)
Exemple #4
0
 def paintEvent(self, event):
     canvas = QPainter(self)
     if Game.state == Game.GameState.PLAY or Game.state == Game.GameState.GAMEOVER:
         canvas.drawImage(self.rect(), self.image, self.image.rect())
     elif Game.state == Game.GameState.PAUSED:
         message = '<b style="font-size:40px;">PAUSED<br> Press P to play or Esc to exit<\b>'
         message = QtGui.QStaticText(message)
         message.setTextFormat(Qt.RichText)
         canvas.drawStaticText(Game.stateMessageBoxX, Game.stateMessageBoxY,
                               message)
Exemple #5
0
class Drawing(QWidget):
    def __init__(self, object):
        super().__init__()

        self.pannel = QWidget(self)
        self.layout = QGridLayout()
        self.qp = QPainter()
        self.sizeScreen = self.__getSize()
        self.coordinatePlane = None

        self.drawableObject = object

        self.initUI()

    def initUI(self):
        self.pannel.setGeometry(
            QRect(0, 0, self.sizeScreen[0], self.sizeScreen[1]))
        self.setGeometry(QRect(0, 0, self.sizeScreen[0], self.sizeScreen[1]))

        self.drawAxes()

        self.pannel.setLayout(self.layout)
        self.setWindowTitle('Lab 3')
        self.show()

    def drawAxes(self):
        self.qp.drawLine(0, 1, self.sizeScreen[0], 1)
        self.qp.drawLine(1, 0, 1, self.sizeScreen[1])

        for i in range(100, self.sizeScreen[0], 100):
            self.qp.drawLine(i, 0, i, 7)
            self.qp.drawStaticText(i - 10, 7, QStaticText(str(i)))

        for i in range(100, self.sizeScreen[1], 100):
            self.qp.drawLine(0, i, 10, i)
            self.qp.drawStaticText(10, i - 10, QStaticText(str(i)))

    def paintEvent(self, QPaintEvent):
        self.drawPlane()

    def drawPlane(self):
        self.coordinatePlane = CoordinatePlane(self.size())
        self.qp.begin(self)
        self.qp.setPen(Qt.black)
        self.drawAxes()
        self.drawableObject.draw(self.sizeScreen, self.qp)

        self.qp.end()

    def __getSize(self):
        h = QDesktopWidget().screenGeometry().height() - 100
        w = QDesktopWidget().screenGeometry().width() - 100
        return [w, h]
Exemple #6
0
    def paintEvent(self, e):
        p = QPainter(self)
        opt = QStyleOptionSlider()
        self.initStyleOption(opt)
        p.translate(opt.rect.x(), opt.rect.y())
        p.setPen(opt.palette.windowText().color())
        # tickOffset = sty.pixelMetric(QStyle.PM_SliderTickmarkOffset, opt, self.slider)
        available = self.style().pixelMetric(QStyle.PM_SliderSpaceAvailable, opt, self)
        slen = self.style().pixelMetric(QStyle.PM_SliderLength, opt, self)
        fudge = slen / 2
        for i in range(len(self.labels)):
            v = opt.minimum + i
            pos = self.style().sliderPositionFromValue(opt.minimum, opt.maximum, v, available) + fudge
            # p.drawLine(pos, 0, pos, tickOffset - 2)
            br = p.fontMetrics().boundingRect(self.labels[i])
            pos = min(max(pos, br.width()/2), available+fudge-br.width()/2)
            p.drawStaticText(pos - br.width()/2, 0, QStaticText(self.labels[i]))

        super().paintEvent(e)
Exemple #7
0
class Mainframe(QWidget):
    def __init__(self):
        super().__init__()
        self.layout = QGridLayout()
        self.pannel = QWidget(self)
        self.qp = QPainter()
        self.coordinatePlane = CoordinatePlane(
            QDesktopWidget().availableGeometry())

        self.sizeScreen = QDesktopWidget().availableGeometry()
        self.__setDefaultPosition()

        self.figures = []
        self.figures = self.__figures()

        self.label_move_dx = QLabel("dx")
        self.label_move_dy = QLabel("dy")
        self.label_resize_xc = QLabel("xc")
        self.label_resize_yc = QLabel("yc")
        self.label_resize_kx = QLabel("kx")
        self.label_resize_ky = QLabel("ky")
        self.label_rotate_xc = QLabel("xc")
        self.label_rotate_yc = QLabel("yc")
        self.label_rotate_angle = QLabel("angle")
        self.label_move = QLabel("Movement")
        self.label_resize = QLabel("Resize")
        self.label_rotate = QLabel("Rotation")

        self.button_move = QPushButton("Move")
        self.button_resize = QPushButton("Resize")
        self.button_rotate = QPushButton("Rotate")
        self.button_reset = QPushButton("Reset")
        self.button_back = QPushButton("Back")

        self.button_move.clicked.connect(self.buttonMoveEvent)
        self.button_resize.clicked.connect(self.buttonResizeEvent)
        self.button_rotate.clicked.connect(self.buttonRotateEvent)
        self.button_back.clicked.connect(self.buttonBackEvent)
        self.button_reset.clicked.connect(self.buttonResetEvent)

        self.edit_move_dx = QDoubleSpinBox()
        self.edit_move_dy = QDoubleSpinBox()
        self.edit_resize_xc = QDoubleSpinBox()
        self.edit_resize_yc = QDoubleSpinBox()
        self.edit_resize_kx = QDoubleSpinBox()
        self.edit_resize_ky = QDoubleSpinBox()
        self.edit_rotate_xc = QDoubleSpinBox()
        self.edit_rotate_yc = QDoubleSpinBox()
        self.edit_angle = QSpinBox()

        self.edit_move_dx.setMaximum(self.sizeScreen.width() / 2)
        self.edit_move_dx.setMinimum(-1 * self.sizeScreen.width() / 2)

        self.edit_move_dy.setMaximum(self.sizeScreen.height() / 2)
        self.edit_move_dy.setMinimum(-1 * self.sizeScreen.height() / 2)

        self.edit_resize_xc.setMinimum(-1 * self.sizeScreen.width() / 2)
        self.edit_resize_xc.setMaximum(self.sizeScreen.width() / 2)

        self.edit_resize_yc.setMinimum(-1 * self.sizeScreen.height() / 2)
        self.edit_resize_yc.setMaximum(self.sizeScreen.height() / 2)

        self.edit_rotate_xc.setMaximum(self.sizeScreen.width())
        self.edit_rotate_xc.setMinimum(0)

        self.edit_rotate_yc.setMaximum(self.sizeScreen.height())
        self.edit_rotate_yc.setMinimum(0)

        self.edit_angle.setMinimum(-360)
        self.edit_angle.setMaximum(360)

        self.initUI()

    def __setDefaultPosition(self):
        self.angle = 0
        self.rotation_center_x = 0
        self.rotation_center_y = 0
        self.radX = 40
        self.radY = 40
        self.astroid_heigth = 200
        self.astroid_width = 200
        self.rect_heigth = 400
        self.rect_width = 400
        self.sstate = QPoint(self.sizeScreen.width() / 2,
                             self.sizeScreen.height() / 2)
        self.state = QPoint(self.sizeScreen.width() / 2,
                            self.sizeScreen.height() / 2)

        self.__clearSavedState()

    def __clearSavedState(self):
        self.curRadX = None
        self.curRadY = None
        self.curAstrHeight = None
        self.curAstrWidth = None
        self.curRectH = None
        self.curRectWidth = None
        self.cur_action = None
        self.cur_angle = None
        self.cur_rotation_center_x = None
        self.cur_rotation_center_y = None
        self.cur_radX = None
        self.cur_radY = None
        self.cur_astroid_heigth = None
        self.cur_astroid_width = None
        self.cur_rect_heigth = None
        self.cur_rect_width = None
        self.cur_state = None

    def __setPreviousPosition(self):
        if (self.cur_action == None):
            self.__setDefaultPosition()
            return
        else:
            if self.cur_action == Action.MOVE:
                for i in self.figures:
                    i.move(-self.cur_dx, -self.cur_dy)
                self.repaint()
            elif self.cur_action == Action.ROTATE:
                for i in self.figures:
                    i.rotate(self.cur_rotation_center_x,
                             self.cur_rotation_center_y, -self.cur_angle)
                self.repaint()
            elif self.cur_action == Action.SCALE:
                # if (self.cur_kx != 0 and self.cur_ky != 0):
                # for i in self.figures:
                self.figures[0].scale1(self.curRadX, self.curRadY,
                                       self.state.x(), self.state.y(),
                                       self.cur_kx, self.cur_ky)
                self.figures[1].scale1(self.curRectH, self.curRectWidth,
                                       self.state.x(), self.state.y(),
                                       self.cur_kx, self.cur_ky)
                self.figures[2].scale1(self.curAstrHeight, self.curAstrWidth,
                                       self.state.x(), self.state.y(),
                                       self.cur_kx, self.cur_ky)
                # i.scale(1 / self.cur_kx, 1 / self.cur_ky, self.cur_scale_xc, self.cur_scale_yc)
                self.repaint()
                # else:
                #     self.__showErrorMessage("Невозможно выполнить действие!")
        self.__clearSavedState()

    def __showErrorMessage(self, message):
        error_message = QErrorMessage(self)
        error_message.setWindowTitle("Error")
        error_message.showMessage(message)

    def buttonResetEvent(self):
        self.figures = self.__figures()
        self.__clearSavedState()
        self.__setDefaultPosition()
        self.repaint()

    def buttonBackEvent(self):
        if self.cur_action != None:
            self.__setPreviousPosition()
            self.repaint()

    def buttonResizeEvent(self):
        self.kx = self.edit_resize_kx.value()
        self.ky = self.edit_resize_ky.value()
        if self.kx == 1 and self.ky == 1:
            return
        self.scale_xc = self.edit_resize_xc.value()
        self.scale_yc = self.edit_resize_yc.value()
        self.cur_action = Action.SCALE
        self.__saveScale()
        for i in self.figures:
            i.scale(self.kx, self.ky, self.scale_xc, self.scale_yc)
        self.repaint()

    def buttonRotateEvent(self):
        self.angle = self.edit_angle.value()
        if self.angle == 0:
            return
        self.rotation_center_x = self.edit_rotate_xc.value()
        self.rotation_center_y = self.edit_rotate_yc.value()
        self.cur_action = Action.ROTATE
        self.__saveRotation()
        for i in self.figures:
            i.rotate(self.rotation_center_x, self.rotation_center_y,
                     self.angle)
        self.repaint()

    def buttonMoveEvent(self):
        self.new_offset_x = self.edit_move_dx.value()
        self.new_offset_y = self.edit_move_dy.value()
        if self.new_offset_x == 0 and self.new_offset_y == 0:
            return
        self.__saveMovement()
        self.cur_action = Action.MOVE
        for i in self.figures:
            i.move(self.new_offset_x, self.new_offset_y)
        self.repaint()

    def initUI(self):
        self.pannel.setGeometry(
            QRect(self.sizeScreen.width() - 200, 40, 200,
                  self.sizeScreen.height() / 2))
        self.setGeometry(0, 0, self.sizeScreen.width(),
                         self.sizeScreen.height())

        self.__addWidgets()

        self.pannel.setLayout(self.layout)
        self.setWindowTitle('Lab 2')
        self.show()

    def __addWidgets(self):
        self.layout.addWidget(self.label_move, 0, 0)
        self.layout.addWidget(self.edit_move_dx, 1, 0)
        self.layout.addWidget(self.label_move_dx, 1, 1)
        self.layout.addWidget(self.edit_move_dy, 2, 0)
        self.layout.addWidget(self.label_move_dy, 2, 1)
        self.layout.addWidget(self.button_move, 3, 0)

        self.layout.addWidget(self.label_resize, 4, 0)
        self.layout.addWidget(self.edit_resize_xc, 5, 0)
        self.layout.addWidget(self.label_resize_xc, 5, 1)
        self.layout.addWidget(self.edit_resize_yc, 6, 0)
        self.layout.addWidget(self.label_resize_yc, 6, 1)
        self.layout.addWidget(self.edit_resize_kx, 7, 0)
        self.layout.addWidget(self.label_resize_kx, 7, 1)
        self.layout.addWidget(self.edit_resize_ky, 8, 0)
        self.layout.addWidget(self.label_resize_ky, 8, 1)
        self.layout.addWidget(self.button_resize, 9, 0)

        self.layout.addWidget(self.label_rotate, 10, 0)
        self.layout.addWidget(self.edit_rotate_xc, 11, 0)
        self.layout.addWidget(self.label_rotate_xc, 11, 1)
        self.layout.addWidget(self.edit_rotate_yc, 12, 0)
        self.layout.addWidget(self.label_rotate_yc, 12, 1)
        self.layout.addWidget(self.edit_angle, 14, 0)
        self.layout.addWidget(self.label_rotate_angle, 14, 1)
        self.layout.addWidget(self.label_rotate, 15, 0)
        self.layout.addWidget(self.button_rotate, 16, 0)

        self.layout.addWidget(self.button_back, 17, 0)
        self.layout.addWidget(self.button_reset, 18, 0)

    def paintEvent(self, e):
        self.drawPlane()

    def drawAxes(self):
        oneUnit = self.coordinatePlane.oneUnit()
        self.qp.drawLine(1, 0, 1, self.sizeScreen.height())
        self.qp.drawLine(0, 1, self.sizeScreen.width(), 1)
        for i in range(100, self.sizeScreen.height(), 100):
            self.qp.drawLine(0, i, 10, i)
            self.qp.drawStaticText(12, i - 7, QStaticText(str(i)))

        for i in range(100, self.sizeScreen.width(), 100):
            self.qp.drawLine(i, 0, i, 10)
            self.qp.drawStaticText(i - 10, 12, QStaticText(str(i)))
            self.qp.drawStaticText(7, 7, QStaticText(str(0)))

    def drawPlane(self):
        self.qp.begin(self)
        self.qp.setPen(Qt.black)
        self.drawAxes()
        self.qp.drawPoint(self.rotation_center_x, self.rotation_center_y)

        for i in self.figures:
            p = i.draw(self.coordinatePlane)
            self.qp.drawPath(p)
        self.qp.end()

    def __saveMovement(self):
        self.cur_dx = self.new_offset_x
        self.cur_dy = self.new_offset_y
        self.cur_state = self.state

    def __saveRotation(self):
        self.cur_angle = self.angle
        self.cur_rotation_center_x = self.rotation_center_x
        self.cur_rotation_center_y = self.rotation_center_y

    def __saveScale(self):
        self.curRadX = self.figures[0].x_height
        self.curRadY = self.figures[0].y_height
        self.curAstrHeight = self.astroid_heigth
        self.curAstrWidth = self.astroid_width
        self.curRectH = self.rect_heigth
        self.curRectWidth = self.rect_width
        self.state.setX(self.figures[0].center_x)
        self.state.setY(self.figures[0].center_y)
        self.cur_kx, self.cur_ky = self.kx, self.ky
        self.cur_scale_xc, self.cur_scale_yc = self.scale_xc, self.scale_yc

    def __figures(self):
        figures = []
        circle = MyCircle(self.radX, self.radY, self.sstate.x(),
                          self.sstate.y())
        rect = Rect(self.sstate.x(), self.sstate.y(), self.rect_heigth,
                    self.rect_width)
        ast = Astroid(self.sstate.x(), self.sstate.y(), self.astroid_heigth,
                      self.astroid_width)
        figures.append(circle)
        figures.append(rect)
        figures.append(ast)
        return figures
class Drawing(QWidget):
    def __init__(self, figures, set1, set2):
        super().__init__()

        self.pannel = QWidget(self)
        self.layout = QGridLayout()
        self.qp = QPainter()
        self.sizeScreen = [QDesktopWidget().availableGeometry().width() - 100,
                           QDesktopWidget().availableGeometry().height() - 100]
        self.coordinatePlane = None
        self.kx = 1
        self.ky = 1
        self.dx = 0
        self.dy = 0

        self.figures = figures
        self.set1 = set1
        self.set2 = set2

        self.initUI()

    def setFigures(self, f):
        self.figures = f

    def paintEvent(self, QPaintEvent):
        self.drawPlane()

    def addFigure(self, twoCircles):
        self.figures.append(twoCircles)

    def initUI(self):
        self.pannel.setGeometry(0, 0, self.sizeScreen[0], self.sizeScreen[1])
        self.setGeometry(0, 0, self.sizeScreen[0], self.sizeScreen[1])

        self.drawAxes()

        self.pannel.setLayout(self.layout)
        self.setWindowTitle('Lab 1')
        self.show()

    def drawPlane(self):
        self.coordinatePlane = CoordinatePlane(self.size())
        self.qp.begin(self)
        self.qp.setPen(Qt.black)

        self.drawAxes()
        self.__drawPoints()

        for i in self.figures:
            random_color = QColor(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
            while random_color == (255, 255, 255):
                random_color = QColor(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
            newPen = QPen()
            newPen.setColor(random_color)
            self.qp.setPen(newPen)

            i.draw(self.qp, self.kx, self.ky, self.dx, self.dy, self.sizeScreen)

        self.qp.end()

    def __drawPoints(self):
        color = Qt.red
        newPen = QPen()
        newPen.setColor(color)
        self.qp.setPen(newPen)
        for i in range(len(self.set1)):
            point = QPoint((self.set1[i].get_x() + self.dx) * self.kx, self.sizeScreen[1] - (self.set1[i].get_y() + self.dy) * self.ky)
            self.qp.drawEllipse(point, 5, 5)
            point = QPoint(round(point.x() - 20), round((point.y() - 20)))
            text = ""
            text += str(self.set1[i].get_x()) + "," + str(self.set1[i].get_y())
            self.qp.drawStaticText(point, QStaticText(text))

        color = Qt.green
        newPen = QPen()
        newPen.setColor(color)
        self.qp.setPen(newPen)
        for i in range(len(self.set2)):
            point = QPoint((self.set2[i].get_x() + self.dx) * self.kx, self.sizeScreen[1] - (self.set2[i].get_y() + self.dy) * self.ky)
            self.qp.drawEllipse(point, 5, 5)
            point = QPoint(round(point.x() - 20), round((point.y() - 20)))
            text = ""
            text += str(self.set2[i].get_x()) + "," + str(self.set2[i].get_y())
            self.qp.drawStaticText(point, QStaticText(text))

    def __randomColor(self):
        return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))

    def drawAxes(self):

        xMax, yMax, xMin, yMin = self.__getBounds()

        resize = 10

        if abs(xMax) < 1 or abs(yMax) < 1 or abs(xMin) < 1 or abs(yMin) < 1:
            resize = 0.5
        if abs(xMax) / 10 < 1 or abs(yMax) / 10 < 1 or abs(xMin) / 10 < 1 or abs(yMin) / 10 < 1:
            resize = 0.1

        xMin -= resize
        yMin -= resize

        self.dx = -1 * xMin
        self.dy = -1 * yMin

        intervalX = (xMax + resize) - xMin
        intervalY = (yMax + resize) - yMin

        k = min((self.sizeScreen[0] - resize) / (intervalX), (self.sizeScreen[1] - resize) / (intervalY))

        self.kx = k
        self.ky = k

        stepX = (intervalX / 10)
        stepY = (intervalY / 10)

        self.qp.drawLine(1, 0, 1, self.sizeScreen[1])
        self.qp.drawLine(0, self.sizeScreen[1] - 2, self.sizeScreen[0], self.sizeScreen[1] - 2)

        i = yMin + stepY
        while i <= self.sizeScreen[1] / self.ky:
            self.qp.drawLine(0, self.sizeScreen[1] - (i + self.dy) * self.ky, 10,
                             self.sizeScreen[1] - (i + self.dy) * self.ky)
            self.qp.drawStaticText(12, self.sizeScreen[1] - (i + self.dy) * self.ky, QStaticText(str(round(i, 2))))
            i += stepY

        i = xMin + stepX
        while i <= self.sizeScreen[0] / self.kx:
            self.qp.drawLine((i + self.dx) * self.kx, self.sizeScreen[1] - 1, (i + self.dx) * self.kx,
                             self.sizeScreen[1] - 11)
            self.qp.drawStaticText((i + self.dx) * self.kx, self.sizeScreen[1] - 25, QStaticText(str(round(i, 2))))
            i += stepX

        # for i in range(yMin + stepY, self.sizeScreen[1], stepY):
        #     self.qp.drawLine(0, self.sizeScreen[1] - (i + self.dy) * self.ky, 10, self.sizeScreen[1] - (i + self.dy) * self.ky)
        #     self.qp.drawStaticText(12, self.sizeScreen[1] - (i + self.dy) * self.ky, QStaticText(str(i)))
        #
        # for i in range(xMin + stepX, self.sizeScreen[0], stepX):
        #     self.qp.drawLine((i + self.dx) * self.kx, self.sizeScreen[1] - 1, (i + self.dx) * self.kx, self.sizeScreen[1] - 11)
        #     self.qp.drawStaticText((i + self.dx) * self.kx, self.sizeScreen[1] - 25, QStaticText(str(i)))

        # self.qp.drawStaticText(7, 7, QStaticText(str(start)))

    def __getBounds(self):
        xMax, yMax, xMin, yMin = None, None, None, None
        for i in range(len(self.figures)):
            c1, c2, r1, r2 = self.figures[i].getCircles()

            xMaxTmp = max((c1.get_x() + r1), (c2.get_x() + r2))
            xMinTmp = min((c1.get_x() - r1), (c2.get_x() - r2))
            yMaxTmp = max((c1.get_y() + r1), (c2.get_y() + r2))
            yMinTmp = min((c1.get_y() - r1), (c2.get_y() - r2))

            # xMaxTmp = max(round(c1.get_x() + r1), round(c2.get_x() + r2))
            # xMinTmp = min(round(c1.get_x() - r1), round(c2.get_x() - r2))
            # yMaxTmp = max(round(c1.get_y() + r1), round(c2.get_y() + r2))
            # yMinTmp = min(round(c1.get_y() - r1), round(c2.get_y() - r2))

            if xMax == None:
                xMax = xMaxTmp
            else:
                xMax = max(xMax, xMaxTmp)

            if yMax == None:
                yMax = yMaxTmp
            else:
                yMax = max(yMax, yMaxTmp)

            if xMin == None:
                xMin = xMinTmp
            else:
                xMin = min(xMin, xMinTmp)

            if yMin == None:
                yMin = yMinTmp
            else:
                yMin = min(yMin, yMinTmp)

        return xMax, yMax, xMin, yMin
Exemple #9
0
class Ui_MainWindow(QMainWindow):
    def __init__(self):
        super(Ui_MainWindow, self).__init__()
        self.setObjectName("MainWindow")
        self.resize(Game.screenWidth, Game.screenHeight)

        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap("res/Instructions-icon.png"),
                       QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.setWindowIcon(icon)

        self.menubar = QtWidgets.QMenuBar(self)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        self.menuFile = QtWidgets.QMenu(self.menubar)
        self.menuFile.setObjectName("menuFile")
        self.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(self)
        self.statusbar.setObjectName("statusbar")
        self.setStatusBar(self.statusbar)
        self.actionExit = QtWidgets.QAction(self)
        self.actionExit.setObjectName("actionExit")
        self.menuFile.addAction(self.actionExit)
        self.menubar.addAction(self.menuFile.menuAction())
        self.actionExit.triggered.connect(self.closeEvent)

        _translate = QtCore.QCoreApplication.translate
        self.menuFile.setTitle(_translate("MainWindow", "File"))
        self.actionExit.setText(_translate("MainWindow", "Exit"))
        self.actionExit.setShortcut(_translate("MainWindow", "Ctrl+Q"))

        self.image = QImage(self.size(), QImage.Format_RGB32)
        self.image.fill(Qt.white)

        pen = QPen()
        pen.setBrush(QtGui.QBrush(Game.angleLineColor))
        self.painter = QPainter(self.image)
        self.painter.setPen(pen)

        self.stateMessage = ''

        #        self.hitSound = QtGui.

        self.homeUi()

    def homeUi(self):
        Game.state = Game.GameState.INTRO
        self.removeAllPaint()

        self.centralwidget = QtWidgets.QWidget(self)
        self.centralwidget.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        self.centralwidget.setAutoFillBackground(False)
        self.centralwidget.setObjectName("centralwidget")

        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")

        spacerItem = QtWidgets.QSpacerItem(20, 40,
                                           QtWidgets.QSizePolicy.Minimum,
                                           QtWidgets.QSizePolicy.Expanding)
        self.gridLayout.addItem(spacerItem, 2, 1, 1, 1)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20,
                                            QtWidgets.QSizePolicy.Expanding,
                                            QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem1, 1, 2, 1, 1)

        self.label = QtWidgets.QLabel(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("Orbitron")
        font.setPointSize(28)
        font.setBold(True)
        font.setWeight(75)
        self.label.setFont(font)
        self.label.setFrameShadow(QtWidgets.QFrame.Raised)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setObjectName("label")
        self.gridLayout.addWidget(self.label, 1, 1, 1, 1)

        spacerItem2 = QtWidgets.QSpacerItem(40, 20,
                                            QtWidgets.QSizePolicy.Expanding,
                                            QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem2, 1, 0, 1, 1)

        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setEnabled(True)
        font = QtGui.QFont()
        font.setPointSize(16)
        self.pushButton.setFont(font)
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap("res/Instructions-icon.png"),
                       QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.pushButton.setIcon(icon)
        self.pushButton.setObjectName("pushButton")
        self.gridLayout.addWidget(self.pushButton, 4, 1, 1, 1)
        self.pushButton.pressed.connect(self.insUi)

        spacerItem3 = QtWidgets.QSpacerItem(20, 40,
                                            QtWidgets.QSizePolicy.Minimum,
                                            QtWidgets.QSizePolicy.Expanding)
        self.gridLayout.addItem(spacerItem3, 0, 1, 1, 1)
        spacerItem4 = QtWidgets.QSpacerItem(20, 40,
                                            QtWidgets.QSizePolicy.Minimum,
                                            QtWidgets.QSizePolicy.Expanding)
        self.gridLayout.addItem(spacerItem4, 5, 1, 1, 1)

        self.playButton = QtWidgets.QPushButton(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(16)
        self.playButton.setFont(font)
        self.playButton.setAutoFillBackground(False)
        icon1 = QtGui.QIcon()
        icon1.addPixmap(QtGui.QPixmap("res/Play-icon.png"), QtGui.QIcon.Normal,
                        QtGui.QIcon.Off)
        self.playButton.setIcon(icon1)
        self.playButton.setObjectName("playButton")
        self.gridLayout.addWidget(self.playButton, 3, 1, 1, 1)
        self.playButton.pressed.connect(self.gameTypeUi)

        self.setCentralWidget(self.centralwidget)

        self.retranslateHomeUi()
        QtCore.QMetaObject.connectSlotsByName(self)

    def retranslateHomeUi(self):
        _translate = QtCore.QCoreApplication.translate
        self.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label.setText(_translate("MainWindow", "HIT ME IF YOU CAN"))
        self.pushButton.setText(_translate("MainWindow", "Instructions"))
        self.playButton.setText(_translate("MainWindow", "Play Now"))

        self.show()

    def gameTypeUi(self):
        self.centralwidget = QtWidgets.QWidget(self)
        self.centralwidget.setAutoFillBackground(False)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")

        self.p2c = QtWidgets.QPushButton(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.p2c.setFont(font)
        self.p2c.setObjectName("p2c")
        self.gridLayout.addWidget(self.p2c, 5, 3, 1, 1)
        self.p2c.pressed.connect(self.p2cSelection)

        self.p2p = QtWidgets.QPushButton(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.p2p.setFont(font)
        self.p2p.setObjectName("p2p")
        self.gridLayout.addWidget(self.p2p, 5, 1, 1, 1)
        self.p2p.pressed.connect(self.p2pSelection)

        spacerItem = QtWidgets.QSpacerItem(20, 100,
                                           QtWidgets.QSizePolicy.Minimum,
                                           QtWidgets.QSizePolicy.Fixed)
        self.gridLayout.addItem(spacerItem, 6, 1, 1, 3)
        spacerItem1 = QtWidgets.QSpacerItem(20, 40,
                                            QtWidgets.QSizePolicy.Minimum,
                                            QtWidgets.QSizePolicy.Preferred)
        self.gridLayout.addItem(spacerItem1, 1, 1, 1, 3)

        self.gameType = QtWidgets.QLabel(self.centralwidget)
        self.gameType.setTextFormat(QtCore.Qt.RichText)
        self.gameType.setAlignment(QtCore.Qt.AlignCenter)
        self.gameType.setObjectName("gameType")

        self.gridLayout.addWidget(self.gameType, 0, 0, 1, 5)
        spacerItem2 = QtWidgets.QSpacerItem(40, 20,
                                            QtWidgets.QSizePolicy.Expanding,
                                            QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem2, 5, 2, 1, 1)
        spacerItem3 = QtWidgets.QSpacerItem(40, 20,
                                            QtWidgets.QSizePolicy.Expanding,
                                            QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem3, 5, 0, 1, 1)
        spacerItem4 = QtWidgets.QSpacerItem(40, 20,
                                            QtWidgets.QSizePolicy.Expanding,
                                            QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem4, 5, 4, 1, 1)

        self.setCentralWidget(self.centralwidget)

        self.retranslateGameTypeUi()
        QtCore.QMetaObject.connectSlotsByName(self)

    def retranslateGameTypeUi(self):
        _translate = QtCore.QCoreApplication.translate
        self.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.p2c.setText(_translate("MainWindow", "With Computer"))
        self.p2p.setText(_translate("MainWindow", "Two Player"))
        self.gameType.setText(
            _translate("MainWindow",
                       "<b style=\'font-size:25px\' >Choose The Game Type<b>"))

    def p2pSelection(self):
        Game.type = Game.Type.P2P
        self.playUi()

    def p2cSelection(self):
        Game.type = Game.Type.P2C
        self.playUi()

    def insUi(self):
        Game.state = Game.GameState.INSTRUCT

        self.centralwidget = QtWidgets.QWidget(self)
        self.centralwidget.setAutoFillBackground(False)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")

        self.backButton = QtWidgets.QPushButton(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(14)
        self.backButton.setFont(font)
        self.backButton.setObjectName("backButton")
        self.gridLayout.addWidget(self.backButton, 8, 1, 1, 1)
        self.backButton.pressed.connect(self.homeUi)

        spacerItem = QtWidgets.QSpacerItem(40, 20,
                                           QtWidgets.QSizePolicy.Expanding,
                                           QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem, 8, 0, 1, 1)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20,
                                            QtWidgets.QSizePolicy.Expanding,
                                            QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem1, 8, 2, 1, 1)
        spacerItem2 = QtWidgets.QSpacerItem(20, 40,
                                            QtWidgets.QSizePolicy.Minimum,
                                            QtWidgets.QSizePolicy.Fixed)
        self.gridLayout.addItem(spacerItem2, 6, 0, 1, 3)

        self.plainTextEdit = QtWidgets.QPlainTextEdit(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(16)
        self.plainTextEdit.setFont(font)
        self.plainTextEdit.setReadOnly(True)
        self.plainTextEdit.setObjectName("plainTextEdit")
        self.gridLayout.addWidget(self.plainTextEdit, 3, 0, 1, 3)

        spacerItem3 = QtWidgets.QSpacerItem(20, 40,
                                            QtWidgets.QSizePolicy.Minimum,
                                            QtWidgets.QSizePolicy.Fixed)
        self.gridLayout.addItem(spacerItem3, 2, 0, 1, 3)

        self.label = QtWidgets.QLabel(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(18)
        font.setBold(True)
        font.setWeight(75)
        self.label.setFont(font)
        self.label.setFrameShape(QtWidgets.QFrame.NoFrame)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setObjectName("label")
        self.gridLayout.addWidget(self.label, 0, 0, 1, 3)

        self.setCentralWidget(self.centralwidget)

        self.retranslateInsUi()
        QtCore.QMetaObject.connectSlotsByName(self)

    def retranslateInsUi(self):
        _translate = QtCore.QCoreApplication.translate
        self.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.backButton.setText(_translate("MainWindow", "Back to Mainmenu"))

        ins = '''
        1. Each of the players will have his turn.
        2. Player 1 can tune angle and speed by Key A and D.
        3. Player 2 can use Key Left Arrow and Right Arrow to do that.
        4. Space Key is used to select an angle or speed and advance.
        5. The opponent has a few time to take his position also using 
            A and D or Right and Left Arrow Button depending on his playing side.
        6. Player who can hit his opponent gains a point.
        7. Press P to pause the game and then Esc to get to the Mainmenu 
            or again P to resume
        8. Player gaining 5 points first, is the winner.
        
        '''

        self.plainTextEdit.setPlainText(_translate("MainWindow", ins))
        self.label.setText(_translate("MainWindow", "INSTRUCTION"))

        self.show()

    def playUi(self):
        Game.state = Game.GameState.PLAY

        self.centralwidget = QtWidgets.QWidget(self)
        self.centralwidget.setAutoFillBackground(False)
        self.centralwidget.setObjectName("centralwidget")

        self.painter.fillRect(0, Game.screenHeight - Game.fieldHeight,
                              Game.screenWidth, Game.fieldHeight,
                              Game.fieldColor)
        self.painter.fillRect(Game.barPosX, Game.barPosY, Game.barWidth,
                              Game.barHeight, Game.fieldColor)

        self.setCentralWidget(self.centralwidget)

        self.show()

        global player1
        global player2
        player1 = Player((Game.player1limitX[0] + Game.player1limitX[1]) / 2)
        player2 = Player((Game.player2limitX[0] + Game.player2limitX[1]) / 2)

        # Main GameLoop Begins
        Game.turn = Game.Turn.P1

        self.startToMove()

        # Main GameLoop Ends

    def startToMove(self):
        Game.action = Game.Action.MOVE
        stone.gotoP()

        self.stateMessage = 'Take your position'
        self.paintField()
        QTimer.singleShot(2000, self.switchMoveToThrow)

        if Game.type == Game.Type.P2C and Game.turn == Game.Turn.P1:
            player2.playerX = random.randint(Game.player2limitX[0],
                                             Game.player2limitX[1])
            self.paintField()
        # ----------------------------- #
        #                               #
        #    for development purpose    #
        #                               #
        # ----------------------------- #
#
#        else:
#            player1.playerX = random.randint(Game.player1limitX[0], Game.player1limitX[1])
##
#        QTimer.singleShot(5, self.switchMoveToThrow)

#  Till here  #

    def switchMoveToThrow(self):
        self.stateMessage = 'Aim and Throw'
        Game.action = Game.Action.SET_ANGLE_FORCE
        angle_line.gotoStone()

        self.paintField()

        if Game.type == Game.Type.P2C and Game.turn == Game.Turn.P2:
            Game.action = Game.Action.THROW

            #            target = player2.playerX - player1.playerX# - Game.playerHeight / 2
            #            bar_dist = player2.playerX - Game.barPosX
            #            print(target - bar_dist, bar_dist)

            #            computer_input = [[target, bar_dist]]

            #to feed the model
            imageCrop = 300
            imageResize = (80, 30)

            computer_input = qimage2ndarray.byte_view(self.image)[imageCrop:]
            computer_input = cv2.resize(computer_input, imageResize)
            #            cv2.imshow(' ', computer_input)
            #            cv2.waitKey(0)
            #            cv2.destroyAllWindows()
            computer_input = computer_input.reshape((1, ) +
                                                    computer_input.shape)
            computer_input = computer_input / 255

            computer_output = Game.computer.predict(computer_input)
            angle = computer_output[0][0]
            velocity = computer_output[0][1]  # - 2
            #
            angle_line.current_angle = angle
            angle_line.current_vel = velocity

            #            print(angle, velocity)

            self.throw()
            self.paintField()
            angle_line.current_vel = Game.defaultForceLen

        # ----------------------------- #
        #                               #
        #    for development purpose    #
        #                               #
        # ----------------------------- #

#            Game.data.append([target, bar_dist, angle, a_velocity])
#            Game.dataCount += 1
#
#            if Game.dataCount >= 100:
#                x_train = []
#                y_train = []
#
#                for i in Game.data:
#                    x_train.append([i[0], i[2]])
#                    y_train.append([i[3]])
#
#                x_train = numpy.array(x_train)
#                y_train = numpy.array(y_train)
#
#                x_train = tf.keras.utils.normalize(x_train)
#                y_train = y_train / 110
#
#                Game.computer_vel.fit(x_train, y_train, epochs=3)
#
#                Game.data = []
#                Game.dataCount = 0
#
#        else:
#            Game.action = Game.Action.THROW
#            self.throw()

#  Till here  #

    def throw(self):
        prevX = stone.stoneX
        prevY = stone.stoneY
        v0 = angle_line.getVel()
        theta = angle_line.current_angle * math.pi / 180
        cos_theta = math.cos(theta)
        sin_theta = math.sin(theta)
        g = 9.8
        ground = Game.screenHeight - Game.fieldHeight - Game.stoneWidth

        t = 0

        if Game.turn == Game.Turn.P1:
            player = player1
            opponent = player2
        else:
            player = player2
            opponent = player1

        while stone.stoneY < ground:
            if Game.state == Game.GameState.PAUSED:
                QtTest.QTest.qWait(1000)
                continue

            x_ = v0 * t * cos_theta
            y_ = v0 * t * sin_theta - 0.5 * g * t * t

            #            if stone.stoneY >= opponent.playerY:
            #                print('distance travelled = ', x_)

            stone.stoneX = prevX + x_
            stone.stoneY = prevY - y_

            if stone.stoneY > ground:
                stone.stoneY = ground
                # unsuccessful
                self.stateMessage = 'Missed...'
                thread.start_new_thread(
                    self.playMusic,
                    ('res\\Woosh-Mark_DiAngelo-4778593.wav', 'ignore it'))
                break

            if stone.stoneX > Game.barPosX - Game.stoneWidth and stone.stoneX < Game.barPosX + Game.barWidth:
                if stone.stoneY > Game.barPosY - Game.stoneHeight:
                    # unsuccessful
                    self.stateMessage = 'Missed...'
                    thread.start_new_thread(
                        self.playMusic,
                        ('res\\Woosh-Mark_DiAngelo-4778593.wav', 'ignore it'))
                    #
                    #                    winsound.PlaySound('res\\Woosh-Mark_DiAngelo-4778593.wav', winsound.SND_FILENAME)
                    break

            if stone.stoneX > opponent.playerX - Game.stoneWidth and stone.stoneX < opponent.playerX + Game.playerWidth:
                if stone.stoneY > opponent.playerY - Game.stoneHeight:
                    # successful
                    self.stateMessage = 'Hit!!'
                    thread.start_new_thread(
                        self.playMusic,
                        ('res\\Realistic_Punch-Mark_DiAngelo-1609462330.wav',
                         'ignore it'))
                    #                    winsound.PlaySound('res\\Realistic_Punch-Mark_DiAngelo-1609462330.wav', winsound.SND_FILENAME)

                    #    for not development purpose    #
                    player.score += 1
                    break

            self.paintField()
            QtTest.QTest.qWait(50)

            # ----------------------------- #
            #                               #
            #    for development purpose    #
            #                               #
            # ----------------------------- #

            #            QtTest.QTest.qWait(1)

            #     Till here  #

            t += 0.3

        if player1.score >= Game.gameScore:
            #player1 wins
            if Game.type == Game.Type.P2P:
                self.stateMessage = 'Player 1 wins <br> Press any key to continue'
            else:
                self.stateMessage = 'You Win..! <br> Press any key to continue'

            thread.start_new_thread(
                self.playMusic,
                ('res\\Applauding-and-cheering.mp3', 'ignore it'))
            Game.state = Game.GameState.GAMEOVER
        elif player2.score >= Game.gameScore:
            #player2 wins
            if Game.type == Game.Type.P2P:
                self.stateMessage = 'Player 2 wins <br> Press any key to continue'
                thread.start_new_thread(
                    self.playMusic,
                    ('res\\Applauding-and-cheering.mp3', 'ignore it'))
            else:
                self.stateMessage = 'You lose..! <br> Press any key to continue'
                thread.start_new_thread(
                    self.playMusic, ('res\\fail-trombone-01.mp3', 'ignore it'))
            Game.state = Game.GameState.GAMEOVER
        else:
            if Game.turn == Game.Turn.P1:
                Game.turn = Game.Turn.P2
            else:
                Game.turn = Game.Turn.P1

            QTimer.singleShot(500, self.startToMove)

            # ----------------------------- #
            #                               #
            #    for development purpose    #
            #                               #
            # ----------------------------- #

#            QTimer.singleShot(1, self.startToMove)

#     Till here  #

    def keyPressEvent(self, event):
        #        print(event)
        if event.key() == Qt.Key_P and Game.state == Game.GameState.PLAY:
            Game.state = Game.GameState.PAUSED
            self.prevMessage = self.stateMessage
            self.stateMessage = 'Paused'
            self.paintField()

        elif Game.state == Game.GameState.PAUSED:
            if event.key() == Qt.Key_P:
                Game.state = Game.GameState.PLAY
                self.stateMessage = self.prevMessage
                self.paintField()
            elif event.key() == Qt.Key_Escape:
                QTimer.singleShot(50, self.homeUi)

        elif Game.state == Game.GameState.PLAY and Game.action != Game.Action.THROW:
            if Game.turn == Game.Turn.P1:
                if Game.type == Game.Type.P2P and Game.action == Game.Action.MOVE:
                    if event.key() == Qt.Key_Left and Game.player2limitX[
                            0] < player2.playerX:
                        player2.move(-1)
                    elif event.key(
                    ) == Qt.Key_Right and player2.playerX < Game.player2limitX[
                            1]:
                        player2.move(1)

                elif Game.action == Game.Action.SET_ANGLE_FORCE:
                    if event.key() == Qt.Key_W and angle_line.getAngle(
                    ) < Game.player1AngleLimit[1]:
                        angle_line.change(1)
                    elif event.key() == Qt.Key_S and Game.player1AngleLimit[
                            0] < angle_line.getAngle():
                        angle_line.change(-1)
                    elif event.key(
                    ) == Qt.Key_A and angle_line.getVel() > Game.minForceLen:
                        angle_line.changeVel(-1)
                    elif event.key(
                    ) == Qt.Key_D and Game.maxForceLen > angle_line.getVel():
                        angle_line.changeVel(1)
                    elif event.key() == Qt.Key_Space:
                        Game.action = Game.Action.THROW
                        self.throw()
                        angle_line.current_vel = Game.defaultForceLen

                else:
                    return
            else:
                if Game.action == Game.Action.MOVE:
                    if event.key(
                    ) == Qt.Key_A and Game.player1limitX[0] < player1.playerX:
                        player1.move(-1)
                    elif event.key(
                    ) == Qt.Key_D and player1.playerX < Game.player1limitX[1]:
                        player1.move(1)

                elif Game.action == Game.Action.SET_ANGLE_FORCE:
                    if event.key() == Qt.Key_Down and angle_line.getAngle(
                    ) < Game.player2AngleLimit[1]:
                        angle_line.change(1)
                    elif event.key() == Qt.Key_Up and Game.player2AngleLimit[
                            0] < angle_line.getAngle():
                        angle_line.change(-1)
                    elif event.key(
                    ) == Qt.Key_Left and Game.maxForceLen > angle_line.getVel(
                    ):
                        angle_line.changeVel(1)
                    elif event.key() == Qt.Key_Right and angle_line.getVel(
                    ) > Game.minForceLen:
                        angle_line.changeVel(-1)
                    elif event.key() == Qt.Key_Space:
                        Game.action = Game.Action.THROW
                        self.throw()
                        angle_line.current_vel = Game.defaultForceLen

                else:
                    return

            self.paintField()

        elif Game.state == Game.GameState.GAMEOVER:
            QTimer.singleShot(50, self.homeUi)


#        print(self.position)

    def removeAllPaint(self):
        self.painter.fillRect(self.image.rect(), Qt.white)
        self.update()

    def paintField(self):
        self.removeAllPaint()

        self.painter.fillRect(0, Game.screenHeight - Game.fieldHeight,
                              Game.screenWidth, Game.fieldHeight,
                              Game.fieldColor)
        self.painter.fillRect(Game.barPosX, Game.barPosY, Game.barWidth,
                              Game.barHeight, Game.fieldColor)

        self.painter.fillRect(player1.playerX, player1.playerY,
                              Game.playerWidth, Game.playerHeight,
                              Game.playerColor)
        self.painter.fillRect(player2.playerX, player2.playerY,
                              Game.playerWidth, Game.playerHeight,
                              Game.playerColor)
        self.painter.fillRect(stone.stoneX, stone.stoneY, Game.stoneWidth,
                              Game.stoneWidth, Game.stoneColor)

        self.scoreText1 = '<b style="font-size:20px;">Player 1 : ' + str(
            player1.score) + '<\b>'

        if Game.type == Game.Type.P2P:
            self.scoreText2 = '<b style="font-size:20px;">Player 2 : ' + str(
                player2.score) + '<\b>'
        else:
            self.scoreText2 = '<b style="font-size:20px;">Computer : ' + str(
                player2.score) + '<\b>'

        self.message = '<b style="font-size:40px;">' + self.stateMessage + '<\b>'

        text1 = QtGui.QStaticText(self.scoreText1)
        text1.setTextFormat(Qt.RichText)
        text2 = QtGui.QStaticText(self.scoreText2)
        text2.setTextFormat(Qt.RichText)
        message = QtGui.QStaticText(self.message)
        message.setTextFormat(Qt.RichText)
        self.painter.drawStaticText(Game.scoreText1PosX, Game.scoreText1PosY,
                                    text1)
        self.painter.drawStaticText(Game.scoreText2PosX, Game.scoreText2PosY,
                                    text2)
        self.painter.drawStaticText(Game.stateMessageBoxX,
                                    Game.stateMessageBoxY, message)

        if Game.action == Game.Action.SET_ANGLE_FORCE:
            self.painter.drawLines(angle_line.getLines())

        self.update()

    def paintEvent(self, event):
        canvas = QPainter(self)
        if Game.state == Game.GameState.PLAY or Game.state == Game.GameState.GAMEOVER:
            canvas.drawImage(self.rect(), self.image, self.image.rect())
        elif Game.state == Game.GameState.PAUSED:
            message = '<b style="font-size:40px;">PAUSED<br> Press P to play or Esc to exit<\b>'
            message = QtGui.QStaticText(message)
            message.setTextFormat(Qt.RichText)
            canvas.drawStaticText(Game.stateMessageBoxX, Game.stateMessageBoxY,
                                  message)

    def playMusic(self, file, ignored):
        playsound(file)

    def closeEvent(self, event):
        #        QCoreApplication.quit()

        # ----------------------------- #
        #                               #
        #    for development purpose    #
        #                               #
        # ----------------------------- #

        #        numpy.save('modelDataReal.npy', Game.data)
        #        Game.computer_vel.save('model6')

        # till here

        sys.exit()
Exemple #10
0
    def paintEvent(self, event):
        painter = QPainter()
        painter.begin(self)
        if not self.ignored:
            self.paint_background(painter)
        painter.setPen(QColor(255, 0, 255))
        painter.setBrush(QColor(0, 0, 0))

        for index, i in enumerate(self.initial_dots):
            painter.setPen(QColor(255, 0, 255))
            painter.drawRect(i.x() - 1, i.y() - 1, 2, 2)
            try:
                end_point = self.final_dots[index]
                painter.setPen(QColor(0, 0, 255))
                moving = False
            except IndexError:
                # There is no end point, so cursor is end point
                end_point = self.cursor().pos()
                painter.setPen(QColor(0, 0, 255, 64))
                moving = True

            mid_point = QPoint(end_point.x(), i.y())
            painter.drawPolyline(i, mid_point, end_point, i)
            painter.setPen(QColor(255, 0, 255))
            halfx = (mid_point.x() - i.x()) / 2 + i.x()
            halfy = (end_point.y() - mid_point.y()) / 2 + mid_point.y()

            # Draw perpendicular magenta lines in each of the triangle's sides' center
            top_horizontal_half = QPoint(halfx, i.y() + 10)
            bot_horizontal_half = QPoint(halfx, i.y() - 10)

            left_vertical_half = QPoint(end_point.x() - 10, halfy)
            right_vertical_half = QPoint(end_point.x() + 10, halfy)
            try:
                hipotenuse = math.sqrt((2 * (halfx - i.x()))**2 +
                                       (2 * (halfy - mid_point.y()))**2)
                scaling_factor = hipotenuse / 10  # To ensure line length = 10
                y_change = (2 * (halfx - i.x()) / scaling_factor)
                x_change = (2 * (halfy - mid_point.y()) / scaling_factor)

            except ZeroDivisionError:
                y_change = 0
                x_change = 0

            top_hipotenuse_half = QPoint(halfx - x_change, halfy + y_change)
            bot_hipotenuse_half = QPoint(halfx + x_change, halfy - y_change)

            if hipotenuse >= 20 and moving:  # To not be in the way while looking for a second point
                painter.drawLine(top_horizontal_half, bot_horizontal_half)
                painter.drawLine(left_vertical_half, right_vertical_half)
                painter.drawLine(top_hipotenuse_half, bot_hipotenuse_half)

            painter.setPen(QColor(255, 255, 255))
            x_px = abs(int((halfx - i.x()) * 2)) + 1
            y_px = abs(int((halfy - mid_point.y()) * 2)) + 1
            hipotenuse = abs(hipotenuse)
            inch_to_cm = 2.54
            x_inches = x_px / self.ppix
            y_inches = y_px / self.ppiy
            hip_inches = hipotenuse / ((self.ppiy + self.ppix) / 2)
            x_cm = x_inches * inch_to_cm
            y_cm = y_inches * inch_to_cm
            hip_cm = hip_inches * inch_to_cm
            x_text = str(
                x_px
            ) + "px | " + f"{x_cm:7.2f}" + "cm | " + f"{x_inches:7.2f}" + "inch"
            y_text = str(
                y_px
            ) + "px | " + f"{y_cm:7.2f}" + "cm | " + f"{y_inches:7.2f}" + "inch"
            hip_text = f"{abs(hipotenuse):7.2f}" + "px | " + f"{hip_cm:7.2f}" + "cm | " + f"{hip_inches:7.2f}" + "inch"
            # in 7.2f -> 7 = max char, 2 = max floating point precision
            if moving and hipotenuse >= 20:  # To not be in the way while looking for a second point
                painter.drawText(QPoint(halfx, i.y()), x_text)
                painter.drawText(QPoint(end_point.x(), halfy), y_text)
                painter.drawText(
                    QPoint(halfx, halfy - 12),
                    hip_text)  # 7 = max char, 2 = max floating point precision
            elif not moving:
                # drawStaticText is more optimized if it rarely updates
                painter.drawStaticText(QPoint(halfx, i.y()),
                                       QStaticText(x_text))
                painter.drawStaticText(QPoint(end_point.x(), halfy),
                                       QStaticText(y_text))
                painter.drawStaticText(QPoint(halfx, halfy - 12),
                                       QStaticText(hip_text))

        painter.setPen(QColor(255, 0, 255))
        for i in self.final_dots:
            painter.drawRect(i.x() - 1, i.y() - 1, 2, 2)
        """if not self.ignored:
            self.paint_cursor(painter)"""
        painter.end()
Exemple #11
0
class PixelWidget(QWidget):
    def __init__(self, form, bufhandler):
        super(PixelWidget, self).__init__()

        self.form = form
        self.set_zoom(10)
        self.maxPixelsPerLine = 64
        self.maxPixelsTotal = 0
        self.prev_mouse_y = 0
        self.key = None
        self.buffers = None
        self.offs = 0
        self.base = 0
        self.fm = None
        self.filter_idx = 0
        self.mouseOffs = 0
        self.sync = True
        self.bh = bufhandler
        self.mouse_abs_x = 0
        self.mouse_abs_y = 0
        self.elemX = 0
        self.elemY = 0
        self.rect_x = 0
        self.rect_x_width = 0
        self.lock_width = False
        self.lock_sync = False
        self.link_pixel = True
        self.highlight_cursor = False
        self.render_data = True
        self.cur_formatter_idx = 0
        self.max_formatters = 2

        self.setMouseTracking(True)
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.sh = SignalHandler()
        self.statechanged = self.sh.pw_statechanged
        self.next_filter = self.sh.pw_next_filter
        self.prev_filter = self.sh.pw_prev_filter

        self.qp = QPainter()

        self.show()

    def paintEvent(self, event):
        if not self.fm:
            return

        # set leftmost x-coordinate of graph
        zoom_level = self.get_zoom()
        self.rect_x_width = self.get_width() * zoom_level
        self.rect_x = (self.rect().width() / 2) - (self.rect_x_width / 2)

        self.qp.begin(self)

        # what is a good default font for OSX/Linux?
        self.qp.setFont(QFont(FONT_DEFAULT))

        # fill background
        self.qp.fillRect(self.rect(), Qt.black)

        content_addr = content_size = None
        if self.fm.support_selection:
            selected, start, end = ida_kernwin.read_range_selection(None)
            if selected:
                content_addr = start  #min(start, end)
                content_size = end - start  #max(start, end) - content_addr

        # use colorfilter to render image
        img = self.render_image(addr=content_addr, buf_size=content_size)

        if img:
            """
            if zoom_level > 6:
                opacity = self.qp.opacity()
                full_opacity_zoom = 40.0
                cur_opacity = (1.0 - (full_opacity_zoom - float(min(zoom_level-1, full_opacity_zoom)))/full_opacity_zoom)
                self.qp.setOpacity(1.0-cur_opacity)
            """
            # draw image
            self.qp.drawImage(
                QRect(
                    QPoint(self.rect_x, 0),
                    QPoint(self.rect_x + self.get_width() * zoom_level,
                           (self.get_pixels_total() / self.get_width()) *
                           zoom_level)), img)

            # TODO: pen color contrast
            # TODO: data export: render data
            # TODO: default fonts / OS?
            # TODO: optimization
            # FIXME: there's a bug with gaps/unmapped buffers
            if self.render_data and not self.fm.disable_data and zoom_level > 6:
                self.qp.setPen(QColor(Qt.white))
                fontsize = self.qp.font().pointSize()
                font = self.qp.font()

                font.setPointSize(zoom_level / 3)
                self.qp.setFont(font)

                opacity = self.qp.opacity()
                full_opacity_zoom = 28
                cur_opacity = (
                    1.0 - (full_opacity_zoom -
                           float(min(zoom_level - 1, full_opacity_zoom))) /
                    full_opacity_zoom)
                self.qp.setOpacity(cur_opacity)

                m = self.qp.fontMetrics()
                x = y = 0
                num_pixels_per_row = self.get_width()

                if self.cur_formatter_idx == 0:
                    sample = "%c" % (ord('X'))
                    cwidth = m.width(sample)
                    cheight = m.height()

                    for mapped, buf in self.buffers:
                        for i in range(len(buf)):
                            if mapped:
                                b = ord(buf[i])
                                data = "%c" % (chr(b) if b in range(
                                    0x20, 0x7E) else ".")

                                self.qp.drawStaticText(
                                    self.rect_x + x * zoom_level +
                                    (zoom_level - cwidth) / 2, y * zoom_level +
                                    (zoom_level - cheight) / 2,
                                    QStaticText(data))

                            x = (i + 1) % num_pixels_per_row
                            if not x:
                                y = y + 1

                elif self.cur_formatter_idx == 1:
                    sample = "%02X" % (ord('X'))
                    cwidth = m.width(sample)
                    cheight = m.height()

                    for mapped, buf in self.buffers:
                        for i in range(len(buf)):
                            if mapped:
                                data = "%02X" % ord(buf[i])

                                self.qp.drawStaticText(
                                    self.rect_x + x * zoom_level +
                                    (zoom_level - cwidth) / 2, y * zoom_level +
                                    (zoom_level - cheight) / 2,
                                    QStaticText(data))

                            x = (i + 1) % num_pixels_per_row
                            if not x:
                                y = y + 1

                self.qp.setOpacity(opacity)
                font.setPointSize(fontsize)
                self.qp.setFont(font)

        if self.show_address_range and self.fm.link_pixel:
            self.render_slider(addr=content_addr, buf_size=content_size)

        # get and draw annotations and pointers
        annotations = self.fm.on_get_annotations(
            content_addr if content_addr else self.get_address(),
            self.get_pixels_total(), self.mouseOffs)

        if annotations:
            self.render_annotations(annotations)

        self.qp.end()
        return

    def render_slider(self, addr=None, buf_size=None):
        if addr is None or buf_size is None:
            addr = self.base + self.offs
            buf_size = self.get_pixels_total()

        lowest_ea = ida_idaapi.get_inf_structure().get_minEA()
        highest_ea = ida_idaapi.get_inf_structure().get_maxEA()
        start_offs = addr - lowest_ea
        addr_space = highest_ea - lowest_ea

        perc_s = float(start_offs) / float(addr_space)
        perc_e = float(start_offs + buf_size) / float(addr_space)

        bar_width = 20

        spaces_bar = 5
        bar_x = self.rect_x - spaces_bar - bar_width
        bar_y = 5
        bar_height = self.rect().height() - 2 * bar_y
        self.qp.fillRect(bar_x, bar_y, bar_width, bar_height, QColor(0x191919))

        slider_offs_s = int(round(perc_s * bar_height))
        slider_offs_e = int(round(perc_e * bar_height))

        spaces_slider = 1
        slider_x = bar_x + spaces_slider
        slider_y = bar_y + slider_offs_s
        slider_width = bar_width - 2 * spaces_slider
        # limit slider height to bar_height
        slider_height = max(
            min(slider_offs_e - slider_offs_s,
                bar_height - (slider_y - bar_y)), 4)

        self.qp.fillRect(slider_x, slider_y, slider_width, slider_height,
                         QColor(0x404040))

        # draw addresses
        top = '%X:' % self.get_address()
        bottom = '%X' % (self.get_address() +
                         ((self.get_pixels_total() / self.get_width()) - 1) *
                         self.get_width())
        self.qp.setPen(QColor(0x808080))
        self.qp.drawText(
            self.rect_x - self.qp.fontMetrics().width(top) - bar_width -
            2 * spaces_bar,
            self.qp.fontMetrics().height(), top)
        self.qp.drawText(
            self.rect_x - self.qp.fontMetrics().width(bottom) - bar_width -
            2 * spaces_bar,
            self.rect().height() - self.qp.fontMetrics().height() / 2, bottom)
        return

    def render_image(self, addr=None, buf_size=None, cursor=True):
        size = self.size()
        self.maxPixelsTotal = self.get_width() * (size.height() /
                                                  self.pixelSize)
        if addr is None or buf_size is None:
            addr = self.base + self.offs
            buf_size = self.get_pixels_total()

        self.buffers = self.bh.get_buffers(addr, buf_size)
        img = QImage(self.get_width(),
                     size.height() / self.pixelSize, QImage.Format_RGB32)
        pixels = self.fm.on_process_buffer(self.buffers, addr,
                                           self.get_pixels_total(),
                                           self.mouseOffs)

        x = y = 0
        # transparency effect for unmapped bytes
        transparency_dark = [qRgb(0x2F, 0x4F, 0x4F), qRgb(0x00, 0x00, 0x00)]
        transparency_err = [qRgb(0x7F, 0x00, 0x00), qRgb(0x33, 0x00, 0x00)]
        for mapped, pix in pixels:
            if not mapped:
                if pix is None:
                    pix = transparency_dark[(x & 2 != 0) ^ (y & 2 != 0)]
            img.setPixel(x, y, pix)

            x = (x + 1) % self.get_width()
            if not x:
                y = y + 1

        if len(pixels) != self.get_pixels_total():
            for i in xrange(self.get_pixels_total() - len(pixels)):
                pix = transparency_err[(x & 2 != 0) ^ (y & 2 != 0)]
                img.setPixel(x, y, pix)
                x = (x + 1) % self.get_width()
                if not x:
                    y = y + 1

        if ((cursor and self.fm.highlight_cursor)
                and self.mouse_abs_x >= self.rect_x
                and self.mouse_abs_x < self.rect_x + self.rect_x_width):

            coords = self.get_coords_by_address(self.get_cursor_address())
            if coords:
                x, y = coords
            else:
                x = self.get_elem_x()
                y = self.get_elem_y()
            p = QPoint(x, y)
            img.setPixel(p, ~(img.pixelColor(p)).rgb())

        return img

    def render_annotations(self, annotations=[]):
        a_offs = 20
        base_x = self.rect_x + self.get_width() * self.pixelSize + a_offs + 10
        base_y = self.qp.fontMetrics().height()
        offs_x = 5
        offs_y = base_y

        for coords, arr_color, ann, txt_color in annotations:
            # draw arrow (experimental / WIP)
            self.qp.setPen(
                QColor(Qt.white if txt_color is None else txt_color))
            self.qp.drawText(base_x + 10, (base_y + offs_y) / 2, ann)
            target_x = target_y = None

            if coords:
                if isinstance(coords, tuple):
                    target_x, target_y = coords
                else:
                    ptr = self.get_coords_by_address(coords)
                    if ptr:
                        target_x, target_y = ptr

                if target_x is not None and target_y is not None:
                    target_x *= self.get_zoom()
                    target_y *= self.get_zoom()

                    self.qp.setPen(
                        QColor(Qt.white if arr_color is None else arr_color))
                    path = QPainterPath()
                    path.moveTo(base_x + offs_x,
                                (base_y + offs_y) / 2 - base_y / 2)

                    path.lineTo(base_x + offs_x - 4 - a_offs,
                                (base_y + offs_y) / 2 - base_y / 2)  # left
                    path.lineTo(base_x + offs_x - 4 - a_offs,
                                ((target_y / 10) * 9) +
                                self.get_zoom() / 2)  # down
                    path.lineTo(self.rect_x + target_x + self.get_zoom() / 2,
                                ((target_y / 10) * 9) +
                                self.get_zoom() / 2)  # left
                    path.lineTo(self.rect_x + target_x + self.get_zoom() / 2,
                                target_y + self.get_zoom() / 2)  # down
                    a_offs = max(a_offs - 2, 0)
                    self.qp.drawPath(path)
                else:
                    if not isinstance(coords, tuple):
                        direction = self.get_target_direction(coords)
                        if direction:
                            self.qp.setPen(
                                QColor(Qt.white
                                       if arr_color is None else arr_color))
                            m = self.qp.fontMetrics()
                            dirhint = ['', '<<', '>>'][direction]
                            cwidth = m.width("%s" % (dirhint))
                            self.qp.drawText(base_x - cwidth,
                                             (base_y + offs_y) / 2, dirhint)

            offs_y += 2 * base_y + 5
        return

    # functions that can be called by filters
    # must no be called from within on_process_buffer()
    def on_filter_request_update(self, ea=None, center=True):
        if not ea:
            self.repaint()
        else:
            curea = self.get_address()
            if ea < curea or ea >= curea + self.get_pixels_total():
                # TODO: verify that ea is valid after following operation
                if center:
                    ea -= self.get_pixels_total() / 2
                self.set_addr(ea)
            else:
                self.repaint()

    def on_filter_update_zoom(self, zoom):
        self.set_zoom(zoom)
        return

    def on_filter_update_zoom_delta(self, delta):
        self.set_zoom_delta(delta)
        return

    # end of functions that can be called by filters

    def show_help(self):
        ida_kernwin.info("%s" % PLUGIN_HELP)

    def keyPressEvent(self, event):
        if self.key is None:
            self.key = event.key()
        return

    def keyReleaseEvent(self, event):
        update = False
        key = event.key()
        modifiers = event.modifiers()

        shift_pressed = ((modifiers & Qt.ShiftModifier) == Qt.ShiftModifier)
        ctrl_pressed = ((modifiers & Qt.ControlModifier) == Qt.ControlModifier)

        if key == Qt.Key_F1 and ctrl_pressed:
            self.show_help()

        elif key == Qt.Key_G:
            addr = ask_addr(self.base + self.offs, 'Jump to address')
            if addr is not None:
                if self.sync:
                    ida_kernwin.jumpto(addr)
                else:
                    minea = ida_idaapi.get_inf_structure().get_minEA()
                    maxea = ida_idaapi.get_inf_structure().get_maxEA()
                    dst = min(max(addr, minea), maxea)
                    self.set_addr(dst)

        elif key == Qt.Key_S:
            if not self.fm.lock_sync:
                self.set_sync_state(not self.get_sync_state())
                update = True

        elif key == Qt.Key_T:
            self.render_data = not self.render_data
            self.repaint()

        elif key == Qt.Key_D:
            self.cur_formatter_idx = (self.cur_formatter_idx +
                                      1) % self.max_formatters
            self.repaint()

        elif key == Qt.Key_N:
            self.next_filter.emit()

        elif key == Qt.Key_B:
            self.prev_filter.emit()

        elif key == Qt.Key_F2:
            hlp = self.fm.help
            if hlp is None:
                hlp = 'Help unavailable'
            ida_kernwin.info('%s\n\n' % hlp)

        elif key == Qt.Key_F12:
            img = self.render_image(cursor=False)
            img = img.scaled(img.width() * self.pixelSize,
                             img.height() * self.pixelSize, Qt.KeepAspectRatio,
                             Qt.FastTransformation)
            done = False
            i = 0
            while not done:
                fname = 'IDACyber_%04d.bmp' % i
                if not os.path.isfile(fname):
                    if img.save(fname):
                        ida_kernwin.msg('File exported to %s\n' % fname)
                    else:
                        ida_kernwin.warning(
                            'Error exporting screenshot to %s.' % fname)
                    done = True
                i += 1
                if i > 40:
                    ida_kernwin.warning('Aborted. Error exporting screenshot.')
                    break

        elif key == Qt.Key_PageDown:
            self.set_offset_delta(-self.get_pixels_total())
            update = True

        elif key == Qt.Key_PageUp:
            self.set_offset_delta(self.get_pixels_total())
            update = True

        elif key == Qt.Key_Down:
            if shift_pressed:
                self.set_offset_delta(-1)
            else:
                self.set_offset_delta(-self.get_width())
            update = True

        elif key == Qt.Key_Up:
            if shift_pressed:
                self.set_offset_delta(1)
            else:
                self.set_offset_delta(self.get_width())
            update = True

        elif key == Qt.Key_Plus:
            if ctrl_pressed:
                self.set_zoom_delta(1)
            update = True

        elif key == Qt.Key_Minus:
            if ctrl_pressed:
                self.set_zoom_delta(-1)
            update = True

        self.key = None

        if update:
            if self.get_sync_state():
                ida_kernwin.jumpto(self.base + self.offs)
                self.activateWindow()
                self.setFocus()
            self.statechanged.emit()
            self.repaint()

        return

    def mouseReleaseEvent(self, event):
        self.prev_mouse_y = event.pos().y()
        self.fm.on_mb_click(event, self.get_address(), self.get_pixels_total(),
                            self.mouseOffs)

        if self.get_sync_state():
            ida_kernwin.jumpto(self.base + self.offs)
            self.activateWindow()
            self.setFocus()
            self.statechanged.emit()
        return

    def mouseDoubleClickEvent(self, event):
        if self.link_pixel and event.button() == Qt.LeftButton:
            addr = self.base + self.offs + self._get_offs_by_pos(event.pos())
            ida_kernwin.jumpto(addr)
        return

    def wheelEvent(self, event):
        delta = event.angleDelta().y() / 120

        # zoom
        if self.key == Qt.Key_Control:
            self.set_zoom_delta(delta)

        # width
        elif self.key == Qt.Key_X:
            if not self.lock_width:
                self.set_width_delta(delta)

        # offset (fine)
        elif self.key == Qt.Key_Shift:
            self.set_offset_delta(delta)

            if self.get_sync_state():
                ida_kernwin.jumpto(self.base + self.offs)
                self.activateWindow()
                self.setFocus()

        elif self.key == Qt.Key_H:
            if not self.lock_width:
                less = delta < 0
                w = -8 if less else 8
                self.set_width((self.get_width() & 0xFFFFFFF8) + w)

        # offset (coarse)
        else:
            self.set_offset_delta(delta * self.get_width())

            if self.get_sync_state():
                ida_kernwin.jumpto(self.base + self.offs)
                self.activateWindow()
                self.setFocus()

        self.statechanged.emit()
        self.repaint()
        return

    def mouseMoveEvent(self, event):
        x = event.pos().x()
        y = event.pos().y()
        within_graph = (x >= self.rect_x
                        and x < self.rect_x + self.rect_x_width)

        if within_graph:
            if event.buttons() == Qt.NoButton:
                self._update_mouse_coords(event.pos())
                self.mouseOffs = self._get_offs_by_pos(event.pos())

                if self.link_pixel and self.highlight_cursor:
                    highlight_item(
                        ida_bytes.get_item_head(self.get_cursor_address()))
                elif self.highlight_cursor:
                    unhighlight_item()

                self.setToolTip(
                    self.fm.on_get_tooltip(self.get_address(),
                                           self.get_pixels_total(),
                                           self.mouseOffs))

            # zoom
            elif self.key == Qt.Key_Control:
                self.set_zoom_delta(-1 if y > self.prev_mouse_y else 1)

            # width
            elif self.key == Qt.Key_X:
                if not self.lock_width:
                    self.set_width_delta(-1 if y > self.prev_mouse_y else 1)

            elif self.key == Qt.Key_H:
                if not self.lock_width:
                    less = y > self.prev_mouse_y
                    delta = -16 if less else 16
                    self.set_width((self.get_width() & 0xFFFFFFF0) + delta)

            # scrolling (offset)
            elif y != self.prev_mouse_y:
                # offset (fine)
                delta = y - self.prev_mouse_y

                # offset (coarse)
                if self.key != Qt.Key_Shift:
                    delta *= self.get_width()

                self.set_offset_delta(delta)

            self.prev_mouse_y = y
            self.x = x
            self.statechanged.emit()
            self.repaint()
        return

    def set_sync_state(self, sync):
        self.sync = sync

    def get_sync_state(self):
        return self.sync

    def get_filter_idx(self):
        return self.filter_idx

    def set_filter(self, fltobj, idx):
        if self.fm:
            self.fm.on_deactivate()
        if fltobj:
            self.fm = fltobj
            """load filter config"""
            self.set_sync_state(self.fm.sync)
            self.lock_width = self.fm.lock_width
            self.set_width(self.fm.width)
            self.lock_sync = self.fm.lock_sync
            self.show_address_range = self.fm.show_address_range
            # disabled for now
            # self.set_zoom(self.fm.zoom)
            self.link_pixel = self.fm.link_pixel
            self.highlight_cursor = self.fm.highlight_cursor
            self.statechanged.emit()
            """load filter config end"""

            self.fm.on_activate(idx)
            self.filter_idx = idx
            unhighlight_item()
            self.repaint()

    def set_addr(self, ea, new_cursor=None):
        base = self.bh.get_base(ea)

        self._set_base(base)
        self._set_offs(ea - base)

        if new_cursor:
            self.set_cursor_address(new_cursor)
            if self.highlight_cursor:
                highlight_item(ea)

        self.repaint()

    def get_zoom(self):
        return self.pixelSize

    def set_zoom(self, zoom):
        self.pixelSize = zoom

    def set_zoom_delta(self, dzoom):
        self.set_zoom(max(1, self.pixelSize + dzoom))
        return

    def get_width(self):
        return self.maxPixelsPerLine

    def get_pixels_total(self):
        return self.maxPixelsTotal

    def get_address(self):
        return self.base + self.offs

    def get_cursor_address(self):
        return self.get_address() + self.mouseOffs

    def set_cursor_address(self, ea):
        self.mouseOffs = ea - self.get_address()

    def get_coords_by_address(self, address):
        base = self.get_address()
        # if address is visible in current window
        if address >= base and address < base + self.get_pixels_total():
            offs = address - base
            x = offs % self.get_width()
            y = offs / (self.get_width())
            return (x, y)
        return None

    def get_target_direction(self, address):
        base = self.get_address()
        # if address is visible in current window
        direction = None
        if address >= base and address < base + self.get_pixels_total():
            direction = 0
        elif address < base:
            direction = 1
        else:
            direction = 2
        return direction

    def set_width(self, width):
        self.maxPixelsPerLine = max(1, width)

    def set_width_delta(self, dwidth):
        self.maxPixelsPerLine = max(1, self.maxPixelsPerLine + dwidth)

    def set_offset_delta(self, doffs):
        newea = self.base + self.offs - doffs
        minea = ida_idaapi.get_inf_structure().get_minEA()
        maxea = ida_idaapi.get_inf_structure().get_maxEA()
        if doffs < 0:
            delta = doffs if newea < maxea else doffs - (maxea - newea)
        else:
            delta = doffs if newea >= minea else doffs - (minea - newea)
        self._set_offs(self.offs - delta)

    def _get_offs_by_pos(self, pos):
        elemX = self.get_elem_x()
        elemY = self.get_elem_y()
        offs = elemY * self.get_width() + elemX
        return offs

    def _update_mouse_coords(self, pos):
        x = pos.x()
        y = pos.y()
        self.mouse_abs_x = x
        self.mouse_abs_y = y

        self.elemX = max(
            0,
            min((max(0, x - self.rect_x)) / self.pixelSize,
                self.get_width() - 1))
        self.elemY = min(y / self.pixelSize,
                         self.maxPixelsTotal / self.get_width() - 1)

    def get_elem_x(self):
        return self.elemX

    def get_elem_y(self):
        return self.elemY

    def _set_offs(self, offs):
        self.offs = offs

    def _set_base(self, ea):
        self.base = ea
Exemple #12
0
    def on_frame_ready(self, frame: QImage, info, instances):
        self.process_results(instances)
        video = self.ui.video
        table = self.ui.infoTable
        origin_pixmap = QPixmap.fromImage(frame)
        painter = QPainter()
        pixmap = origin_pixmap.scaled(video.width(), video.height(),
                                      Qt.KeepAspectRatio)
        painter.begin(pixmap)
        width_scale = pixmap.width() / origin_pixmap.width()
        height_scale = pixmap.height() / origin_pixmap.height()

        def translate_bbox(bbox):
            return [
                width_scale * bbox[0], height_scale * bbox[1],
                width_scale * bbox[2], height_scale * bbox[3]
            ]

        font = painter.font()
        font.setPointSize(FONT_SIZE)
        painter.setFont(font)
        for instance in instances:
            color = instance['instance_color']
            painter.setPen(QPen(QColor(color), 4))
            bbox = translate_bbox(instance['instance_bbox'])
            painter.drawRect(bbox[0], bbox[1], bbox[2] - bbox[0],
                             bbox[3] - bbox[1])
            if instance['face'] is not None:
                painter.setPen(QPen(QColor(instance['face_color']), 2))
                bbox = translate_bbox(instance['face_bbox'])
                painter.drawRect(bbox[0], bbox[1], bbox[2] - bbox[0],
                                 bbox[3] - bbox[1])
        for instance in instances:
            bbox = translate_bbox(instance['instance_bbox'])
            attributes = {
                **instance['attributes'],
                'ID':
                instance['instance_name'] or str(instance['instance'])[:8],
            }
            height = len(attributes) * (FONT_SIZE +
                                        FONT_SPACE) + 2 * FONT_SPACE
            top = bbox[1] - height
            if instance['blacklist'] is not None:
                background_color = QColor(0xff0000)
            else:
                background_color = QColor(0xffffff)
            background_color.setAlphaF(0.5)
            painter.fillRect(bbox[0], top, 150, height, background_color)
            painter.setPen(QPen(QColor(0x0)))
            top += FONT_SPACE
            for key, value in attributes.items():
                painter.drawStaticText(bbox[0] + FONT_SPACE, top,
                                       QStaticText('%s: %s' % (key, value)))
                top += FONT_SIZE + FONT_SPACE
        for instance in instances:
            if instance['face'] is None:
                continue
            bbox = translate_bbox(instance['face_bbox'])
            attributes = {
                'ID': instance['face_name'] or str(instance['face'])[:8],
            }
            if instance['blacklist'] is not None:
                attributes['黑名单'] = instance['blacklist_name'] or str(
                    instance['blacklist'])[:8]
                background_color = QColor(0xff0000)
            else:
                background_color = QColor(0xffffff)
            height = len(attributes) * (FONT_SIZE +
                                        FONT_SPACE) + 2 * FONT_SPACE
            top = bbox[3]
            background_color.setAlphaF(0.5)
            painter.fillRect(bbox[0], top, 100, height, background_color)
            painter.setPen(QPen(QColor(0x0)))
            top += FONT_SPACE
            for key, value in attributes.items():
                painter.drawStaticText(bbox[0] + FONT_SPACE, top,
                                       QStaticText('%s: %s' % (key, value)))
                top += FONT_SIZE + FONT_SPACE
        painter.end()
        video.setPixmap(pixmap)
        table.item(VideoInfoRow.Frame,
                   1).setText(str(info[VideoInfoRow.Frame]))
        table.item(VideoInfoRow.Time,
                   1).setText('%.2f' % info[VideoInfoRow.Time])
        table.item(VideoInfoRow.Progress,
                   1).setText('%.2f' % (info[VideoInfoRow.Progress] * 100))
        time = math.floor(info[VideoInfoRow.Time] / 1000)
        if self.ui.playSlider.isEnabled():
            self.ui.playSlider.blockSignals(True)
            self.ui.playSlider.setValue(info[VideoInfoRow.Frame] - 1)
            self.ui.playSlider.blockSignals(False)
        self.ui.progressText.setText(
            '%02d:%02d/%s %d/%d' %
            (time // 60, time % 60, self.total_time_text,
             info[VideoInfoRow.Frame], self.total_frames))