Skip to content

Commit

Permalink
Added ability to clip (trim) the ends of a framegroup
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewjrobinson committed Apr 29, 2014
1 parent 457eb5f commit 5f89e37
Show file tree
Hide file tree
Showing 10 changed files with 445 additions and 10 deletions.
23 changes: 21 additions & 2 deletions sportsreview/aftertouches/aftertouches.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Form implementation generated from reading ui file 'aftertouches/aftertouches.ui'
#
# Created: Thu Apr 24 12:58:51 2014
# Created: Tue Apr 29 20:06:13 2014
# by: pyside-uic 0.2.15 running on PySide 1.2.1
#
# WARNING! All changes made in this file will be lost!
Expand Down Expand Up @@ -66,7 +66,6 @@ def setupUi(self, MainWindow):
self.playbackToolBar = QtGui.QToolBar(MainWindow)
self.playbackToolBar.setObjectName("playbackToolBar")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.playbackToolBar)
MainWindow.insertToolBarBreak(self.playbackToolBar)
self.timelineDockWidget = QtGui.QDockWidget(MainWindow)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
Expand Down Expand Up @@ -104,6 +103,9 @@ def setupUi(self, MainWindow):
self.verticalLayout_4.addWidget(self.previewLabel)
self.timelineDockWidget.setWidget(self.dockWidgetContents)
MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(8), self.timelineDockWidget)
self.clippingToolBar = QtGui.QToolBar(MainWindow)
self.clippingToolBar.setObjectName("clippingToolBar")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.clippingToolBar)
self.actionOpen = QtGui.QAction(MainWindow)
self.actionOpen.setObjectName("actionOpen")
self.actionExit = QtGui.QAction(MainWindow)
Expand Down Expand Up @@ -160,6 +162,16 @@ def setupUi(self, MainWindow):
icon10.addPixmap(QtGui.QPixmap(":/common/resources/playrev0.5x.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.actionPlayRev0_5x.setIcon(icon10)
self.actionPlayRev0_5x.setObjectName("actionPlayRev0_5x")
self.actionClipStart = QtGui.QAction(MainWindow)
icon11 = QtGui.QIcon()
icon11.addPixmap(QtGui.QPixmap(":/common/resources/clipstart.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.actionClipStart.setIcon(icon11)
self.actionClipStart.setObjectName("actionClipStart")
self.actionClipEnd = QtGui.QAction(MainWindow)
icon12 = QtGui.QIcon()
icon12.addPixmap(QtGui.QPixmap(":/common/resources/clipend.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.actionClipEnd.setIcon(icon12)
self.actionClipEnd.setObjectName("actionClipEnd")
self.menuFile.addAction(self.actionOpen)
self.menuFile.addSeparator()
self.menuFile.addAction(self.actionExit)
Expand All @@ -180,6 +192,8 @@ def setupUi(self, MainWindow):
self.playbackToolBar.addSeparator()
self.playbackToolBar.addAction(self.actionPrev)
self.playbackToolBar.addAction(self.actionNext)
self.clippingToolBar.addAction(self.actionClipStart)
self.clippingToolBar.addAction(self.actionClipEnd)

self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
Expand All @@ -192,6 +206,7 @@ def retranslateUi(self, MainWindow):
self.timelineDockWidget.setWindowTitle(QtGui.QApplication.translate("MainWindow", "Timeline", None, QtGui.QApplication.UnicodeUTF8))
self.frameSlider.setToolTip(QtGui.QApplication.translate("MainWindow", "Select Frame", None, QtGui.QApplication.UnicodeUTF8))
self.previewLabel.setText(QtGui.QApplication.translate("MainWindow", "No file open", None, QtGui.QApplication.UnicodeUTF8))
self.clippingToolBar.setWindowTitle(QtGui.QApplication.translate("MainWindow", "Clipping", None, QtGui.QApplication.UnicodeUTF8))
self.actionOpen.setText(QtGui.QApplication.translate("MainWindow", "Open", None, QtGui.QApplication.UnicodeUTF8))
self.actionOpen.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+O", None, QtGui.QApplication.UnicodeUTF8))
self.actionExit.setText(QtGui.QApplication.translate("MainWindow", "E&xit", None, QtGui.QApplication.UnicodeUTF8))
Expand All @@ -217,5 +232,9 @@ def retranslateUi(self, MainWindow):
self.actionPlayRev2x.setToolTip(QtGui.QApplication.translate("MainWindow", "Play reverse (double speed)", None, QtGui.QApplication.UnicodeUTF8))
self.actionPlayRev0_5x.setText(QtGui.QApplication.translate("MainWindow", "PlayRev0.5x", None, QtGui.QApplication.UnicodeUTF8))
self.actionPlayRev0_5x.setToolTip(QtGui.QApplication.translate("MainWindow", "Play reverse (half speed)", None, QtGui.QApplication.UnicodeUTF8))
self.actionClipStart.setText(QtGui.QApplication.translate("MainWindow", "ClipStart", None, QtGui.QApplication.UnicodeUTF8))
self.actionClipStart.setToolTip(QtGui.QApplication.translate("MainWindow", "Set current frame as start of clip", None, QtGui.QApplication.UnicodeUTF8))
self.actionClipEnd.setText(QtGui.QApplication.translate("MainWindow", "ClipEnd", None, QtGui.QApplication.UnicodeUTF8))
self.actionClipEnd.setToolTip(QtGui.QApplication.translate("MainWindow", "Set current frame as end of clip", None, QtGui.QApplication.UnicodeUTF8))

import resources_rc
39 changes: 38 additions & 1 deletion sportsreview/aftertouches/aftertouches.ui
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>true</bool>
<bool>false</bool>
</attribute>
<addaction name="actionStart"/>
<addaction name="separator"/>
Expand Down Expand Up @@ -202,6 +202,19 @@
</layout>
</widget>
</widget>
<widget class="QToolBar" name="clippingToolBar">
<property name="windowTitle">
<string>Clipping</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionClipStart"/>
<addaction name="actionClipEnd"/>
</widget>
<action name="actionOpen">
<property name="text">
<string>Open</string>
Expand Down Expand Up @@ -343,6 +356,30 @@
<string>Play reverse (half speed)</string>
</property>
</action>
<action name="actionClipStart">
<property name="icon">
<iconset resource="../common/resources.qrc">
<normaloff>:/common/resources/clipstart.svg</normaloff>:/common/resources/clipstart.svg</iconset>
</property>
<property name="text">
<string>ClipStart</string>
</property>
<property name="toolTip">
<string>Set current frame as start of clip</string>
</property>
</action>
<action name="actionClipEnd">
<property name="icon">
<iconset resource="../common/resources.qrc">
<normaloff>:/common/resources/clipend.svg</normaloff>:/common/resources/clipend.svg</iconset>
</property>
<property name="text">
<string>ClipEnd</string>
</property>
<property name="toolTip">
<string>Set current frame as end of clip</string>
</property>
</action>
</widget>
<resources>
<include location="../common/resources.qrc"/>
Expand Down
28 changes: 26 additions & 2 deletions sportsreview/aftertouches/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def setFrame(self, idx):
def jumpStart(self):
'''Move the start of current framegroup'''
if self._openFrameGroup is not None:
self._openFrameGroup.setPosition(0)
self._openFrameGroup.setPosition(self._openFrameGroup.getClipStart())
self.selectedFrameSet.emit(self._openFrameGroup, self._openFrameGroup.index())
else:
self.mainwindow.setStatusMsg("No file open!", 1000)
Expand All @@ -129,7 +129,7 @@ def jumpStart(self):
def jumpEnd(self):
'''Move to the end of current framegroup'''
if self._openFrameGroup is not None:
self._openFrameGroup.setPosition(len(self._openFrameGroup) - 1)
self._openFrameGroup.setPosition(self._openFrameGroup.getClipEnd() - 1)
self.selectedFrameSet.emit(self._openFrameGroup, self._openFrameGroup.index())
else:
self.mainwindow.setStatusMsg("No file open!", 1000)
Expand Down Expand Up @@ -179,6 +179,22 @@ def processGroup(self, modulename, config):

module.processGroup(self._openFrameGroup)

@Slot()
def clipStart(self):
'''Mark current frame as start'''
if self._openFrameGroup is not None:
self._openFrameGroup.clipStart()
else:
self.mainwindow.setStatusMsg("No file open!", 1000)

@Slot()
def clipEnd(self):
'''Mark current frame as end'''
if self._openFrameGroup is not None:
self._openFrameGroup.clipEnd()
else:
self.mainwindow.setStatusMsg("No file open!", 1000)

## Support ##
def _playFrame(self):
'''Plays the next frame if required [timer target]'''
Expand All @@ -195,15 +211,23 @@ def _playFrame(self):
if self._playing > 0: # playing forward
releaseTimestamp = float(self._openFrameGroup[0].timestamp) + playbackTime
nextFrame = self._openFrameGroup.peekNext()
if self._openFrameGroup.index() >= self._openFrameGroup.getClipEnd():
nextFrame = None
while nextFrame is not None and nextFrame.timestamp < releaseTimestamp:
lastFrame = self._openFrameGroup.next()
nextFrame = self._openFrameGroup.peekNext()
if self._openFrameGroup.index() >= self._openFrameGroup.getClipEnd():
nextFrame = None
else: # playing reverse
releaseTimestamp = float(self._openFrameGroup[-1].timestamp) + playbackTime
nextFrame = self._openFrameGroup.peekPrev()
if self._openFrameGroup.index() < self._openFrameGroup.getClipStart():
nextFrame = None
while nextFrame is not None and nextFrame.timestamp > releaseTimestamp:
lastFrame = self._openFrameGroup.prev()
nextFrame = self._openFrameGroup.peekPrev()
if self._openFrameGroup.index() < self._openFrameGroup.getClipStart():
nextFrame = None

# display the last released frame (if required)
if lastFrame is not None:
Expand Down
4 changes: 4 additions & 0 deletions sportsreview/aftertouches/mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ def __init__(self, settings, application=None):
self.ui.actionStart.triggered.connect(self.application.jumpStart)
self.ui.actionEnd.triggered.connect(self.application.jumpEnd)

# Clipping toolbar
self.ui.actionClipStart.triggered.connect(self.application.clipStart)
self.ui.actionClipEnd.triggered.connect(self.application.clipEnd)

self._bindings = {}
self._loadBindings(settings.getSetting('keybinding'))
#end init()
Expand Down
35 changes: 35 additions & 0 deletions sportsreview/common/framegroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ def __init__(self, timestamp=None, loadframelistfunc=None, loadframelistopts=Non
self._currentset = False
self.headers = {}

self._start = 0
self._end = None

def current(self):
'''
Retrieves the current frame
Expand Down Expand Up @@ -283,6 +286,38 @@ def setHeader(self, name, value):
elif name == "filename":
self.filename = value
self.headers[name] = value

def clipStart(self, idx = None):
'''
Sets the specified frame index as the start. If idx is None then uses current index.
@param idx: int, the index that will be the first frame (inclusive)
'''
if idx == None:
self._start = self._current
elif idx > 0 and idx < len(self._frames) and (self._end is None or idx < self._end):
self._start = idx

def clipEnd(self, idx = None):
'''
Sets the specified frame index as the end. If idx is None then uses current index.
@param idx: int, the index that will be the last frame (exclusive)
'''
if idx == None:
self._end = self._current
elif idx > 0 and idx <= len(self._frames) and idx > self._start:
self._end = idx

def getClipStart(self):
'''Returns the current clipping start point (index)'''
return self._start

def getClipEnd(self):
'''Returns the current clipping end point (index)'''
if self._end is None:
return len(self._frames)
return self._end

def __len__(self, *args, **kwargs):
self._loadframeinfo()
Expand Down
2 changes: 2 additions & 0 deletions sportsreview/common/resources.qrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<RCC>
<qresource prefix="common">
<file>resources/clipend.svg</file>
<file>resources/clipstart.svg</file>
<file>resources/playrev0.5x.svg</file>
<file>resources/playrev2x.svg</file>
<file>resources/playrev.svg</file>
Expand Down
Loading

0 comments on commit 5f89e37

Please sign in to comment.