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