consider screens which haven't finished their initialization as shown. this fixes...
[enigma2.git] / lib / python / Screens / Screen.py
1 from Components.HTMLSkin import *
2 from Components.GUISkin import *
3 from Components.Sources.Source import Source
4
5 import sys
6
7 class Screen(dict, HTMLSkin, GUISkin):
8
9         ALLOW_SUSPEND = False
10
11         def __init__(self, session):
12                 self.skinName = self.__class__.__name__
13                 self.session = session
14                 GUISkin.__init__(self)
15
16                 self.onClose = [ ]
17                 self.onFirstExecBegin = [ ]
18                 self.onExecBegin = [ ]
19                 self.onShown = [ ]
20
21                 self.onShow = [ ]
22                 self.onHide = [ ]
23
24                 self.execing = False
25                 self.shown = True
26
27                 self.renderer = [ ]
28
29                 # in order to support screens *without* a help,
30                 # we need the list in every screen. how ironic.
31                 self.helpList = [ ]
32
33                 self.close_on_next_exec = None
34
35                 # stand alone screens (for example web screens)
36                 # don't care about having or not having focus.
37                 self.stand_alone = False
38
39         def execBegin(self):
40                 self.active_components = [ ]
41                 if self.close_on_next_exec is not None:
42                         tmp = self.close_on_next_exec
43                         self.close_on_next_exec = None
44                         self.execing = True
45                         self.close(tmp)
46                 else:
47                         single = self.onFirstExecBegin
48                         self.onFirstExecBegin = []
49                         for x in self.onExecBegin + single:
50                                 x()
51                                 if not self.stand_alone and self.session.current_dialog != self:
52                                         return
53
54 #                       assert self.session == None, "a screen can only exec once per time"
55 #                       self.session = session
56
57                         for val in self.values() + self.renderer:
58                                 val.execBegin()
59                                 if not self.stand_alone and self.session.current_dialog != self:
60                                         return
61                                 self.active_components.append(val)
62
63                         self.execing = True
64         
65                         for x in self.onShown:
66                                 x()
67         
68         def execEnd(self):
69 #               for (name, val) in self.items():
70                 for val in self.active_components:
71                         val.execEnd()
72                 del self.active_components
73 #               assert self.session != None, "execEnd on non-execing screen!"
74 #               self.session = None
75                 self.execing = False
76         
77         # never call this directly - it will be called from the session!
78         def doClose(self):
79                 self.hide()
80                 for x in self.onClose:
81                         x()
82                 
83                 # fixup circular references
84                 del self.helpList
85                 GUISkin.close(self)
86
87                 # first disconnect all render from their sources.
88                 # we might split this out into a "unskin"-call,
89                 # but currently we destroy the screen afterwards
90                 # anyway.
91                 for val in self.renderer:
92                         val.disconnectAll()  # disconnected converter/sources and probably destroy them
93                 
94                 del self.session
95                 for (name, val) in self.items():
96                         val.destroy()
97                         del self[name]
98                 
99                 for val in self.renderer:
100                         val.destroy()
101                 
102                 self.renderer = [ ]
103                 
104                 # really delete all elements now
105                 self.__dict__.clear()
106         
107         def close(self, *retval):
108                 if not self.execing:
109                         self.close_on_next_exec = retval
110                 else:
111                         self.session.close(self, *retval)
112
113         def setFocus(self, o):
114                 self.instance.setFocus(o.instance)
115
116         def show(self, force = False):
117                 if (self.shown and not force) or not self.instance:
118                         return
119                 self.shown = True
120                 self.instance.show()
121                 for x in self.onShow:
122                         x()
123                 for val in self.values() + self.renderer:
124                         if isinstance(val, GUIComponent) or isinstance(val, Source):
125                                 val.onShow()
126
127         def hide(self):
128                 if not self.shown or not self.instance:
129                         return
130                 self.shown = False
131                 self.instance.hide()
132                 for x in self.onHide:
133                         x()
134                 for val in self.values() + self.renderer:
135                         if isinstance(val, GUIComponent) or isinstance(val, Source):
136                                 val.onHide()
137
138         def __repr__(self):
139                 return str(type(self))