Various minor adjustments.
[python-gnt.git] / example / xmms / gx
blobaf4488241f3e2b4cfc7dd2450d680b5b59f8d9d5
1 #!/usr/bin/env python
3 import xmmsclient
4 import xmmsclient.glib as xg
5 import xmmsclient.collections as xc
6 import os
7 import os.path as path
9 import sys
10 from xml.dom.ext.reader import Sax2
11 from xml.dom.NodeFilter import NodeFilter
12 import gnt
14 from xmms_search import XSearch
15 from xmms_eq import XQSettings
16 from xmms_pl import XPList, XPListCurrent
17 from xmms_status import XStatus
18 from xmms_config import XConfig
20 import common
22 gui = """
23 <windows>
24 <window name='Main Window' vertical='True' homo='False' maximize='both' start='True' pad='0' noborder='1'>
25 <title>XMMS2</title>
26 <widgets>
27 <status title='show' quality='show' album='show'/>
28 <playlist current='True' />
29 <box vertical='False'>
30 <widgets>
31 <search />
32 <config />
33 </widgets>
34 </box>
35 </widgets>
36 </window>
37 <window name='Basic Search' vertical='True' homo='False' start='False'>
38 <title>Search...</title>
39 <widgets>
40 <box vertical='False'>
41 <widgets>
42 <search />
43 <equalizer />
44 </widgets>
45 </box>
46 </widgets>
47 </window>
48 <window name='Equalizer'>
49 <title>Equalizer</title>
50 <widgets>
51 <equalizer />
52 </widgets>
53 </window>
54 <window name='Playlist Editor' maximize='vert'>
55 <title>Playlist Editor</title>
56 <widgets>
57 <playlist position='hide' album='hide'/>
58 </widgets>
59 </window>
60 <window name='Configuration Editor' maximize='vert' start='False'>
61 <title>Configuration Editor</title>
62 <widgets>
63 <config />
64 </widgets>
65 </window>
66 </windows>
67 """
69 def setup_xmms():
70 try:
71 xmms = xmmsclient.XMMS("uber-cool")
72 xmms.connect(os.getenv("XMMS_PATH"))
73 conn = xg.GLibConnector(xmms)
74 return xmms
75 except IOError, detail:
76 common.show_error("Connection failed: " + str(detail))
77 return None
79 xmms = setup_xmms()
81 windows = []
83 class WidgetNode:
84 def __init__(self, node, parent = None):
85 self.children = None
86 self.parent = parent
87 self.node = node
88 self.widget = None
90 def process(self):
91 if self.widget is not None:
92 return
93 self.widget = self.create_widget()
94 def reset_widget(w):
95 self.widget = None
96 self.widget.connect('destroy', reset_widget)
97 for attrnode in self.node.attributes:
98 value = attrnode.nodeValue
99 if value == 'False':
100 value = False
101 self.process_attrib(attrnode.nodeName, value)
102 if attrnode.nodeName == 'noborder':
103 gnt.set_flag(self.widget, gnt.WIDGET_NO_BORDER)
104 for child in self.node.childNodes:
105 self.process_child(child)
106 self.done()
108 def create_widget(self):
109 return None
111 def process_attrib(self, name, value):
112 pass
114 def process_child(self, child):
115 pass
117 def done(self):
118 pass
120 class BoxNode(WidgetNode):
121 def create_widget(self):
122 return gnt.Box(False, False)
124 def process_attrib(self, name, value):
125 if name == 'vertical':
126 self.widget.set_property('vertical', bool(value))
127 elif name == 'homo':
128 self.widget.set_property('homogeneous', bool(value))
129 elif name == 'pad':
130 self.widget.set_pad(int(value))
132 def process_child(self, child):
133 if child.nodeName == 'title':
134 self.widget.set_title(child.firstChild.nodeValue)
135 elif child.nodeName == 'widgets':
136 for widget in child.childNodes:
137 wn = process_node(widget, self)
138 if wn is not None:
139 wn.process()
140 if wn.widget is not None:
141 self.widget.add_widget(wn.widget)
143 class WindowNode(BoxNode):
144 def __init__(self, node, parent):
145 self.start = False
146 BoxNode.__init__(self, node, parent)
147 for attrnode in self.node.attributes:
148 value = attrnode.nodeValue
149 if attrnode.nodeName == 'start':
150 if value != 'False':
151 self.process()
152 elif attrnode.nodeName == 'name':
153 self.name = value
155 def create_widget(self):
156 return gnt.Window()
158 def process_attrib(self, name, value):
159 BoxNode.process_attrib(self, name, value)
160 if name == 'maximize':
161 if value == 'both':
162 self.widget.set_maximize(gnt.WINDOW_MAXIMIZE_Y | gnt.WINDOW_MAXIMIZE_X)
163 elif value == 'horiz':
164 self.widget.set_maximize(gnt.WINDOW_MAXIMIZE_X)
165 elif value == 'vert':
166 self.widget.set_maximize(gnt.WINDOW_MAXIMIZE_Y)
167 elif name == 'name':
168 self.name = value
169 elif name == 'start':
170 self.start = value
172 def done(self):
173 windows.append(self)
175 class SearchNode(WidgetNode):
176 def create_widget(self):
177 return XSearch(xmms)
179 class EqualizerNode(WidgetNode):
180 def done(self):
181 if self.widget is None: return
182 parent = self.parent
183 while parent.parent is not None:
184 parent = parent.parent
185 self.widget.win = parent.widget
187 def create_widget(self):
188 return XQSettings(xmms)
190 class PlaylistNode(WidgetNode):
191 def process_attrib(self, name, value):
192 hash = {'position': XPList.POSITION,
193 'title' : XPList.TITLE,
194 'album' : XPList.ALBUM,
195 'artist' : XPList.ARTIST,
196 'time' : XPList.TIME,
198 if name in hash:
199 col = hash[name]
200 if value == 'hide':
201 self.widget.hide_column(col)
203 def create_widget(self):
204 for attr in self.node.attributes:
205 if attr.nodeName == 'current':
206 return XPListCurrent(xmms)
207 return XPList(xmms)
209 class StatusNode(WidgetNode):
210 def create_widget(self):
211 return XStatus(xmms)
213 def process_attrib(self, name, value):
214 hash = {'title': XStatus.PROP_TITLE,
215 'album' : XStatus.PROP_ALBUM,
216 'artist' : XStatus.PROP_ARTIST,
217 'time' : XStatus.PROP_DURATION,
218 'quality' : XStatus.PROP_QUALITY,
219 'url' : XStatus.PROP_URL
221 if name in hash:
222 field = hash[name]
223 if value == 'hide':
224 self.widget.fields = self.widget.fields & ~field
225 elif value == 'show':
226 self.widget.fields = self.widget.fields | field
227 self.widget.update_fields()
229 class ConfigNode(WidgetNode):
230 def create_widget(self):
231 return XConfig(xmms)
233 maps = {
234 'window' : WindowNode,
235 'search' : SearchNode,
236 'equalizer' : EqualizerNode,
237 'playlist' : PlaylistNode,
238 'status' : StatusNode,
239 'box' : BoxNode,
240 'config' : ConfigNode,
243 def process_node(node, parent, dep = 0):
244 if node.nodeType in [node.DOCUMENT_NODE]:
245 for child in node.childNodes:
246 process_node(child, parent, dep)
247 elif node.nodeType == node.ELEMENT_NODE:
248 if node.nodeName in maps:
249 type = maps[node.nodeName]
250 ret = type(node, parent)
251 ret.done()
252 return ret
253 print "\t" * dep, node.nodeName,
254 print "[",
255 for attr in node.attributes.keys():
256 print node.attributes[attr].nodeValue,
257 print "]"
258 for child in node.childNodes:
259 process_node(child, parent, dep + 1)
260 return None
262 def read_gui(gui):
263 xml = path.expanduser("~/.config/xmms2/clients/pygnt.xml")
264 if not path.exists(xml): return gui
265 file = open(xml, "r")
266 if file:
267 gui = file.read()
268 file.close()
269 return gui
271 if xmms:
272 gui = read_gui(gui)
273 reader = Sax2.Reader()
274 doc = reader.fromString(gui)
275 process_node(doc, None)
277 def create_menu(winnode):
278 def show_winnode(item, win):
279 win.process()
280 win.widget.set_menu(create_menu(win))
281 win.widget.show()
282 win.widget.present()
284 menu = gnt.Menu(gnt.MENU_TOPLEVEL)
285 item = gnt.MenuItem("Windows")
286 menu.add_item(item)
287 sub = gnt.Menu(gnt.MENU_POPUP)
288 item.set_submenu(sub)
289 for window in windows:
290 if window == winnode:
291 continue
292 item = gnt.MenuItem(window.name)
293 sub.add_item(item)
294 item.connect('activate', show_winnode, window)
295 return menu
297 for window in windows:
298 if window.start:
299 window.widget.set_menu(create_menu(window))
300 window.widget.show()
302 gnt.gnt_main()
303 gnt.gnt_quit()