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