Add 'auto-play when everyone is ready' feature + make readiness pushbutton more prominent
This commit is contained in:
parent
6acf0a3b63
commit
90f7719322
@ -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)
|
||||
|
||||
|
||||
@ -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;"
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user