1
2 """
3 Module implementing a way to resource-based access to controls in an
4 unified interface dynamic.
5 """
6 from Util import nop
7 from itertools import repeat, izip
8 from Resource import ExclusiveResource
9
12
13
16
17
18 -class Layer(ExclusiveResource):
19 """
20 A layer provides a convenient interface to control resources. In a
21 layer, you can group several controls by name. The layer itself
22 is an exclusive resource. When grabbing the layer, it will try to
23 grab all controls and will forward them to its own owner when he
24 receives them, and will take them from him when they are
25 release. The layer with give and take away the controls from its
26 client using methods of the form::
27
28 client.set[control-name](control)
29
30 Where [control-name] is the name the control was given in this
31 layer. This way, layers are a convenient way to provide controls
32 to components indirectly, with automatic handling of competition
33 for them.
34 """
35
37 super(Layer, self).__init__(*a)
38 self._layer_owner = None
39 self._priority = None
40 self._name_to_controls = dict(izip(controls.iterkeys(), repeat(None)))
41 self._control_to_names = dict()
42 for name, control in controls.iteritems():
43 self._control_to_names.setdefault(control, []).append(name)
44
47
49 if priority != self._priority:
50 self._priority = priority
51 if self._layer_owner:
52 self.grab(self._layer_owner)
53
54 priority = property(_get_priority, _set_priority)
55
57 """ Provides access to controls """
58 try:
59 return self._name_to_controls[name]
60 except KeyError:
61 raise AttributeError
62
64 """
65 Client interface of the ControlElement resource. Please do not
66 call this method directly, nor use a layer to grab controls
67 directly -- do it implicitly by grabing the layer.
68 """
69 if not self._layer_owner:
70 raise AssertionError
71 raise control in self._control_to_names or AssertionError, 'Control not in layer.'
72 owner = self._layer_owner
73 names = self._control_to_names[control]
74 control = grabbed or None
75 for name in names:
76 try:
77 handler = getattr(owner, 'set_' + name)
78 except AttributeError:
79 if name[0] != '_':
80 raise UnhandledControlError, 'Component %s has no handler for control %s' % (str(owner), name)
81 else:
82 handler = nop
83
84 handler(control)
85 self._name_to_controls[name] = control
86
87 - def grab(self, client, *a, **k):
88 if client == self.owner:
89 self.on_grab(client, *a, **k)
90 return True
91 return super(Layer, self).grab(client, *a, **k)
92
93 - def on_grab(self, client, *a, **k):
94 """ Override from ExclusiveResource """
95 self._layer_owner = client
96 for control in self._control_to_names.iterkeys():
97 k.setdefault('priority', self._priority)
98 control.resource.grab(self, *a, **k)
99
101 """ Override from ExclusiveResource """
102 for control in self._control_to_names.iterkeys():
103 control.resource.release(self)
104
105 self._layer_owner = None
106