5 @bug not all of a message is shown
6 @bug Buttons are too small
15 class _NullHildonModule(object):
20 import hildon as _hildon
21 hildon = _hildon # Dumb but gets around pyflakiness
22 except (ImportError, OSError):
23 hildon = _NullHildonModule
26 IS_HILDON_SUPPORTED = hildon is not _NullHildonModule
29 class _NullHildonProgram(object):
31 def add_window(self, window):
35 def _hildon_get_app_class():
39 def _null_get_app_class():
40 return _NullHildonProgram
45 get_app_class = _hildon_get_app_class
46 except AttributeError:
47 get_app_class = _null_get_app_class
50 def _hildon_set_application_title(window, title):
54 def _null_set_application_title(window, title):
55 window.set_title(title)
58 if IS_HILDON_SUPPORTED:
59 set_application_title = _hildon_set_application_title
61 set_application_title = _null_set_application_title
64 def _fremantle_hildonize_window(app, window):
66 newWindow = hildon.StackableWindow()
67 oldWindow.get_child().reparent(newWindow)
68 app.add_window(newWindow)
72 def _hildon_hildonize_window(app, window):
74 newWindow = hildon.Window()
75 oldWindow.get_child().reparent(newWindow)
76 app.add_window(newWindow)
80 def _null_hildonize_window(app, window):
85 hildon.StackableWindow
86 hildonize_window = _fremantle_hildonize_window
87 except AttributeError:
90 hildonize_window = _hildon_hildonize_window
91 except AttributeError:
92 hildonize_window = _null_hildonize_window
95 def _fremantle_hildonize_menu(window, gtkMenu, buttons):
96 appMenu = hildon.AppMenu()
97 for button in buttons:
98 appMenu.append(button)
99 window.set_app_menu(appMenu)
100 gtkMenu.get_parent().remove(gtkMenu)
104 def _hildon_hildonize_menu(window, gtkMenu, ignoredButtons):
105 hildonMenu = gtk.Menu()
106 for child in gtkMenu.get_children():
107 child.reparent(hildonMenu)
108 window.set_menu(hildonMenu)
113 def _null_hildonize_menu(window, gtkMenu, ignoredButtons):
119 GTK_MENU_USED = False
120 IS_FREMANTLE_SUPPORTED = True
121 hildonize_menu = _fremantle_hildonize_menu
122 except AttributeError:
124 IS_FREMANTLE_SUPPORTED = False
125 if IS_HILDON_SUPPORTED:
126 hildonize_menu = _hildon_hildonize_menu
128 hildonize_menu = _null_hildonize_menu
131 def _hildon_set_button_auto_selectable(button):
132 button.set_theme_size(hildon.HILDON_SIZE_AUTO_HEIGHT)
135 def _null_set_button_auto_selectable(button):
140 hildon.HILDON_SIZE_AUTO_HEIGHT
141 gtk.Button.set_theme_size
142 set_button_auto_selectable = _hildon_set_button_auto_selectable
143 except AttributeError:
144 set_button_auto_selectable = _null_set_button_auto_selectable
147 def _hildon_set_button_finger_selectable(button):
148 button.set_theme_size(hildon.HILDON_SIZE_FINGER_HEIGHT)
151 def _null_set_button_finger_selectable(button):
156 hildon.HILDON_SIZE_FINGER_HEIGHT
157 gtk.Button.set_theme_size
158 set_button_finger_selectable = _hildon_set_button_finger_selectable
159 except AttributeError:
160 set_button_finger_selectable = _null_set_button_finger_selectable
163 def _hildon_set_button_thumb_selectable(button):
164 button.set_theme_size(hildon.HILDON_SIZE_THUMB_HEIGHT)
167 def _null_set_button_thumb_selectable(button):
172 hildon.HILDON_SIZE_THUMB_HEIGHT
173 gtk.Button.set_theme_size
174 set_button_thumb_selectable = _hildon_set_button_thumb_selectable
175 except AttributeError:
176 set_button_thumb_selectable = _null_set_button_thumb_selectable
179 def _hildon_set_cell_thumb_selectable(renderer):
180 renderer.set_property("scale", 1.5)
183 def _null_set_cell_thumb_selectable(renderer):
187 if IS_HILDON_SUPPORTED:
188 set_cell_thumb_selectable = _hildon_set_cell_thumb_selectable
190 set_cell_thumb_selectable = _null_set_cell_thumb_selectable
193 def _hildon_set_pix_cell_thumb_selectable(renderer):
194 renderer.set_property("stock-size", 48)
197 def _null_set_pix_cell_thumb_selectable(renderer):
201 if IS_HILDON_SUPPORTED:
202 set_pix_cell_thumb_selectable = _hildon_set_pix_cell_thumb_selectable
204 set_pix_cell_thumb_selectable = _null_set_pix_cell_thumb_selectable
207 def _fremantle_show_information_banner(parent, message):
208 hildon.hildon_banner_show_information(parent, "", message)
211 def _hildon_show_information_banner(parent, message):
212 hildon.hildon_banner_show_information(parent, None, message)
215 def _null_show_information_banner(parent, message):
219 if IS_FREMANTLE_SUPPORTED:
220 show_information_banner = _fremantle_show_information_banner
223 hildon.hildon_banner_show_information
224 show_information_banner = _hildon_show_information_banner
225 except AttributeError:
226 show_information_banner = _null_show_information_banner
229 def _fremantle_show_busy_banner_start(parent, message):
230 hildon.hildon_gtk_window_set_progress_indicator(parent, True)
234 def _fremantle_show_busy_banner_end(banner):
235 hildon.hildon_gtk_window_set_progress_indicator(banner, False)
238 def _hildon_show_busy_banner_start(parent, message):
239 return hildon.hildon_banner_show_animation(parent, None, message)
242 def _hildon_show_busy_banner_end(banner):
246 def _null_show_busy_banner_start(parent, message):
250 def _null_show_busy_banner_end(banner):
251 assert banner is None
255 hildon.hildon_gtk_window_set_progress_indicator
256 show_busy_banner_start = _fremantle_show_busy_banner_start
257 show_busy_banner_end = _fremantle_show_busy_banner_end
258 except AttributeError:
260 hildon.hildon_banner_show_animation
261 show_busy_banner_start = _hildon_show_busy_banner_start
262 show_busy_banner_end = _hildon_show_busy_banner_end
263 except AttributeError:
264 show_busy_banner_start = _null_show_busy_banner_start
265 show_busy_banner_end = _null_show_busy_banner_end
268 def _hildon_hildonize_text_entry(textEntry):
269 textEntry.set_property('hildon-input-mode', 7)
272 def _null_hildonize_text_entry(textEntry):
276 if IS_HILDON_SUPPORTED:
277 hildonize_text_entry = _hildon_hildonize_text_entry
279 hildonize_text_entry = _null_hildonize_text_entry
282 def _hildon_mark_window_rotatable(window):
283 # gtk documentation is unclear whether this does a "=" or a "|="
284 window.set_flags(hildon.HILDON_PORTRAIT_MODE_SUPPORT)
287 def _null_mark_window_rotatable(window):
292 hildon.HILDON_PORTRAIT_MODE_SUPPORT
293 mark_window_rotatable = _hildon_mark_window_rotatable
294 except AttributeError:
295 mark_window_rotatable = _null_mark_window_rotatable
298 def _hildon_window_to_portrait(window):
299 # gtk documentation is unclear whether this does a "=" or a "|="
300 window.set_flags(hildon.HILDON_PORTRAIT_MODE_SUPPORT)
303 def _hildon_window_to_landscape(window):
304 # gtk documentation is unclear whether this does a "=" or a "&= ~"
305 window.unset_flags(hildon.HILDON_PORTRAIT_MODE_REQUEST)
308 def _null_window_to_portrait(window):
312 def _null_window_to_landscape(window):
317 hildon.HILDON_PORTRAIT_MODE_SUPPORT
318 hildon.HILDON_PORTRAIT_MODE_REQUEST
320 window_to_portrait = _hildon_window_to_portrait
321 window_to_landscape = _hildon_window_to_landscape
322 except AttributeError:
323 window_to_portrait = _null_window_to_portrait
324 window_to_landscape = _null_window_to_landscape
327 def get_device_orientation():
328 bus = dbus.SystemBus()
330 rawMceRequest = bus.get_object("com.nokia.mce", "/com/nokia/mce/request")
331 mceRequest = dbus.Interface(rawMceRequest, dbus_interface="com.nokia.mce.request")
332 orientation, standState, faceState, xAxis, yAxis, zAxis = mceRequest.get_device_orientation()
333 except dbus.exception.DBusException:
334 # catching for documentation purposes that when a system doesn't
335 # support this, this is what to expect
338 if orientation == "":
339 return gtk.ORIENTATION_HORIZONTAL
340 elif orientation == "":
341 return gtk.ORIENTATION_VERTICAL
343 raise RuntimeError("Unknown orientation: %s" % orientation)
346 def _hildon_hildonize_password_entry(textEntry):
347 textEntry.set_property('hildon-input-mode', 7 | (1 << 29))
350 def _null_hildonize_password_entry(textEntry):
354 if IS_HILDON_SUPPORTED:
355 hildonize_password_entry = _hildon_hildonize_password_entry
357 hildonize_password_entry = _null_hildonize_password_entry
360 def _hildon_hildonize_combo_entry(comboEntry):
361 comboEntry.set_property('hildon-input-mode', 1 << 4)
364 def _null_hildonize_combo_entry(textEntry):
368 if IS_HILDON_SUPPORTED:
369 hildonize_combo_entry = _hildon_hildonize_combo_entry
371 hildonize_combo_entry = _null_hildonize_combo_entry
374 def _fremantle_hildonize_scrollwindow(scrolledWindow):
375 pannableWindow = hildon.PannableArea()
377 child = scrolledWindow.get_child()
378 scrolledWindow.remove(child)
379 pannableWindow.add(child)
381 parent = scrolledWindow.get_parent()
382 if parent is not None:
383 parent.remove(scrolledWindow)
384 parent.add(pannableWindow)
386 return pannableWindow
389 def _hildon_hildonize_scrollwindow(scrolledWindow):
390 hildon.hildon_helper_set_thumb_scrollbar(scrolledWindow, True)
391 return scrolledWindow
394 def _null_hildonize_scrollwindow(scrolledWindow):
395 return scrolledWindow
400 hildonize_scrollwindow = _fremantle_hildonize_scrollwindow
401 hildonize_scrollwindow_with_viewport = _hildon_hildonize_scrollwindow
402 except AttributeError:
404 hildon.hildon_helper_set_thumb_scrollbar
405 hildonize_scrollwindow = _hildon_hildonize_scrollwindow
406 hildonize_scrollwindow_with_viewport = _hildon_hildonize_scrollwindow
407 except AttributeError:
408 hildonize_scrollwindow = _null_hildonize_scrollwindow
409 hildonize_scrollwindow_with_viewport = _null_hildonize_scrollwindow
412 def _hildon_request_number(parent, title, range, default):
413 spinner = hildon.NumberEditor(*range)
414 spinner.set_value(default)
419 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
420 (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
422 dialog.set_default_response(gtk.RESPONSE_CANCEL)
423 dialog.get_child().add(spinner)
427 response = dialog.run()
429 if response == gtk.RESPONSE_OK:
430 return spinner.get_value()
431 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
432 raise RuntimeError("User cancelled request")
434 raise RuntimeError("Unrecognized response %r", response)
440 def _null_request_number(parent, title, range, default):
441 adjustment = gtk.Adjustment(default, range[0], range[1], 1, 5, 0)
442 spinner = gtk.SpinButton(adjustment, 0, 0)
443 spinner.set_wrap(False)
448 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
449 (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
451 dialog.set_default_response(gtk.RESPONSE_CANCEL)
452 dialog.get_child().add(spinner)
456 response = dialog.run()
458 if response == gtk.RESPONSE_OK:
459 return spinner.get_value_as_int()
460 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
461 raise RuntimeError("User cancelled request")
463 raise RuntimeError("Unrecognized response %r", response)
470 hildon.NumberEditor # TODO deprecated in fremantle
471 request_number = _hildon_request_number
472 except AttributeError:
473 request_number = _null_request_number
476 def _hildon_touch_selector(parent, title, items, defaultIndex):
477 model = gtk.ListStore(gobject.TYPE_STRING)
479 model.append((item, ))
481 selector = hildon.TouchSelector()
482 selector.append_text_column(model, True)
483 selector.set_column_selection_mode(hildon.TOUCH_SELECTOR_SELECTION_MODE_SINGLE)
484 selector.set_active(0, defaultIndex)
486 dialog = hildon.PickerDialog(parent)
487 dialog.set_selector(selector)
491 response = dialog.run()
493 if response == gtk.RESPONSE_OK:
494 return selector.get_active(0)
495 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
496 raise RuntimeError("User cancelled request")
498 raise RuntimeError("Unrecognized response %r", response)
504 def _on_null_touch_selector_activated(treeView, path, column, dialog, pathData):
505 dialog.response(gtk.RESPONSE_OK)
509 def _null_touch_selector(parent, title, items, defaultIndex = -1):
510 parentSize = parent.get_size()
512 model = gtk.ListStore(gobject.TYPE_STRING)
514 model.append((item, ))
516 cell = gtk.CellRendererText()
517 set_cell_thumb_selectable(cell)
518 column = gtk.TreeViewColumn(title)
519 column.pack_start(cell, expand=True)
520 column.add_attribute(cell, "text", 0)
522 treeView = gtk.TreeView()
523 treeView.set_model(model)
524 treeView.append_column(column)
525 selection = treeView.get_selection()
526 selection.set_mode(gtk.SELECTION_SINGLE)
528 selection.select_path((defaultIndex, ))
530 scrolledWin = gtk.ScrolledWindow()
531 scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
532 scrolledWin.add(treeView)
537 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
538 (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
540 dialog.set_default_response(gtk.RESPONSE_CANCEL)
541 dialog.get_child().add(scrolledWin)
542 dialog.resize(parentSize[0], max(parentSize[1]-100, 100))
544 scrolledWin = hildonize_scrollwindow(scrolledWin)
546 treeView.connect("row-activated", _on_null_touch_selector_activated, dialog, pathData)
550 response = dialog.run()
552 if response == gtk.RESPONSE_OK:
553 if pathData[0] is None:
554 raise RuntimeError("No selection made")
555 return pathData[0][0]
556 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
557 raise RuntimeError("User cancelled request")
559 raise RuntimeError("Unrecognized response %r", response)
568 touch_selector = _hildon_touch_selector
569 except AttributeError:
570 touch_selector = _null_touch_selector
573 def _hildon_touch_selector_entry(parent, title, items, defaultItem):
574 # Got a segfault when using append_text_column with TouchSelectorEntry, so using this way
576 selector = hildon.TouchSelectorEntry(text=True)
578 selector = hildon.hildon_touch_selector_entry_new_text()
580 for i, item in enumerate(items):
581 selector.append_text(item)
582 if item == defaultItem:
585 dialog = hildon.PickerDialog(parent)
586 dialog.set_selector(selector)
589 selector.set_active(0, defaultIndex)
591 selector.get_entry().set_text(defaultItem)
595 response = dialog.run()
599 if response == gtk.RESPONSE_OK:
600 return selector.get_entry().get_text()
601 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
602 raise RuntimeError("User cancelled request")
604 raise RuntimeError("Unrecognized response %r", response)
607 def _on_null_touch_selector_entry_entry_changed(entry, result, selection, defaultIndex):
608 custom = entry.get_text().strip()
611 selection.unselect_all()
614 selection.select_path((defaultIndex, ))
617 def _on_null_touch_selector_entry_entry_activated(customEntry, dialog, result):
618 dialog.response(gtk.RESPONSE_OK)
619 result[0] = customEntry.get_text()
622 def _on_null_touch_selector_entry_tree_activated(treeView, path, column, dialog, result):
623 dialog.response(gtk.RESPONSE_OK)
624 model = treeView.get_model()
625 itr = model.get_iter(path)
627 result[0] = model.get_value(itr, 0)
630 def _null_touch_selector_entry(parent, title, items, defaultItem):
631 parentSize = parent.get_size()
633 model = gtk.ListStore(gobject.TYPE_STRING)
635 for i, item in enumerate(items):
636 model.append((item, ))
637 if item == defaultItem:
640 cell = gtk.CellRendererText()
641 set_cell_thumb_selectable(cell)
642 column = gtk.TreeViewColumn(title)
643 column.pack_start(cell, expand=True)
644 column.add_attribute(cell, "text", 0)
646 treeView = gtk.TreeView()
647 treeView.set_model(model)
648 treeView.append_column(column)
649 selection = treeView.get_selection()
650 selection.set_mode(gtk.SELECTION_SINGLE)
652 scrolledWin = gtk.ScrolledWindow()
653 scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
654 scrolledWin.add(treeView)
656 customEntry = gtk.Entry()
659 layout.pack_start(customEntry, expand=False)
660 layout.pack_start(scrolledWin)
665 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
666 (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
668 dialog.set_default_response(gtk.RESPONSE_CANCEL)
669 dialog.get_child().add(layout)
670 dialog.resize(parentSize[0], max(parentSize[1]-100, 100))
672 scrolledWin = hildonize_scrollwindow(scrolledWin)
676 selection.select_path((defaultIndex, ))
677 result[0] = defaultItem
679 customEntry.set_text(defaultItem)
681 customEntry.connect("activate", _on_null_touch_selector_entry_entry_activated, dialog, result)
682 customEntry.connect("changed", _on_null_touch_selector_entry_entry_changed, result, selection, defaultIndex)
683 treeView.connect("row-activated", _on_null_touch_selector_entry_tree_activated, dialog, result)
687 response = dialog.run()
689 if response == gtk.RESPONSE_OK:
690 _, itr = selection.get_selected()
692 return model.get_value(itr, 0)
694 enteredText = customEntry.get_text().strip()
697 elif result[0] is not None:
700 raise RuntimeError("No selection made")
701 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
702 raise RuntimeError("User cancelled request")
704 raise RuntimeError("Unrecognized response %r", response)
712 hildon.TouchSelectorEntry
713 touch_selector_entry = _hildon_touch_selector_entry
714 except AttributeError:
715 touch_selector_entry = _null_touch_selector_entry
718 if __name__ == "__main__":
719 app = get_app_class()()
721 label = gtk.Label("Hello World from a Label!")
725 win = hildonize_window(app, win)
727 print touch_selector(win, "Test", ["A", "B", "C", "D"], 2)
729 print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "C")
730 print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "Blah")
735 (name, value) for (name, value) in locals().iteritems()
736 if not name.startswith("_")
738 pprint.pprint(goodLocals)
741 show_information_banner(win, "Hello World")
745 banner = show_busy_banner_start(win, "Hello World")
747 show_busy_banner_end(banner)