9 class _NullHildonModule(object):
14 import hildon as _hildon
15 hildon = _hildon # Dumb but gets around pyflakiness
16 except (ImportError, OSError):
17 hildon = _NullHildonModule
20 IS_HILDON_SUPPORTED = hildon is not _NullHildonModule
23 class _NullHildonProgram(object):
25 def add_window(self, window):
29 def _hildon_get_app_class():
33 def _null_get_app_class():
34 return _NullHildonProgram
39 get_app_class = _hildon_get_app_class
40 except AttributeError:
41 get_app_class = _null_get_app_class
44 def _hildon_set_application_title(window, title):
48 def _null_set_application_title(window, title):
49 window.set_title(title)
52 if IS_HILDON_SUPPORTED:
53 set_application_title = _hildon_set_application_title
55 set_application_title = _null_set_application_title
58 def _fremantle_hildonize_window(app, window):
60 newWindow = hildon.StackableWindow()
61 oldWindow.get_child().reparent(newWindow)
62 app.add_window(newWindow)
66 def _hildon_hildonize_window(app, window):
68 newWindow = hildon.Window()
69 oldWindow.get_child().reparent(newWindow)
70 app.add_window(newWindow)
74 def _null_hildonize_window(app, window):
79 hildon.StackableWindow
80 hildonize_window = _fremantle_hildonize_window
81 except AttributeError:
84 hildonize_window = _hildon_hildonize_window
85 except AttributeError:
86 hildonize_window = _null_hildonize_window
89 def _fremantle_hildonize_menu(window, gtkMenu, buttons):
90 appMenu = hildon.AppMenu()
91 for button in buttons:
92 appMenu.append(button)
93 window.set_app_menu(appMenu)
94 gtkMenu.get_parent().remove(gtkMenu)
98 def _hildon_hildonize_menu(window, gtkMenu, ignoredButtons):
99 hildonMenu = gtk.Menu()
100 for child in gtkMenu.get_children():
101 child.reparent(hildonMenu)
102 window.set_menu(hildonMenu)
107 def _null_hildonize_menu(window, gtkMenu, ignoredButtons):
113 GTK_MENU_USED = False
114 IS_FREMANTLE_SUPPORTED = True
115 hildonize_menu = _fremantle_hildonize_menu
116 except AttributeError:
118 IS_FREMANTLE_SUPPORTED = False
119 if IS_HILDON_SUPPORTED:
120 hildonize_menu = _hildon_hildonize_menu
122 hildonize_menu = _null_hildonize_menu
125 def _hildon_set_cell_thumb_selectable(renderer):
126 renderer.set_property("scale", 1.5)
129 def _null_set_cell_thumb_selectable(renderer):
133 if IS_HILDON_SUPPORTED:
134 set_cell_thumb_selectable = _hildon_set_cell_thumb_selectable
136 set_cell_thumb_selectable = _null_set_cell_thumb_selectable
139 def _fremantle_show_information_banner(parent, message):
140 hildon.hildon_banner_show_information(parent, "", message)
143 def _hildon_show_information_banner(parent, message):
144 hildon.hildon_banner_show_information(parent, None, message)
147 def _null_show_information_banner(parent, message):
151 if IS_FREMANTLE_SUPPORTED:
152 show_information_banner = _fremantle_show_information_banner
155 hildon.hildon_banner_show_information
156 show_information_banner = _hildon_show_information_banner
157 except AttributeError:
158 show_information_banner = _null_show_information_banner
161 def _fremantle_show_busy_banner_start(parent, message):
162 hildon.hildon_gtk_window_set_progress_indicator(parent, True)
166 def _fremantle_show_busy_banner_end(banner):
167 hildon.hildon_gtk_window_set_progress_indicator(banner, False)
170 def _hildon_show_busy_banner_start(parent, message):
171 return hildon.hildon_banner_show_animation(parent, None, message)
174 def _hildon_show_busy_banner_end(banner):
178 def _null_show_busy_banner_start(parent, message):
182 def _null_show_busy_banner_end(banner):
183 assert banner is None
187 hildon.hildon_gtk_window_set_progress_indicator
188 show_busy_banner_start = _fremantle_show_busy_banner_start
189 show_busy_banner_end = _fremantle_show_busy_banner_end
190 except AttributeError:
192 hildon.hildon_banner_show_animation
193 show_busy_banner_start = _hildon_show_busy_banner_start
194 show_busy_banner_end = _hildon_show_busy_banner_end
195 except AttributeError:
196 show_busy_banner_start = _null_show_busy_banner_start
197 show_busy_banner_end = _null_show_busy_banner_end
200 def _hildon_hildonize_text_entry(textEntry):
201 textEntry.set_property('hildon-input-mode', 7)
204 def _null_hildonize_text_entry(textEntry):
208 if IS_HILDON_SUPPORTED:
209 hildonize_text_entry = _hildon_hildonize_text_entry
211 hildonize_text_entry = _null_hildonize_text_entry
214 def _hildon_mark_window_rotatable(window):
215 # gtk documentation is unclear whether this does a "=" or a "|="
216 window.set_flags(hildon.HILDON_PORTRAIT_MODE_SUPPORT)
219 def _null_mark_window_rotatable(window):
224 hildon.HILDON_PORTRAIT_MODE_SUPPORT
225 mark_window_rotatable = _hildon_mark_window_rotatable
226 except AttributeError:
227 mark_window_rotatable = _null_mark_window_rotatable
230 def _hildon_window_to_portrait(window):
231 # gtk documentation is unclear whether this does a "=" or a "|="
232 window.set_flags(hildon.HILDON_PORTRAIT_MODE_SUPPORT)
235 def _hildon_window_to_landscape(window):
236 # gtk documentation is unclear whether this does a "=" or a "&= ~"
237 window.unset_flags(hildon.HILDON_PORTRAIT_MODE_REQUEST)
240 def _null_window_to_portrait(window):
244 def _null_window_to_landscape(window):
249 hildon.HILDON_PORTRAIT_MODE_SUPPORT
250 hildon.HILDON_PORTRAIT_MODE_REQUEST
252 window_to_portrait = _hildon_window_to_portrait
253 window_to_landscape = _hildon_window_to_landscape
254 except AttributeError:
255 window_to_portrait = _null_window_to_portrait
256 window_to_landscape = _null_window_to_landscape
259 def get_device_orientation():
260 bus = dbus.SystemBus()
262 rawMceRequest = bus.get_object("com.nokia.mce", "/com/nokia/mce/request")
263 mceRequest = dbus.Interface(rawMceRequest, dbus_interface="com.nokia.mce.request")
264 orientation, standState, faceState, xAxis, yAxis, zAxis = mceRequest.get_device_orientation()
265 except dbus.exception.DBusException:
266 # catching for documentation purposes that when a system doesn't
267 # support this, this is what to expect
270 if orientation == "":
271 return gtk.ORIENTATION_HORIZONTAL
272 elif orientation == "":
273 return gtk.ORIENTATION_VERTICAL
275 raise RuntimeError("Unknown orientation: %s" % orientation)
278 def _hildon_hildonize_password_entry(textEntry):
279 textEntry.set_property('hildon-input-mode', 7 | (1 << 29))
282 def _null_hildonize_password_entry(textEntry):
286 if IS_HILDON_SUPPORTED:
287 hildonize_password_entry = _hildon_hildonize_password_entry
289 hildonize_password_entry = _null_hildonize_password_entry
292 def _hildon_hildonize_combo_entry(comboEntry):
293 comboEntry.set_property('hildon-input-mode', 1 << 4)
296 def _null_hildonize_combo_entry(textEntry):
300 if IS_HILDON_SUPPORTED:
301 hildonize_combo_entry = _hildon_hildonize_combo_entry
303 hildonize_combo_entry = _null_hildonize_combo_entry
306 def _fremantle_hildonize_scrollwindow(scrolledWindow):
307 pannableWindow = hildon.PannableArea()
309 child = scrolledWindow.get_child()
310 scrolledWindow.remove(child)
311 pannableWindow.add(child)
313 parent = scrolledWindow.get_parent()
314 parent.remove(scrolledWindow)
315 parent.add(pannableWindow)
317 return pannableWindow
320 def _hildon_hildonize_scrollwindow(scrolledWindow):
321 hildon.hildon_helper_set_thumb_scrollbar(scrolledWindow, True)
322 return scrolledWindow
325 def _null_hildonize_scrollwindow(scrolledWindow):
326 return scrolledWindow
331 hildonize_scrollwindow = _fremantle_hildonize_scrollwindow
332 hildonize_scrollwindow_with_viewport = _hildon_hildonize_scrollwindow
333 except AttributeError:
335 hildon.hildon_helper_set_thumb_scrollbar
336 hildonize_scrollwindow = _hildon_hildonize_scrollwindow
337 hildonize_scrollwindow_with_viewport = _hildon_hildonize_scrollwindow
338 except AttributeError:
339 hildonize_scrollwindow = _null_hildonize_scrollwindow
340 hildonize_scrollwindow_with_viewport = _null_hildonize_scrollwindow
343 def _hildon_request_number(parent, title, range, default):
344 spinner = hildon.NumberEditor(*range)
345 spinner.set_value(default)
350 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
351 (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
353 dialog.set_default_response(gtk.RESPONSE_CANCEL)
354 dialog.get_child().add(spinner)
358 response = dialog.run()
362 if response == gtk.RESPONSE_OK:
363 return spinner.get_value()
364 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
365 raise RuntimeError("User cancelled request")
367 raise RuntimeError("Unrecognized response %r", response)
370 def _null_request_number(parent, title, range, default):
371 adjustment = gtk.Adjustment(default, range[0], range[1], 1, 5, 0)
372 spinner = gtk.SpinButton(adjustment, 0, 0)
373 spinner.set_wrap(False)
378 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
379 (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
381 dialog.set_default_response(gtk.RESPONSE_CANCEL)
382 dialog.get_child().add(spinner)
386 response = dialog.run()
390 if response == gtk.RESPONSE_OK:
391 return spinner.get_value_as_int()
392 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
393 raise RuntimeError("User cancelled request")
395 raise RuntimeError("Unrecognized response %r", response)
399 hildon.NumberEditor # TODO deprecated in fremantle
400 request_number = _hildon_request_number
401 except AttributeError:
402 request_number = _null_request_number
405 def _hildon_touch_selector(parent, title, items, defaultIndex):
406 model = gtk.ListStore(gobject.TYPE_STRING)
408 model.append((item, ))
410 selector = hildon.TouchSelector()
411 selector.append_text_column(model, True)
412 selector.set_column_selection_mode(hildon.TOUCH_SELECTOR_SELECTION_MODE_SINGLE)
413 selector.set_active(0, defaultIndex)
415 dialog = hildon.PickerDialog(parent)
416 dialog.set_selector(selector)
420 response = dialog.run()
424 if response == gtk.RESPONSE_OK:
425 return selector.get_active(0)
426 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
427 raise RuntimeError("User cancelled request")
429 raise RuntimeError("Unrecognized response %r", response)
432 def _on_null_touch_selector_activated(treeView, path, column, dialog):
433 dialog.response(gtk.RESPONSE_OK)
436 def _null_touch_selector(parent, title, items, defaultIndex = -1):
437 model = gtk.ListStore(gobject.TYPE_STRING)
439 model.append((item, ))
441 cell = gtk.CellRendererText()
442 set_cell_thumb_selectable(cell)
443 column = gtk.TreeViewColumn(title)
444 column .pack_start(cell, expand=True)
445 column.add_attribute(cell, "text", 0)
447 treeView = gtk.TreeView()
448 treeView.set_model(model)
449 treeView.append_column(column)
450 selection = treeView.get_selection()
451 selection.set_mode(gtk.SELECTION_SINGLE)
453 selection.select_path((defaultIndex, ))
455 scrolledWin = gtk.ScrolledWindow()
456 scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
457 scrolledWin.add(treeView)
458 hildonize_scrollwindow(scrolledWin)
463 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
464 (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
466 dialog.set_default_response(gtk.RESPONSE_CANCEL)
467 dialog.get_child().add(scrolledWin)
468 parentSize = parent.get_size()
469 dialog.resize(parentSize[0], max(parentSize[1]-100, 100))
470 treeView.connect("row-activated", _on_null_touch_selector_activated, dialog)
474 response = dialog.run()
478 if response == gtk.RESPONSE_OK:
479 model, itr = selection.get_selected()
481 raise RuntimeError("No selection made")
482 return model.get_path(itr)[0]
483 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
484 raise RuntimeError("User cancelled request")
486 raise RuntimeError("Unrecognized response %r", response)
492 touch_selector = _hildon_touch_selector
493 except AttributeError:
494 touch_selector = _null_touch_selector
497 def _hildon_touch_selector_entry(parent, title, items, defaultItem):
498 # Got a segfault when using append_text_column with TouchSelectorEntry, so using this way
499 selector = hildon.hildon_touch_selector_entry_new_text()
501 for i, item in enumerate(items):
502 selector.append_text(item)
503 if item == defaultItem:
506 dialog = hildon.PickerDialog(parent)
507 dialog.set_selector(selector)
510 selector.set_active(0, defaultIndex)
512 selector.get_entry().set_text(defaultItem)
516 response = dialog.run()
520 if response == gtk.RESPONSE_OK:
521 selectedIndex = selector.get_active(0)
522 if 0 < selectedIndex:
523 return items[selectedIndex]
525 return selector.get_entry().get_text()
526 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
527 raise RuntimeError("User cancelled request")
529 raise RuntimeError("Unrecognized response %r", response)
532 def _on_null_touch_selector_entry_entry_activated(entry, dialog, customEntry, result):
533 dialog.response(gtk.RESPONSE_OK)
534 result.append(customEntry.get_text())
537 def _on_null_touch_selector_entry_tree_activated(treeView, path, column, dialog, selection, result):
538 dialog.response(gtk.RESPONSE_OK)
539 model, itr = selection.get_selected()
541 result.append(model.get_value(itr, 0))
544 def _null_touch_selector_entry(parent, title, items, defaultItem):
545 model = gtk.ListStore(gobject.TYPE_STRING)
547 for i, item in enumerate(items):
548 model.append((item, ))
549 if item == defaultItem:
552 cell = gtk.CellRendererText()
553 set_cell_thumb_selectable(cell)
554 column = gtk.TreeViewColumn(title)
555 column .pack_start(cell, expand=True)
556 column.add_attribute(cell, "text", 0)
558 treeView = gtk.TreeView()
559 treeView.set_model(model)
560 treeView.append_column(column)
561 selection = treeView.get_selection()
562 selection.set_mode(gtk.SELECTION_SINGLE)
564 scrolledWin = gtk.ScrolledWindow()
565 scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
566 scrolledWin.add(treeView)
568 customEntry = gtk.Entry()
571 layout.pack_start(customEntry, expand=False)
572 layout.pack_start(scrolledWin)
574 hildonize_scrollwindow(layout)
579 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
580 (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
582 dialog.set_default_response(gtk.RESPONSE_CANCEL)
583 dialog.get_child().add(layout)
584 parentSize = parent.get_size()
585 dialog.resize(parentSize[0], max(parentSize[1]-100, 100))
588 selection.select_path((defaultIndex, ))
590 customEntry.set_text(defaultItem)
592 customEntry.connect("activate", _on_null_touch_selector_entry_entry_activated, dialog, customEntry, result)
593 treeView.connect("row-activated", _on_null_touch_selector_entry_tree_activated, dialog, selection, result)
597 response = dialog.run()
601 if response == gtk.RESPONSE_OK:
602 model, itr = selection.get_selected()
604 raise RuntimeError("No selection made")
607 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
608 raise RuntimeError("User cancelled request")
610 raise RuntimeError("Unrecognized response %r", response)
615 hildon.TouchSelectorEntry
616 touch_selector_entry = _hildon_touch_selector_entry
617 except AttributeError:
618 touch_selector_entry = _null_touch_selector_entry
621 if __name__ == "__main__":
622 app = get_app_class()()
624 label = gtk.Label("Hello World from a Label!")
628 win = hildonize_window(app, win)
630 print touch_selector(win, "Test", ["A", "B", "C", "D"], 2)
632 print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "C")
633 print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "Blah")
638 (name, value) for (name, value) in locals().iteritems()
639 if not name.startswith("_")
641 pprint.pprint(goodLocals)
644 show_information_banner(win, "Hello World")
648 banner = show_busy_banner_start(win, "Hello World")
650 show_busy_banner_end(banner)