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()
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