hydrus/include/ClientGUIMediaControls.py

290 lines
8.5 KiB
Python

from . import ClientConstants as CC
from . import ClientData
from . import ClientGUICommon
from . import ClientGUIFunctions
from . import ClientGUIMenus
from . import ClientGUIMPV
from . import ClientGUITopLevelWindows
from . import HydrusConstants as HC
from . import HydrusData
from . import HydrusGlobals as HG
from qtpy import QtCore as QC
from qtpy import QtWidgets as QW
from qtpy import QtGui as QG
from . import QtPorting as QP
AUDIO_GLOBAL = 0
AUDIO_MEDIA_VIEWER = 1
AUDIO_PREVIEW = 2
volume_types_str_lookup = {}
volume_types_str_lookup[ AUDIO_GLOBAL ] = 'global'
volume_types_str_lookup[ AUDIO_MEDIA_VIEWER ] = 'media viewer'
volume_types_str_lookup[ AUDIO_PREVIEW ] = 'preview'
volume_types_to_option_names = {}
volume_types_to_option_names[ AUDIO_GLOBAL ] = ( 'global_audio_mute', 'global_audio_volume' )
volume_types_to_option_names[ AUDIO_MEDIA_VIEWER ] = ( 'media_viewer_audio_mute', 'media_viewer_audio_volume' )
volume_types_to_option_names[ AUDIO_PREVIEW ] = ( 'preview_audio_mute', 'preview_audio_volume' )
def ChangeVolume( volume_type, volume ):
( mute_option_name, volume_option_name ) = volume_types_to_option_names[ volume_type ]
HG.client_controller.new_options.SetInteger( volume_option_name, volume )
HG.client_controller.pub( 'new_audio_volume' )
def FlipMute( volume_type ):
( mute_option_name, volume_option_name ) = volume_types_to_option_names[ volume_type ]
HG.client_controller.new_options.FlipBoolean( mute_option_name )
HG.client_controller.pub( 'new_audio_mute' )
def SetMute( volume_type, mute ):
( mute_option_name, volume_option_name ) = volume_types_to_option_names[ volume_type ]
HG.client_controller.new_options.SetBoolean( mute_option_name, mute )
HG.client_controller.pub( 'new_audio_mute' )
class AudioMuteButton( ClientGUICommon.BetterBitmapButton ):
def __init__( self, parent, volume_type ):
self._volume_type = volume_type
pixmap = self._GetCorrectPixmap()
ClientGUICommon.BetterBitmapButton.__init__( self, parent, pixmap, FlipMute, self._volume_type )
HG.client_controller.sub( self, 'UpdateMute', 'new_audio_mute' )
def _GetCorrectPixmap( self ):
( mute_option_name, volume_option_name ) = volume_types_to_option_names[ self._volume_type ]
if HG.client_controller.new_options.GetBoolean( mute_option_name ):
pixmap = CC.GlobalPixmaps.mute
else:
pixmap = CC.GlobalPixmaps.sound
return pixmap
def UpdateMute( self ):
pixmap = self._GetCorrectPixmap()
ClientGUIFunctions.SetBitmapButtonBitmap( self, pixmap )
class VolumeControl( QW.QWidget ):
def __init__( self, parent, canvas_type, direction = 'down' ):
QW.QWidget.__init__( self, parent )
self._canvas_type = canvas_type
self._global_mute = AudioMuteButton( self, AUDIO_GLOBAL )
self._global_mute.setToolTip( 'Global mute/unmute' )
vbox = QP.VBoxLayout( margin = 0, spacing = 0 )
QP.AddToLayout( vbox, self._global_mute, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS )
self.setLayout( vbox )
self._popup_window = self._PopupWindow( self, canvas_type, direction = direction )
def enterEvent( self, event ):
if not self.isVisible():
return
self._popup_window.DoShowHide()
event.ignore()
def leaveEvent( self, event ):
if not self.isVisible():
return
self._popup_window.DoShowHide()
event.ignore()
class _PopupWindow( QW.QFrame ):
def __init__( self, parent, canvas_type, direction = 'down' ):
QW.QFrame.__init__( self, parent )
self._canvas_type = canvas_type
self._direction = direction
self.setWindowFlags( QC.Qt.Tool | QC.Qt.FramelessWindowHint )
self.setAttribute( QC.Qt.WA_ShowWithoutActivating )
if self._canvas_type == ClientGUICommon.CANVAS_MEDIA_VIEWER:
option_to_use = 'media_viewer_uses_its_own_audio_volume'
volume_type = AUDIO_MEDIA_VIEWER
else:
option_to_use = 'preview_uses_its_own_audio_volume'
volume_type = AUDIO_PREVIEW
self._specific_mute = AudioMuteButton( self, volume_type )
self._specific_mute.setToolTip( 'Mute/unmute: {}'.format( ClientGUICommon.canvas_str_lookup[ self._canvas_type ] ) )
if HG.client_controller.new_options.GetBoolean( option_to_use ):
slider_volume_type = volume_type
else:
slider_volume_type = AUDIO_GLOBAL
self._volume = VolumeSlider( self, slider_volume_type )
vbox = QP.VBoxLayout()
if self._direction == 'down':
QP.AddToLayout( vbox, self._specific_mute, CC.FLAGS_SMALL_INDENT )
QP.AddToLayout( vbox, self._volume, CC.FLAGS_SMALL_INDENT )
else:
QP.AddToLayout( vbox, self._volume, CC.FLAGS_SMALL_INDENT )
QP.AddToLayout( vbox, self._specific_mute, CC.FLAGS_SMALL_INDENT )
vbox.setAlignment( self._volume, QC.Qt.AlignHCenter )
vbox.setAlignment( self._specific_mute, QC.Qt.AlignHCenter )
self.setLayout( vbox )
self.hide()
self.adjustSize()
def DoShowHide( self ):
parent = self.parent()
horizontal_offset = ( self.width() - parent.width() ) // 2
if self._direction == 'down':
pos = parent.mapToGlobal( parent.rect().bottomLeft() )
else:
pos = parent.mapToGlobal( parent.rect().topLeft() - self.rect().bottomLeft() )
pos.setX( pos.x() - horizontal_offset )
self.move( pos )
# QWidget.underMouse() doesn't work on the border edge and hence gives flicker, so just do it manually
cursor_pos = QG.QCursor.pos()
over_parent = parent.rect().contains( parent.mapFromGlobal( cursor_pos ) )
over_me = self.rect().contains( self.mapFromGlobal( cursor_pos ) )
should_show = over_parent or over_me
if should_show:
self.show()
else:
self.hide()
def leaveEvent( self, event ):
if not self.isVisible():
return
self.DoShowHide()
event.ignore()
class VolumeSlider( QW.QSlider ):
def __init__( self, parent, volume_type ):
QW.QSlider.__init__( self, parent )
self._volume_type = volume_type
self.setOrientation( QC.Qt.Vertical )
self.setTickInterval( 1 )
self.setTickPosition( QW.QSlider.TicksBothSides )
self.setRange( 0, 100 )
volume = self._GetCorrectValue()
self.setValue( volume )
self.valueChanged.connect( self._VolumeSliderMoved )
def _GetCorrectValue( self ):
( mute_option_name, volume_option_name ) = volume_types_to_option_names[ self._volume_type ]
return HG.client_controller.new_options.GetInteger( volume_option_name )
def _VolumeSliderMoved( self ):
ChangeVolume( self._volume_type, self.value() )
def UpdateMute( self ):
volume = self._GetCorrectValue()
self.setValue( volume )