Add 'auto-play when everyone is ready' feature + make readiness pushbutton more prominent

This commit is contained in:
Et0h 2015-01-03 15:47:32 +00:00
parent 6acf0a3b63
commit 90f7719322
5 changed files with 72 additions and 12 deletions

View File

@ -105,6 +105,7 @@ class SyncplayClient(object):
self._userOffset = 0.0
self._speedChanged = False
self.behindFirstDetected = None
self.autoPlay = False
self._warnings = self._WarningManager(self._player, self.userlist, self.ui, self)
if constants.LIST_RELATIVE_CONFIGS and self._config.has_key('loadedRelativePaths') and self._config['loadedRelativePaths']:
@ -310,6 +311,7 @@ class SyncplayClient(object):
self.ui.showMessage(getMessage("current-offset-notification").format(self._userOffset))
def onDisconnect(self):
self.resetAutoPlayState()
if self._config['pauseOnLeave']:
self.setPaused(True)
self.lastPausedOnLeaveTime = time.time()
@ -396,6 +398,7 @@ class SyncplayClient(object):
def setRoom(self, roomName):
self.userlist.currentUser.room = roomName
self.resetAutoPlayState()
def sendRoom(self):
room = self.userlist.currentUser.room
@ -482,6 +485,18 @@ class SyncplayClient(object):
return wrapper
return requireMinVersionDecorator
def changeAutoPlayState(self, newState):
self.autoPlay = newState
self.autoPlayCheck()
def autoPlayCheck(self):
if self.autoPlay and self.userlist.currentUser.canControl() and self.userlist.isReadinessSupported() and self.userlist.areAllUsersInRoomReady():
self.setPaused(False)
def resetAutoPlayState(self):
self.autoPlay = False
self.ui.updateAutoPlayState(False)
@requireMinServerVersion(constants.USER_READY_MIN_VERSION)
def toggleReady(self, manuallyInitiated=True):
self._protocol.setReady(not self.userlist.currentUser.isReady(), manuallyInitiated)
@ -613,14 +628,6 @@ class SyncplayClient(object):
self._warnings["alone-in-the-room"]['timer'].start(constants.WARNING_OSD_MESSAGES_LOOP_INTERVAL, True)
elif self._warnings["alone-in-the-room"]['timer'].running:
self._warnings["alone-in-the-room"]['timer'].stop()
def isReadinessSupported(self):
if not utils.meetsMinVersion(self._client.serverVersion,constants.USER_READY_MIN_VERSION):
return False
elif self._userlist.onlyUserInRoomWhoSupportsReadiness():
return False
else:
return True
def checkReadyStates(self):
if not self._client:
@ -646,14 +653,14 @@ class SyncplayClient(object):
osdMessage = None
if not self._userlist.areAllFilesInRoomSame():
fileDifferencesMessage = getMessage("room-file-differences").format(self._userlist.getFileDifferencesForRoom())
if self._userlist.currentUser.canControl() and self.isReadinessSupported():
if self._userlist.currentUser.canControl() and self._userlist.isReadinessSupported():
if self._userlist.areAllUsersInRoomReady():
osdMessage = u"{}{}{}".format(fileDifferencesMessage, self._client._player.osdMessageSeparator, getMessage("all-users-ready"))
else:
osdMessage = u"{}{}{}".format(fileDifferencesMessage, self._client._player.osdMessageSeparator, getMessage("not-all-ready").format(self._userlist.usersInRoomNotReady()))
else:
osdMessage = fileDifferencesMessage
elif self.isReadinessSupported():
elif self._userlist.isReadinessSupported():
if self._userlist.areAllUsersInRoomReady():
osdMessage = getMessage("all-users-ready")
else:
@ -741,6 +748,14 @@ class SyncplayUserlist(object):
self._client = client
self._roomUsersChanged = True
def isReadinessSupported(self):
if not utils.meetsMinVersion(self._client.serverVersion,constants.USER_READY_MIN_VERSION):
return False
elif self.onlyUserInRoomWhoSupportsReadiness():
return False
else:
return True
def isRoomSame(self, room):
if room and self.currentUser.room and self.currentUser.room == room:
return True
@ -925,6 +940,7 @@ class SyncplayUserlist(object):
self.currentUser.setReady(isReady)
elif self._users.has_key(username):
self._users[username].setReady(isReady)
self._client.autoPlayCheck()
def userListChange(self, room = None):
if room is not None and self.isRoomSame(room):
@ -948,6 +964,7 @@ class SyncplayUserlist(object):
rooms[self.currentUser.room].append(self.currentUser)
rooms = self.sortList(rooms)
self.ui.showUserList(self.currentUser, rooms)
self._client.autoPlayCheck()
def clearList(self):
self._users = {}
@ -976,6 +993,9 @@ class UiManager(object):
if not noPlayer: self.showOSDMessage(message, duration=constants.OSD_DURATION, secondaryOSD=secondaryOSD)
self.__ui.showMessage(message, noTimestamp)
def updateAutoPlayState(self, newState):
self.__ui.updateAutoPlayState(newState)
def showUserList(self, currentUser, rooms):
self.__ui.showUserList(currentUser, rooms)

View File

@ -120,7 +120,8 @@ STYLE_SUBCHECKBOX = "QCheckBox, QLabel {{ margin-left: 6px; padding-left: 21px;
STYLE_SUBLABEL = "QCheckBox, QLabel {{ margin-left: 6px; padding-left: 16px; background:url('{}') left no-repeat }}" #Graphic path
STYLE_ERRORLABEL = "QLabel { color : black; border-style: outset; border-width: 2px; border-radius: 7px; border-color: red; padding: 2px; background: #FFAAAA; }"
STYLE_SUCCESSLABEL = "QLabel { color : black; border-style: outset; border-width: 2px; border-radius: 7px; border-color: green; padding: 2px; background: #AAFFAA; }"
STYLE_READY_PUSHBUTTON = "QPushButton { text-align: left; color : black; border-style: outset; border-width: 2px; border-radius: 7px; padding: 2px; } QPushButton::Checked {border-color: green; background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #00CC00, stop: 1 #00FF00); } QPushButton::!Checked { border-color: maroon; background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #FF0000, stop: 1 #BB0000); } QPushButton::hover:Checked {border-color: green; background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #00FF00, stop: 1 #00DD00); } QPushButton::hover:!Checked { border-color: maroon; background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #BB0000, stop: 1 #FF0000); } QPushButton::pressed { border-style: inset; }"
STYLE_READY_PUSHBUTTON = "QPushButton { text-align: left; color : black; border-style: outset; border-width: 2px; border-radius: 7px; padding: 5px 3px 5px 3px; font-size: 11pt; font-weight: bold; } QPushButton::Checked {border-color: green; background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #00CC00, stop: 1 #00FF00); } QPushButton::!Checked { border-color: maroon; background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #FF0000, stop: 1 #BB0000); } QPushButton::hover:Checked {border-color: green; background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #00FF00, stop: 1 #00DD00); } QPushButton::hover:!Checked { border-color: maroon; background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #BB0000, stop: 1 #FF0000); } QPushButton::pressed { border-style: inset; }"
STYLE_AUTO_PLAY_PUSHBUTTON = "QPushButton { text-align: left; color : black; border-style: outset; border-width: 2px; border-radius: 7px; padding: 2px; margin-left: 10px; } QPushButton::Checked {border-color: green; background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #00CC00, stop: 1 #00FF00); } QPushButton::!Checked { border-color: maroon; background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #FF0000, stop: 1 #BB0000); } QPushButton::hover:Checked {border-color: green; background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #00FF00, stop: 1 #00DD00); } QPushButton::hover:!Checked { border-color: maroon; background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #BB0000, stop: 1 #FF0000); } QPushButton::pressed { border-style: inset; }"
STYLE_NOTIFICATIONBOX = "Username { color: #367AA9; font-weight:bold; }"
STYLE_USERNAME = "color: #367AA9; font-weight:bold;"
STYLE_ERRORNOTIFICATION = "color: red;"

View File

@ -213,6 +213,8 @@ en = {
"pause-guibuttonlabel" : "Pause",
"ready-guipushbuttonlabel" : u"I'm ready to watch! (Click to toggle)",
"notready-guipushbuttonlabel" : u"I'm not ready to watch! (Click to toggle)",
"autoplay-guipushbuttonlabel" : u"Auto-play when everyone is ready",
"noautoplay-guipushbuttonlabel" : u"Don't auto-play when everyone is ready",
"roomuser-heading-label" : "Room / User",
"size-heading-label" : "Size",
@ -550,6 +552,8 @@ ru = {
"pause-guibuttonlabel" : u"Пауза",
"ready-guipushbuttonlabel" : u"I'm ready to watch! (Click to toggle)", # TODO: Translate into Russian
"notready-guipushbuttonlabel" : u"I'm not ready to watch! (Click to toggle)", # TODO: Translate into Russian
"autoplay-guipushbuttonlabel" : u"Auto-play when everyone is ready", # TODO: Translate into Russian
"noautoplay-guipushbuttonlabel" : u"Don't auto-play when everyone is ready", # TODO: Translate into Russian
"roomuser-heading-label" : u"Комната / Пользователь",
"size-heading-label" : u"Size", # TODO: Translate into Russian
@ -885,6 +889,8 @@ de = {
"pause-guibuttonlabel" : u"Pause",
"ready-guipushbuttonlabel" : u"I'm ready to watch! (Click to toggle)", # TODO: Translate into German
"notready-guipushbuttonlabel" : u"I'm not ready to watch! (Click to toggle)", # TODO: Translate into German
"autoplay-guipushbuttonlabel" : u"Auto-play when everyone is ready", # TODO: Translate into German
"noautoplay-guipushbuttonlabel" : u"Don't auto-play when everyone is ready", # TODO: Translate into German
"roomuser-heading-label" : u"Raum / Benutzer",
"size-heading-label" : u"Größe",

View File

@ -39,6 +39,9 @@ class ConsoleUI(threading.Thread):
def updateRoomName(self, room=""):
pass
def updateAutoPlayState(self, newState):
pass
def promptFor(self, prompt=">", message=""):
if message <> "":
print(message)

View File

@ -209,6 +209,12 @@ class MainWindow(QtGui.QMainWindow):
self.readyPushButton.setChecked(newState)
self.updateReadyIcon()
def updateAutoPlayState(self, newState):
oldState = self.autoPlayPushButton.isChecked()
if newState != oldState and newState != None:
self.autoPlayPushButton.setChecked(newState)
self.updateAutoPlayIcon()
def roomClicked(self, item):
while item.parent().row() != -1:
item = item.parent()
@ -473,12 +479,23 @@ class MainWindow(QtGui.QMainWindow):
readyFont = QtGui.QFont()
readyFont.setWeight(QtGui.QFont.Bold)
window.readyPushButton.setCheckable(True)
window.readyPushButton.setAutoExclusive(True)
window.readyPushButton.setAutoExclusive(False)
window.readyPushButton.toggled.connect(self.changeReadyState)
window.readyPushButton.setFont(readyFont)
window.readyPushButton.setStyleSheet(constants.STYLE_READY_PUSHBUTTON)
window.listLayout.addWidget(window.readyPushButton, Qt.AlignRight)
window.autoPlayPushButton = QtGui.QPushButton()
autoPlayFont = QtGui.QFont()
autoPlayFont.setWeight(QtGui.QFont.Bold)
window.autoPlayPushButton.setCheckable(True)
window.autoPlayPushButton.setAutoExclusive(False)
window.autoPlayPushButton.toggled.connect(self.changeAutoPlayState)
window.autoPlayPushButton.setFont(autoPlayFont)
window.autoPlayPushButton.setStyleSheet(constants.STYLE_AUTO_PLAY_PUSHBUTTON)
window.listLayout.addWidget(window.autoPlayPushButton, Qt.AlignRight)
self.updateAutoPlayIcon()
window.contactLabel = QtGui.QLabel()
window.contactLabel.setWordWrap(True)
window.contactLabel.setFrameStyle(QtGui.QFrame.Box | QtGui.QFrame.Sunken)
@ -649,6 +666,10 @@ class MainWindow(QtGui.QMainWindow):
self.updateReadyIcon()
self._syncplayClient.changeReadyState(self.readyPushButton.isChecked())
def changeAutoPlayState(self):
self.updateAutoPlayIcon()
self._syncplayClient.changeAutoPlayState(self.autoPlayPushButton.isChecked())
def updateReadyIcon(self):
ready = self.readyPushButton.isChecked()
if ready:
@ -658,6 +679,15 @@ class MainWindow(QtGui.QMainWindow):
self.readyPushButton.setIcon(QtGui.QIcon(self.resourcespath + 'cross_checkbox.png'))
self.readyPushButton.setText(getMessage("notready-guipushbuttonlabel"))
def updateAutoPlayIcon(self):
ready = self.autoPlayPushButton.isChecked()
if ready:
self.autoPlayPushButton.setIcon(QtGui.QIcon(self.resourcespath + 'tick_checkbox.png'))
self.autoPlayPushButton.setText(getMessage("autoplay-guipushbuttonlabel"))
else:
self.autoPlayPushButton.setIcon(QtGui.QIcon(self.resourcespath + 'cross_checkbox.png'))
self.autoPlayPushButton.setText(getMessage("noautoplay-guipushbuttonlabel"))
def automaticUpdateCheck(self):
if not self.config['checkForUpdatesAutomatically']:
return