videowindow.py (24357B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\videowindow.py 2 import logging 3 import math 4 import uthread2 5 from carbonui import const as uiconst 6 from carbonui.control.slider import Slider 7 from carbonui.primitives.container import Container 8 from carbonui.primitives.containerAutoSize import ContainerAutoSize 9 from carbonui.primitives.fill import Fill 10 from carbonui.primitives.sprite import StreamingVideoSprite, Sprite 11 from carbonui.uianimations import animations 12 from carbonui.uicore import uicore 13 from carbonui.util.color import Color 14 from eve.client.script.ui import eveColor 15 from carbonui.control.buttonIcon import ButtonIcon 16 from eve.client.script.ui.control.eveLabel import EveLabelMedium, EveCaptionMedium 17 from carbonui.control.window import Window 18 from eve.client.script.ui.control.simpleTextTooltip import SimpleTextTooltip 19 from eve.client.script.ui.shared.subtitles import Subtitles 20 from eve.common.lib import appConst 21 from localization import GetByLabel 22 from localization.formatters import FormatTimeIntervalShort, TIME_CATEGORY_HOUR, TIME_CATEGORY_SECOND 23 SUBTITLE_BG_COLOR = (0.15, 24 0.15, 25 0.15, 26 0.6) 27 NANOS_PER_SECOND = 1000000000 28 logger = logging.getLogger(__name__) 29 30 class VideoPlayerWindow(Window): 31 default_caption = 'Video' 32 default_minSize = (500, 400) 33 default_windowID = 'VideoPlayerWnd' 34 default_iconNum = 'res:/ui/texture/icons/bigplay_64.png' 35 36 def ApplyAttributes(self, attributes): 37 Window.ApplyAttributes(self, attributes) 38 self.videoPlayer = VideoPlayer(parent=self.sr.main, padding=appConst.defaultPadding) 39 40 def SetVideoPath(self, path, title = None, subtitles = None): 41 self.SetCaption(title if title is not None else self.default_caption) 42 self.videoPlayer.SetVideoPath(path, title, subtitles) 43 44 def SetVideoFinishedCallback(self, callback): 45 self.videoPlayer.SetVideoFinishedCallback(callback) 46 47 48 class VideoPlayer(Container): 49 default_name = 'VideoPlayer' 50 default_sendAnalytics = False 51 play_texture_path = 'res:/UI/Texture/classes/agency/helpSection/play_Icon.png' 52 pause_texture_path = 'res:/UI/Texture/classes/agency/helpSection/pause_Icon.png' 53 replay_texture_path = 'res:/UI/Texture/classes/agency/helpSection/replay_Icon.png' 54 volume_texture_path = 'res:/UI/Texture/classes/agency/helpSection/volumeIcon.png' 55 volume_muted_texture_path = 'res:/UI/Texture/classes/agency/helpSection/muteIcon.png' 56 next_texture_path = 'res:/UI/Texture/classes/agency/helpSection/next_Icon.png' 57 58 def ApplyAttributes(self, attributes): 59 super(VideoPlayer, self).ApplyAttributes(attributes) 60 self._updatePosition = True 61 self._onFinish = None 62 self._subtitles = None 63 self._finished = False 64 self._isScrubbing = False 65 self.showSubtitles = True 66 self.updateThread = None 67 self.videoSequence = [] 68 self.loops = 0 69 self.sendAnalytics = attributes.get('sendAnalytics', False) 70 self.volume = settings.user.ui.Get('videoPlayerVolume', 100) 71 self.ConstructLayout() 72 self.layoutAreaParent._OnSizeChange_NoBlock = self.RecalcLayout 73 self.UpdateLayoutArea() 74 75 def StartUpdateThread(self): 76 self.updateThread = uthread2.StartTasklet(self._UpdatePosition) 77 78 def ConstructLayout(self): 79 self.layoutAreaParent = Container(name='layoutAreaParent', parent=self) 80 self.layoutArea = Container(name='layoutArea', parent=self.layoutAreaParent, align=uiconst.CENTER, state=uiconst.UI_NORMAL, width=100, height=100) 81 self.layoutArea.OnMouseEnter = self.RevealControls 82 self.layoutArea.OnMouseExit = self.HideControls 83 self.ConstructLargePlayButton() 84 self.ConstructControls() 85 self.ConstructPausedOverlay() 86 self.ConstructSubtitleContainer() 87 self.ConstructVideoSprite() 88 89 def ConstructLargePlayButton(self): 90 self.largePlayButton = ButtonIcon(name='PlayButtonOverlay', parent=self.layoutArea, align=uiconst.CENTER, iconSize=86, width=86, height=86, texturePath='res:/UI/Texture/classes/agency/helpSection/largePlay_Icon.png', func=self.PlayPauseToggle, state=uiconst.UI_HIDDEN) 91 92 def ConstructPausedOverlay(self): 93 self.pausedOverlay = Fill(name='pausedOverlay', parent=self.layoutArea, color=(0, 0, 0, 0.25), state=uiconst.UI_HIDDEN) 94 95 def ConstructSubtitleContainer(self): 96 subtitleCont = Container(parent=self.layoutArea, name='subtitleCont', align=uiconst.TOBOTTOM_NOPUSH, state=uiconst.UI_DISABLED, height=100) 97 self.subtitleBackground = ContainerAutoSize(name='subtitleBackground', parent=subtitleCont, bgColor=SUBTITLE_BG_COLOR, align=uiconst.CENTER, padding=(-5, 0, -5, 0)) 98 self.subtitleLabel = EveCaptionMedium(parent=self.subtitleBackground, color=Color.WHITE, align=uiconst.CENTER, bold=False, state=uiconst.UI_DISABLED, maxLines=2) 99 100 def RevealControls(self, *args): 101 if self.controlsContainer.GetOpacity() == 1: 102 return 103 animations.FadeIn(self.controlsContainer, duration=0.225, callback=lambda : self.controlsContainer.SetState(uiconst.UI_NORMAL)) 104 105 def HideControls(self, *args): 106 if self.video.isPaused: 107 return 108 animations.FadeOut(self.controlsContainer, duration=0.225, callback=lambda : self.controlsContainer.SetState(uiconst.UI_DISABLED)) 109 110 def ConstructVideoSprite(self): 111 self.video = StreamingVideoSprite(parent=self.layoutArea, align=uiconst.TOALL, state=uiconst.UI_DISABLED, sendAnalytics=self.sendAnalytics) 112 self.video.OnVideoSizeAvailable = self.RecalcLayout 113 self.video.OnVideoFinished = self._OnVideoFinished 114 self.video.OnVideoDurationAvailable = self.OnVideoDurationAvailable 115 116 def ConstructControls(self): 117 self.controlsContainer = ContainerAutoSize(name='controlsContainer', parent=self.layoutArea, align=uiconst.TOBOTTOM_NOPUSH, bgColor=(0.1, 0.1, 0.1, 0.45), opacity=0) 118 self.ConstructButtonContainer() 119 self.ConstructControlButtons() 120 self.ConstructPositionContainer() 121 self.ConstructTimeLabelContainer() 122 123 def ConstructButtonContainer(self): 124 self.buttonContainer = Container(name='buttonContainer', parent=self.controlsContainer, align=uiconst.TOBOTTOM, height=24) 125 126 def ConstructControlButtons(self): 127 if self.videoSequence: 128 self.previousButton = ButtonIcon(name='previousVideoButton', parent=self.buttonContainer, func=self.PlayPreviousVideoInSequence, align=uiconst.TOLEFT, texturePath=self.next_texture_path, rotation=math.pi, hint=GetByLabel('UI/VideoPlayer/Previous')) 129 self.ConstructPlayPauseButton() 130 self.nextButton = ButtonIcon(name='nextVideoButton', parent=self.buttonContainer, func=self.PlayNextVideoInSequence, align=uiconst.TOLEFT, texturePath=self.next_texture_path, hint=GetByLabel('UI/VideoPlayer/Next')) 131 else: 132 self.ConstructPlayPauseButton() 133 self.ConstructVolumeControl() 134 self.subtitlesBtn = ButtonIcon(parent=self.buttonContainer, func=self.ToggleSubtitles, align=uiconst.TORIGHT, texturePath='res:/ui/texture/icons/73_16_10.png', hint=GetByLabel('UI/VideoPlayer/ToggleSubtitles')) 135 136 def ConstructVolumeControl(self): 137 volumeControlsContainer = ContainerAutoSize(name='volumeControlsContainer', parent=self.buttonContainer, align=uiconst.TOLEFT) 138 volumeControlsContainer.OnMouseEnter = self.RevealVolumeSlider 139 volumeControlsContainer.OnMouseExit = self.HideVolumeSlider 140 self.muteBtn = ButtonIcon(mame='muteBtn', parent=volumeControlsContainer, func=self.Mute, align=uiconst.TOLEFT, texturePath=self.volume_texture_path, iconSize=24, hint=GetByLabel('UI/VideoPlayer/Mute')) 141 self.volumeSlider = VideoPlayerVolumeSlider(parent=volumeControlsContainer, width=100, value=self.volume, minValue=0, maxValue=100, startValue=100, showLabel=False, on_dragging=self.SetVolume, align=uiconst.TOLEFT, opacity=0) 142 143 def ConstructPlayPauseButton(self): 144 self.playPauseBtn = ButtonIcon(name='PlayPauseButton', parent=self.buttonContainer, func=self.PlayPauseToggle, align=uiconst.TOLEFT, texturePath=self.pause_texture_path, iconSize=24, hint=GetByLabel('UI/VideoPlayer/Pause')) 145 146 def ConstructPositionContainer(self): 147 self.positionContainer = Container(name='positionCont', parent=self.controlsContainer, align=uiconst.TOBOTTOM, height=16, padLeft=9, padRight=9) 148 self.positionCircle = Sprite(name='positionCircle', parent=self.positionContainer, align=uiconst.TOPLEFT_PROP, height=16, width=16, state=uiconst.UI_HIDDEN, texturePath='res:/UI/Texture/classes/agency/helpSection/timeline_Icon.png') 149 self.positionCircle.OnClick = self.ApplyVideoPosition 150 self.positionCircle.OnMouseEnter = self.positionCircle.Show 151 self.positionCircle.OnMouseDown = self.OnPosContMouseDown 152 self.positionCircle.OnMouseUp = self.OnPosContMouseUp 153 self.positionCircle.OnMouseMove = self.Scrub 154 self.timelineContainer = Container(name='fillContainer', parent=self.positionContainer, height=4, top=4, state=uiconst.UI_NORMAL) 155 self.timelineContainer.OnClick = self.ApplyVideoPosition 156 self.timelineContainer.OnMouseMove = self.OnTimelineMouseMove 157 self.timelineContainer.OnMouseDown = self.OnPosContMouseDown 158 self.timelineContainer.OnMouseUp = self.OnPosContMouseUp 159 self.timelineContainer.OnMouseEnter = self.OnPosContMouseEnter 160 self.timelineContainer.OnMouseExit = self.OnPosContMouseExit 161 self.timelineContainer.GetTooltipPosition = self.GetTooltipPosition 162 self.timelineContainer.GetTooltipDelay = self.GetTooltipDelay 163 self.positionFill = Fill(name='positionFill', parent=self.timelineContainer, align=uiconst.TOPLEFT_PROP, height=8, width=2, state=uiconst.UI_DISABLED, color=Color.WHITE) 164 self.progressFill = Fill(parent=Container(parent=self.timelineContainer, state=uiconst.UI_DISABLED), name='progressFill', align=uiconst.TOLEFT_PROP, color=(0.1804, 0.5412, 0.6392, 1)) 165 self.downloadedFill = Fill(parent=Container(parent=self.timelineContainer, state=uiconst.UI_DISABLED), name='downloadFill', align=uiconst.TOLEFT_PROP, color=(0.4667, 0.7529, 0.8392, 0.45)) 166 Fill(parent=self.timelineContainer, align=uiconst.TOALL, color=(1.0, 1.0, 1.0, 0.3)) 167 168 def ConstructTimeLabelContainer(self): 169 timeLabelContainer = Container(name='timeLabelContainer', parent=self.controlsContainer, align=uiconst.TOBOTTOM, height=20, padLeft=9, padRight=9) 170 self.currentTimeLabel = EveLabelMedium(name='currentTimeLabel', parent=timeLabelContainer, align=uiconst.CENTERLEFT) 171 self.totalDurationLabel = EveLabelMedium(name='totalDurationLabel', parent=timeLabelContainer, align=uiconst.CENTERRIGHT) 172 173 def Reset(self): 174 self.progressFill.width = 0 175 self.downloadedFill.width = 0 176 self.playPauseBtn.SetTexturePath(self.pause_texture_path) 177 self.playPauseBtn.SetHint(GetByLabel('UI/VideoPlayer/Pause')) 178 self.muteBtn.SetTexturePath(self.volume_texture_path) 179 self.muteBtn.SetHint(GetByLabel('UI/VideoPlayer/Mute')) 180 self.largePlayButton.SetState(uiconst.UI_HIDDEN) 181 self.volumeSlider.SetValue(self.volume) 182 183 def RevealVolumeSlider(self, *args): 184 animations.FadeIn(self.volumeSlider, duration=0.225) 185 186 def HideVolumeSlider(self, *args): 187 animations.FadeOut(self.volumeSlider, duration=0.225) 188 189 def OnPosContMouseUp(self, *args): 190 self._isScrubbing = False 191 192 def OnPosContMouseDown(self, *args): 193 self._isScrubbing = True 194 195 def GetTooltipPosition(self): 196 x, y = self.timelineContainer.GetAbsolutePosition() 197 return (int(uicore.uilib.x * uicore.desktop.dpiScaling), 198 y, 199 0, 200 0) 201 202 def OnPosContMouseEnter(self, *args): 203 self.positionCircle.Show() 204 self.timelineContainer.tooltipPanelClassInfo = SimpleTextTooltip(text=self.GetFormattedVideoTimeFromMousePosition(), margin=4) 205 206 def OnTimelineMouseMove(self, *args): 207 if self.timelineContainer.tooltipPanelClassInfo: 208 self.UpdateVideoTimeTooltip() 209 self.Scrub() 210 211 def Scrub(self, *args): 212 if self._isScrubbing: 213 self.ApplyVideoPosition() 214 215 def OnPosContMouseExit(self, *args): 216 if self._isScrubbing: 217 return 218 self.positionCircle.Hide() 219 220 def GetTooltipDelay(self): 221 return 0 222 223 def UpdateVideoTimeTooltip(self): 224 self.UpdateVideoTimeTooltipPosition() 225 self.UpdateVideoTimeTooltipText() 226 227 def UpdateVideoTimeTooltipText(self): 228 if not self.timelineContainer.tooltipPanelClassInfo.textLabel: 229 return 230 currentTime = self.GetFormattedVideoTimeFromMousePosition() 231 self.timelineContainer.tooltipPanelClassInfo.textLabel.SetText(currentTime) 232 233 def GetFormattedVideoTimeFromMousePosition(self): 234 nanoseconds = self.GetVideoTimeFromMousePosition() 235 seconds_in_video = int(nanoseconds / NANOS_PER_SECOND) 236 currentTime = FormatTimeIntervalShort(seconds_in_video * appConst.SEC, showFrom=TIME_CATEGORY_HOUR, showTo=TIME_CATEGORY_SECOND) 237 return currentTime 238 239 def UpdateVideoTimeTooltipPosition(self): 240 if not self.timelineContainer.tooltipPanelClassInfo.tooltipPanel: 241 return 242 l, t, w, h = self.GetTooltipPosition() 243 t -= self.timelineContainer.tooltipPanelClassInfo.tooltipPanel.height + 9 244 l -= self.timelineContainer.tooltipPanelClassInfo.tooltipPanel.width / 2 245 self.timelineContainer.tooltipPanelClassInfo.tooltipPanel.SetPosition(l, t) 246 247 def GetVideoTimeFromMousePosition(self): 248 l, t, w, h = self.timelineContainer.GetAbsolute() 249 try: 250 x = (uicore.uilib.x - l) / float(w) 251 except ZeroDivisionError: 252 x = 0.0 253 254 if x >= 1.0: 255 return 1.0 256 x = max(0.0, x) 257 x = int(x * self.video.duration) 258 return x 259 260 def ApplyVideoPosition(self): 261 nanoseconds = self.GetVideoTimeFromMousePosition() 262 self.video.Seek(nanoseconds) 263 264 def SetVideoFinishedCallback(self, callback): 265 self._onFinish = callback 266 267 def _OnVideoFinished(self): 268 self._finished = True 269 self.playPauseBtn.SetTexturePath(self.replay_texture_path) 270 self.playPauseBtn.SetHint(GetByLabel('UI/VideoPlayer/Replay')) 271 self._updatePosition = False 272 if self._onFinish is not None: 273 self._onFinish() 274 self.updateThread.kill() 275 276 def SetVideoSequence(self, videoPaths): 277 if not videoPaths: 278 return 279 self.videoSequence = list(videoPaths) 280 self.buttonContainer.Flush() 281 self.ConstructControlButtons() 282 self.UpdateNextPreviousButtons() 283 self.subtitleLabel.text = '' 284 285 def ClearVideoSequence(self): 286 self.videoSequence = [] 287 self.buttonContainer.Flush() 288 self.ConstructControlButtons() 289 self.UpdateNextPreviousButtons() 290 self.subtitleLabel.text = '' 291 292 def UpdateNextPreviousButtons(self, videoIndexInSequence = None): 293 if not self.video.path: 294 return 295 if not videoIndexInSequence: 296 videoIndexInSequence = self.videoSequence.index(self.video.path) 297 if videoIndexInSequence == len(self.videoSequence) - 1: 298 self.nextButton.Disable() 299 elif videoIndexInSequence == 0: 300 self.previousButton.Disable() 301 302 def PlayNextVideoInSequence(self): 303 try: 304 nextIndex = self.videoSequence.index(self.video.path) + 1 305 except ValueError: 306 logger.warn('Video Player: Unable to play next video in sequence', exc_info=True) 307 return 308 309 if nextIndex > len(self.videoSequence) - 1: 310 return 311 self.SetVideoPath(self.videoSequence[nextIndex], *self._replayArgs[1:]) 312 self.OnNextButtonClicked() 313 if not self.previousButton.enabled: 314 self.previousButton.Enable() 315 self.UpdateNextPreviousButtons(nextIndex) 316 317 def OnNextButtonClicked(self): 318 pass 319 320 def PlayPreviousVideoInSequence(self): 321 try: 322 prevIndex = self.videoSequence.index(self.video.path) - 1 323 except ValueError: 324 logger.warn('Video Player: Unable to play previous video in sequence', exc_info=True) 325 return 326 327 if prevIndex < 0: 328 return 329 self.SetVideoPath(self.videoSequence[prevIndex], *self._replayArgs[1:]) 330 self.OnPreviousButtonClicked() 331 if not self.nextButton.enabled: 332 self.nextButton.Enable() 333 self.UpdateNextPreviousButtons(prevIndex) 334 335 def OnPreviousButtonClicked(self): 336 pass 337 338 def SetVideoPath(self, path, title = None, subtitles = None, videoLoop = False): 339 if self.video and path == self.video.path: 340 return 341 self.Reset() 342 self.video.SetVideoPath(path, videoLoop=videoLoop) 343 self.video.SetVolume(float(self.volume) / 100.0) 344 self._finished = False 345 self._replayArgs = (path, 346 title, 347 subtitles, 348 videoLoop) 349 subtitleText = None 350 if subtitles is None: 351 self._subtitles = None 352 else: 353 self._subtitles = Subtitles() 354 subtitleText = self._subtitles.LoadSubtitleFile(subtitles) 355 if not subtitleText: 356 self.subtitleBackground.Hide() 357 self._subtitles = None 358 else: 359 self._subtitles.PrepareSubtitles(subtitleText) 360 self.subtitleBackground.Show() 361 self.StartUpdateThread() 362 363 def OnVideoDurationAvailable(self): 364 self.UpdateDurationLabel() 365 366 def UpdateDurationLabel(self): 367 if not self.video or not self.video.duration: 368 return 369 seconds_in_video = self.video.duration / NANOS_PER_SECOND 370 totalDuration = FormatTimeIntervalShort(seconds_in_video * appConst.SEC, showFrom=TIME_CATEGORY_HOUR, showTo=TIME_CATEGORY_SECOND) 371 self.totalDurationLabel.SetText(totalDuration) 372 373 def UpdateCurrentTimeLabel(self): 374 if not self.video or not self.video.mediaTime: 375 return 376 currentTime = self.GetVideoCurrentTime() 377 self.currentTimeLabel.SetText(currentTime) 378 379 def GetVideoCurrentTime(self): 380 seconds_in_video = self.video.mediaTime % self.video.duration / NANOS_PER_SECOND 381 currentTime = FormatTimeIntervalShort(seconds_in_video * appConst.SEC, showFrom=TIME_CATEGORY_HOUR, showTo=TIME_CATEGORY_SECOND) 382 return currentTime 383 384 def Close(self, *args, **kwds): 385 self._updatePosition = False 386 self.video = None 387 if self.updateThread: 388 self.updateThread.kill() 389 super(VideoPlayer, self).Close() 390 391 def _UpdatePosition(self): 392 while self._updatePosition: 393 if self.video: 394 mediaTime = self.video.GetPositionRatioInVideo() 395 self.UpdateCurrentTimeLabel() 396 if mediaTime == 0: 397 self.progressFill.Hide() 398 else: 399 self.progressFill.Show() 400 self.progressFill.width = mediaTime 401 self.positionCircle.left = mediaTime 402 self.positionFill.left = mediaTime 403 duration = float((self.video.duration or 1) / 1000000) 404 if duration == 0: 405 duration = 1 406 downloadedTime = min(float((self.video.downloadedTime or 0) / 1000000) / duration, 1) 407 if downloadedTime == 0: 408 self.downloadedFill.Hide() 409 else: 410 self.downloadedFill.Show() 411 self.downloadedFill.width = downloadedTime 412 self._UpdateSubtitles() 413 uthread2.Sleep(0.1) 414 415 def _UpdateSubtitles(self): 416 if self._subtitles is None or not self.showSubtitles: 417 return 418 currentTime = self.video.mediaTime or 0 419 currentTime /= 1000000 420 text = self._subtitles.GetSubtitle(currentTime) 421 self.subtitleLabel.maxWidth = self.displayWidth - 50 422 if text: 423 self.subtitleLabel.SetText(text) 424 425 def UpdateLayoutArea(self): 426 size = self.video.GetVideoSize() 427 if not size: 428 return 429 areaWidth, areaHeight = self.layoutAreaParent.GetAbsoluteSize() 430 xFitScale = areaWidth / float(size[0]) 431 yFitScale = areaHeight / float(size[1]) 432 scaling = min(xFitScale, yFitScale) 433 self.layoutArea.width = int(size[0] * scaling) 434 self.layoutArea.height = int(size[1] * scaling) 435 436 def RecalcLayout(self, *args): 437 self.UpdateLayoutArea() 438 439 def PlayPauseToggle(self, *args): 440 if self._finished: 441 self.Replay() 442 elif self.video.isPaused: 443 self.Play() 444 else: 445 self.Pause() 446 447 def Play(self): 448 self.video.Play() 449 self.controlsContainer.SetOpacity(1.0) 450 self.largePlayButton.SetState(uiconst.UI_HIDDEN) 451 self.playPauseBtn.SetTexturePath(self.pause_texture_path) 452 self.playPauseBtn.SetHint(GetByLabel('UI/VideoPlayer/Pause')) 453 self.pausedOverlay.SetState(uiconst.UI_HIDDEN) 454 455 def Pause(self): 456 self.video.Pause() 457 self.largePlayButton.SetState(uiconst.UI_NORMAL) 458 self.playPauseBtn.SetTexturePath(self.play_texture_path) 459 self.playPauseBtn.SetHint(GetByLabel('UI/VideoPlayer/Play')) 460 self.pausedOverlay.SetState(uiconst.UI_NORMAL) 461 462 def Replay(self): 463 self._finished = False 464 self.SetVideoPath(*self._replayArgs) 465 self.Play() 466 467 def Mute(self, *args): 468 if self.video.isMuted: 469 self.video.UnmuteAudio() 470 self.volumeSlider.SetValue(self.volume) 471 self.muteBtn.SetTexturePath(self.volume_texture_path) 472 self.muteBtn.SetHint(GetByLabel('UI/VideoPlayer/Mute')) 473 else: 474 self.video.MuteAudio() 475 self.volumeSlider.SetValue(0) 476 self.muteBtn.SetTexturePath(self.volume_muted_texture_path) 477 self.muteBtn.SetHint(GetByLabel('UI/VideoPlayer/Unmute')) 478 479 def SetVolume(self, slider): 480 self.video.SetVolume(float(slider.value) / 100.0) 481 self.volume = slider.value 482 settings.user.ui.Set('videoPlayerVolume', self.volume) 483 if self.volume: 484 self.muteBtn.SetTexturePath(self.volume_texture_path) 485 self.muteBtn.SetHint(GetByLabel('UI/VideoPlayer/Mute')) 486 487 def ToggleSubtitles(self): 488 self.showSubtitles = not self.showSubtitles 489 if self.showSubtitles: 490 self.subtitlesBtn.opacity = 1.0 491 self.subtitleLabel.Show() 492 self.subtitleBackground.Show() 493 else: 494 self.subtitlesBtn.opacity = 0.2 495 self.subtitleLabel.Hide() 496 self.subtitleBackground.Hide() 497 498 499 class VideoPlayerVolumeSlider(Slider): 500 default_name = 'VideoPlayerVolumeSlider' 501 502 def ApplyAttributes(self, attributes): 503 super(VideoPlayerVolumeSlider, self).ApplyAttributes(attributes) 504 self.callback.connect(self.UpdateFillWidth) 505 self.on_dragging.connect(self.UpdateFillWidth) 506 self.UpdateFillWidth() 507 508 def _ConstructHandle(self): 509 super(VideoPlayerVolumeSlider, self)._ConstructHandle() 510 511 def _ConstructBackground(self): 512 volumeFillContainer = Container(parent=self, align=uiconst.CENTER, height=self.barHeight / 2, width=self.width) 513 Fill(name='backgroundFill', bgParent=volumeFillContainer, color=Color.GRAY5, opacity=0.25) 514 self.volumeFill = Fill(parent=volumeFillContainer, align=uiconst.TOLEFT_PROP, width=0.0, color=Color.WHITE) 515 516 def _ConstructBarCont(self): 517 self.barCont = Container(parent=self, name='barCont', align=uiconst.CENTER, state=uiconst.UI_NORMAL, height=self.barHeight + 10, width=self.width) 518 self.barCont.OnClick = self.OnSliderClicked 519 self.barCont.OnMouseMove = self.OnSliderMouseMove 520 self.barCont.OnMouseExit = self.OnMouseBarExit 521 self.barCont.OnMouseWheel = self.OnMouseWheel 522 self.barCont.GetHint = self.GetHint 523 524 def UpdateFillWidth(self, *args): 525 self.volumeFill.width = self.value / 100 526 527 def OnHandleMouseEnter(self, *args): 528 pass 529 530 def OnHandleMouseExit(self, *args): 531 pass