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 gtk.Button.set_theme_size
136 set_button_auto_selectable = _hildon_set_button_auto_selectable
137 except AttributeError:
138 set_button_auto_selectable = _null_set_button_auto_selectable
141 def _hildon_set_button_finger_selectable(button):
142 button.set_theme_size(hildon.HILDON_SIZE_FINGER_HEIGHT)
145 def _null_set_button_finger_selectable(button):
150 hildon.HILDON_SIZE_FINGER_HEIGHT
151 gtk.Button.set_theme_size
152 set_button_finger_selectable = _hildon_set_button_finger_selectable
153 except AttributeError:
154 set_button_finger_selectable = _null_set_button_finger_selectable
157 def _hildon_set_button_thumb_selectable(button):
158 button.set_theme_size(hildon.HILDON_SIZE_THUMB_HEIGHT)
161 def _null_set_button_thumb_selectable(button):
166 hildon.HILDON_SIZE_THUMB_HEIGHT
167 gtk.Button.set_theme_size
168 set_button_thumb_selectable = _hildon_set_button_thumb_selectable
169 except AttributeError:
170 set_button_thumb_selectable = _null_set_button_thumb_selectable
173 def _hildon_set_cell_thumb_selectable(renderer):
174 renderer.set_property("scale", 1.5)
177 def _null_set_cell_thumb_selectable(renderer):
181 if IS_HILDON_SUPPORTED:
182 set_cell_thumb_selectable = _hildon_set_cell_thumb_selectable
184 set_cell_thumb_selectable = _null_set_cell_thumb_selectable
187 def _fremantle_show_information_banner(parent, message):
188 hildon.hildon_banner_show_information(parent, "", message)
191 def _hildon_show_information_banner(parent, message):
192 hildon.hildon_banner_show_information(parent, None, message)
195 def _null_show_information_banner(parent, message):
199 if IS_FREMANTLE_SUPPORTED:
200 show_information_banner = _fremantle_show_information_banner
203 hildon.hildon_banner_show_information
204 show_information_banner = _hildon_show_information_banner
205 except AttributeError:
206 show_information_banner = _null_show_information_banner
209 def _fremantle_show_busy_banner_start(parent, message):
210 hildon.hildon_gtk_window_set_progress_indicator(parent, True)
214 def _fremantle_show_busy_banner_end(banner):
215 hildon.hildon_gtk_window_set_progress_indicator(banner, False)
218 def _hildon_show_busy_banner_start(parent, message):
219 return hildon.hildon_banner_show_animation(parent, None, message)
222 def _hildon_show_busy_banner_end(banner):
226 def _null_show_busy_banner_start(parent, message):
230 def _null_show_busy_banner_end(banner):
231 assert banner is None
235 hildon.hildon_gtk_window_set_progress_indicator
236 show_busy_banner_start = _fremantle_show_busy_banner_start
237 show_busy_banner_end = _fremantle_show_busy_banner_end
238 except AttributeError:
240 hildon.hildon_banner_show_animation
241 show_busy_banner_start = _hildon_show_busy_banner_start
242 show_busy_banner_end = _hildon_show_busy_banner_end
243 except AttributeError:
244 show_busy_banner_start = _null_show_busy_banner_start
245 show_busy_banner_end = _null_show_busy_banner_end
248 def _hildon_hildonize_text_entry(textEntry):
249 textEntry.set_property('hildon-input-mode', 7)
252 def _null_hildonize_text_entry(textEntry):
256 if IS_HILDON_SUPPORTED:
257 hildonize_text_entry = _hildon_hildonize_text_entry
259 hildonize_text_entry = _null_hildonize_text_entry
262 def _hildon_mark_window_rotatable(window):
263 # gtk documentation is unclear whether this does a "=" or a "|="
264 window.set_flags(hildon.HILDON_PORTRAIT_MODE_SUPPORT)
267 def _null_mark_window_rotatable(window):
272 hildon.HILDON_PORTRAIT_MODE_SUPPORT
273 mark_window_rotatable = _hildon_mark_window_rotatable
274 except AttributeError:
275 mark_window_rotatable = _null_mark_window_rotatable
278 def _hildon_window_to_portrait(window):
279 # gtk documentation is unclear whether this does a "=" or a "|="
280 window.set_flags(hildon.HILDON_PORTRAIT_MODE_SUPPORT)
283 def _hildon_window_to_landscape(window):
284 # gtk documentation is unclear whether this does a "=" or a "&= ~"
285 window.unset_flags(hildon.HILDON_PORTRAIT_MODE_REQUEST)
288 def _null_window_to_portrait(window):
292 def _null_window_to_landscape(window):
297 hildon.HILDON_PORTRAIT_MODE_SUPPORT
298 hildon.HILDON_PORTRAIT_MODE_REQUEST
300 window_to_portrait = _hildon_window_to_portrait
301 window_to_landscape = _hildon_window_to_landscape
302 except AttributeError:
303 window_to_portrait = _null_window_to_portrait
304 window_to_landscape = _null_window_to_landscape
307 def get_device_orientation():
308 bus = dbus.SystemBus()
310 rawMceRequest = bus.get_object("com.nokia.mce", "/com/nokia/mce/request")
311 mceRequest = dbus.Interface(rawMceRequest, dbus_interface="com.nokia.mce.request")
312 orientation, standState, faceState, xAxis, yAxis, zAxis = mceRequest.get_device_orientation()
313 except dbus.exception.DBusException:
314 # catching for documentation purposes that when a system doesn't
315 # support this, this is what to expect
318 if orientation == "":
319 return gtk.ORIENTATION_HORIZONTAL
320 elif orientation == "":
321 return gtk.ORIENTATION_VERTICAL
323 raise RuntimeError("Unknown orientation: %s" % orientation)
326 def _hildon_hildonize_password_entry(textEntry):
327 textEntry.set_property('hildon-input-mode', 7 | (1 << 29))
330 def _null_hildonize_password_entry(textEntry):
334 if IS_HILDON_SUPPORTED:
335 hildonize_password_entry = _hildon_hildonize_password_entry
337 hildonize_password_entry = _null_hildonize_password_entry
340 def _hildon_hildonize_combo_entry(comboEntry):
341 comboEntry.set_property('hildon-input-mode', 1 << 4)
344 def _null_hildonize_combo_entry(textEntry):
348 if IS_HILDON_SUPPORTED:
349 hildonize_combo_entry = _hildon_hildonize_combo_entry
351 hildonize_combo_entry = _null_hildonize_combo_entry
354 def _fremantle_hildonize_scrollwindow(scrolledWindow):
355 pannableWindow = hildon.PannableArea()
357 child = scrolledWindow.get_child()
358 scrolledWindow.remove(child)
359 pannableWindow.add(child)
361 parent = scrolledWindow.get_parent()
362 if parent is not None:
363 parent.remove(scrolledWindow)
364 parent.add(pannableWindow)
366 return pannableWindow
369 def _hildon_hildonize_scrollwindow(scrolledWindow):
370 hildon.hildon_helper_set_thumb_scrollbar(scrolledWindow, True)
371 return scrolledWindow
374 def _null_hildonize_scrollwindow(scrolledWindow):
375 return scrolledWindow
380 hildonize_scrollwindow = _fremantle_hildonize_scrollwindow
381 hildonize_scrollwindow_with_viewport = _hildon_hildonize_scrollwindow
382 except AttributeError:
384 hildon.hildon_helper_set_thumb_scrollbar
385 hildonize_scrollwindow = _hildon_hildonize_scrollwindow
386 hildonize_scrollwindow_with_viewport = _hildon_hildonize_scrollwindow
387 except AttributeError:
388 hildonize_scrollwindow = _null_hildonize_scrollwindow
389 hildonize_scrollwindow_with_viewport = _null_hildonize_scrollwindow
392 def _hildon_request_number(parent, title, range, default):
393 spinner = hildon.NumberEditor(*range)
394 spinner.set_value(default)
399 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
400 (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
402 dialog.set_default_response(gtk.RESPONSE_CANCEL)
403 dialog.get_child().add(spinner)
407 response = dialog.run()
409 if response == gtk.RESPONSE_OK:
410 return spinner.get_value()
411 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
412 raise RuntimeError("User cancelled request")
414 raise RuntimeError("Unrecognized response %r", response)
420 def _null_request_number(parent, title, range, default):
421 adjustment = gtk.Adjustment(default, range[0], range[1], 1, 5, 0)
422 spinner = gtk.SpinButton(adjustment, 0, 0)
423 spinner.set_wrap(False)
428 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
429 (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
431 dialog.set_default_response(gtk.RESPONSE_CANCEL)
432 dialog.get_child().add(spinner)
436 response = dialog.run()
438 if response == gtk.RESPONSE_OK:
439 return spinner.get_value_as_int()
440 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
441 raise RuntimeError("User cancelled request")
443 raise RuntimeError("Unrecognized response %r", response)
450 hildon.NumberEditor # TODO deprecated in fremantle
451 request_number = _hildon_request_number
452 except AttributeError:
453 request_number = _null_request_number
456 def _hildon_touch_selector(parent, title, items, defaultIndex):
457 model = gtk.ListStore(gobject.TYPE_STRING)
459 model.append((item, ))
461 selector = hildon.TouchSelector()
462 selector.append_text_column(model, True)
463 selector.set_column_selection_mode(hildon.TOUCH_SELECTOR_SELECTION_MODE_SINGLE)
464 selector.set_active(0, defaultIndex)
466 dialog = hildon.PickerDialog(parent)
467 dialog.set_selector(selector)
471 response = dialog.run()
473 if response == gtk.RESPONSE_OK:
474 return selector.get_active(0)
475 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
476 raise RuntimeError("User cancelled request")
478 raise RuntimeError("Unrecognized response %r", response)
484 def _on_null_touch_selector_activated(treeView, path, column, dialog, pathData):
485 dialog.response(gtk.RESPONSE_OK)
489 def _null_touch_selector(parent, title, items, defaultIndex = -1):
490 parentSize = parent.get_size()
492 model = gtk.ListStore(gobject.TYPE_STRING)
494 model.append((item, ))
496 cell = gtk.CellRendererText()
497 set_cell_thumb_selectable(cell)
498 column = gtk.TreeViewColumn(title)
499 column.pack_start(cell, expand=True)
500 column.add_attribute(cell, "text", 0)
502 treeView = gtk.TreeView()
503 treeView.set_model(model)
504 treeView.append_column(column)
505 selection = treeView.get_selection()
506 selection.set_mode(gtk.SELECTION_SINGLE)
508 selection.select_path((defaultIndex, ))
510 scrolledWin = gtk.ScrolledWindow()
511 scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
512 scrolledWin.add(treeView)
517 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
518 (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
520 dialog.set_default_response(gtk.RESPONSE_CANCEL)
521 dialog.get_child().add(scrolledWin)
522 dialog.resize(parentSize[0], max(parentSize[1]-100, 100))
524 scrolledWin = hildonize_scrollwindow(scrolledWin)
526 treeView.connect("row-activated", _on_null_touch_selector_activated, dialog, pathData)
530 response = dialog.run()
532 if response == gtk.RESPONSE_OK:
533 if pathData[0] is None:
534 raise RuntimeError("No selection made")
535 return pathData[0][0]
536 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
537 raise RuntimeError("User cancelled request")
539 raise RuntimeError("Unrecognized response %r", response)
548 touch_selector = _hildon_touch_selector
549 except AttributeError:
550 touch_selector = _null_touch_selector
553 def _hildon_touch_selector_entry(parent, title, items, defaultItem):
554 # Got a segfault when using append_text_column with TouchSelectorEntry, so using this way
556 selector = hildon.TouchSelectorEntry(text=True)
558 selector = hildon.hildon_touch_selector_entry_new_text()
560 for i, item in enumerate(items):
561 selector.append_text(item)
562 if item == defaultItem:
565 dialog = hildon.PickerDialog(parent)
566 dialog.set_selector(selector)
569 selector.set_active(0, defaultIndex)
571 selector.get_entry().set_text(defaultItem)
575 response = dialog.run()
579 if response == gtk.RESPONSE_OK:
580 return selector.get_entry().get_text()
581 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
582 raise RuntimeError("User cancelled request")
584 raise RuntimeError("Unrecognized response %r", response)
587 def _on_null_touch_selector_entry_entry_changed(entry, result, selection, defaultIndex):
588 custom = entry.get_text().strip()
591 selection.unselect_all()
594 selection.select_path((defaultIndex, ))
597 def _on_null_touch_selector_entry_entry_activated(customEntry, dialog, result):
598 dialog.response(gtk.RESPONSE_OK)
599 result[0] = customEntry.get_text()
602 def _on_null_touch_selector_entry_tree_activated(treeView, path, column, dialog, result):
603 dialog.response(gtk.RESPONSE_OK)
604 model = treeView.get_model()
605 itr = model.get_iter(path)
607 result[0] = model.get_value(itr, 0)
610 def _null_touch_selector_entry(parent, title, items, defaultItem):
611 parentSize = parent.get_size()
613 model = gtk.ListStore(gobject.TYPE_STRING)
615 for i, item in enumerate(items):
616 model.append((item, ))
617 if item == defaultItem:
620 cell = gtk.CellRendererText()
621 set_cell_thumb_selectable(cell)
622 column = gtk.TreeViewColumn(title)
623 column.pack_start(cell, expand=True)
624 column.add_attribute(cell, "text", 0)
626 treeView = gtk.TreeView()
627 treeView.set_model(model)
628 treeView.append_column(column)
629 selection = treeView.get_selection()
630 selection.set_mode(gtk.SELECTION_SINGLE)
632 scrolledWin = gtk.ScrolledWindow()
633 scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
634 scrolledWin.add(treeView)
636 customEntry = gtk.Entry()
639 layout.pack_start(customEntry, expand=False)
640 layout.pack_start(scrolledWin)
645 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
646 (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
648 dialog.set_default_response(gtk.RESPONSE_CANCEL)
649 dialog.get_child().add(layout)
650 dialog.resize(parentSize[0], max(parentSize[1]-100, 100))
652 scrolledWin = hildonize_scrollwindow(scrolledWin)
656 selection.select_path((defaultIndex, ))
657 result[0] = defaultItem
659 customEntry.set_text(defaultItem)
661 customEntry.connect("activate", _on_null_touch_selector_entry_entry_activated, dialog, result)
662 customEntry.connect("changed", _on_null_touch_selector_entry_entry_changed, result, selection, defaultIndex)
663 treeView.connect("row-activated", _on_null_touch_selector_entry_tree_activated, dialog, result)
667 response = dialog.run()
669 if response == gtk.RESPONSE_OK:
670 _, itr = selection.get_selected()
672 return model.get_value(itr, 0)
674 enteredText = customEntry.get_text().strip()
677 elif result[0] is not None:
680 raise RuntimeError("No selection made")
681 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
682 raise RuntimeError("User cancelled request")
684 raise RuntimeError("Unrecognized response %r", response)
692 hildon.TouchSelectorEntry
693 touch_selector_entry = _hildon_touch_selector_entry
694 except AttributeError:
695 touch_selector_entry = _null_touch_selector_entry
698 if __name__ == "__main__":
699 app = get_app_class()()
701 label = gtk.Label("Hello World from a Label!")
705 win = hildonize_window(app, win)
707 print touch_selector(win, "Test", ["A", "B", "C", "D"], 2)
709 print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "C")
710 print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "Blah")
715 (name, value) for (name, value) in locals().iteritems()
716 if not name.startswith("_")
718 pprint.pprint(goodLocals)
721 show_information_banner(win, "Hello World")
725 banner = show_busy_banner_start(win, "Hello World")
727 show_busy_banner_end(banner)