- default fonts handled in windowstyle
[enigma2.git] / skin.py
1 from enigma import *
2 import xml.dom.minidom
3 from xml.dom import EMPTY_NAMESPACE
4
5 def dump(x, i=0):
6         print " " * i + str(x)
7         try:
8                 for n in x.childNodes:
9                         dump(n, i + 1)
10         except:
11                 None
12
13 dom = xml.dom.minidom.parseString(
14         """
15         <skin>
16                 <screen name="mainMenu" position="300,100" size="300,300" title="real main menu">
17                         <widget name="okbutton" position="10,190" size="280,50" font="Arial:20" valign="center" halign="center" />
18                         <widget name="title" position="10,10" size="280,20" />
19                         <widget name="menu" position="10,30" size="280,140" />
20                 </screen>
21                 <screen name="clockDisplay" position="300,100" size="300,300">
22                         <widget name="okbutton" position="10,10" size="280,40" />
23                         <widget name="title" position="10,120" size="280,50" />
24                         <widget name="theClock" position="10,60" size="280,50" />
25                 </screen>
26                 <screen name="infoBar" position="80,350" size="540,150" title="InfoBar">
27                         <widget name="CurrentTime" position="10,10" size="40,30" />
28                         <widget name="ServiceName" position="50,20" size="200,30" />
29                         <widget name="Event_Now" position="100,40" size="300,30" />
30                         <widget name="Event_Next" position="100,90" size="300,30" />
31                         <widget name="Event_Now_Duration" position="440,40" size="80,30" />
32                         <widget name="Event_Next_Duration" position="440,90" size="80,30" />
33                 </screen>
34                 <screen name="channelSelection" position="100,80" size="500,240" title="Channel Selection">
35                         <widget name="list" position="20,50" size="300,150" />
36                         <widget name="okbutton" position="340,50" size="140,30" />
37                 </screen>
38                 <screen name="serviceScan" position="150,100" size="300,200" title="Service Scan">
39                         <widget name="scan_progress" position="10,10" size="280,50" />
40                         <widget name="scan_state" position="10,60" size="280,30" />
41                         <widget name="okbutton" position="10,100" size="280,40" />
42                 </screen>
43         </skin>
44 """)
45
46
47 def elementsWithTag(el, tag):
48         for x in el:
49                 if x.nodeType != xml.dom.minidom.Element.nodeType:
50                         continue
51                 if x.tagName == tag:
52                         yield x
53
54 def parsePosition(str):
55         x, y = str.split(',')
56         return ePoint(int(x), int(y))
57
58 def parseSize(str):
59         x, y = str.split(',')
60         return eSize(int(x), int(y))
61
62 def parseFont(str):
63         name, size = str.split(':')
64         return gFont(name, int(size))
65
66 def applyAttributes(guiObject, node):
67         # walk all attributes
68         for p in range(node.attributes.length):
69                 a = node.attributes.item(p)
70                 
71                 # convert to string (was: unicode)
72                 attrib = str(a.name)
73                 # TODO: proper UTF8 translation?! (for value)
74                 # TODO: localization? as in e1?
75                 value = str(a.value)
76                 
77                 # and set attributes
78                 try:
79                         if attrib == 'position':
80                                 guiObject.move(parsePosition(value))
81                         elif attrib == 'size':
82                                 guiObject.resize(parseSize(value))
83                         elif attrib == 'title':
84                                 guiObject.setTitle(value)
85                         elif attrib == 'font':
86                                 guiObject.setFont(parseFont(value))
87                         elif attrib == "valign":
88                                 try:
89                                         guiObject.setVAlign(
90                                                 { "top": guiObject.alignTop,
91                                                         "center": guiObject.alignCenter,
92                                                         "bottom": guiObject.alignBottom
93                                                 }[value])
94                                 except KeyError:
95                                         print "valign must be either top, center or bottom!"
96                         elif attrib == "halign":
97                                 try:
98                                         guiObject.setHAlign(
99                                                 { "left": guiObject.alignLeft,
100                                                         "center": guiObject.alignCenter,
101                                                         "right": guiObject.alignRight,
102                                                         "block": guiObject.alignBlock
103                                                 }[value])
104                                 except KeyError:
105                                         print "halign must be either left, center, right or block!"
106                         elif attrib != 'name':
107                                 print "unsupported attribute " + attrib + "=" + value
108                 except AttributeError:
109                         print "widget %s (%s) doesn't support attribute %s!" % ("", guiObject.__class__.__name__, attrib)
110
111 def applyGUIskin(screen, parent, skin, name):
112         
113         myscreen = None
114         
115         # first, find the corresponding screen element
116         skin = dom.childNodes[0]
117         assert skin.tagName == "skin", "root element in skin must be 'skin'!"
118         
119         for x in elementsWithTag(skin.childNodes, "screen"):
120                 if x.getAttribute('name') == name:
121                         myscreen = x
122         del skin
123         
124         assert myscreen != None, "no skin for screen '" + name + "' found!"
125         
126         applyAttributes(parent, myscreen)
127         
128         # now walk all widgets
129         for widget in elementsWithTag(myscreen.childNodes, "widget"):
130                 wname = widget.getAttribute('name')
131                 if wname == None:
132                         print "widget has no name!"
133                         continue
134                 
135                 # get corresponding gui object
136                 try:
137                         guiObject = screen[wname].instance
138                 except:
139                         raise str("component with name '" + wname + "' was not found in skin of screen '" + name + "'!")
140                 
141                 applyAttributes(guiObject, widget)