diff --git a/data/keymap.xml b/data/keymap.xml index b9e86eea38a..d0a4a0992f2 100644 --- a/data/keymap.xml +++ b/data/keymap.xml @@ -15,7 +15,11 @@ + + + + diff --git a/data/setup.xml b/data/setup.xml index 8f762d9a441..a9eeb8e3262 100644 --- a/data/setup.xml +++ b/data/setup.xml @@ -3,6 +3,9 @@ + config.volumeControl.pressStep + config.volumeControl.longStep + config.volumeControl.hideTimer config.av.pcm_multichannel config.av.downmix_ac3 config.av.transcodeac3plus @@ -18,11 +21,6 @@ config.av.surround_3d config.av.surround_3d_speaker config.av.autovolume - config.av.volume_stepsize - config.av.volume_stepsize_fastmode - config.audio.volumeLogSteps - config.audio.volumeHideTimer - config.av.volume_hide_mute config.av.btaudio config.av.btaudiodelay diff --git a/lib/python/Components/AVSwitch.py b/lib/python/Components/AVSwitch.py index 331c07e07da..d80eeb36dc3 100644 --- a/lib/python/Components/AVSwitch.py +++ b/lib/python/Components/AVSwitch.py @@ -2,7 +2,7 @@ from os import W_OK, access, system from time import sleep -from enigma import eAVControl, eDVBVolumecontrol, getDesktop +from enigma import eAVControl, getDesktop from Components.config import ConfigBoolean, ConfigEnableDisable, ConfigInteger, ConfigNothing, ConfigOnOff, ConfigSelection, ConfigSelectionInteger, ConfigSelectionNumber, ConfigSlider, ConfigSubDict, ConfigSubsection, ConfigText, ConfigYesNo, NoSave, config from Components.About import about @@ -611,13 +611,6 @@ def setPCMMultichannel(configElement): config.av.pcm_multichannel = ConfigYesNo(default=False) config.av.pcm_multichannel.addNotifier(setPCMMultichannel) - def setVolumeStepSize(configElement): - eDVBVolumecontrol.getInstance().setVolumeSteps(int(configElement.value)) - - config.av.volume_stepsize = ConfigSelectionNumber(min=1, max=10, stepwidth=1, default=5) - config.av.volume_stepsize.addNotifier(setVolumeStepSize) - config.av.volume_stepsize_fastmode = ConfigSelectionNumber(min=1, max=10, stepwidth=1, default=5) - config.av.volume_hide_mute = ConfigYesNo(default=True) if AMLOGIC: downmixAC3 = True BoxInfo.setItem("CanPcmMultichannel", True) diff --git a/lib/python/Components/VolumeControl.py b/lib/python/Components/VolumeControl.py index 9357f1b1e30..c4548f8b823 100644 --- a/lib/python/Components/VolumeControl.py +++ b/lib/python/Components/VolumeControl.py @@ -1,161 +1,123 @@ from enigma import eDVBVolumecontrol, eTimer from GlobalActions import globalActionMap -from Components.config import ConfigInteger, ConfigSelectionNumber, ConfigSubsection, ConfigYesNo, config -from Screens.Mute import Mute -from Screens.Volume import Volume +from Components.config import ConfigBoolean, ConfigInteger, ConfigSelectionNumber, ConfigSubsection, config +from Screens.VolumeControl import Mute, Volume +# NOTE: This code does not remember the current volume as other code can change +# the volume directly. Always get the current volume from the driver. +# class VolumeControl: - """Volume control, handles volUp, volDown, volMute actions and display a corresponding dialog.""" + """Volume control, handles volumeUp, volumeDown, volumeMute, and other actions and display a corresponding dialog.""" instance = None def __init__(self, session): - global globalActionMap - globalActionMap.actions["volumeUp"] = self.volUp - globalActionMap.actions["volumeDown"] = self.volDown - globalActionMap.actions["volumeMute"] = self.volMute - globalActionMap.actions["volumeMuteLong"] = self.volMuteLong - assert not VolumeControl.instance, "[VolumeControl] Error: Only one VolumeControl instance is allowed!" - VolumeControl.instance = self - config.audio = ConfigSubsection() - config.audio.volume = ConfigInteger(default=50, limits=(0, 100)) - config.audio.volumeLogSteps = ConfigYesNo(default=True) - config.audio.volumeHideTimer = ConfigSelectionNumber(1, 10, 1, default=3) - self.volumeDialog = session.instantiateDialog(Volume) - self.volumeDialog.setAnimationMode(0) - self.muteDialog = session.instantiateDialog(Mute) - self.muteDialog.setAnimationMode(0) - self.hideVolTimer = eTimer() - self.hideVolTimer.callback.append(self.volHide) - self.stepVolTimer = eTimer() - self.repeat = 500 - self.delay = 3000 - vol = config.audio.volume.value - self.volumeDialog.setValue(vol) - self.volctrl = eDVBVolumecontrol.getInstance() - self.volctrl.setVolume(vol, vol) - self.last_vol = vol + def updateStep(configElement): + self.dvbVolumeControl.setVolumeSteps(configElement.value) - def volSave(self): - if self.volctrl.isMuted(): - config.audio.volume.setValue(0) + if VolumeControl.instance: + print("[VolumeControl] Error: Only one VolumeControl instance is allowed!") else: - config.audio.volume.setValue(self.volctrl.getVolume()) - config.audio.volume.save() + VolumeControl.instance = self + global globalActionMap + globalActionMap.actions["volumeUp"] = self.keyVolumeUp + globalActionMap.actions["volumeUpLong"] = self.keyVolumeLong + globalActionMap.actions["volumeUpStop"] = self.keyVolumeStop + globalActionMap.actions["volumeDown"] = self.keyVolumeDown + globalActionMap.actions["volumeDownLong"] = self.keyVolumeLong + globalActionMap.actions["volumeDownStop"] = self.keyVolumeStop + globalActionMap.actions["volumeMute"] = self.keyVolumeMute + globalActionMap.actions["volumeMuteLong"] = self.keyVolumeMuteLong + self.dvbVolumeControl = eDVBVolumecontrol.getInstance() + config.volumeControl = ConfigSubsection() + config.volumeControl.volume = ConfigInteger(default=20, limits=(0, 100)) + config.volumeControl.mute = ConfigBoolean(default=False) + config.volumeControl.pressStep = ConfigSelectionNumber(1, 10, 1, default=1) + config.volumeControl.pressStep.addNotifier(updateStep, initial_call=True, immediate_feedback=True) + config.volumeControl.longStep = ConfigSelectionNumber(1, 10, 1, default=5) + config.volumeControl.hideTimer = ConfigSelectionNumber(1, 10, 1, default=3) + self.muteDialog = session.instantiateDialog(Mute) + self.muteDialog.setAnimationMode(0) + self.volumeDialog = session.instantiateDialog(Volume) + self.volumeDialog.setAnimationMode(0) + self.hideTimer = eTimer() + self.hideTimer.callback.append(self.hideVolume) + if config.volumeControl.mute.value: + self.dvbVolumeControl.volumeMute() + self.muteDialog.show() + volume = config.volumeControl.volume.value + self.volumeDialog.setValue(volume) + self.dvbVolumeControl.setVolume(volume, volume) + # Compatibility interface for shared plugins. + self.volctrl = self.dvbVolumeControl + self.hideVolTimer = self.hideTimer - def volUp(self): - vol = self.volctrl.getVolume() - step = self.stepVolume() - if config.audio.volumeLogSteps.value: - if vol < 3: - step = 1 - elif vol < 9: - if step > 2: - step = 2 - elif vol < 18: - if step > 3: - step = 3 - elif vol < 30: - if step > 4: - step = 4 - self.setVolume(vol + step) + def keyVolumeUp(self): + self.dvbVolumeControl.volumeUp(0, 0) + self.updateVolume() - def volDown(self): - vol = self.volctrl.getVolume() - step = self.stepVolume() - if config.audio.volumeLogSteps.value: - if vol <= 3: - step = 1 - elif vol <= 9: - if step > 2: - step = 2 - elif vol <= 18: - if step > 3: - step = 3 - elif vol <= 30: - if step > 4: - step = 4 - self.setVolume(vol - step) - - def stepVolume(self): - if self.stepVolTimer.isActive(): - step = config.av.volume_stepsize_fastmode.value - else: - self.getInputConfig() - step = config.av.volume_stepsize.value - self.stepVolTimer.start(self.repeat, True) - return step - - def getInputConfig(self): - if self.hideVolTimer.isActive(): - return - try: - inputconfig = config.inputDevices.getSavedValue() - except KeyError: - return - delay = 0 - repeat = 0 - - for device in inputconfig.values(): - if "enabled" in device and bool(device["enabled"]): - if "delay" in device: - val = int(device["delay"]) - if val > delay: - delay = val - if "repeat" in device: - val = int(device["repeat"]) - if val > repeat: - repeat = val - if repeat + 100 > self.repeat: - self.repeat = repeat + 100 - if delay + 100 > self.delay: - self.delay = delay + 100 - - def setVolume(self, newvol): - self.volctrl.setVolume(newvol, newvol) - is_muted = self.volctrl.isMuted() - vol = self.volctrl.getVolume() - self.last_vol = vol - self.volumeDialog.show() - if is_muted: - self.volMute() # Unmute. - elif not vol: - self.volMute(False, True) # Mute but don't show mute symbol. - if self.volctrl.isMuted(): - self.volumeDialog.setValue(0) - else: - self.volumeDialog.setValue(self.volctrl.getVolume()) - self.volSave() - self.hideVolTimer.start(self.delay, True) + def keyVolumeDown(self): + self.dvbVolumeControl.volumeDown(0, 0) + self.updateVolume() - def volHide(self): - self.volumeDialog.hide() - # Set volume on if muted and volume is changed in OpenWebif. - vol = self.volctrl.getVolume() - if self.volctrl.isMuted() and self.last_vol != vol: - self.volctrl.volumeUnMute() - self.last_vol = vol - # - if not self.volctrl.isMuted() or config.av.volume_hide_mute.value: - self.muteDialog.hide() - - def showMute(self): - if self.volctrl.isMuted(): - self.muteDialog.show() - self.hideVolTimer.start(int(config.audio.volumeHideTimer.value) * 1000, True) - - def volMute(self, showMuteSymbol=True, force=False): - vol = self.volctrl.getVolume() - if vol or force: - self.volctrl.volumeToggleMute() - if self.volctrl.isMuted(): - if showMuteSymbol: - self.showMute() - self.volumeDialog.setValue(0) + def keyVolumeLong(self): + self.dvbVolumeControl.setVolumeSteps(config.volumeControl.longStep.value) + + def keyVolumeStop(self): + self.dvbVolumeControl.setVolumeSteps(config.volumeControl.pressStep.value) + + def keyVolumeMute(self): # This will toggle the current mute status. Mute will not be activated if the volume is at 0. + volume = self.dvbVolumeControl.getVolume() + isMuted = self.dvbVolumeControl.isMuted() + if volume or (volume == 0 and isMuted): + self.dvbVolumeControl.volumeToggleMute() + if self.dvbVolumeControl.isMuted(): + self.muteDialog.show() + self.volumeDialog.hide() else: self.muteDialog.hide() - self.volumeDialog.setValue(vol) + self.volumeDialog.setValue(volume) + self.volumeDialog.show() + self.hideTimer.start(config.volumeControl.hideTimer.value * 1000, True) + + def keyVolumeMuteLong(self): # Long press MUTE will keep the mute icon on-screen without a timeout. + if self.dvbVolumeControl.isMuted(): + self.hideTimer.stop() + + def updateVolume(self): + if self.dvbVolumeControl.isMuted(): + self.keyVolumeMute() # Unmute. + else: + self.volumeDialog.setValue(self.dvbVolumeControl.getVolume()) + self.volumeDialog.show() + self.hideTimer.start(config.volumeControl.hideTimer.value * 1000, True) - def volMuteLong(self): + def hideVolume(self): self.muteDialog.hide() + self.volumeDialog.hide() + + def saveVolumeState(self): + config.volumeControl.mute.value = self.dvbVolumeControl.isMuted() + config.volumeControl.volume.setValue(self.dvbVolumeControl.getVolume()) + config.volumeControl.save() + + def showMute(self): # This method is only called by InfoBarGenerics.py: + if self.dvbVolumeControl.isMuted(): + self.muteDialog.show() + self.hideTimer.start(config.volumeControl.hideTimer.value * 1000, True) + + # These methods are provided for compatibly with shared plugins. + # + def volUp(self): + self.keyVolumeUp() + + def volDown(self): + self.keyVolumeDown() + + def volMute(self): + self.keyVolumeMute() + + def volSave(self): + # Volume (and mute) saving is now done when Enigma2 shuts down. + pass diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py index 11274e5ecb4..48b3bf87893 100644 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -10,7 +10,7 @@ from sys import maxsize from time import localtime, strftime, time -from enigma import eActionMap, eAVControl, eDBoxLCD, eDVBDB, eDVBServicePMTHandler, eDVBVolumecontrol, eEPGCache, eServiceCenter, eServiceReference, eTimer, getBsodCounter, getDesktop, iPlayableService, iServiceInformation, quitMainloop, resetBsodCounter, eDVBVolumecontrol +from enigma import eActionMap, eAVControl, eDBoxLCD, eDVBDB, eDVBServicePMTHandler, eDVBVolumecontrol, eEPGCache, eServiceCenter, eServiceReference, eTimer, getBsodCounter, getDesktop, iPlayableService, iServiceInformation, quitMainloop, resetBsodCounter from keyids import KEYFLAGS, KEYIDNAMES, KEYIDS from RecordTimer import AFTEREVENT, RecordTimer, RecordTimerEntry, findSafeRecordPath, parseEvent @@ -1756,10 +1756,10 @@ def zapDown(self): self["SeekActionsPTS"].setEnabled(True) def volumeUp(self): # Called from ButtonSetup - VolumeControl.instance.volUp() + VolumeControl.instance.keyVolumeUp() def volumeDown(self): # Called from ButtonSetup - VolumeControl.instance.volDown() + VolumeControl.instance.keyVolumeDown() class InfoBarMenu: diff --git a/lib/python/Screens/Mute.py b/lib/python/Screens/Mute.py deleted file mode 100644 index d99050d8611..00000000000 --- a/lib/python/Screens/Mute.py +++ /dev/null @@ -1,5 +0,0 @@ -from Screens.Screen import Screen - - -class Mute(Screen): - pass diff --git a/lib/python/Screens/Volume.py b/lib/python/Screens/VolumeControl.py similarity index 93% rename from lib/python/Screens/Volume.py rename to lib/python/Screens/VolumeControl.py index abe978fe4dd..1d9d3b0464d 100644 --- a/lib/python/Screens/Volume.py +++ b/lib/python/Screens/VolumeControl.py @@ -3,13 +3,17 @@ from Screens.Screen import Screen +class Mute(Screen): + pass + + class Volume(Screen): def __init__(self, session): Screen.__init__(self, session) - self["Volume"] = VolumeBar() self["VolumeText"] = Label() + self["Volume"] = VolumeBar() def setValue(self, volume): print(f"[Volume] Volume set to {volume}.") - self["Volume"].setValue(volume) self["VolumeText"].setText(str(volume)) + self["Volume"].setValue(volume) diff --git a/lib/python/StartEnigma.py b/lib/python/StartEnigma.py index 8d2f83fd1c5..02df9d4eb1b 100644 --- a/lib/python/StartEnigma.py +++ b/lib/python/StartEnigma.py @@ -559,6 +559,7 @@ def runNextScreen(session, screensToRun, *result): print("=" * 100) session.nav.stopService() session.nav.shutdown() + VolumeControl.instance.saveVolumeState() configfile.save() from Screens.InfoBarGenerics import saveResumePoints saveResumePoints()