Skip to content

Commit

Permalink
Merge pull request #3788 from DimitarCC/dev-screens-ui-extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
littlesat committed Oct 6, 2023
2 parents bd82070 + 8b35c32 commit d14a85b
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 28 deletions.
22 changes: 19 additions & 3 deletions lib/python/Components/ChoiceList.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,34 @@
from Components.MenuList import MenuList
from Components.MultiContent import MultiContentEntryText
from Tools.Directories import SCOPE_CURRENT_SKIN, resolveFilename
from enigma import RT_HALIGN_LEFT, eListboxPythonMultiContent, gFont
from enigma import RT_HALIGN_LEFT, RT_VALIGN_CENTER, eListboxPythonMultiContent, gFont
from Tools.LoadPixmap import LoadPixmap
from skin import applySkinFactor, fonts, parameters


def ChoiceEntryComponent(key=None, text=["--"]):
res = [text]
if text[0] == "--":
# Get are we want graphical separator (solid line with color) or dashed line
isUseGraphicalSeparator = parameters.get("UseGraphicalSeparator", 0)
x, y, w, h = parameters.get("ChoicelistDash", applySkinFactor(0, 0, 800, 25))
res.append((eListboxPythonMultiContent.TYPE_TEXT, x, y, w, h, 0, RT_HALIGN_LEFT, "-" * 200))
if isUseGraphicalSeparator:
bk_color = parameters.get("ChoicelistSeparatorColor", "0x00555556")
res.append(MultiContentEntryText(
pos=(x, y + 20),
size=(w, 2),
font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER,
text="",
color=None, color_sel=None,
backcolor=bk_color, backcolor_sel=bk_color))
else:
res.append((eListboxPythonMultiContent.TYPE_TEXT, x, y, w, h, 0, RT_HALIGN_LEFT, "-" * 200))
else:
if key:
x, y, w, h = parameters.get("ChoicelistName", applySkinFactor(45, 0, 800, 25))
res.append((eListboxPythonMultiContent.TYPE_TEXT, x, y, w, h, 0, RT_HALIGN_LEFT, text[0]))
# separate the sizes definition for keybutton is=cons and the rest so there to be possibility to use different size images for different type icons
iconKeyConfigName = "ChoicelistIcon"
if key == "dummy":
png = None
elif key == "expandable":
Expand All @@ -25,9 +40,10 @@ def ChoiceEntryComponent(key=None, text=["--"]):
elif key == "bullet":
png = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/bullet.png"))
else:
iconKeyConfigName = "ChoicelistButtonIcon"
png = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "buttons/key_%s.png" % key))
if png:
x, y, w, h = parameters.get("ChoicelistIcon", applySkinFactor(5, 0, 35, 25))
x, y, w, h = parameters.get(iconKeyConfigName, applySkinFactor(5, 0, 35, 25))
res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, x, y, w, h, png))
else:
x, y, w, h = parameters.get("ChoicelistNameSingle", applySkinFactor(5, 0, 800, 25))
Expand Down
5 changes: 4 additions & 1 deletion lib/python/Components/Pixmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ class Pixmap(GUIComponent):
def getSize(self):
s = self.instance.size()
return (s.width(), s.height())

def setPixmap(self, pixmap):
self.instance.setPixmap(pixmap)


class PixmapConditional(ConditionalWidget, Pixmap):
Expand Down Expand Up @@ -120,4 +123,4 @@ def setPixmapNum(self, x):
if len(self.pixmaps) > x:
self.instance.setPixmap(self.pixmaps[x])
else:
print("setPixmapNum(%d) failed! defined pixmaps:" % (x), self.pixmaps)
print("setPixmapNum(%d) failed! defined pixmaps:" % (x), self.pixmaps)
10 changes: 10 additions & 0 deletions lib/python/Components/PluginComponent.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,16 @@ def getPluginsForMenu(self, menuid):
for p in self.getPlugins(PluginDescriptor.WHERE_MENU):
res += p(menuid)
return res

def getDescriptionForMenuEntryID(self, menuid, entryid ):
for p in self.getPlugins(PluginDescriptor.WHERE_MENU):
if p(menuid) and isinstance(p(menuid), (list,tuple)):
if p(menuid)[0][2] == entryid:
return p.description
return None

def getPluginsForMenuWithDescription(self, menuid):
return [(x[0], p.description) for p in self.getPlugins(PluginDescriptor.WHERE_MENU) if (x := p(menuid))]

def clearPluginList(self):
self.pluginList = []
Expand Down
9 changes: 7 additions & 2 deletions lib/python/Screens/AudioSelection.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,18 @@
from Components.UsageConfig import originalAudioTracks, visuallyImpairedCommentary
from Components.Converter.ServiceInfo import StdAudioDesc
from Tools.ISO639 import LanguageCodes
from Tools.Directories import resolveFilename, SCOPE_CURRENT_SKIN
from Tools.LoadPixmap import LoadPixmap

from enigma import iPlayableService, eTimer, eSize, eDVBDB, eServiceReference, eServiceCenter, iServiceInformation

FOCUS_CONFIG, FOCUS_STREAMS = range(2)
[PAGE_AUDIO, PAGE_SUBTITLES] = ["audio", "subtitles"]


selectionpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "selections/audioselectionmark.png"))


class AudioSelection(ConfigListScreen, Screen):
def __init__(self, session, infobar=None, page=PAGE_AUDIO):
Screen.__init__(self, session)
Expand Down Expand Up @@ -146,7 +151,7 @@ def fillList(self, arg=None):
language += lang
cnt += 1

streams.append((x, "", number, description, language, selected))
streams.append((x, "", number, description, language, selected, selectionpng if selected == "X" else None))

else:
streams = []
Expand Down Expand Up @@ -229,7 +234,7 @@ def __call__(self, *args, **kwargs):
description = _("unknown") + ": %s" % x[2]
number = str(int(number) + 1)

streams.append((x, "", number, description, language, selected))
streams.append((x, "", number, description, language, selected, selectionpng if selected == "X" else None))
idx += 1

conflist.append((_("To audio selection"), self.settings.menupage))
Expand Down
75 changes: 61 additions & 14 deletions lib/python/Screens/Menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,48 @@
from Components.Sources.StaticText import StaticText
from Components.config import configfile
from Components.PluginComponent import plugins
from Components.NimManager import nimmanager
from Components.config import config, ConfigDictionarySet, NoSave
from Components.SystemInfo import SystemInfo
from Tools.BoundFunction import boundFunction
from Plugins.Plugin import PluginDescriptor
from Tools.Directories import resolveFilename, SCOPE_SKIN
from Tools.Directories import resolveFilename, SCOPE_SKINS, SCOPE_GUISKIN
from Tools.LoadPixmap import LoadPixmap
from enigma import eTimer

import xml.etree.ElementTree

from Screens.Setup import Setup, getSetupTitle

def MenuEntryPixmap(entryID, png_cache, parentMenuEntryID):
# imported here to avoid circular import
from skin import parameters
icoSize = int(parameters.get("MenuIconsSize", 192))
width = icoSize
height = icoSize
png = png_cache.get(entryID, None)
if png is None: # no cached entry
pngPath = resolveFilename(SCOPE_GUISKIN, "menu/" + entryID + ".svg")
pos = config.skin.primary_skin.value.rfind('/')
if pos > -1:
current_skin = config.skin.primary_skin.value[:pos+1]
else:
current_skin = ""
if ( current_skin in pngPath and current_skin ) or not current_skin:
png = LoadPixmap(pngPath, cached=True, width=width, height=0 if pngPath.endswith(".svg") else height) #looking for a dedicated icon
if png is None: # no dedicated icon found
if parentMenuEntryID is not None: # check do we have parent menu item that can use for icon
png = png_cache.get(parentMenuEntryID, None)
png_cache[entryID] = png
if png is None:
png = png_cache.get("missing", None)
if png is None:
pngPath = resolveFilename(SCOPE_GUISKIN, "menu/missing.svg")
png = LoadPixmap(pngPath, cached=True, width=width, height=0 if pngPath.endswith(".svg") else height)
png_cache["missing"] = png
return png

# read the menu
mdom = xml.etree.ElementTree.parse(resolveFilename(SCOPE_SKIN, 'menu.xml'))
mdom = xml.etree.ElementTree.parse(resolveFilename(SCOPE_SKINS, 'menu.xml'))


class MenuSummary(Screen):
Expand All @@ -30,6 +58,7 @@ def __init__(self, session, parent):

class Menu(Screen, ProtectedScreen):
ALLOW_SUSPEND = True
png_cache = {}

def okbuttonClick(self):
if self.number:
Expand Down Expand Up @@ -61,7 +90,7 @@ def openDialog(self, *dialog): # in every layer needed
def openSetup(self, dialog):
self.session.openWithCallback(self.menuClosed, Setup, dialog)

def addMenu(self, destList, node):
def addMenu(self, destList, node, parent=None):
requires = node.get("requires")
if requires:
if requires[0] == '!':
Expand All @@ -72,13 +101,16 @@ def addMenu(self, destList, node):
MenuTitle = _(node.get("text", "??"))
entryID = node.get("entryID", "undefined")
weight = node.get("weight", 50)
description = node.get("description", "").encode("UTF-8") or None
description = description and _(description)
menupng = MenuEntryPixmap(entryID, self.png_cache, parent)
x = node.get("flushConfigOnClose")
if x:
a = boundFunction(self.session.openWithCallback, self.menuClosedWithConfigFlush, Menu, node)
else:
a = boundFunction(self.session.openWithCallback, self.menuClosed, Menu, node)
#TODO add check if !empty(node.childNodes)
destList.append((MenuTitle, a, entryID, weight))
destList.append((MenuTitle, a, entryID, weight, description, menupng))

def menuClosedWithConfigFlush(self, *res):
configfile.save()
Expand All @@ -92,7 +124,7 @@ def menuClosed(self, *res):
else:
self.createMenuList()

def addItem(self, destList, node):
def addItem(self, destList, node, parent=None):
requires = node.get("requires")
if requires:
if requires[0] == '!':
Expand All @@ -106,6 +138,9 @@ def addItem(self, destList, node):
item_text = node.get("text", "")
entryID = node.get("entryID", "undefined")
weight = node.get("weight", 50)
description = node.get("description", "").encode("UTF-8") or None
description = description and _(description)
menupng = MenuEntryPixmap(entryID, self.png_cache, parent)
for x in node:
if x.tag == 'screen':
module = x.get("module")
Expand All @@ -125,20 +160,20 @@ def addItem(self, destList, node):
args = x.text or ""
screen += ", " + args

destList.append((_(item_text or "??"), boundFunction(self.runScreen, (module, screen)), entryID, weight))
destList.append((_(item_text or "??"), boundFunction(self.runScreen, (module, screen)), entryID, weight, description, menupng))
return
elif x.tag == 'code':
destList.append((_(item_text or "??"), boundFunction(self.execText, x.text), entryID, weight))
destList.append((_(item_text or "??"), boundFunction(self.execText, x.text), entryID, weight, description, menupng))
return
elif x.tag == 'setup':
id = x.get("id")
if item_text == "":
item_text = _(getSetupTitle(id))
else:
item_text = _(item_text)
destList.append((item_text, boundFunction(self.openSetup, id), entryID, weight))
destList.append((item_text, boundFunction(self.openSetup, id), entryID, weight, description, menupng))
return
destList.append((item_text, self.nothing, entryID, weight))
destList.append((item_text, self.nothing, entryID, weight, description, menupng))

def sortByName(self, listentry):
return listentry[0].lower()
Expand Down Expand Up @@ -204,33 +239,36 @@ def createMenuList(self, showNumericHelp=False):
self["key_blue"].text = _("Edit menu") if config.usage.menu_sort_mode.value == "user" else ""
self.list = []
self.menuID = None
parentEntryID = None
for x in self.parentmenu: #walk through the actual nodelist
if not x.tag:
continue
parentEntryID = self.parentmenu.get("entryID", None)
if x.tag == 'item':
item_level = int(x.get("level", 0))
if item_level <= config.usage.setup_level.index:
self.addItem(self.list, x)
self.addItem(self.list, x, parentEntryID)
count += 1
elif x.tag == 'menu':
item_level = int(x.get("level", 0))
if item_level <= config.usage.setup_level.index:
self.addMenu(self.list, x)
self.addMenu(self.list, x, parentEntryID)
count += 1
elif x.tag == "id":
self.menuID = x.get("val")
count = 0

if self.menuID:
# plugins
for l in plugins.getPluginsForMenu(self.menuID):
for l, description in plugins.getPluginsForMenuWithDescription(self.menuID):
# check if a plugin overrides an existing menu
plugin_menuid = l[2]
for x in self.list:
if x[2] == plugin_menuid:
self.list.remove(x)
break
self.list.append((l[0], boundFunction(l[1], self.session, close=self.close), l[2], l[3] or 50))
menupng = MenuEntryPixmap(l[2], self.png_cache, parentEntryID)
self.list.append((l[0], boundFunction(l[1], self.session, close=self.close), l[2], l[3] or 50, description, menupng))

if "user" in config.usage.menu_sort_mode.value and self.menuID == "mainmenu":
plugin_list = []
Expand Down Expand Up @@ -272,6 +310,15 @@ def createMenuList(self, showNumericHelp=False):

self["menu"].updateList(self.list)

def _onSelectionChanged(self):
current = self["menu"].current
description, pixmap = "", None
if current:
description, pixmap = current[4:]
self["description"].setText(_(description))
if pixmap:
self["pixmap"].setPixmap(pixmap)

def keyNumberGlobal(self, number):
self.number = self.number * 10 + number
if self.number and self.number <= len(self["menu"].list):
Expand Down
1 change: 1 addition & 0 deletions lib/python/Screens/MessageBox.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def __init__(self, session, text, type=TYPE_YESNO, timeout=-1, close_on_any_key=
self["text"] = Label(text)
self["Text"] = StaticText(text)
self["selectedChoice"] = StaticText()
self["title_sep"] = Label("")

self.text = text
self.close_on_any_key = close_on_any_key
Expand Down
18 changes: 15 additions & 3 deletions lib/python/Screens/MovieSelection.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
from Screens.Screen import Screen
from Components.Button import Button
from Components.ActionMap import HelpableActionMap, ActionMap, NumberActionMap
Expand All @@ -7,7 +8,7 @@
from Components.Pixmap import Pixmap, MultiPixmap
from Components.Label import Label
from Components.PluginComponent import plugins
from Components.config import config, ConfigSubsection, ConfigText, ConfigInteger, ConfigLocations, ConfigSet, ConfigYesNo, ConfigSelection
from Components.config import config, ConfigSubsection, ConfigText, ConfigInteger, ConfigLocations, ConfigSet, ConfigYesNo, ConfigSelection, getConfigListEntry
from Components.ConfigList import ConfigListScreen
from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
from Components.Sources.Boolean import Boolean
Expand Down Expand Up @@ -36,6 +37,7 @@
from enigma import eServiceReference, eServiceCenter, eTimer, eSize, iPlayableService, iServiceInformation, getPrevAsciiCode, eRCInput
import os
import time
from time import localtime, strftime
import pickle

config.movielist = ConfigSubsection()
Expand Down Expand Up @@ -460,6 +462,13 @@ def __selectionChanged(self):
def updateEventInfo(self):
serviceref = self.getCurrent()
self["Service"].newService(serviceref)
info = serviceref and eServiceCenter.getInstance().info(serviceref)
if info:
timeCreate = strftime("%A %d %b %Y", localtime(info.getInfo(serviceref, iServiceInformation.sTimeCreate)))
duration = "%d min" % (info.getLength(serviceref) / 60)
filesize = "%d MB" % (info.getInfoObject(serviceref, iServiceInformation.sFileSize) / (1024*1024))
moviedetails = "%s • %s • %s" % (timeCreate, duration, filesize)
self["moviedetails"].setText(moviedetails)


class MovieSelectionSummary(Screen):
Expand Down Expand Up @@ -534,6 +543,7 @@ def __init__(self, session, selectedmovie=None, timeshiftEnabled=False):
self["chosenletter"].visible = False

self["waitingtext"] = Label(_("Please wait... Loading list..."))
self["moviedetails"] = Label()

# create optional description border and hide immediately
self["DescriptionBorder"] = Pixmap()
Expand Down Expand Up @@ -1380,16 +1390,18 @@ def reloadWithDelay(self):
self.updateTags()
title = _("Recorded files...")
if config.usage.setup_level.index >= 2: # expert+
title += " " + config.movielist.last_videodir.value
title += " " + config.movielist.last_videodir.value
if self.selected_tags:
title += " - " + ','.join(self.selected_tags)
self.setTitle(title)

self.displayMovieOffStatus()
self.displaySortStatus()
if not (self.reload_sel and self["list"].moveTo(self.reload_sel)):
if self.reload_home:
self["list"].moveToFirstMovie()
self["freeDiskSpace"].update()
title += " • " + self.diskinfo.getText()
self.setTitle(title)
self["waitingtext"].visible = False
self.createPlaylist()
if self.playGoTo:
Expand Down

0 comments on commit d14a85b

Please sign in to comment.