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_name(name):
51 gtk.set_application_name(name)
54 def _null_set_application_name(name):
59 gtk.set_application_name
60 set_application_name = _hildon_set_application_name
61 except AttributeError:
62 set_application_name = _null_set_application_name
65 def _fremantle_hildonize_window(app, window):
67 newWindow = hildon.StackableWindow()
68 if oldWindow.get_child() is not None:
69 oldWindow.get_child().reparent(newWindow)
70 app.add_window(newWindow)
74 def _hildon_hildonize_window(app, window):
76 newWindow = hildon.Window()
77 if oldWindow.get_child() is not None:
78 oldWindow.get_child().reparent(newWindow)
79 app.add_window(newWindow)
83 def _null_hildonize_window(app, window):
88 hildon.StackableWindow
89 hildonize_window = _fremantle_hildonize_window
90 except AttributeError:
93 hildonize_window = _hildon_hildonize_window
94 except AttributeError:
95 hildonize_window = _null_hildonize_window
98 def _fremantle_hildonize_menu(window, gtkMenu):
99 appMenu = hildon.AppMenu()
100 window.set_app_menu(appMenu)
101 gtkMenu.get_parent().remove(gtkMenu)
105 def _hildon_hildonize_menu(window, gtkMenu):
106 hildonMenu = gtk.Menu()
107 for child in gtkMenu.get_children():
108 child.reparent(hildonMenu)
109 window.set_menu(hildonMenu)
114 def _null_hildonize_menu(window, gtkMenu):
120 GTK_MENU_USED = False
121 IS_FREMANTLE_SUPPORTED = True
122 hildonize_menu = _fremantle_hildonize_menu
123 except AttributeError:
125 IS_FREMANTLE_SUPPORTED = False
126 if IS_HILDON_SUPPORTED:
127 hildonize_menu = _hildon_hildonize_menu
129 hildonize_menu = _null_hildonize_menu
132 def _hildon_set_button_auto_selectable(button):
133 button.set_theme_size(hildon.HILDON_SIZE_AUTO_HEIGHT)
136 def _null_set_button_auto_selectable(button):
141 hildon.HILDON_SIZE_AUTO_HEIGHT
142 gtk.Button.set_theme_size
143 set_button_auto_selectable = _hildon_set_button_auto_selectable
144 except AttributeError:
145 set_button_auto_selectable = _null_set_button_auto_selectable
148 def _hildon_set_button_finger_selectable(button):
149 button.set_theme_size(hildon.HILDON_SIZE_FINGER_HEIGHT)
152 def _null_set_button_finger_selectable(button):
157 hildon.HILDON_SIZE_FINGER_HEIGHT
158 gtk.Button.set_theme_size
159 set_button_finger_selectable = _hildon_set_button_finger_selectable
160 except AttributeError:
161 set_button_finger_selectable = _null_set_button_finger_selectable
164 def _hildon_set_button_thumb_selectable(button):
165 button.set_theme_size(hildon.HILDON_SIZE_THUMB_HEIGHT)
168 def _null_set_button_thumb_selectable(button):
173 hildon.HILDON_SIZE_THUMB_HEIGHT
174 gtk.Button.set_theme_size
175 set_button_thumb_selectable = _hildon_set_button_thumb_selectable
176 except AttributeError:
177 set_button_thumb_selectable = _null_set_button_thumb_selectable
180 def _hildon_set_cell_thumb_selectable(renderer):
181 renderer.set_property("scale", 1.5)
184 def _null_set_cell_thumb_selectable(renderer):
185 renderer.set_property("scale", 1.5)
188 if IS_HILDON_SUPPORTED:
189 set_cell_thumb_selectable = _hildon_set_cell_thumb_selectable
191 set_cell_thumb_selectable = _null_set_cell_thumb_selectable
194 def _hildon_set_pix_cell_thumb_selectable(renderer):
195 renderer.set_property("stock-size", 48)
198 def _null_set_pix_cell_thumb_selectable(renderer):
202 if IS_HILDON_SUPPORTED:
203 set_pix_cell_thumb_selectable = _hildon_set_pix_cell_thumb_selectable
205 set_pix_cell_thumb_selectable = _null_set_pix_cell_thumb_selectable
208 def _fremantle_show_information_banner(parent, message):
209 hildon.hildon_banner_show_information(parent, "", message)
212 def _hildon_show_information_banner(parent, message):
213 hildon.hildon_banner_show_information(parent, None, message)
216 def _null_show_information_banner(parent, message):
220 if IS_FREMANTLE_SUPPORTED:
221 show_information_banner = _fremantle_show_information_banner
224 hildon.hildon_banner_show_information
225 show_information_banner = _hildon_show_information_banner
226 except AttributeError:
227 show_information_banner = _null_show_information_banner
230 def _fremantle_show_busy_banner_start(parent, message):
231 hildon.hildon_gtk_window_set_progress_indicator(parent, True)
235 def _fremantle_show_busy_banner_end(banner):
236 hildon.hildon_gtk_window_set_progress_indicator(banner, False)
239 def _hildon_show_busy_banner_start(parent, message):
240 return hildon.hildon_banner_show_animation(parent, None, message)
243 def _hildon_show_busy_banner_end(banner):
247 def _null_show_busy_banner_start(parent, message):
251 def _null_show_busy_banner_end(banner):
252 assert banner is None
256 hildon.hildon_gtk_window_set_progress_indicator
257 show_busy_banner_start = _fremantle_show_busy_banner_start
258 show_busy_banner_end = _fremantle_show_busy_banner_end
259 except AttributeError:
261 hildon.hildon_banner_show_animation
262 show_busy_banner_start = _hildon_show_busy_banner_start
263 show_busy_banner_end = _hildon_show_busy_banner_end
264 except AttributeError:
265 show_busy_banner_start = _null_show_busy_banner_start
266 show_busy_banner_end = _null_show_busy_banner_end
269 def _hildon_hildonize_text_entry(textEntry):
270 textEntry.set_property('hildon-input-mode', 7)
273 def _null_hildonize_text_entry(textEntry):
277 if IS_HILDON_SUPPORTED:
278 hildonize_text_entry = _hildon_hildonize_text_entry
280 hildonize_text_entry = _null_hildonize_text_entry
283 def _hildon_window_to_portrait(window):
284 # gtk documentation is unclear whether this does a "=" or a "|="
285 flags = hildon.PORTRAIT_MODE_SUPPORT | hildon.PORTRAIT_MODE_REQUEST
286 hildon.hildon_gtk_window_set_portrait_flags(window, flags)
289 def _hildon_window_to_landscape(window):
290 # gtk documentation is unclear whether this does a "=" or a "&= ~"
292 hildon.hildon_gtk_window_set_portrait_flags(window, flags)
295 def _null_window_to_portrait(window):
299 def _null_window_to_landscape(window):
304 hildon.PORTRAIT_MODE_SUPPORT
305 hildon.PORTRAIT_MODE_REQUEST
306 hildon.hildon_gtk_window_set_portrait_flags
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 _null_create_seekbar():
363 adjustment = gtk.Adjustment(0, 0, 101, 1, 5, 1)
364 seek = gtk.HScale(adjustment)
365 seek.set_draw_value(False)
369 def _fremantle_create_seekbar():
370 seek = hildon.Seekbar()
371 seek.set_range(0.0, 100)
372 seek.set_draw_value(False)
373 seek.set_update_policy(gtk.UPDATE_DISCONTINUOUS)
379 create_seekbar = _fremantle_create_seekbar
380 except AttributeError:
381 create_seekbar = _null_create_seekbar
384 def _fremantle_hildonize_scrollwindow(scrolledWindow):
385 pannableWindow = hildon.PannableArea()
387 child = scrolledWindow.get_child()
388 scrolledWindow.remove(child)
389 pannableWindow.add(child)
391 parent = scrolledWindow.get_parent()
392 if parent is not None:
393 parent.remove(scrolledWindow)
394 parent.add(pannableWindow)
396 return pannableWindow
399 def _hildon_hildonize_scrollwindow(scrolledWindow):
400 hildon.hildon_helper_set_thumb_scrollbar(scrolledWindow, True)
401 return scrolledWindow
404 def _null_hildonize_scrollwindow(scrolledWindow):
405 return scrolledWindow
410 hildonize_scrollwindow = _fremantle_hildonize_scrollwindow
411 hildonize_scrollwindow_with_viewport = _hildon_hildonize_scrollwindow
412 except AttributeError:
414 hildon.hildon_helper_set_thumb_scrollbar
415 hildonize_scrollwindow = _hildon_hildonize_scrollwindow
416 hildonize_scrollwindow_with_viewport = _hildon_hildonize_scrollwindow
417 except AttributeError:
418 hildonize_scrollwindow = _null_hildonize_scrollwindow
419 hildonize_scrollwindow_with_viewport = _null_hildonize_scrollwindow
422 def _hildon_request_number(parent, title, range, default):
423 spinner = hildon.NumberEditor(*range)
424 spinner.set_value(default)
429 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
430 (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
432 dialog.set_default_response(gtk.RESPONSE_CANCEL)
433 dialog.get_child().add(spinner)
437 response = dialog.run()
439 if response == gtk.RESPONSE_OK:
440 return spinner.get_value()
441 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
442 raise RuntimeError("User cancelled request")
444 raise RuntimeError("Unrecognized response %r", response)
450 def _null_request_number(parent, title, range, default):
451 adjustment = gtk.Adjustment(default, range[0], range[1], 1, 5, 0)
452 spinner = gtk.SpinButton(adjustment, 0, 0)
453 spinner.set_wrap(False)
458 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
459 (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
461 dialog.set_default_response(gtk.RESPONSE_CANCEL)
462 dialog.get_child().add(spinner)
466 response = dialog.run()
468 if response == gtk.RESPONSE_OK:
469 return spinner.get_value_as_int()
470 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
471 raise RuntimeError("User cancelled request")
473 raise RuntimeError("Unrecognized response %r", response)
480 hildon.NumberEditor # TODO deprecated in fremantle
481 request_number = _hildon_request_number
482 except AttributeError:
483 request_number = _null_request_number
486 def _hildon_touch_selector(parent, title, items, defaultIndex):
487 model = gtk.ListStore(gobject.TYPE_STRING)
489 model.append((item, ))
491 selector = hildon.TouchSelector()
492 selector.append_text_column(model, True)
493 selector.set_column_selection_mode(hildon.TOUCH_SELECTOR_SELECTION_MODE_SINGLE)
494 selector.set_active(0, defaultIndex)
496 dialog = hildon.PickerDialog(parent)
497 dialog.set_selector(selector)
501 response = dialog.run()
503 if response == gtk.RESPONSE_OK:
504 return selector.get_active(0)
505 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
506 raise RuntimeError("User cancelled request")
508 raise RuntimeError("Unrecognized response %r", response)
514 def _on_null_touch_selector_activated(treeView, path, column, dialog, pathData):
515 dialog.response(gtk.RESPONSE_OK)
519 def _null_touch_selector(parent, title, items, defaultIndex = -1):
520 parentSize = parent.get_size()
522 model = gtk.ListStore(gobject.TYPE_STRING)
524 model.append((item, ))
526 cell = gtk.CellRendererText()
527 set_cell_thumb_selectable(cell)
528 column = gtk.TreeViewColumn(title)
529 column.pack_start(cell, expand=True)
530 column.add_attribute(cell, "text", 0)
532 treeView = gtk.TreeView()
533 treeView.set_model(model)
534 treeView.append_column(column)
535 selection = treeView.get_selection()
536 selection.set_mode(gtk.SELECTION_SINGLE)
538 selection.select_path((defaultIndex, ))
540 scrolledWin = gtk.ScrolledWindow()
541 scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
542 scrolledWin.add(treeView)
547 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
548 (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
550 dialog.set_default_response(gtk.RESPONSE_CANCEL)
551 dialog.get_child().add(scrolledWin)
552 dialog.resize(parentSize[0], max(parentSize[1]-100, 100))
554 scrolledWin = hildonize_scrollwindow(scrolledWin)
556 treeView.connect("row-activated", _on_null_touch_selector_activated, dialog, pathData)
560 response = dialog.run()
562 if response == gtk.RESPONSE_OK:
563 if pathData[0] is None:
564 raise RuntimeError("No selection made")
565 return pathData[0][0]
566 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
567 raise RuntimeError("User cancelled request")
569 raise RuntimeError("Unrecognized response %r", response)
578 touch_selector = _hildon_touch_selector
579 except AttributeError:
580 touch_selector = _null_touch_selector
583 def _hildon_touch_selector_entry(parent, title, items, defaultItem):
584 # Got a segfault when using append_text_column with TouchSelectorEntry, so using this way
586 selector = hildon.TouchSelectorEntry(text=True)
588 selector = hildon.hildon_touch_selector_entry_new_text()
590 for i, item in enumerate(items):
591 selector.append_text(item)
592 if item == defaultItem:
595 dialog = hildon.PickerDialog(parent)
596 dialog.set_selector(selector)
599 selector.set_active(0, defaultIndex)
601 selector.get_entry().set_text(defaultItem)
605 response = dialog.run()
609 if response == gtk.RESPONSE_OK:
610 return selector.get_entry().get_text()
611 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
612 raise RuntimeError("User cancelled request")
614 raise RuntimeError("Unrecognized response %r", response)
617 def _on_null_touch_selector_entry_entry_changed(entry, result, selection, defaultIndex):
618 custom = entry.get_text().strip()
621 selection.unselect_all()
624 selection.select_path((defaultIndex, ))
627 def _on_null_touch_selector_entry_entry_activated(customEntry, dialog, result):
628 dialog.response(gtk.RESPONSE_OK)
629 result[0] = customEntry.get_text()
632 def _on_null_touch_selector_entry_tree_activated(treeView, path, column, dialog, result):
633 dialog.response(gtk.RESPONSE_OK)
634 model = treeView.get_model()
635 itr = model.get_iter(path)
637 result[0] = model.get_value(itr, 0)
640 def _null_touch_selector_entry(parent, title, items, defaultItem):
641 parentSize = parent.get_size()
643 model = gtk.ListStore(gobject.TYPE_STRING)
645 for i, item in enumerate(items):
646 model.append((item, ))
647 if item == defaultItem:
650 cell = gtk.CellRendererText()
651 set_cell_thumb_selectable(cell)
652 column = gtk.TreeViewColumn(title)
653 column.pack_start(cell, expand=True)
654 column.add_attribute(cell, "text", 0)
656 treeView = gtk.TreeView()
657 treeView.set_model(model)
658 treeView.append_column(column)
659 selection = treeView.get_selection()
660 selection.set_mode(gtk.SELECTION_SINGLE)
662 scrolledWin = gtk.ScrolledWindow()
663 scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
664 scrolledWin.add(treeView)
666 customEntry = gtk.Entry()
669 layout.pack_start(customEntry, expand=False)
670 layout.pack_start(scrolledWin)
675 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
676 (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
678 dialog.set_default_response(gtk.RESPONSE_CANCEL)
679 dialog.get_child().add(layout)
680 dialog.resize(parentSize[0], max(parentSize[1]-100, 100))
682 scrolledWin = hildonize_scrollwindow(scrolledWin)
686 selection.select_path((defaultIndex, ))
687 result[0] = defaultItem
689 customEntry.set_text(defaultItem)
691 customEntry.connect("activate", _on_null_touch_selector_entry_entry_activated, dialog, result)
692 customEntry.connect("changed", _on_null_touch_selector_entry_entry_changed, result, selection, defaultIndex)
693 treeView.connect("row-activated", _on_null_touch_selector_entry_tree_activated, dialog, result)
697 response = dialog.run()
699 if response == gtk.RESPONSE_OK:
700 _, itr = selection.get_selected()
702 return model.get_value(itr, 0)
704 enteredText = customEntry.get_text().strip()
707 elif result[0] is not None:
710 raise RuntimeError("No selection made")
711 elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
712 raise RuntimeError("User cancelled request")
714 raise RuntimeError("Unrecognized response %r", response)
722 hildon.TouchSelectorEntry
723 touch_selector_entry = _hildon_touch_selector_entry
724 except AttributeError:
725 touch_selector_entry = _null_touch_selector_entry
728 if __name__ == "__main__":
729 app = get_app_class()()
731 label = gtk.Label("Hello World from a Label!")
735 win = hildonize_window(app, win)
736 if False and IS_FREMANTLE_SUPPORTED:
737 appMenu = hildon.AppMenu()
739 b = gtk.Button(str(i))
741 win.set_app_menu(appMenu)
746 print touch_selector(win, "Test", ["A", "B", "C", "D"], 2)
748 print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "C")
749 print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "Blah")
754 (name, value) for (name, value) in locals().iteritems()
755 if not name.startswith("_")
757 pprint.pprint(goodLocals)
760 show_information_banner(win, "Hello World")
764 banner = show_busy_banner_start(win, "Hello World")
766 show_busy_banner_end(banner)