X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=src%2Fhildonize.py;h=6c50017f5e2a80ce673b0bdd192629fbdb1aa04e;hb=15b7c992b85a342c95fc1d0e4312887b8d3a2cf4;hp=377313b0ac354bed504f868b19de3137436fe9cb;hpb=4325208b27013d04c6e2dead4930a8d70b55abdc;p=gc-dialer diff --git a/src/hildonize.py b/src/hildonize.py index 377313b..6c50017 100644 --- a/src/hildonize.py +++ b/src/hildonize.py @@ -1,5 +1,11 @@ #!/usr/bin/env python +""" +Open Issues + @bug not all of a message is shown + @bug Buttons are too small +""" + import gobject import gtk @@ -34,9 +40,10 @@ def _null_get_app_class(): return _NullHildonProgram -if IS_HILDON_SUPPORTED: +try: + hildon.Program get_app_class = _hildon_get_app_class -else: +except AttributeError: get_app_class = _null_get_app_class @@ -110,15 +117,65 @@ def _null_hildonize_menu(window, gtkMenu, ignoredButtons): try: hildon.AppMenu GTK_MENU_USED = False + IS_FREMANTLE_SUPPORTED = True hildonize_menu = _fremantle_hildonize_menu except AttributeError: GTK_MENU_USED = True + IS_FREMANTLE_SUPPORTED = False if IS_HILDON_SUPPORTED: hildonize_menu = _hildon_hildonize_menu else: hildonize_menu = _null_hildonize_menu +def _hildon_set_button_auto_selectable(button): + button.set_theme_size(hildon.HILDON_SIZE_AUTO_HEIGHT) + + +def _null_set_button_auto_selectable(button): + pass + + +try: + hildon.HILDON_SIZE_AUTO_HEIGHT + gtk.Button.set_theme_size + set_button_auto_selectable = _hildon_set_button_auto_selectable +except AttributeError: + set_button_auto_selectable = _null_set_button_auto_selectable + + +def _hildon_set_button_finger_selectable(button): + button.set_theme_size(hildon.HILDON_SIZE_FINGER_HEIGHT) + + +def _null_set_button_finger_selectable(button): + pass + + +try: + hildon.HILDON_SIZE_FINGER_HEIGHT + gtk.Button.set_theme_size + set_button_finger_selectable = _hildon_set_button_finger_selectable +except AttributeError: + set_button_finger_selectable = _null_set_button_finger_selectable + + +def _hildon_set_button_thumb_selectable(button): + button.set_theme_size(hildon.HILDON_SIZE_THUMB_HEIGHT) + + +def _null_set_button_thumb_selectable(button): + pass + + +try: + hildon.HILDON_SIZE_THUMB_HEIGHT + gtk.Button.set_theme_size + set_button_thumb_selectable = _hildon_set_button_thumb_selectable +except AttributeError: + set_button_thumb_selectable = _null_set_button_thumb_selectable + + def _hildon_set_cell_thumb_selectable(renderer): renderer.set_property("scale", 1.5) @@ -133,6 +190,81 @@ else: set_cell_thumb_selectable = _null_set_cell_thumb_selectable +def _hildon_set_pix_cell_thumb_selectable(renderer): + renderer.set_property("stock-size", 48) + + +def _null_set_pix_cell_thumb_selectable(renderer): + pass + + +if IS_HILDON_SUPPORTED: + set_pix_cell_thumb_selectable = _hildon_set_pix_cell_thumb_selectable +else: + set_pix_cell_thumb_selectable = _null_set_pix_cell_thumb_selectable + + +def _fremantle_show_information_banner(parent, message): + hildon.hildon_banner_show_information(parent, "", message) + + +def _hildon_show_information_banner(parent, message): + hildon.hildon_banner_show_information(parent, None, message) + + +def _null_show_information_banner(parent, message): + pass + + +if IS_FREMANTLE_SUPPORTED: + show_information_banner = _fremantle_show_information_banner +else: + try: + hildon.hildon_banner_show_information + show_information_banner = _hildon_show_information_banner + except AttributeError: + show_information_banner = _null_show_information_banner + + +def _fremantle_show_busy_banner_start(parent, message): + hildon.hildon_gtk_window_set_progress_indicator(parent, True) + return parent + + +def _fremantle_show_busy_banner_end(banner): + hildon.hildon_gtk_window_set_progress_indicator(banner, False) + + +def _hildon_show_busy_banner_start(parent, message): + return hildon.hildon_banner_show_animation(parent, None, message) + + +def _hildon_show_busy_banner_end(banner): + banner.destroy() + + +def _null_show_busy_banner_start(parent, message): + return None + + +def _null_show_busy_banner_end(banner): + assert banner is None + + +try: + hildon.hildon_gtk_window_set_progress_indicator + show_busy_banner_start = _fremantle_show_busy_banner_start + show_busy_banner_end = _fremantle_show_busy_banner_end +except AttributeError: + try: + hildon.hildon_banner_show_animation + show_busy_banner_start = _hildon_show_busy_banner_start + show_busy_banner_end = _hildon_show_busy_banner_end + except AttributeError: + show_busy_banner_start = _null_show_busy_banner_start + show_busy_banner_end = _null_show_busy_banner_end + + def _hildon_hildonize_text_entry(textEntry): textEntry.set_property('hildon-input-mode', 7) @@ -268,7 +400,7 @@ try: hildonize_scrollwindow_with_viewport = _hildon_hildonize_scrollwindow except AttributeError: try: - hildon.hildon_helper_hildonize_scrollwindow + hildon.hildon_helper_set_thumb_scrollbar hildonize_scrollwindow = _hildon_hildonize_scrollwindow hildonize_scrollwindow_with_viewport = _hildon_hildonize_scrollwindow except AttributeError: @@ -292,15 +424,16 @@ def _hildon_request_number(parent, title, range, default): try: dialog.show_all() response = dialog.run() + + if response == gtk.RESPONSE_OK: + return spinner.get_value() + elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT: + raise RuntimeError("User cancelled request") + else: + raise RuntimeError("Unrecognized response %r", response) finally: dialog.hide() - - if response == gtk.RESPONSE_OK: - return spinner.get_value() - elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT: - raise RuntimeError("User cancelled request") - else: - raise RuntimeError("Unrecognized response %r", response) + dialog.destroy() def _null_request_number(parent, title, range, default): @@ -320,15 +453,16 @@ def _null_request_number(parent, title, range, default): try: dialog.show_all() response = dialog.run() + + if response == gtk.RESPONSE_OK: + return spinner.get_value_as_int() + elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT: + raise RuntimeError("User cancelled request") + else: + raise RuntimeError("Unrecognized response %r", response) finally: dialog.hide() - - if response == gtk.RESPONSE_OK: - return spinner.get_value_as_int() - elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT: - raise RuntimeError("User cancelled request") - else: - raise RuntimeError("Unrecognized response %r", response) + dialog.destroy() try: @@ -354,38 +488,106 @@ def _hildon_touch_selector(parent, title, items, defaultIndex): try: dialog.show_all() response = dialog.run() + + if response == gtk.RESPONSE_OK: + return selector.get_active(0) + elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT: + raise RuntimeError("User cancelled request") + else: + raise RuntimeError("Unrecognized response %r", response) finally: dialog.hide() + dialog.destroy() - if response == gtk.RESPONSE_OK: - return selector.get_active(0) - elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT: - raise RuntimeError("User cancelled request") - else: - raise RuntimeError("Unrecognized response %r", response) + +def _on_null_touch_selector_activated(treeView, path, column, dialog, pathData): + dialog.response(gtk.RESPONSE_OK) + pathData[0] = path def _null_touch_selector(parent, title, items, defaultIndex = -1): + parentSize = parent.get_size() + model = gtk.ListStore(gobject.TYPE_STRING) for item in items: model.append((item, )) cell = gtk.CellRendererText() - - combo = gtk.ComboBox() - combo.set_model(model) - combo.pack_start(cell, True) - combo.add_attribute(cell, 'text', 0) - combo.set_active(defaultIndex) + set_cell_thumb_selectable(cell) + column = gtk.TreeViewColumn(title) + column.pack_start(cell, expand=True) + column.add_attribute(cell, "text", 0) + + treeView = gtk.TreeView() + treeView.set_model(model) + treeView.append_column(column) + selection = treeView.get_selection() + selection.set_mode(gtk.SELECTION_SINGLE) + if 0 < defaultIndex: + selection.select_path((defaultIndex, )) + + scrolledWin = gtk.ScrolledWindow() + scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + scrolledWin.add(treeView) dialog = gtk.Dialog( title, parent, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, - (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL), + (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL), ) dialog.set_default_response(gtk.RESPONSE_CANCEL) - dialog.get_child().add(combo) + dialog.get_child().add(scrolledWin) + dialog.resize(parentSize[0], max(parentSize[1]-100, 100)) + + scrolledWin = hildonize_scrollwindow(scrolledWin) + pathData = [None] + treeView.connect("row-activated", _on_null_touch_selector_activated, dialog, pathData) + + try: + dialog.show_all() + response = dialog.run() + + if response == gtk.RESPONSE_OK: + if pathData[0] is None: + raise RuntimeError("No selection made") + return pathData[0][0] + elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT: + raise RuntimeError("User cancelled request") + else: + raise RuntimeError("Unrecognized response %r", response) + finally: + dialog.hide() + dialog.destroy() + + +try: + hildon.PickerDialog + hildon.TouchSelector + touch_selector = _hildon_touch_selector +except AttributeError: + touch_selector = _null_touch_selector + + +def _hildon_touch_selector_entry(parent, title, items, defaultItem): + # Got a segfault when using append_text_column with TouchSelectorEntry, so using this way + try: + selector = hildon.TouchSelectorEntry(text=True) + except TypeError: + selector = hildon.hildon_touch_selector_entry_new_text() + defaultIndex = -1 + for i, item in enumerate(items): + selector.append_text(item) + if item == defaultItem: + defaultIndex = i + + dialog = hildon.PickerDialog(parent) + dialog.set_selector(selector) + + if 0 < defaultIndex: + selector.set_active(0, defaultIndex) + else: + selector.get_entry().set_text(defaultItem) try: dialog.show_all() @@ -394,20 +596,151 @@ def _null_touch_selector(parent, title, items, defaultIndex = -1): dialog.hide() if response == gtk.RESPONSE_OK: - return combo.get_active() + return selector.get_entry().get_text() elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT: raise RuntimeError("User cancelled request") else: raise RuntimeError("Unrecognized response %r", response) +def _on_null_touch_selector_entry_entry_changed(entry, result, selection, defaultIndex): + custom = entry.get_text().strip() + if custom: + result[0] = custom + selection.unselect_all() + else: + result[0] = None + selection.select_path((defaultIndex, )) + + +def _on_null_touch_selector_entry_entry_activated(customEntry, dialog, result): + dialog.response(gtk.RESPONSE_OK) + result[0] = customEntry.get_text() + + +def _on_null_touch_selector_entry_tree_activated(treeView, path, column, dialog, result): + dialog.response(gtk.RESPONSE_OK) + model = treeView.get_model() + itr = model.get_iter(path) + if itr is not None: + result[0] = model.get_value(itr, 0) + + +def _null_touch_selector_entry(parent, title, items, defaultItem): + parentSize = parent.get_size() + + model = gtk.ListStore(gobject.TYPE_STRING) + defaultIndex = -1 + for i, item in enumerate(items): + model.append((item, )) + if item == defaultItem: + defaultIndex = i + + cell = gtk.CellRendererText() + set_cell_thumb_selectable(cell) + column = gtk.TreeViewColumn(title) + column.pack_start(cell, expand=True) + column.add_attribute(cell, "text", 0) + + treeView = gtk.TreeView() + treeView.set_model(model) + treeView.append_column(column) + selection = treeView.get_selection() + selection.set_mode(gtk.SELECTION_SINGLE) + + scrolledWin = gtk.ScrolledWindow() + scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + scrolledWin.add(treeView) + + customEntry = gtk.Entry() + + layout = gtk.VBox() + layout.pack_start(customEntry, expand=False) + layout.pack_start(scrolledWin) + + dialog = gtk.Dialog( + title, + parent, + gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, + (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL), + ) + dialog.set_default_response(gtk.RESPONSE_CANCEL) + dialog.get_child().add(layout) + dialog.resize(parentSize[0], max(parentSize[1]-100, 100)) + + scrolledWin = hildonize_scrollwindow(scrolledWin) + + result = [None] + if 0 < defaultIndex: + selection.select_path((defaultIndex, )) + result[0] = defaultItem + else: + customEntry.set_text(defaultItem) + + customEntry.connect("activate", _on_null_touch_selector_entry_entry_activated, dialog, result) + customEntry.connect("changed", _on_null_touch_selector_entry_entry_changed, result, selection, defaultIndex) + treeView.connect("row-activated", _on_null_touch_selector_entry_tree_activated, dialog, result) + + try: + dialog.show_all() + response = dialog.run() + + if response == gtk.RESPONSE_OK: + _, itr = selection.get_selected() + if itr is not None: + return model.get_value(itr, 0) + else: + enteredText = customEntry.get_text().strip() + if enteredText: + return enteredText + elif result[0] is not None: + return result[0] + else: + raise RuntimeError("No selection made") + elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT: + raise RuntimeError("User cancelled request") + else: + raise RuntimeError("Unrecognized response %r", response) + finally: + dialog.hide() + dialog.destroy() + + try: hildon.PickerDialog - hildon.TouchSelector - touch_selector = _hildon_touch_selector + hildon.TouchSelectorEntry + touch_selector_entry = _hildon_touch_selector_entry except AttributeError: - touch_selector = _null_touch_selector + touch_selector_entry = _null_touch_selector_entry if __name__ == "__main__": - pass + app = get_app_class()() + + label = gtk.Label("Hello World from a Label!") + + win = gtk.Window() + win.add(label) + win = hildonize_window(app, win) + if False: + print touch_selector(win, "Test", ["A", "B", "C", "D"], 2) + if True: + print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "C") + print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "Blah") + if False: + import pprint + name, value = "", "" + goodLocals = [ + (name, value) for (name, value) in locals().iteritems() + if not name.startswith("_") + ] + pprint.pprint(goodLocals) + if False: + import time + show_information_banner(win, "Hello World") + time.sleep(5) + if False: + import time + banner = show_busy_banner_start(win, "Hello World") + time.sleep(5) + show_busy_banner_end(banner)