1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 from flumotion.common import log, pygobject
24
25 import os
26
27 import gobject
28 import gst
29 import gst.interfaces
30 import gtk
31 import gtk.glade
32
33 from flumotion.configure import configure
34 from flumotion.common.pygobject import gsignal
35
36 if gtk.pygtk_version < (2,3,91):
37 raise SystemExit, "PyGTK 2.3.91 or higher required"
38
40 log.debug('spyglass', ' '.join(args))
41
42
43 __all__ = ('Controller', )
44
46 """
47 Controller for a spyglass, used for viewing a video feed.
48 The controller's model takes a raw video feed as accepted by ximagesink.
49 """
50
51
52 gsignal('prepared')
53 gsignal('focus-changed', object)
54
56 """
57 Create a new spyglass controller.
58 The spyglass controller needs to be prepared.
59 """
60 self.__gobject_init__()
61 self.view = View()
62 self.model = Model()
63
64
65
76
77
79 """
80 Adds a focus point for the spyglass.
81 @type key: C{object}
82 @param key: the key for this focus point.
83 @type description: C{string}
84 @param description: the description for the focus point in the view.
85 """
86 self.view.add_focus(key, description)
87
89 """
90 Sets the focus point in the view given by the key.
91 @type key: C{object}
92 @param key: the key for the focus point.
93 """
94 self.view.set_focus(key)
95
96
97
102
104 self.emit('focus-changed', key)
105
106 -class View(gobject.GObject):
107 gsignal('have-xid', long)
108 gsignal('focus-changed' , object)
109
111 """
112 Construct a new Spyglass View.
113 """
114 self.__gobject_init__()
115 self._gladefile = os.path.join(configure.gladedir, 'spyglass.glade')
116 self._glade = gtk.glade.XML(self._gladefile, "spyglass-widget")
117 self._widget = self._glade.get_widget("spyglass-widget")
118 self._combo = self._glade.get_widget("spyglass-combo")
119
121
122 self._focus_model = gtk.ListStore(str, object)
123
124 self._focus_key = {}
125 self._combo.set_model(self._focus_model)
126 self._combo.connect("changed", self.view_combo_changed_cb)
127
128
129
130 area = self._glade.get_widget("spyglass-area")
131 assert(area)
132 self._expose_id = area.connect("expose-event", self.view_exposed_cb)
133
136
140
142 self._combo.set_active(self._focus_key[key])
143
144
145
147 row = self._focus_model[combo.get_active()]
148 key = row[1]
149 self.emit('focus-changed', key)
150
152 'store our xid now that we are exposed'
153 widget.disconnect(self._expose_id)
154 self._xid = widget.window.xid
155 _debug("view_exposed_cb, got xid %d" % self._xid)
156 self.emit('have-xid', self._xid)
157
160 self._sink = gst.Element('ximagesink')
161
163 'Gets the element we should link and put in our main bin'
164 return self._sink
165
167
168 self._sink.set_xwindow_id(long(xid))
169
170
171 pygobject.type_register(View)
172 pygobject.type_register(Controller)
173
174 if __name__ == '__main__':
176
177 _debug("setting thread to PLAYING")
178 thread.set_state(gst.STATE_PLAYING)
179
181 _debug("focus changed to key %s" % key)
182 src.set_property('pattern', key)
183
184 _debug("testing")
185
186
187 thread = gst.Thread()
188 src = gst.Element('videotestsrc')
189 csp = gst.Element('ffmpegcolorspace')
190
191
192 controller = Controller()
193 controller.connect("prepared", controller_prepared_cb, thread)
194 controller.connect("focus-changed", controller_focus_changed_cb, src)
195 controller.prepare()
196
197
198
199
200 controller.add_focus(1, 'Snow source')
201 controller.add_focus(0, 'Snow embedded in test signal')
202 controller.add_focus(2, 'Snow in the dark')
203
204 controller.set_focus(2)
205
206
207 window = gtk.Window()
208 window.connect('destroy', gtk.main_quit)
209 window.add(controller.view.get_widget())
210 window.show_all()
211
212
213 sink = controller.model.get_element()
214 prev = None
215 for e in (src, csp, sink):
216 thread.add(e)
217 if prev: prev.link(e)
218 prev = e
219
220 _debug("going into gtk.main")
221 gtk.main()
222