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