Beispiel #1
0
    def __init__(self, size, parent=None):
        super(PadNavigator, self).__init__(parent)

        self.form = Ui_Form()

        splash = SplashItem()
        splash.setZValue(1)

        pad = FlippablePad(size)
        flipRotation = QGraphicsRotation(pad)
        xRotation = QGraphicsRotation(pad)
        yRotation = QGraphicsRotation(pad)
        flipRotation.setAxis(Qt.YAxis)
        xRotation.setAxis(Qt.YAxis)
        yRotation.setAxis(Qt.XAxis)
        pad.setTransformations([flipRotation, xRotation, yRotation])

        backItem = QGraphicsProxyWidget(pad)
        widget = QWidget()
        self.form.setupUi(widget)
        self.form.hostName.setFocus()
        backItem.setWidget(widget)
        backItem.setVisible(False)
        backItem.setFocus()
        backItem.setCacheMode(QGraphicsItem.ItemCoordinateCache)
        r = backItem.rect()
        backItem.setTransform(QTransform().rotate(180, Qt.YAxis).translate(
            -r.width() / 2, -r.height() / 2))

        selectionItem = RoundRectItem(QRectF(-60, -60, 120, 120),
                                      QColor(Qt.gray), pad)
        selectionItem.setZValue(0.5)

        smoothSplashMove = QPropertyAnimation(splash)
        smoothSplashOpacity = QPropertyAnimation(splash)
        smoothSplashMove.setEasingCurve(QEasingCurve.InQuad)
        smoothSplashMove.setDuration(250)
        smoothSplashOpacity.setDuration(250)

        smoothXSelection = QPropertyAnimation(selectionItem)
        smoothYSelection = QPropertyAnimation(selectionItem)
        smoothXRotation = QPropertyAnimation(xRotation)
        smoothYRotation = QPropertyAnimation(yRotation)
        smoothXSelection.setDuration(125)
        smoothYSelection.setDuration(125)
        smoothXRotation.setDuration(125)
        smoothYRotation.setDuration(125)
        smoothXSelection.setEasingCurve(QEasingCurve.InOutQuad)
        smoothYSelection.setEasingCurve(QEasingCurve.InOutQuad)
        smoothXRotation.setEasingCurve(QEasingCurve.InOutQuad)
        smoothYRotation.setEasingCurve(QEasingCurve.InOutQuad)

        smoothFlipRotation = QPropertyAnimation(flipRotation)
        smoothFlipScale = QPropertyAnimation(pad)
        smoothFlipXRotation = QPropertyAnimation(xRotation)
        smoothFlipYRotation = QPropertyAnimation(yRotation)
        flipAnimation = QParallelAnimationGroup(self)
        smoothFlipScale.setDuration(500)
        smoothFlipRotation.setDuration(500)
        smoothFlipXRotation.setDuration(500)
        smoothFlipYRotation.setDuration(500)
        smoothFlipScale.setEasingCurve(QEasingCurve.InOutQuad)
        smoothFlipRotation.setEasingCurve(QEasingCurve.InOutQuad)
        smoothFlipXRotation.setEasingCurve(QEasingCurve.InOutQuad)
        smoothFlipYRotation.setEasingCurve(QEasingCurve.InOutQuad)
        smoothFlipScale.setKeyValueAt(0, 1.0)
        smoothFlipScale.setKeyValueAt(0.5, 0.7)
        smoothFlipScale.setKeyValueAt(1, 1.0)
        flipAnimation.addAnimation(smoothFlipRotation)
        flipAnimation.addAnimation(smoothFlipScale)
        flipAnimation.addAnimation(smoothFlipXRotation)
        flipAnimation.addAnimation(smoothFlipYRotation)

        setVariablesSequence = QSequentialAnimationGroup()
        setFillAnimation = QPropertyAnimation(pad)
        setBackItemVisibleAnimation = QPropertyAnimation(backItem)
        setSelectionItemVisibleAnimation = QPropertyAnimation(selectionItem)
        setFillAnimation.setDuration(0)
        setBackItemVisibleAnimation.setDuration(0)
        setSelectionItemVisibleAnimation.setDuration(0)
        setVariablesSequence.addPause(250)
        setVariablesSequence.addAnimation(setBackItemVisibleAnimation)
        setVariablesSequence.addAnimation(setSelectionItemVisibleAnimation)
        setVariablesSequence.addAnimation(setFillAnimation)
        flipAnimation.addAnimation(setVariablesSequence)

        stateMachine = QStateMachine(self)
        splashState = QState(stateMachine)
        frontState = QState(stateMachine)
        historyState = QHistoryState(frontState)
        backState = QState(stateMachine)

        frontState.assignProperty(pad, "fill", False)
        frontState.assignProperty(splash, "opacity", 0.0)
        frontState.assignProperty(backItem, "visible", False)
        frontState.assignProperty(flipRotation, "angle", 0.0)
        frontState.assignProperty(selectionItem, "visible", True)

        backState.assignProperty(pad, "fill", True)
        backState.assignProperty(backItem, "visible", True)
        backState.assignProperty(xRotation, "angle", 0.0)
        backState.assignProperty(yRotation, "angle", 0.0)
        backState.assignProperty(flipRotation, "angle", 180.0)
        backState.assignProperty(selectionItem, "visible", False)

        stateMachine.addDefaultAnimation(smoothXRotation)
        stateMachine.addDefaultAnimation(smoothYRotation)
        stateMachine.addDefaultAnimation(smoothXSelection)
        stateMachine.addDefaultAnimation(smoothYSelection)
        stateMachine.setInitialState(splashState)

        anyKeyTransition = QEventTransition(self, QEvent.KeyPress, splashState)
        anyKeyTransition.setTargetState(frontState)
        anyKeyTransition.addAnimation(smoothSplashMove)
        anyKeyTransition.addAnimation(smoothSplashOpacity)

        enterTransition = QKeyEventTransition(self, QEvent.KeyPress,
                                              Qt.Key_Enter, backState)
        returnTransition = QKeyEventTransition(self, QEvent.KeyPress,
                                               Qt.Key_Return, backState)
        backEnterTransition = QKeyEventTransition(self, QEvent.KeyPress,
                                                  Qt.Key_Enter, frontState)
        backReturnTransition = QKeyEventTransition(self, QEvent.KeyPress,
                                                   Qt.Key_Return, frontState)
        enterTransition.setTargetState(historyState)
        returnTransition.setTargetState(historyState)
        backEnterTransition.setTargetState(backState)
        backReturnTransition.setTargetState(backState)
        enterTransition.addAnimation(flipAnimation)
        returnTransition.addAnimation(flipAnimation)
        backEnterTransition.addAnimation(flipAnimation)
        backReturnTransition.addAnimation(flipAnimation)

        columns = size.width()
        rows = size.height()
        stateGrid = []
        for y in range(rows):
            stateGrid.append([QState(frontState) for _ in range(columns)])

        frontState.setInitialState(stateGrid[0][0])
        selectionItem.setPos(pad.iconAt(0, 0).pos())

        for y in range(rows):
            for x in range(columns):
                state = stateGrid[y][x]

                rightTransition = QKeyEventTransition(self, QEvent.KeyPress,
                                                      Qt.Key_Right, state)
                leftTransition = QKeyEventTransition(self, QEvent.KeyPress,
                                                     Qt.Key_Left, state)
                downTransition = QKeyEventTransition(self, QEvent.KeyPress,
                                                     Qt.Key_Down, state)
                upTransition = QKeyEventTransition(self, QEvent.KeyPress,
                                                   Qt.Key_Up, state)

                rightTransition.setTargetState(stateGrid[y][(x + 1) % columns])
                leftTransition.setTargetState(
                    stateGrid[y][((x - 1) + columns) % columns])
                downTransition.setTargetState(stateGrid[(y + 1) % rows][x])
                upTransition.setTargetState(stateGrid[((y - 1) + rows) %
                                                      rows][x])

                icon = pad.iconAt(x, y)
                state.assignProperty(xRotation, "angle", -icon.x() / 6.0)
                state.assignProperty(yRotation, "angle", icon.y() / 6.0)
                state.assignProperty(selectionItem, "x", icon.x())
                state.assignProperty(selectionItem, "y", icon.y())
                frontState.assignProperty(icon, "visible", True)
                backState.assignProperty(icon, "visible", False)

                setIconVisibleAnimation = QPropertyAnimation(icon)
                setIconVisibleAnimation.setDuration(0)
                setVariablesSequence.addAnimation(setIconVisibleAnimation)

        scene = QGraphicsScene(self)
        scene.setBackgroundBrush(
            QBrush(QPixmap(":/images/blue_angle_swirl.jpg")))
        scene.setItemIndexMethod(QGraphicsScene.NoIndex)
        scene.addItem(pad)
        scene.setSceneRect(scene.itemsBoundingRect())
        self.setScene(scene)

        sbr = splash.boundingRect()
        splash.setPos(-sbr.width() / 2, scene.sceneRect().top() - 2)
        frontState.assignProperty(splash, "y", splash.y() - 100.0)
        scene.addItem(splash)

        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setMinimumSize(50, 50)
        self.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)
        self.setCacheMode(QGraphicsView.CacheBackground)
        self.setRenderHints(QPainter.Antialiasing
                            | QPainter.SmoothPixmapTransform
                            | QPainter.TextAntialiasing)

        if QGLFormat.hasOpenGL():
            self.setViewport(QGLWidget(QGLFormat(QGL.SampleBuffers)))

        stateMachine.start()
Beispiel #2
0
    def loadState(self, dev, stateParam, stateID = ""):

        curExecContext = ScExecContext()
        curExecContext.stateMachine = self.stateMachine
        curHistoryState = None
        debug = True

        r = QXmlStreamReader(dev)

        while not r.atEnd():
            r.readNext()
            if r.isStartElement():
                logger.info("Element :<%s>", r.name())
                #
                # <scxml>
                #
                name = r.name().lower()
                if name == "scxml":

                    if stateID == "":
                        topLevelState = curState = stateParam
                        self.stateInfo[curState] = r.attributes().value("initial")
                        if curState == self.stateMachine:
                            pass
                #
                # <state> || <parallel>
                #
                elif name == "state" or name == "parallel":
                    inRoot = False
                    stateId = r.attributes().value("id")
                    newState = None
                    #
                    # Create state
                    #
                    if curState is not None:
                        logger.info("Creating state [%s] child of [%s]", stateId, curState.objectName())
                        type = QState.ExclusiveStates if name == "state" else QState.ParallelStates
                        newState = QState(type, curState)
                    #
                    # ???
                    #
                    elif stateId == stateID:
                        topLevelState = newState = stateParam

                    if newState is not None:
                        self.stateInfo[newState] = r.attributes().value("initial")
                        newState.setObjectName(stateId)
                        #
                        # initial state
                        #
                        if stateId is not "" and self.stateInfo[curState] == stateId:
                            if curState == self.stateMachine:
                                logger.info("Setting [%s] initial state to [%s]",
                                            self.stateMachine.objectName(),
                                            newState.objectName())
                                self.stateMachine.setInitialState(newState)
                            else:
                                logger.info("Setting [%s] initial state to [%s]",
                                            curState.objectName(),
                                            newState.objectName())
                                curState.setInitialState(newState)
                        #
                        # TODO implement src attribute management in state element
                        #
                        initialID = r.attributes().value("initial")
                        self.stateByID[stateId] = newState
                        curState = newState
                        curExecContext.state = newState

                        if debug:

                            # Add entry and exit log

                            curExecContext.script = 'logger.debug("[scxml] [debug] > Entering state: [' + stateId + ']")'
                            curExecContext.type = ScExecContext.StateEntry
                            curExecContext.applyScript()
                            curExecContext.script = 'logger.debug("[scxml] [debug] < Exiting state: [' + stateId + ']")'
                            curExecContext.type = ScExecContext.StateExit
                            curExecContext.applyScript()
                #
                # <initial>
                #
                elif name == "initial":
                    if curState is not None and self.stateInfo[curState] == "":
                        logger.info("Creating state [%s] child of [%s]", stateId, curState.objectName())
                        newState = QState(curState)
                        curState.setInitialState(newState)
                #
                # <history>
                #
                elif name == "history":
                    if curState is not None:
                        stateId = r.attributes().value("id")
                        type = r.attributes().value("type")
                        type = QHistoryState.ShallowHistory if type == "shallow" else QHistoryState.DeepHistory
                        curHistoryState = QHistoryState(type)
                        curHistoryState.setObjectName(stateId)
                        self.stateByID[stateId] = curHistoryState
                #
                # <final>
                #
                elif name == "final":
                    if curState is not None:
                        stateId = r.attributes().value("id")
                        f = QFinalState(curState)
                        f.setObjectName(stateId)
                        curExecContext.state = f
                        self.statesWithFinal.add(curState)
                        gp = curState.parentState()
                        if gp is not None:
                            if gp.childMode() == QState.ParallelStates:
                                self.statesWithFinal.add()
                        self.stateByID[stateId] = f

                        if debug:

                            # Add entry and exit log

                            curExecContext.script = 'logger.debug("[scxml] [debug] > Entering final state: [' + stateId + ']")'
                            curExecContext.type = ScExecContext.StateEntry
                            curExecContext.applyScript()
                            curExecContext.script = 'logger.debug("[scxml] [debug] < Exiting final state: [' + stateId + ']")'
                            curExecContext.type = ScExecContext.StateExit
                            curExecContext.applyScript()

                #
                # <script>
                #
                elif name == "script":
                    txt = r.readElementText()
                    #
                    # The SCXML Processor MUST evaluate any <script> element that is a child
                    # of <scxml> at document load time
                    #
                    if curExecContext.type == ScExecContext.Unknown and curState == topLevelState:
                        # TODO execute script
                        pass
                    else:
                        curExecContext.script += txt
                #
                # <log>
                #
                elif name == "log":
                    curExecContext.script += 'logger.' + r.attributes().value("level") + '("[' + \
                                             r.attributes().value("label") + '] [' +  \
                                             r.attributes().value("level") + '] ' + r.attributes().value("expr") + '")'
                #
                # <assign>
                #
                elif name == "assign":
                    pass
                #
                # <if>
                #
                elif name == "if":
                    pass
                #
                # <elseif>
                #
                elif name == "elseif":
                    pass
                #
                # <else>
                #
                elif name == "else":
                    pass
                #
                # <cancel>
                #
                elif name == "cancel":
                    pass
                #
                # <onentry>
                #
                elif name == "onentry":
                    curExecContext.type = ScExecContext.StateEntry
                    curExecContext.script = ""
                #
                # <onexit>
                #
                elif name == "onexit":
                    curExecContext.type = ScExecContext.StateExit
                    curExecContext.script = ""
                #
                # <raise>
                #
                elif name == "raise":
                    pass
                #
                # <send>
                #
                elif name == "send":
                    pass
                #
                # <invoke>
                #
                elif name == "invoke":
                    pass
                #
                # <transition>
                #
                elif name == "transition":
                    if curHistoryState is not None:
                        inf = ScHistoryInfo()
                        inf.hstate = curHistoryState
                        inf.defaultStateID = r.attributes().value("target")
                        self.historyInfo.append(inf)
                    else:
                        inf = ScTransitionInfo()
                        inf.targets = r.attributes().value("target").split() # TODO split targets
                        curExecContext.type = ScExecContext.Transition

                        curExecContext.script = ""
                        if debug:
                            curExecContext.script = 'logger.debug("[scxml] [debug] = Transitioning to: [' \
                                                    + ', '.join(inf.targets) + ']")' + '\n'


                        curTransitions = list()
                        inf.transitions = list()
                        self.transitionsInf.append(inf)

                        for pfx in r.attributes().value("event").split(' '):
                            sigTransition = None
                            if pfx == '':

                                # For eventless transition create QScxmlEventlessTransition transition

                                sigTransition = QScxmlEventlessTransition(self.stateMachine)

                            elif pfx.startswith("q-signal:"):

                                # For all q-signal event, add a QSxcmlSignalTransition

                                self.signalEvents.append(pfx)

                                # get object name (a.b.c) => a

                                objName = pfx[pfx.index(':')+1:pfx.index('.')]

                                # get object reference

                                obj = self.stateMachine.registeredObjects[objName]

                                # get signal reference

                                for attr in pfx[pfx.index('.')+1:].split('.'):
                                    sig = getattr(obj, attr)
                                    obj = sig

                                # create Signal transition

                                sigTransition = QScxmlSignalTransition(sig, self.stateMachine)

                            if sigTransition is not None:

                                # add condition to transition

                                sigTransition.setConditionExpression(r.attributes().value("cond"))

                                # add transition to current state

                                curState.addTransition(sigTransition)

                                # append sigTransition to transition info

                                inf.transitions.append(sigTransition)

                                # append sigTransition to curTransitions list

                                curTransitions.append(sigTransition)

                            else:
                                logger.error("Transition creation error")
            #
            # End element
            #
            elif r.isEndElement():
                name = r.name().lower()
                #
                # </state> or </parallel>
                #
                if name == "state" or name == "parallel":
                    if curState == topLevelState:
                        return
                    else:
                        curState = curState.parent()
                        curExecContext.state = curState
                #
                # </history>
                #
                elif name == "history":
                    curHistoryState = None
                #
                # </final>
                #
                elif name == "final":
                    curExecContext.state = curExecContext.state.parentState()
                #
                # </if>
                #
                elif name == "if":
                    pass
                #
                # </send> </raise>
                #
                elif name == "send" or name == "raise":
                    pass
                #
                # </onentry> </onexit> </scxml>
                #
                elif name == "onentry" or name == "onexit" or name == "scxml":
                    curExecContext.state = curState
                    curExecContext.type = ScExecContext.StateExit if name == "onexit" else ScExecContext.StateEntry
                    curExecContext.applyScript()
                    curExecContext.type = ScExecContext.Unknown
                    curExecContext.script = ""
                #
                # </transition>
                #
                elif name == "transition":
                    if curHistoryState is None:
                        curExecContext.transitions = curTransitions
                        curExecContext.type = ScExecContext.Transition
                        curExecContext.applyScript()
                        curExecContext.script = ""
                    curExecContext.type = ScExecContext.Unknown