#!/usr/bin/env python # -*- coding: utf-8 -*- # # Enyo activity: A case study for developing a HTML5 activity with Enyo Framework. # Lionel Laské inspired by Manuel Quiñones and Simon Schampijer from gi.repository import Gtk import logging import os from gettext import gettext as _ from sugar3.activity import activity from sugar3.graphics.toolbarbox import ToolbarBox from sugar3.graphics.toolbutton import ToolButton from sugar3.activity.widgets import ActivityButton from sugar3.activity.widgets import TitleEntry from sugar3.activity.widgets import StopButton from sugar3.activity.widgets import ShareButton from sugar3.activity.widgets import DescriptionItem from sugar3.presence import presenceservice from gi.repository import WebKit import logging import gconf from datetime import date from enyo import Enyo class EnyoActivity(activity.Activity): """EnyoActivity class as specified in activity.info""" def __init__(self, handle): """Set up the activity.""" activity.Activity.__init__(self, handle) self.max_participants = 1 self.make_toolbar() self.make_mainview() class DummyObject: """Dummy class used to demonstrated object transfer to JavaScript""" name = "Lionel" version = 2.0 modified = date.today() language = ['Python', 'JavaScript'] def foo(self): pass def send_string(self, button): """Click on send string button, send a simple string to JavaScript""" self.enyo.send_message("helloFromPY", "Hello JavaScript !") def send_object(self, button): """Click on send string button, send a simple string to JavaScript""" self.enyo.send_message("helloFromPY", self.DummyObject()) def alert(self, msg): """Display a message dialog""" messagedialog = Gtk.MessageDialog(self, type=1, buttons=1, message_format=msg) messagedialog.run() messagedialog.destroy() def display_message(self, param): """A message was received from JavaScript, display it""" # Display as a JSON string to see structure self.alert("Python received "+self.enyo.json_encode(param)) def go_home(self, button): """Toolbar button home clicked, signal to JavaScript to update page count""" self.enyo.send_message("home_clicked", 0) def go_back(self, button): """Toolbar button back clicked, signal to JavaScript to update page count""" self.enyo.send_message("back_clicked", -1) def go_forward(self, button): """Toolbar button forward clicked, signal to JavaScript to update page count""" self.enyo.send_message("forward_clicked", 1) def checkbox_changed(self, button): """Checked state changed, signal to JavaScript to update the matching control""" self.enyo.send_message("py_checkbox_changed", self.checkbox.get_active()) def slider_changed(self, event): """Slider changed, signal to JavaScript to update page count""" self.enyo.send_message("py_slider_changed", self.adjustment.get_value()) def turtle_forward(self, button): """Turtle forward button clicked, signal to JavaScript to update Canvas""" self.enyo.send_message("liogo_forward_clicked", 60) def turtle_left(self, button): """Turtle left button clicked, signal to JavaScript to update Canvas""" self.enyo.send_message("liogo_left_clicked", 90) def turtle_right(self, button): """Turtle right button clicked, signal to JavaScript to update Canvas""" self.enyo.send_message("liogo_right_clicked", 90) def turtle_clear(self, button): """Turtle clear button clicked, signal to JavaScript to update Canvas""" self.enyo.send_message("liogo_clear_clicked") def jscript_slider_changed(self, args): """Javascript slider changed, update the matching slider""" self.adjustment.set_value(int(args)) def jscript_checkbox_changed(self, args): """Javascript checkbox changed, update the matching checkbox""" if args: self.checkbox.set_active(True) else: self.checkbox.set_active(False) def disable_back(self, args): """Javascript request to change sensitive status of the toolbar back button""" self.back_button.set_sensitive(args != "True") def disable_forward(self, args): """Javascript request to change sensitive status of the toolbar forward button""" self.forward_button.set_sensitive(args != "True") def init_context(self, args): """Init Javascript context sending buddy information""" # Get XO colors buddy = {} client = gconf.client_get_default() colors = client.get_string("/desktop/sugar/user/color") buddy["colors"] = colors.split(",") # Get XO name presenceService = presenceservice.get_instance() buddy["name"] = presenceService.get_owner().props.nick self.enyo.send_message("buddy", buddy) def make_mainview(self): """Create the activity view""" # Create global box vbox = Gtk.VBox(True) # Create webview scrolled_window = Gtk.ScrolledWindow() self.webview = webview = WebKit.WebView() scrolled_window.add(webview) webview.show() vbox.pack_start(scrolled_window, True, True, 0) scrolled_window.show() # Create python view hbox = Gtk.VBox(False) # Create image and label ubox = Gtk.HBox(False) image = Gtk.Image() image.set_from_file("images/python-logo.jpg") ubox.pack_start(image, False, False, 5) image.show() label = Gtk.Label("This the Sugar part of the activity. All content is handle by Python code.") ubox.pack_start(label, False, False, 10) label.show() ubox.show() hbox.pack_start(ubox, False, False, 10) # Create send simple message buttons ubox = Gtk.HBox(False) button = Gtk.Button("Send string to JavaScript") button.connect('clicked', self.send_string) ubox.pack_start(button, False, False, 0) button.show() button = Gtk.Button("Send object to JavaScript") button.connect('clicked', self.send_object) ubox.pack_start(button, False, False, 10) button.show() ubox.show() hbox.pack_start(ubox, False, False, 0) # Create synchronized control ubox = Gtk.HBox(False) checkbox = self.checkbox = Gtk.CheckButton("Checkbox") checkbox.set_active(True) checkbox.connect('toggled', self.checkbox_changed) ubox.pack_start(checkbox, False, False, 0) checkbox.show() adjustment = self.adjustment = Gtk.Adjustment(50, 0, 100, 1) adjustment.connect('value-changed', self.slider_changed) hscale = self.hscale = Gtk.HScale() hscale.set_adjustment(adjustment) hscale.set_size_request(250, 50) hscale.set_digits(0) ubox.pack_start(hscale, False, False, 20) hscale.show() ubox.show() hbox.pack_start(ubox, False, False, 20) # Create turtle commander ubox = Gtk.HBox(False) label = Gtk.Label("Turtle command:") ubox.pack_start(label, False, False, 10) label.show() button = Gtk.Button("forward 60") button.connect('clicked', self.turtle_forward) ubox.pack_start(button, False, False, 10) button.show() button = Gtk.Button("left 90") button.connect('clicked', self.turtle_left) ubox.pack_start(button, False, False, 10) button.show() button = Gtk.Button("right 90") button.connect('clicked', self.turtle_right) ubox.pack_start(button, False, False, 10) button.show() button = Gtk.Button("clear") button.connect('clicked', self.turtle_clear) ubox.pack_start(button, False, False, 10) button.show() ubox.show() hbox.pack_start(ubox, False, False, 20) vbox.pack_start(hbox, False, False, 0) hbox.show() # Activate Enyo interface self.enyo = Enyo(webview) self.enyo.connect("ready", self.init_context) self.enyo.connect("helloFromJS", self.display_message) self.enyo.connect("disableBack", self.disable_back) self.enyo.connect("disableForward", self.disable_forward) self.enyo.connect("JSsliderChanged", self.jscript_slider_changed) self.enyo.connect("JScheckboxChanged", self.jscript_checkbox_changed) # Go to first page web_app_page = os.path.join(activity.get_bundle_path(), "html/index.html") self.webview.load_uri('file://' + web_app_page) # Display all self.set_canvas(vbox) vbox.show() def make_toolbar(self): # toolbar with the new toolbar redesign toolbar_box = ToolbarBox() activity_button = ActivityButton(self) toolbar_box.toolbar.insert(activity_button, 0) activity_button.show() home_button = ToolButton('go-home') home_button.set_tooltip('Page count to 0') home_button.connect('clicked', self.go_home) toolbar_box.toolbar.insert(home_button, -1) home_button.show() title_entry = TitleEntry(self) toolbar_box.toolbar.insert(title_entry, -1) title_entry.show() description_item = DescriptionItem(self) toolbar_box.toolbar.insert(description_item, -1) description_item.show() back_button = self.back_button = ToolButton('go-previous-paired') back_button.set_tooltip('Page count -1') back_button.connect('clicked', self.go_back) back_button.set_sensitive(False) toolbar_box.toolbar.insert(back_button, -1) back_button.show() forward_button = self.forward_button = ToolButton('go-next-paired') forward_button.set_tooltip('Page count +1') forward_button.connect('clicked', self.go_forward) toolbar_box.toolbar.insert(forward_button, -1) forward_button.show() share_button = ShareButton(self) toolbar_box.toolbar.insert(share_button, -1) share_button.show() separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) toolbar_box.toolbar.insert(separator, -1) separator.show() stop_button = StopButton(self) toolbar_box.toolbar.insert(stop_button, -1) stop_button.show() self.set_toolbar_box(toolbar_box) toolbar_box.show()