From 1837e66b4c16260152cc9e98d7331dea368ea565 Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Tue, 11 Jul 2006 17:14:16 +0000 Subject: [PATCH] finally use new styled skins for infobar, menu --- data/skin.xml | 179 ++++++++++++++++++------- data/skin_default.xml | 51 +++++-- doc/SOURCES | 165 +++++++++++++++++++++++ lib/python/Screens/ChannelSelection.py | 4 +- lib/python/Screens/InfoBar.py | 12 +- lib/python/Screens/InfoBarGenerics.py | 151 +++------------------ lib/python/Screens/Menu.py | 2 +- lib/python/Screens/PVRState.py | 4 +- 8 files changed, 354 insertions(+), 214 deletions(-) create mode 100644 doc/SOURCES diff --git a/data/skin.xml b/data/skin.xml index b5c99682..af37dbdf 100644 --- a/data/skin.xml +++ b/data/skin.xml @@ -47,70 +47,147 @@ - - - + + + - - - - - - - - - + + + + + + SNR + + + AGC + + + BER + + + + SNR + + + AGC + + + BER + - - - + + + + IsCrypted + + + + + + IsMultichannel + + + + + IsWidescreen + + - - - - - - - - - + + Name + + + + + WithSeconds + + + + StartTime + Default + + + StartTime + Default + + + Name + + + Name + + + Remaining + InMinutes + + + Duration + InMinutes + + + Progress + - - - - - - - - + + + + + + + + + + + SubservicesAvailable + + + + SubservicesAvailable + + + + + + + + + + + + + + + - - - - - - - - + + + Name + + + + Position + + + + Remaining + + + Gauge + - diff --git a/data/skin_default.xml b/data/skin_default.xml index 8cdc6752..1f4db7b2 100644 --- a/data/skin_default.xml +++ b/data/skin_default.xml @@ -4,7 +4,9 @@ - + + + @@ -209,16 +211,39 @@ - + + Name + - - - - - - - - + + WithSeconds + + + Progress + + + StartTime + Default + + + StartTime + Default + + + Name + + + Name + + + + Remaining + InMinutes + + + Duration + InMinutes + @@ -346,8 +371,10 @@ newwidth = wsize[0] - + + Remaining + diff --git a/doc/SOURCES b/doc/SOURCES new file mode 100644 index 00000000..b65a1083 --- /dev/null +++ b/doc/SOURCES @@ -0,0 +1,165 @@ +Skins are now converted to use a "source"/"covert"/"render"-mechanism. + +A "source" is a data-source. For example, the infobar has a source called +"CurrentService", which is the currently displayed service, i.e. the channel +the user is watching at the moment. + +Now, a "current service" has a lot of properties, like + - Service Name + - service number + - flags like "are subservices available?" + - playback position, length, ... + +Say you want to display the "service name" on screen. Only "renderers" can +paint on the screen. The most basic renderer is the "Label"-Renderer, which +can display a text. The "service name" is a text, so we use the +"Label"-renderer. We also know that "CurrentService" is our source. + +But the renderer can only display texts, not "services". It needs something +to turn a "service" into a "text", i.e. something which extracts the service +name out of a service. + +That's where "converters" come into action. If we want to extract the +servicename from a service, we need the "ServiceName"-converter. The +"ServiceName"-converter can not only extract the service *name*, but also +the provider name (another property of a service), so we have to specify +what we want. + +So our skin data could look like: + + + Name + + +The "call chain" consists of + +"CurrentService" -> "ServiceName(NAME)" -> "Label" + + +The are the following source types: + +Clock - the current time +EventInfo - the current now&next events +MenuList - a menu +CurrentService - the currently playing service +FrontendStatus - frontend status, like BER, Signal Strength etc. +Boolean - a usually fixed boolean value, for example "is record possible?" + +Actually used sources are defined in a "Screen". That is, a Screen offers +sources, which you can use inside your skin. + +The "Infobar", for example, offers the following sources: + +Event_Now +Event_Next +CurrentService +RecordingPossible +TimeshiftPossible +ExtensionsAvailable +Clock + +Then there are the following "Converters": + +ClockToText - turns a 'Clock' source into a text + Parameters: + "WithSeconds": "hh:mm:ss" + "InMinutes" : "mm min" + "Date" : "Wednesday, 07 June, 2006" + "Default" : "hh:mm" +EventName - extracts the event name + Parameters: + "Description": Extracts the description of the event + "ExtendedDescription": Extracts the extended description of the event + "Name": extracts the name of the event +EventTime - extracts the event time + Parameters: + "EndTime": extracts the end time of the event + "Remaining": extracts the remaining time of the event + "StartTime": extracts the start time of the event + "Duration": extracts the duration of the event + "Progress": extracts the progress of the event +RemainingToText - turns a "remaining"-time into text ("xxx m", or "+xx m") + It automatically uses the event length when the remaining time is invalid +StringList - turns a menulist into a list usable for a "Listbox"-renderer +FrontendInfo - extracts specific information out of a frontend + Parameters: + BER + SNR + AGC + LOCK + + You can either use a "Progress" or "Label" renderer, or, with Lock or + BER, you can use a ConditionalShowHide to show a "warning symbol" when + BER is >0. + +ServiceInfo - extracts info out of a service + Parameters: + HasTeletext + IsMultichannel + IsCrypted + IsWidescreen + SubservicesAvailable +ConditionalShowHide - conditionally show/hide a widgets based on the + source's boolean output + Optional parameter: "Invert" - inverts the sense, i.e. show when boolean + value is false +ServicePosition - extracts the current service play position out of a + service + Parameters: + "Length" + "Position" + "Remaining" + "Gauge" +ServiceName + Parameters: + "Name" + "Provider" + +Then there are the following renderers: +Label +Progress +Listbox +Pixmap +PositionGauge +FixedLabel + +You can also put multiple converters in a row. Each one will pick up the +output of the last coverter. + +Of course you can only connect items which are compatible. Right now you +have to look at the examples :) + +Some more examples: + +"SUBSERVICES AVAILABLE DISPLAY" +=============================== + + + SubservicesAvailable + + + +will display a pixmap whenever the "CurrentService" has +"SubservicesAvailable". + +"CURRENT SERVICE POSITION IN A POSITION GAUGE" +============================================== + + + Gauge + + +The "ServicePosition" is extracted from the CurrentService, and the +PositionGauge picks that information up and displays it on screen. + +"START TIME OF CURRENT EVENT" +============================= + + + StartTime + Default + +The StartTime is extracted from the Event_Now (current event), and converted +into text with the standard (hh:mm) style, then displayed with the +"Label"-renderer. diff --git a/lib/python/Screens/ChannelSelection.py b/lib/python/Screens/ChannelSelection.py index a52fd367..cd159681 100644 --- a/lib/python/Screens/ChannelSelection.py +++ b/lib/python/Screens/ChannelSelection.py @@ -10,7 +10,7 @@ from Screens.FixedMenu import FixedMenu from Tools.NumericalTextInput import NumericalTextInput from Components.NimManager import nimmanager from Components.ServiceName import ServiceName -from Components.Clock import Clock +from Components.Sources.Clock import Clock from Components.EventInfo import EventInfo from Components.Input import Input from Screens.InputBox import InputBox @@ -1080,7 +1080,7 @@ class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName, InfoBarInstantRecor InfoBarEvent.__init__(self) InfoBarServiceName.__init__(self) InfoBarInstantRecord.__init__(self) - self["Clock"] = Clock() + self["CurrentTime"] = Clock() class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG): def __init__(self, session): diff --git a/lib/python/Screens/InfoBar.py b/lib/python/Screens/InfoBar.py index 98a0f7cd..ca126eda 100644 --- a/lib/python/Screens/InfoBar.py +++ b/lib/python/Screens/InfoBar.py @@ -6,11 +6,10 @@ from Screens.MessageBox import MessageBox from Screens.Ci import CiHandler from ServiceReference import ServiceReference -from Components.Clock import Clock +from Components.Sources.Clock import Clock from Components.Date import DateLabel from Components.ProviderName import ProviderName from Components.ActionMap import ActionMap, HelpableActionMap -from Components.ServicePosition import ServicePosition, ServicePositionGauge from Components.config import currentConfigSelectionElement, config from Tools.Notifications import AddNotificationWithCallback @@ -63,9 +62,6 @@ class InfoBar(InfoBarShowHide, self.helpList.append((self["actions"], "InfobarActions", [("showRadio", "Hear Radio...")])) self["CurrentTime"] = Clock() - # ServicePosition(self.session.nav, ServicePosition.TYPE_REMAINING) - self["CurrentDate"] = DateLabel() - self["CurrentProvider"] = ProviderName(self.session.nav) def showTv(self): self.showTvChannelList(True) @@ -104,12 +100,6 @@ class MoviePlayer(InfoBarShowHide, \ InfoBarSummarySupport, InfoBarTeletextPlugin, InfoBarSubtitleSupport: x.__init__(self) - self["CurrentTime"] = ServicePosition(self.session.nav, ServicePosition.TYPE_REMAINING) - self["ElapsedTime"] = ServicePosition(self.session.nav, ServicePosition.TYPE_POSITION) - self["PositionGauge"] = ServicePositionGauge(self.session.nav) - - # TYPE_LENGTH? - self.lastservice = self.session.nav.getCurrentlyPlayingServiceReference() self.session.nav.playService(service) diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py index d43c9dda..f6f50b6d 100644 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -4,7 +4,6 @@ from Components.ActionMap import ActionMap, HelpableActionMap from Components.ActionMap import NumberActionMap from Components.BlinkingPixmap import BlinkingPixmapConditional from Components.Clock import Clock -from Components.EventInfo import EventInfo, EventInfoProgress from Components.Harddisk import harddiskmanager from Components.Input import Input from Components.Label import * @@ -12,11 +11,13 @@ from Components.Pixmap import Pixmap, PixmapConditional from Components.PluginComponent import plugins from Components.ProgressBar import * from Components.ServiceEventTracker import ServiceEventTracker -from Components.ServiceName import ServiceName +from Components.Sources.CurrentService import CurrentService +from Components.Sources.EventInfo import EventInfo +from Components.Sources.FrontendStatus import FrontendStatus +from Components.Sources.Boolean import Boolean +from Components.TimerList import TimerEntryComponent from Components.config import config, configElement, ConfigSubsection, configSequence, configElementBoolean, configSelection, configElement_nonSave, getConfigListEntry from Components.config import configfile, configsequencearg -from Components.TimerList import TimerEntryComponent -from Components.TunerInfo import TunerInfo from EpgSelection import EPGSelection from Plugins.Plugin import PluginDescriptor @@ -499,45 +500,17 @@ class InfoBarEPG: class InfoBarTuner: """provides a snr/agc/ber display""" def __init__(self): - self["snr"] = Label() - self["agc"] = Label() - self["ber"] = Label() - self["snr_percent"] = TunerInfo(TunerInfo.SNR_PERCENTAGE, servicefkt = self.session.nav.getCurrentService) - self["agc_percent"] = TunerInfo(TunerInfo.AGC_PERCENTAGE, servicefkt = self.session.nav.getCurrentService) - self["ber_count"] = TunerInfo(TunerInfo.BER_VALUE, servicefkt = self.session.nav.getCurrentService) - self["snr_progress"] = TunerInfo(TunerInfo.SNR_BAR, servicefkt = self.session.nav.getCurrentService) - self["agc_progress"] = TunerInfo(TunerInfo.AGC_BAR, servicefkt = self.session.nav.getCurrentService) - self["ber_progress"] = TunerInfo(TunerInfo.BER_BAR, servicefkt = self.session.nav.getCurrentService) - self.timer = eTimer() - self.timer.timeout.get().append(self.updateTunerInfo) - self.timer.start(1000) - - def updateTunerInfo(self): - if self.instance.isVisible(): - self["snr_percent"].update() - self["agc_percent"].update() - self["ber_count"].update() - self["snr_progress"].update() - self["agc_progress"].update() - self["ber_progress"].update() + self["FrontendStatus"] = FrontendStatus(service_source = self.session.nav.getCurrentService) class InfoBarEvent: """provides a current/next event info display""" def __init__(self): - self["Event_Now_StartTime"] = EventInfo(self.session.nav, EventInfo.Now_StartTime) - self["Event_Next_StartTime"] = EventInfo(self.session.nav, EventInfo.Next_StartTime) - - self["Event_Now"] = EventInfo(self.session.nav, EventInfo.Now) - self["Event_Next"] = EventInfo(self.session.nav, EventInfo.Next) - - self["Event_Now_Duration"] = EventInfo(self.session.nav, EventInfo.Now_Remaining) - self["Event_Next_Duration"] = EventInfo(self.session.nav, EventInfo.Next_Duration) - - self["Now_ProgressBar"] = EventInfoProgress(self.session.nav, EventInfo.Now) + self["Event_Now"] = EventInfo(self.session.nav, EventInfo.NOW) + self["Event_Next"] = EventInfo(self.session.nav, EventInfo.NEXT) class InfoBarServiceName: def __init__(self): - self["ServiceName"] = ServiceName(self.session.nav) + self["CurrentService"] = CurrentService(self.session.nav) class InfoBarSeek: """handles actions like seeking, pause""" @@ -940,7 +913,9 @@ class InfoBarTimeshift: if not ts.startTimeshift(): import time self.timeshift_enabled = 1 - self.pvrStateDialog["timeshift"].setRelative(time.time()) + + # we remove the "relative time" for now. + #self.pvrStateDialog["timeshift"].setRelative(time.time()) # PAUSE. self.setSeekState(self.SEEK_STATE_PAUSE) @@ -1367,36 +1342,12 @@ class InfoBarAdditionalInfo: def __init__(self): self["NimA"] = Pixmap() self["NimB"] = Pixmap() - self["TextActive"] = Pixmap() - self["DolbyActive"] = Pixmap() - self["CryptActive"] = Pixmap() - self["FormatActive"] = Pixmap() self["NimA_Active"] = Pixmap() self["NimB_Active"] = Pixmap() - self["ButtonRed"] = PixmapConditional(withTimer = False) - self["ButtonRed"].setConnect(lambda: harddiskmanager.HDDCount() > 0) - self.onLayoutFinish.append(self["ButtonRed"].update) - self["ButtonRedText"] = LabelConditional(text = _("Record"), withTimer = False) - self["ButtonRedText"].setConnect(lambda: harddiskmanager.HDDCount() > 0) - self.onLayoutFinish.append(self["ButtonRedText"].update) - - self["ButtonGreen"] = Pixmap() - self["ButtonGreenText"] = Label(_("Subservices")) - - self["ButtonYellow"] = PixmapConditional(withTimer = False) - self["ButtonYellow"].setConnect(lambda: harddiskmanager.HDDCount() > 0) - self["ButtonYellowText"] = LabelConditional(text = _("Timeshifting"), withTimer = False) - self["ButtonYellowText"].setConnect(lambda: harddiskmanager.HDDCount() > 0) - self.onLayoutFinish.append(self["ButtonYellow"].update) - self.onLayoutFinish.append(self["ButtonYellowText"].update) - - self["ButtonBlue"] = PixmapConditional(withTimer = False) - self["ButtonBlue"].setConnect(lambda: True) - self["ButtonBlueText"] = LabelConditional(text = _("Extensions"), withTimer = False) - self["ButtonBlueText"].setConnect(lambda: True) - self.onLayoutFinish.append(self["ButtonBlue"].update) - self.onLayoutFinish.append(self["ButtonBlueText"].update) + self["RecordingPossible"] = Boolean(fixed=harddiskmanager.HDDCount() > 0) + self["TimeshiftPossible"] = self["RecordingPossible"] + self["ExtensionsAvailable"] = Boolean(fixed=1) self.session.nav.event.append(self.gotServiceEvent) # we like to get service events res_mgr = eDVBResourceManagerPtr() @@ -1413,63 +1364,6 @@ class InfoBarAdditionalInfo: else: self["NimB_Active"].hide() - def hideSubServiceIndication(self): - self["ButtonGreen"].hide() - self["ButtonGreenText"].hide() - - def showSubServiceIndication(self): - self["ButtonGreen"].show() - self["ButtonGreenText"].show() - - def checkFormat(self, service): - info = service.info() - if info: - aspect = info.getInfo(iServiceInformation.sAspect) - if aspect in [ 3, 4, 7, 8, 0xB, 0xC, 0xF, 0x10 ]: - self["FormatActive"].show() - return - self["FormatActive"].hide() - - def checkText(self, service): - info = service.info() - if info: - tpid = info.getInfo(iServiceInformation.sTXTPID) - if tpid != -1: - self["TextActive"].show() - return - self["TextActive"].hide() - - def checkSubservices(self, service): - subservices = service.subServices() - if subservices and subservices.getNumberOfSubservices() > 0: - self.showSubServiceIndication() - else: - self.hideSubServiceIndication() - - def checkDolby(self, service): - # FIXME - dolby = False - audio = service.audioTracks() - if audio: - n = audio.getNumberOfTracks() - for x in range(n): - i = audio.getTrackInfo(x) - description = i.getDescription(); - if description.find("AC3") != -1 or description.find("DTS") != -1: - dolby = True - break - if dolby: - self["DolbyActive"].show() - else: - self["DolbyActive"].hide() - - def checkCrypted(self, service): - info = service.info() - if info and info.getInfo(iServiceInformation.sIsCrypted) > 0: - self["CryptActive"].show() - else: - self["CryptActive"].hide() - def checkTunerState(self, service): info = service.frontendInfo() feNumber = info and info.getFrontendInfo(iFrontendInformation.frontendNumber) @@ -1487,19 +1381,6 @@ class InfoBarAdditionalInfo: service = self.session.nav.getCurrentService() if ev == iPlayableService.evStart: self.checkTunerState(service) - elif ev == iPlayableService.evUpdatedEventInfo: - self.checkSubservices(service) - self.checkFormat(service) - elif ev == iPlayableService.evUpdatedInfo: - self.checkCrypted(service) - self.checkDolby(service) - self.checkText(service) - elif ev == iPlayableService.evEnd: - self.hideSubServiceIndication() - self["CryptActive"].hide() - self["DolbyActive"].hide() - self["FormatActive"].hide() - self["TextActive"].hide() class InfoBarNotifications: def __init__(self): @@ -1668,7 +1549,7 @@ class InfoBarSummary(Screen): def __init__(self, session, parent): Screen.__init__(self, session) - self["CurrentService"] = ServiceName(self.session.nav) + self["CurrentService"] = CurrentService(self.session.nav) self["Clock"] = Clock() class InfoBarSummarySupport: diff --git a/lib/python/Screens/Menu.py b/lib/python/Screens/Menu.py index f1a01348..4d112abb 100644 --- a/lib/python/Screens/Menu.py +++ b/lib/python/Screens/Menu.py @@ -1,5 +1,5 @@ from Screen import * -from Components.MenuList import MenuList +from Components.Sources.MenuList import MenuList from Components.ActionMap import ActionMap from Components.Header import Header from Components.Button import Button diff --git a/lib/python/Screens/PVRState.py b/lib/python/Screens/PVRState.py index 051d6288..b2c8a4d9 100644 --- a/lib/python/Screens/PVRState.py +++ b/lib/python/Screens/PVRState.py @@ -1,7 +1,7 @@ from Screen import Screen from Components.Label import Label -from Components.ServicePosition import ServicePosition +from Components.Sources.CurrentService import CurrentService from enigma import * @@ -15,4 +15,4 @@ class TimeshiftState(PVRState): def __init__(self, session): PVRState.__init__(self, session) - self["timeshift"] = ServicePosition(self.session.nav, ServicePosition.TYPE_RELATIVE) + self["CurrentService"] = CurrentService(self.session.nav) -- 2.30.2