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