Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/activity.py
blob: 54460df9ac7a530bafc7cd57f52ddb1b88f0c38f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
#!/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()