286 lines
8.4 KiB
Python
286 lines
8.4 KiB
Python
from qtpy import QtCore as QC
|
|
from qtpy import QtWidgets as QW
|
|
from qtpy import QtGui as QG
|
|
|
|
from hydrus.core import HydrusGlobals as HG
|
|
|
|
from hydrus.client import ClientConstants as CC
|
|
from hydrus.client.gui import ClientGUIFunctions
|
|
from hydrus.client.gui import QtPorting as QP
|
|
from hydrus.client.gui.widgets import ClientGUICommon
|
|
|
|
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.global_pixmaps().mute
|
|
|
|
else:
|
|
|
|
pixmap = CC.global_pixmaps().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_CENTER )
|
|
QP.AddToLayout( vbox, self._volume, CC.FLAGS_CENTER )
|
|
|
|
else:
|
|
|
|
QP.AddToLayout( vbox, self._volume, CC.FLAGS_CENTER )
|
|
QP.AddToLayout( vbox, self._specific_mute, CC.FLAGS_CENTER )
|
|
|
|
|
|
#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.parentWidget()
|
|
|
|
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 )
|
|
|
|
|