Beispiel #1
0
 def overlayIndex(self):
     """
     :rtype: int
     """
     return gSettings.value('overlayIndex', 0)
Beispiel #2
0
 def overlayColor(self):
     """
     :rtype: QColor
     """
     return QColor(
         gSettings.value('overlayColor', qRgba(255, 255, 255, 255)))
Beispiel #3
0
def muteState():
    return gSettings.value('mute', 'False') == 'True'
Beispiel #4
0
    def __init__(self, timer=None, parent=None):
        super(CurveEditor, self).__init__(parent)
        self.setWindowTitle('CurveEditor')
        self.setObjectName('CurveEditor')

        self.__model = QStandardItemModel()
        self.__shot = None
        self.__timer = timer

        tools = hlayout(spacing=4.0)

        add = QPushButton(icons.get('Add Node'), '')
        add.setToolTip('Add channels')
        add.setStatusTip('Add channels')
        add.setIconSize(QSize(24, 24))
        add.clicked.connect(self._onAddChannel)
        tools.addWidget(add)

        delete = QPushButton(icons.get('Delete Node'), '')
        delete.setToolTip('Delete channels')
        delete.setStatusTip('Delete channels')
        delete.setIconSize(QSize(24, 24))
        delete.clicked.connect(self._onDeleteChannel)
        tools.addWidget(delete)

        # input fields to move keys around with exact numbers
        self.__relative = CheckBox()
        tools.addWidget(QLabel('Relative:'))
        tools.addWidget(self.__relative)
        self.__relative.setValue(
            (Qt.Unchecked, Qt.Checked,
             Qt.Checked)[int(gSettings.value('RelativeKeyInput', 0))])
        self.__relative.valueChanged.connect(
            functools.partial(gSettings.setValue, 'RelativeKeyInput'))

        self.__time = DoubleSpinBox()
        self.__time.setDecimals(4)
        tools.addWidget(QLabel('Time:'))
        tools.addWidget(self.__time)
        self.__time.setEnabled(False)
        self.__time.setFixedWidth(70)
        self.__time.editingFinished.connect(self.__onShiftSelectedKeyTimes)

        self.__value = DoubleSpinBox()
        self.__value.setDecimals(4)
        tools.addWidget(QLabel('Value:'))
        tools.addWidget(self.__value)
        self.__value.setEnabled(False)
        self.__value.setFixedWidth(70)
        self.__value.editingFinished.connect(self.__onShiftSelectedKeyValues)

        # when editing keys with the input fields I'm storing the initial reference poitn so all changes may be relative
        self.__unshiftedKeyValue = [0.0, 0.0]

        self.__snapping = EnumBox(
            ['1/1', '1/2', '1/4', '1/8', '1/16', '1/32', '1/64'])
        tools.addWidget(QLabel('Beat snap:'))
        tools.addWidget(self.__snapping)
        self.__snapping.setValue(int(gSettings.value('KeySnapSetting', 3)))
        self.__snapping.valueChanged.connect(
            functools.partial(gSettings.setValue, 'KeySnapSetting'))
        self.__snapping.valueChanged.connect(self.__updateSnapping)

        self.__tangentMode = TangentMode()
        tools.addWidget(self.__tangentMode)
        self.__tangentMode.valueChanged.connect(self.__setSelectedKeyTangents)
        # self.__tangentMode.tangentBrokenChanged.connect(self.__toggleBreakSelectedKeyTangents)

        positionKey = QPushButton(icons.get('Move'), '', self)
        positionKey.setToolTip('Key camera position into selection')
        positionKey.setStatusTip('Key camera position into selection')
        positionKey.setShortcut(QKeySequence(Qt.SHIFT + Qt.Key_I))
        tools.addWidget(positionKey)
        self.requestPositionKey = positionKey.clicked

        rotationKey = QPushButton(icons.get('3D Rotate'), '', self)
        rotationKey.setToolTip('Key camera rotation into selection')
        rotationKey.setStatusTip('Key camera rotation into selection')
        rotationKey.setShortcut(QKeySequence(Qt.SHIFT + Qt.Key_O))
        tools.addWidget(rotationKey)
        self.requestRotationKey = rotationKey.clicked

        dupe = QPushButton(icons.get('Duplicate-Keys-24'), '')
        dupe.setToolTip('Duplicate selected keys')
        dupe.setStatusTip('Duplicate selected keys')
        dupe.setIconSize(QSize(24, 24))
        dupe.clicked.connect(self.__onDuplicateSelectedKeys)
        tools.addWidget(dupe)

        tools.addStretch(1)

        self.__channels = QListView()
        self.__channels.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.__channels.setModel(self.__model)
        # can't rename channels
        self.__channels.setEditTriggers(QAbstractItemView.NoEditTriggers)

        self.__view = CurveView(timer, self)
        self.__view.setModel(self.__model, self.__channels.selectionModel())

        self.__time.editingFinished.connect(self.__view.repaint)
        self.__value.editingFinished.connect(self.__view.repaint)
        self.__updateSnapping(self.__snapping.value())

        def forwardFocus(event):
            self.__view.setFocus(Qt.MouseFocusReason)

        self.__channels.focusInEvent = forwardFocus
        self.__channels.selectionModel().selectionChanged.connect(
            self.__view.onChannelsChanged)
        self.__view.selectionChanged.connect(self.__onUpdateKeyEditor)

        widget = QSplitterState('CurveEditor/Channels', Qt.Horizontal)
        widget.addWidget(self.__channels)
        widget.addWidget(self.__view)
        widget.setStretchFactor(1, 1)
        widget.addWidget(self.__view.createUndoView())
        widget.addWidget(self.__view.createCameraUndoView())
        widget.setSizes([128, 128, 0, 0])

        layout = vlayout()
        self.setLayout(layout)

        layout.addLayout(tools)
        layout.addWidget(widget)
        layout.setStretch(1, 1)

        self.setEnabled(False)

        self.__channels.setContextMenuPolicy(Qt.CustomContextMenu)
        self.__channels.customContextMenuRequested.connect(
            self.__channelContextMenu)
        self.__channelMenu = QMenu()
        self.__copyAction = self.__channelMenu.addAction(
            'Copy selected channel(s)')
        self.__copyAction.triggered.connect(self.__copySelectedChannels)
        self.__pasteAction = self.__channelMenu.addAction('Paste channels')
        self.__pasteAction.triggered.connect(self.__pasteChannels)
        self.__pasteOverAction = self.__channelMenu.addAction(
            'Paste into selected channel')
        self.__pasteOverAction.triggered.connect(self.__pasteSelectedChannel)
        self.__clipboard = []
Beispiel #5
0
    def __init__(self):
        super(App, self).__init__(gSettings)
        self.setAnimated(False)
        month, day, year = time.strftime('%x').split('/')
        if month == '12':
            self.setWindowIcon(icons.get('Candy Cane'))
        else:
            self.setWindowIcon(icons.get('SqrMelon'))
        self.setWindowTitle('SqrMelon')
        self.setDockNestingEnabled(True)

        self.__menuBar = QMenuBar()
        self.setMenuBar(self.__menuBar)

        self.__dockWidgetMenu = QMenu('Components')

        self.__statusBar = QStatusBar()
        self.setStatusBar(self.__statusBar)

        self._timer = Timer()
        self.__shotsManager = ShotManager()
        self.__shotsManager.viewShotAction.connect(self.__onViewShot)
        self.__graphEditor = CurveEditor(self._timer)
        self.__shotsManager.currentChanged.connect(self.__graphEditor.setShot)
        self.__overlays = Overlays()
        self.__sceneView = SceneView(self.__shotsManager, self._timer, self.__overlays)
        self.__overlays.changed.connect(self.__sceneView.repaint)
        self._timer.timeChanged.connect(self.__setCurrentShot)
        self.__shotsManager.shotPinned.connect(self.__setCurrentShot)
        self.__shotsManager.shotsEnabled.connect(self.__setCurrentShot)
        self.__shotsManager.shotsDisabled.connect(self.__setCurrentShot)

        self.setCentralWidget(None)
        cameraView = Camera(self.__shotsManager, self.__graphEditor, self._timer)
        cameraView.cameraChanged.connect(self.__sceneView.repaint)
        self.__graphEditor.requestPositionKey.connect(cameraView.forwardPositionKey)
        self.__graphEditor.requestRotationKey.connect(cameraView.forwardRotationKey)
        self.__sceneView.setCamera(cameraView)
        self.__projectMenu = self.__menuBar.addMenu('&Project')
        self.__projectMenu.addAction('&New').triggered.connect(self.__onNewProject)
        self.__projectMenu.addAction('&Open').triggered.connect(self.__onOpenProject)
        save = self.__projectMenu.addAction('&Save')
        save.setShortcut(QKeySequence.Save)
        save.setShortcutContext(Qt.ApplicationShortcut)
        save.triggered.connect(self.__onCtrlS)
        self.__sceneList = SceneList()
        self.__shotsManager.findSceneRequest.connect(self.__sceneList.selectSceneWithName)
        self.__sceneList.requestCreateShot.connect(self.__shotsManager.createShot)
        self.__sceneList.setEnabled(False)
        self.__sceneList.setShotsManager(self.__shotsManager)

        self.__profiler = Profiler()

        self.timeSlider = TimeSlider(self._timer, self.__shotsManager)
        self.__shotsManager.shotChanged.connect(self.timeSlider.repaint)

        self._addDockWidget(self.__sceneList, where=Qt.TopDockWidgetArea)
        self._addDockWidget(self.__shotsManager, where=Qt.TopDockWidgetArea)
        viewDock = self._addDockWidget(self.__sceneView, '3D View', where=Qt.TopDockWidgetArea)
        logDock = self._addDockWidget(PyDebugLog.create(), 'Python log', where=Qt.TopDockWidgetArea)
        self.tabifyDockWidget(logDock, viewDock)

        self._addDockWidget(self.timeSlider, where=Qt.LeftDockWidgetArea)
        cameraDock = self._addDockWidget(cameraView, where=Qt.LeftDockWidgetArea)
        overlayDock = self._addDockWidget(self.__overlays, 'Overlays', Qt.LeftDockWidgetArea)
        self.tabifyDockWidget(overlayDock, cameraDock)

        self._addDockWidget(self.__graphEditor, where=Qt.BottomDockWidgetArea)
        self._addDockWidget(self.__profiler, where=Qt.BottomDockWidgetArea, direction=Qt.Vertical)

        self.__initializeProject()

        undoStack, cameraUndoStack = self.__graphEditor.undoStacks()
        undo = undoStack.createUndoAction(self, '&Undo')
        undo.setShortcut(QKeySequence.Undo)
        undo.setShortcutContext(Qt.ApplicationShortcut)

        redo = undoStack.createRedoAction(self, '&Redo')
        redo.setShortcuts(QKeySequence.Redo)
        redo.setShortcutContext(Qt.ApplicationShortcut)

        camUndo = cameraUndoStack.createUndoAction(self, 'Undo')
        camUndo.setShortcuts(QKeySequence('['))
        camUndo.setShortcutContext(Qt.ApplicationShortcut)

        camRedo = cameraUndoStack.createRedoAction(self, 'Redo')
        camRedo.setShortcuts(QKeySequence(']'))
        camRedo.setShortcutContext(Qt.ApplicationShortcut)

        camKey = QAction('&Key camera', self)
        camKey.setShortcuts(QKeySequence(Qt.Key_K))
        camKey.setShortcutContext(Qt.ApplicationShortcut)
        camKey.triggered.connect(cameraView.insertKey)

        camToggle = QAction('&Toggle camera control', self)
        camToggle.setShortcuts(QKeySequence(Qt.Key_T))
        camToggle.setShortcutContext(Qt.ApplicationShortcut)
        camToggle.triggered.connect(cameraView.toggle)

        camCopAnim = QAction('Snap came&ra to animation', self)
        camCopAnim.setShortcuts(QKeySequence(Qt.Key_R))
        camCopAnim.setShortcutContext(Qt.ApplicationShortcut)
        camCopAnim.triggered.connect(cameraView.copyAnim)

        self.__editMenu = self.__menuBar.addMenu('Edit')
        self.__editMenu.addAction(undo)
        self.__editMenu.addAction(redo)
        self.__editMenu.addAction(camUndo)
        self.__editMenu.addAction(camRedo)
        self.__editMenu.addSeparator()
        self.__editMenu.addAction(camKey)
        self.__editMenu.addAction(camToggle)
        self.__editMenu.addAction(camCopAnim)

        toolsMenu = self.__menuBar.addMenu('Tools')
        toolsMenu.addAction('Color Picker').triggered.connect(self.__colorPicker)

        lock = toolsMenu.addAction('Lock UI')
        lock.setCheckable(True)
        lock.toggled.connect(self.__toggleUILock)

        fs = toolsMenu.addAction('Full screen viewport')
        fs.setShortcut(Qt.Key_F11)
        fs.setShortcutContext(Qt.ApplicationShortcut)
        fs.triggered.connect(self.__fullScreenViewport)

        self.__previewMenu = toolsMenu.addMenu('Preview resolution')
        previewRadioGroup = QActionGroup(self)
        # add action & connect it to the setPreviewRes with right parameters
        hd = self.__previewMenu.addAction('1070p (HD)')
        hd.triggered.connect(functools.partial(self.__sceneView.setPreviewRes, 1920, 1080, 1.0))
        hd.setCheckable(True)
        hd.setActionGroup(previewRadioGroup)
        hdready = self.__previewMenu.addAction('720p')
        hdready.triggered.connect(functools.partial(self.__sceneView.setPreviewRes, 1280, 720, 1.0))
        hdready.setCheckable(True)
        hdready.setActionGroup(previewRadioGroup)
        sdready = self.__previewMenu.addAction('480p')
        sdready.triggered.connect(functools.partial(self.__sceneView.setPreviewRes, 854, 480, 1.0))
        sdready.setCheckable(True)
        sdready.setActionGroup(previewRadioGroup)

        viewport = self.__previewMenu.addAction('Viewport')
        viewport.triggered.connect(functools.partial(self.__sceneView.setPreviewRes, None, None, 1.0))
        viewport.setCheckable(True)
        viewport.setActionGroup(previewRadioGroup)
        half = self.__previewMenu.addAction('1/2 view')
        half.triggered.connect(functools.partial(self.__sceneView.setPreviewRes, None, None, 0.5))
        half.setCheckable(True)
        half.setActionGroup(previewRadioGroup)
        quart = self.__previewMenu.addAction('1/4 view')
        quart.triggered.connect(functools.partial(self.__sceneView.setPreviewRes, None, None, 0.25))
        quart.setCheckable(True)
        quart.setActionGroup(previewRadioGroup)
        eight = self.__previewMenu.addAction('1/8 view')
        eight.triggered.connect(functools.partial(self.__sceneView.setPreviewRes, None, None, 0.125))
        eight.setCheckable(True)
        eight.setActionGroup(previewRadioGroup)

        toolsMenu.addAction('Record').triggered.connect(self.__record)

        option = viewport
        if gSettings.contains('GLViewScale'):
            option = {1.0: viewport, 0.5: half, 0.25: quart, 0.125: eight}[float(gSettings.value('GLViewScale'))]
        option.setChecked(True)

        self.__menuBar.addMenu(self.__dockWidgetMenu)
        self.__menuBar.addAction('About').triggered.connect(self.__aboutDialog)
        self.__restoreUiLock(lock)
Beispiel #6
0
 def __restoreUiLock(self, action):
     state = True if gSettings.value('lockui', '0') == '1' else False
     action.setChecked(state)
     features = QDockWidget.NoDockWidgetFeatures if state else QDockWidget.AllDockWidgetFeatures
     for dockWidget in self.findChildren(QDockWidget):
         dockWidget.setFeatures(features)
Beispiel #7
0
    def __record(self):
        diag = QDialog()
        fId = gSettings.value('RecordFPS', 2)
        rId = gSettings.value('RecordResolution', 3)
        layout = QGridLayout()
        diag.setLayout(layout)
        layout.addWidget(QLabel('FPS: '), 0, 0)
        fps = QComboBox()
        fps.addItems(['12', '24', '30', '48', '60', '120'])
        fps.setCurrentIndex(fId)
        layout.addWidget(fps, 0, 1)
        layout.addWidget(QLabel('Vertical resolution: '), 1, 0)
        resolution = QComboBox()
        resolution.addItems(['144', '288', '360', '720', '1080', '2160'])
        resolution.setCurrentIndex(rId)
        layout.addWidget(resolution, 1, 1)
        ok = QPushButton('Ok')
        ok.clicked.connect(diag.accept)
        cancel = QPushButton('Cancel')
        cancel.clicked.connect(diag.reject)
        layout.addWidget(ok, 2, 0)
        layout.addWidget(cancel, 2, 1)
        diag.exec_()
        if diag.result() != QDialog.Accepted:
            return
        gSettings.setValue('RecordFPS', fps.currentIndex())
        gSettings.setValue('RecordResolution', resolution.currentIndex())

        FPS = int(fps.currentText())
        HEIGHT = int(resolution.currentText())
        WIDTH = (HEIGHT * 16) / 9
        data = (ctypes.c_ubyte * (WIDTH * HEIGHT * 3))()  # alloc buffer once
        flooredStart = self._timer.secondsToBeats(int(self._timer.beatsToSeconds(self._timer.start) * FPS) / float(FPS))
        duration = self._timer.beatsToSeconds(self._timer.end - flooredStart)
        if not fileutil.exists('capture'):
            os.makedirs('capture')
        progress = QProgressDialog(self)
        progress.setMaximum(int(duration * FPS))
        prevFrame = 0
        for frame in xrange(int(duration * FPS)):
            deltaTime = (frame - prevFrame) / float(FPS)
            prevFrame = frame
            progress.setValue(frame)
            QApplication.processEvents()
            if progress.wasCanceled():
                break
            beats = flooredStart + self._timer.secondsToBeats(frame / float(FPS))

            shot = self.__shotsManager.shotAtTime(beats)
            if shot is None:
                continue
            sceneFile = os.path.join(ScenesPath(), shot.sceneName + SCENE_EXT)
            scene = Scene.getScene(sceneFile)
            scene.setSize(WIDTH, HEIGHT)

            uniforms = self.__shotsManager.evaluate(beats)
            textureUniforms = self.__shotsManager.additionalTextures(beats)
            self.__sceneView._cameraInput.setData(*(uniforms['uOrigin'] + uniforms['uAngles']))  # feed animation into camera so animationprocessor can read it again
            cameraData = self.__sceneView._cameraInput.data()

            modifier = os.path.join(ProjectDir(), 'animationprocessor.py')
            if fileutil.exists(modifier):
                execfile(modifier, globals(), locals())

            for name in self.__sceneView._textures:
                uniforms[name] = self.__sceneView._textures[name]._id

            scene.drawToScreen(self._timer.beatsToSeconds(beats), beats, uniforms, (0, 0, WIDTH, HEIGHT), textureUniforms)
            scene.colorBuffers[-1][0].use()

            from OpenGL.GL import glGetTexImage, GL_TEXTURE_2D, GL_RGB, GL_UNSIGNED_BYTE
            glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, data)

            QImage(data, WIDTH, HEIGHT, QImage.Format_RGB888).mirrored(False, True).save('capture/dump_%s_%05d.jpg' % (FPS, int(self._timer.beatsToSeconds(self._timer.start) * FPS) + frame))
        progress.close()

        if not fileutil.exists('convertcapture'):
            os.makedirs('convertcapture')
        with fileutil.edit('convertcapture/convert.bat') as fh:
            start = ''
            start2 = ''
            if int(self._timer.start * FPS) > 0:
                start = '-start_number {} '.format(int(self._timer.beatsToSeconds(self._timer.start) * FPS))
                start2 = '-vframes {} '.format(int(self._timer.beatsToSeconds(self._timer.start) * FPS))
            fh.write('cd "../capture"\n"../convertcapture/ffmpeg.exe" -framerate {} {}-i dump_{}_%%05d.jpg {}-c:v libx264 -r {} -pix_fmt yuv420p "../convertcapture/output.mp4"'.format(FPS, start, FPS,
                                                                                                                                                                                        start2, FPS))

        with fileutil.edit('convertcapture/convertGif.bat') as fh:
            start = ''
            start2 = ''
            if int(self._timer.start * FPS) > 0:
                start = '-start_number {} '.format(int(self._timer.beatsToSeconds(self._timer.start) * FPS))
                start2 = '-vframes {} '.format(int(self._timer.beatsToSeconds(self._timer.start) * FPS))
            fh.write('cd "../capture"\n"../convertcapture/ffmpeg.exe" -framerate {} {}-i dump_{}_%%05d.jpg {}-r {} "../convertcapture/output.gif"'.format(FPS, start, FPS, start2, FPS))

        sound = self.timeSlider.soundtrackPath()
        if not sound:
            return
        with fileutil.edit('convertcapture/merge.bat') as fh:
            startSeconds = self._timer.beatsToSeconds(self._timer.start)
            fh.write('ffmpeg -i output.mp4 -itsoffset {} -i "{}" -vcodec copy -shortest merged.mp4'.format(-startSeconds, sound))