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_button_auto_selectable(button):
126 button.set_theme_size(hildon.HILDON_SIZE_AUTO_HEIGHT)
129 def _null_set_button_auto_selectable(button):
134 hildon.HILDON_SIZE_AUTO_HEIGHT
135 set_button_auto_selectable = _hildon_set_button_auto_selectable
136 except AttributeError:
137 set_button_auto_selectable = _null_set_button_auto_selectable
140 def _hildon_set_button_finger_selectable(button):
141 button.set_theme_size(hildon.HILDON_SIZE_FINGER_HEIGHT)
144 def _null_set_button_finger_selectable(button):
149 hildon.HILDON_SIZE_FINGER_HEIGHT
150 set_button_finger_selectable = _hildon_set_button_finger_selectable
151 except AttributeError:
152 set_button_finger_selectable = _null_set_button_finger_selectable
155 def _hildon_set_button_thumb_selectable(button):
156 button.set_theme_size(hildon.HILDON_SIZE_THUMB_HEIGHT)
159 def _null_set_button_thumb_selectable(button):
164 hildon.HILDON_SIZE_THUMB_HEIGHT
165 set_button_thumb_selectable = _hildon_set_button_thumb_selectable
166 except AttributeError:
167 set_button_thumb_selectable = _null_set_button_thumb_selectable
170 def _hildon_set_cell_thumb_selectable(renderer):
171 renderer.set_property("scale", 1.5)
174 def _null_set_cell_thumb_selectable(renderer):
178 if IS_HILDON_SUPPORTED:
179 set_cell_thumb_selectable = _hildon_set_cell_thumb_selectable
181 set_cell_thumb_selectable = _null_set_cell_thumb_selectable
184 def _fremantle_show_information_banner(parent, message):
185 hildon.hildon_banner_show_information(parent, "", message)
188 def _hildon_show_information_banner(parent, message):
189 hildon.hildon_banner_show_information(parent, None, message)
192 def _null_show_information_banner(parent, message):
196 if IS_FREMANTLE_SUPPORTED:
197 show_information_banner = _fremantle_show_information_banner
200 hildon.hildon_banner_show_information
201 show_information_banner = _hildon_show_information_banner
202 except AttributeError:
203 show_information_banner = _null_show_information_banner
206 def _fremantle_show_busy_banner_start(parent, message):
207 hildon.hildon_gtk_window_set_progress_indicator(parent, True)
211 def _fremantle_show_busy_banner_end(banner):
212 hildon.hildon_gtk_window_set_progress_indicator(banner, False)
215 def _hildon_show_busy_banner_start(parent, message):
216 return hildon.hildon_banner_show_animation(parent, None, message)
219 def _hildon_show_busy_banner_end(banner):
223 def _null_show_busy_banner_start(parent, message):
227 def _null_show_busy_banner_end(banner):
228 assert banner is None
232 hildon.hildon_gtk_window_set_progress_indicator
233 show_busy_banner_start = _fremantle_show_busy_banner_start
234 show_busy_banner_end = _fremantle_show_busy_banner_end
235 except AttributeError:
237 hildon.hildon_banner_show_animation
238 show_busy_banner_start = _hildon_show_busy_banner_start
239 show_busy_banner_end = _hildon_show_busy_banner_end
240 except AttributeError:
241 show_busy_banner_start = _null_show_busy_banner_start
242 show_busy_banner_end = _null_show_busy_banner_end
245 def _hildon_hildonize_text_entry(textEntry):
246 textEntry.set_property('hildon-input-mode', 7)
249 def _null_hildonize_text_entry(textEntry):
253 if IS_HILDON_SUPPORTED:
254 hildonize_text_entry = _hildon_hildonize_text_entry
256 hildonize_text_entry = _null_hildonize_text_entry
259 def _hildon_mark_window_rotatable(window):
260 # gtk documentation is unclear whether this does a "=" or a "|="
261 window.set_flags(hildon.HILDON_PORTRAIT_MODE_SUPPORT)
264 def _null_mark_window_rotatable(window):
269 hildon.HILDON_PORTRAIT_MODE_SUPPORT
270 mark_window_rotatable = _hildon_mark_window_rotatable
271 except AttributeError:
272 mark_window_rotatable = _null_mark_window_rotatable
275 def _hildon_window_to_portrait(window):
276 # gtk documentation is unclear whether this does a "=" or a "|="
277 window.set_flags(hildon.HILDON_PORTRAIT_MODE_SUPPORT)
280 def _hildon_window_to_landscape(window):
281 # gtk documentation is unclear whether this does a "=" or a "&= ~"
282 window.unset_flags(hildon.HILDON_PORTRAIT_MODE_REQUEST)
285 def _null_window_to_portrait(window):
289 def _null_window_to_landscape(window):
294 hildon.HILDON_PORTRAIT_MODE_SUPPORT
295 hildon.HILDON_PORTRAIT_MODE_REQUEST
297 window_to_portrait = _hildon_window_to_portrait
298 window_to_landscape = _hildon_window_to_landscape
299 except AttributeError:
300 window_to_portrait = _null_window_to_portrait
301 window_to_landscape = _null_window_to_landscape
304 def get_device_orientation():
305 bus = dbus.SystemBus()
307 rawMceRequest = bus.get_object("com.nokia.mce", "/com/nokia/mce/request")
308 mceRequest = dbus.Interface(rawMceRequest, dbus_interface="com.nokia.mce.request")
309 orientation, standState, faceState, xAxis, yAxis, zAxis = mceRequest.get_device_orientation()
310 except dbus.exception.DBusException:
311 # catching for documentation purposes that when a system doesn't
312 # support this, this is what to expect
315 if orientation == "":
316 return gtk.ORIENTATION_HORIZONTAL
317 elif orientation == "":
318 return gtk.ORIENTATION_VERTICAL
320 raise RuntimeError("Unknown orientation: %s" % orientation)
323 def _hildon_hildonize_password_entry(textEntry):
324 textEntry.set_property('hildon-input-mode', 7 | (1 << 29))
327 def _null_hildonize_password_entry(textEntry):
331 if IS_HILDON_SUPPORTED:
332 hildonize_password_entry = _hildon_hildonize_password_entry
334 hildonize_password_entry = _null_hildonize_password_entry
337 def _hildon_hildonize_combo_entry(comboEntry):
338 comboEntry.set_property('hildon-input-mode', 1 << 4)
341 def _null_hildonize_combo_entry(textEntry):
345 if IS_HILDON_SUPPORTED:
346 hildonize_combo_entry = _hildon_hildonize_combo_entry
348 hildonize_combo_entry = _null_hildonize_combo_entry
351 def _fremantle_hildonize_scrollwindow(scrolledWindow):
352 pannableWindow = hildon.PannableArea()
354 child = scrolledWindow.get_child()
355 scrolledWindow.remove(child)
356 pannableWindow.add(child)
358 parent = scrolledWindow.get_parent()
359 parent.remove(scrolledWindow)
360 parent.add(pannableWindow)
362 return pannableWindow
365 def _hildon_hildonize_scrollwindow(scrolledWindow):
366 hildon.hildon_helper_set_thumb_scrollbar(scrolledWindow, True)
367 return scrolledWindow
370 def _null_hildonize_scrollwindow(scrolledWindow):
371 return scrolledWindow
376 hildonize_scrollwindow = _fremantle_hildonize_scrollwindow
377 hildonize_scrollwindow_with_viewport = _hildon_hildonize_scrollwindow
378 except AttributeError:
380 hildon.hildon_helper_set_thumb_scrollbar
381 hildonize_scrollwindow = _hildon_hildonize_scrollwindow
382 hildonize_scrollwindow_with_viewport = _hildon_hildonize_scrollwindow
383 except AttributeError:
384 hildonize_scrollwindow = _null_hildonize_scrollwindow
385 hildonize_scrollwindow_with_viewport = _null_hildonize_scrollwindow
388 def _hildon_request_number(parent, title, range, default):
389 spinner = hildon.NumberEditor(*range)
390 spinner.set_value(default)
395 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
396 (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
398 dialog.set_default_response(gtk.RESPONSE_CANCEL)
399 dialog.get_child().add(spinner)
403 response = dialog.run()
407 if response == gtk.RESPONSE_OK:
408 return spinner.get_value()
409 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
410 raise RuntimeError("User cancelled request")
412 raise RuntimeError("Unrecognized response %r", response)
415 def _null_request_number(parent, title, range, default):
416 adjustment = gtk.Adjustment(default, range[0], range[1], 1, 5, 0)
417 spinner = gtk.SpinButton(adjustment, 0, 0)
418 spinner.set_wrap(False)
423 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
424 (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
426 dialog.set_default_response(gtk.RESPONSE_CANCEL)
427 dialog.get_child().add(spinner)
431 response = dialog.run()
435 if response == gtk.RESPONSE_OK:
436 return spinner.get_value_as_int()
437 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
438 raise RuntimeError("User cancelled request")
440 raise RuntimeError("Unrecognized response %r", response)
444 hildon.NumberEditor # TODO deprecated in fremantle
445 request_number = _hildon_request_number
446 except AttributeError:
447 request_number = _null_request_number
450 def _hildon_touch_selector(parent, title, items, defaultIndex):
451 model = gtk.ListStore(gobject.TYPE_STRING)
453 model.append((item, ))
455 selector = hildon.TouchSelector()
456 selector.append_text_column(model, True)
457 selector.set_column_selection_mode(hildon.TOUCH_SELECTOR_SELECTION_MODE_SINGLE)
458 selector.set_active(0, defaultIndex)
460 dialog = hildon.PickerDialog(parent)
461 dialog.set_selector(selector)
465 response = dialog.run()
469 if response == gtk.RESPONSE_OK:
470 return selector.get_active(0)
471 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
472 raise RuntimeError("User cancelled request")
474 raise RuntimeError("Unrecognized response %r", response)
477 def _on_null_touch_selector_activated(treeView, path, column, dialog):
478 dialog.response(gtk.RESPONSE_OK)
481 def _null_touch_selector(parent, title, items, defaultIndex = -1):
482 model = gtk.ListStore(gobject.TYPE_STRING)
484 model.append((item, ))
486 cell = gtk.CellRendererText()
487 set_cell_thumb_selectable(cell)
488 column = gtk.TreeViewColumn(title)
489 column .pack_start(cell, expand=True)
490 column.add_attribute(cell, "text", 0)
492 treeView = gtk.TreeView()
493 treeView.set_model(model)
494 treeView.append_column(column)
495 selection = treeView.get_selection()
496 selection.set_mode(gtk.SELECTION_SINGLE)
498 selection.select_path((defaultIndex, ))
500 scrolledWin = gtk.ScrolledWindow()
501 scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
502 scrolledWin.add(treeView)
503 hildonize_scrollwindow(scrolledWin)
508 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
509 (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
511 dialog.set_default_response(gtk.RESPONSE_CANCEL)
512 dialog.get_child().add(scrolledWin)
513 parentSize = parent.get_size()
514 dialog.resize(parentSize[0], max(parentSize[1]-100, 100))
515 treeView.connect("row-activated", _on_null_touch_selector_activated, dialog)
519 response = dialog.run()
523 if response == gtk.RESPONSE_OK:
524 model, itr = selection.get_selected()
526 raise RuntimeError("No selection made")
527 return model.get_path(itr)[0]
528 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
529 raise RuntimeError("User cancelled request")
531 raise RuntimeError("Unrecognized response %r", response)
537 touch_selector = _hildon_touch_selector
538 except AttributeError:
539 touch_selector = _null_touch_selector
542 def _hildon_touch_selector_entry(parent, title, items, defaultItem):
543 # Got a segfault when using append_text_column with TouchSelectorEntry, so using this way
545 selector = hildon.TouchSelectorEntry(text=True)
547 selector = hildon.hildon_touch_selector_entry_new_text()
549 for i, item in enumerate(items):
550 selector.append_text(item)
551 if item == defaultItem:
554 dialog = hildon.PickerDialog(parent)
555 dialog.set_selector(selector)
558 selector.set_active(0, defaultIndex)
560 selector.get_entry().set_text(defaultItem)
564 response = dialog.run()
568 if response == gtk.RESPONSE_OK:
569 return selector.get_entry().get_text()
570 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
571 raise RuntimeError("User cancelled request")
573 raise RuntimeError("Unrecognized response %r", response)
576 def _on_null_touch_selector_entry_entry_activated(entry, dialog, customEntry, result):
577 dialog.response(gtk.RESPONSE_OK)
578 result.append(customEntry.get_text())
581 def _on_null_touch_selector_entry_tree_activated(treeView, path, column, dialog, selection, result):
582 dialog.response(gtk.RESPONSE_OK)
583 model, itr = selection.get_selected()
585 result.append(model.get_value(itr, 0))
588 def _null_touch_selector_entry(parent, title, items, defaultItem):
589 model = gtk.ListStore(gobject.TYPE_STRING)
591 for i, item in enumerate(items):
592 model.append((item, ))
593 if item == defaultItem:
596 cell = gtk.CellRendererText()
597 set_cell_thumb_selectable(cell)
598 column = gtk.TreeViewColumn(title)
599 column .pack_start(cell, expand=True)
600 column.add_attribute(cell, "text", 0)
602 treeView = gtk.TreeView()
603 treeView.set_model(model)
604 treeView.append_column(column)
605 selection = treeView.get_selection()
606 selection.set_mode(gtk.SELECTION_SINGLE)
608 scrolledWin = gtk.ScrolledWindow()
609 scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
610 scrolledWin.add(treeView)
611 hildonize_scrollwindow(scrolledWin)
613 customEntry = gtk.Entry()
616 layout.pack_start(customEntry, expand=False)
617 layout.pack_start(scrolledWin)
622 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
623 (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
625 dialog.set_default_response(gtk.RESPONSE_CANCEL)
626 dialog.get_child().add(layout)
627 parentSize = parent.get_size()
628 dialog.resize(parentSize[0], max(parentSize[1]-100, 100))
631 selection.select_path((defaultIndex, ))
633 customEntry.set_text(defaultItem)
635 customEntry.connect("activate", _on_null_touch_selector_entry_entry_activated, dialog, customEntry, result)
636 treeView.connect("row-activated", _on_null_touch_selector_entry_tree_activated, dialog, selection, result)
640 response = dialog.run()
644 if response == gtk.RESPONSE_OK:
645 model, itr = selection.get_selected()
647 raise RuntimeError("No selection made")
650 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
651 raise RuntimeError("User cancelled request")
653 raise RuntimeError("Unrecognized response %r", response)
658 hildon.TouchSelectorEntry
659 touch_selector_entry = _hildon_touch_selector_entry
660 except AttributeError:
661 touch_selector_entry = _null_touch_selector_entry
664 if __name__ == "__main__":
665 app = get_app_class()()
667 label = gtk.Label("Hello World from a Label!")
671 win = hildonize_window(app, win)
673 print touch_selector(win, "Test", ["A", "B", "C", "D"], 2)
675 print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "C")
676 print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "Blah")
681 (name, value) for (name, value) in locals().iteritems()
682 if not name.startswith("_")
684 pprint.pprint(goodLocals)
687 show_information_banner(win, "Hello World")
691 banner = show_busy_banner_start(win, "Hello World")
693 show_busy_banner_end(banner)