📄 videodisplay.py
字号:
@platformutils.onMainThread def exitFullScreen(self): if self.videoWindow.isFullScreen: self.window().addChildWindow_ordered_(self.videoWindow, NSWindowAbove) self.window().makeKeyAndOrderFront_(nil) self.videoWindow.exitFullScreen() ###############################################################################class VideoWindow (NibClassBuilder.AutoBaseClass): def initWithContentRect_styleMask_backing_defer_(self, rect, style, backing, defer): self = super(VideoWindow, self).initWithContentRect_styleMask_backing_defer_( rect, NSBorderlessWindowMask, backing, defer ) self.setAcceptsMouseMovedEvents_(YES) self.setBackgroundColor_(NSColor.blackColor()) self.isFullScreen = NO return self def setup(self, renderer, item): self.installRendererView_(renderer.view) self.palette.setup(item, renderer) if self.isFullScreen: platformutils.callOnMainThreadAfterDelay(0.5, self.palette.reveal, self) def teardown(self): platformutils.warnIfNotOnMainThread('VideoWindow.teardown') self.setContentView_(nil) @platformutils.onMainThreadWaitingUntilDone def installRendererView_(self, view): if self.contentView() is not nil: self.contentView().removeFromSuperviewWithoutNeedingDisplay() self.setContentView_(view) def canBecomeMainWindow(self): return self.isFullScreen def canBecomeKeyWindow(self): return self.isFullScreen def enterFullScreen(self, screen): platformutils.warnIfNotOnMainThread('VideoWindow.enterFullScreen') SetSystemUIMode(kUIModeAllHidden, 0) NSCursor.setHiddenUntilMouseMoves_(YES) self.isFullScreen = YES self.previousFrame = self.frame() self.setFrame_display_animate_(screen.frame(), YES, YES) self.makeKeyAndOrderFront_(nil) def exitFullScreen(self): platformutils.warnIfNotOnMainThread('VideoWindow.exitFullScreen') NSCursor.setHiddenUntilMouseMoves_(NO) self.isFullScreen = NO self.palette.remove() self.setFrame_display_animate_(self.previousFrame, YES, YES) SetSystemUIMode(kUIModeNormal, 0) def toggleFullScreen_(self, sender): app.controller.videoDisplay.exitFullScreen() def sendEvent_(self, event): if self.isFullScreen: if event.type() == NSLeftMouseDown: if NSApplication.sharedApplication().isActive(): app.controller.videoDisplay.exitFullScreen() else: NSApplication.sharedApplication().activateIgnoringOtherApps_(YES) elif event.type() == NSKeyDown: if event.characters().characterAtIndex_(0) == 0x1B: app.controller.videoDisplay.exitFullScreen() elif event.characters().characterAtIndex_(0) == 0x20: eventloop.addUrgentCall(lambda:app.controller.playbackController.playPause(), "Play/Pause") elif event.type() == NSMouseMoved: if not self.palette.isVisible(): self.palette.reveal(self) else: self.palette.resetAutoConceal() else: if event.type() == NSLeftMouseDown: if NSApplication.sharedApplication().isActive(): app.controller.videoDisplay.goFullScreen() else: NSApplication.sharedApplication().activateIgnoringOtherApps_(YES)###############################################################################class SkipSeekButtonCell (NSButtonCell): @classmethod def cellFromButtonCell_direction_delay_(self, cell, direction, delay): newCell = SkipSeekButtonCell.alloc().initWithPrimaryAction_direction_delay_(cell.action(), direction, delay) newCell.setType_(cell.type()) newCell.setBezeled_(cell.isBezeled()) newCell.setBezelStyle_(cell.bezelStyle()) newCell.setBordered_(cell.isBordered()) newCell.setTransparent_(cell.isTransparent()) newCell.setImage_(cell.image()) newCell.setAlternateImage_(cell.alternateImage()) newCell.setState_(cell.state()) newCell.setHighlightsBy_(cell.highlightsBy()) newCell.setShowsStateBy_(cell.showsStateBy()) newCell.setEnabled_(cell.isEnabled()) newCell.setTarget_(cell.target()) newCell.setAction_(nil) return newCell def initWithPrimaryAction_direction_delay_(self, action, direction, delay): self = NSButtonCell.init(self) self.primaryAction = action self.direction = direction self.seekTimer = nil self.seekDelay = delay self.allowSkipping = True self.allowSeeking = True return self def setAllowsFastSeeking(self, allow): self.allowSeeking = allow def setAllowsSkipping(self, allow): self.allowSkipping = allow def trackMouse_inRect_ofView_untilMouseUp_(self, event, frame, control, untilMouseUp): if self.allowSeeking: if self.seekDelay > 0.0: self.seekTimer = NSTimer.timerWithTimeInterval_target_selector_userInfo_repeats_(self.seekDelay, self, 'fastSeek:', nil, NO) NSRunLoop.currentRunLoop().addTimer_forMode_(self.seekTimer, NSEventTrackingRunLoopMode) else: self.fastSeek_(nil) mouseIsUp = NSButtonCell.trackMouse_inRect_ofView_untilMouseUp_(self, event, frame, control, YES) if self.seekTimer is not nil or not self.allowSeeking: self.resetSeekTimer() control.sendAction_to_(self.primaryAction, self.target()) else: self.target().stopSeeking() return mouseIsUp def fastSeek_(self, timer): self.target().fastSeek(self.direction) self.resetSeekTimer() def resetSeekTimer(self): if self.seekTimer is not nil: self.seekTimer.invalidate() self.seekTimer = nil###############################################################################class FullScreenPalette (NibClassBuilder.AutoBaseClass): HOLD_TIME = 2 def initWithContentRect_styleMask_backing_defer_(self, rect, style, backing, defer): self = super(FullScreenPalette, self).initWithContentRect_styleMask_backing_defer_( rect, NSBorderlessWindowMask, backing, defer ) nc = NSNotificationCenter.defaultCenter() nc.addObserver_selector_name_object_(self, 'videoWillPlay:', 'videoWillPlay', nil) nc.addObserver_selector_name_object_(self, 'videoWillPause:', 'videoWillPause', nil) self.setBackgroundColor_(NSColor.clearColor()) self.setAlphaValue_(1.0) self.setOpaque_(NO) self.autoConcealTimer = nil self.updateTimer = nil self.holdStartTime = 0.0 self.renderer = None self.wasPlaying = False return self def awakeFromNib(self): self.seekForwardButton.setCell_(SkipSeekButtonCell.cellFromButtonCell_direction_delay_(self.seekForwardButton.cell(), 1, 0.0)) self.seekForwardButton.cell().setAllowsSkipping(False) self.seekBackwardButton.setCell_(SkipSeekButtonCell.cellFromButtonCell_direction_delay_(self.seekBackwardButton.cell(), -1, 0.0)) self.seekBackwardButton.cell().setAllowsSkipping(False) self.progressSlider.track = NSImage.imageNamed_('fs-progress-background') self.progressSlider.cursor = NSImage.imageNamed_('fs-progress-slider') self.progressSlider.sliderWasClicked = self.progressSliderWasClicked self.progressSlider.sliderWasDragged = self.progressSliderWasDragged self.progressSlider.sliderWasReleased = self.progressSliderWasReleased self.progressSlider.setShowCursor_(True) self.volumeSlider.track = NSImage.imageNamed_('fs-volume-background') self.volumeSlider.cursor = NSImage.imageNamed_('fs-volume-slider') self.volumeSlider.sliderWasDragged = self.volumeSliderWasDragged self.volumeSlider.setShowCursor_(True) def canBecomeKeyWindow(self): return NO def canBecomeMainWindow(self): return NO def setup(self, item, renderer): self.titleLabel.setStringValue_(item.getTitle()) self.feedLabel.setStringValue_(item.getFeed().getTitle()) self.donationLabel.setStringValue_(u'') self.renderer = renderer self.update_(nil) def reveal(self, parent): platformutils.warnIfNotOnMainThread('FullScreenPalette.reveal') if not self.isVisible(): self.update_(nil) self.volumeSlider.setFloatValue_(app.controller.videoDisplay.getVolume()) screenOrigin = parent.screen().frame().origin screenSize = parent.screen().frame().size height = self.frame().size.height frame = ((screenOrigin.x, screenOrigin.y-height), (screenSize.width, height)) self.setFrame_display_(frame, NO) parent.addChildWindow_ordered_(self, NSWindowAbove) self.orderFront_(nil) frame = (screenOrigin, (screenSize.width, height)) self.setFrame_display_animate_(frame, YES, YES) self.holdStartTime = time.time() self.autoConcealTimer = NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_( 1.0, self, 'concealAfterDelay:', nil, YES) self.updateTimer = NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_( 1.0, self, 'update:', nil, YES) NSRunLoop.currentRunLoop().addTimer_forMode_(self.updateTimer, NSEventTrackingRunLoopMode) self.update_(nil) def conceal(self): platformutils.warnIfNotOnMainThread('FullScreenPalette.conceal') if self.autoConcealTimer is not nil: self.autoConcealTimer.invalidate() self.autoConcealTimer = nil if self.updateTimer is not nil: self.updateTimer.invalidate() self.updateTimer = nil frame = self.frame() frame.origin.y = -frame.size.height self.setFrame_display_animate_(frame, YES, YES) self.remove() NSCursor.setHiddenUntilMouseMoves_(YES) def concealAfterDelay_(self, timer): if time.time() - self.holdStartTime > self.HOLD_TIME: self.conceal() def resetAutoConceal(self): self.holdStartTime = time.time() def expireNow_(self, sender): pass def tellAFriend_(self, sender): pass def update_(self, timer): self.timeIndicator.setStringValue_(self.renderer.getDisplayTime()) self.progressSlider.setFloatValue_(self.renderer.getProgress()) def progressSliderWasClicked(self, slider): if app.controller.videoDisplay.isPlaying: self.wasPlaying = True self.renderer.pause() self.renderer.setProgress(slider.floatValue()) self.renderer.interactivelySeeking = True self.resetAutoConceal() def progressSliderWasDragged(self, slider): self.renderer.setProgress(slider.floatValue()) self.resetAutoConceal() def progressSliderWasReleased(self, slider): self.renderer.interactivelySeeking = False if self.wasPlaying: self.wasPlaying = False self.renderer.play() def volumeSliderWasDragged(self, slider): app.controller.videoDisplay.setVolume(slider.floatValue()) self.resetAutoConceal() def videoWillPlay_(self, notification): self.playPauseButton.setImage_(NSImage.imageNamed_('fs-button-pause')) self.playPauseButton.setAlternateImage_(NSImage.imageNamed_('fs-button-pause-alt')) def videoWillPause_(self, notification): self.playPauseButton.setImage_(NSImage.imageNamed_('fs-button-play')) self.playPauseButton.setAlternateImage_(NSImage.imageNamed_('fs-button-play-alt')) def remove(self): platformutils.warnIfNotOnMainThread('FullScreenPalette.remove') if self.parentWindow() is not nil: self.parentWindow().removeChildWindow_(self) self.orderOut_(nil)###############################################################################class FullScreenPaletteView (NibClassBuilder.AutoBaseClass): def awakeFromNib(self): self.background = NSImage.imageNamed_('fs-background') self.backgroundRect = NSRect((0,0), self.background.size()) self.topLine = NSImage.imageNamed_('fs-topline') self.topLineRect = NSRect((0,0), self.topLine.size()) def drawRect_(self, rect): width = self.bounds().size.width bgRect = ((0,0), (width, self.backgroundRect.size.height)) self.background.drawInRect_fromRect_operation_fraction_(bgRect, self.backgroundRect, NSCompositeSourceOver, 1.0) tlRect1 = ((0,self.backgroundRect.size.height), (width-135, self.topLineRect.size.height)) self.topLine.drawInRect_fromRect_operation_fraction_(tlRect1, self.topLineRect, NSCompositeSourceOver, 1.0) tlRect2 = ((width-25,self.backgroundRect.size.height), (25, self.topLineRect.size.height)) self.topLine.drawInRect_fromRect_operation_fraction_(tlRect2, self.topLineRect, NSCompositeSourceOver, 1.0)###############################################################################class FullScreenControlsView (NibClassBuilder.AutoBaseClass): def awakeFromNib(self): self.background = NSImage.imageNamed_('fs-controls-background') self.backgroundRect = NSRect((0,0), self.background.size()) def drawRect_(self, rect): self.background.compositeToPoint_operation_((0, 0), NSCompositeSourceOver) def hitTest_(self, point): # Our buttons have transparent parts, but we still want mouse clicks # to be detected if they happen there, so we override hit testing and # simply test for button frames. for subview in self.subviews(): if NSPointInRect(self.convertPoint_fromView_(point, nil), subview.frame()): return subview return self###############################################################################class FullScreenSlider (NibClassBuilder.AutoBaseClass): def drawTrack(self): self.track.compositeToPoint_operation_((0, 2), NSCompositeSourceOver)###############################################################################
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -