X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=blobdiff_plain;f=skin.py;fp=skin.py;h=f763dd0ca9f8a42dac991b03917443929498c987;hp=a0190f1c2dfbdc1f2f58700ce6ed38d18f0797ae;hb=4911a0121954f6b6657ba28fab8d9dd9031d9a59;hpb=e41f07f1d0855ff8e47059f109413a41a065268b diff --git a/skin.py b/skin.py index a0190f1..f763dd0 100755 --- a/skin.py +++ b/skin.py @@ -15,6 +15,13 @@ from Tools.LoadPixmap import LoadPixmap colorNames = dict() +fonts = { + "Body": ("Regular", 18, 22, 16), + "ChoiceList": ("Regular", 20, 24, 18), +} + +parameters = {} + def dump(x, i=0): print " " * i + str(x) try: @@ -70,6 +77,31 @@ profile("LoadSkinDefault") loadSkin('skin_default.xml') profile("LoadSkinDefaultDone") +def parseCoordinate(str, e, size = 0): + str = str.strip() + if str == "center": + val = (e - size)/2 + else: + sl = len(str) + l = 1 + + if str[0] is 'e': + val = e + elif str[0] is 'c': + val = e/2 + else: + val = 0; + l = 0 + + if sl - l > 0: + if str[sl-1] is '%': + val += e * int(str[l:sl-1]) / 100 + else: + val += int(str[l:sl]) + if val < 0: + val = 0 + return val + def evalPos(pos, wsize, ssize, scale): if pos == "center": pos = (ssize - wsize) / 2 @@ -96,8 +128,13 @@ def parseSize(str, scale): x, y = str.split(',') return eSize(int(x) * scale[0][0] / scale[0][1], int(y) * scale[1][0] / scale[1][1]) -def parseFont(str, scale): - name, size = str.split(';') +def parseFont(s, scale): + try: + f = fonts[s] + name = f[0] + size = f[1] + except: + name, size = s.split(';') return gFont(name, int(size) * scale[0][0] / scale[0][1]) def parseColor(str): @@ -108,18 +145,34 @@ def parseColor(str): raise SkinError("color '%s' must be #aarrggbb or valid named color" % (str)) return gRGB(int(str[1:], 0x10)) -def collectAttributes(skinAttributes, node, skin_path_prefix=None, ignore=[]): +def collectAttributes(skinAttributes, node, context, skin_path_prefix=None, ignore=[]): # walk all attributes - for a in node.items(): - #print a - attrib = a[0] - value = a[1] - - if attrib in ("pixmap", "pointer", "seek_pointer", "backgroundPixmap", "selectionPixmap"): - value = resolveFilename(SCOPE_SKIN_IMAGE, value, path_prefix=skin_path_prefix) - + size = None + pos = None + for attrib, value in node.items(): if attrib not in ignore: - skinAttributes.append((attrib, value.encode("utf-8"))) + if attrib in ("pixmap", "pointer", "seek_pointer", "backgroundPixmap", "selectionPixmap"): + value = resolveFilename(SCOPE_SKIN_IMAGE, value, path_prefix=skin_path_prefix) + + # Bit of a hack this, really. When a window has a flag (e.g. wfNoBorder) + # it needs to be set at least before the size is set, in order for the + # window dimensions to be calculated correctly in all situations. + # If wfNoBorder is applied after the size has been set, the window will fail to clear the title area. + # Similar situation for a scrollbar in a listbox; when the scrollbar setting is applied after + # the size, a scrollbar will not be shown until the selection moves for the first time + + if attrib == 'size': + size = value.encode("utf-8") + elif attrib == 'position': + pos = value.encode("utf-8") + else: + skinAttributes.append((attrib, value.encode("utf-8"))) + + if pos is not None: + pos, size = context.parse(pos, size) + skinAttributes.append(('position', pos)) + if size is not None: + skinAttributes.append(('size', size)) def loadPixmap(path, desktop): cached = False @@ -133,136 +186,164 @@ def loadPixmap(path, desktop): raise SkinError("pixmap file %s not found!" % (path)) return ptr -def applySingleAttribute(guiObject, desktop, attrib, value, scale = ((1,1),(1,1))): - # and set attributes - try: - if attrib == 'position': - guiObject.move(parsePosition(value, scale, desktop, guiObject.csize())) - elif attrib == 'size': - guiObject.resize(parseSize(value, scale)) - elif attrib == 'animationPaused': - pass - elif attrib == 'animationMode': - guiObject.setAnimationMode( - { "disable": 0x00, - "off": 0x00, - "offshow": 0x10, - "offhide": 0x01, - "onshow": 0x01, - "onhide": 0x10, +class AttributeParser: + def __init__(self, guiObject, desktop, scale = ((1,1),(1,1))): + self.guiObject = guiObject + self.desktop = desktop + self.scale = scale + def applyOne(self, attrib, value): + try: + getattr(self, attrib)(value) + except AttributeError: + print "[Skin] Attribute not implemented:", attrib, "value:", value + except SkinError, ex: + print "[Skin] Error:", ex + def applyAll(self, attrs): + for attrib, value in attrs: + try: + getattr(self, attrib)(value) + except AttributeError: + print "[Skin] Attribute not implemented:", attrib, "value:", value + except SkinError, ex: + print "[Skin] Error:", ex + def position(self, value): + if isinstance(value, tuple): + self.guiObject.move(ePoint(*value)) + else: + self.guiObject.move(parsePosition(value, self.scale, self.desktop, self.guiObject.csize())) + def size(self, value): + if isinstance(value, tuple): + self.guiObject.resize(eSize(*value)) + else: + self.guiObject.resize(parseSize(value, self.scale)) + def animationPaused(self, value): + pass + def animationPaused(self, value): + self.guiObject.setAnimationMode( + { "disable": 0x00, + "off": 0x00, + "offshow": 0x10, + "offhide": 0x01, + "onshow": 0x01, + "onhide": 0x10, + }[value]) + def title(self, value): + self.guiObject.setTitle(_(value)) + def text(self, value): + self.guiObject.setText(_(value)) + def font(self, value): + self.guiObject.setFont(parseFont(value, self.scale)) + def zPosition(self, value): + self.guiObject.setZPosition(int(value)) + def itemHeight(self, value): + self.guiObject.setItemHeight(int(value)) + def pixmap(self, value): + ptr = loadPixmap(value, self.desktop) + self.guiObject.setPixmap(ptr) + def backgroundPixmap(self, value): + ptr = loadPixmap(value, self.desktop) + self.guiObject.setBackgroundPicture(ptr) + def selectionPixmap(self, value): + ptr = loadPixmap(value, self.desktop) + self.guiObject.setSelectionPicture(ptr) + def itemHeight(self, value): + self.guiObject.setItemHeight(int(value)) + def alphatest(self, value): + self.guiObject.setAlphatest( + { "on": 1, + "off": 0, + "blend": 2, + }[value]) + def scale(self, value): + self.guiObject.setScale(1) + def orientation(self, value): + try: + self.guiObject.setOrientation(* + { "orVertical": (self.guiObject.orVertical, False), + "orTopToBottom": (self.guiObject.orVertical, False), + "orBottomToTop": (self.guiObject.orVertical, True), + "orHorizontal": (self.guiObject.orHorizontal, False), + "orLeftToRight": (self.guiObject.orHorizontal, False), + "orRightToLeft": (self.guiObject.orHorizontal, True), }[value]) - elif attrib == 'title': - guiObject.setTitle(_(value)) - elif attrib == 'text': - guiObject.setText(_(value)) - elif attrib == 'font': - guiObject.setFont(parseFont(value, scale)) - elif attrib == 'zPosition': - guiObject.setZPosition(int(value)) - elif attrib == 'itemHeight': - guiObject.setItemHeight(int(value)) - elif attrib in ("pixmap", "backgroundPixmap", "selectionPixmap"): - ptr = loadPixmap(value, desktop) # this should already have been filename-resolved. - if attrib == "pixmap": - guiObject.setPixmap(ptr) - elif attrib == "backgroundPixmap": - guiObject.setBackgroundPicture(ptr) - elif attrib == "selectionPixmap": - guiObject.setSelectionPicture(ptr) - # guiObject.setPixmapFromFile(value) - elif attrib == "alphatest": # used by ePixmap - guiObject.setAlphatest( - { "on": 1, - "off": 0, - "blend": 2, + except KeyError: + print "oprientation must be either orVertical or orHorizontal!" + def valign(self, value): + try: + self.guiObject.setVAlign( + { "top": self.guiObject.alignTop, + "center": self.guiObject.alignCenter, + "bottom": self.guiObject.alignBottom }[value]) - elif attrib == "scale": - guiObject.setScale(1) - elif attrib == "orientation": # used by eSlider - try: - guiObject.setOrientation(* - { "orVertical": (guiObject.orVertical, False), - "orTopToBottom": (guiObject.orVertical, False), - "orBottomToTop": (guiObject.orVertical, True), - "orHorizontal": (guiObject.orHorizontal, False), - "orLeftToRight": (guiObject.orHorizontal, False), - "orRightToLeft": (guiObject.orHorizontal, True), - }[value]) - except KeyError: - print "oprientation must be either orVertical or orHorizontal!" - elif attrib == "valign": - try: - guiObject.setVAlign( - { "top": guiObject.alignTop, - "center": guiObject.alignCenter, - "bottom": guiObject.alignBottom - }[value]) - except KeyError: - print "valign must be either top, center or bottom!" - elif attrib == "halign": + except KeyError: + print "valign must be either top, center or bottom!" + def halign(self, value): + try: + self.guiObject.setHAlign( + { "left": self.guiObject.alignLeft, + "center": self.guiObject.alignCenter, + "right": self.guiObject.alignRight, + "block": self.guiObject.alignBlock + }[value]) + except KeyError: + print "halign must be either left, center, right or block!" + def flags(self, value): + flags = value.split(',') + for f in flags: try: - guiObject.setHAlign( - { "left": guiObject.alignLeft, - "center": guiObject.alignCenter, - "right": guiObject.alignRight, - "block": guiObject.alignBlock - }[value]) + fv = eWindow.__dict__[f] + self.guiObject.setFlag(fv) except KeyError: - print "halign must be either left, center, right or block!" - elif attrib == "flags": - flags = value.split(',') - for f in flags: - try: - fv = eWindow.__dict__[f] - guiObject.setFlag(fv) - except KeyError: - print "illegal flag %s!" % f - elif attrib == "backgroundColor": - guiObject.setBackgroundColor(parseColor(value)) - elif attrib == "backgroundColorSelected": - guiObject.setBackgroundColorSelected(parseColor(value)) - elif attrib == "foregroundColor": - guiObject.setForegroundColor(parseColor(value)) - elif attrib == "foregroundColorSelected": - guiObject.setForegroundColorSelected(parseColor(value)) - elif attrib == "shadowColor": - guiObject.setShadowColor(parseColor(value)) - elif attrib == "selectionDisabled": - guiObject.setSelectionEnable(0) - elif attrib == "transparent": - guiObject.setTransparent(int(value)) - elif attrib == "borderColor": - guiObject.setBorderColor(parseColor(value)) - elif attrib == "borderWidth": - guiObject.setBorderWidth(int(value)) - elif attrib == "scrollbarMode": - guiObject.setScrollbarMode( - { "showOnDemand": guiObject.showOnDemand, - "showAlways": guiObject.showAlways, - "showNever": guiObject.showNever - }[value]) - elif attrib == "enableWrapAround": - guiObject.setWrapAround(True) - elif attrib == "pointer" or attrib == "seek_pointer": - (name, pos) = value.split(':') - pos = parsePosition(pos, scale) - ptr = loadPixmap(name, desktop) - guiObject.setPointer({"pointer": 0, "seek_pointer": 1}[attrib], ptr, pos) - elif attrib == 'shadowOffset': - guiObject.setShadowOffset(parsePosition(value, scale)) - elif attrib == 'noWrap': - guiObject.setNoWrap(1) - elif attrib == 'id': - pass - else: - raise SkinError("unsupported attribute " + attrib + "=" + value) - except int: -# AttributeError: - print "widget %s (%s) doesn't support attribute %s!" % ("", guiObject.__class__.__name__, attrib) + print "illegal flag %s!" % f + def backgroundColor(self, value): + self.guiObject.setBackgroundColor(parseColor(value)) + def backgroundColorSelected(self, value): + self.guiObject.setBackgroundColorSelected(parseColor(value)) + def foregroundColor(self, value): + self.guiObject.setForegroundColor(parseColor(value)) + def foregroundColorSelected(self, value): + self.guiObject.setForegroundColorSelected(parseColor(value)) + def shadowColor(self, value): + self.guiObject.setShadowColor(parseColor(value)) + def selectionDisabled(self, value): + self.guiObject.setSelectionEnable(0) + def transparent(self, value): + self.guiObject.setTransparent(int(value)) + def borderColor(self, value): + self.guiObject.setBorderColor(parseColor(value)) + def borderWidth(self, value): + self.guiObject.setBorderWidth(int(value)) + def scrollbarMode(self, value): + self.guiObject.setScrollbarMode( + { "showOnDemand": self.guiObject.showOnDemand, + "showAlways": self.guiObject.showAlways, + "showNever": self.guiObject.showNever + }[value]) + def enableWrapAround(self, value): + self.guiObject.setWrapAround(True) + def pointer(self, value): + (name, pos) = value.split(':') + pos = parsePosition(pos, self.scale) + ptr = loadPixmap(name, self.desktop) + self.guiObject.setPointer(0, ptr, pos) + def seek_pointer(self, value): + (name, pos) = value.split(':') + pos = parsePosition(pos, self.scale) + ptr = loadPixmap(name, self.desktop) + self.guiObject.setPointer(1, ptr, pos) + def shadowOffset(self, value): + self.guiObject.setShadowOffset(parsePosition(value, self.scale)) + def noWrap(self, value): + self.guiObject.setNoWrap(1) + def id(self, value): + pass + +def applySingleAttribute(guiObject, desktop, attrib, value, scale = ((1,1),(1,1))): + # Someone still using applySingleAttribute? + AttributeParser(guiObject, desktop, scale).applyOne(attrib, value) def applyAllAttributes(guiObject, desktop, attributes, scale): - for (attrib, value) in attributes: - applySingleAttribute(guiObject, desktop, attrib, value, scale) + AttributeParser(guiObject, desktop, scale).applyAll(attributes) def loadSingleSkinData(desktop, skin, path_prefix): """loads skin data like colors, windowstyle etc.""" @@ -332,6 +413,29 @@ def loadSingleSkinData(desktop, skin, path_prefix): addFont(resolved_font, name, scale, is_replacement) #print "Font: ", resolved_font, name, scale, is_replacement + for alias in c.findall("alias"): + get = alias.attrib.get + try: + name = get("name") + font = get("font") + size = int(get("size")) + height = int(get("height", size)) # to be calculated some day + width = int(get("width", size)) + global fonts + fonts[name] = (font, size, height, width) + except Exception, ex: + print "[SKIN] bad font alias", ex + + for c in skin.findall("parameters"): + for parameter in c.findall("parameter"): + get = parameter.attrib.get + try: + name = get("name") + value = get("value") + parameters[name] = map(int, value.split(",")) + except Exception, ex: + print "[SKIN] bad parameter", ex + for c in skin.findall("subtitles"): from enigma import eWidget, eSubtitleWidget scale = ((1,1),(1,1)) @@ -402,27 +506,148 @@ def loadSingleSkinData(desktop, skin, path_prefix): x = eWindowStyleManager.getInstance() x.setStyle(id, style) +display_skin_id = 1 +dom_screens = {} + def loadSkinData(desktop): + global dom_skins, dom_screens, display_skin_id skins = dom_skins[:] skins.reverse() for (path, dom_skin) in skins: loadSingleSkinData(desktop, dom_skin, path) + for elem in dom_skin: + if elem.tag == 'screen': + name = elem.attrib.get('name', None) + if name: + sid = elem.attrib.get('id', None) + if sid and (int(sid) != display_skin_id): + # not for this display + elem.clear() + continue + if name in dom_screens: + # Kill old versions, save memory + dom_screens[name][0].clear() + dom_screens[name] = (elem, path) + else: + # without name, it's useless! + elem.clear() + else: + # non-screen element, no need for it any longer + elem.clear() + # no longer needed, we know where the screens are now. + del dom_skins + def lookupScreen(name, style_id): - for (path, skin) in dom_skins: - # first, find the corresponding screen element - for x in skin.findall("screen"): - if x.attrib.get('name', '') == name: - screen_style_id = x.attrib.get('id', '-1') - if screen_style_id == '-1' and name.find('ummary') > 0: - screen_style_id = '1' - if (style_id != 2 and int(screen_style_id) == -1) or int(screen_style_id) == style_id: - return x, path + if dom_screens.has_key(name): + elem, path = dom_screens[name] + screen_style_id = elem.attrib.get('id', '-1') + if screen_style_id == '-1' and name.find('ummary') > 0: + screen_style_id = '1' + if (style_id != 2 and int(screen_style_id) == -1) or int(screen_style_id) == style_id: + return elem, path + return None, None class additionalWidget: pass +# Class that makes a tuple look like something else. Some plugins just assume +# that size is a string and try to parse it. This class makes that work. +class SizeTuple(tuple): + def split(self, *args): + return (str(self[0]), str(self[1])) + def strip(self, *args): + return '%s,%s' % self + def __str__(self): + return '%s,%s' % self + +class SkinContext: + def __init__(self, parent=None, pos=None, size=None): + if parent is not None: + if pos is not None: + pos, size = parent.parse(pos, size) + self.x, self.y = pos + self.w, self.h = size + else: + self.x = None + self.y = None + self.w = None + self.h = None + def __str__(self): + return "Context (%s,%s)+(%s,%s) " % (self.x, self.y, self.w, self.h) + def parse(self, pos, size): + if pos == "fill": + pos = (self.x, self.y) + size = (self.w, self.h) + self.w = 0 + self.h = 0 + elif pos == "bottom": + w,h = size.split(',') + h = int(h) + pos = (self.x, self.y + self.h - h) + size = (self.w, h) + self.h -= h + elif pos == "top": + w,h = size.split(',') + h = int(h) + pos = (self.x, self.y) + size = (self.w, h) + self.h -= h + self.y += h + elif pos == "left": + w,h = size.split(',') + w = int(w) + pos = (self.x, self.y) + size = (w, self.h) + self.x += w + self.w -= w + elif pos == "right": + w,h = size.split(',') + w = int(w) + pos = (self.x + self.w - w, self.y) + size = (w, self.h) + self.w -= w + else: + size = size.split(',') + size = (parseCoordinate(size[0], self.w), parseCoordinate(size[1], self.h)) + pos = pos.split(',') + pos = (self.x + parseCoordinate(pos[0], self.w, size[0]), self.y + parseCoordinate(pos[1], self.h, size[1])) + return (SizeTuple(pos), SizeTuple(size)) + +class SkinContextStack(SkinContext): + # A context that stacks things instead of aligning them + def parse(self, pos, size): + if pos == "fill": + pos = (self.x, self.y) + size = (self.w, self.h) + elif pos == "bottom": + w,h = size.split(',') + h = int(h) + pos = (self.x, self.y + self.h - h) + size = (self.w, h) + elif pos == "top": + w,h = size.split(',') + h = int(h) + pos = (self.x, self.y) + size = (self.w, h) + elif pos == "left": + w,h = size.split(',') + w = int(w) + pos = (self.x, self.y) + size = (w, self.h) + elif pos == "right": + w,h = size.split(',') + w = int(w) + pos = (self.x + self.w - w, self.y) + size = (w, self.h) + else: + size = size.split(',') + size = (parseCoordinate(size[0], self.w), parseCoordinate(size[1], self.h)) + pos = pos.split(',') + pos = (self.x + parseCoordinate(pos[0], self.w, size[0]), self.y + parseCoordinate(pos[1], self.h, size[1])) + return (SizeTuple(pos), SizeTuple(size)) + def readSkin(screen, skin, names, desktop): if not isinstance(names, list): names = [names] @@ -466,15 +691,30 @@ def readSkin(screen, skin, names, desktop): skin_path_prefix = getattr(screen, "skin_path", path) - collectAttributes(screen.skinAttributes, myscreen, skin_path_prefix, ignore=["name"]) +# collectAttributes(screen.skinAttributes, myscreen, skin_path_prefix, ignore=["name"]) + + context = SkinContext() + s = desktop.size() + context.x = 0 + context.y = 0 + context.w = s.width() + context.h = s.height() + del s + collectAttributes(screen.skinAttributes, myscreen, context, skin_path_prefix, ignore=("name",)) + context = SkinContext(context, myscreen.attrib.get('position'), myscreen.attrib.get('size')) + +# screen.additionalWidgets = [ ] screen.renderer = [ ] visited_components = set() - # now walk all widgets - for widget in myscreen.findall("widget"): + # now walk all widgets and stuff + def process_none(widget, context): + pass + + def process_widget(widget, context): get_attr = widget.attrib.get # ok, we either have 1:1-mapped widgets ('old style'), or 1:n-mapped # widgets (source->renderer). @@ -484,7 +724,7 @@ def readSkin(screen, skin, names, desktop): if wname is None and wsource is None: print "widget has no name and no source!" - continue + return if wname: #print "Widget name=", wname @@ -500,7 +740,7 @@ def readSkin(screen, skin, names, desktop): # assert screen[wname] is not Source # and collect attributes for this - collectAttributes(attributes, widget, skin_path_prefix, ignore=['name']) + collectAttributes(attributes, widget, context, skin_path_prefix, ignore=['name']) elif wsource: # get corresponding source #print "Widget source=", wsource @@ -575,55 +815,98 @@ def readSkin(screen, skin, names, desktop): renderer.connect(source) # connect to source attributes = renderer.skinAttributes = [ ] - collectAttributes(attributes, widget, skin_path_prefix, ignore=['render', 'source']) + collectAttributes(attributes, widget, context, skin_path_prefix, ignore=['render', 'source']) screen.renderer.append(renderer) - from Components.GUIComponent import GUIComponent - nonvisited_components = [x for x in set(screen.keys()) - visited_components if isinstance(x, GUIComponent)] - assert not nonvisited_components, "the following components in %s don't have a skin entry: %s" % (name, ', '.join(nonvisited_components)) + def process_applet(widget, context): + try: + codeText = widget.text.strip() + except: + codeText = "" - # now walk additional objects - for widget in myscreen.getchildren(): - w_tag = widget.tag + #print "Found code:" + #print codeText + widgetType = widget.attrib.get('type') - if w_tag == "widget": - continue + code = compile(codeText, "skin applet", "exec") - if w_tag == "applet": - try: - codeText = widget.text.strip() - except: - codeText = "" + if widgetType == "onLayoutFinish": + screen.onLayoutFinish.append(code) + #print "onLayoutFinish = ", codeText + else: + raise SkinError("applet type '%s' unknown!" % widgetType) + #print "applet type '%s' unknown!" % type + + def process_elabel(widget, context): + w = additionalWidget() + w.widget = eLabel + w.skinAttributes = [ ] + collectAttributes(w.skinAttributes, widget, context, skin_path_prefix, ignore=['name']) + screen.additionalWidgets.append(w) + + def process_epixmap(widget, context): + w = additionalWidget() + w.widget = ePixmap + w.skinAttributes = [ ] + collectAttributes(w.skinAttributes, widget, context, skin_path_prefix, ignore=['name']) + screen.additionalWidgets.append(w) - #print "Found code:" - #print codeText - widgetType = widget.attrib.get('type') + def process_screen(widget, context): + for w in widget.findall("widget"): + process_widget(w, context) + + for w in widget.getchildren(): + if w.tag == "widget": + continue - code = compile(codeText, "skin applet", "exec") + p = processors.get(w.tag, process_none) + p(w, context) - if widgetType == "onLayoutFinish": - screen.onLayoutFinish.append(code) - #print "onLayoutFinish = ", codeText + def process_panel(widget, context): + n = widget.attrib.get('name') + if n: + try: + s = dom_screens.get(n, None) + except KeyError: + print "[SKIN] Unable to find screen '%s' referred in screen '%s'" % (n, name) else: - raise SkinError("applet type '%s' unknown!" % widgetType) - #print "applet type '%s' unknown!" % type + process_screen(s[0], context) + + layout = widget.attrib.get('layout') + if layout == 'stack': + cc = SkinContextStack + else: + cc = SkinContext + try: + c = cc(context, widget.attrib.get('position'), widget.attrib.get('size')) + except Exception, ex: + raise SkinError("Failed to create skincontext (%s,%s) in %s: %s" % (widget.attrib.get('position'), widget.attrib.get('size'), context, ex) ) - continue + process_screen(widget, c) - w = additionalWidget() + processors = { + None: process_none, + "widget": process_widget, + "applet": process_applet, + "eLabel": process_elabel, + "ePixmap": process_epixmap, + "panel": process_panel + } - if w_tag == "eLabel": - w.widget = eLabel - elif w_tag == "ePixmap": - w.widget = ePixmap - else: - raise SkinError("unsupported stuff : %s" % w_tag) - #print "unsupported stuff : %s" % widget.tag + try: + context.x = 0 # reset offsets, all components are relative to screen + context.y = 0 # coordinates. + process_screen(myscreen, context) + except SkinError, e: + print "[Skin] SKIN ERROR:", e - w.skinAttributes = [ ] - collectAttributes(w.skinAttributes, widget, skin_path_prefix, ignore=['name']) + from Components.GUIComponent import GUIComponent + nonvisited_components = [x for x in set(screen.keys()) - visited_components if isinstance(x, GUIComponent)] + assert not nonvisited_components, "the following components in %s don't have a skin entry: %s" % (name, ', '.join(nonvisited_components)) + # This may look pointless, but it unbinds 'screen' from the nested scope. A better + # solution is to avoid the nested scope above and use the context object to pass + # things around. + screen = None + visited_components = None - # applyAttributes(guiObject, widget, desktop) - # guiObject.thisown = 0 - screen.additionalWidgets.append(w)