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)
73 def _hildon_hildonize_window(app, window):
75 newWindow = hildon.Window()
76 oldWindow.get_child().reparent(newWindow)
77 app.add_window(newWindow)
82 def _null_hildonize_window(app, window):
87 hildon.StackableWindow
88 hildonize_window = _fremantle_hildonize_window
89 except AttributeError:
92 hildonize_window = _hildon_hildonize_window
93 except AttributeError:
94 hildonize_window = _null_hildonize_window
97 def _fremantle_hildonize_menu(window, gtkMenu, buttons):
98 appMenu = hildon.AppMenu()
99 for button in buttons:
100 appMenu.append(button)
101 window.set_app_menu(appMenu)
102 gtkMenu.get_parent().remove(gtkMenu)
106 def _hildon_hildonize_menu(window, gtkMenu, ignoredButtons):
107 hildonMenu = gtk.Menu()
108 for child in gtkMenu.get_children():
109 child.reparent(hildonMenu)
110 window.set_menu(hildonMenu)
115 def _null_hildonize_menu(window, gtkMenu, ignoredButtons):
121 GTK_MENU_USED = False
122 IS_FREMANTLE_SUPPORTED = True
123 hildonize_menu = _fremantle_hildonize_menu
124 except AttributeError:
126 IS_FREMANTLE_SUPPORTED = False
127 if IS_HILDON_SUPPORTED:
128 hildonize_menu = _hildon_hildonize_menu
130 hildonize_menu = _null_hildonize_menu
133 def _hildon_set_button_auto_selectable(button):
134 button.set_theme_size(hildon.HILDON_SIZE_AUTO_HEIGHT)
137 def _null_set_button_auto_selectable(button):
142 hildon.HILDON_SIZE_AUTO_HEIGHT
143 gtk.Button.set_theme_size
144 set_button_auto_selectable = _hildon_set_button_auto_selectable
145 except AttributeError:
146 set_button_auto_selectable = _null_set_button_auto_selectable
149 def _hildon_set_button_finger_selectable(button):
150 button.set_theme_size(hildon.HILDON_SIZE_FINGER_HEIGHT)
153 def _null_set_button_finger_selectable(button):
158 hildon.HILDON_SIZE_FINGER_HEIGHT
159 gtk.Button.set_theme_size
160 set_button_finger_selectable = _hildon_set_button_finger_selectable
161 except AttributeError:
162 set_button_finger_selectable = _null_set_button_finger_selectable
165 def _hildon_set_button_thumb_selectable(button):
166 button.set_theme_size(hildon.HILDON_SIZE_THUMB_HEIGHT)
169 def _null_set_button_thumb_selectable(button):
174 hildon.HILDON_SIZE_THUMB_HEIGHT
175 gtk.Button.set_theme_size
176 set_button_thumb_selectable = _hildon_set_button_thumb_selectable
177 except AttributeError:
178 set_button_thumb_selectable = _null_set_button_thumb_selectable
181 def _hildon_set_cell_thumb_selectable(renderer):
182 renderer.set_property("scale", 1.5)
185 def _null_set_cell_thumb_selectable(renderer):
189 if IS_HILDON_SUPPORTED:
190 set_cell_thumb_selectable = _hildon_set_cell_thumb_selectable
192 set_cell_thumb_selectable = _null_set_cell_thumb_selectable
195 def _fremantle_show_information_banner(parent, message):
196 hildon.hildon_banner_show_information(parent, "", message)
199 def _hildon_show_information_banner(parent, message):
200 hildon.hildon_banner_show_information(parent, None, message)
203 def _null_show_information_banner(parent, message):
207 if IS_FREMANTLE_SUPPORTED:
208 show_information_banner = _fremantle_show_information_banner
211 hildon.hildon_banner_show_information
212 show_information_banner = _hildon_show_information_banner
213 except AttributeError:
214 show_information_banner = _null_show_information_banner
217 def _fremantle_show_busy_banner_start(parent, message):
218 hildon.hildon_gtk_window_set_progress_indicator(parent, True)
222 def _fremantle_show_busy_banner_end(banner):
223 hildon.hildon_gtk_window_set_progress_indicator(banner, False)
226 def _hildon_show_busy_banner_start(parent, message):
227 return hildon.hildon_banner_show_animation(parent, None, message)
230 def _hildon_show_busy_banner_end(banner):
234 def _null_show_busy_banner_start(parent, message):
238 def _null_show_busy_banner_end(banner):
239 assert banner is None
243 hildon.hildon_gtk_window_set_progress_indicator
244 show_busy_banner_start = _fremantle_show_busy_banner_start
245 show_busy_banner_end = _fremantle_show_busy_banner_end
246 except AttributeError:
248 hildon.hildon_banner_show_animation
249 show_busy_banner_start = _hildon_show_busy_banner_start
250 show_busy_banner_end = _hildon_show_busy_banner_end
251 except AttributeError:
252 show_busy_banner_start = _null_show_busy_banner_start
253 show_busy_banner_end = _null_show_busy_banner_end
256 def _hildon_hildonize_text_entry(textEntry):
257 textEntry.set_property('hildon-input-mode', 7)
260 def _null_hildonize_text_entry(textEntry):
264 if IS_HILDON_SUPPORTED:
265 hildonize_text_entry = _hildon_hildonize_text_entry
267 hildonize_text_entry = _null_hildonize_text_entry
270 def _hildon_mark_window_rotatable(window):
271 # gtk documentation is unclear whether this does a "=" or a "|="
272 window.set_flags(hildon.HILDON_PORTRAIT_MODE_SUPPORT)
275 def _null_mark_window_rotatable(window):
280 hildon.HILDON_PORTRAIT_MODE_SUPPORT
281 mark_window_rotatable = _hildon_mark_window_rotatable
282 except AttributeError:
283 mark_window_rotatable = _null_mark_window_rotatable
286 def _hildon_window_to_portrait(window):
287 # gtk documentation is unclear whether this does a "=" or a "|="
288 window.set_flags(hildon.HILDON_PORTRAIT_MODE_SUPPORT)
291 def _hildon_window_to_landscape(window):
292 # gtk documentation is unclear whether this does a "=" or a "&= ~"
293 window.unset_flags(hildon.HILDON_PORTRAIT_MODE_REQUEST)
296 def _null_window_to_portrait(window):
300 def _null_window_to_landscape(window):
305 hildon.HILDON_PORTRAIT_MODE_SUPPORT
306 hildon.HILDON_PORTRAIT_MODE_REQUEST
308 window_to_portrait = _hildon_window_to_portrait
309 window_to_landscape = _hildon_window_to_landscape
310 except AttributeError:
311 window_to_portrait = _null_window_to_portrait
312 window_to_landscape = _null_window_to_landscape
315 def get_device_orientation():
316 bus = dbus.SystemBus()
318 rawMceRequest = bus.get_object("com.nokia.mce", "/com/nokia/mce/request")
319 mceRequest = dbus.Interface(rawMceRequest, dbus_interface="com.nokia.mce.request")
320 orientation, standState, faceState, xAxis, yAxis, zAxis = mceRequest.get_device_orientation()
321 except dbus.exception.DBusException:
322 # catching for documentation purposes that when a system doesn't
323 # support this, this is what to expect
326 if orientation == "":
327 return gtk.ORIENTATION_HORIZONTAL
328 elif orientation == "":
329 return gtk.ORIENTATION_VERTICAL
331 raise RuntimeError("Unknown orientation: %s" % orientation)
334 def _hildon_hildonize_password_entry(textEntry):
335 textEntry.set_property('hildon-input-mode', 7 | (1 << 29))
338 def _null_hildonize_password_entry(textEntry):
342 if IS_HILDON_SUPPORTED:
343 hildonize_password_entry = _hildon_hildonize_password_entry
345 hildonize_password_entry = _null_hildonize_password_entry
348 def _hildon_hildonize_combo_entry(comboEntry):
349 comboEntry.set_property('hildon-input-mode', 1 << 4)
352 def _null_hildonize_combo_entry(textEntry):
356 if IS_HILDON_SUPPORTED:
357 hildonize_combo_entry = _hildon_hildonize_combo_entry
359 hildonize_combo_entry = _null_hildonize_combo_entry
362 def _fremantle_hildonize_scrollwindow(scrolledWindow):
363 pannableWindow = hildon.PannableArea()
365 child = scrolledWindow.get_child()
366 scrolledWindow.remove(child)
367 pannableWindow.add(child)
369 parent = scrolledWindow.get_parent()
370 parent.remove(scrolledWindow)
371 parent.add(pannableWindow)
373 return pannableWindow
376 def _hildon_hildonize_scrollwindow(scrolledWindow):
377 hildon.hildon_helper_set_thumb_scrollbar(scrolledWindow, True)
378 return scrolledWindow
381 def _null_hildonize_scrollwindow(scrolledWindow):
382 return scrolledWindow
387 hildonize_scrollwindow = _fremantle_hildonize_scrollwindow
388 hildonize_scrollwindow_with_viewport = _hildon_hildonize_scrollwindow
389 except AttributeError:
391 hildon.hildon_helper_set_thumb_scrollbar
392 hildonize_scrollwindow = _hildon_hildonize_scrollwindow
393 hildonize_scrollwindow_with_viewport = _hildon_hildonize_scrollwindow
394 except AttributeError:
395 hildonize_scrollwindow = _null_hildonize_scrollwindow
396 hildonize_scrollwindow_with_viewport = _null_hildonize_scrollwindow
399 def _hildon_request_number(parent, title, range, default):
400 spinner = hildon.NumberEditor(*range)
401 spinner.set_value(default)
406 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
407 (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
409 dialog.set_default_response(gtk.RESPONSE_CANCEL)
410 dialog.get_child().add(spinner)
414 response = dialog.run()
416 if response == gtk.RESPONSE_OK:
417 return spinner.get_value()
418 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
419 raise RuntimeError("User cancelled request")
421 raise RuntimeError("Unrecognized response %r", response)
427 def _null_request_number(parent, title, range, default):
428 adjustment = gtk.Adjustment(default, range[0], range[1], 1, 5, 0)
429 spinner = gtk.SpinButton(adjustment, 0, 0)
430 spinner.set_wrap(False)
435 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
436 (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
438 dialog.set_default_response(gtk.RESPONSE_CANCEL)
439 dialog.get_child().add(spinner)
443 response = dialog.run()
445 if response == gtk.RESPONSE_OK:
446 return spinner.get_value_as_int()
447 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
448 raise RuntimeError("User cancelled request")
450 raise RuntimeError("Unrecognized response %r", response)
457 hildon.NumberEditor # TODO deprecated in fremantle
458 request_number = _hildon_request_number
459 except AttributeError:
460 request_number = _null_request_number
463 def _hildon_touch_selector(parent, title, items, defaultIndex):
464 model = gtk.ListStore(gobject.TYPE_STRING)
466 model.append((item, ))
468 selector = hildon.TouchSelector()
469 selector.append_text_column(model, True)
470 selector.set_column_selection_mode(hildon.TOUCH_SELECTOR_SELECTION_MODE_SINGLE)
471 selector.set_active(0, defaultIndex)
473 dialog = hildon.PickerDialog(parent)
474 dialog.set_selector(selector)
478 response = dialog.run()
480 if response == gtk.RESPONSE_OK:
481 return selector.get_active(0)
482 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
483 raise RuntimeError("User cancelled request")
485 raise RuntimeError("Unrecognized response %r", response)
491 def _on_null_touch_selector_activated(treeView, path, column, dialog, pathData):
492 dialog.response(gtk.RESPONSE_OK)
496 def _null_touch_selector(parent, title, items, defaultIndex = -1):
497 parentSize = parent.get_size()
499 model = gtk.ListStore(gobject.TYPE_STRING)
501 model.append((item, ))
503 cell = gtk.CellRendererText()
504 set_cell_thumb_selectable(cell)
505 column = gtk.TreeViewColumn(title)
506 column.pack_start(cell, expand=True)
507 column.add_attribute(cell, "text", 0)
509 treeView = gtk.TreeView()
510 treeView.set_model(model)
511 treeView.append_column(column)
512 selection = treeView.get_selection()
513 selection.set_mode(gtk.SELECTION_SINGLE)
515 selection.select_path((defaultIndex, ))
517 scrolledWin = gtk.ScrolledWindow()
518 scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
519 scrolledWin.add(treeView)
524 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
525 (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
527 dialog.set_default_response(gtk.RESPONSE_CANCEL)
528 dialog.get_child().add(scrolledWin)
529 dialog.resize(parentSize[0], max(parentSize[1]-100, 100))
531 scrolledWin = hildonize_scrollwindow(scrolledWin)
533 treeView.connect("row-activated", _on_null_touch_selector_activated, dialog, pathData)
537 response = dialog.run()
539 if response == gtk.RESPONSE_OK:
540 if pathData[0] is None:
541 raise RuntimeError("No selection made")
542 return pathData[0][0]
543 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
544 raise RuntimeError("User cancelled request")
546 raise RuntimeError("Unrecognized response %r", response)
555 touch_selector = _hildon_touch_selector
556 except AttributeError:
557 touch_selector = _null_touch_selector
560 def _hildon_touch_selector_entry(parent, title, items, defaultItem):
561 # Got a segfault when using append_text_column with TouchSelectorEntry, so using this way
563 selector = hildon.TouchSelectorEntry(text=True)
565 selector = hildon.hildon_touch_selector_entry_new_text()
567 for i, item in enumerate(items):
568 selector.append_text(item)
569 if item == defaultItem:
572 dialog = hildon.PickerDialog(parent)
573 dialog.set_selector(selector)
576 selector.set_active(0, defaultIndex)
578 selector.get_entry().set_text(defaultItem)
582 response = dialog.run()
586 if response == gtk.RESPONSE_OK:
587 return selector.get_entry().get_text()
588 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
589 raise RuntimeError("User cancelled request")
591 raise RuntimeError("Unrecognized response %r", response)
594 def _on_null_touch_selector_entry_entry_changed(entry, result, selection, defaultIndex):
595 custom = entry.get_text().strip()
598 selection.unselect_all()
601 selection.select_path((defaultIndex, ))
604 def _on_null_touch_selector_entry_entry_activated(customEntry, dialog, result):
605 dialog.response(gtk.RESPONSE_OK)
606 result[0] = customEntry.get_text()
609 def _on_null_touch_selector_entry_tree_activated(treeView, path, column, dialog, result):
610 dialog.response(gtk.RESPONSE_OK)
611 model = treeView.get_model()
612 itr = model.get_iter(path)
614 result[0] = model.get_value(itr, 0)
617 def _null_touch_selector_entry(parent, title, items, defaultItem):
618 parentSize = parent.get_size()
620 model = gtk.ListStore(gobject.TYPE_STRING)
622 for i, item in enumerate(items):
623 model.append((item, ))
624 if item == defaultItem:
627 cell = gtk.CellRendererText()
628 set_cell_thumb_selectable(cell)
629 column = gtk.TreeViewColumn(title)
630 column.pack_start(cell, expand=True)
631 column.add_attribute(cell, "text", 0)
633 treeView = gtk.TreeView()
634 treeView.set_model(model)
635 treeView.append_column(column)
636 selection = treeView.get_selection()
637 selection.set_mode(gtk.SELECTION_SINGLE)
639 scrolledWin = gtk.ScrolledWindow()
640 scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
641 scrolledWin.add(treeView)
643 customEntry = gtk.Entry()
646 layout.pack_start(customEntry, expand=False)
647 layout.pack_start(scrolledWin)
652 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
653 (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
655 dialog.set_default_response(gtk.RESPONSE_CANCEL)
656 dialog.get_child().add(layout)
657 dialog.resize(parentSize[0], max(parentSize[1]-100, 100))
659 scrolledWin = hildonize_scrollwindow(scrolledWin)
663 selection.select_path((defaultIndex, ))
664 result[0] = defaultItem
666 customEntry.set_text(defaultItem)
668 customEntry.connect("activate", _on_null_touch_selector_entry_entry_activated, dialog, result)
669 customEntry.connect("changed", _on_null_touch_selector_entry_entry_changed, result, selection, defaultIndex)
670 treeView.connect("row-activated", _on_null_touch_selector_entry_tree_activated, dialog, result)
674 response = dialog.run()
676 if response == gtk.RESPONSE_OK:
677 _, itr = selection.get_selected()
679 return model.get_value(itr, 0)
681 enteredText = customEntry.get_text().strip()
684 elif result[0] is not None:
687 raise RuntimeError("No selection made")
688 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
689 raise RuntimeError("User cancelled request")
691 raise RuntimeError("Unrecognized response %r", response)
699 hildon.TouchSelectorEntry
700 touch_selector_entry = _hildon_touch_selector_entry
701 except AttributeError:
702 touch_selector_entry = _null_touch_selector_entry
705 if __name__ == "__main__":
706 app = get_app_class()()
708 label = gtk.Label("Hello World from a Label!")
712 win = hildonize_window(app, win)
714 print touch_selector(win, "Test", ["A", "B", "C", "D"], 2)
716 print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "C")
717 print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "Blah")
722 (name, value) for (name, value) in locals().iteritems()
723 if not name.startswith("_")
725 pprint.pprint(goodLocals)
728 show_information_banner(win, "Hello World")
732 banner = show_busy_banner_start(win, "Hello World")
734 show_busy_banner_end(banner)