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):
96 appMenu = hildon.AppMenu()
97 window.set_app_menu(appMenu)
98 gtkMenu.get_parent().remove(gtkMenu)
102 def _hildon_hildonize_menu(window, gtkMenu):
103 hildonMenu = gtk.Menu()
104 for child in gtkMenu.get_children():
105 child.reparent(hildonMenu)
106 window.set_menu(hildonMenu)
111 def _null_hildonize_menu(window, gtkMenu):
117 GTK_MENU_USED = False
118 IS_FREMANTLE_SUPPORTED = True
119 hildonize_menu = _fremantle_hildonize_menu
120 except AttributeError:
122 IS_FREMANTLE_SUPPORTED = False
123 if IS_HILDON_SUPPORTED:
124 hildonize_menu = _hildon_hildonize_menu
126 hildonize_menu = _null_hildonize_menu
129 def _hildon_set_button_auto_selectable(button):
130 button.set_theme_size(hildon.HILDON_SIZE_AUTO_HEIGHT)
133 def _null_set_button_auto_selectable(button):
138 hildon.HILDON_SIZE_AUTO_HEIGHT
139 gtk.Button.set_theme_size
140 set_button_auto_selectable = _hildon_set_button_auto_selectable
141 except AttributeError:
142 set_button_auto_selectable = _null_set_button_auto_selectable
145 def _hildon_set_button_finger_selectable(button):
146 button.set_theme_size(hildon.HILDON_SIZE_FINGER_HEIGHT)
149 def _null_set_button_finger_selectable(button):
154 hildon.HILDON_SIZE_FINGER_HEIGHT
155 gtk.Button.set_theme_size
156 set_button_finger_selectable = _hildon_set_button_finger_selectable
157 except AttributeError:
158 set_button_finger_selectable = _null_set_button_finger_selectable
161 def _hildon_set_button_thumb_selectable(button):
162 button.set_theme_size(hildon.HILDON_SIZE_THUMB_HEIGHT)
165 def _null_set_button_thumb_selectable(button):
170 hildon.HILDON_SIZE_THUMB_HEIGHT
171 gtk.Button.set_theme_size
172 set_button_thumb_selectable = _hildon_set_button_thumb_selectable
173 except AttributeError:
174 set_button_thumb_selectable = _null_set_button_thumb_selectable
177 def _hildon_set_cell_thumb_selectable(renderer):
178 renderer.set_property("scale", 1.5)
181 def _null_set_cell_thumb_selectable(renderer):
185 if IS_HILDON_SUPPORTED:
186 set_cell_thumb_selectable = _hildon_set_cell_thumb_selectable
188 set_cell_thumb_selectable = _null_set_cell_thumb_selectable
191 def _hildon_set_pix_cell_thumb_selectable(renderer):
192 renderer.set_property("stock-size", 48)
195 def _null_set_pix_cell_thumb_selectable(renderer):
199 if IS_HILDON_SUPPORTED:
200 set_pix_cell_thumb_selectable = _hildon_set_pix_cell_thumb_selectable
202 set_pix_cell_thumb_selectable = _null_set_pix_cell_thumb_selectable
205 def _fremantle_show_information_banner(parent, message):
206 hildon.hildon_banner_show_information(parent, "", message)
209 def _hildon_show_information_banner(parent, message):
210 hildon.hildon_banner_show_information(parent, None, message)
213 def _null_show_information_banner(parent, message):
217 if IS_FREMANTLE_SUPPORTED:
218 show_information_banner = _fremantle_show_information_banner
221 hildon.hildon_banner_show_information
222 show_information_banner = _hildon_show_information_banner
223 except AttributeError:
224 show_information_banner = _null_show_information_banner
227 def _fremantle_show_busy_banner_start(parent, message):
228 hildon.hildon_gtk_window_set_progress_indicator(parent, True)
232 def _fremantle_show_busy_banner_end(banner):
233 hildon.hildon_gtk_window_set_progress_indicator(banner, False)
236 def _hildon_show_busy_banner_start(parent, message):
237 return hildon.hildon_banner_show_animation(parent, None, message)
240 def _hildon_show_busy_banner_end(banner):
244 def _null_show_busy_banner_start(parent, message):
248 def _null_show_busy_banner_end(banner):
249 assert banner is None
253 hildon.hildon_gtk_window_set_progress_indicator
254 show_busy_banner_start = _fremantle_show_busy_banner_start
255 show_busy_banner_end = _fremantle_show_busy_banner_end
256 except AttributeError:
258 hildon.hildon_banner_show_animation
259 show_busy_banner_start = _hildon_show_busy_banner_start
260 show_busy_banner_end = _hildon_show_busy_banner_end
261 except AttributeError:
262 show_busy_banner_start = _null_show_busy_banner_start
263 show_busy_banner_end = _null_show_busy_banner_end
266 def _hildon_hildonize_text_entry(textEntry):
267 textEntry.set_property('hildon-input-mode', 7)
270 def _null_hildonize_text_entry(textEntry):
274 if IS_HILDON_SUPPORTED:
275 hildonize_text_entry = _hildon_hildonize_text_entry
277 hildonize_text_entry = _null_hildonize_text_entry
280 def _hildon_mark_window_rotatable(window):
281 # gtk documentation is unclear whether this does a "=" or a "|="
282 window.set_flags(hildon.HILDON_PORTRAIT_MODE_SUPPORT)
285 def _null_mark_window_rotatable(window):
290 hildon.HILDON_PORTRAIT_MODE_SUPPORT
291 mark_window_rotatable = _hildon_mark_window_rotatable
292 except AttributeError:
293 mark_window_rotatable = _null_mark_window_rotatable
296 def _hildon_window_to_portrait(window):
297 # gtk documentation is unclear whether this does a "=" or a "|="
298 window.set_flags(hildon.HILDON_PORTRAIT_MODE_SUPPORT)
301 def _hildon_window_to_landscape(window):
302 # gtk documentation is unclear whether this does a "=" or a "&= ~"
303 window.unset_flags(hildon.HILDON_PORTRAIT_MODE_REQUEST)
306 def _null_window_to_portrait(window):
310 def _null_window_to_landscape(window):
315 hildon.HILDON_PORTRAIT_MODE_SUPPORT
316 hildon.HILDON_PORTRAIT_MODE_REQUEST
318 window_to_portrait = _hildon_window_to_portrait
319 window_to_landscape = _hildon_window_to_landscape
320 except AttributeError:
321 window_to_portrait = _null_window_to_portrait
322 window_to_landscape = _null_window_to_landscape
325 def get_device_orientation():
326 bus = dbus.SystemBus()
328 rawMceRequest = bus.get_object("com.nokia.mce", "/com/nokia/mce/request")
329 mceRequest = dbus.Interface(rawMceRequest, dbus_interface="com.nokia.mce.request")
330 orientation, standState, faceState, xAxis, yAxis, zAxis = mceRequest.get_device_orientation()
331 except dbus.exception.DBusException:
332 # catching for documentation purposes that when a system doesn't
333 # support this, this is what to expect
336 if orientation == "":
337 return gtk.ORIENTATION_HORIZONTAL
338 elif orientation == "":
339 return gtk.ORIENTATION_VERTICAL
341 raise RuntimeError("Unknown orientation: %s" % orientation)
344 def _hildon_hildonize_password_entry(textEntry):
345 textEntry.set_property('hildon-input-mode', 7 | (1 << 29))
348 def _null_hildonize_password_entry(textEntry):
352 if IS_HILDON_SUPPORTED:
353 hildonize_password_entry = _hildon_hildonize_password_entry
355 hildonize_password_entry = _null_hildonize_password_entry
358 def _hildon_hildonize_combo_entry(comboEntry):
359 comboEntry.set_property('hildon-input-mode', 1 << 4)
362 def _null_hildonize_combo_entry(textEntry):
366 if IS_HILDON_SUPPORTED:
367 hildonize_combo_entry = _hildon_hildonize_combo_entry
369 hildonize_combo_entry = _null_hildonize_combo_entry
372 def _fremantle_hildonize_scrollwindow(scrolledWindow):
373 pannableWindow = hildon.PannableArea()
375 child = scrolledWindow.get_child()
376 scrolledWindow.remove(child)
377 pannableWindow.add(child)
379 parent = scrolledWindow.get_parent()
380 if parent is not None:
381 parent.remove(scrolledWindow)
382 parent.add(pannableWindow)
384 return pannableWindow
387 def _hildon_hildonize_scrollwindow(scrolledWindow):
388 hildon.hildon_helper_set_thumb_scrollbar(scrolledWindow, True)
389 return scrolledWindow
392 def _null_hildonize_scrollwindow(scrolledWindow):
393 return scrolledWindow
398 hildonize_scrollwindow = _fremantle_hildonize_scrollwindow
399 hildonize_scrollwindow_with_viewport = _hildon_hildonize_scrollwindow
400 except AttributeError:
402 hildon.hildon_helper_set_thumb_scrollbar
403 hildonize_scrollwindow = _hildon_hildonize_scrollwindow
404 hildonize_scrollwindow_with_viewport = _hildon_hildonize_scrollwindow
405 except AttributeError:
406 hildonize_scrollwindow = _null_hildonize_scrollwindow
407 hildonize_scrollwindow_with_viewport = _null_hildonize_scrollwindow
410 def _fremantle_pannable_treeview_theme_workaround(treeview):
411 scrollWindow = treeview.get_parent()
412 scrollWindow.remove(treeview)
416 viewport = gtk.Viewport()
418 scrollWindow.add(viewport)
421 def _null_pannable_treeview_theme_workaround(treeview):
425 if IS_FREMANTLE_SUPPORTED:
426 pannable_treeview_theme_workaround = _fremantle_pannable_treeview_theme_workaround
428 pannable_treeview_theme_workaround = _null_pannable_treeview_theme_workaround
431 def _hildon_request_number(parent, title, range, default):
432 spinner = hildon.NumberEditor(*range)
433 spinner.set_value(default)
438 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
439 (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
441 dialog.set_default_response(gtk.RESPONSE_CANCEL)
442 dialog.get_child().add(spinner)
446 response = dialog.run()
448 if response == gtk.RESPONSE_OK:
449 return spinner.get_value()
450 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
451 raise RuntimeError("User cancelled request")
453 raise RuntimeError("Unrecognized response %r", response)
459 def _null_request_number(parent, title, range, default):
460 adjustment = gtk.Adjustment(default, range[0], range[1], 1, 5, 0)
461 spinner = gtk.SpinButton(adjustment, 0, 0)
462 spinner.set_wrap(False)
467 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
468 (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
470 dialog.set_default_response(gtk.RESPONSE_CANCEL)
471 dialog.get_child().add(spinner)
475 response = dialog.run()
477 if response == gtk.RESPONSE_OK:
478 return spinner.get_value_as_int()
479 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
480 raise RuntimeError("User cancelled request")
482 raise RuntimeError("Unrecognized response %r", response)
489 hildon.NumberEditor # TODO deprecated in fremantle
490 request_number = _hildon_request_number
491 except AttributeError:
492 request_number = _null_request_number
495 def _hildon_touch_selector(parent, title, items, defaultIndex):
496 model = gtk.ListStore(gobject.TYPE_STRING)
498 model.append((item, ))
500 selector = hildon.TouchSelector()
501 selector.append_text_column(model, True)
502 selector.set_column_selection_mode(hildon.TOUCH_SELECTOR_SELECTION_MODE_SINGLE)
503 selector.set_active(0, defaultIndex)
505 dialog = hildon.PickerDialog(parent)
506 dialog.set_selector(selector)
510 response = dialog.run()
512 if response == gtk.RESPONSE_OK:
513 return selector.get_active(0)
514 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
515 raise RuntimeError("User cancelled request")
517 raise RuntimeError("Unrecognized response %r", response)
523 def _on_null_touch_selector_activated(treeView, path, column, dialog, pathData):
524 dialog.response(gtk.RESPONSE_OK)
528 def _null_touch_selector(parent, title, items, defaultIndex = -1):
529 parentSize = parent.get_size()
531 model = gtk.ListStore(gobject.TYPE_STRING)
533 model.append((item, ))
535 cell = gtk.CellRendererText()
536 set_cell_thumb_selectable(cell)
537 column = gtk.TreeViewColumn(title)
538 column.pack_start(cell, expand=True)
539 column.add_attribute(cell, "text", 0)
541 treeView = gtk.TreeView()
542 treeView.set_model(model)
543 treeView.append_column(column)
544 selection = treeView.get_selection()
545 selection.set_mode(gtk.SELECTION_SINGLE)
547 selection.select_path((defaultIndex, ))
549 scrolledWin = gtk.ScrolledWindow()
550 scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
551 scrolledWin.add(treeView)
556 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
557 (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
559 dialog.set_default_response(gtk.RESPONSE_CANCEL)
560 dialog.get_child().add(scrolledWin)
561 dialog.resize(parentSize[0], max(parentSize[1]-100, 100))
563 scrolledWin = hildonize_scrollwindow(scrolledWin)
565 treeView.connect("row-activated", _on_null_touch_selector_activated, dialog, pathData)
569 response = dialog.run()
571 if response == gtk.RESPONSE_OK:
572 if pathData[0] is None:
573 raise RuntimeError("No selection made")
574 return pathData[0][0]
575 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
576 raise RuntimeError("User cancelled request")
578 raise RuntimeError("Unrecognized response %r", response)
587 touch_selector = _hildon_touch_selector
588 except AttributeError:
589 touch_selector = _null_touch_selector
592 def _hildon_touch_selector_entry(parent, title, items, defaultItem):
593 # Got a segfault when using append_text_column with TouchSelectorEntry, so using this way
595 selector = hildon.TouchSelectorEntry(text=True)
597 selector = hildon.hildon_touch_selector_entry_new_text()
599 for i, item in enumerate(items):
600 selector.append_text(item)
601 if item == defaultItem:
604 dialog = hildon.PickerDialog(parent)
605 dialog.set_selector(selector)
608 selector.set_active(0, defaultIndex)
610 selector.get_entry().set_text(defaultItem)
614 response = dialog.run()
618 if response == gtk.RESPONSE_OK:
619 return selector.get_entry().get_text()
620 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
621 raise RuntimeError("User cancelled request")
623 raise RuntimeError("Unrecognized response %r", response)
626 def _on_null_touch_selector_entry_entry_changed(entry, result, selection, defaultIndex):
627 custom = entry.get_text().strip()
630 selection.unselect_all()
633 selection.select_path((defaultIndex, ))
636 def _on_null_touch_selector_entry_entry_activated(customEntry, dialog, result):
637 dialog.response(gtk.RESPONSE_OK)
638 result[0] = customEntry.get_text()
641 def _on_null_touch_selector_entry_tree_activated(treeView, path, column, dialog, result):
642 dialog.response(gtk.RESPONSE_OK)
643 model = treeView.get_model()
644 itr = model.get_iter(path)
646 result[0] = model.get_value(itr, 0)
649 def _null_touch_selector_entry(parent, title, items, defaultItem):
650 parentSize = parent.get_size()
652 model = gtk.ListStore(gobject.TYPE_STRING)
654 for i, item in enumerate(items):
655 model.append((item, ))
656 if item == defaultItem:
659 cell = gtk.CellRendererText()
660 set_cell_thumb_selectable(cell)
661 column = gtk.TreeViewColumn(title)
662 column.pack_start(cell, expand=True)
663 column.add_attribute(cell, "text", 0)
665 treeView = gtk.TreeView()
666 treeView.set_model(model)
667 treeView.append_column(column)
668 selection = treeView.get_selection()
669 selection.set_mode(gtk.SELECTION_SINGLE)
671 scrolledWin = gtk.ScrolledWindow()
672 scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
673 scrolledWin.add(treeView)
675 customEntry = gtk.Entry()
678 layout.pack_start(customEntry, expand=False)
679 layout.pack_start(scrolledWin)
684 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
685 (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
687 dialog.set_default_response(gtk.RESPONSE_CANCEL)
688 dialog.get_child().add(layout)
689 dialog.resize(parentSize[0], max(parentSize[1]-100, 100))
691 scrolledWin = hildonize_scrollwindow(scrolledWin)
695 selection.select_path((defaultIndex, ))
696 result[0] = defaultItem
698 customEntry.set_text(defaultItem)
700 customEntry.connect("activate", _on_null_touch_selector_entry_entry_activated, dialog, result)
701 customEntry.connect("changed", _on_null_touch_selector_entry_entry_changed, result, selection, defaultIndex)
702 treeView.connect("row-activated", _on_null_touch_selector_entry_tree_activated, dialog, result)
706 response = dialog.run()
708 if response == gtk.RESPONSE_OK:
709 _, itr = selection.get_selected()
711 return model.get_value(itr, 0)
713 enteredText = customEntry.get_text().strip()
716 elif result[0] is not None:
719 raise RuntimeError("No selection made")
720 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
721 raise RuntimeError("User cancelled request")
723 raise RuntimeError("Unrecognized response %r", response)
731 hildon.TouchSelectorEntry
732 touch_selector_entry = _hildon_touch_selector_entry
733 except AttributeError:
734 touch_selector_entry = _null_touch_selector_entry
737 if __name__ == "__main__":
738 app = get_app_class()()
740 label = gtk.Label("Hello World from a Label!")
744 win = hildonize_window(app, win)
745 if False and IS_FREMANTLE_SUPPORTED:
746 appMenu = hildon.AppMenu()
748 b = gtk.Button(str(i))
750 win.set_app_menu(appMenu)
755 print touch_selector(win, "Test", ["A", "B", "C", "D"], 2)
757 print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "C")
758 print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "Blah")
763 (name, value) for (name, value) in locals().iteritems()
764 if not name.startswith("_")
766 pprint.pprint(goodLocals)
769 show_information_banner(win, "Hello World")
773 banner = show_busy_banner_start(win, "Hello World")
775 show_busy_banner_end(banner)