Line 1: |
Line 1: |
− | = Toolbar =
| + | {{Translations}} |
| | | |
− | This snippet shows how an activity would have a toolbar with two buttons:
| + | The [[Development_Team/Almanac|Sugar Almanac]] also has lots of code snippets. |
| | | |
| + | == Smooth animation == |
| + | |
| + | [[PyGTK/Smooth_Animation_with_PyGTK]] |
| + | |
| + | == WebKit WebView == |
| + | |
| + | from gi.repository import WebKit |
| + | from gi.repository import Gtk |
| + | |
| + | WINDOW_WIDTH, WINDOW_HEIGHT = 700, 500 |
| + | |
| + | # create window: |
| + | |
| + | def _destroy_cb(widget, data=None): |
| + | Gtk.main_quit() |
| + | |
| + | window = Gtk.Window() |
| + | window.resize(WINDOW_WIDTH, WINDOW_HEIGHT) |
| + | window.connect("destroy", _destroy_cb) |
| + | window.show() |
| + | |
| + | # create and add scrolled window: |
| + | s = Gtk.ScrolledWindow() |
| + | window.add(s) |
| + | s.show() |
| + | |
| + | # create and add webview: |
| + | v = WebKit.WebView() |
| + | s.add(v) |
| + | v.show() |
| + | |
| + | # load google page: |
| + | v.load_uri('http://wiki.laptop.org') |
| + | |
| + | Gtk.main() |
| + | |
| + | == Toolbar == |
| + | |
| + | === Toolbar icons === |
| + | |
| + | Setting a standard Sugar toolbar. |
| + | from sugar.activity import activity |
| + | ... |
| + | class MyActivity(activity.Activity): |
| + | ... |
| + | toolbox = activity.ActivityToolbox(self) |
| + | self.set_toolbox(toolbox) |
| + | toolbox.show() |
| + | |
| + | Adding a custom toolbar and icons. |
| + | from sugar.graphics.toolbutton import ToolButton |
| + | from sugar.activity import activity |
| + | ... |
| + | class MyActivity(activity.Activity): |
| + | ... |
| + | mytoolbox = gtk.Toolbar() |
| + | helpbut = ToolButton('help') #Stock help icon |
| + | helpbut.set_tooltip(_("Get help")) |
| + | helpbut.connect('clicked', self.help_button_pressed) |
| + | mytoolbox.insert(helpbut, -1) |
| + | helpbut.show() |
| + | mytoolbox.show() |
| + | |
| + | toolbox = activity.ActivityToolbox(self) |
| + | toolbox.add_toolbar("mytoolbar",mytoolbox) |
| + | self.set_toolbox(toolbox) |
| + | toolbox.show() |
| + | |
| + | In addition to the standard icons in /usr/share/icons/sugar/scalable/ (eg, "go-next"), you can create additional icons by putting an svg in your activity's icons/ directory. E.g., |
| + | icons/my-icon.svg |
| + | And then use it. |
| + | mybut = ToolButton('my-icon')# without extension |
| + | |
| + | == Files == |
| + | |
| + | This snippet shows how to get a [http://mailman.laptop.org/pipermail/sugar/2007-February/001459.html path to files in the running Activity]: |
| + | |
| + | from sugar.activity import activity |
| + | bundle_path = activity.get_bundle_path() |
| + | |
| + | This snippet shows how to get [http://lists.laptop.org/pipermail/devel/2008-March/011799.html a path to an activity's writable directories] (i.e. the SUGAR_ACTIVITY_ROOT environment variable; see also [[Activity_DBus_API#Security | the activity DBus API]]): |
| + | |
| + | class WebActivity(activity.Activity): |
| + | def __init__(self, handle): |
| + | activity.Activity.__init__(self, handle) |
| + | temp_path = os.path.join(self.get_activity_root(), 'instance') |
| + | |
| + | == Images == |
| + | |
| + | * [http://mailman.laptop.org/pipermail/sugar/2007-February/001528.html Loading an SVG file onto a surface with a transparent background]: |
| + | |
| + | target = ctx.get_target() |
| + | buf = target.create_similar(cairo.CONTENT_COLOR_ALPHA, w, h) |
| + | ctx.set_source_surface(buf, x, y) |
| + | ctx.paint() |
| + | |
| + | * [http://mailman.laptop.org/pipermail/sugar/2007-February/001547.html Measuring an SVG file's original dimensions] |
| + | |
| + | width, height = handle.get_dimension_data() |
| + | |
| + | * Loading a JPEG file onto a surface: |
| + | |
| + | pixbuf = gtk.gdk.pixbuf_new_from_file("foo.jpg") |
| + | ctx = # a cairo context |
| + | ctx.set_source_pixbuf(pixbuf, 0, 0) |
| + | ctx.paint() |
| + | |
| + | libjpeg is said to be an alternative to using pixbuf. Which is better? Perhaps Sugar/[[HippoCanvas]] provides an easier way to do this? |
| + | |
| + | [[Cairo]] image expansion is good quality, but expensive. Shrinking is fine and notably faster. So for images rendered large (ie, screen-size), you might want to start with a big image, rather than expanding a small one. A speed/space tradeoff. And use SVG instead if appropriate, of course. [[User:MitchellNCharity|MitchellNCharity]] 10:37, 10 May 2007 (EDT) |
| + | |
| + | == Audio == |
| + | |
| + | * [http://lists.laptop.org/pipermail/sugar/2007-October/003480.html Playing a sound via csound]: |
| + | |
| + | import sys |
| + | sys.path.append('/usr/share/activities/Pippy.activity/sound') |
| + | from sound import * |
| + | playWave(sound='triangle') |
| + | audioOut() |
| + | |
| + | == Processes == |
| + | |
| + | * [http://lists.laptop.org/pipermail/sugar/2007-October/003596.html Starting an external process] |
| + | |
| + | : Use Python's [http://docs.python.org/lib/module-subprocess.html subprocess module]. |
| + | |
| + | * [http://lists.laptop.org/pipermail/sugar/2007-October/003597.html Starting a binary activity instead of a Python activity] |
| + | |
| + | : Set the "exec" property of the <tt>activity.info</tt> file to your binary. |
| + | |
| + | == Not yet sorted == |
| + | |
| + | * [http://mailman.laptop.org/pipermail/sugar/2007-March/002028.html Getting a unique ID for the XO user]: |
| + | |
| + | from sugar import profile |
| + | |
| + | key = profile.get_pubkey() |
| + | |
| + | # If you want a shorter key, you can hash that like: |
| + | |
| + | from sugar import util |
| + | |
| + | key_hash = util._sha_data(key) |
| + | hashed_key = util.printable_hash(key_hash) |
| + | |
| + | * Avoid memory exhaustion from large dead pygtk objects by using |
| + | |
| + | import gc |
| + | |
| + | gc.collect() |
| + | |
| + | Not all trash pygtk objects are garbage collected promptly. If you are throwing away large pixmaps, for instance, this can be deadly. gc.collect() forces a garbage collection pass. |
| + | |
| + | == Performance Tips == |
| + | ''This section belongs on a different, as yet non-existent page. But a good organization for software development tips is currently unclear to me, so I'll stash this here for now.'' [[User:MitchellNCharity|MitchellNCharity]] 14:05, 10 May 2007 (EDT) |
| + | |
| + | * ctx.stroke() several lines at once. stroke() currently has significant overhead. So it is faster to stroke several, than to stroke them individually. They need not be contiguous. [[User:MitchellNCharity|MitchellNCharity]] 14:05, 10 May 2007 (EDT) |
| + | |
| + | == Old snippets which need to be overhauled == |
| + | === Toolbar === |
| + | |
| + | This snippet shows how an activity would have a toolbar with a button and a gtk.TextView widget embedded in a hippo Canvas: |
| + | |
| + | import logging |
| import hippo | | import hippo |
| + | import gtk |
| | | |
− | from sugar.activity.Activity import Activity | + | from gettext import gettext as _ |
| + | |
| + | from sugar.activity import activity |
| from sugar.graphics.toolbar import Toolbar | | from sugar.graphics.toolbar import Toolbar |
− | from sugar.graphics.button import Button | + | from sugar.graphics.iconbutton import IconButton |
| + | from sugar.graphics.entry import Entry |
| + | from sugar.graphics.optionmenu import OptionMenu |
| + | from sugar.graphics.menu import MenuItem |
| | | |
− | class FooActivity(Activity): | + | class FooActivity(activity.Activity): |
− | def __init__(self): | + | |
− | Activity.__init__(self) | + | _ACTION_ANYTHING = 1 |
| + | _ACTION_APPLES = 2 |
| + | _ACTION_ORANGES = 3 |
| + | |
| + | def __init__(self, handle): |
| + | activity.Activity.__init__(self, handle) |
| | | |
− | canvas = hippo.Canvas()
| |
− | self.add(canvas)
| |
− | canvas.show()
| |
− |
| |
| vbox = hippo.CanvasBox() | | vbox = hippo.CanvasBox() |
− | canvas.set_root(vbox) | + | self.set_root(vbox) |
| | | |
| toolbar = Toolbar() | | toolbar = Toolbar() |
| vbox.append(toolbar) | | vbox.append(toolbar) |
| | | |
− | button1 = Button('button1_icon') | + | button = IconButton(icon_name='theme:stock-close') |
− | button1.connect("activated", self._button1_activated_cb) | + | button.connect("activated", self._button_activated_cb) |
− | self.append(button1) | + | toolbar.append(button) |
| + | |
| + | entry = Entry() |
| + | button.connect("activated", self._entry_activated_cb) |
| + | toolbar.append(entry) |
| + | |
| + | option_menu = OptionMenu() |
| + | option_menu.add_item(MenuItem(self._ACTION_ANYTHING, _('Anything'))) |
| + | option_menu.add_item(MenuItem(self._ACTION_APPLES, _('Apples'), |
| + | 'theme:stock-close')) |
| + | option_menu.add_item(MenuItem(self._ACTION_ORANGES, _('Oranges'))) |
| + | option_menu.add_separator() |
| + | toolbar.append(option_menu) |
| + | |
| + | text_view_widget = hippo.CanvasWidget() |
| + | vbox.append(text_view_widget, hippo.PACK_EXPAND) |
| + | |
| + | text_view = gtk.TextView() |
| + | text_view.get_buffer().set_text('Write here!', -1) |
| + | text_view_widget.props.widget = text_view |
| + | |
| + | def _button_activated_cb(self, button): |
| + | logging.debug('FooActivity._button_activated_cb') |
| | | |
− | button2 = Button('button2_icon')
| + | def _entry_activated_cb(self, entry): |
− | button2.connect("activated", self._button2_activated_cb) | + | logging.debug('FooActivity._entry_activated_cb') |
− | self.append(button2)
| |
| | | |
| + | :In build 443 (June '07), <tt>from sugar.graphics.entry import Entry</tt> yields ''ImportError: No module named entry''. [[User:MitchellNCharity|MitchellNCharity]] 19:52, 15 June 2007 (EDT) |
| + | :And obsolete, now deleted code like sugar.graphics.toolbar is being used. Snippet needs to be overhauled. [[User:MitchellNCharity|MitchellNCharity]] 18:04, 21 June 2007 (EDT) |
| | | |
| [[Category:HowTo]] | | [[Category:HowTo]] |
| [[Category:Sugar]] | | [[Category:Sugar]] |
| + | [[Category:Developer]] |